wbemprox: Add support for uncommitted instances in IWbemClassObject::Get.
[wine] / dlls / jscript / jsval.h
1 /*
2  * Copyright 2012 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #ifndef JSVAL_H
20 #define JSVAL_H
21
22 /*
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.
29  */
30
31 #ifdef __i386__
32 #define JSVAL_DOUBLE_LAYOUT_PTR32
33 #endif
34
35 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
36 /* NaN exponent and our 0x80000 marker */
37 #define JSV_VAL(x) (0x7ff80000|x)
38 #else
39 #define JSV_VAL(x) x
40 #endif
41
42 typedef enum {
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)
50 } jsval_type_t;
51
52 struct _jsval_t {
53 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
54     union {
55         double n;
56         struct {
57             union {
58                 IDispatch *obj;
59                 BSTR str;
60                 BOOL b;
61                 VARIANT *v;
62                 UINT_PTR as_uintptr;
63             } u;
64             jsval_type_t tag;
65         } s;
66     } u;
67 #else
68     jsval_type_t type;
69     union {
70         IDispatch *obj;
71         BSTR str;
72         double n;
73         BOOL b;
74         VARIANT *v;
75     } u;
76 #endif
77 };
78
79 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
80
81 C_ASSERT(sizeof(jsval_t) == sizeof(double));
82
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)
88
89 #else
90
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)
96
97 #endif
98
99 static inline jsval_t jsval_bool(BOOL b)
100 {
101     jsval_t ret;
102     __JSVAL_TYPE(ret) = JSV_BOOL;
103     __JSVAL_BOOL(ret) = b;
104     return ret;
105 }
106
107 static inline jsval_t jsval_string(BSTR str)
108 {
109     jsval_t ret;
110     __JSVAL_TYPE(ret) = JSV_STRING;
111     __JSVAL_STR(ret) = str;
112     return ret;
113 }
114
115 static inline jsval_t jsval_disp(IDispatch *obj)
116 {
117     jsval_t ret;
118     __JSVAL_TYPE(ret) = JSV_OBJECT;
119     __JSVAL_OBJ(ret) = obj;
120     return ret;
121 }
122
123 static inline jsval_t jsval_obj(jsdisp_t *obj)
124 {
125     return jsval_disp(to_disp(obj));
126 }
127
128 static inline jsval_t jsval_null(void)
129 {
130     jsval_t ret;
131     __JSVAL_TYPE(ret) = JSV_NULL;
132     return ret;
133 }
134
135 static inline jsval_t jsval_undefined(void)
136 {
137     jsval_t ret;
138     __JSVAL_TYPE(ret) = JSV_UNDEFINED;
139     return ret;
140 }
141
142 static inline jsval_t jsval_number(double n)
143 {
144     jsval_t ret;
145 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
146     ret.u.n = n;
147     /* normalize NaN value */
148     if((ret.u.s.tag & 0x7ff00000) == 0x7ff00000) {
149         /* isinf */
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;
155         }
156     }
157 #else
158     ret.type = JSV_NUMBER;
159     ret.u.n = n;
160 #endif
161     return ret;
162 }
163
164 static inline BOOL is_object_instance(jsval_t v)
165 {
166     return __JSVAL_TYPE(v) == JSV_OBJECT;
167 }
168
169 static inline BOOL is_undefined(jsval_t v)
170 {
171     return __JSVAL_TYPE(v) == JSV_UNDEFINED;
172 }
173
174 static inline BOOL is_null(jsval_t v)
175 {
176     return __JSVAL_TYPE(v) == JSV_NULL;
177 }
178
179 static inline BOOL is_null_instance(jsval_t v)
180 {
181     return is_null(v) || (is_object_instance(v) && !__JSVAL_OBJ(v));
182 }
183
184 static inline BOOL is_string(jsval_t v)
185 {
186     return __JSVAL_TYPE(v) == JSV_STRING;
187 }
188
189 static inline BOOL is_number(jsval_t v)
190 {
191 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
192     return (v.u.s.tag & 0x7ff80000) != 0x7ff80000;
193 #else
194     return v.type == JSV_NUMBER;
195 #endif
196 }
197
198 static inline BOOL is_variant(jsval_t v)
199 {
200     return __JSVAL_TYPE(v) == JSV_VARIANT;
201 }
202
203 static inline BOOL is_bool(jsval_t v)
204 {
205     return __JSVAL_TYPE(v) == JSV_BOOL;
206 }
207
208 static inline jsval_type_t jsval_type(jsval_t v)
209 {
210 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
211     return is_number(v) ? JSV_NUMBER : v.u.s.tag;
212 #else
213     return v.type;
214 #endif
215 }
216
217 static inline IDispatch *get_object(jsval_t v)
218 {
219     return __JSVAL_OBJ(v);
220 }
221
222 static inline double get_number(jsval_t v)
223 {
224     return v.u.n;
225 }
226
227 static inline BSTR get_string(jsval_t v)
228 {
229     return __JSVAL_STR(v);
230 }
231
232 static inline VARIANT *get_variant(jsval_t v)
233 {
234     return __JSVAL_VAR(v);
235 }
236
237 static inline BOOL get_bool(jsval_t v)
238 {
239     return __JSVAL_BOOL(v);
240 }
241
242 HRESULT variant_to_jsval(VARIANT*,jsval_t*) DECLSPEC_HIDDEN;
243 HRESULT jsval_to_variant(jsval_t,VARIANT*) DECLSPEC_HIDDEN;
244 void jsval_release(jsval_t) DECLSPEC_HIDDEN;
245 HRESULT jsval_copy(jsval_t,jsval_t*) DECLSPEC_HIDDEN;
246
247 #endif