diff options
| author | KOBAYASHI Shuji <[email protected]> | 2019-09-06 13:24:35 +0900 |
|---|---|---|
| committer | KOBAYASHI Shuji <[email protected]> | 2019-09-06 13:24:35 +0900 |
| commit | 19e2cc187b16507366977bcfa9d40c9a1b892eb0 (patch) | |
| tree | 5e22a112d1088afb400b2171c1845cc94499d6f7 /include | |
| parent | c3b16c26a6a4729ec7b1ca69e7b13f2d8af2adf8 (diff) | |
| download | mruby-19e2cc187b16507366977bcfa9d40c9a1b892eb0.tar.gz mruby-19e2cc187b16507366977bcfa9d40c9a1b892eb0.zip | |
Avoid bit fields in `mrb_value`; ref b2c3d88f
The changes at b2c3d88f were inappropriate because the memory layout of bit
fields are implementation defined. Therefor, I fixed it not to use bit
fields.
Diffstat (limited to 'include')
| -rw-r--r-- | include/mruby/boxing_nan.h | 6 | ||||
| -rw-r--r-- | include/mruby/boxing_word.h | 102 | ||||
| -rw-r--r-- | include/mruby/value.h | 15 |
3 files changed, 68 insertions, 55 deletions
diff --git a/include/mruby/boxing_nan.h b/include/mruby/boxing_nan.h index 4b47a3f17..af598e34e 100644 --- a/include/mruby/boxing_nan.h +++ b/include/mruby/boxing_nan.h @@ -21,12 +21,6 @@ #define MRB_FIXNUM_SHIFT 0 -#ifdef MRB_ENDIAN_BIG -#define MRB_ENDIAN_LOHI(a,b) a b -#else -#define MRB_ENDIAN_LOHI(a,b) b a -#endif - /* value representation by nan-boxing: * float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF * object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP diff --git a/include/mruby/boxing_word.h b/include/mruby/boxing_word.h index 9e4ee456f..de48278da 100644 --- a/include/mruby/boxing_word.h +++ b/include/mruby/boxing_word.h @@ -37,29 +37,39 @@ enum mrb_special_consts { }; #define MRB_IMMEDIATE_MASK 0x07 +#define MRB_FIXNUM_MASK 0x01 +#define MRB_SYMBOL_MASK 0x0f #define MRB_FIXNUM_FLAG 0x01 #define MRB_SYMBOL_FLAG 0x0e -#define MRB_SPECIAL_SHIFT 8 +#define MRB_SYMBOL_SHIFT 8 -#if defined(MRB_64BIT) +#ifdef MRB_64BIT #define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT) #define MRB_SYMBOL_MAX UINT32_MAX #else -#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT - MRB_SPECIAL_SHIFT) -#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SPECIAL_SHIFT) +#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT) +#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT) #endif +#define BOXWORD_SHIFT_VALUE(o,n,t) \ + ((((t)(o).w)) >> MRB_##n##_SHIFT) +#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \ + ((o).w = (((unsigned long)(v)) << MRB_##n##_SHIFT) | MRB_##n##_FLAG) +#define BOXWORD_SHIFT_VALUE_P(o,n) \ + (((o).w & MRB_##n##_MASK) == MRB_##n##_FLAG) + typedef union mrb_value { union { void *p; +#ifdef MRB_64BIT + /* use struct to avoid bit shift. */ struct { - unsigned int i_flag : MRB_FIXNUM_SHIFT; - mrb_int i : (MRB_INT_BIT - MRB_FIXNUM_SHIFT); - }; - struct { - unsigned int sym_flag : MRB_SPECIAL_SHIFT; - mrb_sym sym : MRB_SYMBOL_BITSIZE; + MRB_ENDIAN_LOHI( + mrb_sym sym; + ,uint32_t sym_flag; + ) }; +#endif struct RBasic *bp; #ifndef MRB_WITHOUT_FLOAT struct RFloat *fp; @@ -84,8 +94,42 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); #ifndef MRB_WITHOUT_FLOAT #define mrb_float(o) (o).value.fp->f #endif -#define mrb_fixnum(o) ((mrb_int)(o).value.i) +#define mrb_fixnum(o) BOXWORD_SHIFT_VALUE(o, FIXNUM, mrb_int) +#ifdef MRB_64BIT #define mrb_symbol(o) (o).value.sym +#else +#define mrb_symbol(o) BOXWORD_SHIFT_VALUE(o, SYMBOL, mrb_sym) +#endif +#define mrb_bool(o) ((o).w != MRB_Qnil && (o).w != MRB_Qfalse) + +#define mrb_immediate_p(o) ((o).w & MRB_IMMEDIATE_MASK || (o).w == MRB_Qnil) +#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM) +#ifdef MRB_64BIT +#define mrb_symbol_p(o) ((o).value.sym_flag == MRB_SYMBOL_FLAG) +#else +#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL) +#endif +#define mrb_undef_p(o) ((o).w == MRB_Qundef) +#define mrb_nil_p(o) ((o).w == MRB_Qnil) +#define mrb_false_p(o) ((o).w == MRB_Qfalse) +#define mrb_true_p(o) ((o).w == MRB_Qtrue) + +#ifndef MRB_WITHOUT_FLOAT +#define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v)) +#endif +#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v)) +#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef) +#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil) +#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse) +#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue) +#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r)) +#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n) +#ifdef MRB_64BIT +#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = MRB_SYMBOL_FLAG) +#else +#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n) +#endif +#define SET_OBJ_VALUE(r,v) ((r).value.p = v) MRB_INLINE enum mrb_vtype mrb_type(mrb_value o) @@ -99,45 +143,13 @@ mrb_type(mrb_value o) case MRB_Qundef: return MRB_TT_UNDEF; } - if (o.value.i_flag == MRB_FIXNUM_FLAG) { + if (mrb_fixnum_p(o)) { return MRB_TT_FIXNUM; } - if (o.value.sym_flag == MRB_SYMBOL_FLAG) { + if (mrb_symbol_p(o)) { return MRB_TT_SYMBOL; } return o.value.bp->tt; } -#define mrb_bool(o) ((o).w != MRB_Qnil && (o).w != MRB_Qfalse) -#define mrb_immediate_p(o) ((o).w & MRB_IMMEDIATE_MASK || (o).w == MRB_Qnil) -#define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG) -#define mrb_undef_p(o) ((o).w == MRB_Qundef) -#define mrb_nil_p(o) ((o).w == MRB_Qnil) -#define mrb_false_p(o) ((o).w == MRB_Qfalse) -#define mrb_true_p(o) ((o).w == MRB_Qtrue) - -#ifndef MRB_WITHOUT_FLOAT -#define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v)) -#endif -#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v)) -#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef) -#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil) -#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse) -#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue) -#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r)) -#define SET_INT_VALUE(r,n) do { \ - (r).w = 0; \ - (r).value.i_flag = MRB_FIXNUM_FLAG; \ - (r).value.i = (n); \ -} while (0) -#define SET_SYM_VALUE(r,v) do { \ - (r).w = 0; \ - (r).value.sym_flag = MRB_SYMBOL_FLAG; \ - (r).value.sym = (v); \ -} while (0) -#define SET_OBJ_VALUE(r,v) do { \ - (r).w = 0; \ - (r).value.p = (v); \ -} while (0) - #endif /* MRUBY_BOXING_WORD_H */ diff --git a/include/mruby/value.h b/include/mruby/value.h index d2b85078e..52ce93d58 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -17,7 +17,7 @@ MRB_BEGIN_DECL /** * mruby Symbol. * @class mrb_sym - * + * * You can create an mrb_sym by simply using mrb_str_intern() or mrb_intern_cstr() */ typedef uint32_t mrb_sym; @@ -25,10 +25,10 @@ typedef uint32_t mrb_sym; /** * mruby Boolean. * @class mrb_bool - * + * * * Used internally to represent boolean. Can be TRUE or FALSE. - * Not to be confused with Ruby's boolean classes, which can be + * Not to be confused with Ruby's boolean classes, which can be * obtained using mrb_false_value() and mrb_true_value() */ typedef uint8_t mrb_bool; @@ -78,6 +78,11 @@ struct mrb_state; # define MRB_PRIx PRIx32 #endif +#ifdef MRB_ENDIAN_BIG +# define MRB_ENDIAN_LOHI(a,b) a b +#else +# define MRB_ENDIAN_LOHI(a,b) b a +#endif #ifndef MRB_WITHOUT_FLOAT MRB_API double mrb_float_read(const char*, char**); @@ -169,6 +174,9 @@ typedef void mrb_value; #ifndef mrb_fixnum_p #define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM) #endif +#ifndef mrb_symbol_p +#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL) +#endif #ifndef mrb_undef_p #define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF) #endif @@ -191,7 +199,6 @@ typedef void mrb_value; #ifndef MRB_WITHOUT_FLOAT #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) #endif -#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL) #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) |
