Skip to content

Commit 249f05e

Browse files
AE9RBmatz
authored andcommitted
Clean up value.h and mrb_value boxing
1 parent 5c50bcd commit 249f05e

13 files changed

Lines changed: 438 additions & 476 deletions

File tree

include/mruby.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,11 @@ int mrb_gc_arena_save(mrb_state*);
325325
void mrb_gc_arena_restore(mrb_state*,int);
326326
void mrb_gc_mark(mrb_state*,struct RBasic*);
327327
#define mrb_gc_mark_value(mrb,val) do {\
328-
if (MRB_TT_HAS_BASIC_P(mrb_type(val))) mrb_gc_mark((mrb), mrb_basic_ptr(val)); \
328+
if (!mrb_immediate_p(val)) mrb_gc_mark((mrb), mrb_basic_ptr(val)); \
329329
} while (0)
330330
void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*);
331331
#define mrb_field_write_barrier_value(mrb, obj, val) do{\
332-
if (MRB_TT_HAS_BASIC_P(mrb_type(val))) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val)); \
332+
if (!mrb_immediate_p(val)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val)); \
333333
} while (0)
334334
void mrb_write_barrier(mrb_state *, struct RBasic*);
335335

include/mruby/boxing_nan.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
** mruby/boxing_nan.h - nan boxing mrb_value definition
3+
**
4+
** See Copyright Notice in mruby.h
5+
*/
6+
7+
#ifndef MRUBY_BOXING_NAN_H
8+
#define MRUBY_BOXING_NAN_H
9+
10+
#ifdef MRB_USE_FLOAT
11+
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
12+
#endif
13+
14+
#ifdef MRB_INT64
15+
# error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<----
16+
#endif
17+
18+
#define MRB_FIXNUM_SHIFT 0
19+
#define MRB_TT_HAS_BASIC MRB_TT_OBJECT
20+
21+
#ifdef MRB_ENDIAN_BIG
22+
#define MRB_ENDIAN_LOHI(a,b) a b
23+
#else
24+
#define MRB_ENDIAN_LOHI(a,b) b a
25+
#endif
26+
27+
/* value representation by nan-boxing:
28+
* float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
29+
* object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP
30+
* int : 1111111111110001 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII
31+
* sym : 1111111111110001 0100000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS
32+
* In order to get enough bit size to save TT, all pointers are shifted 2 bits
33+
* in the right direction. Also, TTTTTT is the mrb_vtype + 1;
34+
*/
35+
typedef struct mrb_value {
36+
union {
37+
mrb_float f;
38+
union {
39+
void *p;
40+
struct {
41+
MRB_ENDIAN_LOHI(
42+
uint32_t ttt;
43+
,union {
44+
mrb_int i;
45+
mrb_sym sym;
46+
};
47+
)
48+
};
49+
} value;
50+
};
51+
} mrb_value;
52+
53+
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
54+
55+
#define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1)
56+
#define mrb_type(o) ((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
57+
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
58+
#define mrb_float(o) (o).f
59+
#define mrb_cptr(o) mrb_ptr(o)
60+
#define mrb_fixnum(o) (o).value.i
61+
#define mrb_symbol(o) (o).value.sym
62+
63+
#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\
64+
(o).value.ttt = (0xfff00000|(((tt)+1)<<14));\
65+
switch (tt) {\
66+
case MRB_TT_FALSE:\
67+
case MRB_TT_TRUE:\
68+
case MRB_TT_UNDEF:\
69+
case MRB_TT_FIXNUM:\
70+
case MRB_TT_SYMBOL: (o).attr = (v); break;\
71+
default: (o).value.i = 0; (o).value.p = (void*)((uintptr_t)(o).value.p | (((uintptr_t)(v))>>2)); break;\
72+
}\
73+
} while (0)
74+
75+
#define SET_FLOAT_VALUE(mrb,r,v) do { \
76+
if (v != v) { \
77+
(r).value.ttt = 0x7ff80000; \
78+
(r).value.i = 0; \
79+
} else { \
80+
(r).f = v; \
81+
}} while(0)
82+
83+
#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
84+
#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
85+
#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
86+
#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
87+
#define SET_FIXNUM_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
88+
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
89+
#define SET_OBJ_VALUE(r,v) BOXNAN_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
90+
#define SET_PROC_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_PROC, value.p, v)
91+
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
92+
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
93+
94+
#endif /* MRUBY_BOXING_NAN_H */

