more efficient impelementation of nan boxing

This commit is contained in:
Yuichi Nishiwaki 2014-09-12 13:50:23 +09:00
parent c6b46ae2ac
commit edcc26466c
2 changed files with 77 additions and 41 deletions

View File

@ -117,21 +117,24 @@ destroy_analyze_state(analyze_state *state)
static bool static bool
analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect *locals) analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect *locals)
{ {
pic_value v, sym; pic_value v, t;
pic_sym sym;
for (v = formals; pic_pair_p(v); v = pic_cdr(pic, v)) { for (v = formals; pic_pair_p(v); v = pic_cdr(pic, v)) {
sym = pic_car(pic, v); t = pic_car(pic, v);
if (! pic_sym_p(sym)) { if (! pic_sym_p(t)) {
return false; return false;
} }
xv_push(args, &pic_sym(sym)); sym = pic_sym(t);
xv_push(args, &sym);
} }
if (pic_nil_p(v)) { if (pic_nil_p(v)) {
*varg = false; *varg = false;
} }
else if (pic_sym_p(v)) { else if (pic_sym_p(v)) {
*varg = true; *varg = true;
xv_push(locals, &pic_sym(v)); sym = pic_sym(v);
xv_push(locals, &sym);
} }
else { else {
return false; return false;
@ -972,6 +975,7 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
pic_state *pic = state->pic; pic_state *pic = state->pic;
codegen_context *cxt; codegen_context *cxt;
pic_value var; pic_value var;
pic_sym sym;
assert(pic_sym_p(name) || pic_false_p(name)); assert(pic_sym_p(name) || pic_false_p(name));
@ -987,13 +991,16 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
xv_init(&cxt->captures, sizeof(pic_sym)); xv_init(&cxt->captures, sizeof(pic_sym));
pic_for_each (var, args) { pic_for_each (var, args) {
xv_push(&cxt->args, &pic_sym(var)); sym = pic_sym(var);
xv_push(&cxt->args, &sym);
} }
pic_for_each (var, locals) { pic_for_each (var, locals) {
xv_push(&cxt->locals, &pic_sym(var)); sym = pic_sym(var);
xv_push(&cxt->locals, &sym);
} }
pic_for_each (var, captures) { pic_for_each (var, captures) {
xv_push(&cxt->captures, &pic_sym(var)); sym = pic_sym(var);
xv_push(&cxt->captures, &sym);
} }
cxt->code = pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code)); cxt->code = pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code));

View File

