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
25 * jsval_t structure is used to represent JavaScript dynamically-typed values.
26 * It's a (type,value) pair, usually represented as a structure of enum (type)
27 * and union (value of given type). For both memory and speed performance, we
28 * use tricks allowing storing both values as a struct with size equal to
29 * size of double (that is 64-bit) on 32-bit systems. For that, we use the fact
30 * that NaN value representation has 52 (almost) free bits.
34 #define JSVAL_DOUBLE_LAYOUT_PTR32
37 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
38 /* NaN exponent, quiet bit 0x80000 and our 0x10000 marker */
39 #define JSV_VAL(x) (0x7ff90000|x)
45 JSV_UNDEFINED
= JSV_VAL(1),
46 JSV_NULL
= JSV_VAL(2),
47 JSV_OBJECT
= JSV_VAL(3),
48 JSV_STRING
= JSV_VAL(4),
49 JSV_NUMBER
= JSV_VAL(5),
50 JSV_BOOL
= JSV_VAL(6),
51 JSV_VARIANT
= JSV_VAL(7)
55 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
81 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
83 C_ASSERT(sizeof(jsval_t
) == sizeof(double));
85 #define __JSVAL_TYPE(x) ((x).u.s.tag)
86 #define __JSVAL_BOOL(x) ((x).u.s.u.b)
87 #define __JSVAL_STR(x) ((x).u.s.u.str)
88 #define __JSVAL_OBJ(x) ((x).u.s.u.obj)
89 #define __JSVAL_VAR(x) ((x).u.s.u.v)
93 #define __JSVAL_TYPE(x) ((x).type)
94 #define __JSVAL_BOOL(x) ((x).u.b)
95 #define __JSVAL_STR(x) ((x).u.str)
96 #define __JSVAL_OBJ(x) ((x).u.obj)
97 #define __JSVAL_VAR(x) ((x).u.v)
101 static inline jsval_t
jsval_bool(BOOL b
)
104 __JSVAL_TYPE(ret
) = JSV_BOOL
;
105 __JSVAL_BOOL(ret
) = b
;
109 static inline jsval_t
jsval_string(jsstr_t
*str
)
112 __JSVAL_TYPE(ret
) = JSV_STRING
;
113 __JSVAL_STR(ret
) = str
;
117 static inline jsval_t
jsval_disp(IDispatch
*obj
)
120 __JSVAL_TYPE(ret
) = JSV_OBJECT
;
121 __JSVAL_OBJ(ret
) = obj
;
125 static inline jsval_t
jsval_obj(jsdisp_t
*obj
)
127 return jsval_disp(to_disp(obj
));
130 static inline jsval_t
jsval_null(void)
133 __JSVAL_TYPE(ret
) = JSV_NULL
;
134 __JSVAL_BOOL(ret
) = FALSE
;
138 static inline jsval_t
jsval_null_disp(void)
141 __JSVAL_TYPE(ret
) = JSV_NULL
;
142 __JSVAL_BOOL(ret
) = TRUE
;
146 static inline jsval_t
jsval_undefined(void)
149 __JSVAL_TYPE(ret
) = JSV_UNDEFINED
;
153 static inline jsval_t
jsval_number(double n
)
156 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
158 /* normalize NaN value */
159 if((ret
.u
.s
.tag
& 0x7ff00000) == 0x7ff00000) {
161 if(ret
.u
.s
.tag
& 0xfffff) {
162 ret
.u
.s
.tag
= 0x7ff80000;
163 ret
.u
.s
.u
.as_uintptr
= ~0;
164 }else if(ret
.u
.s
.u
.as_uintptr
) {
165 ret
.u
.s
.tag
= 0x7ff80000;
169 ret
.type
= JSV_NUMBER
;
175 static inline BOOL
is_object_instance(jsval_t v
)
177 return __JSVAL_TYPE(v
) == JSV_OBJECT
;
180 static inline BOOL
is_undefined(jsval_t v
)
182 return __JSVAL_TYPE(v
) == JSV_UNDEFINED
;
185 static inline BOOL
is_null(jsval_t v
)
187 return __JSVAL_TYPE(v
) == JSV_NULL
;
190 static inline BOOL
is_null_disp(jsval_t v
)
192 return is_null(v
) && __JSVAL_BOOL(v
);
195 static inline BOOL
is_string(jsval_t v
)
197 return __JSVAL_TYPE(v
) == JSV_STRING
;
200 static inline BOOL
is_number(jsval_t v
)
202 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
203 return (v
.u
.s
.tag
& 0x7ff10000) != 0x7ff10000;
205 return v
.type
== JSV_NUMBER
;
209 static inline BOOL
is_variant(jsval_t v
)
211 return __JSVAL_TYPE(v
) == JSV_VARIANT
;
214 static inline BOOL
is_bool(jsval_t v
)
216 return __JSVAL_TYPE(v
) == JSV_BOOL
;
219 static inline jsval_type_t
jsval_type(jsval_t v
)
221 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
222 return is_number(v
) ? JSV_NUMBER
: v
.u
.s
.tag
;
228 static inline IDispatch
*get_object(jsval_t v
)
230 return __JSVAL_OBJ(v
);
233 static inline double get_number(jsval_t v
)
238 static inline jsstr_t
*get_string(jsval_t v
)
240 return __JSVAL_STR(v
);
243 static inline VARIANT
*get_variant(jsval_t v
)
245 return __JSVAL_VAR(v
);
248 static inline BOOL
get_bool(jsval_t v
)
250 return __JSVAL_BOOL(v
);
253 HRESULT
variant_to_jsval(script_ctx_t
*,VARIANT
*,jsval_t
*);
254 HRESULT
jsval_to_variant(jsval_t
,VARIANT
*);
255 void jsval_release(jsval_t
);
256 HRESULT
jsval_copy(jsval_t
,jsval_t
*);