Skip to content

Commit b98fc13

Browse files
committed
Create extend byte code flags with function types.
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
1 parent fde0d55 commit b98fc13

File tree

10 files changed

+191
-108
lines changed

10 files changed

+191
-108
lines changed

jerry-core/api/jerry-snapshot.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -161,21 +161,21 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
161161
ecma_compiled_code_t *copied_code_p = (ecma_compiled_code_t *) copied_code_start_p;
162162

163163
#if ENABLED (JERRY_ESNEXT)
164-
if (compiled_code_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
164+
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
165165
{
166166
const char * const error_message_p = "Unsupported feature: tagged template literals.";
167167
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
168168
return 0;
169169
}
170170

171-
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR)
171+
if (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags) == CBC_FUNCTION_CONSTRUCTOR)
172172
{
173173
globals_p->class_found = true;
174174
}
175175
#endif /* ENABLED (JERRY_ESNEXT) */
176176

177177
#if ENABLED (JERRY_BUILTIN_REGEXP)
178-
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
178+
if (!CBC_IS_FUNCTION (compiled_code_p->status_flags))
179179
{
180180
/* Regular expression. */
181181
if (globals_p->snapshot_buffer_write_offset + sizeof (ecma_compiled_code_t) > snapshot_buffer_size)
@@ -228,7 +228,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
228228
}
229229
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
230230

