| Line |
Branch |
Exec |
Source |
| 1 |
|
|
/** |
| 2 |
|
|
** @file mruby/boxing_word.h - word boxing mrb_value definition |
| 3 |
|
|
** |
| 4 |
|
|
** See Copyright Notice in mruby.h |
| 5 |
|
|
*/ |
| 6 |
|
|
|
| 7 |
|
|
#ifndef MRUBY_BOXING_WORD_H |
| 8 |
|
|
#define MRUBY_BOXING_WORD_H |
| 9 |
|
|
|
| 10 |
|
|
#if defined(MRB_32BIT) && !defined(MRB_USE_FLOAT32) && !defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) |
| 11 |
|
|
# define MRB_WORDBOX_NO_FLOAT_TRUNCATE |
| 12 |
|
|
#endif |
| 13 |
|
|
|
| 14 |
|
|
#if !defined(MRB_NO_FLOAT) && defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) |
| 15 |
|
|
struct RFloat { |
| 16 |
|
|
MRB_OBJECT_HEADER; |
| 17 |
|
|
mrb_float f; |
| 18 |
|
|
}; |
| 19 |
|
|
#endif |
| 20 |
|
|
|
| 21 |
|
|
struct RInteger { |
| 22 |
|
|
MRB_OBJECT_HEADER; |
| 23 |
|
|
mrb_int i; |
| 24 |
|
|
}; |
| 25 |
|
|
|
| 26 |
|
|
enum mrb_special_consts { |
| 27 |
|
|
MRB_Qnil = 0, |
| 28 |
|
|
MRB_Qfalse = 4, |
| 29 |
|
|
MRB_Qtrue = 12, |
| 30 |
|
|
MRB_Qundef = 20, |
| 31 |
|
|
}; |
| 32 |
|
|
|
| 33 |
|
|
#if defined(MRB_64BIT) && defined(MRB_INT32) |
| 34 |
|
|
#define MRB_FIXNUM_SHIFT 0 |
| 35 |
|
|
#else |
| 36 |
|
|
#define MRB_FIXNUM_SHIFT WORDBOX_FIXNUM_SHIFT |
| 37 |
|
|
#endif |
| 38 |
|
|
#define MRB_SYMBOL_SHIFT WORDBOX_SYMBOL_SHIFT |
| 39 |
|
|
|
| 40 |
|
|
#if defined(MRB_64BIT) && defined(MRB_INT64) |
| 41 |
|
|
# define MRB_FIXNUM_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT) |
| 42 |
|
|
# define MRB_FIXNUM_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT) |
| 43 |
|
|
#else |
| 44 |
|
|
# define MRB_FIXNUM_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT) |
| 45 |
|
|
# define MRB_FIXNUM_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT) |
| 46 |
|
|
#endif |
| 47 |
|
|
|
| 48 |
|
|
#define WORDBOX_FIXNUM_BIT_POS 1 |
| 49 |
|
|
#define WORDBOX_FIXNUM_SHIFT WORDBOX_FIXNUM_BIT_POS |
| 50 |
|
|
#define WORDBOX_FIXNUM_FLAG (1 << (WORDBOX_FIXNUM_BIT_POS - 1)) |
| 51 |
|
|
#define WORDBOX_FIXNUM_MASK ((1 << WORDBOX_FIXNUM_BIT_POS) - 1) |
| 52 |
|
|
|
| 53 |
|
|
#if defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) |
| 54 |
|
|
/* floats are allocated in heaps */ |
| 55 |
|
|
#define WORDBOX_SYMBOL_BIT_POS 2 |
| 56 |
|
|
#define WORDBOX_SYMBOL_SHIFT WORDBOX_SYMBOL_BIT_POS |
| 57 |
|
|
#define WORDBOX_SYMBOL_FLAG (1 << (WORDBOX_SYMBOL_BIT_POS - 1)) |
| 58 |
|
|
#define WORDBOX_SYMBOL_MASK ((1 << WORDBOX_SYMBOL_BIT_POS) - 1) |
| 59 |
|
|
#else |
| 60 |
|
|
#define WORDBOX_FLOAT_FLAG 2 |
| 61 |
|
|
#define WORDBOX_FLOAT_MASK 3 |
| 62 |
|
|
#if defined(MRB_64BIT) |
| 63 |
|
|
#define WORDBOX_SYMBOL_SHIFT 32 |
| 64 |
|
|
#else /* MRB_32BIT */ |
| 65 |
|
|
#define WORDBOX_SYMBOL_SHIFT 5 |
| 66 |
|
|
#endif |
| 67 |
|
|
#define WORDBOX_SYMBOL_FLAG 0x1c |
| 68 |
|
|
#define WORDBOX_SYMBOL_MASK 0x1f |
| 69 |
|
|
#endif |
| 70 |
|
|
|
| 71 |
|
|
#define WORDBOX_IMMEDIATE_MASK 0x07 |
| 72 |
|
|
|
| 73 |
|
|
#define WORDBOX_SET_SHIFT_VALUE(o,n,v) \ |
| 74 |
|
|
((o).w = (((uintptr_t)(v)) << WORDBOX_##n##_SHIFT) | WORDBOX_##n##_FLAG) |
| 75 |
|
|
#define WORDBOX_SHIFT_VALUE_P(o,n) \ |
| 76 |
|
|
(((o).w & WORDBOX_##n##_MASK) == WORDBOX_##n##_FLAG) |
| 77 |
|
|
#define WORDBOX_OBJ_TYPE_P(o,n) \ |
| 78 |
|
|
(!mrb_immediate_p(o) && mrb_val_union(o).bp->tt == MRB_TT_##n) |
| 79 |
|
|
|
| 80 |
|
|
/* |
| 81 |
|
|
* mrb_value representation: |
| 82 |
|
|
* |
| 83 |
|
|
* 64bit word with inline float: |
| 84 |
|
|
* nil : ...0000 0000 (all bits are 0) |
| 85 |
|
|
* false : ...0000 0100 (mrb_fixnum(v) != 0) |
| 86 |
|
|
* true : ...0000 1100 |
| 87 |
|
|
* undef : ...0001 0100 |
| 88 |
|
|
* symbol: ...0001 1100 (use only upper 32-bit as symbol value with MRB_64BIT) |
| 89 |
|
|
* fixnum: ...IIII III1 |
| 90 |
|
|
* float : ...FFFF FF10 (51 bit significands; require MRB_64BIT) |
| 91 |
|
|
* object: ...PPPP P000 |
| 92 |
|
|
* |
| 93 |
|
|
* 32bit word with inline float: |
| 94 |
|
|
* nil : ...0000 0000 (all bits are 0) |
| 95 |
|
|
* false : ...0000 0100 (mrb_fixnum(v) != 0) |
| 96 |
|
|
* true : ...0000 1100 |
| 97 |
|
|
* undef : ...0001 0100 |
| 98 |
|
|
* symbol: ...SSS1 0100 (symbol occupies 20bits) |
| 99 |
|
|
* fixnum: ...IIII III1 |
| 100 |
|
|
* float : ...FFFF FF10 (22 bit significands; require MRB_64BIT) |
| 101 |
|
|
* object: ...PPPP P000 |
| 102 |
|
|
* |
| 103 |
|
|
* and word boxing without inline float (MRB_WORDBOX_NO_FLOAT_TRUNCATE): |
| 104 |
|
|
* nil : ...0000 0000 (all bits are 0) |
| 105 |
|
|
* false : ...0000 0100 (mrb_fixnum(v) != 0) |
| 106 |
|
|
* true : ...0000 1100 |
| 107 |
|
|
* undef : ...0001 0100 |
| 108 |
|
|
* fixnum: ...IIII III1 |
| 109 |
|
|
* symbol: ...SSSS SS10 |
| 110 |
|
|
* object: ...PPPP P000 (any bits are 1) |
| 111 |
|
|
*/ |
| 112 |
|
|
typedef struct mrb_value { |
| 113 |
|
|
uintptr_t w; |
| 114 |
|
|
} mrb_value; |
| 115 |
|
|
|
| 116 |
|
|
union mrb_value_ { |
| 117 |
|
|
void *p; |
| 118 |
|
|
struct RBasic *bp; |
| 119 |
|
|
#ifndef MRB_NO_FLOAT |
| 120 |
|
|
#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE |
| 121 |
|
|
mrb_float f; |
| 122 |
|
|
#else |
| 123 |
|
|
struct RFloat *fp; |
| 124 |
|
|
#endif |
| 125 |
|
|
#endif |
| 126 |
|
|
struct RInteger *ip; |
| 127 |
|
|
struct RCptr *vp; |
| 128 |
|
|
uintptr_t w; |
| 129 |
|
|
mrb_value value; |
| 130 |
|
|
}; |
| 131 |
|
|
|
| 132 |
|
|
mrb_static_assert(sizeof(mrb_value) == sizeof(union mrb_value_)); |
| 133 |
|
|
|
| 134 |
|
|
static inline union mrb_value_ |
| 135 |
|
341 |
mrb_val_union(mrb_value v) |
| 136 |
|
|
{ |
| 137 |
|
|
union mrb_value_ x; |
| 138 |
|
341 |
x.value = v; |
| 139 |
|
341 |
return x; |
| 140 |
|
|
} |
| 141 |
|
|
|
| 142 |
|
|
MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*); |
| 143 |
|
|
#ifndef MRB_NO_FLOAT |
| 144 |
|
|
MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float); |
| 145 |
|
|
#endif |
| 146 |
|
|
MRB_API mrb_value mrb_boxing_int_value(struct mrb_state*, mrb_int); |
| 147 |
|
|
|
| 148 |
|
|
#define mrb_immediate_p(o) ((o).w & WORDBOX_IMMEDIATE_MASK || (o).w == MRB_Qnil) |
| 149 |
|
|
|
| 150 |
|
|
#define mrb_ptr(o) mrb_val_union(o).p |
| 151 |
|
|
#define mrb_cptr(o) mrb_val_union(o).vp->p |
| 152 |
|
|
#ifndef MRB_NO_FLOAT |
| 153 |
|
|
#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE |
| 154 |
|
|
MRB_API mrb_float mrb_word_boxing_value_float(mrb_value v); |
| 155 |
|
|
#define mrb_float(o) mrb_word_boxing_value_float(o) |
| 156 |
|
|
#else |
| 157 |
|
|
#define mrb_float(o) mrb_val_union(o).fp->f |
| 158 |
|
|
#endif |
| 159 |
|
|
#endif |
| 160 |
|
|
#define mrb_fixnum(o) (mrb_int)(((intptr_t)(o).w) >> WORDBOX_FIXNUM_SHIFT) |
| 161 |
|
|
MRB_INLINE mrb_int |
| 162 |
|
|
mrb_integer_func(mrb_value o) { |
| 163 |
|
|
if (mrb_immediate_p(o)) return mrb_fixnum(o); |
| 164 |
|
|
return mrb_val_union(o).ip->i; |
| 165 |
|
|
} |
| 166 |
|
|
#define mrb_integer(o) mrb_integer_func(o) |
| 167 |
|
|
#define mrb_symbol(o) (mrb_sym)(((o).w) >> WORDBOX_SYMBOL_SHIFT) |
| 168 |
|
|
#define mrb_bool(o) (((o).w & ~(uintptr_t)MRB_Qfalse) != 0) |
| 169 |
|
|
|
| 170 |
|
|
#define mrb_fixnum_p(o) WORDBOX_SHIFT_VALUE_P(o, FIXNUM) |
| 171 |
|
|
#define mrb_integer_p(o) (WORDBOX_SHIFT_VALUE_P(o, FIXNUM)||WORDBOX_OBJ_TYPE_P(o, INTEGER)) |
| 172 |
|
|
#define mrb_symbol_p(o) WORDBOX_SHIFT_VALUE_P(o, SYMBOL) |
| 173 |
|
|
#define mrb_undef_p(o) ((o).w == MRB_Qundef) |
| 174 |
|
|
#define mrb_nil_p(o) ((o).w == MRB_Qnil) |
| 175 |
|
|
#define mrb_false_p(o) ((o).w == MRB_Qfalse) |
| 176 |
|
|
#define mrb_true_p(o) ((o).w == MRB_Qtrue) |
| 177 |
|
|
#ifndef MRB_NO_FLOAT |
| 178 |
|
|
#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE |
| 179 |
|
|
#define mrb_float_p(o) WORDBOX_SHIFT_VALUE_P(o, FLOAT) |
| 180 |
|
|
#else |
| 181 |
|
|
#define mrb_float_p(o) WORDBOX_OBJ_TYPE_P(o, FLOAT) |
| 182 |
|
|
#endif |
| 183 |
|
|
#else |
| 184 |
|
|
#define mrb_float_p(o) FALSE |
| 185 |
|
|
#endif |
| 186 |
|
|
#define mrb_array_p(o) WORDBOX_OBJ_TYPE_P(o, ARRAY) |
| 187 |
|
|
#define mrb_string_p(o) WORDBOX_OBJ_TYPE_P(o, STRING) |
| 188 |
|
|
#define mrb_hash_p(o) WORDBOX_OBJ_TYPE_P(o, HASH) |
| 189 |
|
|
#define mrb_cptr_p(o) WORDBOX_OBJ_TYPE_P(o, CPTR) |
| 190 |
|
|
#define mrb_exception_p(o) WORDBOX_OBJ_TYPE_P(o, EXCEPTION) |
| 191 |
|
|
#define mrb_free_p(o) WORDBOX_OBJ_TYPE_P(o, FREE) |
| 192 |
|
|
#define mrb_object_p(o) WORDBOX_OBJ_TYPE_P(o, OBJECT) |
| 193 |
|
|
#define mrb_class_p(o) WORDBOX_OBJ_TYPE_P(o, CLASS) |
| 194 |
|
|
#define mrb_module_p(o) WORDBOX_OBJ_TYPE_P(o, MODULE) |
| 195 |
|
|
#define mrb_iclass_p(o) WORDBOX_OBJ_TYPE_P(o, ICLASS) |
| 196 |
|
|
#define mrb_sclass_p(o) WORDBOX_OBJ_TYPE_P(o, SCLASS) |
| 197 |
|
|
#define mrb_proc_p(o) WORDBOX_OBJ_TYPE_P(o, PROC) |
| 198 |
|
|
#define mrb_range_p(o) WORDBOX_OBJ_TYPE_P(o, RANGE) |
| 199 |
|
|
#define mrb_env_p(o) WORDBOX_OBJ_TYPE_P(o, ENV) |
| 200 |
|
|
#define mrb_data_p(o) WORDBOX_OBJ_TYPE_P(o, DATA) |
| 201 |
|
|
#define mrb_fiber_p(o) WORDBOX_OBJ_TYPE_P(o, FIBER) |
| 202 |
|
|
#define mrb_istruct_p(o) WORDBOX_OBJ_TYPE_P(o, ISTRUCT) |
| 203 |
|
|
#define mrb_break_p(o) WORDBOX_OBJ_TYPE_P(o, BREAK) |
| 204 |
|
|
|
| 205 |
|
|
#ifndef MRB_NO_FLOAT |
| 206 |
|
|
#define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v)) |
| 207 |
|
|
#endif |
| 208 |
|
|
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v)) |
| 209 |
|
|
#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef) |
| 210 |
|
|
#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil) |
| 211 |
|
|
#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse) |
| 212 |
|
|
#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue) |
| 213 |
|
|
#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r)) |
| 214 |
|
|
#define SET_INT_VALUE(mrb,r,n) ((r) = mrb_boxing_int_value(mrb, n)) |
| 215 |
|
|
#define SET_FIXNUM_VALUE(r,n) WORDBOX_SET_SHIFT_VALUE(r, FIXNUM, n) |
| 216 |
|
|
#define SET_SYM_VALUE(r,n) WORDBOX_SET_SHIFT_VALUE(r, SYMBOL, n) |
| 217 |
|
|
#define SET_OBJ_VALUE(r,v) ((r).w = (uintptr_t)(v)) |
| 218 |
|
|
|
| 219 |
|
|
MRB_INLINE enum mrb_vtype |
| 220 |
|
72 |
mrb_type(mrb_value o) |
| 221 |
|
|
{ |
| 222 |
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
|
144 |
return !mrb_bool(o) ? MRB_TT_FALSE : |
| 223 |
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
|
144 |
mrb_true_p(o) ? MRB_TT_TRUE : |
| 224 |
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
|
144 |
mrb_fixnum_p(o) ? MRB_TT_INTEGER : |
| 225 |
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 47 times.
|
97 |
mrb_symbol_p(o) ? MRB_TT_SYMBOL : |
| 226 |
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
50 |
mrb_undef_p(o) ? MRB_TT_UNDEF : |
| 227 |
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 |
mrb_float_p(o) ? MRB_TT_FLOAT : |
| 228 |
|
97 |
mrb_val_union(o).bp->tt; |
| 229 |
|
|
} |
| 230 |
|
|
|
| 231 |
|
|
#endif /* MRUBY_BOXING_WORD_H */ |
| 232 |
|
|
|