Commit 19e2cc18 authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

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.
parent c3b16c26
......@@ -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
......
......@@ -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 */
......@@ -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)
......
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