231-
JERRY_ASSERT (compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
231+
JERRY_ASSERT (CBC_IS_FUNCTION (compiled_code_p->status_flags));
232232

233233
if (!snapshot_write_to_buffer_by_offset (snapshot_buffer_p,
234234
snapshot_buffer_size,
@@ -345,7 +345,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
345345
uint8_t *copied_code_start_p = snapshot_buffer_p + globals_p->snapshot_buffer_write_offset;
346346
ecma_compiled_code_t *copied_code_p = (ecma_compiled_code_t *) copied_code_start_p;
347347

348-
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
348+
if (!CBC_IS_FUNCTION (compiled_code_p->status_flags))
349349
{
350350
/* Regular expression literals are not supported. */
351351
const char * const error_message_p = "Regular expression literals are not supported.";
@@ -454,7 +454,7 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
454454
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
455455
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
456456

457-
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
457+
if (CBC_IS_FUNCTION (bytecode_p->status_flags))
458458
{
459459
ecma_value_t *literal_start_p;
460460
uint32_t const_literal_end;
@@ -549,9 +549,8 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
549549
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
550550

551551
#if ENABLED (JERRY_BUILTIN_REGEXP)
552-
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
552+
if (!CBC_IS_FUNCTION (bytecode_p->status_flags))
553553
{
554-
555554
const uint8_t *regex_start_p = ((const uint8_t *) bytecode_p) + sizeof (ecma_compiled_code_t);
556555

557556
/* Real size is stored in refs. */
@@ -564,10 +563,10 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
564563

565564
return (ecma_compiled_code_t *) re_bytecode_p;
566565
}
566+
#else /* !ENABLED (JERRY_BUILTIN_REGEXP) */
567+
JERRY_ASSERT (CBC_IS_FUNCTION (bytecode_p->status_flags));
567568
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
568569

569-
JERRY_ASSERT (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
570-
571570
size_t header_size;
572571
uint32_t argument_end;
573572
uint32_t const_literal_end;
@@ -620,13 +619,13 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
620619

621620
#if ENABLED (JERRY_ESNEXT)
622621
/* function name */
623-
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
622+
if (CBC_FUNCTION_GET_TYPE (bytecode_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
624623
{
625624
extra_bytes += (uint32_t) sizeof (ecma_value_t);
626625
}
627626

628627
/* tagged template literals */
629-
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
628+
if (bytecode_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
630629
{
631630
extra_bytes += (uint32_t) sizeof (ecma_value_t);
632631
}
@@ -1083,7 +1082,7 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
10831082
const ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
10841083
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
10851084

1086-
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
1085+
if (CBC_IS_FUNCTION (bytecode_p->status_flags)
10871086
&& !(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
10881087
{
10891088
const ecma_value_t *literal_start_p;
@@ -1149,7 +1148,7 @@ update_literal_offsets (uint8_t *buffer_p, /**< [in,out] snapshot buffer start *
11491148
const ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
11501149
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
11511150

1152-
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
1151+
if (CBC_IS_FUNCTION (bytecode_p->status_flags)
11531152
&& !(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
11541153
{
11551154
ecma_value_t *literal_start_p;

jerry-core/ecma/base/ecma-gc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
683683
#if ENABLED (JERRY_ESNEXT)
684684
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_p);
685685

686-
if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
686+
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ARROW)
687687
{
688688
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
689689

@@ -1201,7 +1201,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
12011201
ext_func_p->u.function.bytecode_cp));
12021202

12031203
#if ENABLED (JERRY_ESNEXT)
1204-
if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
1204+
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ARROW)
12051205
{
12061206
ecma_free_value_if_not_object (((ecma_arrow_function_t *) object_p)->this_binding);
12071207
ecma_free_value_if_not_object (((ecma_arrow_function_t *) object_p)->new_target);

jerry-core/ecma/base/ecma-globals.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -963,8 +963,8 @@ typedef struct
963963
uint16_t size; /**< real size >> JMEM_ALIGNMENT_LOG */
964964
uint16_t refs; /**< reference counter for the byte code */
965965
uint16_t status_flags; /**< various status flags:
966-
* CBC_CODE_FLAGS_FUNCTION flag tells whether
967-
* the byte code is function or regular expression.
966+
* CBC_IS_FUNCTION check tells whether the byte code
967+
* is function or regular expression.
968968
* If function, the other flags must be CBC_CODE_FLAGS...
969969
* If regexp, the other flags must be RE_FLAG... */
970970
} ecma_compiled_code_t;

jerry-core/ecma/base/ecma-helpers.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
13671367
return;
13681368
}
13691369

1370-
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
1370+
if (CBC_IS_FUNCTION (bytecode_p->status_flags))
13711371
{
13721372
ecma_value_t *literal_start_p = NULL;
13731373
uint32_t literal_end;
@@ -1439,7 +1439,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
14391439
#endif /* ENABLED (JERRY_DEBUGGER) */
14401440

14411441
#if ENABLED (JERRY_ESNEXT)
1442-
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
1442+
if (bytecode_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
14431443
{
14441444
ecma_collection_t *collection_p = ecma_compiled_code_get_tagged_template_collection (bytecode_p);
14451445

@@ -1477,7 +1477,7 @@ ecma_collection_t *
14771477
ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *bytecode_header_p) /**< compiled code */
14781478
{
14791479
JERRY_ASSERT (bytecode_header_p != NULL);
1480-
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS);
1480+
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS);
14811481

14821482
ecma_value_t *base_p = ecma_compiled_code_resolve_function_name (bytecode_header_p);
14831483

@@ -1539,7 +1539,7 @@ ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_h
15391539
ecma_value_t *base_p = ecma_compiled_code_resolve_arguments_start (bytecode_header_p);
15401540

15411541
#if ENABLED (JERRY_ESNEXT)
1542-
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
1542+
if (CBC_FUNCTION_GET_TYPE (bytecode_header_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
15431543
{
15441544
base_p--;
15451545
}

jerry-core/ecma/base/ecma-literal-storage.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
334334
uint32_t const_literal_end;
335335
uint32_t literal_end;
336336

337-
JERRY_ASSERT (compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
337+
JERRY_ASSERT (CBC_IS_FUNCTION (compiled_code_p->status_flags));
338338

339339
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
340340
{
@@ -377,7 +377,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
377377
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
378378
literal_p[i]);
379379

380-
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
380+
if (CBC_IS_FUNCTION (bytecode_p->status_flags)
381381
&& bytecode_p != compiled_code_p)
382382
{
383383
ecma_save_literals_add_compiled_code (bytecode_p, lit_pool_p);
@@ -570,7 +570,7 @@ ecma_snapshot_resolve_serializable_values (ecma_compiled_code_t *compiled_code_p
570570

571571
#if ENABLED (JERRY_ESNEXT)
572572
/* function name */
573-
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
573+
if (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
574574
{
575575
base_p--;
576576
}

jerry-core/ecma/operations/ecma-function-object.c

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,9 @@ ecma_op_function_is_generator (ecma_object_t *obj_p) /**< object */
602602
&& !ecma_get_object_is_builtin (obj_p))
603603
{
604604
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) obj_p;
605-
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
605+
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
606606

607-
return (bytecode_data_p->status_flags & CBC_CODE_FLAGS_GENERATOR) != 0;
607+
return CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_GENERATOR;
608608
}
609609

610610
return false;
@@ -844,26 +844,20 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
844844
uint16_t status_flags = bytecode_data_p->status_flags;
845845

846846
#if ENABLED (JERRY_ESNEXT)
847-
bool is_construct_call = JERRY_CONTEXT (current_new_target) != NULL;
848-
if (JERRY_UNLIKELY (status_flags & (CBC_CODE_FLAGS_CLASS_CONSTRUCTOR | CBC_CODE_FLAGS_GENERATOR)))
849-
{
850-
if (!is_construct_call && (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
851-
{
852-
return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
853-
}
847+
uint16_t function_type = CBC_FUNCTION_GET_TYPE (status_flags);
854848

855-
if ((status_flags & CBC_CODE_FLAGS_GENERATOR) && is_construct_call)
856-
{
857-
return ecma_raise_type_error (ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'."));
858-
}
849+
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_CONSTRUCTOR)
850+
&& JERRY_CONTEXT (current_new_target) == NULL)
851+
{
852+
return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
859853
}
860854
#endif /* ENABLED (JERRY_ESNEXT) */
861855

862856
/* 1. */
863857
#if ENABLED (JERRY_ESNEXT)
864858
ecma_object_t *old_function_object_p = JERRY_CONTEXT (current_function_obj_p);
865859

866-
if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
860+
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_ARROW))
867861
{
868862
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
869863

@@ -921,7 +915,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
921915
}
922916
#if ENABLED (JERRY_ESNEXT)
923917
// ECMAScript v6, 9.2.2.8
924-
if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
918+
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_CONSTRUCTOR))
925919
{
926920
ecma_value_t lexical_this;
927921
lexical_this = (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp) ? ECMA_VALUE_UNINITIALIZED
@@ -1279,20 +1273,39 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
12791273

12801274
ecma_object_t *new_this_obj_p = NULL;
12811275
ecma_value_t this_arg;
1276+
1277+
#if ENABLED (JERRY_ESNEXT)
12821278
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
12831279
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
12841280

1285-
if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1281+
if (!CBC_FUNCTION_IS_CONSTRUCTABLE (byte_code_p->status_flags))
12861282
{
1287-
if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
1283+
const char *message_p;
1284+
1285+
switch (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags))
12881286
{
1289-
return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor."));
1287+
case CBC_FUNCTION_GENERATOR:
1288+
{
1289+
message_p = ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'.");
1290+
break;
1291+
}
1292+
case CBC_FUNCTION_ARROW:
1293+
{
1294+
message_p = ECMA_ERR_MSG ("Arrow functions cannot be invoked with 'new'.");
1295+
break;
1296+
}
1297+
default:
1298+
{
1299+
JERRY_ASSERT (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ACCESSOR);
1300+
1301+
message_p = ECMA_ERR_MSG ("Accessor functions cannot be invoked with 'new'.");
1302+
break;
1303+
}
12901304
}
12911305

1292-
return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
1306+
return ecma_raise_type_error (message_p);
12931307
}
12941308

1295-
#if ENABLED (JERRY_ESNEXT)
12961309
/* 6. */
12971310
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
12981311
JERRY_CONTEXT (current_new_target) = new_target_p;
@@ -1367,17 +1380,18 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun
13671380
{
13681381
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
13691382

1370-
if (byte_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
1383+
if (!CBC_FUNCTION_HAS_PROTOTYPE (byte_code_p->status_flags))
1384+
{
1385+
return NULL;
1386+
}
1387+
1388+
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_GENERATOR)
13711389
{
13721390
proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
13731391
0,
13741392
ECMA_OBJECT_TYPE_GENERAL);
13751393
init_constructor = false;
13761394
}
1377-
else if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1378-
{
1379-
return NULL;
1380-
}
13811395
}
13821396
#endif /* ENABLED (JERRY_ESNEXT) */
13831397

@@ -1475,7 +1489,7 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
14751489
ECMA_SET_SECOND_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp);
14761490
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
14771491

1478-
if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
1492+
if (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
14791493
{
14801494
ecma_value_t value = *ecma_compiled_code_resolve_function_name (bytecode_data_p);
14811495
if (value != ECMA_VALUE_EMPTY)
@@ -1695,7 +1709,7 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
16951709
bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
16961710

16971711
#if ENABLED (JERRY_ESNEXT)
1698-
if (bytecode_data_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1712+
if (!CBC_FUNCTION_HAS_PROTOTYPE (bytecode_data_p->status_flags))
16991713
{
17001714
return;
17011715
}

jerry-core/ecma/operations/ecma-regexp-object.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ typedef enum
4141
RE_FLAG_MULTILINE = (1u << 3), /**< ECMA-262 v5, 15.10.7.4 */
4242
RE_FLAG_STICKY = (1u << 4), /**< ECMA-262 v6, 21.2.5.12 */
4343
RE_FLAG_UNICODE = (1u << 5) /**< ECMA-262 v6, 21.2.5.15 */
44+
45+
/* Bits from bit 13 is reserved for function types (see CBC_FUNCTION_TYPE_SHIFT). */
4446
} ecma_regexp_flags_t;
4547

4648
/**

0 commit comments

Comments
 (0)