summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorKOBAYASHI Shuji <[email protected]>2019-09-06 13:24:35 +0900
committerKOBAYASHI Shuji <[email protected]>2019-09-06 13:24:35 +0900
commit19e2cc187b16507366977bcfa9d40c9a1b892eb0 (patch)
tree5e22a112d1088afb400b2171c1845cc94499d6f7 /include
parentc3b16c26a6a4729ec7b1ca69e7b13f2d8af2adf8 (diff)
downloadmruby-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.h6
-rw-r--r--include/mruby/boxing_word.h102
-rw-r--r--include/mruby/value.h15
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)