diff options
| author | kimu_shu <[email protected]> | 2013-05-26 09:43:30 +0900 |
|---|---|---|
| committer | kimu_shu <[email protected]> | 2013-05-26 10:09:17 +0900 |
| commit | e720782f815b809a692818851582be019afe52a9 (patch) | |
| tree | a3c25239fb5afe2a33708e38d185a142f1c543a3 | |
| parent | d78f23d28b4706e58622493de60e17818b491fde (diff) | |
| download | mruby-e720782f815b809a692818851582be019afe52a9.tar.gz mruby-e720782f815b809a692818851582be019afe52a9.zip | |
Add MRB_WORD_BOXING mode (represent mrb_value as a word)
| -rw-r--r-- | include/mrbconf.h | 3 | ||||
| -rw-r--r-- | include/mruby.h | 4 | ||||
| -rw-r--r-- | include/mruby/value.h | 262 | ||||
| -rw-r--r-- | mrbgems/mruby-math/src/math.c | 60 | ||||
| -rw-r--r-- | mrbgems/mruby-random/src/random.c | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-time/src/time.c | 4 | ||||
| -rw-r--r-- | src/codegen.c | 8 | ||||
| -rw-r--r-- | src/etc.c | 22 | ||||
| -rw-r--r-- | src/gc.c | 8 | ||||
| -rw-r--r-- | src/kernel.c | 2 | ||||
| -rw-r--r-- | src/load.c | 2 | ||||
| -rw-r--r-- | src/numeric.c | 50 | ||||
| -rw-r--r-- | src/object.c | 4 | ||||
| -rw-r--r-- | src/string.c | 2 | ||||
| -rw-r--r-- | src/vm.c | 122 |
15 files changed, 411 insertions, 146 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h index 2b9cc5e60..0d65ae13a 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -26,6 +26,9 @@ /* define on big endian machines; used by MRB_NAN_BOXING */ //#define MRB_ENDIAN_BIG +/* represent mrb_value as a word (natural unit of data for the processor) */ +// #define MRB_WORD_BOXING + /* argv max size in mrb_funcall */ //#define MRB_FUNCALL_ARGC_MAX 16 diff --git a/include/mruby.h b/include/mruby.h index fac7e6fcd..f9f448b45 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -273,11 +273,11 @@ int mrb_gc_arena_save(mrb_state*); void mrb_gc_arena_restore(mrb_state*,int); void mrb_gc_mark(mrb_state*,struct RBasic*); #define mrb_gc_mark_value(mrb,val) do {\ - if (mrb_type(val) >= MRB_TT_OBJECT) mrb_gc_mark((mrb), mrb_basic_ptr(val));\ + if (mrb_type(val) >= MRB_TT_HAS_BASIC) mrb_gc_mark((mrb), mrb_basic_ptr(val));\ } while (0) void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*); #define mrb_field_write_barrier_value(mrb, obj, val) do{\ - if ((val.tt >= MRB_TT_OBJECT)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val));\ + if ((val.tt >= MRB_TT_HAS_BASIC)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val));\ } while (0) void mrb_write_barrier(mrb_state *, struct RBasic*); diff --git a/include/mruby/value.h b/include/mruby/value.h index fa2a68ac8..d4030ed2d 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -8,63 +8,9 @@ #define MRUBY_VALUE_H typedef uint8_t mrb_bool; +struct mrb_state; -#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_OBJECT, /* 8 */ - MRB_TT_CLASS, /* 9 */ - MRB_TT_MODULE, /* 10 */ - MRB_TT_ICLASS, /* 11 */ - MRB_TT_SCLASS, /* 12 */ - MRB_TT_PROC, /* 13 */ - MRB_TT_ARRAY, /* 14 */ - MRB_TT_HASH, /* 15 */ - MRB_TT_STRING, /* 16 */ - MRB_TT_RANGE, /* 17 */ - MRB_TT_EXCEPTION, /* 18 */ - MRB_TT_FILE, /* 19 */ - MRB_TT_ENV, /* 20 */ - MRB_TT_DATA, /* 21 */ - MRB_TT_FIBER, /* 22 */ - MRB_TT_MAXDEFINE /* 23 */ -}; - -typedef struct mrb_value { - union { - mrb_float f; - void *p; - mrb_int i; - mrb_sym sym; - } value; - enum mrb_vtype tt; -} 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 */ +#if defined(MRB_NAN_BOXING) #ifdef MRB_USE_FLOAT # error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<---- @@ -97,6 +43,8 @@ enum mrb_vtype { MRB_TT_MAXDEFINE /* 24 */ }; +#define MRB_TT_HAS_BASIC MRB_TT_OBJECT + #ifdef MRB_ENDIAN_BIG #define MRB_ENDIAN_LOHI(a,b) a b #else @@ -130,7 +78,7 @@ typedef struct mrb_value { } while (0) static inline mrb_value -mrb_float_value(mrb_float f) +mrb_float_value(struct mrb_state *mrb, mrb_float f) { mrb_value v; @@ -142,7 +90,163 @@ mrb_float_value(mrb_float f) } return v; } -#endif /* MRB_NAN_BOXING */ + +#elif defined(MRB_WORD_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_OBJECT, /* 8 */ + MRB_TT_CLASS, /* 9 */ + MRB_TT_MODULE, /* 10 */ + MRB_TT_ICLASS, /* 11 */ + MRB_TT_SCLASS, /* 12 */ + MRB_TT_PROC, /* 13 */ + MRB_TT_ARRAY, /* 14 */ + MRB_TT_HASH, /* 15 */ + MRB_TT_STRING, /* 16 */ + MRB_TT_RANGE, /* 17 */ + MRB_TT_EXCEPTION, /* 18 */ + MRB_TT_FILE, /* 19 */ + MRB_TT_ENV, /* 20 */ + MRB_TT_DATA, /* 21 */ + MRB_TT_FIBER, /* 22 */ + MRB_TT_MAXDEFINE /* 23 */ +}; + +#define MRB_TT_HAS_BASIC MRB_TT_FLOAT + +enum mrb_special_consts { + MRB_Qnil = 0, + MRB_Qfalse = 2, + MRB_Qtrue = 4, + MRB_Qundef = 6, + + MRB_FIXNUM_FLAG = 0x01, + MRB_FIXNUM_SHIFT = 1, + MRB_SYMBOL_FLAG = 0x0e, + MRB_SPECIAL_SHIFT = 8, +}; + +typedef union mrb_value { + union { + void *p; + struct { + unsigned int i_flag : MRB_FIXNUM_SHIFT; + mrb_int i : (sizeof(mrb_int) * 8 - MRB_FIXNUM_SHIFT); + }; + struct { + unsigned int sym_flag : MRB_SPECIAL_SHIFT; + int sym : (sizeof(mrb_sym) * 8); + }; + struct RBasic *bp; + struct RFloat *fp; + struct RVoidp *vp; + } value; + unsigned long w; +} mrb_value; + +#define mrb_float(o) (o).value.fp->f + +#define MRB_SET_VALUE(o, ttt, attr, v) do {\ + (o).w = 0;\ + (o).attr = (v);\ + switch (ttt) {\ + case MRB_TT_FALSE: (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\ + case MRB_TT_TRUE: (o).w = MRB_Qtrue; break;\ + case MRB_TT_UNDEF: (o).w = MRB_Qundef; break;\ + case MRB_TT_FIXNUM: (o).value.i_flag = MRB_FIXNUM_FLAG; break;\ + case MRB_TT_SYMBOL: (o).value.sym_flag = MRB_SYMBOL_FLAG; break;\ + default: if ((o).value.bp) (o).value.bp->tt = ttt; break;\ + }\ +} while (0) + +extern mrb_value +mrb_float_value(struct mrb_state *mrb, mrb_float f); + +#else /* No MRB_xxx_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_OBJECT, /* 8 */ + MRB_TT_CLASS, /* 9 */ + MRB_TT_MODULE, /* 10 */ + MRB_TT_ICLASS, /* 11 */ + MRB_TT_SCLASS, /* 12 */ + MRB_TT_PROC, /* 13 */ + MRB_TT_ARRAY, /* 14 */ + MRB_TT_HASH, /* 15 */ + MRB_TT_STRING, /* 16 */ + MRB_TT_RANGE, /* 17 */ + MRB_TT_EXCEPTION, /* 18 */ + MRB_TT_FILE, /* 19 */ + MRB_TT_ENV, /* 20 */ + MRB_TT_DATA, /* 21 */ + MRB_TT_FIBER, /* 22 */ + MRB_TT_MAXDEFINE /* 23 */ +}; + +#define MRB_TT_HAS_BASIC MRB_TT_OBJECT + +typedef struct mrb_value { + union { + mrb_float f; + void *p; + mrb_int i; + mrb_sym sym; + } value; + enum mrb_vtype tt; +} 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(struct mrb_state *mrb, mrb_float f) +{ + mrb_value v; + + MRB_SET_VALUE(v, MRB_TT_FLOAT, value.f, f); + return v; +} +#endif /* no boxing */ + +#ifdef MRB_WORD_BOXING + +#define mrb_fixnum(o) (o).value.i +#define mrb_symbol(o) (o).value.sym +#define mrb_voidp(o) (o).value.vp->p +#define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG) +#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) +#define mrb_undef_p(o) ((o).w == MRB_Qundef) +#define mrb_nil_p(o) ((o).w == MRB_Qnil) +#define mrb_symbol_p(o) ((o).value.sym_flag == MRB_SYMBOL_FLAG) +#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_bool(o) ((o).w != MRB_Qnil && (o).w != MRB_Qfalse) +#define mrb_test(o) mrb_bool(o) + +#else #define mrb_fixnum(o) (o).value.i #define mrb_symbol(o) (o).value.sym @@ -159,6 +263,8 @@ mrb_float_value(mrb_float f) #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) #define mrb_test(o) mrb_bool(o) +#endif /* no boxing */ + #define MRB_OBJECT_HEADER \ enum mrb_vtype tt:8;\ uint32_t color:3;\ @@ -209,6 +315,39 @@ struct RFiber { struct mrb_context *cxt; }; +#ifdef MRB_WORD_BOXING +struct RFloat { + MRB_OBJECT_HEADER; + mrb_float f; +}; + +struct RVoidp { + MRB_OBJECT_HEADER; + void *p; +}; + +static inline enum mrb_vtype +mrb_type(mrb_value o) +{ + switch (o.w) { + case MRB_Qfalse: + case MRB_Qnil: + return MRB_TT_FALSE; + case MRB_Qtrue: + return MRB_TT_TRUE; + case MRB_Qundef: + return MRB_TT_UNDEF; + } + if (o.value.i_flag == MRB_FIXNUM_FLAG) { + return MRB_TT_FIXNUM; + } + if (o.value.sym_flag == MRB_SYMBOL_FLAG) { + return MRB_TT_SYMBOL; + } + return o.value.bp->tt; +} +#endif /* MRB_WORD_BOXING */ + static inline mrb_value mrb_fixnum_value(mrb_int i) { @@ -237,14 +376,19 @@ mrb_obj_value(void *p) return v; } +#ifdef MRB_WORD_BOXING +mrb_value +mrb_voidp_value(struct mrb_state *mrb, void *p); +#else static inline mrb_value -mrb_voidp_value(void *p) +mrb_voidp_value(struct mrb_state *mrb, void *p) { mrb_value v; MRB_SET_VALUE(v, MRB_TT_VOIDP, value.p, p); return v; } +#endif static inline mrb_value mrb_false_value(void) diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index 561d80178..bf3c007b4 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -108,7 +108,7 @@ math_sin(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = sin(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -126,7 +126,7 @@ math_cos(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = cos(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -143,7 +143,7 @@ math_tan(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = tan(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -164,7 +164,7 @@ math_asin(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = asin(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -181,7 +181,7 @@ math_acos(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = acos(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -198,7 +198,7 @@ math_atan(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = atan(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -228,7 +228,7 @@ math_atan2(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "ff", &x, &y); x = atan2(x, y); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } @@ -251,7 +251,7 @@ math_sinh(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = sinh(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -268,7 +268,7 @@ math_cosh(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = cosh(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -286,7 +286,7 @@ math_tanh(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = tanh(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } @@ -309,7 +309,7 @@ math_asinh(mrb_state *mrb, mrb_value obj) x = asinh(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -326,7 +326,7 @@ math_acosh(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = acosh(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -343,7 +343,7 @@ math_atanh(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = atanh(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -389,7 +389,7 @@ math_exp(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = exp(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -418,7 +418,7 @@ math_log(mrb_state *mrb, mrb_value obj) if (argc == 2) { x /= log(base); } - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -441,7 +441,7 @@ math_log2(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = log2(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -463,7 +463,7 @@ math_log10(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = log10(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -481,7 +481,7 @@ math_sqrt(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = sqrt(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } @@ -524,7 +524,7 @@ math_cbrt(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = cbrt(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } @@ -548,7 +548,7 @@ math_frexp(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = frexp(x, &exp); - return mrb_assoc_new(mrb, mrb_float_value(x), mrb_fixnum_value(exp)); + return mrb_assoc_new(mrb, mrb_float_value(mrb, x), mrb_fixnum_value(exp)); } /* @@ -569,7 +569,7 @@ math_ldexp(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "fi", &x, &i); x = ldexp(x, i); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -589,7 +589,7 @@ math_hypot(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "ff", &x, &y); x = hypot(x, y); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* @@ -606,7 +606,7 @@ math_erf(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = erf(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } @@ -624,7 +624,7 @@ math_erfc(mrb_state *mrb, mrb_value obj) mrb_get_args(mrb, "f", &x); x = erfc(x); - return mrb_float_value(x); + return mrb_float_value(mrb, x); } /* ------------------------------------------------------------------------*/ @@ -635,21 +635,21 @@ mrb_mruby_math_gem_init(mrb_state* mrb) mrb_math = mrb_define_module(mrb, "Math"); #ifdef M_PI - mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(M_PI)); + mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, M_PI)); #else - mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(atan(1.0)*4.0)); + mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, atan(1.0)*4.0)); #endif #ifdef M_E - mrb_define_const(mrb, mrb_math, "E", mrb_float_value(M_E)); + mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, M_E)); #else - mrb_define_const(mrb, mrb_math, "E", mrb_float_value(exp(1.0))); + mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0))); #endif #ifdef MRB_USE_FLOAT - mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-5)); + mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-5)); #else - mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-12)); + mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-12)); #endif mrb_define_module_function(mrb, mrb_math, "sin", math_sin, MRB_ARGS_REQ(1)); diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index b2a9926bd..13b4fa7a3 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -66,7 +66,7 @@ static mrb_value mrb_random_mt_g_rand(mrb_state *mrb, mrb_value max) mrb_value value; if (mrb_fixnum(max) == 0) { - value = mrb_float_value(mt_g_rand_real()); + value = mrb_float_value(mrb, mt_g_rand_real()); } else { value = mrb_fixnum_value(mt_g_rand() % mrb_fixnum(max)); } @@ -108,7 +108,7 @@ static mrb_value mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max) mrb_value value; if (mrb_fixnum(max) == 0) { - value = mrb_float_value(mt_rand_real(t)); + value = mrb_float_value(mrb, mt_rand_real(t)); } else { value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max)); } diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 6a44590a8..2a2aabe72 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -358,7 +358,7 @@ mrb_time_minus(mrb_state *mrb, mrb_value self) if (tm2) { f = (mrb_float)(tm->sec - tm2->sec) + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; - return mrb_float_value(f); + return mrb_float_value(mrb, f); } else { mrb_get_args(mrb, "f", &f); @@ -628,7 +628,7 @@ mrb_time_to_f(mrb_state *mrb, mrb_value self) tm = (struct mrb_time*)mrb_data_get_ptr(mrb, self, &mrb_time_type); if (!tm) return mrb_nil_value(); - return mrb_float_value((mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); + return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); } /* 15.2.19.7.25 */ diff --git a/src/codegen.c b/src/codegen.c index 581d13280..cfbbe7286 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1901,7 +1901,7 @@ codegen(codegen_scope *s, node *tree, int val) i = readint_mrb_int(s, p, base, FALSE, &overflow); if (overflow) { double f = readint_float(s, p, base); - int off = new_lit(s, mrb_float_value(f)); + int off = new_lit(s, mrb_float_value(s->mrb, f)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); } @@ -1923,7 +1923,7 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { char *p = (char*)tree; mrb_float f = str_to_mrb_float(p); - int off = new_lit(s, mrb_float_value(f)); + int off = new_lit(s, mrb_float_value(s->mrb, f)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); push(); @@ -1939,7 +1939,7 @@ codegen(codegen_scope *s, node *tree, int val) { char *p = (char*)tree; mrb_float f = str_to_mrb_float(p); - int off = new_lit(s, mrb_float_value(-f)); + int off = new_lit(s, mrb_float_value(s->mrb, -f)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); push(); @@ -1957,7 +1957,7 @@ codegen(codegen_scope *s, node *tree, int val) i = readint_mrb_int(s, p, base, TRUE, &overflow); if (overflow) { double f = readint_float(s, p, base); - int off = new_lit(s, mrb_float_value(-f)); + int off = new_lit(s, mrb_float_value(s->mrb, -f)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); } @@ -180,3 +180,25 @@ mrb_obj_id(mrb_value obj) } } +#ifdef MRB_WORD_BOXING +mrb_value +mrb_float_value(mrb_state *mrb, mrb_float f) +{ + mrb_value v; + + v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class); + v.value.fp->f = f; + return v; +} + +mrb_value +mrb_voidp_value(mrb_state *mrb, void *p) +{ + mrb_value v; + + v.value.p = mrb_obj_alloc(mrb, MRB_TT_VOIDP, mrb->object_class); + v.value.vp->p = p; + return v; +} +#endif /* MRB_WORD_BOXING */ + @@ -530,10 +530,16 @@ obj_free(mrb_state *mrb, struct RBasic *obj) case MRB_TT_TRUE: case MRB_TT_FIXNUM: case MRB_TT_SYMBOL: - case MRB_TT_FLOAT: /* cannot happen */ return; + case MRB_TT_FLOAT: +#ifdef MRB_WORD_BOXING + break; +#else + return; +#endif + case MRB_TT_OBJECT: mrb_gc_free_iv(mrb, (struct RObject*)obj); break; diff --git a/src/kernel.c b/src/kernel.c index af4806378..0fe374e73 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -894,7 +894,7 @@ mrb_f_raise(mrb_state *mrb, mrb_value self) /* fall through */ default: exc = mrb_make_exception(mrb, argc, a); - mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb->c->ci->pc)); + mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb, mrb->c->ci->pc)); mrb_exc_raise(mrb, exc); break; } diff --git a/src/load.c b/src/load.c index 81d47858a..62010e425 100644 --- a/src/load.c +++ b/src/load.c @@ -130,7 +130,7 @@ read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len) break; case MRB_TT_FLOAT: - irep->pool[i] = mrb_float_value(mrb_str_to_dbl(mrb, s, FALSE)); + irep->pool[i] = mrb_float_value(mrb, mrb_str_to_dbl(mrb, s, FALSE)); break; case MRB_TT_STRING: diff --git a/src/numeric.c b/src/numeric.c index 14b4929e0..6b118dfb4 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -65,7 +65,7 @@ num_uplus(mrb_state *mrb, mrb_value num) static mrb_value num_uminus(mrb_state *mrb, mrb_value num) { - return mrb_float_value((mrb_float)0 - mrb_to_flo(mrb, num)); + return mrb_float_value(mrb, (mrb_float)0 - mrb_to_flo(mrb, num)); } static mrb_value @@ -95,7 +95,7 @@ num_pow(mrb_state *mrb, mrb_value x) d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); if (both_int && FIXABLE(d)) return mrb_fixnum_value((mrb_int)d); - return mrb_float_value(d); + return mrb_float_value(mrb, d); } /* 15.2.8.3.4 */ @@ -112,7 +112,7 @@ num_pow(mrb_state *mrb, mrb_value x) mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) { - return mrb_float_value(mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); } /* 15.2.9.3.19(x) */ @@ -129,7 +129,7 @@ num_div(mrb_state *mrb, mrb_value x) mrb_float y; mrb_get_args(mrb, "f", &y); - return mrb_float_value(mrb_to_flo(mrb, x) / y); + return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); } /* @@ -297,7 +297,7 @@ flo_minus(mrb_state *mrb, mrb_value x) mrb_value y; mrb_get_args(mrb, "o", &y); - return mrb_float_value(mrb_float(x) - mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y)); } /* 15.2.9.3.3 */ @@ -315,7 +315,7 @@ flo_mul(mrb_state *mrb, mrb_value x) mrb_value y; mrb_get_args(mrb, "o", &y); - return mrb_float_value(mrb_float(x) * mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); } static void @@ -366,7 +366,7 @@ flo_mod(mrb_state *mrb, mrb_value x) fy = mrb_to_flo(mrb, y); flodivmod(mrb, mrb_float(x), fy, 0, &mod); - return mrb_float_value(mod); + return mrb_float_value(mrb, mod); } /* 15.2.8.3.16 */ @@ -545,7 +545,7 @@ flo_floor(mrb_state *mrb, mrb_value num) mrb_float f = floor(mrb_float(num)); if (!FIXABLE(f)) { - return mrb_float_value(f); + return mrb_float_value(mrb, f); } return mrb_fixnum_value((mrb_int)f); } @@ -570,7 +570,7 @@ flo_ceil(mrb_state *mrb, mrb_value num) mrb_float f = ceil(mrb_float(num)); if (!FIXABLE(f)) { - return mrb_float_value(f); + return mrb_float_value(mrb, f); } return mrb_fixnum_value((mrb_int)f); } @@ -642,7 +642,7 @@ flo_round(mrb_state *mrb, mrb_value num) if (ndigits < 0) number *= f; else number /= f; } - if (ndigits > 0) return mrb_float_value(number); + if (ndigits > 0) return mrb_float_value(mrb, number); return mrb_fixnum_value((mrb_int)number); } @@ -666,7 +666,7 @@ flo_truncate(mrb_state *mrb, mrb_value num) if (f < 0.0) f = ceil(f); if (!FIXABLE(f)) { - return mrb_float_value(f); + return mrb_float_value(mrb, f); } return mrb_fixnum_value((mrb_int)f); } @@ -750,11 +750,11 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) return mrb_fixnum_value(a*b); c = a * b; if (a != 0 && c/a != b) { - return mrb_float_value((mrb_float)a*(mrb_float)b); + return mrb_float_value(mrb, (mrb_float)a*(mrb_float)b); } return mrb_fixnum_value(c);; } - return mrb_float_value((mrb_float)a * mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); } /* 15.2.8.3.3 */ @@ -826,7 +826,7 @@ fix_mod(mrb_state *mrb, mrb_value x) mrb_int mod; if (mrb_fixnum(y) == 0) { - return mrb_float_value(str_to_mrb_float("nan")); + return mrb_float_value(mrb, str_to_mrb_float("nan")); } fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod); return mrb_fixnum_value(mod); @@ -835,7 +835,7 @@ fix_mod(mrb_state *mrb, mrb_value x) mrb_float mod; flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); - return mrb_float_value(mod); + return mrb_float_value(mrb, mod); } } @@ -856,8 +856,8 @@ fix_divmod(mrb_state *mrb, mrb_value x) mrb_int div, mod; if (mrb_fixnum(y) == 0) { - return mrb_assoc_new(mrb, mrb_float_value(str_to_mrb_float("inf")), - mrb_float_value(str_to_mrb_float("nan"))); + return mrb_assoc_new(mrb, mrb_float_value(mrb, str_to_mrb_float("inf")), + mrb_float_value(mrb, str_to_mrb_float("nan"))); } fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); @@ -867,8 +867,8 @@ fix_divmod(mrb_state *mrb, mrb_value x) mrb_value a, b; flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod); - a = mrb_float_value((mrb_int)div); - b = mrb_float_value(mod); + a = mrb_float_value(mrb, (mrb_int)div); + b = mrb_float_value(mrb, mod); return mrb_assoc_new(mrb, a, b); } } @@ -1121,7 +1121,7 @@ fix_to_f(mrb_state *mrb, mrb_value num) val = (mrb_float)mrb_fixnum(num); - return mrb_float_value(val); + return mrb_float_value(mrb, val); } /* @@ -1175,11 +1175,11 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) c = a + b; if (((a < 0) ^ (b < 0)) == 0 && (a < 0) != (c < 0)) { /* integer overflow */ - return mrb_float_value((mrb_float)a + (mrb_float)b); + return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); } return mrb_fixnum_value(c); } - return mrb_float_value((mrb_float)a + mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); } /* 15.2.8.3.1 */ @@ -1213,11 +1213,11 @@ mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) c = a - b; if (((a < 0) ^ (b < 0)) != 0 && (a < 0) != (c < 0)) { /* integer overflow */ - return mrb_float_value((mrb_float)a - (mrb_float)b); + return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); } return mrb_fixnum_value(c); } - return mrb_float_value((mrb_float)a - mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); } /* 15.2.8.3.2 */ @@ -1347,7 +1347,7 @@ flo_plus(mrb_state *mrb, mrb_value self) x = mrb_float(self); mrb_get_args(mrb, "f", &y); - return mrb_float_value(x + y); + return mrb_float_value(mrb, x + y); } /* ------------------------------------------------------------------------*/ void diff --git a/src/object.c b/src/object.c index 09dfba41e..a2162f77f 100644 --- a/src/object.c +++ b/src/object.c @@ -571,13 +571,13 @@ mrb_Float(mrb_state *mrb, mrb_value val) } switch (mrb_type(val)) { case MRB_TT_FIXNUM: - return mrb_float_value((mrb_float)mrb_fixnum(val)); + return mrb_float_value(mrb, (mrb_float)mrb_fixnum(val)); case MRB_TT_FLOAT: return val; case MRB_TT_STRING: - return mrb_float_value(mrb_str_to_dbl(mrb, val, TRUE)); + return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE)); default: return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f"); diff --git a/src/string.c b/src/string.c index 9bc178499..77f81ecc6 100644 --- a/src/string.c +++ b/src/string.c @@ -2222,7 +2222,7 @@ mrb_str_to_dbl(mrb_state *mrb, mrb_value str, int badcheck) static mrb_value mrb_str_to_f(mrb_state *mrb, mrb_value self) { - return mrb_float_value(mrb_str_to_dbl(mrb, self, 0/*Qfalse*/)); + return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, 0/*Qfalse*/)); } /* 15.2.10.5.40 */ @@ -39,9 +39,11 @@ void abort(void); #define SET_SYM_VALUE(r,v) MRB_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) #define SET_OBJ_VALUE(r,v) MRB_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v)) #ifdef MRB_NAN_BOXING -#define SET_FLT_VALUE(r,v) r.f = (v) +#define SET_FLT_VALUE(mrb,r,v) r.f = (v) +#elif defined(MRB_WORD_BOXING) +#define SET_FLT_VALUE(mrb,r,v) r = mrb_float_value(mrb, (v)) #else -#define SET_FLT_VALUE(r,v) MRB_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v)) +#define SET_FLT_VALUE(mrb,r,v) MRB_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v)) #endif #define STACK_INIT_SIZE 128 @@ -1243,7 +1245,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) L_RAISE: ci = mrb->c->ci; - mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(pc)); + mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb, pc)); mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->c->cibase)); eidx = ci->eidx; if (ci == mrb->c->cibase) { @@ -1441,6 +1443,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) #define attr_i value.i #ifdef MRB_NAN_BOXING #define attr_f f +#elif defined(MRB_WORD_BOXING) +#define attr_f value.fp->f #else #define attr_f value.f #endif @@ -1464,27 +1468,45 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) x = mrb_fixnum(regs_a[0]); y = mrb_fixnum(regs_a[1]); z = x + y; +#ifdef MRB_WORD_BOXING + z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT); +#endif if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) == 0) { /* integer overflow */ - SET_FLT_VALUE(regs_a[0], (mrb_float)x + (mrb_float)y); - } - else { - regs_a[0].attr_i = z; + SET_FLT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); + break; } + SET_INT_VALUE(regs[a], z); } break; case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): { mrb_int x = mrb_fixnum(regs[a]); mrb_float y = mrb_float(regs[a+1]); - SET_FLT_VALUE(regs[a], (mrb_float)x + y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x + y); } break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x + y); + } +#else OP_MATH_BODY(+,attr_f,attr_i); +#endif break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x + y); + } +#else OP_MATH_BODY(+,attr_f,attr_f); +#endif break; case TYPES2(MRB_TT_STRING,MRB_TT_STRING): regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); @@ -1509,9 +1531,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) x = mrb_fixnum(regs[a]); y = mrb_fixnum(regs[a+1]); z = x - y; +#ifdef MRB_WORD_BOXING + z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT); +#endif if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) { /* integer overflow */ - SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); break; } SET_INT_VALUE(regs[a], z); @@ -1521,14 +1546,30 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) { mrb_int x = mrb_fixnum(regs[a]); mrb_float y = mrb_float(regs[a+1]); - SET_FLT_VALUE(regs[a], (mrb_float)x - y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x - y); } break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x - y); + } +#else OP_MATH_BODY(-,attr_f,attr_i); +#endif break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x - y); + } +#else OP_MATH_BODY(-,attr_f,attr_f); +#endif break; default: goto L_SEND; @@ -1549,8 +1590,11 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) x = mrb_fixnum(regs[a]); y = mrb_fixnum(regs[a+1]); z = x * y; +#ifdef MRB_WORD_BOXING + z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT); +#endif if (x != 0 && z/x != y) { - SET_FLT_VALUE(regs[a], (mrb_float)x * (mrb_float)y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); } else { SET_INT_VALUE(regs[a], z); @@ -1561,14 +1605,30 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) { mrb_int x = mrb_fixnum(regs[a]); mrb_float y = mrb_float(regs[a+1]); - SET_FLT_VALUE(regs[a], (mrb_float)x * y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x * y); } break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x * y); + } +#else OP_MATH_BODY(*,attr_f,attr_i); +#endif break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x * y); + } +#else OP_MATH_BODY(*,attr_f,attr_f); +#endif break; default: goto L_SEND; @@ -1586,21 +1646,37 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) { mrb_int x = mrb_fixnum(regs[a]); mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLT_VALUE(regs[a], (mrb_float)x / (mrb_float)y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y); } break; case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): { mrb_int x = mrb_fixnum(regs[a]); mrb_float y = mrb_float(regs[a+1]); - SET_FLT_VALUE(regs[a], (mrb_float)x / y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x / y); } break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_int y = mrb_fixnum(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x / y); + } +#else OP_MATH_BODY(/,attr_f,attr_i); +#endif break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + mrb_float y = mrb_float(regs[a+1]); + SET_FLT_VALUE(mrb, regs[a], x / y); + } +#else OP_MATH_BODY(/,attr_f,attr_f); +#endif break; default: goto L_SEND; @@ -1622,14 +1698,21 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { /* integer overflow */ - SET_FLT_VALUE(regs[a], (mrb_float)x + (mrb_float)y); + SET_FLT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); break; } regs[a].attr_i = z; } break; case MRB_TT_FLOAT: +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + SET_FLT_VALUE(mrb, regs[a], x + GETARG_C(i)); + } +#else regs[a].attr_f += GETARG_C(i); +#endif break; default: SET_INT_VALUE(regs[a+1], GETARG_C(i)); @@ -1654,7 +1737,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) != 0) { /* integer overflow */ - SET_FLT_VALUE(regs_a[0], (mrb_float)x - (mrb_float)y); + SET_FLT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y); } else { regs_a[0].attr_i = z; @@ -1662,7 +1745,14 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) } break; case MRB_TT_FLOAT: +#ifdef MRB_WORD_BOXING + { + mrb_float x = mrb_float(regs[a]); + SET_FLT_VALUE(mrb, regs[a], x - GETARG_C(i)); + } +#else regs_a[0].attr_f -= GETARG_C(i); +#endif break; default: SET_INT_VALUE(regs_a[1], GETARG_C(i)); |
