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 @@ ...@@ -21,12 +21,6 @@
#define MRB_FIXNUM_SHIFT 0 #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: /* value representation by nan-boxing:
* float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF * float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
* object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP * object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP
......
...@@ -37,29 +37,39 @@ enum mrb_special_consts { ...@@ -37,29 +37,39 @@ enum mrb_special_consts {
}; };
#define MRB_IMMEDIATE_MASK 0x07 #define MRB_IMMEDIATE_MASK 0x07
#define MRB_FIXNUM_MASK 0x01
#define MRB_SYMBOL_MASK 0x0f
#define MRB_FIXNUM_FLAG 0x01 #define MRB_FIXNUM_FLAG 0x01
#define MRB_SYMBOL_FLAG 0x0e #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_BITSIZE (sizeof(mrb_sym) * CHAR_BIT)
#define MRB_SYMBOL_MAX UINT32_MAX #define MRB_SYMBOL_MAX UINT32_MAX
#else #else
#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT - MRB_SPECIAL_SHIFT) #define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT)
#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SPECIAL_SHIFT) #define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT)
#endif #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 { typedef union mrb_value {
union { union {
void *p; void *p;
#ifdef MRB_64BIT
/* use struct to avoid bit shift. */
struct { struct {
unsigned int i_flag : MRB_FIXNUM_SHIFT; MRB_ENDIAN_LOHI(
mrb_int i : (MRB_INT_BIT - MRB_FIXNUM_SHIFT); mrb_sym sym;
}; ,uint32_t sym_flag;
struct { )
unsigned int sym_flag : MRB_SPECIAL_SHIFT;
mrb_sym sym : MRB_SYMBOL_BITSIZE;
}; };
#endif
struct RBasic *bp; struct RBasic *bp;
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
struct RFloat *fp; struct RFloat *fp;
...@@ -84,8 +94,42 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); ...@@ -84,8 +94,42 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
#define mrb_float(o) (o).value.fp->f #define mrb_float(o) (o).value.fp->f
#endif #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 #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_INLINE enum mrb_vtype
mrb_type(mrb_value o) mrb_type(mrb_value o)
...@@ -99,45 +143,13 @@ mrb_type(mrb_value o) ...@@ -99,45 +143,13 @@ mrb_type(mrb_value o)
case MRB_Qundef: case MRB_Qundef:
return MRB_TT_UNDEF; return MRB_TT_UNDEF;
} }
if (o.value.i_flag == MRB_FIXNUM_FLAG) { if (mrb_fixnum_p(o)) {
return MRB_TT_FIXNUM; return MRB_TT_FIXNUM;
} }
if (o.value.sym_flag == MRB_SYMBOL_FLAG) { if (mrb_symbol_p(o)) {
return MRB_TT_SYMBOL; return MRB_TT_SYMBOL;
} }
return o.value.bp->tt; 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 */ #endif /* MRUBY_BOXING_WORD_H */
...@@ -17,7 +17,7 @@ MRB_BEGIN_DECL ...@@ -17,7 +17,7 @@ MRB_BEGIN_DECL
/** /**
* mruby Symbol. * mruby Symbol.
* @class mrb_sym * @class mrb_sym
* *
* You can create an mrb_sym by simply using mrb_str_intern() or mrb_intern_cstr() * You can create an mrb_sym by simply using mrb_str_intern() or mrb_intern_cstr()
*/ */
typedef uint32_t mrb_sym; typedef uint32_t mrb_sym;
...@@ -25,10 +25,10 @@ typedef uint32_t mrb_sym; ...@@ -25,10 +25,10 @@ typedef uint32_t mrb_sym;
/** /**
* mruby Boolean. * mruby Boolean.
* @class mrb_bool * @class mrb_bool
* *
* *
* Used internally to represent boolean. Can be TRUE or FALSE. * 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() * obtained using mrb_false_value() and mrb_true_value()
*/ */
typedef uint8_t mrb_bool; typedef uint8_t mrb_bool;
...@@ -78,6 +78,11 @@ struct mrb_state; ...@@ -78,6 +78,11 @@ struct mrb_state;
# define MRB_PRIx PRIx32 # define MRB_PRIx PRIx32
#endif #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 #ifndef MRB_WITHOUT_FLOAT
MRB_API double mrb_float_read(const char*, char**); MRB_API double mrb_float_read(const char*, char**);
...@@ -169,6 +174,9 @@ typedef void mrb_value; ...@@ -169,6 +174,9 @@ typedef void mrb_value;
#ifndef mrb_fixnum_p #ifndef mrb_fixnum_p
#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM) #define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
#endif #endif
#ifndef mrb_symbol_p
#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
#endif
#ifndef mrb_undef_p #ifndef mrb_undef_p
#define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF) #define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
#endif #endif
...@@ -191,7 +199,6 @@ typedef void mrb_value; ...@@ -191,7 +199,6 @@ typedef void mrb_value;
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
#endif #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_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING) #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
#define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH) #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