@ -44,32 +44,29 @@ enum pic_vtype {
* char : 1111111111111000 0000000000000000 CCCCCCCCCCCCCCCC ................ * char : 1111111111111000 0000000000000000 CCCCCCCCCCCCCCCC ................
*/ */
typedef struct { typedef uint64_t pic_value;
union {
void *data;
double f;
struct {
union {
int i;
pic_sym sym;
char c;
};
uint32_t type_;
};
} u;
} pic_value;
#define pic_ptr(v) ((void *)((uint64_t)0xffffffffffff & (uint64_t)(v).u.data)) #define pic_ptr(v) ((void *)(0xfffffffffffful & (v)))
#define pic_init_value(v,vtype) (((v).u.type_ = (((uint32_t)0xfff00000)|((uint32_t)((vtype)<<16)))), (v).u.i = 0) #define pic_init_value(v,vtype) (v = (0xfff0000000000000ul | ((uint64_t)(vtype) << 48)))
static inline enum pic_vtype static inline enum pic_vtype
pic_vtype(pic_value v) pic_vtype(pic_value v)
{ {
return 0xfff00000 >= v.u.type_ return 0xfff0 >= (v >> 48) ? PIC_VTYPE_FLOAT : ((v >> 48) & 0xf);
? PIC_VTYPE_FLOAT
: (v.u.type_ & 0xf0000)>>16;
} }
static inline double
pic_float(pic_value v)
{
union { double f; uint64_t i; } u;
u.i = v;
return u.f;
}
#define pic_int(v) ((v) & 0xfffffffful)
#define pic_sym(v) ((v) & 0xfffffffful)
#define pic_char(v) ((v) & 0xfffffffful)
#else #else
typedef struct { typedef struct {
@ -87,6 +84,11 @@ typedef struct {
#define pic_vtype(v) ((v).type) #define pic_vtype(v) ((v).type)
#define pic_init_value(v,vtype) ((v).type = (vtype), (v).u.data = NULL) #define pic_init_value(v,vtype) ((v).type = (vtype), (v).u.data = NULL)
#define pic_float(v) ((v).u.f)
#define pic_int(v) ((v).u.i)
#define pic_sym(v) ((v).u.sym)
#define pic_char(v) ((v).u.c)
#endif #endif
enum pic_tt { enum pic_tt {
@ -142,11 +144,6 @@ typedef struct pic_string pic_str;
typedef struct pic_vector pic_vec; typedef struct pic_vector pic_vec;
typedef struct pic_blob pic_blob; typedef struct pic_blob pic_blob;
#define pic_float(v) ((v).u.f)
#define pic_int(v) ((v).u.i)
#define pic_sym(v) ((v).u.sym)
#define pic_char(v) ((v).u.c)
#define pic_obj_p(v) (pic_vtype(v) == PIC_VTYPE_HEAP) #define pic_obj_p(v) (pic_vtype(v) == PIC_VTYPE_HEAP)
#define pic_obj_ptr(v) ((struct pic_object *)pic_ptr(v)) #define pic_obj_ptr(v) ((struct pic_object *)pic_ptr(v))
@ -328,21 +325,53 @@ pic_obj_value(void *ptr)
pic_value v; pic_value v;
pic_init_value(v, PIC_VTYPE_HEAP); pic_init_value(v, PIC_VTYPE_HEAP);
v.u.data = (void*)((long long)v.u.data | ((long long)ptr)); v |= 0xfffffffffffful & (uint64_t)ptr;
return v; return v;
} }
static inline pic_value static inline pic_value
pic_float_value(double f) pic_float_value(double f)
{ {
pic_value v; union { double f; uint64_t i; } u;
if (f != f) { if (f != f) {
v.u.type_ = 0x7ff80000; return 0x7ff8000000000000ul;
v.u.i = 0;
} else { } else {
v.u.f = f; u.f = f;
return u.i;
} }
}
static inline pic_value
pic_int_value(int i)
{
union { int i; unsigned u; } u;
pic_value v;
u.i = i;
pic_init_value(v, PIC_VTYPE_INT);
v |= u.u;
return v;
}
static inline pic_value
pic_symbol_value(pic_sym sym)
{
pic_value v;
pic_init_value(v, PIC_VTYPE_SYMBOL);
v |= sym;
return v;
}
static inline pic_value
pic_char_value(char c)
{
pic_value v;
pic_init_value(v, PIC_VTYPE_CHAR);
v |= c;
return v; return v;
} }
@ -368,8 +397,6 @@ pic_float_value(double f)
return v; return v;
} }
#endif
static inline pic_value static inline pic_value
pic_int_value(int i) pic_int_value(int i)
{ {
@ -400,6 +427,8 @@ pic_char_value(char c)
return v; return v;
} }
#endif
static inline pic_value static inline pic_value
pic_undef_value() pic_undef_value()
{ {
@ -424,13 +453,13 @@ pic_none_value()
static inline bool static inline bool
pic_eq_p(pic_value x, pic_value y) pic_eq_p(pic_value x, pic_value y)
{ {
return x.u.data == y.u.data; return x == y;
} }
static inline bool static inline bool
pic_eqv_p(pic_value x, pic_value y) pic_eqv_p(pic_value x, pic_value y)
{ {
return x.u.data == y.u.data; return x == y;
} }
#else #else