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 |
|
|
|