Module: wine Branch: master Commit: 37509e540fc892c7919613204cf527fde6cd4090 URL: http://source.winehq.org/git/wine.git/?a=commit;h=37509e540fc892c7919613204c...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Sep 18 19:02:27 2012 +0200
jscript: Pack jsval_t to 64-bit structure on i386.
---
dlls/jscript/jsutils.c | 4 +- dlls/jscript/jsval.h | 143 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 114 insertions(+), 33 deletions(-)
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index d4260ca..c76d09a 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -239,8 +239,8 @@ HRESULT jsval_variant(jsval_t *val, VARIANT *var) VARIANT *v; HRESULT hres;
- val->type = JSV_VARIANT; - val->u.v = v = heap_alloc(sizeof(VARIANT)); + __JSVAL_TYPE(*val) = JSV_VARIANT; + __JSVAL_VAR(*val) = v = heap_alloc(sizeof(VARIANT)); if(!v) return E_OUTOFMEMORY;
diff --git a/dlls/jscript/jsval.h b/dlls/jscript/jsval.h index a678e05..9909de7 100644 --- a/dlls/jscript/jsval.h +++ b/dlls/jscript/jsval.h @@ -19,17 +19,52 @@ #ifndef JSVAL_H #define JSVAL_H
+/* + * jsval_t structure is used to represent JavaScript dynamically-typed values. + * It's a (type,value) pair, usually represented as a structure of enum (type) + * and union (value of given type). For both memory and speed performance, we + * use tricks allowing storing both values as a struct with size equal to + * size of double (that is 64-bit) on 32-bit systems. For that, we use the fact + * that NaN value representation has 52 (almost) free bits. + */ + +#ifdef __i386__ +#define JSVAL_DOUBLE_LAYOUT_PTR32 +#endif + +#ifdef JSVAL_DOUBLE_LAYOUT_PTR32 +/* NaN exponent and our 0x80000 marker */ +#define JSV_VAL(x) (0x7ff80000|x) +#else +#define JSV_VAL(x) x +#endif + typedef enum { - JSV_UNDEFINED, - JSV_NULL, - JSV_OBJECT, - JSV_STRING, - JSV_NUMBER, - JSV_BOOL, - JSV_VARIANT + JSV_UNDEFINED = JSV_VAL(1), + JSV_NULL = JSV_VAL(2), + JSV_OBJECT = JSV_VAL(3), + JSV_STRING = JSV_VAL(4), + JSV_NUMBER = JSV_VAL(5), + JSV_BOOL = JSV_VAL(6), + JSV_VARIANT = JSV_VAL(7) } jsval_type_t;
struct _jsval_t { +#ifdef JSVAL_DOUBLE_LAYOUT_PTR32 + union { + double n; + struct { + union { + IDispatch *obj; + BSTR str; + BOOL b; + VARIANT *v; + UINT_PTR as_uintptr; + } u; + jsval_type_t tag; + } s; + } u; +#else jsval_type_t type; union { IDispatch *obj; @@ -38,29 +73,50 @@ struct _jsval_t { BOOL b; VARIANT *v; } u; +#endif };
+#ifdef JSVAL_DOUBLE_LAYOUT_PTR32 + +C_ASSERT(sizeof(jsval_t) == sizeof(double)); + +#define __JSVAL_TYPE(x) ((x).u.s.tag) +#define __JSVAL_BOOL(x) ((x).u.s.u.b) +#define __JSVAL_STR(x) ((x).u.s.u.str) +#define __JSVAL_OBJ(x) ((x).u.s.u.obj) +#define __JSVAL_VAR(x) ((x).u.s.u.v) + +#else + +#define __JSVAL_TYPE(x) ((x).type) +#define __JSVAL_BOOL(x) ((x).u.b) +#define __JSVAL_STR(x) ((x).u.str) +#define __JSVAL_OBJ(x) ((x).u.obj) +#define __JSVAL_VAR(x) ((x).u.v) + +#endif + static inline jsval_t jsval_bool(BOOL b) { jsval_t ret; - ret.type = JSV_BOOL; - ret.u.b = b; + __JSVAL_TYPE(ret) = JSV_BOOL; + __JSVAL_BOOL(ret) = b; return ret; }
static inline jsval_t jsval_string(BSTR str) { jsval_t ret; - ret.type = JSV_STRING; - ret.u.str = str; + __JSVAL_TYPE(ret) = JSV_STRING; + __JSVAL_STR(ret) = str; return ret; }
static inline jsval_t jsval_disp(IDispatch *obj) { jsval_t ret; - ret.type = JSV_OBJECT; - ret.u.obj = obj; + __JSVAL_TYPE(ret) = JSV_OBJECT; + __JSVAL_OBJ(ret) = obj; return ret; }
@@ -71,72 +127,97 @@ static inline jsval_t jsval_obj(jsdisp_t *obj)
static inline jsval_t jsval_null(void) { - jsval_t ret = { JSV_NULL }; + jsval_t ret; + __JSVAL_TYPE(ret) = JSV_NULL; return ret; }
static inline jsval_t jsval_undefined(void) { - jsval_t ret = { JSV_UNDEFINED }; + jsval_t ret; + __JSVAL_TYPE(ret) = JSV_UNDEFINED; return ret; }
static inline jsval_t jsval_number(double n) { jsval_t ret; +#ifdef JSVAL_DOUBLE_LAYOUT_PTR32 + ret.u.n = n; + /* normalize NaN value */ + if((ret.u.s.tag & 0x7ff00000) == 0x7ff00000) { + /* isinf */ + if(ret.u.s.tag & 0xfffff) { + ret.u.s.tag = 0x7ff00000; + ret.u.s.u.as_uintptr = ~0; + }else if(ret.u.s.u.as_uintptr) { + ret.u.s.tag = 0x7ff00000; + } + } + return ret; +#else ret.type = JSV_NUMBER; ret.u.n = n; +#endif return ret; }
-static inline jsval_type_t jsval_type(jsval_t v) -{ - return v.type; -} - static inline BOOL is_object_instance(jsval_t v) { - return v.type == JSV_OBJECT; + return __JSVAL_TYPE(v) == JSV_OBJECT; }
static inline BOOL is_undefined(jsval_t v) { - return v.type == JSV_UNDEFINED; + return __JSVAL_TYPE(v) == JSV_UNDEFINED; }
static inline BOOL is_null(jsval_t v) { - return v.type == JSV_NULL; + return __JSVAL_TYPE(v) == JSV_NULL; }
static inline BOOL is_null_instance(jsval_t v) { - return v.type == JSV_NULL || (v.type == JSV_OBJECT && !v.u.obj); + return is_null(v) || (is_object_instance(v) && !__JSVAL_OBJ(v)); }
static inline BOOL is_string(jsval_t v) { - return v.type == JSV_STRING; + return __JSVAL_TYPE(v) == JSV_STRING; }
static inline BOOL is_number(jsval_t v) { +#ifdef JSVAL_DOUBLE_LAYOUT_PTR32 + return (v.u.s.tag & 0x7ff80000) != 0x7ff80000; +#else return v.type == JSV_NUMBER; +#endif }
static inline BOOL is_variant(jsval_t v) { - return v.type == JSV_VARIANT; + return __JSVAL_TYPE(v) == JSV_VARIANT; }
static inline BOOL is_bool(jsval_t v) { - return v.type == JSV_BOOL; + return __JSVAL_TYPE(v) == JSV_BOOL; +} + +static inline jsval_type_t jsval_type(jsval_t v) +{ +#ifdef JSVAL_DOUBLE_LAYOUT_PTR32 + return is_number(v) ? JSV_NUMBER : v.u.s.tag; +#else + return v.type; +#endif }
static inline IDispatch *get_object(jsval_t v) { - return v.u.obj; + return __JSVAL_OBJ(v); }
static inline double get_number(jsval_t v) @@ -146,17 +227,17 @@ static inline double get_number(jsval_t v)
static inline BSTR get_string(jsval_t v) { - return v.u.str; + return __JSVAL_STR(v); }
static inline VARIANT *get_variant(jsval_t v) { - return v.u.v; + return __JSVAL_VAR(v); }
static inline BOOL get_bool(jsval_t v) { - return v.u.b; + return __JSVAL_BOOL(v); }
HRESULT variant_to_jsval(VARIANT*,jsval_t*) DECLSPEC_HIDDEN;