1 // bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*"
2 // bindgen-flags: -- -std=c++11
3
4 /**
5 * These typedefs are hacky, but keep our tests consistent across 64-bit
6 * platforms, otherwise the id's change and our CI is unhappy.
7 */
8 typedef unsigned char uint8_t;
9 typedef int int32_t;
10 typedef unsigned int uint32_t;
11 typedef unsigned long long uint64_t;
12 typedef unsigned long long size_t;
13 typedef unsigned long long uintptr_t;
14
15
16 #define JS_PUNBOX64
17 #define IS_LITTLE_ENDIAN
18
19 /*
20 * Try to get jsvals 64-bit aligned. We could almost assert that all values are
21 * aligned, but MSVC and GCC occasionally break alignment.
22 */
23 #if defined(__GNUC__) || defined(__xlc__) || defined(__xlC__)
24 # define JSVAL_ALIGNMENT __attribute__((aligned (8)))
25 #elif defined(_MSC_VER)
26 /*
27 * Structs can be aligned with MSVC, but not if they are used as parameters,
28 * so we just don't try to align.
29 */
30 # define JSVAL_ALIGNMENT
31 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
32 # define JSVAL_ALIGNMENT
33 #elif defined(__HP_cc) || defined(__HP_aCC)
34 # define JSVAL_ALIGNMENT
35 #endif
36
37 #if defined(JS_PUNBOX64)
38 # define JSVAL_TAG_SHIFT 47
39 #endif
40
41 /*
42 * We try to use enums so that printing a jsval_layout in the debugger shows
43 * nice symbolic type tags, however we can only do this when we can force the
44 * underlying type of the enum to be the desired size.
45 */
46 #if !defined(__SUNPRO_CC) && !defined(__xlC__)
47
48 #if defined(_MSC_VER)
49 # define JS_ENUM_HEADER(id, type) enum id : type
50 # define JS_ENUM_FOOTER(id)
51 #else
52 # define JS_ENUM_HEADER(id, type) enum id
53 # define JS_ENUM_FOOTER(id) __attribute__((packed))
54 #endif
55
56 /* Remember to propagate changes to the C defines below. */
JS_ENUM_HEADER(JSValueType,uint8_t)57 JS_ENUM_HEADER(JSValueType, uint8_t)
58 {
59 JSVAL_TYPE_DOUBLE = 0x00,
60 JSVAL_TYPE_INT32 = 0x01,
61 JSVAL_TYPE_UNDEFINED = 0x02,
62 JSVAL_TYPE_BOOLEAN = 0x03,
63 JSVAL_TYPE_MAGIC = 0x04,
64 JSVAL_TYPE_STRING = 0x05,
65 JSVAL_TYPE_SYMBOL = 0x06,
66 JSVAL_TYPE_NULL = 0x07,
67 JSVAL_TYPE_OBJECT = 0x08,
68
69 /* These never appear in a jsval; they are only provided as an out-of-band value. */
70 JSVAL_TYPE_UNKNOWN = 0x20,
71 JSVAL_TYPE_MISSING = 0x21
72 } JS_ENUM_FOOTER(JSValueType);
73
74 static_assert(sizeof(JSValueType) == 1,
75 "compiler typed enum support is apparently buggy");
76
77 #if defined(JS_NUNBOX32)
78
79 /* Remember to propagate changes to the C defines below. */
JS_ENUM_HEADER(JSValueTag,uint32_t)80 JS_ENUM_HEADER(JSValueTag, uint32_t)
81 {
82 JSVAL_TAG_CLEAR = 0xFFFFFF80,
83 JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32,
84 JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED,
85 JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING,
86 JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL,
87 JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN,
88 JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC,
89 JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL,
90 JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT
91 } JS_ENUM_FOOTER(JSValueTag);
92
93 static_assert(sizeof(JSValueTag) == sizeof(uint32_t),
94 "compiler typed enum support is apparently buggy");
95
96 #elif defined(JS_PUNBOX64)
97
98 /* Remember to propagate changes to the C defines below. */
JS_ENUM_HEADER(JSValueTag,uint32_t)99 JS_ENUM_HEADER(JSValueTag, uint32_t)
100 {
101 JSVAL_TAG_MAX_DOUBLE = 0x1FFF0,
102 JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32,
103 JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED,
104 JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING,
105 JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL,
106 JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN,
107 JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC,
108 JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL,
109 JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT
110 } JS_ENUM_FOOTER(JSValueTag);
111
112 static_assert(sizeof(JSValueTag) == sizeof(uint32_t),
113 "compiler typed enum support is apparently buggy");
114
JS_ENUM_HEADER(JSValueShiftedTag,uint64_t)115 JS_ENUM_HEADER(JSValueShiftedTag, uint64_t)
116 {
117 JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF),
118 JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT),
119 JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT),
120 JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT),
121 JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT),
122 JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT),
123 JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT),
124 JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT),
125 JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT)
126 } JS_ENUM_FOOTER(JSValueShiftedTag);
127
128 static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t),
129 "compiler typed enum support is apparently buggy");
130
131 #endif
132
133 /*
134 * All our supported compilers implement C++11 |enum Foo : T| syntax, so don't
135 * expose these macros. (This macro exists *only* because gcc bug 51242
136 * <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51242> makes bit-fields of
137 * typed enums trigger a warning that can't be turned off. Don't expose it
138 * beyond this file!)
139 */
140 #undef JS_ENUM_HEADER
141 #undef JS_ENUM_FOOTER
142
143 #else /* !defined(__SUNPRO_CC) && !defined(__xlC__) */
144
145 typedef uint8_t JSValueType;
146 #define JSVAL_TYPE_DOUBLE ((uint8_t)0x00)
147 #define JSVAL_TYPE_INT32 ((uint8_t)0x01)
148 #define JSVAL_TYPE_UNDEFINED ((uint8_t)0x02)
149 #define JSVAL_TYPE_BOOLEAN ((uint8_t)0x03)
150 #define JSVAL_TYPE_MAGIC ((uint8_t)0x04)
151 #define JSVAL_TYPE_STRING ((uint8_t)0x05)
152 #define JSVAL_TYPE_SYMBOL ((uint8_t)0x06)
153 #define JSVAL_TYPE_NULL ((uint8_t)0x07)
154 #define JSVAL_TYPE_OBJECT ((uint8_t)0x08)
155 #define JSVAL_TYPE_UNKNOWN ((uint8_t)0x20)
156
157 #if defined(JS_NUNBOX32)
158
159 typedef uint32_t JSValueTag;
160 #define JSVAL_TAG_CLEAR ((uint32_t)(0xFFFFFF80))
161 #define JSVAL_TAG_INT32 ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32))
162 #define JSVAL_TAG_UNDEFINED ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED))
163 #define JSVAL_TAG_STRING ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING))
164 #define JSVAL_TAG_SYMBOL ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL))
165 #define JSVAL_TAG_BOOLEAN ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN))
166 #define JSVAL_TAG_MAGIC ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC))
167 #define JSVAL_TAG_NULL ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL))
168 #define JSVAL_TAG_OBJECT ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT))
169
170 #elif defined(JS_PUNBOX64)
171
172 typedef uint32_t JSValueTag;
173 #define JSVAL_TAG_MAX_DOUBLE ((uint32_t)(0x1FFF0))
174 #define JSVAL_TAG_INT32 (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32)
175 #define JSVAL_TAG_UNDEFINED (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED)
176 #define JSVAL_TAG_STRING (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING)
177 #define JSVAL_TAG_SYMBOL (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL)
178 #define JSVAL_TAG_BOOLEAN (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN)
179 #define JSVAL_TAG_MAGIC (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC)
180 #define JSVAL_TAG_NULL (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL)
181 #define JSVAL_TAG_OBJECT (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT)
182
183 typedef uint64_t JSValueShiftedTag;
184 #define JSVAL_SHIFTED_TAG_MAX_DOUBLE ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF)
185 #define JSVAL_SHIFTED_TAG_INT32 (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT)
186 #define JSVAL_SHIFTED_TAG_UNDEFINED (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT)
187 #define JSVAL_SHIFTED_TAG_STRING (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT)
188 #define JSVAL_SHIFTED_TAG_SYMBOL (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT)
189 #define JSVAL_SHIFTED_TAG_BOOLEAN (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT)
190 #define JSVAL_SHIFTED_TAG_MAGIC (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT)
191 #define JSVAL_SHIFTED_TAG_NULL (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT)
192 #define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT)
193
194 #endif /* JS_PUNBOX64 */
195 #endif /* !defined(__SUNPRO_CC) && !defined(__xlC__) */
196
197 #if defined(JS_NUNBOX32)
198
199 #define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type)))
200
201 #define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL
202 #define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT
203 #define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32
204 #define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING
205
206 #elif defined(JS_PUNBOX64)
207
208 #define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL
209 #define JSVAL_TAG_MASK 0xFFFF800000000000LL
210 #define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type)))
211 #define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT)
212
213 #define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL
214 #define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT
215 #define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32
216 #define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING
217
218 #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL
219 #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT
220 #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED
221 #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING
222
223 #endif /* JS_PUNBOX64 */
224
225 typedef enum JSWhyMagic
226 {
227 /** a hole in a native object's elements */
228 JS_ELEMENTS_HOLE,
229
230 /** there is not a pending iterator value */
231 JS_NO_ITER_VALUE,
232
233 /** exception value thrown when closing a generator */
234 JS_GENERATOR_CLOSING,
235
236 /** compiler sentinel value */
237 JS_NO_CONSTANT,
238
239 /** used in debug builds to catch tracing errors */
240 JS_THIS_POISON,
241
242 /** used in debug builds to catch tracing errors */
243 JS_ARG_POISON,
244
245 /** an empty subnode in the AST serializer */
246 JS_SERIALIZE_NO_NODE,
247
248 /** lazy arguments value on the stack */
249 JS_LAZY_ARGUMENTS,
250
251 /** optimized-away 'arguments' value */
252 JS_OPTIMIZED_ARGUMENTS,
253
254 /** magic value passed to natives to indicate construction */
255 JS_IS_CONSTRUCTING,
256
257 /** arguments.callee has been overwritten */
258 JS_OVERWRITTEN_CALLEE,
259
260 /** value of static block object slot */
261 JS_BLOCK_NEEDS_CLONE,
262
263 /** see class js::HashableValue */
264 JS_HASH_KEY_EMPTY,
265
266 /** error while running Ion code */
267 JS_ION_ERROR,
268
269 /** missing recover instruction result */
270 JS_ION_BAILOUT,
271
272 /** optimized out slot */
273 JS_OPTIMIZED_OUT,
274
275 /** uninitialized lexical bindings that produce ReferenceError on touch. */
276 JS_UNINITIALIZED_LEXICAL,
277
278 /** for local use */
279 JS_GENERIC_MAGIC,
280
281 JS_WHY_MAGIC_COUNT
282 } JSWhyMagic;
283
284 #if defined(IS_LITTLE_ENDIAN)
285 # if defined(JS_NUNBOX32)
286 typedef union jsval_layout
287 {
288 uint64_t asBits;
289 struct {
290 union {
291 int32_t i32;
292 uint32_t u32;
293 uint32_t boo; // Don't use |bool| -- it must be four bytes.
294 JSString* str;
295 JS::Symbol* sym;
296 JSObject* obj;
297 js::gc::Cell* cell;
298 void* ptr;
299 JSWhyMagic why;
300 size_t word;
301 uintptr_t uintptr;
302 } payload;
303 JSValueTag tag;
304 } s;
305 double asDouble;
306 void* asPtr;
307 } JSVAL_ALIGNMENT jsval_layout;
308 # elif defined(JS_PUNBOX64)
309 typedef union jsval_layout
310 {
311 uint64_t asBits;
312 #if !defined(_WIN64)
313 /* MSVC does not pack these correctly :-( */
314 struct {
315 uint64_t payload47 : 47;
316 JSValueTag tag : 17;
317 } debugView;
318 #endif
319 struct {
320 union {
321 int32_t i32;
322 uint32_t u32;
323 JSWhyMagic why;
324 } payload;
325 } s;
326 double asDouble;
327 void* asPtr;
328 size_t asWord;
329 uintptr_t asUIntPtr;
330 } JSVAL_ALIGNMENT jsval_layout;
331 # endif /* JS_PUNBOX64 */
332 #else /* defined(IS_LITTLE_ENDIAN) */
333 # if defined(JS_NUNBOX32)
334 typedef union jsval_layout
335 {
336 uint64_t asBits;
337 struct {
338 JSValueTag tag;
339 union {
340 int32_t i32;
341 uint32_t u32;
342 uint32_t boo; // Don't use |bool| -- it must be four bytes.
343 JSString* str;
344 JS::Symbol* sym;
345 JSObject* obj;
346 js::gc::Cell* cell;
347 void* ptr;
348 JSWhyMagic why;
349 size_t word;
350 uintptr_t uintptr;
351 } payload;
352 } s;
353 double asDouble;
354 void* asPtr;
355 } JSVAL_ALIGNMENT jsval_layout;
356 # elif defined(JS_PUNBOX64)
357 typedef union jsval_layout
358 {
359 uint64_t asBits;
360 struct {
361 JSValueTag tag : 17;
362 uint64_t payload47 : 47;
363 } debugView;
364 struct {
365 uint32_t padding;
366 union {
367 int32_t i32;
368 uint32_t u32;
369 JSWhyMagic why;
370 } payload;
371 } s;
372 double asDouble;
373 void* asPtr;
374 size_t asWord;
375 uintptr_t asUIntPtr;
376 } JSVAL_ALIGNMENT jsval_layout;
377 # endif /* JS_PUNBOX64 */
378 #endif /* defined(IS_LITTLE_ENDIAN) */
379
380 /*
381 * For codesize purposes on some platforms, it's important that the
382 * compiler know that JS::Values constructed from constant values can be
383 * folded to constant bit patterns at compile time, rather than
384 * constructed at runtime. Doing this requires a fair amount of C++11
385 * features, which are not supported on all of our compilers. Set up
386 * some defines and helper macros in an attempt to confine the ugliness
387 * here, rather than scattering it all about the file. The important
388 * features are:
389 *
390 * - constexpr;
391 * - defaulted functions;
392 * - C99-style designated initializers.
393 */
394 #if defined(__clang__)
395 # if __has_feature(cxx_constexpr) && __has_feature(cxx_defaulted_functions)
396 # define JS_VALUE_IS_CONSTEXPR
397 # endif
398 #elif defined(__GNUC__)
399 /*
400 * We need 4.5 for defaulted functions, 4.6 for constexpr, 4.7 because 4.6
401 * doesn't understand |(X) { .field = ... }| syntax, and 4.7.3 because
402 * versions prior to that have bugs in the C++ front-end that cause crashes.
403 */
404 # if MOZ_GCC_VERSION_AT_LEAST(4, 7, 3)
405 # define JS_VALUE_IS_CONSTEXPR
406 # endif
407 #endif
408
409 #if defined(JS_VALUE_IS_CONSTEXPR)
410 # define JS_RETURN_LAYOUT_FROM_BITS(BITS) \
411 return (jsval_layout) { .asBits = (BITS) }
412 # define JS_VALUE_CONSTEXPR MOZ_CONSTEXPR
413 # define JS_VALUE_CONSTEXPR_VAR MOZ_CONSTEXPR_VAR
414 #else
415 # define JS_RETURN_LAYOUT_FROM_BITS(BITS) \
416 jsval_layout l; \
417 l.asBits = (BITS); \
418 return l;
419 # define JS_VALUE_CONSTEXPR
420 # define JS_VALUE_CONSTEXPR_VAR const
421 #endif
422
423 struct Value {
424 jsval_layout data;
425 };
426