mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
277 lines
6.1 KiB
C
277 lines
6.1 KiB
C
/*
|
|
** mruby/value.h - mrb_value definition
|
|
**
|
|
** See Copyright Notice in mruby.h
|
|
*/
|
|
|
|
#ifndef MRUBY_VALUE_H
|
|
#define MRUBY_VALUE_H
|
|
|
|
#ifndef MRB_NAN_BOXING
|
|
|
|
enum mrb_vtype {
|
|
MRB_TT_FALSE = 0, /* 0 */
|
|
MRB_TT_FREE, /* 1 */
|
|
MRB_TT_TRUE, /* 2 */
|
|
MRB_TT_FIXNUM, /* 3 */
|
|
MRB_TT_SYMBOL, /* 4 */
|
|
MRB_TT_UNDEF, /* 5 */
|
|
MRB_TT_FLOAT, /* 6 */
|
|
MRB_TT_VOIDP, /* 7 */
|
|
MRB_TT_MAIN, /* 8 */
|
|
MRB_TT_OBJECT, /* 9 */
|
|
MRB_TT_CLASS, /* 10 */
|
|
MRB_TT_MODULE, /* 11 */
|
|
MRB_TT_ICLASS, /* 12 */
|
|
MRB_TT_SCLASS, /* 13 */
|
|
MRB_TT_PROC, /* 14 */
|
|
MRB_TT_ARRAY, /* 15 */
|
|
MRB_TT_HASH, /* 16 */
|
|
MRB_TT_STRING, /* 17 */
|
|
MRB_TT_RANGE, /* 18 */
|
|
MRB_TT_STRUCT, /* 19 */
|
|
MRB_TT_EXCEPTION, /* 20 */
|
|
MRB_TT_FILE, /* 21 */
|
|
MRB_TT_ENV, /* 22 */
|
|
MRB_TT_DATA, /* 23 */
|
|
MRB_TT_MAXDEFINE /* 24 */
|
|
};
|
|
|
|
typedef struct mrb_value {
|
|
union {
|
|
mrb_float f;
|
|
void *p;
|
|
mrb_int i;
|
|
mrb_sym sym;
|
|
} value;
|
|
enum mrb_vtype tt:8;
|
|
} mrb_value;
|
|
|
|
#define mrb_type(o) (o).tt
|
|
#define mrb_float(o) (o).value.f
|
|
|
|
#define MRB_SET_VALUE(o, ttt, attr, v) do {\
|
|
(o).tt = ttt;\
|
|
(o).attr = v;\
|
|
} while (0)
|
|
|
|
static inline mrb_value
|
|
mrb_float_value(mrb_float f)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_FLOAT, value.f, f);
|
|
return v;
|
|
}
|
|
#else /* MRB_NAN_BOXING */
|
|
|
|
#ifdef MRB_USE_FLOAT
|
|
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
|
|
#endif
|
|
|
|
enum mrb_vtype {
|
|
MRB_TT_FALSE = 1, /* 1 */
|
|
MRB_TT_FREE, /* 2 */
|
|
MRB_TT_TRUE, /* 3 */
|
|
MRB_TT_FIXNUM, /* 4 */
|
|
MRB_TT_SYMBOL, /* 5 */
|
|
MRB_TT_UNDEF, /* 6 */
|
|
MRB_TT_FLOAT, /* 7 */
|
|
MRB_TT_VOIDP, /* 8 */
|
|
MRB_TT_MAIN, /* 9 */
|
|
MRB_TT_OBJECT, /* 10 */
|
|
MRB_TT_CLASS, /* 11 */
|
|
MRB_TT_MODULE, /* 12 */
|
|
MRB_TT_ICLASS, /* 13 */
|
|
MRB_TT_SCLASS, /* 14 */
|
|
MRB_TT_PROC, /* 15 */
|
|
MRB_TT_ARRAY, /* 16 */
|
|
MRB_TT_HASH, /* 17 */
|
|
MRB_TT_STRING, /* 18 */
|
|
MRB_TT_RANGE, /* 19 */
|
|
MRB_TT_STRUCT, /* 20 */
|
|
MRB_TT_EXCEPTION, /* 21 */
|
|
MRB_TT_FILE, /* 22 */
|
|
MRB_TT_ENV, /* 23 */
|
|
MRB_TT_DATA, /* 24 */
|
|
MRB_TT_MAXDEFINE /* 25 */
|
|
};
|
|
|
|
#ifdef MRB_ENDIAN_BIG
|
|
#define MRB_ENDIAN_LOHI(a,b) a b
|
|
#else
|
|
#define MRB_ENDIAN_LOHI(a,b) b a
|
|
#endif
|
|
|
|
typedef struct mrb_value {
|
|
union {
|
|
mrb_float f;
|
|
struct {
|
|
MRB_ENDIAN_LOHI(
|
|
uint32_t ttt;
|
|
,union {
|
|
void *p;
|
|
mrb_int i;
|
|
mrb_sym sym;
|
|
} value;
|
|
)
|
|
};
|
|
};
|
|
} mrb_value;
|
|
|
|
#define mrb_tt(o) ((o).ttt & 0xff)
|
|
#define mrb_mktt(tt) (0xfff00000|(tt))
|
|
#define mrb_type(o) ((uint32_t)0xfff00000 < (o).ttt ? mrb_tt(o) : MRB_TT_FLOAT)
|
|
#define mrb_float(o) (o).f
|
|
|
|
#define MRB_SET_VALUE(o, tt, attr, v) do {\
|
|
(o).ttt = mrb_mktt(tt);\
|
|
(o).attr = v;\
|
|
} while (0)
|
|
|
|
static inline mrb_value
|
|
mrb_float_value(mrb_float f)
|
|
{
|
|
mrb_value v;
|
|
|
|
if (f != f) {
|
|
v.ttt = 0x7ff80000;
|
|
v.value.i = 0;
|
|
} else {
|
|
v.f = f;
|
|
}
|
|
return v;
|
|
}
|
|
#endif /* MRB_NAN_BOXING */
|
|
|
|
#define mrb_fixnum(o) (o).value.i
|
|
#define mrb_symbol(o) (o).value.sym
|
|
#define mrb_object(o) ((struct RBasic *) (o).value.p)
|
|
#define mrb_voidp(o) (o).value.p
|
|
#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
|
|
#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
|
|
#define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
|
|
#define mrb_nil_p(o) (mrb_type(o) == MRB_TT_FALSE && !(o).value.i)
|
|
#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
|
|
#define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
|
|
#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
|
|
#define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
|
|
#define mrb_voidp_p(o) (mrb_type(o) == MRB_TT_VOIDP)
|
|
#define mrb_test(o) (mrb_type(o) != MRB_TT_FALSE)
|
|
|
|
#define MRB_OBJECT_HEADER \
|
|
enum mrb_vtype tt:8;\
|
|
unsigned int color:3;\
|
|
unsigned int flags:21;\
|
|
struct RClass *c;\
|
|
struct RBasic *gcnext
|
|
|
|
/* white: 011, black: 100, gray: 000 */
|
|
#define MRB_GC_GRAY 0
|
|
#define MRB_GC_WHITE_A 1
|
|
#define MRB_GC_WHITE_B (1 << 1)
|
|
#define MRB_GC_BLACK (1 << 2)
|
|
#define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B)
|
|
#define MRB_GC_COLOR_MASK 7
|
|
|
|
#define paint_gray(o) ((o)->color = MRB_GC_GRAY)
|
|
#define paint_black(o) ((o)->color = MRB_GC_BLACK)
|
|
#define paint_white(o) ((o)->color = MRB_GC_WHITES)
|
|
#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
|
|
#define is_gray(o) ((o)->color == MRB_GC_GRAY)
|
|
#define is_white(o) ((o)->color & MRB_GC_WHITES)
|
|
#define is_black(o) ((o)->color & MRB_GC_BLACK)
|
|
#define is_dead(s, o) (((o)->color & other_white_part(s) & MRB_GC_WHITES) || (o)->tt == MRB_TT_FREE)
|
|
#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
|
|
#define other_white_part(s) ((s)->current_white_part ^ MRB_GC_WHITES)
|
|
|
|
struct RBasic {
|
|
MRB_OBJECT_HEADER;
|
|
};
|
|
|
|
#define mrb_basic(v) ((struct RBasic*)((v).value.p))
|
|
|
|
struct RObject {
|
|
MRB_OBJECT_HEADER;
|
|
struct iv_tbl *iv;
|
|
};
|
|
|
|
#define mrb_obj_ptr(v) ((struct RObject*)((v).value.p))
|
|
#define mrb_immediate_p(x) (mrb_type(x) <= MRB_TT_MAIN)
|
|
#define mrb_special_const_p(x) mrb_immediate_p(x)
|
|
|
|
static inline mrb_value
|
|
mrb_fixnum_value(mrb_int i)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_FIXNUM, value.i, i);
|
|
return v;
|
|
}
|
|
|
|
static inline mrb_value
|
|
mrb_symbol_value(mrb_sym i)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_SYMBOL, value.sym, i);
|
|
return v;
|
|
}
|
|
|
|
static inline mrb_value
|
|
mrb_obj_value(void *p)
|
|
{
|
|
mrb_value v;
|
|
struct RBasic *b = (struct RBasic*)p;
|
|
|
|
MRB_SET_VALUE(v, b->tt, value.p, p);
|
|
return v;
|
|
}
|
|
|
|
static inline mrb_value
|
|
mrb_voidp_value(void *p)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_VOIDP, value.p, p);
|
|
return v;
|
|
}
|
|
|
|
static inline mrb_value
|
|
mrb_false_value(void)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_FALSE, value.i, 1);
|
|
return v;
|
|
}
|
|
|
|
static inline mrb_value
|
|
mrb_nil_value(void)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_FALSE, value.i, 0);
|
|
return v;
|
|
}
|
|
|
|
static inline mrb_value
|
|
mrb_true_value(void)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_TRUE, value.i, 1);
|
|
return v;
|
|
}
|
|
|
|
static inline mrb_value
|
|
mrb_undef_value(void)
|
|
{
|
|
mrb_value v;
|
|
|
|
MRB_SET_VALUE(v, MRB_TT_UNDEF, value.i, 0);
|
|
return v;
|
|
}
|
|
|
|
#endif /* MRUBY_OBJECT_H */
|