2 * Copyright 2012 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * jsval_t structure is used to represent JavaScript dynamically-typed values.
24 * It's a (type,value) pair, usually represented as a structure of enum (type)
25 * and union (value of given type). For both memory and speed performance, we
26 * use tricks allowing storing both values as a struct with size equal to
27 * size of double (that is 64-bit) on 32-bit systems. For that, we use the fact
28 * that NaN value representation has 52 (almost) free bits.
32 #define JSVAL_DOUBLE_LAYOUT_PTR32
35 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
36 /* NaN exponent and our 0x80000 marker */
37 #define JSV_VAL(x) (0x7ff80000|x)
43 JSV_UNDEFINED
= JSV_VAL(1),
44 JSV_NULL
= JSV_VAL(2),
45 JSV_OBJECT
= JSV_VAL(3),
46 JSV_STRING
= JSV_VAL(4),
47 JSV_NUMBER
= JSV_VAL(5),
48 JSV_BOOL
= JSV_VAL(6),
49 JSV_VARIANT
= JSV_VAL(7)
53 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
79 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
81 C_ASSERT(sizeof(jsval_t
) == sizeof(double));
83 #define __JSVAL_TYPE(x) ((x).u.s.tag)
84 #define __JSVAL_BOOL(x) ((x).u.s.u.b)
85 #define __JSVAL_STR(x) ((x).u.s.u.str)
86 #define __JSVAL_OBJ(x) ((x).u.s.u.obj)
87 #define __JSVAL_VAR(x) ((x).u.s.u.v)
91 #define __JSVAL_TYPE(x) ((x).type)
92 #define __JSVAL_BOOL(x) ((x).u.b)
93 #define __JSVAL_STR(x) ((x).u.str)
94 #define __JSVAL_OBJ(x) ((x).u.obj)
95 #define __JSVAL_VAR(x) ((x).u.v)
99 static inline jsval_t
jsval_bool(BOOL b
)
102 __JSVAL_TYPE(ret
) = JSV_BOOL
;
103 __JSVAL_BOOL(ret
) = b
;
107 static inline jsval_t
jsval_string(BSTR str
)
110 __JSVAL_TYPE(ret
) = JSV_STRING
;
111 __JSVAL_STR(ret
) = str
;
115 static inline jsval_t
jsval_disp(IDispatch
*obj
)
118 __JSVAL_TYPE(ret
) = JSV_OBJECT
;
119 __JSVAL_OBJ(ret
) = obj
;
123 static inline jsval_t
jsval_obj(jsdisp_t
*obj
)
125 return jsval_disp(to_disp(obj
));
128 static inline jsval_t
jsval_null(void)
131 __JSVAL_TYPE(ret
) = JSV_NULL
;
135 static inline jsval_t
jsval_undefined(void)
138 __JSVAL_TYPE(ret
) = JSV_UNDEFINED
;
142 static inline jsval_t
jsval_number(double n
)
145 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
147 /* normalize NaN value */
148 if((ret
.u
.s
.tag
& 0x7ff00000) == 0x7ff00000) {
150 if(ret
.u
.s
.tag
& 0xfffff) {
151 ret
.u
.s
.tag
= 0x7ff00000;
152 ret
.u
.s
.u
.as_uintptr
= ~0;
153 }else if(ret
.u
.s
.u
.as_uintptr
) {
154 ret
.u
.s
.tag
= 0x7ff00000;
159 ret
.type
= JSV_NUMBER
;
165 static inline BOOL
is_object_instance(jsval_t v
)
167 return __JSVAL_TYPE(v
) == JSV_OBJECT
;
170 static inline BOOL
is_undefined(jsval_t v
)
172 return __JSVAL_TYPE(v
) == JSV_UNDEFINED
;
175 static inline BOOL
is_null(jsval_t v
)
177 return __JSVAL_TYPE(v
) == JSV_NULL
;
180 static inline BOOL
is_null_instance(jsval_t v
)
182 return is_null(v
) || (is_object_instance(v
) && !__JSVAL_OBJ(v
));
185 static inline BOOL
is_string(jsval_t v
)
187 return __JSVAL_TYPE(v
) == JSV_STRING
;
190 static inline BOOL
is_number(jsval_t v
)
192 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
193 return (v
.u
.s
.tag
& 0x7ff80000) != 0x7ff80000;
195 return v
.type
== JSV_NUMBER
;
199 static inline BOOL
is_variant(jsval_t v
)
201 return __JSVAL_TYPE(v
) == JSV_VARIANT
;
204 static inline BOOL
is_bool(jsval_t v
)
206 return __JSVAL_TYPE(v
) == JSV_BOOL
;
209 static inline jsval_type_t
jsval_type(jsval_t v
)
211 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
212 return is_number(v
) ? JSV_NUMBER
: v
.u
.s
.tag
;
218 static inline IDispatch
*get_object(jsval_t v
)
220 return __JSVAL_OBJ(v
);
223 static inline double get_number(jsval_t v
)
228 static inline BSTR
get_string(jsval_t v
)
230 return __JSVAL_STR(v
);
233 static inline VARIANT
*get_variant(jsval_t v
)
235 return __JSVAL_VAR(v
);
238 static inline BOOL
get_bool(jsval_t v
)
240 return __JSVAL_BOOL(v
);
243 HRESULT
variant_to_jsval(VARIANT
*,jsval_t
*) DECLSPEC_HIDDEN
;
244 HRESULT
jsval_to_variant(jsval_t
,VARIANT
*) DECLSPEC_HIDDEN
;
245 void jsval_release(jsval_t
) DECLSPEC_HIDDEN
;
246 HRESULT
jsval_copy(jsval_t
,jsval_t
*) DECLSPEC_HIDDEN
;