Codebase list mruby / ec3a5f3
Merge pull request #1266 from kimushu/feature/word-boxing Add MRB_WORD_BOXING mode (represent mrb_value as a word) Yukihiro "Matz" Matsumoto 10 years ago
15 changed file(s) with 435 addition(s) and 170 deletion(s). Raw diff Collapse all Expand all
2424
2525 /* define on big endian machines; used by MRB_NAN_BOXING */
2626 //#define MRB_ENDIAN_BIG
27
28 /* represent mrb_value as a word (natural unit of data for the processor) */
29 // #define MRB_WORD_BOXING
2730
2831 /* argv max size in mrb_funcall */
2932 //#define MRB_FUNCALL_ARGC_MAX 16
77 #define MRUBY_VALUE_H
88
99 typedef uint8_t mrb_bool;
10
11 #ifndef MRB_NAN_BOXING
10 struct mrb_state;
11
12 #if defined(MRB_NAN_BOXING)
13
14 #ifdef MRB_USE_FLOAT
15 # error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
16 #endif
17
18 enum mrb_vtype {
19 MRB_TT_FALSE = 1, /* 1 */
20 MRB_TT_FREE, /* 2 */
21 MRB_TT_TRUE, /* 3 */
22 MRB_TT_FIXNUM, /* 4 */
23 MRB_TT_SYMBOL, /* 5 */
24 MRB_TT_UNDEF, /* 6 */
25 MRB_TT_FLOAT, /* 7 */
26 MRB_TT_VOIDP, /* 8 */
27 MRB_TT_OBJECT, /* 9 */
28 MRB_TT_CLASS, /* 10 */
29 MRB_TT_MODULE, /* 11 */
30 MRB_TT_ICLASS, /* 12 */
31 MRB_TT_SCLASS, /* 13 */
32 MRB_TT_PROC, /* 14 */
33 MRB_TT_ARRAY, /* 15 */
34 MRB_TT_HASH, /* 16 */
35 MRB_TT_STRING, /* 17 */
36 MRB_TT_RANGE, /* 18 */
37 MRB_TT_EXCEPTION, /* 19 */
38 MRB_TT_FILE, /* 20 */
39 MRB_TT_ENV, /* 21 */
40 MRB_TT_DATA, /* 22 */
41 MRB_TT_FIBER, /* 23 */
42 MRB_TT_MAXDEFINE /* 24 */
43 };
44
45 #define MRB_TT_HAS_BASIC MRB_TT_OBJECT
46
47 #ifdef MRB_ENDIAN_BIG
48 #define MRB_ENDIAN_LOHI(a,b) a b
49 #else
50 #define MRB_ENDIAN_LOHI(a,b) b a
51 #endif
52
53 typedef struct mrb_value {
54 union {
55 mrb_float f;
56 struct {
57 MRB_ENDIAN_LOHI(
58 uint32_t ttt;
59 ,union {
60 void *p;
61 mrb_int i;
62 mrb_sym sym;
63 } value;
64 )
65 };
66 };
67 } mrb_value;
68
69 #define mrb_tt(o) ((o).ttt & 0xff)
70 #define mrb_mktt(tt) (0xfff00000|(tt))
71 #define mrb_type(o) ((uint32_t)0xfff00000 < (o).ttt ? mrb_tt(o) : MRB_TT_FLOAT)
72 #define mrb_float(o) (o).f
73
74 #define MRB_SET_VALUE(o, tt, attr, v) do {\
75 (o).ttt = mrb_mktt(tt);\
76 (o).attr = v;\
77 } while (0)
78
79 static inline mrb_value
80 mrb_float_value(struct mrb_state *mrb, mrb_float f)
81 {
82 mrb_value v;
83
84 if (f != f) {
85 v.ttt = 0x7ff80000;
86 v.value.i = 0;
87 } else {
88 v.f = f;
89 }
90 return v;
91 }
92
93 #elif defined(MRB_WORD_BOXING)
1294
1395 enum mrb_vtype {
1496 MRB_TT_FALSE = 0, /* 0 */
37119 MRB_TT_MAXDEFINE /* 23 */
38120 };
39121
122 #define MRB_TT_HAS_BASIC MRB_TT_FLOAT
123
124 enum mrb_special_consts {
125 MRB_Qnil = 0,
126 MRB_Qfalse = 2,
127 MRB_Qtrue = 4,
128 MRB_Qundef = 6,
129
130 MRB_FIXNUM_FLAG = 0x01,
131 MRB_FIXNUM_SHIFT = 1,
132 MRB_SYMBOL_FLAG = 0x0e,
133 MRB_SPECIAL_SHIFT = 8,
134 };
135
136 typedef union mrb_value {
137 union {
138 void *p;
139 struct {
140 unsigned int i_flag : MRB_FIXNUM_SHIFT;
141 mrb_int i : (sizeof(mrb_int) * 8 - MRB_FIXNUM_SHIFT);
142 };
143 struct {
144 unsigned int sym_flag : MRB_SPECIAL_SHIFT;
145 int sym : (sizeof(mrb_sym) * 8);
146 };
147 struct RBasic *bp;
148 struct RFloat *fp;
149 struct RVoidp *vp;
150 } value;
151 unsigned long w;
152 } mrb_value;
153
154 #define mrb_float(o) (o).value.fp->f
155
156 #define MRB_SET_VALUE(o, ttt, attr, v) do {\
157 (o).w = 0;\
158 (o).attr = (v);\
159 switch (ttt) {\
160 case MRB_TT_FALSE: (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\
161 case MRB_TT_TRUE: (o).w = MRB_Qtrue; break;\
162 case MRB_TT_UNDEF: (o).w = MRB_Qundef; break;\
163 case MRB_TT_FIXNUM: (o).value.i_flag = MRB_FIXNUM_FLAG; break;\
164 case MRB_TT_SYMBOL: (o).value.sym_flag = MRB_SYMBOL_FLAG; break;\
165 default: if ((o).value.bp) (o).value.bp->tt = ttt; break;\
166 }\
167 } while (0)
168
169 extern mrb_value
170 mrb_float_value(struct mrb_state *mrb, mrb_float f);
171
172 #else /* No MRB_xxx_BOXING */
173
174 enum mrb_vtype {
175 MRB_TT_FALSE = 0, /* 0 */
176 MRB_TT_FREE, /* 1 */
177 MRB_TT_TRUE, /* 2 */
178 MRB_TT_FIXNUM, /* 3 */
179 MRB_TT_SYMBOL, /* 4 */
180 MRB_TT_UNDEF, /* 5 */
181 MRB_TT_FLOAT, /* 6 */
182 MRB_TT_VOIDP, /* 7 */
183 MRB_TT_OBJECT, /* 8 */
184 MRB_TT_CLASS, /* 9 */
185 MRB_TT_MODULE, /* 10 */
186 MRB_TT_ICLASS, /* 11 */
187 MRB_TT_SCLASS, /* 12 */
188 MRB_TT_PROC, /* 13 */
189 MRB_TT_ARRAY, /* 14 */
190 MRB_TT_HASH, /* 15 */
191 MRB_TT_STRING, /* 16 */
192 MRB_TT_RANGE, /* 17 */
193 MRB_TT_EXCEPTION, /* 18 */
194 MRB_TT_FILE, /* 19 */
195 MRB_TT_ENV, /* 20 */
196 MRB_TT_DATA, /* 21 */
197 MRB_TT_FIBER, /* 22 */
198 MRB_TT_MAXDEFINE /* 23 */
199 };
200
201 #define MRB_TT_HAS_BASIC MRB_TT_OBJECT
202
40203 typedef struct mrb_value {
41204 union {
42205 mrb_float f;
56219 } while (0)
57220
58221 static inline mrb_value
59 mrb_float_value(mrb_float f)
222 mrb_float_value(struct mrb_state *mrb, mrb_float f)
60223 {
61224 mrb_value v;
62225
63226 MRB_SET_VALUE(v, MRB_TT_FLOAT, value.f, f);
64227 return v;
65228 }
66 #else /* MRB_NAN_BOXING */
67
68 #ifdef MRB_USE_FLOAT
69 # error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
70 #endif
71
72 enum mrb_vtype {
73 MRB_TT_FALSE = 1, /* 1 */
74 MRB_TT_FREE, /* 2 */
75 MRB_TT_TRUE, /* 3 */
76 MRB_TT_FIXNUM, /* 4 */
77 MRB_TT_SYMBOL, /* 5 */
78 MRB_TT_UNDEF, /* 6 */
79 MRB_TT_FLOAT, /* 7 */
80 MRB_TT_VOIDP, /* 8 */
81 MRB_TT_OBJECT, /* 9 */
82 MRB_TT_CLASS, /* 10 */
83 MRB_TT_MODULE, /* 11 */
84 MRB_TT_ICLASS, /* 12 */
85 MRB_TT_SCLASS, /* 13 */
86 MRB_TT_PROC, /* 14 */
87 MRB_TT_ARRAY, /* 15 */
88 MRB_TT_HASH, /* 16 */
89 MRB_TT_STRING, /* 17 */
90 MRB_TT_RANGE, /* 18 */
91 MRB_TT_EXCEPTION, /* 19 */
92 MRB_TT_FILE, /* 20 */
93 MRB_TT_ENV, /* 21 */
94 MRB_TT_DATA, /* 22 */
95 MRB_TT_FIBER, /* 23 */
96 MRB_TT_MAXDEFINE /* 24 */
97 };
98
99 #ifdef MRB_ENDIAN_BIG
100 #define MRB_ENDIAN_LOHI(a,b) a b
229 #endif /* no boxing */
230
231 #ifdef MRB_WORD_BOXING
232
233 #define mrb_fixnum(o) (o).value.i
234 #define mrb_symbol(o) (o).value.sym
235 #define mrb_voidp(o) (o).value.vp->p
236 #define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG)
237 #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
238 #define mrb_undef_p(o) ((o).w == MRB_Qundef)
239 #define mrb_nil_p(o) ((o).w == MRB_Qnil)
240 #define mrb_symbol_p(o) ((o).value.sym_flag == MRB_SYMBOL_FLAG)
241 #define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
242 #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
243 #define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
244 #define mrb_voidp_p(o) (mrb_type(o) == MRB_TT_VOIDP)
245 #define mrb_bool(o) ((o).w != MRB_Qnil && (o).w != MRB_Qfalse)
246 #define mrb_test(o) mrb_bool(o)
247
101248 #else
102 #define MRB_ENDIAN_LOHI(a,b) b a
103 #endif
104
105 typedef struct mrb_value {
106 union {
107 mrb_float f;
108 struct {
109 MRB_ENDIAN_LOHI(
110 uint32_t ttt;
111 ,union {
112 void *p;
113 mrb_int i;
114 mrb_sym sym;
115 } value;
116 )
117 };
118 };
119 } mrb_value;
120
121 #define mrb_tt(o) ((o).ttt & 0xff)
122 #define mrb_mktt(tt) (0xfff00000|(tt))
123 #define mrb_type(o) ((uint32_t)0xfff00000 < (o).ttt ? mrb_tt(o) : MRB_TT_FLOAT)
124 #define mrb_float(o) (o).f
125
126 #define MRB_SET_VALUE(o, tt, attr, v) do {\
127 (o).ttt = mrb_mktt(tt);\
128 (o).attr = v;\
129 } while (0)
130
131 static inline mrb_value
132 mrb_float_value(mrb_float f)
133 {
134 mrb_value v;
135
136 if (f != f) {
137 v.ttt = 0x7ff80000;
138 v.value.i = 0;
139 } else {
140 v.f = f;
141 }
142 return v;
143 }
144 #endif /* MRB_NAN_BOXING */
145249
146250 #define mrb_fixnum(o) (o).value.i
147251 #define mrb_symbol(o) (o).value.sym
158262 #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE)
159263 #define mrb_test(o) mrb_bool(o)
160264
265 #endif /* no boxing */
266
161267 #define MRB_OBJECT_HEADER \
162268 enum mrb_vtype tt:8;\
163269 uint32_t color:3;\
208314 struct mrb_context *cxt;
209315 };
210316
317 #ifdef MRB_WORD_BOXING
318 struct RFloat {
319 MRB_OBJECT_HEADER;
320 mrb_float f;
321 };
322
323 struct RVoidp {
324 MRB_OBJECT_HEADER;
325 void *p;
326 };
327
328 static inline enum mrb_vtype
329 mrb_type(mrb_value o)
330 {
331 switch (o.w) {
332 case MRB_Qfalse:
333 case MRB_Qnil:
334 return MRB_TT_FALSE;
335 case MRB_Qtrue:
336 return MRB_TT_TRUE;
337 case MRB_Qundef:
338 return MRB_TT_UNDEF;
339 }
340 if (o.value.i_flag == MRB_FIXNUM_FLAG) {
341 return MRB_TT_FIXNUM;
342 }
343 if (o.value.sym_flag == MRB_SYMBOL_FLAG) {
344 return MRB_TT_SYMBOL;
345 }
346 return o.value.bp->tt;
347 }
348 #endif /* MRB_WORD_BOXING */
349
211350 static inline mrb_value
212351 mrb_fixnum_value(mrb_int i)
213352 {
236375 return v;
237376 }
238377
239 static inline mrb_value
240 mrb_voidp_value(void *p)
378 #ifdef MRB_WORD_BOXING
379 mrb_value
380 mrb_voidp_value(struct mrb_state *mrb, void *p);
381 #else
382 static inline mrb_value
383 mrb_voidp_value(struct mrb_state *mrb, void *p)
241384 {
242385 mrb_value v;
243386
244387 MRB_SET_VALUE(v, MRB_TT_VOIDP, value.p, p);
245388 return v;
246389 }
390 #endif
247391
248392 static inline mrb_value
249393 mrb_false_value(void)
272272 void mrb_gc_arena_restore(mrb_state*,int);
273273 void mrb_gc_mark(mrb_state*,struct RBasic*);
274274 #define mrb_gc_mark_value(mrb,val) do {\
275 if (mrb_type(val) >= MRB_TT_OBJECT) mrb_gc_mark((mrb), mrb_basic_ptr(val));\
275 if (mrb_type(val) >= MRB_TT_HAS_BASIC) mrb_gc_mark((mrb), mrb_basic_ptr(val));\
276276 } while (0)
277277 void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*);
278278 #define mrb_field_write_barrier_value(mrb, obj, val) do{\
279 if ((val.tt >= MRB_TT_OBJECT)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val));\
279 if ((val.tt >= MRB_TT_HAS_BASIC)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val));\
280280 } while (0)
281281 void mrb_write_barrier(mrb_state *, struct RBasic*);
282282
107107 mrb_get_args(mrb, "f", &x);
108108 x = sin(x);
109109
110 return mrb_float_value(x);
110 return mrb_float_value(mrb, x);
111111 }
112112
113113 /*
125125 mrb_get_args(mrb, "f", &x);
126126 x = cos(x);
127127
128 return mrb_float_value(x);
128 return mrb_float_value(mrb, x);
129129 }
130130
131131 /*
142142 mrb_get_args(mrb, "f", &x);
143143 x = tan(x);
144144
145 return mrb_float_value(x);
145 return mrb_float_value(mrb, x);
146146 }
147147
148148 /*
163163 mrb_get_args(mrb, "f", &x);
164164 x = asin(x);
165165
166 return mrb_float_value(x);
166 return mrb_float_value(mrb, x);
167167 }
168168
169169 /*
180180 mrb_get_args(mrb, "f", &x);
181181 x = acos(x);
182182
183 return mrb_float_value(x);
183 return mrb_float_value(mrb, x);
184184 }
185185
186186 /*
197197 mrb_get_args(mrb, "f", &x);
198198 x = atan(x);
199199
200 return mrb_float_value(x);
200 return mrb_float_value(mrb, x);
201201 }
202202
203203 /*
227227 mrb_get_args(mrb, "ff", &x, &y);
228228 x = atan2(x, y);
229229
230 return mrb_float_value(x);
230 return mrb_float_value(mrb, x);
231231 }
232232
233233
250250 mrb_get_args(mrb, "f", &x);
251251 x = sinh(x);
252252
253 return mrb_float_value(x);
253 return mrb_float_value(mrb, x);
254254 }
255255
256256 /*
267267 mrb_get_args(mrb, "f", &x);
268268 x = cosh(x);
269269
270 return mrb_float_value(x);
270 return mrb_float_value(mrb, x);
271271 }
272272
273273 /*
285285 mrb_get_args(mrb, "f", &x);
286286 x = tanh(x);
287287
288 return mrb_float_value(x);
288 return mrb_float_value(mrb, x);
289289 }
290290
291291
308308
309309 x = asinh(x);
310310
311 return mrb_float_value(x);
311 return mrb_float_value(mrb, x);
312312 }
313313
314314 /*
325325 mrb_get_args(mrb, "f", &x);
326326 x = acosh(x);
327327
328 return mrb_float_value(x);
328 return mrb_float_value(mrb, x);
329329 }
330330
331331 /*
342342 mrb_get_args(mrb, "f", &x);
343343 x = atanh(x);
344344
345 return mrb_float_value(x);
345 return mrb_float_value(mrb, x);
346346 }
347347
348348 /*
388388 mrb_get_args(mrb, "f", &x);
389389 x = exp(x);
390390
391 return mrb_float_value(x);
391 return mrb_float_value(mrb, x);
392392 }
393393
394394 /*
417417 if (argc == 2) {
418418 x /= log(base);
419419 }
420 return mrb_float_value(x);
420 return mrb_float_value(mrb, x);
421421 }
422422
423423 /*
440440 mrb_get_args(mrb, "f", &x);
441441 x = log2(x);
442442
443 return mrb_float_value(x);
443 return mrb_float_value(mrb, x);
444444 }
445445
446446 /*
462462 mrb_get_args(mrb, "f", &x);
463463 x = log10(x);
464464
465 return mrb_float_value(x);
465 return mrb_float_value(mrb, x);
466466 }
467467
468468 /*
480480 mrb_get_args(mrb, "f", &x);
481481 x = sqrt(x);
482482
483 return mrb_float_value(x);
483 return mrb_float_value(mrb, x);
484484 }
485485
486486
523523 mrb_get_args(mrb, "f", &x);
524524 x = cbrt(x);
525525
526 return mrb_float_value(x);
526 return mrb_float_value(mrb, x);
527527 }
528528
529529
547547 mrb_get_args(mrb, "f", &x);
548548 x = frexp(x, &exp);
549549
550 return mrb_assoc_new(mrb, mrb_float_value(x), mrb_fixnum_value(exp));
550 return mrb_assoc_new(mrb, mrb_float_value(mrb, x), mrb_fixnum_value(exp));
551551 }
552552
553553 /*
568568 mrb_get_args(mrb, "fi", &x, &i);
569569 x = ldexp(x, i);
570570
571 return mrb_float_value(x);
571 return mrb_float_value(mrb, x);
572572 }
573573
574574 /*
588588 mrb_get_args(mrb, "ff", &x, &y);
589589 x = hypot(x, y);
590590
591 return mrb_float_value(x);
591 return mrb_float_value(mrb, x);
592592 }
593593
594594 /*
605605 mrb_get_args(mrb, "f", &x);
606606 x = erf(x);
607607
608 return mrb_float_value(x);
608 return mrb_float_value(mrb, x);
609609 }
610610
611611
623623 mrb_get_args(mrb, "f", &x);
624624 x = erfc(x);
625625
626 return mrb_float_value(x);
626 return mrb_float_value(mrb, x);
627627 }
628628
629629 /* ------------------------------------------------------------------------*/
634634 mrb_math = mrb_define_module(mrb, "Math");
635635
636636 #ifdef M_PI
637 mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(M_PI));
637 mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, M_PI));
638638 #else
639 mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(atan(1.0)*4.0));
639 mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, atan(1.0)*4.0));
640640 #endif
641641
642642 #ifdef M_E
643 mrb_define_const(mrb, mrb_math, "E", mrb_float_value(M_E));
643 mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, M_E));
644644 #else
645 mrb_define_const(mrb, mrb_math, "E", mrb_float_value(exp(1.0)));
645 mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0)));
646646 #endif
647647
648648 #ifdef MRB_USE_FLOAT
649 mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-5));
649 mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-5));
650650 #else
651 mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-12));
651 mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-12));
652652 #endif
653653
654654 mrb_define_module_function(mrb, mrb_math, "sin", math_sin, MRB_ARGS_REQ(1));
6565 mrb_value value;
6666
6767 if (mrb_fixnum(max) == 0) {
68 value = mrb_float_value(mt_g_rand_real());
68 value = mrb_float_value(mrb, mt_g_rand_real());
6969 } else {
7070 value = mrb_fixnum_value(mt_g_rand() % mrb_fixnum(max));
7171 }
107107 mrb_value value;
108108
109109 if (mrb_fixnum(max) == 0) {
110 value = mrb_float_value(mt_rand_real(t));
110 value = mrb_float_value(mrb, mt_rand_real(t));
111111 } else {
112112 value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max));
113113 }
357357 if (tm2) {
358358 f = (mrb_float)(tm->sec - tm2->sec)
359359 + (mrb_float)(tm->usec - tm2->usec) / 1.0e6;
360 return mrb_float_value(f);
360 return mrb_float_value(mrb, f);
361361 }
362362 else {
363363 mrb_get_args(mrb, "f", &f);
627627
628628 tm = (struct mrb_time*)mrb_data_get_ptr(mrb, self, &mrb_time_type);
629629 if (!tm) return mrb_nil_value();
630 return mrb_float_value((mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6);
630 return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6);
631631 }
632632
633633 /* 15.2.19.7.25 */
19001900 i = readint_mrb_int(s, p, base, FALSE, &overflow);
19011901 if (overflow) {
19021902 double f = readint_float(s, p, base);
1903 int off = new_lit(s, mrb_float_value(f));
1903 int off = new_lit(s, mrb_float_value(s->mrb, f));
19041904
19051905 genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
19061906 }
19221922 if (val) {
19231923 char *p = (char*)tree;
19241924 mrb_float f = str_to_mrb_float(p);
1925 int off = new_lit(s, mrb_float_value(f));
1925 int off = new_lit(s, mrb_float_value(s->mrb, f));
19261926
19271927 genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
19281928 push();
19381938 {
19391939 char *p = (char*)tree;
19401940 mrb_float f = str_to_mrb_float(p);
1941 int off = new_lit(s, mrb_float_value(-f));
1941 int off = new_lit(s, mrb_float_value(s->mrb, -f));
19421942
19431943 genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
19441944 push();
19561956 i = readint_mrb_int(s, p, base, TRUE, &overflow);
19571957 if (overflow) {
19581958 double f = readint_float(s, p, base);
1959 int off = new_lit(s, mrb_float_value(-f));
1959 int off = new_lit(s, mrb_float_value(s->mrb, -f));
19601960
19611961 genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
19621962 }
179179 }
180180 }
181181
182 #ifdef MRB_WORD_BOXING
183 mrb_value
184 mrb_float_value(mrb_state *mrb, mrb_float f)
185 {
186 mrb_value v;
187
188 v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class);
189 v.value.fp->f = f;
190 return v;
191 }
192
193 mrb_value
194 mrb_voidp_value(mrb_state *mrb, void *p)
195 {
196 mrb_value v;
197
198 v.value.p = mrb_obj_alloc(mrb, MRB_TT_VOIDP, mrb->object_class);
199 v.value.vp->p = p;
200 return v;
201 }
202 #endif /* MRB_WORD_BOXING */
203
529529 case MRB_TT_TRUE:
530530 case MRB_TT_FIXNUM:
531531 case MRB_TT_SYMBOL:
532 case MRB_TT_FLOAT:
533532 /* cannot happen */
534533 return;
534
535 case MRB_TT_FLOAT:
536 #ifdef MRB_WORD_BOXING
537 break;
538 #else
539 return;
540 #endif
535541
536542 case MRB_TT_OBJECT:
537543 mrb_gc_free_iv(mrb, (struct RObject*)obj);
893893 /* fall through */
894894 default:
895895 exc = mrb_make_exception(mrb, argc, a);
896 mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb->c->ci->pc));
896 mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb, mrb->c->ci->pc));
897897 mrb_exc_raise(mrb, exc);
898898 break;
899899 }
129129 break;
130130
131131 case MRB_TT_FLOAT:
132 irep->pool[i] = mrb_float_value(mrb_str_to_dbl(mrb, s, FALSE));
132 irep->pool[i] = mrb_float_value(mrb, mrb_str_to_dbl(mrb, s, FALSE));
133133 break;
134134
135135 case MRB_TT_STRING:
6464 static mrb_value
6565 num_uminus(mrb_state *mrb, mrb_value num)
6666 {
67 return mrb_float_value((mrb_float)0 - mrb_to_flo(mrb, num));
67 return mrb_float_value(mrb, (mrb_float)0 - mrb_to_flo(mrb, num));
6868 }
6969
7070 static mrb_value
9494 d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y));
9595 if (both_int && FIXABLE(d))
9696 return mrb_fixnum_value((mrb_int)d);
97 return mrb_float_value(d);
97 return mrb_float_value(mrb, d);
9898 }
9999
100100 /* 15.2.8.3.4 */
111111 mrb_value
112112 mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
113113 {
114 return mrb_float_value(mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
114 return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
115115 }
116116
117117 /* 15.2.9.3.19(x) */
128128 mrb_float y;
129129
130130 mrb_get_args(mrb, "f", &y);
131 return mrb_float_value(mrb_to_flo(mrb, x) / y);
131 return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y);
132132 }
133133
134134 /*
296296 mrb_value y;
297297
298298 mrb_get_args(mrb, "o", &y);
299 return mrb_float_value(mrb_float(x) - mrb_to_flo(mrb, y));
299 return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y));
300300 }
301301
302302 /* 15.2.9.3.3 */
314314 mrb_value y;
315315
316316 mrb_get_args(mrb, "o", &y);
317 return mrb_float_value(mrb_float(x) * mrb_to_flo(mrb, y));
317 return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y));
318318 }
319319
320320 static void
365365
366366 fy = mrb_to_flo(mrb, y);
367367 flodivmod(mrb, mrb_float(x), fy, 0, &mod);
368 return mrb_float_value(mod);
368 return mrb_float_value(mrb, mod);
369369 }
370370
371371 /* 15.2.8.3.16 */
544544 mrb_float f = floor(mrb_float(num));
545545
546546 if (!FIXABLE(f)) {
547 return mrb_float_value(f);
547 return mrb_float_value(mrb, f);
548548 }
549549 return mrb_fixnum_value((mrb_int)f);
550550 }
569569 mrb_float f = ceil(mrb_float(num));
570570
571571 if (!FIXABLE(f)) {
572 return mrb_float_value(f);
572 return mrb_float_value(mrb, f);
573573 }
574574 return mrb_fixnum_value((mrb_int)f);
575575 }
641641 if (ndigits < 0) number *= f;
642642 else number /= f;
643643 }
644 if (ndigits > 0) return mrb_float_value(number);
644 if (ndigits > 0) return mrb_float_value(mrb, number);
645645 return mrb_fixnum_value((mrb_int)number);
646646 }
647647
665665 if (f < 0.0) f = ceil(f);
666666
667667 if (!FIXABLE(f)) {
668 return mrb_float_value(f);
668 return mrb_float_value(mrb, f);
669669 }
670670 return mrb_fixnum_value((mrb_int)f);
671671 }
749749 return mrb_fixnum_value(a*b);
750750 c = a * b;
751751 if (a != 0 && c/a != b) {
752 return mrb_float_value((mrb_float)a*(mrb_float)b);
752 return mrb_float_value(mrb, (mrb_float)a*(mrb_float)b);
753753 }
754754 return mrb_fixnum_value(c);;
755755 }
756 return mrb_float_value((mrb_float)a * mrb_to_flo(mrb, y));
756 return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y));
757757 }
758758
759759 /* 15.2.8.3.3 */
825825 mrb_int mod;
826826
827827 if (mrb_fixnum(y) == 0) {
828 return mrb_float_value(str_to_mrb_float("nan"));
828 return mrb_float_value(mrb, str_to_mrb_float("nan"));
829829 }
830830 fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod);
831831 return mrb_fixnum_value(mod);
834834 mrb_float mod;
835835
836836 flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod);
837 return mrb_float_value(mod);
837 return mrb_float_value(mrb, mod);
838838 }
839839 }
840840
855855 mrb_int div, mod;
856856
857857 if (mrb_fixnum(y) == 0) {
858 return mrb_assoc_new(mrb, mrb_float_value(str_to_mrb_float("inf")),
859 mrb_float_value(str_to_mrb_float("nan")));
858 return mrb_assoc_new(mrb, mrb_float_value(mrb, str_to_mrb_float("inf")),
859 mrb_float_value(mrb, str_to_mrb_float("nan")));
860860 }
861861 fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod);
862862 return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod));
866866 mrb_value a, b;
867867
868868 flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod);
869 a = mrb_float_value((mrb_int)div);
870 b = mrb_float_value(mod);
869 a = mrb_float_value(mrb, (mrb_int)div);
870 b = mrb_float_value(mrb, mod);
871871 return mrb_assoc_new(mrb, a, b);
872872 }
873873 }
11201120
11211121 val = (mrb_float)mrb_fixnum(num);
11221122
1123 return mrb_float_value(val);
1123 return mrb_float_value(mrb, val);
11241124 }
11251125
11261126 /*
11741174 c = a + b;
11751175 if (((a < 0) ^ (b < 0)) == 0 && (a < 0) != (c < 0)) {
11761176 /* integer overflow */
1177 return mrb_float_value((mrb_float)a + (mrb_float)b);
1177 return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b);
11781178 }
11791179 return mrb_fixnum_value(c);
11801180 }
1181 return mrb_float_value((mrb_float)a + mrb_to_flo(mrb, y));
1181 return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y));
11821182 }
11831183
11841184 /* 15.2.8.3.1 */
12121212 c = a - b;
12131213 if (((a < 0) ^ (b < 0)) != 0 && (a < 0) != (c < 0)) {
12141214 /* integer overflow */
1215 return mrb_float_value((mrb_float)a - (mrb_float)b);
1215 return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b);
12161216 }
12171217 return mrb_fixnum_value(c);
12181218 }
1219 return mrb_float_value((mrb_float)a - mrb_to_flo(mrb, y));
1219 return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y));
12201220 }
12211221
12221222 /* 15.2.8.3.2 */
13461346 x = mrb_float(self);
13471347 mrb_get_args(mrb, "f", &y);
13481348
1349 return mrb_float_value(x + y);
1349 return mrb_float_value(mrb, x + y);
13501350 }
13511351 /* ------------------------------------------------------------------------*/
13521352 void
570570 }
571571 switch (mrb_type(val)) {
572572 case MRB_TT_FIXNUM:
573 return mrb_float_value((mrb_float)mrb_fixnum(val));
573 return mrb_float_value(mrb, (mrb_float)mrb_fixnum(val));
574574
575575 case MRB_TT_FLOAT:
576576 return val;
577577
578578 case MRB_TT_STRING:
579 return mrb_float_value(mrb_str_to_dbl(mrb, val, TRUE));
579 return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE));
580580
581581 default:
582582 return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f");
22212221 static mrb_value
22222222 mrb_str_to_f(mrb_state *mrb, mrb_value self)
22232223 {
2224 return mrb_float_value(mrb_str_to_dbl(mrb, self, 0/*Qfalse*/));
2224 return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, 0/*Qfalse*/));
22252225 }
22262226
22272227 /* 15.2.10.5.40 */
3838 #define SET_SYM_VALUE(r,v) MRB_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
3939 #define SET_OBJ_VALUE(r,v) MRB_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
4040 #ifdef MRB_NAN_BOXING
41 #define SET_FLT_VALUE(r,v) r.f = (v)
41 #define SET_FLT_VALUE(mrb,r,v) r.f = (v)
42 #elif defined(MRB_WORD_BOXING)
43 #define SET_FLT_VALUE(mrb,r,v) r = mrb_float_value(mrb, (v))
4244 #else
43 #define SET_FLT_VALUE(r,v) MRB_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
45 #define SET_FLT_VALUE(mrb,r,v) MRB_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
4446 #endif
4547
4648 #define STACK_INIT_SIZE 128
12421244
12431245 L_RAISE:
12441246 ci = mrb->c->ci;
1245 mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(pc));
1247 mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb, pc));
12461248 mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->c->cibase));
12471249 eidx = ci->eidx;
12481250 if (ci == mrb->c->cibase) {
14401442 #define attr_i value.i
14411443 #ifdef MRB_NAN_BOXING
14421444 #define attr_f f
1445 #elif defined(MRB_WORD_BOXING)
1446 #define attr_f value.fp->f
14431447 #else
14441448 #define attr_f value.f
14451449 #endif
14631467 x = mrb_fixnum(regs_a[0]);
14641468 y = mrb_fixnum(regs_a[1]);
14651469 z = x + y;
1470 #ifdef MRB_WORD_BOXING
1471 z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT);
1472 #endif
14661473 if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) == 0) {
14671474 /* integer overflow */
1468 SET_FLT_VALUE(regs_a[0], (mrb_float)x + (mrb_float)y);
1475 SET_FLT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
1476 break;
14691477 }
1470 else {
1471 regs_a[0].attr_i = z;
1472 }
1478 SET_INT_VALUE(regs[a], z);
14731479 }
14741480 break;
14751481 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
14761482 {
14771483 mrb_int x = mrb_fixnum(regs[a]);
14781484 mrb_float y = mrb_float(regs[a+1]);
1479 SET_FLT_VALUE(regs[a], (mrb_float)x + y);
1485 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x + y);
14801486 }
14811487 break;
14821488 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
1489 #ifdef MRB_WORD_BOXING
1490 {
1491 mrb_float x = mrb_float(regs[a]);
1492 mrb_int y = mrb_fixnum(regs[a+1]);
1493 SET_FLT_VALUE(mrb, regs[a], x + y);
1494 }
1495 #else
14831496 OP_MATH_BODY(+,attr_f,attr_i);
1497 #endif
14841498 break;
14851499 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
1500 #ifdef MRB_WORD_BOXING
1501 {
1502 mrb_float x = mrb_float(regs[a]);
1503 mrb_float y = mrb_float(regs[a+1]);
1504 SET_FLT_VALUE(mrb, regs[a], x + y);
1505 }
1506 #else
14861507 OP_MATH_BODY(+,attr_f,attr_f);
1508 #endif
14871509 break;
14881510 case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
14891511 regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
15081530 x = mrb_fixnum(regs[a]);
15091531 y = mrb_fixnum(regs[a+1]);
15101532 z = x - y;
1533 #ifdef MRB_WORD_BOXING
1534 z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT);
1535 #endif
15111536 if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) {
15121537 /* integer overflow */
1513 SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y);
1538 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
15141539 break;
15151540 }
15161541 SET_INT_VALUE(regs[a], z);
15201545 {
15211546 mrb_int x = mrb_fixnum(regs[a]);
15221547 mrb_float y = mrb_float(regs[a+1]);
1523 SET_FLT_VALUE(regs[a], (mrb_float)x - y);
1548 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x - y);
15241549 }
15251550 break;
15261551 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
1552 #ifdef MRB_WORD_BOXING
1553 {
1554 mrb_float x = mrb_float(regs[a]);
1555 mrb_int y = mrb_fixnum(regs[a+1]);
1556 SET_FLT_VALUE(mrb, regs[a], x - y);
1557 }
1558 #else
15271559 OP_MATH_BODY(-,attr_f,attr_i);
1560 #endif
15281561 break;
15291562 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
1563 #ifdef MRB_WORD_BOXING
1564 {
1565 mrb_float x = mrb_float(regs[a]);
1566 mrb_float y = mrb_float(regs[a+1]);
1567 SET_FLT_VALUE(mrb, regs[a], x - y);
1568 }
1569 #else
15301570 OP_MATH_BODY(-,attr_f,attr_f);
1571 #endif
15311572 break;
15321573 default:
15331574 goto L_SEND;
15481589 x = mrb_fixnum(regs[a]);
15491590 y = mrb_fixnum(regs[a+1]);
15501591 z = x * y;
1592 #ifdef MRB_WORD_BOXING
1593 z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT);
1594 #endif
15511595 if (x != 0 && z/x != y) {
1552 SET_FLT_VALUE(regs[a], (mrb_float)x * (mrb_float)y);
1596 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
15531597 }
15541598 else {
15551599 SET_INT_VALUE(regs[a], z);
15601604 {
15611605 mrb_int x = mrb_fixnum(regs[a]);
15621606 mrb_float y = mrb_float(regs[a+1]);
1563 SET_FLT_VALUE(regs[a], (mrb_float)x * y);
1607 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x * y);
15641608 }
15651609 break;
15661610 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
1611 #ifdef MRB_WORD_BOXING
1612 {
1613 mrb_float x = mrb_float(regs[a]);
1614 mrb_int y = mrb_fixnum(regs[a+1]);
1615 SET_FLT_VALUE(mrb, regs[a], x * y);
1616 }
1617 #else
15671618 OP_MATH_BODY(*,attr_f,attr_i);
1619 #endif
15681620 break;
15691621 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
1622 #ifdef MRB_WORD_BOXING
1623 {
1624 mrb_float x = mrb_float(regs[a]);
1625 mrb_float y = mrb_float(regs[a+1]);
1626 SET_FLT_VALUE(mrb, regs[a], x * y);
1627 }
1628 #else
15701629 OP_MATH_BODY(*,attr_f,attr_f);
1630 #endif
15711631 break;
15721632 default:
15731633 goto L_SEND;
15851645 {
15861646 mrb_int x = mrb_fixnum(regs[a]);
15871647 mrb_int y = mrb_fixnum(regs[a+1]);
1588 SET_FLT_VALUE(regs[a], (mrb_float)x / (mrb_float)y);
1648 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y);
15891649 }
15901650 break;
15911651 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
15921652 {
15931653 mrb_int x = mrb_fixnum(regs[a]);
15941654 mrb_float y = mrb_float(regs[a+1]);
1595 SET_FLT_VALUE(regs[a], (mrb_float)x / y);
1655 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x / y);
15961656 }
15971657 break;
15981658 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
1659 #ifdef MRB_WORD_BOXING
1660 {
1661 mrb_float x = mrb_float(regs[a]);
1662 mrb_int y = mrb_fixnum(regs[a+1]);
1663 SET_FLT_VALUE(mrb, regs[a], x / y);
1664 }
1665 #else
15991666 OP_MATH_BODY(/,attr_f,attr_i);
1667 #endif
16001668 break;
16011669 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
1670 #ifdef MRB_WORD_BOXING
1671 {
1672 mrb_float x = mrb_float(regs[a]);
1673 mrb_float y = mrb_float(regs[a+1]);
1674 SET_FLT_VALUE(mrb, regs[a], x / y);
1675 }
1676 #else
16021677 OP_MATH_BODY(/,attr_f,attr_f);
1678 #endif
16031679 break;
16041680 default:
16051681 goto L_SEND;
16211697
16221698 if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) {
16231699 /* integer overflow */
1624 SET_FLT_VALUE(regs[a], (mrb_float)x + (mrb_float)y);
1700 SET_FLT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
16251701 break;
16261702 }
16271703 regs[a].attr_i = z;
16281704 }
16291705 break;
16301706 case MRB_TT_FLOAT:
1707 #ifdef MRB_WORD_BOXING
1708 {
1709 mrb_float x = mrb_float(regs[a]);
1710 SET_FLT_VALUE(mrb, regs[a], x + GETARG_C(i));
1711 }
1712 #else
16311713 regs[a].attr_f += GETARG_C(i);
1714 #endif
16321715 break;
16331716 default:
16341717 SET_INT_VALUE(regs[a+1], GETARG_C(i));
16531736
16541737 if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) != 0) {
16551738 /* integer overflow */
1656 SET_FLT_VALUE(regs_a[0], (mrb_float)x - (mrb_float)y);
1739 SET_FLT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
16571740 }
16581741 else {
16591742 regs_a[0].attr_i = z;
16611744 }
16621745 break;
16631746 case MRB_TT_FLOAT:
1747 #ifdef MRB_WORD_BOXING
1748 {
1749 mrb_float x = mrb_float(regs[a]);
1750 SET_FLT_VALUE(mrb, regs[a], x - GETARG_C(i));
1751 }
1752 #else
16641753 regs_a[0].attr_f -= GETARG_C(i);
1754 #endif
16651755 break;
16661756 default:
16671757 SET_INT_VALUE(regs_a[1], GETARG_C(i));