Implement computed properties for object literals. (#2481)
Also disable ES5.1 property name dumplication checks when ES2015 object literals are enabled. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -101,12 +101,10 @@ opfunc_typeof (ecma_value_t left_value) /**< left value */
|
||||
void
|
||||
opfunc_set_accessor (bool is_getter, /**< is getter accessor */
|
||||
ecma_value_t object, /**< object value */
|
||||
ecma_value_t accessor_name, /**< accessor name value */
|
||||
ecma_string_t *accessor_name_p, /**< accessor name */
|
||||
ecma_value_t accessor) /**< accessor value */
|
||||
{
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (object);
|
||||
JERRY_ASSERT (ecma_is_value_string (accessor_name) || ecma_is_value_number (accessor_name));
|
||||
ecma_string_t *accessor_name_p = ecma_get_string_from_value (ecma_op_to_string (accessor_name));
|
||||
ecma_property_t *property_p = ecma_find_named_property (object_p, accessor_name_p);
|
||||
|
||||
if (property_p != NULL
|
||||
@@ -153,8 +151,6 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */
|
||||
ECMA_PROPERTY_VALUE_PTR (property_p),
|
||||
setter_func_p);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (accessor_name_p);
|
||||
} /* opfunc_set_accessor */
|
||||
|
||||
/**
|
||||
|
||||
@@ -85,7 +85,7 @@ ecma_value_t
|
||||
opfunc_typeof (ecma_value_t left_value);
|
||||
|
||||
void
|
||||
opfunc_set_accessor (bool is_getter, ecma_value_t object, ecma_value_t accessor_name, ecma_value_t accessor);
|
||||
opfunc_set_accessor (bool is_getter, ecma_value_t object, ecma_string_t *accessor_name_p, ecma_value_t accessor);
|
||||
|
||||
ecma_value_t
|
||||
vm_op_delete_prop (ecma_value_t object, ecma_value_t property, bool is_strict);
|
||||
|
||||
+79
-29
@@ -927,11 +927,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
switch (VM_OC_GROUP_GET_INDEX (opcode_data))
|
||||
{
|
||||
case VM_OC_NONE:
|
||||
{
|
||||
JERRY_ASSERT (opcode == CBC_EXT_DEBUGGER);
|
||||
continue;
|
||||
}
|
||||
case VM_OC_POP:
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
@@ -1045,23 +1040,26 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
*stack_top_p++ = ecma_make_object_value (obj_p);
|
||||
continue;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
|
||||
case VM_OC_SET_COMPUTED_PROPERTY:
|
||||
{
|
||||
/* Swap values. */
|
||||
left_value ^= right_value;
|
||||
right_value ^= left_value;
|
||||
left_value ^= right_value;
|
||||
/* FALLTHRU */
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
|
||||
case VM_OC_SET_PROPERTY:
|
||||
{
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
const int index = (byte_code_start_p[0] == CBC_EXT_OPCODE) ? -2 : -1;
|
||||
#else
|
||||
const int index = -1;
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
JERRY_STATIC_ASSERT (VM_OC_NON_STATIC_FLAG == VM_OC_BACKWARD_BRANCH,
|
||||
vm_oc_non_static_flag_must_be_equal_to_vm_oc_backward_branch);
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[index]);
|
||||
ecma_string_t *prop_name_p;
|
||||
ecma_property_t *property_p;
|
||||
JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1);
|
||||
|
||||
if (ecma_is_value_string (right_value))
|
||||
{
|
||||
prop_name_p = ecma_get_string_from_value (right_value);
|
||||
}
|
||||
else
|
||||
result = right_value;
|
||||
|
||||
if (JERRY_UNLIKELY (!ecma_is_value_string (right_value)))
|
||||
{
|
||||
result = ecma_op_to_string (right_value);
|
||||
|
||||
@@ -1069,11 +1067,30 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
prop_name_p = ecma_get_string_from_value (result);
|
||||
}
|
||||
|
||||
property_p = ecma_find_named_property (object_p, prop_name_p);
|
||||
ecma_string_t *prop_name_p = ecma_get_string_from_value (result);
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE))
|
||||
&& !(opcode_data & VM_OC_NON_STATIC_FLAG))
|
||||
{
|
||||
if (!ecma_is_value_string (right_value))
|
||||
{
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
}
|
||||
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2;
|
||||
#else /* CONFIG_DISABLE_ES2015_CLASS */
|
||||
const int index = -1;
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[index]);
|
||||
ecma_property_t *property_p = ecma_find_named_property (object_p, prop_name_p);
|
||||
|
||||
if (property_p != NULL
|
||||
&& ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
|
||||
@@ -1108,18 +1125,50 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
case VM_OC_SET_GETTER:
|
||||
case VM_OC_SET_SETTER:
|
||||
{
|
||||
JERRY_ASSERT (byte_code_start_p[0] == CBC_EXT_OPCODE);
|
||||
JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1);
|
||||
|
||||
result = left_value;
|
||||
|
||||
if (JERRY_UNLIKELY (!ecma_is_value_string (left_value)))
|
||||
{
|
||||
result = ecma_op_to_string (left_value);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
ecma_string_t *prop_name_p = ecma_get_string_from_value (result);
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
const int index = (byte_code_start_p[1] > CBC_EXT_SET_SETTER) ? -2 : -1;
|
||||
#else
|
||||
if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE))
|
||||
&& !(opcode_data & VM_OC_NON_STATIC_FLAG))
|
||||
{
|
||||
if (!ecma_is_value_string (left_value))
|
||||
{
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
}
|
||||
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2;
|
||||
#else /* CONFIG_DISABLE_ES2015_CLASS */
|
||||
const int index = -1;
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
|
||||
opfunc_set_accessor (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_SET_GETTER,
|
||||
stack_top_p[index],
|
||||
left_value,
|
||||
prop_name_p,
|
||||
right_value);
|
||||
|
||||
if (!ecma_is_value_string (left_value))
|
||||
{
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
}
|
||||
|
||||
goto free_both_values;
|
||||
}
|
||||
case VM_OC_PUSH_ARRAY:
|
||||
@@ -2560,9 +2609,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
continue;
|
||||
}
|
||||
#ifdef JERRY_DEBUGGER
|
||||
case VM_OC_BREAKPOINT_ENABLED:
|
||||
{
|
||||
#ifdef JERRY_DEBUGGER
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE)
|
||||
{
|
||||
continue;
|
||||
@@ -2580,12 +2629,10 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
result = ECMA_VALUE_ERROR;
|
||||
goto error;
|
||||
}
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
continue;
|
||||
}
|
||||
case VM_OC_BREAKPOINT_DISABLED:
|
||||
{
|
||||
#ifdef JERRY_DEBUGGER
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE)
|
||||
{
|
||||
continue;
|
||||
@@ -2634,9 +2681,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
continue;
|
||||
}
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
#ifdef JERRY_ENABLE_LINE_INFO
|
||||
case VM_OC_RESOURCE_NAME:
|
||||
{
|
||||
@@ -2685,6 +2732,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
#endif /* JERRY_ENABLE_LINE_INFO */
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_NONE);
|
||||
|
||||
jerry_fatal (ERR_DISABLED_BYTE_CODE);
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
|
||||
+39
-2
@@ -41,7 +41,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Branch argument is a backward branch
|
||||
* If VM_OC_GET_ARGS_INDEX(opcode) == VM_OC_GET_BRANCH,
|
||||
* this flag signals that the branch is a backward branch.
|
||||
*/
|
||||
#define VM_OC_BACKWARD_BRANCH 0x4000
|
||||
|
||||
@@ -102,7 +103,6 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_OC_NONE, /**< do nothing */
|
||||
VM_OC_POP, /**< pop from stack */
|
||||
VM_OC_POP_BLOCK, /**< pop block */
|
||||
VM_OC_PUSH, /**< push one literal */
|
||||
@@ -121,6 +121,9 @@ typedef enum
|
||||
VM_OC_PUSH_LIT_NEG_BYTE, /**< push literal and number between -1 and -256 */
|
||||
VM_OC_PUSH_OBJECT, /**< push object */
|
||||
VM_OC_SET_PROPERTY, /**< set property */
|
||||
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
|
||||
VM_OC_SET_COMPUTED_PROPERTY, /**< set computed property */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
|
||||
VM_OC_SET_GETTER, /**< set getter */
|
||||
VM_OC_SET_SETTER, /**< set setter */
|
||||
VM_OC_PUSH_UNDEFINED_BASE, /**< push undefined base */
|
||||
@@ -206,12 +209,36 @@ typedef enum
|
||||
VM_OC_FINALLY, /**< finally */
|
||||
VM_OC_CONTEXT_END, /**< context end */
|
||||
VM_OC_JUMP_AND_EXIT_CONTEXT, /**< jump and exit context */
|
||||
#ifdef JERRY_DEBUGGER
|
||||
VM_OC_BREAKPOINT_ENABLED, /**< enabled breakpoint for debugger */
|
||||
VM_OC_BREAKPOINT_DISABLED, /**< disabled breakpoint for debugger */
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
#ifdef JERRY_ENABLE_LINE_INFO
|
||||
VM_OC_RESOURCE_NAME, /**< resource name of the current function */
|
||||
VM_OC_LINE, /**< line number of the next statement */
|
||||
#endif /* JERRY_ENABLE_LINE_INFO */
|
||||
VM_OC_NONE, /**< a special opcode for */
|
||||
} vm_oc_types;
|
||||
|
||||
/**
|
||||
* Unused opcodes, but required by byte-code types.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
|
||||
VM_OC_SET_COMPUTED_PROPERTY = VM_OC_NONE, /**< set computed property is unused */
|
||||
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
|
||||
#ifndef JERRY_DEBUGGER
|
||||
VM_OC_BREAKPOINT_ENABLED = VM_OC_NONE, /**< enabled breakpoint for debugger is unused */
|
||||
VM_OC_BREAKPOINT_DISABLED = VM_OC_NONE, /**< disabled breakpoint for debugger is unused */
|
||||
#endif /* !JERRY_DEBUGGER */
|
||||
#ifndef JERRY_ENABLE_LINE_INFO
|
||||
VM_OC_RESOURCE_NAME = VM_OC_NONE, /**< resource name of the current function is unused */
|
||||
VM_OC_LINE = VM_OC_NONE, /**< line number of the next statement is unused */
|
||||
#endif /* !JERRY_ENABLE_LINE_INFO */
|
||||
VM_OC_UNUSED = VM_OC_NONE /**< placeholder if the list is empty */
|
||||
} vm_oc_unused_types;
|
||||
|
||||
/**
|
||||
* Decrement operator.
|
||||
*/
|
||||
@@ -237,6 +264,16 @@ typedef enum
|
||||
*/
|
||||
#define VM_OC_LOGICAL_BRANCH_FLAG 0x2
|
||||
|
||||
/**
|
||||
* Bit index shift for non-static property initializers.
|
||||
*/
|
||||
#define VM_OC_NON_STATIC_SHIFT 14
|
||||
|
||||
/**
|
||||
* This flag is set for static property initializers.
|
||||
*/
|
||||
#define VM_OC_NON_STATIC_FLAG (0x1 << VM_OC_NON_STATIC_SHIFT)
|
||||
|
||||
/**
|
||||
* Position of "put result" opcode.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user