Implement proper creation of function arguments, let and const declarations. (#3725)

After the rework it is possible to detect use before init errors for function arguments.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-05-12 14:38:17 +02:00
committed by GitHub
parent df7e303145
commit 4dc2cb3328
16 changed files with 729 additions and 218 deletions
+39 -1
View File
@@ -1366,7 +1366,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
continue;
}
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
case VM_OC_INIT_LOCAL:
case VM_OC_INIT_ARG_OR_FUNC:
{
uint32_t literal_index, value_index;
ecma_value_t lit_value;
@@ -1505,6 +1505,44 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
}
continue;
}
case VM_OC_INIT_BINDING:
{
uint32_t literal_index;
READ_LITERAL_INDEX (literal_index);
JERRY_ASSERT (literal_index >= register_end);
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
JERRY_ASSERT (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
JERRY_ASSERT (ecma_find_named_property (frame_ctx_p->lex_env_p, name_p) == NULL);
uint8_t prop_attributes = ECMA_PROPERTY_FLAG_WRITABLE;
if (opcode == CBC_INIT_LET)
{
prop_attributes = ECMA_PROPERTY_ENUMERABLE_WRITABLE;
}
else if (opcode == CBC_INIT_CONST)
{
prop_attributes = ECMA_PROPERTY_FLAG_ENUMERABLE;
}
ecma_property_value_t *property_value_p;
property_value_p = ecma_create_named_data_property (frame_ctx_p->lex_env_p,
name_p,
prop_attributes,
NULL);
JERRY_ASSERT (property_value_p->value == ECMA_VALUE_UNDEFINED);
ecma_value_t value = *(--stack_top_p);
property_value_p->value = value;
ecma_deref_if_object (value);
continue;
}
case VM_OC_THROW_CONST_ERROR:
{
result = ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned."));
+4 -2
View File
@@ -161,7 +161,7 @@ typedef enum
VM_OC_ERROR, /**< error while the vm_loop is suspended */
VM_OC_JUMP, /**< jump */
VM_OC_BRANCH_IF_STRICT_EQUAL, /**< branch if stric equal */
VM_OC_BRANCH_IF_STRICT_EQUAL, /**< branch if strict equal */
/* These four opcodes must be in this order. */
VM_OC_BRANCH_IF_TRUE, /**< branch if true */
@@ -219,7 +219,7 @@ typedef enum
VM_OC_CREATE_BINDING, /**< create variables */
VM_OC_SET_BYTECODE_PTR, /**< setting bytecode pointer */
VM_OC_VAR_EVAL, /**< variable and function evaluation */
VM_OC_INIT_LOCAL, /**< initialize local variable */
VM_OC_INIT_ARG_OR_FUNC, /**< create and init a function or argument binding */
#if ENABLED (JERRY_DEBUGGER)
VM_OC_BREAKPOINT_ENABLED, /**< enabled breakpoint for debugger */
@@ -235,6 +235,7 @@ typedef enum
VM_OC_CHECK_VAR, /**< check redeclared vars in the global scope */
VM_OC_CHECK_LET, /**< check redeclared lets in the global scope */
VM_OC_ASSIGN_LET_CONST, /**< assign values to let/const declarations */
VM_OC_INIT_BINDING, /**< create and intialize a binding */
VM_OC_THROW_CONST_ERROR, /**< throw invalid assignment to const variable error */
VM_OC_COPY_TO_GLOBAL, /**< copy value to global lex env */
VM_OC_CLONE_CONTEXT, /**< clone lexical environment with let/const declarations */
@@ -298,6 +299,7 @@ typedef enum
VM_OC_CHECK_VAR = VM_OC_NONE, /**< check redeclared vars in the global scope */
VM_OC_CHECK_LET = VM_OC_NONE, /**< check redeclared lets in the global scope */
VM_OC_ASSIGN_LET_CONST = VM_OC_NONE, /**< assign values to let/const declarations */
VM_OC_INIT_BINDING = VM_OC_NONE, /**< create and intialize a binding */
VM_OC_THROW_CONST_ERROR = VM_OC_NONE, /**< throw invalid assignment to const variable error */
VM_OC_COPY_TO_GLOBAL = VM_OC_NONE, /**< copy value to global lex env */
VM_OC_CLONE_CONTEXT = VM_OC_NONE, /**< clone lexical environment with let/const declarations */