@@ -51,6 +51,99 @@ typedef ecma_value_t (*ecma_builtin_dispatch_routine_t)(uint16_t builtin_routine
51
51
*/
52
52
typedef ecma_value_t (* ecma_builtin_dispatch_call_t )(const ecma_value_t arguments_list [],
53
53
ecma_length_t arguments_number );
54
+ /**
55
+ * Definition of a builtin descriptor which contains the builtin object's:
56
+ * - prototype objects's id (13-bits)
57
+ * - type (3-bits)
58
+ *
59
+ * Layout:
60
+ *
61
+ * |----------------------|---------------|
62
+ * prototype_id(13) obj_type(3)
63
+ */
64
+ typedef uint16_t ecma_builtin_descriptor_t ;
65
+
66
+ /**
67
+ * Bitshift index for get the prototype object's id from a builtin descriptor
68
+ */
69
+ #define ECMA_BUILTIN_PROTOTYPE_ID_SHIFT 3
70
+
71
+ /**
72
+ * Bitmask for get the object's type from a builtin descriptor
73
+ */
74
+ #define ECMA_BUILTIN_OBJECT_TYPE_MASK ((1 << ECMA_BUILTIN_PROTOTYPE_ID_SHIFT) - 1)
75
+
76
+ /**
77
+ * Create a builtin descriptor value
78
+ */
79
+ #define ECMA_MAKE_BUILTIN_DESCRIPTOR (type , proto_id ) \
80
+ (((proto_id) << ECMA_BUILTIN_PROTOTYPE_ID_SHIFT) | (type))
81
+
82
+ /**
83
+ * List of the built-in descriptors.
84
+ */
85
+ static const ecma_builtin_descriptor_t ecma_builtin_descriptors [] =
86
+ {
87
+ /** @cond doxygen_suppress */
88
+ #define BUILTIN (a , b , c , d , e )
89
+ #define BUILTIN_ROUTINE (builtin_id , \
90
+ object_type , \
91
+ object_prototype_builtin_id , \
92
+ is_extensible , \
93
+ lowercase_name ) \
94
+ ECMA_MAKE_BUILTIN_DESCRIPTOR (object_type , object_prototype_builtin_id ),
95
+ #include "ecma-builtins.inc.h"
96
+ #undef BUILTIN
97
+ #undef BUILTIN_ROUTINE
98
+ #define BUILTIN_ROUTINE (a , b , c , d , e )
99
+ #define BUILTIN (builtin_id , \
100
+ object_type , \
101
+ object_prototype_builtin_id , \
102
+ is_extensible , \
103
+ lowercase_name ) \
104
+ ECMA_MAKE_BUILTIN_DESCRIPTOR (object_type , object_prototype_builtin_id ),
105
+ #include "ecma-builtins.inc.h"
106
+ #undef BUILTIN
107
+ #undef BUILTIN_ROUTINE
108
+ /** @endcond */
109
+ };
110
+
111
+ #ifndef JERRY_NDEBUG
112
+ /** @cond doxygen_suppress */
113
+ enum
114
+ {
115
+ ECMA_BUILTIN_EXTENSIBLE_CHECK =
116
+ #define BUILTIN (a , b , c , d , e )
117
+ #define BUILTIN_ROUTINE (builtin_id , \
118
+ object_type , \
119
+ object_prototype_builtin_id , \
120
+ is_extensible , \
121
+ lowercase_name ) \
122
+ (is_extensible != 0 || builtin_id == ECMA_BUILTIN_ID_TYPE_ERROR_THROWER ) &&
123
+ #include "ecma-builtins.inc.h"
124
+ #undef BUILTIN
125
+ #undef BUILTIN_ROUTINE
126
+ #define BUILTIN_ROUTINE (a , b , c , d , e )
127
+ #define BUILTIN (builtin_id , \
128
+ object_type , \
129
+ object_prototype_builtin_id , \
130
+ is_extensible , \
131
+ lowercase_name ) \
132
+ (is_extensible != 0 || builtin_id == ECMA_BUILTIN_ID_TYPE_ERROR_THROWER ) &&
133
+ #include "ecma-builtins.inc.h"
134
+ #undef BUILTIN
135
+ #undef BUILTIN_ROUTINE
136
+ true
137
+ };
138
+ /** @endcond */
139
+
140
+ /**
141
+ * All the builtin object must be extensible except the ThrowTypeError object.
142
+ */
143
+ JERRY_STATIC_ASSERT (ECMA_BUILTIN_EXTENSIBLE_CHECK == true,
144
+ ecma_builtin_must_be_extensible_except_the_builtin_thorw_type_error_object );
145
+ #endif /* !JERRY_NDEBUG */
146
+
54
147
/**
55
148
* List of the built-in routines.
56
149
*/
@@ -240,16 +333,35 @@ ecma_builtin_function_is_routine (ecma_object_t *func_obj_p) /**< function objec
240
333
} /* ecma_builtin_function_is_routine */
241
334
242
335
/**
243
- * Initialize specified built-in object.
244
- *
245
- * @return pointer to the object
336
+ * Instantiate specified ECMA built-in object
246
337
*/
247
- static ecma_object_t *
248
- ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id , /**< built-in ID */
249
- ecma_object_t * prototype_obj_p , /**< prototype object */
250
- ecma_object_type_t obj_type , /**< object's type */
251
- bool is_extensible ) /**< value of object's [[Extensible]] property */
338
+ static void
339
+ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id ) /**< built-in id */
252
340
{
341
+ JERRY_ASSERT (obj_builtin_id < ECMA_BUILTIN_ID__COUNT );
342
+ JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects )[obj_builtin_id ] == NULL );
343
+
344
+ ecma_builtin_descriptor_t builtin_desc = ecma_builtin_descriptors [obj_builtin_id ];
345
+ ecma_builtin_id_t object_prototype_builtin_id = (ecma_builtin_id_t ) builtin_desc >> ECMA_BUILTIN_PROTOTYPE_ID_SHIFT ;
346
+
347
+ ecma_object_t * prototype_obj_p ;
348
+
349
+ if (JERRY_UNLIKELY (object_prototype_builtin_id == ECMA_BUILTIN_ID__COUNT ))
350
+ {
351
+ prototype_obj_p = NULL ;
352
+ }
353
+ else
354
+ {
355
+ if (JERRY_CONTEXT (ecma_builtin_objects )[object_prototype_builtin_id ] == NULL )
356
+ {
357
+ ecma_instantiate_builtin (object_prototype_builtin_id );
358
+ }
359
+ prototype_obj_p = JERRY_CONTEXT (ecma_builtin_objects )[object_prototype_builtin_id ];
360
+ JERRY_ASSERT (prototype_obj_p != NULL );
361
+ }
362
+
363
+ ecma_object_type_t obj_type = (builtin_desc & ECMA_BUILTIN_OBJECT_TYPE_MASK );
364
+
253
365
bool is_extended_built_in = (obj_type == ECMA_OBJECT_TYPE_CLASS
254
366
|| obj_type == ECMA_OBJECT_TYPE_ARRAY );
255
367
@@ -269,10 +381,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
269
381
270
382
ecma_object_t * obj_p = ecma_create_object (prototype_obj_p , ext_object_size , obj_type );
271
383
272
- if (JERRY_UNLIKELY (!is_extensible ))
273
- {
274
- ecma_set_object_extensible (obj_p , false);
275
- }
384
+ ecma_set_object_extensible (obj_p , (obj_builtin_id != ECMA_BUILTIN_ID_TYPE_ERROR_THROWER ));
276
385
277
386
/*
278
387
* [[Class]] property of built-in object is not stored explicitly.
@@ -393,75 +502,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
393
502
}
394
503
}
395
504
396
- return obj_p ;
397
- } /* ecma_builtin_init_object */
398
-
399
- /**
400
- * Helper function for 'ecma_instantiate_builtin'
401
- */
402
- static void
403
- ecma_instantiate_builtin_helper (ecma_builtin_id_t builtin_id , /**< built-in id */
404
- ecma_object_type_t object_type , /**< object type */
405
- ecma_builtin_id_t object_prototype_builtin_id , /**< built-in id of prototype */
406
- bool is_extensible ) /**< value of object's [[Extensible]] property */
407
- {
408
- JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects )[builtin_id ] == NULL );
409
-
410
- ecma_object_t * prototype_obj_p ;
411
- if (object_prototype_builtin_id == ECMA_BUILTIN_ID__COUNT )
412
- {
413
- prototype_obj_p = NULL ;
414
- }
415
- else
416
- {
417
- if (JERRY_CONTEXT (ecma_builtin_objects )[object_prototype_builtin_id ] == NULL )
418
- {
419
- ecma_instantiate_builtin (object_prototype_builtin_id );
420
- }
421
- prototype_obj_p = JERRY_CONTEXT (ecma_builtin_objects )[object_prototype_builtin_id ];
422
- JERRY_ASSERT (prototype_obj_p != NULL );
423
- }
424
-
425
- ecma_object_t * builtin_obj_p = ecma_builtin_init_object (builtin_id ,
426
- prototype_obj_p ,
427
- object_type ,
428
- is_extensible );
429
- JERRY_CONTEXT (ecma_builtin_objects )[builtin_id ] = builtin_obj_p ;
430
- } /* ecma_instantiate_builtin_helper */
431
-
432
- /**
433
- * Instantiate specified ECMA built-in object
434
- */
435
- static void
436
- ecma_instantiate_builtin (ecma_builtin_id_t id ) /**< built-in id */
437
- {
438
- JERRY_ASSERT (id < ECMA_BUILTIN_ID__COUNT );
439
- switch (id )
440
- {
441
- /** @cond doxygen_suppress */
442
- #define BUILTIN (builtin_id , \
443
- object_type , \
444
- object_prototype_builtin_id , \
445
- is_extensible , \
446
- lowercase_name ) \
447
- case builtin_id: \
448
- { \
449
- ecma_instantiate_builtin_helper (builtin_id, \
450
- object_type, \
451
- object_prototype_builtin_id, \
452
- is_extensible); \
453
- break; \
454
- }
455
- #define BUILTIN_ROUTINE (a , b , c , d , e ) BUILTIN(a, b, c, d, e)
456
- #include "ecma-builtins.inc.h"
457
- #undef BUILTIN
458
- #undef BUILTIN_ROUTINE
459
- /** @endcond */
460
- default :
461
- {
462
- JERRY_UNREACHABLE (); /* The built-in is not implemented. */
463
- }
464
- }
505
+ JERRY_CONTEXT (ecma_builtin_objects )[obj_builtin_id ] = obj_p ;
465
506
} /* ecma_instantiate_builtin */
466
507
467
508
/**
0 commit comments