wininet: Correctly set headers size in CommitUrlCacheEntryW function.
[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     return ret;
158 #else
159     ret.type = JSV_NUMBER;
160     ret.u.n = n;
161 #endif
162     return ret;
163 }
164
165 static inline BOOL is_object_instance(jsval_t v)
166 {
167     return __JSVAL_TYPE(v) == JSV_OBJECT;
168 }
169
170 static inline BOOL is_undefined(jsval_t v)
171 {
172     return __JSVAL_TYPE(v) == JSV_UNDEFINED;
173 }
174
175 static inline BOOL is_null(jsval_t v)
176 {
177     return __JSVAL_TYPE(v) == JSV_NULL;
178 }
179
180 static inline BOOL is_null_instance(jsval_t v)
181 {
182     return is_null(v) || (is_object_instance(v) && !__JSVAL_OBJ(v));
183 }
184
185 static inline BOOL is_string(jsval_t v)
186 {
187     return __JSVAL_TYPE(v) == JSV_STRING;
188 }
189
190 static inline BOOL is_number(jsval_t v)
191 {
192 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
193     return (v.u.s.tag & 0x7ff80000) != 0x7ff80000;
194 #else
195     return v.type == JSV_NUMBER;
196 #endif
197 }
198
199 static inline BOOL is_variant(jsval_t v)
200 {
201     return __JSVAL_TYPE(v) == JSV_VARIANT;
202 }
203
204 static inline BOOL is_bool(jsval_t v)
205 {
206     return __JSVAL_TYPE(v) == JSV_BOOL;
207 }
208
209 static inline jsval_type_t jsval_type(jsval_t v)
210 {
211 #ifdef JSVAL_DOUBLE_LAYOUT_PTR32
212     return is_number(v) ? JSV_NUMBER : v.u.s.tag;
213 #else
214     return v.type;
215 #endif
216 }
217
218 static inline IDispatch *get_object(jsval_t v)
219 {
220     return __JSVAL_OBJ(v);
221 }
222
223 static inline double get_number(jsval_t v)
224 {
225     return v.u.n;
226 }
227
228 static inline BSTR get_string(jsval_t v)
229 {
230     return __JSVAL_STR(v);
231 }
232
233 static inline VARIANT *get_variant(jsval_t v)
234 {
235     return __JSVAL_VAR(v);
236 }
237
238 static inline BOOL get_bool(jsval_t v)
239 {
240     return __JSVAL_BOOL(v);
241 }
242
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;
247
248 #endif