Implement optional chaining (#5164)

The work is based on PR #4843, only fixed some conflicts and cppcheck errors.

Co-authored-by: Robert Fancsik robert.fancsik@h-lab.eu
JerryScript-DCO-1.0-Signed-off-by: Gergo Csizi gergocs@inf.u-szeged.hu
This commit is contained in:
Gergo Csizi
2024-11-20 11:57:58 +01:00
committed by GitHub
parent e9f08a7879
commit f54f2d3a7b
14 changed files with 1012 additions and 412 deletions
+25 -3
View File
@@ -3174,9 +3174,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
case VM_OC_EVAL:
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_DIRECT_EVAL;
JERRY_ASSERT ((*byte_code_p >= CBC_CALL && *byte_code_p <= CBC_CALL2_PROP_BLOCK)
|| (*byte_code_p == CBC_EXT_OPCODE && byte_code_p[1] >= CBC_EXT_SPREAD_CALL
&& byte_code_p[1] <= CBC_EXT_SPREAD_CALL_PROP_BLOCK));
continue;
}
case VM_OC_CALL:
@@ -3307,6 +3304,31 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_fast_free_value (value);
continue;
}
case VM_OC_BRANCH_OPTIONAL_CHAIN:
{
left_value = stack_top_p[-1];
bool pop_reference = byte_code_p[0] == CBC_EXT_OPCODE && byte_code_p[1] == CBC_EXT_POP_REFERENCE;
if (!(ecma_is_value_null (left_value) || ecma_is_value_undefined (left_value)))
{
if (pop_reference)
{
byte_code_p += 2;
}
continue;
}
stack_top_p[-1] = ECMA_VALUE_UNDEFINED;
byte_code_p = byte_code_start_p + branch_offset;
if (!pop_reference)
{
continue;
}
/* FALLTHRU */
}
case VM_OC_POP_REFERENCE:
{
ecma_free_value (stack_top_p[-2]);
+1
View File
@@ -165,6 +165,7 @@ typedef enum
VM_OC_JUMP, /**< jump */
VM_OC_BRANCH_IF_NULLISH, /** branch if undefined or null */
VM_OC_BRANCH_OPTIONAL_CHAIN, /** branch if undefined or null and adjust stack */
VM_OC_POP_REFERENCE, /** prop identifier or property reference from the stack */
VM_OC_BRANCH_IF_STRICT_EQUAL, /**< branch if strict equal */