From d9cb5d4eee50901d16d5ed9561605fa945badb8d Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 5 Nov 2013 20:33:24 +0900 Subject: [PATCH] nan-boxing support --- include/picconf.h | 3 ++ include/picrin/value.h | 33 ++++++++++++++++++++ src/value.c | 70 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/include/picconf.h b/include/picconf.h index 62b42bc1..3808701a 100644 --- a/include/picconf.h +++ b/include/picconf.h @@ -4,6 +4,9 @@ /* switch normal VM and direct threaded VM */ #define PIC_DIRECT_THREADED_VM 1 +/* switch internal value representation */ +#define PIC_NAN_BOXING 1 + /* enable readline module */ #define PIC_ENABLE_READLINE 1 diff --git a/include/picrin/value.h b/include/picrin/value.h index ce2d0af2..1ca74b30 100644 --- a/include/picrin/value.h +++ b/include/picrin/value.h @@ -16,6 +16,37 @@ enum pic_vtype { PIC_VTYPE_HEAP }; +#if PIC_NAN_BOXING + +/** + * value representation by nan-boxing: + * float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF + * ptr : 111111111111TTTT PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP + * int : 1111111111110110 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII + * sym : 1111111111110111 0000000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS + * char : 1111111111111000 0000000000000000 CCCCCCCCCCCCCCCC ................ + */ +typedef struct { + union { + void *data; + double f; + struct { + union { + int i; + pic_sym sym; + char c; + }; + unsigned int type_; + }; + } u; +} pic_value; + +#define pic_ptr(v) ((void *)((long long)0xffffffffffff & (long long)(v).u.data)) +#define pic_vtype(v) (((v).u.type_ & 0xf0000)>>16) +#define pic_init_value(v,vtype) (((v).u.type_ = ((unsigned int)0xfff00000|((vtype)<<16))), (v).u.i = 0) + +#else + typedef struct { enum pic_vtype type; union { @@ -31,6 +62,8 @@ typedef struct { #define pic_vtype(v) ((v).type) #define pic_init_value(v,vtype) ((v).type = (vtype), (v).u.data = NULL) +#endif + enum pic_tt { /* immediate */ PIC_TT_NIL, diff --git a/src/value.c b/src/value.c index 750dd08d..2ea602bc 100644 --- a/src/value.c +++ b/src/value.c @@ -1,7 +1,43 @@ #include #include -#include "picrin/value.h" +#include "picrin.h" + +#if PIC_NAN_BOXING + +enum pic_tt +pic_type(pic_value v) +{ + if ((int)0xfff00000 >= v.u.type_) + return PIC_TT_FLOAT; + + switch (pic_vtype(v)) { + case PIC_VTYPE_NIL: + return PIC_TT_NIL; + case PIC_VTYPE_TRUE: + return PIC_TT_BOOL; + case PIC_VTYPE_FALSE: + return PIC_TT_BOOL; + case PIC_VTYPE_UNDEF: + return PIC_TT_UNDEF; + case PIC_VTYPE_FLOAT: + return PIC_TT_FLOAT; + case PIC_VTYPE_INT: + return PIC_TT_INT; + case PIC_VTYPE_SYMBOL: + return PIC_TT_SYMBOL; + case PIC_VTYPE_CHAR: + return PIC_TT_CHAR; + case PIC_VTYPE_EOF: + return PIC_TT_EOF; + case PIC_VTYPE_HEAP: + return ((struct pic_object *)pic_ptr(v))->tt; + } + /* logic flaw (suppress warnings gcc will emit) */ + abort(); +} + +#else enum pic_tt pic_type(pic_value v) @@ -32,6 +68,8 @@ pic_type(pic_value v) abort(); } +#endif + const char * pic_type_repr(enum pic_tt tt) { @@ -91,6 +129,34 @@ pic_bool_value(bool b) return v; } +#if PIC_NAN_BOXING + +pic_value +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)); + return v; +} + +pic_value +pic_float_value(double f) +{ + pic_value v; + + if (f != f) { + v.u.type_ = 0x7ff80000; + v.u.i = 0; + } else { + v.u.f = f; + } + return v; +} + +#else + pic_value pic_obj_value(void *ptr) { @@ -111,6 +177,8 @@ pic_float_value(double f) return v; } +#endif + pic_value pic_int_value(int i) {