Commit ec3a5f33 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #1266 from kimushu/feature/word-boxing

Add MRB_WORD_BOXING mode (represent mrb_value as a word)
parents d78f23d2 e720782f
......@@ -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
......
......@@ -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*);
......
......@@ -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)
......
......@@ -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));
......
......@@ -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));
}
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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:
......
......@@ -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
......
......@@ -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");
......
......@@ -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));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment