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
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)) {
sym = pic_car(pic, v);
if (! pic_sym_p(sym)) {
t = pic_car(pic, v);
if (! pic_sym_p(t)) {
return false;
}
xv_push(args, &pic_sym(sym));
sym = pic_sym(t);
xv_push(args, &sym);
}
if (pic_nil_p(v)) {
*varg = false;
}
else if (pic_sym_p(v)) {
*varg = true;
xv_push(locals, &pic_sym(v));
sym = pic_sym(v);
xv_push(locals, &sym);
}
else {
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;
codegen_context *cxt;
pic_value var;
pic_sym sym;
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));
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) {
xv_push(&cxt->locals, &pic_sym(var));
sym = pic_sym(var);
xv_push(&cxt->locals, &sym);
}
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));

View File

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