From b9fd80ce365a50b43d4e1ed94e33e6f078c7c407 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Thu, 4 Sep 2014 21:02:29 +0400 Subject: [PATCH] Fixing object declaration and function expression opcode handlers; adding unit test that declares object and operates on the object's properties. --- src/libcoreint/opcodes.c | 31 ++-- src/libecmaoperations/ecma-objects-general.c | 2 +- tests/unit/test_obj_initializer.c | 158 +++++++++++++++++++ 3 files changed, 179 insertions(+), 12 deletions(-) create mode 100644 tests/unit/test_obj_initializer.c diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 349b5c3ae..6f0580528 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -595,6 +595,8 @@ ecma_completion_value_t opfunc_func_expr_n (opcode_t opdata, /**< operation data */ int_data_t *int_data) /**< interpreter context */ { + int_data->pos++; + const idx_t dst_var_idx = opdata.data.func_expr_n.lhs; const idx_t function_name_lit_idx = opdata.data.func_expr_n.name_lit_idx; const ecma_length_t params_number = opdata.data.func_expr_n.arg_list; @@ -985,9 +987,12 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */ ecma_string_t *prop_name_string_p = ecma_new_ecma_string_from_lit_index (prop_name_lit_idx); ecma_property_t *previous_p = ecma_op_object_get_own_property (obj_p, prop_name_string_p); - const bool is_previous_data_desc = (previous_p->type == ECMA_PROPERTY_NAMEDDATA); - const bool is_previous_accessor_desc = (previous_p->type == ECMA_PROPERTY_NAMEDACCESSOR); - JERRY_ASSERT (is_previous_data_desc || is_previous_accessor_desc); + const bool is_previous_undefined = (previous_p == NULL); + const bool is_previous_data_desc = (!is_previous_undefined + && previous_p->type == ECMA_PROPERTY_NAMEDDATA); + const bool is_previous_accessor_desc = (!is_previous_undefined + && previous_p->type == ECMA_PROPERTY_NAMEDACCESSOR); + JERRY_ASSERT (is_previous_undefined || is_previous_data_desc || is_previous_accessor_desc); ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); { @@ -1006,9 +1011,10 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */ prop_desc.is_writable_defined = true; prop_desc.writable = ECMA_PROPERTY_WRITABLE; - if ((is_previous_data_desc - && int_data->is_strict) - || is_previous_accessor_desc) + if (!is_previous_undefined + && ((is_previous_data_desc + && int_data->is_strict) + || is_previous_accessor_desc)) { is_throw_syntax_error = true; } @@ -1020,7 +1026,8 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */ prop_desc.is_get_defined = true; prop_desc.get_p = ECMA_GET_POINTER (value_for_prop_desc.u.value.value); - if (is_previous_data_desc) + if (!is_previous_undefined + && is_previous_data_desc) { is_throw_syntax_error = true; } @@ -1032,7 +1039,8 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */ prop_desc.is_set_defined = true; prop_desc.set_p = ECMA_GET_POINTER (value_for_prop_desc.u.value.value); - if (is_previous_data_desc) + if (!is_previous_undefined + && is_previous_data_desc) { is_throw_syntax_error = true; } @@ -1765,6 +1773,9 @@ opfunc_meta (opcode_t opdata, /**< operation data */ switch (type) { case OPCODE_META_TYPE_VARG: + case OPCODE_META_TYPE_VARG_PROP_DATA: + case OPCODE_META_TYPE_VARG_PROP_GETTER: + case OPCODE_META_TYPE_VARG_PROP_SETTER: case OPCODE_META_TYPE_END_WITH: case OPCODE_META_TYPE_CATCH: case OPCODE_META_TYPE_FINALLY: @@ -1774,9 +1785,7 @@ opfunc_meta (opcode_t opdata, /**< operation data */ } case OPCODE_META_TYPE_UNDEFINED: case OPCODE_META_TYPE_THIS_ARG: - case OPCODE_META_TYPE_VARG_PROP_DATA: - case OPCODE_META_TYPE_VARG_PROP_GETTER: - case OPCODE_META_TYPE_VARG_PROP_SETTER: + case OPCODE_META_TYPE_FUNCTION_END: case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER: case OPCODE_META_TYPE_STRICT_CODE: diff --git a/src/libecmaoperations/ecma-objects-general.c b/src/libecmaoperations/ecma-objects-general.c index 42252862c..b6a1aa12d 100644 --- a/src/libecmaoperations/ecma-objects-general.c +++ b/src/libecmaoperations/ecma-objects-general.c @@ -61,7 +61,7 @@ ecma_op_create_object_object_noarg (void) FIXME (/* Set to built-in Object prototype (15.2.4) */); // 3., 4., 6., 7. - ecma_object_t *obj_p = ecma_create_object (NULL, false, ECMA_OBJECT_TYPE_GENERAL); + ecma_object_t *obj_p = ecma_create_object (NULL, true, ECMA_OBJECT_TYPE_GENERAL); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); class_prop_p->u.internal_property.value = ECMA_OBJECT_CLASS_OBJECT; diff --git a/tests/unit/test_obj_initializer.c b/tests/unit/test_obj_initializer.c new file mode 100644 index 000000000..d642adcbc --- /dev/null +++ b/tests/unit/test_obj_initializer.c @@ -0,0 +1,158 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "globals.h" +#include "interpreter.h" +#include "mem-allocator.h" +#include "opcodes.h" +#include "serializer.h" + +/** + * Unit test's main function. + */ +int +main( int __unused argc, + char __unused **argv) +{ + const opcode_t test_program[] = { + [ 0] = getop_reg_var_decl (240, 255), + [ 1] = getop_jmp_down (2), + [ 2] = getop_exitval (1), + + /* var a, b; */ + [ 3] = getop_var_decl (0), + [ 4] = getop_var_decl (1), + + /* b = 'property1'; */ + [ 5] = getop_assignment (1, OPCODE_ARG_TYPE_STRING, 2), + + /* a = { */ + [ 6] = getop_obj_decl (0, 4), + + /* 'property1' : 'value1', */ + [ 7] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 5), + [ 8] = getop_meta (OPCODE_META_TYPE_VARG_PROP_DATA, 2, 240), + + /* get property2 () { return 1; }, */ + [ 9] = getop_func_expr_n (240, 243 /* any tmp reg */, 0), + [10] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 14), + [11] = getop_reg_var_decl (250, 255), + [12] = getop_assignment (250, OPCODE_ARG_TYPE_SMALLINT, 1), + [13] = getop_retval (250), + [14] = getop_meta (OPCODE_META_TYPE_VARG_PROP_GETTER, 3, 240), + + /* set property2 (a) { this.property3 = a * 10; }, */ + [15] = getop_func_expr_n (250, 243 /* any tmp reg */, 1), + [16] = getop_meta (OPCODE_META_TYPE_VARG, 0, 255), + [17] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 25), + [18] = getop_reg_var_decl (250, 255), + [19] = getop_this (250), + [20] = getop_assignment (251, OPCODE_ARG_TYPE_STRING, 4), + [21] = getop_assignment (252, OPCODE_ARG_TYPE_SMALLINT, 10), + [22] = getop_multiplication (252, 0, 252), + [23] = getop_prop_setter (250, 251, 252), + [24] = getop_ret (), + [25] = getop_meta (OPCODE_META_TYPE_VARG_PROP_SETTER, 3, 250), + + /* set property3 (b) { this.property1 = b; } }; */ + [26] = getop_func_expr_n (250, 243 /* any tmp reg */, 1), + [27] = getop_meta (OPCODE_META_TYPE_VARG, 1, 255), + [28] = getop_meta (OPCODE_META_TYPE_FUNCTION_END, 0, 34), + [29] = getop_reg_var_decl (250, 255), + [30] = getop_this (250), + [31] = getop_assignment (251, OPCODE_ARG_TYPE_STRING, 2), + [32] = getop_prop_setter (250, 251, 1), + [33] = getop_ret (), + [34] = getop_meta (OPCODE_META_TYPE_VARG_PROP_SETTER, 4, 250), + + /* assert (a.property1 === 'value1'); */ + [35] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2), + [36] = getop_prop_getter (240, 0, 240), + [37] = getop_assignment (241, OPCODE_ARG_TYPE_STRING, 5), + [38] = getop_equal_value_type (240, 240, 241), + [39] = getop_is_false_jmp (240, 2), + + /* assert (a.property2 === 1); */ + [40] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 3), + [41] = getop_prop_getter (240, 0, 240), + [42] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 1), + [43] = getop_equal_value_type (240, 240, 241), + [44] = getop_is_false_jmp (240, 2), + + /* a.property3 = 'value2'; */ + [45] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 4), + [46] = getop_assignment (241, OPCODE_ARG_TYPE_STRING, 6), + [47] = getop_prop_setter (0, 240, 241), + + /* assert (a.property1 === 'value2'); */ + [48] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2), + [49] = getop_prop_getter (240, 0, 240), + [50] = getop_assignment (241, OPCODE_ARG_TYPE_STRING, 6), + [51] = getop_equal_value_type (240, 240, 241), + [52] = getop_is_false_jmp (240, 2), + + /* a.property2 = 2.5; */ + [53] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 3), + [54] = getop_assignment (241, OPCODE_ARG_TYPE_NUMBER, 7), + [55] = getop_prop_setter (0, 240, 241), + + /* assert (a.property1 === 25); */ + [56] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2), + [57] = getop_prop_getter (240, 0, 240), + [58] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 25), + [59] = getop_equal_value_type (240, 240, 241), + [60] = getop_is_false_jmp (240, 2), + + /* b = delete a[b]; */ + [61] = getop_delete_prop (1, 0, 1), + + /* assert (b === true); */ + [62] = getop_assignment (240, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_TRUE), + [63] = getop_equal_value_type (240, 240, 1), + [64] = getop_is_false_jmp (240, 2), + + /* assert (a.property1 === undefined); */ + [65] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2), + [66] = getop_prop_getter (240, 0, 240), + [67] = getop_assignment (241, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_UNDEFINED), + [68] = getop_equal_value_type (240, 240, 241), + [69] = getop_is_false_jmp (240, 2), + + [70] = getop_exitval (0) + }; + + mem_init(); + serializer_init (false); + + const char *strings[] = { "a", + "b", + "property1", + "property2", + "property3", + "value1", + "value2" }; + ecma_number_t nums [] = { 2.5 }; + uint16_t offset = serializer_dump_strings( strings, 7); + serializer_dump_nums( nums, 1, offset, 7); + + init_int( test_program); + + bool status = run_int(); + + serializer_free (); + mem_finalize (false); + + return (status ? 0 : 1); +} /* main */