• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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