include/mruby/boxing_nix.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
** mruby/boxing_nix.h - unboxed mrb_value definition
3+
**
4+
** See Copyright Notice in mruby.h
5+
*/
6+
7+
#ifndef MRUBY_BOXING_NIX_H
8+
#define MRUBY_BOXING_NIX_H
9+
10+
#define MRB_FIXNUM_SHIFT 0
11+
#define MRB_TT_HAS_BASIC MRB_TT_OBJECT
12+
13+
typedef struct mrb_value {
14+
union {
15+
mrb_float f;
16+
void *p;
17+
mrb_int i;
18+
mrb_sym sym;
19+
} value;
20+
enum mrb_vtype tt;
21+
} mrb_value;
22+
23+
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
24+
25+
#define mrb_ptr(o) (o).value.p
26+
#define mrb_cptr(o) mrb_ptr(o)
27+
#define mrb_float(o) (o).value.f
28+
#define mrb_fixnum(o) (o).value.i
29+
#define mrb_symbol(o) (o).value.sym
30+
#define mrb_type(o) (o).tt
31+
32+
#define BOXNIX_SET_VALUE(o, ttt, attr, v) do {\
33+
(o).tt = ttt;\
34+
(o).attr = v;\
35+
} while (0)
36+
37+
#define SET_NIL_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
38+
#define SET_FALSE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
39+
#define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
40+
#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
41+
#define SET_FIXNUM_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
42+
#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
43+
#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
44+
#define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
45+
#define SET_PROC_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_PROC, value.p, v)
46+
#define SET_CPTR_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
47+
#define SET_UNDEF_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
48+
49+
#endif /* MRUBY_BOXING_NIX_H */

include/mruby/boxing_word.h

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
** mruby/boxing_word.h - word boxing mrb_value definition
3+
**
4+
** See Copyright Notice in mruby.h
5+
*/
6+
7+
#ifndef MRUBY_BOXING_WORD_H
8+
#define MRUBY_BOXING_WORD_H
9+
10+
#if defined(MRB_INT16)
11+
# error MRB_INT16 is too small for MRB_WORD_BOXING.
12+
#endif
13+
14+
#define MRB_FIXNUM_SHIFT 1
15+
#define MRB_TT_HAS_BASIC MRB_TT_FLOAT
16+
17+
enum mrb_special_consts {
18+
MRB_Qnil = 0,
19+
MRB_Qfalse = 2,
20+
MRB_Qtrue = 4,
21+
MRB_Qundef = 6,
22+
};
23+
24+
#define MRB_FIXNUM_FLAG 0x01
25+
#define MRB_SYMBOL_FLAG 0x0e
26+
#define MRB_SPECIAL_SHIFT 8
27+
28+
typedef union mrb_value {
29+
union {
30+
void *p;
31+
struct {
32+
unsigned int i_flag : MRB_FIXNUM_SHIFT;
33+
mrb_int i : (MRB_INT_BIT - MRB_FIXNUM_SHIFT);
34+
};
35+
struct {
36+
unsigned int sym_flag : MRB_SPECIAL_SHIFT;
37+
int sym : (sizeof(mrb_sym) * CHAR_BIT);
38+
};
39+
struct RBasic *bp;
40+
struct RFloat *fp;
41+
struct RCptr *vp;
42+
} value;
43+
unsigned long w;
44+
} mrb_value;
45+
46+
mrb_value word_boxing_mrb_cptr_value(struct mrb_state*, void*);
47+
mrb_value word_boxing_mrb_float_value(struct mrb_state*, mrb_float);
48+
mrb_value word_boxing_mrb_float_pool(struct mrb_state*, mrb_float);
49+
50+
#define mrb_float_pool(mrb,f) word_boxing_mrb_float_pool(mrb,f)
51+
52+
#define mrb_ptr(o) (o).value.p
53+
#define mrb_cptr(o) (o).value.vp->p
54+
#define mrb_float(o) (o).value.fp->f
55+
#define mrb_fixnum(o) (o).value.i
56+
#define mrb_symbol(o) (o).value.sym
57+
58+
static inline enum mrb_vtype
59+
mrb_type(mrb_value o)
60+
{
61+
switch (o.w) {
62+
case MRB_Qfalse:
63+
case MRB_Qnil:
64+
return MRB_TT_FALSE;
65+
case MRB_Qtrue:
66+
return MRB_TT_TRUE;
67+
case MRB_Qundef:
68+
return MRB_TT_UNDEF;
69+
}
70+
if (o.value.i_flag == MRB_FIXNUM_FLAG) {
71+
return MRB_TT_FIXNUM;
72+
}
73+
if (o.value.sym_flag == MRB_SYMBOL_FLAG) {
74+
return MRB_TT_SYMBOL;
75+
}
76+
return o.value.bp->tt;
77+
}
78+
79+
#define mrb_bool(o) ((o).w != MRB_Qnil && (o).w != MRB_Qfalse)
80+
#define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG)
81+
#define mrb_undef_p(o) ((o).w == MRB_Qundef)
82+
#define mrb_nil_p(o) ((o).w == MRB_Qnil)
83+
84+
#define BOXWORD_SET_VALUE(o, ttt, attr, v) do {\
85+
(o).w = 0;\
86+
(o).attr = (v);\
87+
switch (ttt) {\
88+
case MRB_TT_FALSE: (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\
89+
case MRB_TT_TRUE: (o).w = MRB_Qtrue; break;\
90+
case MRB_TT_UNDEF: (o).w = MRB_Qundef; break;\
91+
case MRB_TT_FIXNUM: (o).value.i_flag = MRB_FIXNUM_FLAG; break;\
92+
case MRB_TT_SYMBOL: (o).value.sym_flag = MRB_SYMBOL_FLAG; break;\
93+
default: if ((o).value.bp) (o).value.bp->tt = ttt; break;\
94+
}\
95+
} while (0)
96+
97+
#define SET_FLOAT_VALUE(mrb,r,v) r = word_boxing_mrb_float_value(mrb, v)
98+
#define SET_CPTR_VALUE(mrb,r,v) r = word_boxing_mrb_cptr_value(mrb, v)
99+
#define SET_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
100+
#define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
101+
#define SET_TRUE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
102+
#define SET_BOOL_VALUE(r,b) BOXWORD_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
103+
#define SET_FIXNUM_VALUE(r,n) BOXWORD_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
104+
#define SET_SYM_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
105+
#define SET_OBJ_VALUE(r,v) BOXWORD_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
106+
#define SET_PROC_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_PROC, value.p, v)
107+
#define SET_UNDEF_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
108+
109+
#endif /* MRUBY_BOXING_WORD_H */

