Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cc74bcc

Browse files
author
Robert Fancsik
committedJan 20, 2022
Rework VM dispatch
Overview: - `VM_OC_*` opcodes are removed, now the dispatch is based on the `CBC`/`CBC_EXT` opcode - The common argument decoding is removed, now each opcode resolves it's arguments individually using `VM_DECODE_{EXT}_...` macros. Whenever an argument is decoded the dispatcher continues with the same opcode increased by `VM_OPCODE_DECODED_ARG`. - E.g.: A opcode with 2 literal arguments dispatches as the following: - step_1: `case opcode: goto resolve_first_literal`, opcode increment by `VM_OPCODE_DECODED_ARG`, dispatch again (Hidden by macro) - step_2: `case VM_OPCODE_ONE_LITERAL(opcode): goto resolve_second_literal`, opcode increment by `VM_OPCODE_DECODED_ARG`, dispatch again (Hidden by macro) - step_3: `case VM_OPCODE_TWO_LITERALS (opcode):` Opcode handler implementation goes here. - The opcode handler implementation goes as the following: ```c case VM_OPCODE_TWO_LITERALS (opcode): { VM_DECODE_LITERAL_LITERAL (opcode); /* use left and right value as before */ } ``` - The put result block is optimized, each assignment knows whether an ident or property reference should be resolved - `free_left_value` and `free_both_values` labels are removed, due to the extra long jumps they caused to execute 1 or 2 simple calls. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
1 parent 0ef5094 commit cc74bcc

File tree

12 files changed

+2123
-1953
lines changed

12 files changed

+2123
-1953
lines changed
 

