windows.networking.hostname/tests: Check if passed HSTRING is duplicated.
[wine.git] / dlls / jscript / jsval.h
blob16aacda71620c4695e29a00cc10089ac350d74fd
1 /*
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
19 #ifndef JSVAL_H
20 #define JSVAL_H
22 #include "jsstr.h"
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.
33 #ifdef __i386__
34 #define JSVAL_DOUBLE_LAYOUT_PTR32
35 #endif
37 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
38 /* NaN exponent, quiet bit 0x80000 and our 0x10000 marker */
39 #define JSV_VAL(x) (0x7ff90000|x)
40 #else
41 #define JSV_VAL(x) x
42 #endif
44 typedef enum {
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)
52 } jsval_type_t;
54 struct _jsval_t {
55 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
56 union {
57 double n;
58 struct {
59 union {
60 IDispatch *obj;
61 jsstr_t *str;
62 BOOL b;
63 VARIANT *v;
64 UINT_PTR as_uintptr;
65 } u;
66 jsval_type_t tag;
67 } s;
68 } u;
69 #else
70 jsval_type_t type;
71 union {
72 IDispatch *obj;
73 jsstr_t *str;
74 double n;
75 BOOL b;
76 VARIANT *v;
77 } u;
78 #endif
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)
91 #else
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)
99 #endif
101 static inline jsval_t jsval_bool(BOOL b)
103 jsval_t ret;
104 __JSVAL_TYPE(ret) = JSV_BOOL;
105 __JSVAL_BOOL(ret) = b;
106 return ret;
109 static inline jsval_t jsval_string(jsstr_t *str)
111 jsval_t ret;
112 __JSVAL_TYPE(ret) = JSV_STRING;
113 __JSVAL_STR(ret) = str;
114 return ret;
117 static inline jsval_t jsval_disp(IDispatch *obj)
119 jsval_t ret;
120 __JSVAL_TYPE(ret) = JSV_OBJECT;
121 __JSVAL_OBJ(ret) = obj;
122 return ret;
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)
132 jsval_t ret;
133 __JSVAL_TYPE(ret) = JSV_NULL;
134 __JSVAL_BOOL(ret) = FALSE;
135 return ret;
138 static inline jsval_t jsval_null_disp(void)
140 jsval_t ret;
141 __JSVAL_TYPE(ret) = JSV_NULL;
142 __JSVAL_BOOL(ret) = TRUE;
143 return ret;
146 static inline jsval_t jsval_undefined(void)
148 jsval_t ret;
149 __JSVAL_TYPE(ret) = JSV_UNDEFINED;
150 return ret;
153 static inline jsval_t jsval_number(double n)
155 jsval_t ret;
156 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
157 ret.u.n = n;
158 /* normalize NaN value */
159 if((ret.u.s.tag & 0x7ff00000) == 0x7ff00000) {
160 /* isinf */
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;
168 #else
169 ret.type = JSV_NUMBER;
170 ret.u.n = n;
171 #endif
172 return ret;
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;
204 #else
205 return v.type == JSV_NUMBER;
206 #endif
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;
223 #else
224 return v.type;
225 #endif
228 static inline IDispatch *get_object(jsval_t v)
230 return __JSVAL_OBJ(v);
233 static inline double get_number(jsval_t v)
235 return v.u.n;
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*);
258 #endif