summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mrbconf.h3
-rw-r--r--include/mruby.h4
-rw-r--r--include/mruby/value.h262
-rw-r--r--mrbgems/mruby-math/src/math.c60
-rw-r--r--mrbgems/mruby-random/src/random.c4
-rw-r--r--mrbgems/mruby-time/src/time.c4
-rw-r--r--src/codegen.c8
-rw-r--r--src/etc.c22
-rw-r--r--src/gc.c8
-rw-r--r--src/kernel.c2
-rw-r--r--src/load.c2
-rw-r--r--src/numeric.c50
-rw-r--r--src/object.c4
-rw-r--r--src/string.c2
-rw-r--r--src/vm.c122
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));
}
diff --git a/src/etc.c b/src/etc.c
index f2ff34fec..2aee0f0f7 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -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 */
+
diff --git a/src/gc.c b/src/gc.c
index 00ddadffc..6419726eb 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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 */
diff --git a/src/vm.c b/src/vm.c
index 9d615e50f..38e3cd6ed 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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));