Diff for: ‎docs/05.PORT-API.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ typedef enum
2626
{
2727
JERRY_FATAL_OUT_OF_MEMORY = 10,
2828
JERRY_FATAL_REF_COUNT_LIMIT = 12,
29-
JERRY_FATAL_DISABLED_BYTE_CODE = 13,
30-
JERRY_FATAL_UNTERMINATED_GC_LOOPS = 14,
29+
JERRY_FATAL_UNTERMINATED_GC_LOOPS = 13,
3130
JERRY_FATAL_FAILED_ASSERTION = 120
3231
} jerry_fatal_code_t;
3332
```

Diff for: ‎jerry-core/api/jerry-snapshot.c

+27-46
Original file line numberDiff line numberDiff line change
@@ -34,46 +34,43 @@
3434
#if JERRY_SNAPSHOT_SAVE || JERRY_SNAPSHOT_EXEC
3535

3636
/**
37-
* Get snapshot configuration flags.
37+
* Get snapshot feature configuration flags.
3838
*
39-
* @return configuration flags
39+
* @return feature configuration flags
4040
*/
41-
static inline uint32_t JERRY_ATTR_ALWAYS_INLINE
42-
snapshot_get_global_flags (bool has_regex, /**< regex literal is present */
43-
bool has_class) /**< class literal is present */
41+
static inline jerry_snapshot_feature_flags_t
42+
snapshot_get_feature_flags (void)
4443
{
45-
JERRY_UNUSED (has_regex);
46-
JERRY_UNUSED (has_class);
47-
48-
uint32_t flags = 0;
44+
jerry_snapshot_feature_flags_t flags = JERRY_SNAPSHOT_FEATURE_NONE;
4945

5046
#if JERRY_BUILTIN_REGEXP
51-
flags |= (has_regex ? JERRY_SNAPSHOT_HAS_REGEX_LITERAL : 0);
47+
flags |= JERRY_SNAPSHOT_FEATURE_REGEXP;
5248
#endif /* JERRY_BUILTIN_REGEXP */
49+
#if JERRY_MODULE_SYSTEM
50+
flags |= JERRY_SNAPSHOT_FEATURE_MODULE;
51+
#endif /* JERRY_MODULE_SYSTEM */
52+
#if JERRY_DEBUGGER
53+
flags |= JERRY_SNAPSHOT_FEATURE_DEBUGGER;
54+
#endif /* JERRY_DEBUGGER */
5355
#if JERRY_ESNEXT
54-
flags |= (has_class ? JERRY_SNAPSHOT_HAS_CLASS_LITERAL : 0);
56+
flags |= JERRY_SNAPSHOT_FEATURE_ESNEXT;
5557
#endif /* JERRY_ESNEXT */
5658

5759
return flags;
58-
} /* snapshot_get_global_flags */
60+
} /* snapshot_get_feature_flags */
5961

6062
/**
61-
* Checks whether the global_flags argument matches to the current feature set.
63+
* Validate snapshot header
6264
*
63-
* @return true if global_flags accepted, false otherwise
65+
* @return true - if the header is valid
66+
* false - otherwise
6467
*/
65-
static inline bool JERRY_ATTR_ALWAYS_INLINE
66-
snapshot_check_global_flags (uint32_t global_flags) /**< global flags */
68+
static bool
69+
snapshot_validate_header (const jerry_snapshot_header_t *header_p)
6770
{
68-
#if JERRY_BUILTIN_REGEXP
69-
global_flags &= (uint32_t) ~JERRY_SNAPSHOT_HAS_REGEX_LITERAL;
70-
#endif /* JERRY_BUILTIN_REGEXP */
71-
#if JERRY_ESNEXT
72-
global_flags &= (uint32_t) ~JERRY_SNAPSHOT_HAS_CLASS_LITERAL;
73-
#endif /* JERRY_ESNEXT */
74-
75-
return global_flags == snapshot_get_global_flags (false, false);
76-
} /* snapshot_check_global_flags */
71+
return (header_p->magic == JERRY_SNAPSHOT_MAGIC && header_p->version == JERRY_SNAPSHOT_VERSION
72+
&& (header_p->feature_flags & snapshot_get_feature_flags ()) == header_p->feature_flags);
73+
} /* snapshot_validate_header */
7774

7875
#endif /* JERRY_SNAPSHOT_SAVE || JERRY_SNAPSHOT_EXEC */
7976

@@ -86,8 +83,6 @@ typedef struct
8683
{
8784
size_t snapshot_buffer_write_offset;
8885
ecma_value_t snapshot_error;
89-
bool regex_found;
90-
bool class_found;
9186
} snapshot_globals_t;
9287

9388
/** \addtogroup jerrysnapshot Jerry snapshot operations
@@ -171,11 +166,6 @@ snapshot_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< co
171166
jerry_throw_sz (JERRY_ERROR_RANGE, ecma_get_error_msg (ECMA_ERR_TAGGED_TEMPLATE_LITERALS));
172167
return 0;
173168
}
174-
175-
if (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags) == CBC_FUNCTION_CONSTRUCTOR)
176-
{
177-
globals_p->class_found = true;
178-
}
179169
#endif /* JERRY_ESNEXT */
180170

181171
#if JERRY_BUILTIN_REGEXP
@@ -216,7 +206,6 @@ snapshot_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< co
216206
return 0;
217207
}
218208

219-
globals_p->regex_found = true;
220209
globals_p->snapshot_buffer_write_offset = JERRY_ALIGNUP (globals_p->snapshot_buffer_write_offset, JMEM_ALIGNMENT);
221210

222211
/* Regexp character size is stored in refs. */
@@ -788,8 +777,6 @@ jerry_generate_snapshot (jerry_value_t compiled_code, /**< parsed script or func
788777

789778
globals.snapshot_buffer_write_offset = aligned_header_size;
790779
globals.snapshot_error = ECMA_VALUE_EMPTY;
791-
globals.regex_found = false;
792-
globals.class_found = false;
793780

794781
if (generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC)
795782
{
@@ -808,7 +795,7 @@ jerry_generate_snapshot (jerry_value_t compiled_code, /**< parsed script or func
808795
jerry_snapshot_header_t header;
809796
header.magic = JERRY_SNAPSHOT_MAGIC;
810797
header.version = JERRY_SNAPSHOT_VERSION;
811-
header.global_flags = snapshot_get_global_flags (globals.regex_found, globals.class_found);
798+
header.feature_flags = (uint32_t) snapshot_get_feature_flags ();
812799
header.lit_table_offset = (uint32_t) globals.snapshot_buffer_write_offset;
813800
header.number_of_funcs = 1;
814801
header.func_offsets[0] = aligned_header_size;
@@ -897,8 +884,7 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
897884

898885
const jerry_snapshot_header_t *header_p = (const jerry_snapshot_header_t *) snapshot_data_p;
899886

900-
if (header_p->magic != JERRY_SNAPSHOT_MAGIC || header_p->version != JERRY_SNAPSHOT_VERSION
901-
|| !snapshot_check_global_flags (header_p->global_flags))
887+
if (!snapshot_validate_header (header_p))
902888
{
903889
return jerry_throw_sz (JERRY_ERROR_TYPE, ecma_get_error_msg (ECMA_ERR_INVALID_SNAPSHOT_VERSION_OR_FEATURES));
904890
}
@@ -1219,7 +1205,6 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
12191205
{
12201206
#if JERRY_SNAPSHOT_SAVE
12211207
uint32_t number_of_funcs = 0;
1222-
uint32_t merged_global_flags = 0;
12231208
size_t functions_size = sizeof (jerry_snapshot_header_t);
12241209

12251210
if (number_of_snapshots < 2)
@@ -1241,16 +1226,13 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
12411226

12421227
const jerry_snapshot_header_t *header_p = (const jerry_snapshot_header_t *) inp_buffers_p[i];
12431228

1244-
if (header_p->magic != JERRY_SNAPSHOT_MAGIC || header_p->version != JERRY_SNAPSHOT_VERSION
1245-
|| !snapshot_check_global_flags (header_p->global_flags))
1229+
if (!snapshot_validate_header (header_p))
12461230
{
12471231
*error_p = "invalid snapshot version or unsupported features present";
12481232
ecma_collection_destroy (lit_pool_p);
12491233
return 0;
12501234
}
12511235

1252-
merged_global_flags |= header_p->global_flags;
1253-
12541236
uint32_t start_offset = header_p->func_offsets[0];
12551237
const uint8_t *data_p = (const uint8_t *) inp_buffers_p[i];
12561238
const uint8_t *literal_base_p = data_p + header_p->lit_table_offset;
@@ -1278,7 +1260,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
12781260

12791261
header_p->magic = JERRY_SNAPSHOT_MAGIC;
12801262
header_p->version = JERRY_SNAPSHOT_VERSION;
1281-
header_p->global_flags = merged_global_flags;
1263+
header_p->feature_flags = snapshot_get_feature_flags ();
12821264
header_p->lit_table_offset = (uint32_t) functions_size;
12831265
header_p->number_of_funcs = number_of_funcs;
12841266

@@ -1555,8 +1537,7 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
15551537
const uint8_t *snapshot_data_p = (uint8_t *) snapshot_p;
15561538
const jerry_snapshot_header_t *header_p = (const jerry_snapshot_header_t *) snapshot_data_p;
15571539

1558-
if (snapshot_size <= sizeof (jerry_snapshot_header_t) || header_p->magic != JERRY_SNAPSHOT_MAGIC
1559-
|| header_p->version != JERRY_SNAPSHOT_VERSION || !snapshot_check_global_flags (header_p->global_flags))
1540+
if (snapshot_size <= sizeof (jerry_snapshot_header_t) || !snapshot_validate_header (header_p))
15601541
{
15611542
/* Invalid snapshot format */
15621543
return 0;

Diff for: ‎jerry-core/api/jerry-snapshot.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ typedef struct
2727
* uint32_t alignment. Otherwise some bytes after the header are wasted. */
2828
uint32_t magic; /**< four byte magic number */
2929
uint32_t version; /**< version number */
30-
uint32_t global_flags; /**< global configuration and feature flags */
30+
uint32_t feature_flags; /**< combination of jerry_snapshot_global_flags_t */
3131
uint32_t lit_table_offset; /**< byte offset of the literal table */
3232
uint32_t number_of_funcs; /**< number of primary ECMAScript functions */
3333
uint32_t func_offsets[1]; /**< function offsets (lowest bit: global(0) or eval(1) context) */
@@ -39,15 +39,15 @@ typedef struct
3939
#define JERRY_SNAPSHOT_MAGIC (0x5952524Au)
4040

4141
/**
42-
* Snapshot configuration flags.
42+
* Feature flags for snapshot execution.
4343
*/
4444
typedef enum
4545
{
46-
/* 8 bits are reserved for dynamic features */
47-
JERRY_SNAPSHOT_HAS_REGEX_LITERAL = (1u << 0), /**< byte code has regex literal */
48-
JERRY_SNAPSHOT_HAS_CLASS_LITERAL = (1u << 1), /**< byte code has class literal */
49-
/* 24 bits are reserved for compile time features */
50-
JERRY_SNAPSHOT_FOUR_BYTE_CPOINTER = (1u << 8) /**< deprecated, an unused placeholder now */
51-
} jerry_snapshot_global_flags_t;
46+
JERRY_SNAPSHOT_FEATURE_NONE = 0,
47+
JERRY_SNAPSHOT_FEATURE_REGEXP = (1u << 0), /**< feature flag for JERRY_BUILTIN_REGEXP */
48+
JERRY_SNAPSHOT_FEATURE_MODULE = (1u << 1), /**< feature flag for JERRY_MODULE_SYSTEM */
49+
JERRY_SNAPSHOT_FEATURE_DEBUGGER = (1u << 2), /**< feature flag for JERRY_DEBUGGER */
50+
JERRY_SNAPSHOT_FEATURE_ESNEXT = (1u << 3), /**< feature flag for JERRY_ESNEXT */
51+
} jerry_snapshot_feature_flags_t;
5252

5353
#endif /* !JERRY_SNAPSHOT_H */

Diff for: ‎jerry-core/include/jerryscript-port.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ typedef enum
4444
{
4545
JERRY_FATAL_OUT_OF_MEMORY = 10, /**< Out of memory */
4646
JERRY_FATAL_REF_COUNT_LIMIT = 12, /**< Reference count limit reached */
47-
JERRY_FATAL_DISABLED_BYTE_CODE = 13, /**< Executed disabled instruction */
48-
JERRY_FATAL_UNTERMINATED_GC_LOOPS = 14, /**< Garbage collection loop limit reached */
47+
JERRY_FATAL_UNTERMINATED_GC_LOOPS = 13, /**< Garbage collection loop limit reached */
4948
JERRY_FATAL_FAILED_ASSERTION = 120 /**< Assertion failed */
5049
} jerry_fatal_code_t;
5150

Diff for: ‎jerry-core/jrt/jrt-fatals.c

-5
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
4747
JERRY_ERROR_MSG ("Error: JERRY_FATAL_UNTERMINATED_GC_LOOPS\n");
4848
break;
4949
}
50-
case JERRY_FATAL_DISABLED_BYTE_CODE:
51-
{
52-
JERRY_ERROR_MSG ("Error: JERRY_FATAL_DISABLED_BYTE_CODE\n");
53-
break;
54-
}
5550
case JERRY_FATAL_FAILED_ASSERTION:
5651
{
5752
JERRY_ERROR_MSG ("Error: JERRY_FATAL_FAILED_ASSERTION\n");

Diff for: ‎jerry-core/parser/js/byte-code.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ JERRY_STATIC_ASSERT (CBC_EXT_END == 167, number_of_cbc_ext_opcodes_changed);
4545
/**
4646
* Compact bytecode definition
4747
*/
48-
#define CBC_OPCODE(arg1, arg2, arg3, arg4) ((arg2) | (((arg3) + CBC_STACK_ADJUST_BASE) << CBC_STACK_ADJUST_SHIFT)),
48+
#define CBC_OPCODE(arg1, arg2, arg3) ((arg2) | (((arg3) + CBC_STACK_ADJUST_BASE) << CBC_STACK_ADJUST_SHIFT)),
4949

5050
/**
5151
* Flags of the opcodes.
@@ -63,7 +63,7 @@ const uint8_t cbc_ext_flags[] = { CBC_EXT_OPCODE_LIST };
6363

6464
#if JERRY_PARSER_DUMP_BYTE_CODE
6565

66-
#define CBC_OPCODE(arg1, arg2, arg3, arg4) #arg1,
66+
#define CBC_OPCODE(arg1, arg2, arg3) #arg1,
6767

6868
/**
6969
* Names of the opcodes.

Diff for: ‎jerry-core/parser/js/byte-code.h

+360-575
Large diffs are not rendered by default.

Diff for: ‎jerry-core/parser/js/js-parser-expr.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
14201420
uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
14211421

14221422
#if JERRY_ESNEXT
1423-
if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
1423+
if (is_computed)
14241424
{
14251425
literal_index = function_literal_index;
14261426
}
@@ -3487,7 +3487,7 @@ parser_process_binary_assignment_token (parser_context_t *context_p, /**< contex
34873487

34883488
if (opcode == CBC_ASSIGN_PROP_THIS_LITERAL && (context_p->stack_depth >= context_p->stack_limit))
34893489
{
3490-
/* Stack limit is increased for VM_OC_ASSIGN_PROP_THIS. Needed by vm.c. */
3490+
/* Needed by vm.c. */
34913491
JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit);
34923492

34933493
context_p->stack_limit++;

Diff for: ‎jerry-core/vm/opcodes.c

+90-136
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ opfunc_typeof (ecma_value_t left_value) /**< left value */
5959
/**
6060
* Update data property for object literals.
6161
*/
62-
void
63-
opfunc_set_data_property (ecma_object_t *object_p, /**< object */
64-
ecma_string_t *prop_name_p, /**< data property name */
65-
ecma_value_t value) /**< new value */
62+
static void
63+
opfunc_assing_data_property (ecma_object_t *object_p, /**< object */
64+
ecma_string_t *prop_name_p, /**< data property name */
65+
ecma_value_t value) /**< new value */
6666
{
6767
JERRY_ASSERT (!ecma_op_object_is_fast_array (object_p));
6868

@@ -96,7 +96,7 @@ opfunc_set_data_property (ecma_object_t *object_p, /**< object */
9696
}
9797

9898
ecma_named_data_property_assign_value (object_p, prop_value_p, value);
99-
} /* opfunc_set_data_property */
99+
} /* opfunc_assing_data_property */
100100

101101
/**
102102
* Update getter or setter for object literals.
@@ -320,17 +320,15 @@ opfunc_for_in (ecma_value_t iterable_value, /**< ideally an iterable value */
320320
#if JERRY_ESNEXT
321321

322322
/**
323-
* 'VM_OC_APPEND_ARRAY' opcode handler specialized for spread objects
323+
* 'CBC_EXT_SPREAD_ARRAY_APPEND' opcode handler specialized for spread objects
324324
*
325325
* @return ECMA_VALUE_ERROR - if the operation failed
326326
* ECMA_VALUE_EMPTY, otherwise
327327
*/
328-
static ecma_value_t JERRY_ATTR_NOINLINE
328+
ecma_value_t JERRY_ATTR_NOINLINE
329329
opfunc_append_to_spread_array (ecma_value_t *stack_top_p, /**< current stack top */
330330
uint16_t values_length) /**< number of elements to set */
331331
{
332-
JERRY_ASSERT (!(values_length & OPFUNC_HAS_SPREAD_ELEMENT));
333-
334332
ecma_object_t *array_obj_p = ecma_get_object_from_value (stack_top_p[-1]);
335333
JERRY_ASSERT (ecma_get_object_type (array_obj_p) == ECMA_OBJECT_TYPE_ARRAY);
336334

@@ -501,23 +499,15 @@ opfunc_spread_arguments (ecma_value_t *stack_top_p, /**< pointer to the current
501499
#endif /* JERRY_ESNEXT */
502500

503501
/**
504-
* 'VM_OC_APPEND_ARRAY' opcode handler, for setting array object properties
502+
* 'CBC_ARRAY_APPEND' opcode handler, for setting array object properties
505503
*
506504
* @return ECMA_VALUE_ERROR - if the operation failed
507505
* ECMA_VALUE_EMPTY, otherwise
508506
*/
509507
ecma_value_t JERRY_ATTR_NOINLINE
510508
opfunc_append_array (ecma_value_t *stack_top_p, /**< current stack top */
511-
uint16_t values_length) /**< number of elements to set
512-
* with potential OPFUNC_HAS_SPREAD_ELEMENT flag */
509+
uint16_t values_length) /**< number of elements to set */
513510
{
514-
#if JERRY_ESNEXT
515-
if (values_length >= OPFUNC_HAS_SPREAD_ELEMENT)
516-
{
517-
return opfunc_append_to_spread_array (stack_top_p, (uint16_t) (values_length & ~OPFUNC_HAS_SPREAD_ELEMENT));
518-
}
519-
#endif /* JERRY_ESNEXT */
520-
521511
ecma_object_t *array_obj_p = ecma_get_object_from_value (stack_top_p[-1]);
522512
JERRY_ASSERT (ecma_get_object_type (array_obj_p) == ECMA_OBJECT_TYPE_ARRAY);
523513

@@ -1158,8 +1148,8 @@ opfunc_add_computed_field (ecma_value_t class_object, /**< class object */
11581148
* @return - new external function ecma-object
11591149
*/
11601150
ecma_value_t
1161-
opfunc_create_implicit_class_constructor (uint8_t opcode, /**< current cbc opcode */
1162-
const ecma_compiled_code_t *bytecode_p) /**< current byte code */
1151+
opfunc_create_implicit_class_constructor (const ecma_compiled_code_t *bytecode_p, /**< current byte code */
1152+
bool is_herigate) /* true -if class heritage is present */
11631153
{
11641154
/* 8. */
11651155
ecma_value_t script_value = ((cbc_uint8_arguments_t *) bytecode_p)->script_value;
@@ -1181,7 +1171,7 @@ opfunc_create_implicit_class_constructor (uint8_t opcode, /**< current cbc opcod
11811171
constructor_object_p->u.constructor_function.flags = 0;
11821172

11831173
/* 10.a.i */
1184-
if (opcode == CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE)
1174+
if (is_herigate)
11851175
{
11861176
constructor_object_p->u.constructor_function.flags |= ECMA_CONSTRUCTOR_FUNCTION_HAS_HERITAGE;
11871177
}
@@ -1574,9 +1564,6 @@ opfunc_collect_private_properties (ecma_value_t constructor, ecma_value_t prop_n
15741564

15751565
if (opcode == CBC_EXT_COLLECT_PRIVATE_METHOD)
15761566
{
1577-
prop_name ^= value;
1578-
value ^= prop_name;
1579-
prop_name ^= value;
15801567
kind = ECMA_PRIVATE_METHOD;
15811568
}
15821569
else if (opcode == CBC_EXT_COLLECT_PRIVATE_GETTER)
@@ -1977,10 +1964,7 @@ opfunc_finalize_class (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
19771964
* ECMA_VALUE_EMPTY - otherwise
19781965
*/
19791966
ecma_value_t
1980-
opfunc_form_super_reference (ecma_value_t **vm_stack_top_p, /**< current vm stack top */
1981-
vm_frame_ctx_t *frame_ctx_p, /**< frame context */
1982-
ecma_value_t prop_name, /**< property name to resolve */
1983-
uint8_t opcode) /**< current cbc opcode */
1967+
opfunc_resolve_super (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
19841968
{
19851969
ecma_environment_record_t *environment_record_p = ecma_op_get_environment_record (frame_ctx_p->lex_env_p);
19861970

@@ -2001,112 +1985,8 @@ opfunc_form_super_reference (ecma_value_t **vm_stack_top_p, /**< current vm stac
20011985
return ECMA_VALUE_ERROR;
20021986
}
20031987

2004-
ecma_value_t *stack_top_p = *vm_stack_top_p;
2005-
2006-
if (opcode >= CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE)
2007-
{
2008-
JERRY_ASSERT (opcode == CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE
2009-
|| opcode == CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
2010-
*stack_top_p++ = parent;
2011-
*stack_top_p++ = ecma_copy_value (prop_name);
2012-
*vm_stack_top_p = stack_top_p;
2013-
2014-
return ECMA_VALUE_EMPTY;
2015-
}
2016-
2017-
ecma_object_t *parent_p = ecma_get_object_from_value (parent);
2018-
ecma_string_t *prop_name_p = ecma_op_to_property_key (prop_name);
2019-
2020-
if (prop_name_p == NULL)
2021-
{
2022-
ecma_deref_object (parent_p);
2023-
return ECMA_VALUE_ERROR;
2024-
}
2025-
2026-
ecma_value_t result = ecma_op_object_get_with_receiver (parent_p, prop_name_p, frame_ctx_p->this_binding);
2027-
ecma_deref_ecma_string (prop_name_p);
2028-
ecma_deref_object (parent_p);
2029-
2030-
if (ECMA_IS_VALUE_ERROR (result))
2031-
{
2032-
return result;
2033-
}
2034-
2035-
if (opcode == CBC_EXT_SUPER_PROP_LITERAL_REFERENCE || opcode == CBC_EXT_SUPER_PROP_REFERENCE)
2036-
{
2037-
*stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding);
2038-
*stack_top_p++ = ECMA_VALUE_UNDEFINED;
2039-
}
2040-
2041-
*stack_top_p++ = result;
2042-
*vm_stack_top_p = stack_top_p;
2043-
2044-
return ECMA_VALUE_EMPTY;
2045-
} /* opfunc_form_super_reference */
2046-
2047-
/**
2048-
* Assignment operation for SuperRefence base
2049-
*
2050-
* @return ECMA_VALUE_ERROR - if the operation fails
2051-
* ECMA_VALUE_EMPTY - otherwise
2052-
*/
2053-
ecma_value_t
2054-
opfunc_assign_super_reference (ecma_value_t **vm_stack_top_p, /**< vm stack top */
2055-
vm_frame_ctx_t *frame_ctx_p, /**< frame context */
2056-
uint32_t opcode_data) /**< opcode data to store the result */
2057-
{
2058-
ecma_value_t *stack_top_p = *vm_stack_top_p;
2059-
2060-
ecma_value_t base_obj = ecma_op_to_object (stack_top_p[-3]);
2061-
2062-
if (ECMA_IS_VALUE_ERROR (base_obj))
2063-
{
2064-
return base_obj;
2065-
}
2066-
2067-
ecma_object_t *base_obj_p = ecma_get_object_from_value (base_obj);
2068-
ecma_string_t *prop_name_p = ecma_op_to_property_key (stack_top_p[-2]);
2069-
2070-
if (prop_name_p == NULL)
2071-
{
2072-
ecma_deref_object (base_obj_p);
2073-
return ECMA_VALUE_ERROR;
2074-
}
2075-
2076-
bool is_strict = (frame_ctx_p->status_flags & VM_FRAME_CTX_IS_STRICT) != 0;
2077-
2078-
ecma_value_t result =
2079-
ecma_op_object_put_with_receiver (base_obj_p, prop_name_p, stack_top_p[-1], frame_ctx_p->this_binding, is_strict);
2080-
2081-
ecma_deref_ecma_string (prop_name_p);
2082-
ecma_deref_object (base_obj_p);
2083-
2084-
if (ECMA_IS_VALUE_ERROR (result))
2085-
{
2086-
return result;
2087-
}
2088-
2089-
for (int32_t i = 1; i <= 3; i++)
2090-
{
2091-
ecma_free_value (stack_top_p[-i]);
2092-
}
2093-
2094-
stack_top_p -= 3;
2095-
2096-
if (opcode_data & VM_OC_PUT_STACK)
2097-
{
2098-
*stack_top_p++ = result;
2099-
}
2100-
else if (opcode_data & VM_OC_PUT_BLOCK)
2101-
{
2102-
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, 0));
2103-
VM_GET_REGISTERS (frame_ctx_p)[0] = result;
2104-
}
2105-
2106-
*vm_stack_top_p = stack_top_p;
2107-
2108-
return result;
2109-
} /* opfunc_assign_super_reference */
1988+
return parent;
1989+
} /* opfunc_resolve_super */
21101990

21111991
/**
21121992
* Copy data properties of an object
@@ -2222,7 +2102,7 @@ opfunc_copy_data_properties (ecma_value_t target_object, /**< target object */
22222102
}
22232103
}
22242104

2225-
opfunc_set_data_property (target_object_p, property_name_p, result);
2105+
opfunc_assing_data_property (target_object_p, property_name_p, result);
22262106
ecma_free_value (result);
22272107

22282108
result = ECMA_VALUE_EMPTY;
@@ -2303,8 +2183,82 @@ opfunc_lexical_scope_has_restricted_binding (vm_frame_ctx_t *frame_ctx_p, /**< f
23032183
&& !ecma_is_property_configurable (property));
23042184
} /* opfunc_lexical_scope_has_restricted_binding */
23052185

2186+
/**
2187+
* Create function name property to the given function object
2188+
*/
2189+
void
2190+
opfunc_set_function_name (ecma_value_t function_object, /**< function object */
2191+
ecma_value_t function_name, /**< function name */
2192+
char *prefix_p, /**< function name prefix */
2193+
lit_utf8_size_t prefix_size) /**< function name prefix's length */
2194+
{
2195+
ecma_object_t *func_obj_p = ecma_get_object_from_value (function_object);
2196+
2197+
if (ecma_find_named_property (func_obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_NAME)) != NULL)
2198+
{
2199+
return;
2200+
}
2201+
2202+
ecma_property_value_t *value_p;
2203+
value_p = ecma_create_named_data_property (func_obj_p,
2204+
ecma_get_magic_string (LIT_MAGIC_STRING_NAME),
2205+
ECMA_PROPERTY_FLAG_CONFIGURABLE,
2206+
NULL);
2207+
2208+
if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
2209+
{
2210+
ECMA_SET_SECOND_BIT_TO_POINTER_TAG (((ecma_extended_object_t *) func_obj_p)->u.function.scope_cp);
2211+
}
2212+
2213+
value_p->value = ecma_op_function_form_name (ecma_get_prop_name_from_value (function_name), prefix_p, prefix_size);
2214+
} /* opfunc_set_function_name */
2215+
23062216
#endif /* JERRY_ESNEXT */
23072217

2218+
/**
2219+
* Set data property to an object/class
2220+
*
2221+
* @return ECMA_VALUE_ERROR - if the operation fails
2222+
* ECMA_VALUE_EMPTY - otherwise
2223+
*/
2224+
ecma_value_t
2225+
opfunc_set_data_property (ecma_value_t *stack_top_p, /**< vm stack */
2226+
ecma_value_t prop_name, /**< property name to set */
2227+
ecma_value_t value, /**< value to set */
2228+
bool is_static) /**< true - if set class property
2229+
false - otherwise */
2230+
{
2231+
ecma_string_t *prop_name_p = ecma_op_to_property_key (prop_name);
2232+
2233+
if (JERRY_UNLIKELY (prop_name_p == NULL))
2234+
{
2235+
return ECMA_VALUE_ERROR;
2236+
}
2237+
2238+
int index = -1;
2239+
2240+
#if JERRY_ESNEXT
2241+
if (JERRY_UNLIKELY (is_static))
2242+
{
2243+
if (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE))
2244+
{
2245+
return ecma_raise_type_error (ECMA_ERR_CLASS_IS_NON_CONFIGURABLE);
2246+
}
2247+
2248+
index--;
2249+
}
2250+
#else /* !JERRY_ESNEXT */
2251+
JERRY_UNUSED (is_static);
2252+
#endif /* JERRY_ESNEXT */
2253+
2254+
ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[index]);
2255+
2256+
opfunc_assing_data_property (object_p, prop_name_p, value);
2257+
ecma_deref_ecma_string (prop_name_p);
2258+
2259+
return ECMA_VALUE_EMPTY;
2260+
} /* opfunc_set_data_property */
2261+
23082262
/**
23092263
* @}
23102264
* @}

Diff for: ‎jerry-core/vm/opcodes.h

+13-19
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,6 @@ typedef enum
6767

6868
#endif /* JERRY_ESNEXT */
6969

70-
/**
71-
* The stack contains spread object during the upcoming APPEND_ARRAY operation
72-
*/
73-
#define OPFUNC_HAS_SPREAD_ELEMENT (1 << 8)
74-
7570
ecma_value_t opfunc_equality (ecma_value_t left_value, ecma_value_t right_value);
7671

7772
ecma_value_t do_number_arithmetic (number_arithmetic_op op, ecma_value_t left_value, ecma_value_t right_value);
@@ -92,8 +87,6 @@ ecma_value_t opfunc_instanceof (ecma_value_t left_value, ecma_value_t right_valu
9287

9388
ecma_value_t opfunc_typeof (ecma_value_t left_value);
9489

95-
void opfunc_set_data_property (ecma_object_t *object_p, ecma_string_t *prop_name_p, ecma_value_t value);
96-
9790
void opfunc_set_accessor (bool is_getter, ecma_value_t object, ecma_string_t *accessor_name_p, ecma_value_t accessor);
9891

9992
ecma_value_t vm_op_delete_prop (ecma_value_t object, ecma_value_t property, bool is_strict);
@@ -102,13 +95,12 @@ ecma_value_t vm_op_delete_var (ecma_value_t name_literal, ecma_object_t *lex_env
10295

10396
ecma_collection_t *opfunc_for_in (ecma_value_t left_value, ecma_value_t *result_obj_p);
10497

105-
#if JERRY_ESNEXT
106-
ecma_collection_t *opfunc_spread_arguments (ecma_value_t *stack_top_p, uint8_t argument_list_len);
107-
#endif /* JERRY_ESNEXT */
108-
10998
ecma_value_t opfunc_append_array (ecma_value_t *stack_top_p, uint16_t values_length);
11099

111100
#if JERRY_ESNEXT
101+
ecma_value_t opfunc_append_to_spread_array (ecma_value_t *stack_top_p, uint16_t values_length);
102+
103+
ecma_collection_t *opfunc_spread_arguments (ecma_value_t *stack_top_p, uint8_t argument_list_len);
112104

113105
vm_executable_object_t *opfunc_create_executable_object (vm_frame_ctx_t *frame_ctx_p,
114106
vm_create_executable_object_type_t type);
@@ -128,7 +120,7 @@ ecma_value_t opfunc_init_static_class_fields (ecma_value_t function_object, ecma
128120

129121
ecma_value_t opfunc_add_computed_field (ecma_value_t class_object, ecma_value_t name);
130122

131-
ecma_value_t opfunc_create_implicit_class_constructor (uint8_t opcode, const ecma_compiled_code_t *bytecode_p);
123+
ecma_value_t opfunc_create_implicit_class_constructor (const ecma_compiled_code_t *bytecode_p, bool is_herigate);
132124

133125
void opfunc_set_home_object (ecma_object_t *func_p, ecma_object_t *parent_env_p);
134126

@@ -162,20 +154,22 @@ void opfunc_pop_lexical_environment (vm_frame_ctx_t *frame_ctx_p);
162154

163155
void opfunc_finalize_class (vm_frame_ctx_t *frame_ctx_p, ecma_value_t **vm_stack_top_p, ecma_value_t class_name);
164156

165-
ecma_value_t opfunc_form_super_reference (ecma_value_t **vm_stack_top_p,
166-
vm_frame_ctx_t *frame_ctx_p,
167-
ecma_value_t prop_name,
168-
uint8_t opcode);
169-
170-
ecma_value_t
171-
opfunc_assign_super_reference (ecma_value_t **vm_stack_top_p, vm_frame_ctx_t *frame_ctx_p, uint32_t opcode_data);
157+
ecma_value_t opfunc_resolve_super (vm_frame_ctx_t *frame_ctx_p);
172158

173159
ecma_value_t
174160
opfunc_copy_data_properties (ecma_value_t target_object, ecma_value_t source_object, ecma_value_t filter_array);
175161

176162
ecma_value_t opfunc_lexical_scope_has_restricted_binding (vm_frame_ctx_t *vm_frame_ctx_p, ecma_string_t *name_p);
163+
164+
void opfunc_set_function_name (ecma_value_t function_object,
165+
ecma_value_t function_name,
166+
char *prefix_p,
167+
lit_utf8_size_t prefix_size);
177168
#endif /* JERRY_ESNEXT */
178169

170+
ecma_value_t
171+
opfunc_set_data_property (ecma_value_t *stack_top_p, ecma_value_t prop_name, ecma_value_t value, bool is_static);
172+
179173
/**
180174
* @}
181175
* @}

Diff for: ‎jerry-core/vm/vm.c

+1,609-708
Large diffs are not rendered by default.

Diff for: ‎jerry-core/vm/vm.h

+10-448
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.