include/mruby/class.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ mrb_class(mrb_state *mrb, mrb_value v)
2828
{
2929
switch (mrb_type(v)) {
3030
case MRB_TT_FALSE:
31-
if (v.value.i)
31+
if (mrb_fixnum(v))
3232
return mrb->false_class;
3333
return mrb->nil_class;
3434
case MRB_TT_TRUE:

include/mruby/object.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
** mruby/object.h - mruby object definition
3+
**
4+
** See Copyright Notice in mruby.h
5+
*/
6+
7+
#ifndef MRUBY_OBJECT_H
8+
#define MRUBY_OBJECT_H
9+
10+
#define MRB_OBJECT_HEADER \
11+
enum mrb_vtype tt:8;\
12+
uint32_t color:3;\
13+
uint32_t flags:21;\
14+
struct RClass *c;\
15+
struct RBasic *gcnext
16+
17+
/* white: 011, black: 100, gray: 000 */
18+
#define MRB_GC_GRAY 0
19+
#define MRB_GC_WHITE_A 1
20+
#define MRB_GC_WHITE_B (1 << 1)
21+
#define MRB_GC_BLACK (1 << 2)
22+
#define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B)
23+
#define MRB_GC_COLOR_MASK 7
24+
25+
#define paint_gray(o) ((o)->color = MRB_GC_GRAY)
26+
#define paint_black(o) ((o)->color = MRB_GC_BLACK)
27+
#define paint_white(o) ((o)->color = MRB_GC_WHITES)
28+
#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
29+
#define is_gray(o) ((o)->color == MRB_GC_GRAY)
30+
#define is_white(o) ((o)->color & MRB_GC_WHITES)
31+
#define is_black(o) ((o)->color & MRB_GC_BLACK)
32+
#define is_dead(s, o) (((o)->color & other_white_part(s) & MRB_GC_WHITES) || (o)->tt == MRB_TT_FREE)
33+
#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
34+
#define other_white_part(s) ((s)->current_white_part ^ MRB_GC_WHITES)
35+
36+
struct RBasic {
37+
MRB_OBJECT_HEADER;
38+
};
39+
#define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v)))
40+
/* obsolete macro mrb_basic; will be removed soon */
41+
#define mrb_basic(v) mrb_basic_ptr(v)
42+
43+
struct RObject {
44+
MRB_OBJECT_HEADER;
45+
struct iv_tbl *iv;
46+
};
47+
#define mrb_obj_ptr(v) ((struct RObject*)(mrb_ptr(v)))
48+
/* obsolete macro mrb_object; will be removed soon */
49+
#define mrb_object(o) mrb_obj_ptr(o)
50+
#define mrb_immediate_p(x) (mrb_type(x) < MRB_TT_HAS_BASIC)
51+
#define mrb_special_const_p(x) mrb_immediate_p(x)
52+
53+
struct RFiber {
54+
MRB_OBJECT_HEADER;
55+
struct mrb_context *cxt;
56+
};
57+
58+
struct RFloat {
59+
MRB_OBJECT_HEADER;
60+
mrb_float f;
61+
};
62+
63+
struct RCptr {
64+
MRB_OBJECT_HEADER;
65+
void *p;
66+
};
67+
68+
#endif /* MRUBY_OBJECT_H */

0 commit comments

Comments
 (0)