diff options
| -rw-r--r-- | include/mrbconf.h | 3 | ||||
| -rw-r--r-- | include/mruby/boxing_word.h | 63 | ||||
| -rw-r--r-- | src/etc.c | 17 | ||||
| -rw-r--r-- | src/symbol.c | 4 |
4 files changed, 79 insertions, 8 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h index 5d54a1c22..7b29cb0ba 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -42,6 +42,9 @@ #error Cannot define MRB_USE_FLOAT32 and MRB_NO_FLOAT at the same time #endif +/* if defined mruby allocates Float objects in the heap to keep full precision if needed */ +//#define MRB_USE_FLOAT_FULL_PRECISION + /* add -DMRB_NO_METHOD_CACHE to disable method cache to save memory */ //#define MRB_NO_METHOD_CACHE /* size of the method cache (need to be the power of 2) */ diff --git a/include/mruby/boxing_word.h b/include/mruby/boxing_word.h index e64eb815e..4b80fd6c5 100644 --- a/include/mruby/boxing_word.h +++ b/include/mruby/boxing_word.h @@ -7,7 +7,11 @@ #ifndef MRUBY_BOXING_WORD_H #define MRUBY_BOXING_WORD_H -#ifndef MRB_NO_FLOAT +#if defined(MRB_32BIT) && !defined(MRB_USE_FLOAT_FULL_PRECISION) && !defined(MRB_USE_FLOAT32) +# define MRB_USE_FLOAT_FULL_PRECISION +#endif + +#if !defined(MRB_NO_FLOAT) && defined(MRB_USE_FLOAT_FULL_PRECISION) struct RFloat { MRB_OBJECT_HEADER; mrb_float f; @@ -46,15 +50,22 @@ enum mrb_special_consts { #define BOXWORD_FIXNUM_FLAG (1 << (BOXWORD_FIXNUM_BIT_POS - 1)) #define BOXWORD_FIXNUM_MASK ((1 << BOXWORD_FIXNUM_BIT_POS) - 1) -#ifdef MRB_64BIT -#define BOXWORD_SYMBOL_SHIFT 32 -#define BOXWORD_SYMBOL_FLAG 0x34 -#define BOXWORD_SYMBOL_MASK 0x3f -#else +#if defined(MRB_USE_FLOAT_FULL_PRECISION) +/* floats are allocated in heaps */ #define BOXWORD_SYMBOL_BIT_POS 2 #define BOXWORD_SYMBOL_SHIFT BOXWORD_SYMBOL_BIT_POS #define BOXWORD_SYMBOL_FLAG (1 << (BOXWORD_SYMBOL_BIT_POS - 1)) #define BOXWORD_SYMBOL_MASK ((1 << BOXWORD_SYMBOL_BIT_POS) - 1) +#else +#define BOXWORD_FLOAT_FLAG 2 +#define BOXWORD_FLOAT_MASK 3 +#if defined(MRB_64BIT) +#define BOXWORD_SYMBOL_SHIFT 32 +#else /* MRB_32BIT */ +#define BOXWORD_SYMBOL_SHIFT 5 +#endif +#define BOXWORD_SYMBOL_FLAG 0x1c +#define BOXWORD_SYMBOL_MASK 0x1f #endif #define BOXWORD_IMMEDIATE_MASK 0x07 @@ -69,12 +80,34 @@ enum mrb_special_consts { /* * mrb_value representation: * + * 64bit word with inline float: + * nil : ...0000 0000 (all bits are 0) + * false : ...0000 0100 (mrb_fixnum(v) != 0) + * true : ...0000 1100 + * undef : ...0001 0100 + * symbol: ...0001 1100 (use only upper 32-bit as symbol value with MRB_64BIT) + * fixnum: ...IIII III1 + * float : ...FFFF FF10 (51 bit significands; require MRB_64BIT) + * object: ...PPPP P000 + * + * 32bit word with inline float: * nil : ...0000 0000 (all bits are 0) * false : ...0000 0100 (mrb_fixnum(v) != 0) * true : ...0000 1100 * undef : ...0001 0100 + * symbol: ...SSS1 1100 (use only upper 32-bit as symbol value with MRB_64BIT) + * symbol: ...SSS1 0100 (symbol occupies 20bits) * fixnum: ...IIII III1 - * symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU) + * float : ...FFFF FF10 (22 bit significands; require MRB_64BIT) + * object: ...PPPP P000 + * + * and word boxing without inline float: + * nil : ...0000 0000 (all bits are 0) + * false : ...0000 0100 (mrb_fixnum(v) != 0) + * true : ...0000 1100 + * undef : ...0001 0100 + * fixnum: ...IIII III1 + * symbol: ...SSSS SS10 * object: ...PPPP P000 (any bits are 1) */ typedef struct mrb_value { @@ -85,8 +118,12 @@ union mrb_value_ { void *p; struct RBasic *bp; #ifndef MRB_NO_FLOAT +#ifndef MRB_USE_FLOAT_FULL_PRECISION + mrb_float f; +#else struct RFloat *fp; #endif +#endif struct RInteger *ip; struct RCptr *vp; uintptr_t w; @@ -114,7 +151,12 @@ MRB_API mrb_value mrb_word_boxing_int_value(struct mrb_state*, mrb_int); #define mrb_ptr(o) mrb_val_union(o).p #define mrb_cptr(o) mrb_val_union(o).vp->p #ifndef MRB_NO_FLOAT -#define mrb_float(o) mrb_val_union(o).fp->f +#ifndef MRB_USE_FLOAT_FULL_PRECISION +MRB_API mrb_float mrb_word_boxing_value_float(mrb_value v); +#define mrb_float(o) mrb_word_boxing_value_float(o) +#else +#define mrb_float(o) mrb_val_union(o).fp->f +#endif #endif #define mrb_fixnum(o) (mrb_int)(((intptr_t)(o).w) >> BOXWORD_FIXNUM_SHIFT) MRB_INLINE mrb_int @@ -134,8 +176,12 @@ mrb_integer_func(mrb_value o) { #define mrb_false_p(o) ((o).w == MRB_Qfalse) #define mrb_true_p(o) ((o).w == MRB_Qtrue) #ifndef MRB_NO_FLOAT +#ifndef MRB_USE_FLOAT_FULL_PRECISION +#define mrb_float_p(o) BOXWORD_SHIFT_VALUE_P(o, FLOAT) +#else #define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT) #endif +#endif #define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY) #define mrb_string_p(o) BOXWORD_OBJ_TYPE_P(o, STRING) #define mrb_hash_p(o) BOXWORD_OBJ_TYPE_P(o, HASH) @@ -177,6 +223,7 @@ mrb_type(mrb_value o) mrb_fixnum_p(o) ? MRB_TT_INTEGER : mrb_symbol_p(o) ? MRB_TT_SYMBOL : mrb_undef_p(o) ? MRB_TT_UNDEF : + mrb_float_p(o) ? MRB_TT_FLOAT : mrb_val_union(o).bp->tt; } @@ -158,11 +158,28 @@ mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f) { union mrb_value_ v; +#ifndef MRB_USE_FLOAT_FULL_PRECISION + v.f = f; + v.w = (v.w & ~3) | 2; +#else v.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class); v.fp->f = f; MRB_SET_FROZEN_FLAG(v.bp); +#endif return v.value; } + + +#ifndef MRB_USE_FLOAT_FULL_PRECISION +MRB_API mrb_float +mrb_word_boxing_value_float(mrb_value v) +{ + union mrb_value_ u; + u.value = v; + u.w = u.w & ~3; + return u.f; +} +#endif #endif /* MRB_NO_FLOAT */ MRB_API mrb_value diff --git a/src/symbol.c b/src/symbol.c index 9d68b5cf3..dbdeca459 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -73,7 +73,11 @@ static const char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS static mrb_sym sym_inline_pack(const char *name, size_t len) { +#if defined(MRB_WORD_BOXING) && defined(MRB_32BIT) && !defined(MRB_USE_FLOAT_FULL_PRECISION) + const size_t pack_length_max = 4; +#else const size_t pack_length_max = 5; +#endif char c; const char *p; |
