jscript: Pack jsval_t to 64-bit structure on i386.
This commit is contained in:
parent
33331b1ccf
commit
37509e540f
|
@ -239,8 +239,8 @@ HRESULT jsval_variant(jsval_t *val, VARIANT *var)
|
||||||
VARIANT *v;
|
VARIANT *v;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
val->type = JSV_VARIANT;
|
__JSVAL_TYPE(*val) = JSV_VARIANT;
|
||||||
val->u.v = v = heap_alloc(sizeof(VARIANT));
|
__JSVAL_VAR(*val) = v = heap_alloc(sizeof(VARIANT));
|
||||||
if(!v)
|
if(!v)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
|
|
@ -19,17 +19,52 @@
|
||||||
#ifndef JSVAL_H
|
#ifndef JSVAL_H
|
||||||
#define 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 {
|
typedef enum {
|
||||||
JSV_UNDEFINED,
|
JSV_UNDEFINED = JSV_VAL(1),
|
||||||
JSV_NULL,
|
JSV_NULL = JSV_VAL(2),
|
||||||
JSV_OBJECT,
|
JSV_OBJECT = JSV_VAL(3),
|
||||||
JSV_STRING,
|
JSV_STRING = JSV_VAL(4),
|
||||||
JSV_NUMBER,
|
JSV_NUMBER = JSV_VAL(5),
|
||||||
JSV_BOOL,
|
JSV_BOOL = JSV_VAL(6),
|
||||||
JSV_VARIANT
|
JSV_VARIANT = JSV_VAL(7)
|
||||||
} jsval_type_t;
|
} jsval_type_t;
|
||||||
|
|
||||||
struct _jsval_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;
|
jsval_type_t type;
|
||||||
union {
|
union {
|
||||||
IDispatch *obj;
|
IDispatch *obj;
|
||||||
|
@ -38,29 +73,50 @@ struct _jsval_t {
|
||||||
BOOL b;
|
BOOL b;
|
||||||
VARIANT *v;
|
VARIANT *v;
|
||||||
} u;
|
} 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)
|
static inline jsval_t jsval_bool(BOOL b)
|
||||||
{
|
{
|
||||||
jsval_t ret;
|
jsval_t ret;
|
||||||
ret.type = JSV_BOOL;
|
__JSVAL_TYPE(ret) = JSV_BOOL;
|
||||||
ret.u.b = b;
|
__JSVAL_BOOL(ret) = b;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsval_t jsval_string(BSTR str)
|
static inline jsval_t jsval_string(BSTR str)
|
||||||
{
|
{
|
||||||
jsval_t ret;
|
jsval_t ret;
|
||||||
ret.type = JSV_STRING;
|
__JSVAL_TYPE(ret) = JSV_STRING;
|
||||||
ret.u.str = str;
|
__JSVAL_STR(ret) = str;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsval_t jsval_disp(IDispatch *obj)
|
static inline jsval_t jsval_disp(IDispatch *obj)
|
||||||
{
|
{
|
||||||
jsval_t ret;
|
jsval_t ret;
|
||||||
ret.type = JSV_OBJECT;
|
__JSVAL_TYPE(ret) = JSV_OBJECT;
|
||||||
ret.u.obj = obj;
|
__JSVAL_OBJ(ret) = obj;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,72 +127,97 @@ static inline jsval_t jsval_obj(jsdisp_t *obj)
|
||||||
|
|
||||||
static inline jsval_t jsval_null(void)
|
static inline jsval_t jsval_null(void)
|
||||||
{
|
{
|
||||||
jsval_t ret = { JSV_NULL };
|
jsval_t ret;
|
||||||
|
__JSVAL_TYPE(ret) = JSV_NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsval_t jsval_undefined(void)
|
static inline jsval_t jsval_undefined(void)
|
||||||
{
|
{
|
||||||
jsval_t ret = { JSV_UNDEFINED };
|
jsval_t ret;
|
||||||
|
__JSVAL_TYPE(ret) = JSV_UNDEFINED;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsval_t jsval_number(double n)
|
static inline jsval_t jsval_number(double n)
|
||||||
{
|
{
|
||||||
jsval_t ret;
|
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.type = JSV_NUMBER;
|
||||||
ret.u.n = n;
|
ret.u.n = n;
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsval_type_t jsval_type(jsval_t v)
|
|
||||||
{
|
|
||||||
return v.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline BOOL is_object_instance(jsval_t v)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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;
|
return v.type == JSV_NUMBER;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline BOOL is_variant(jsval_t v)
|
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)
|
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)
|
static inline IDispatch *get_object(jsval_t v)
|
||||||
{
|
{
|
||||||
return v.u.obj;
|
return __JSVAL_OBJ(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double get_number(jsval_t 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)
|
static inline BSTR get_string(jsval_t v)
|
||||||
{
|
{
|
||||||
return v.u.str;
|
return __JSVAL_STR(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VARIANT *get_variant(jsval_t 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)
|
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;
|
HRESULT variant_to_jsval(VARIANT*,jsval_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue