From f18222a44f9d8a8b2b055dc3acb5e67f5f713c38 Mon Sep 17 00:00:00 2001 From: Kristof Kosztyo Date: Tue, 12 May 2015 14:41:48 +0200 Subject: [PATCH 1/2] Implement Object.defineProperties function JerryScript-DCO-1.0-Signed-off-by: Kristof Kosztyo kkosztyo.u-szeged@partner.samsung.com --- .../builtin-objects/ecma-builtin-object.cpp | 64 ++++++++++++++++++- tests/jerry/object_define_properties.js | 34 ++++++++++ 2 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 tests/jerry/object_define_properties.js diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp index 553574f1f3..5ed2672d6c 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp @@ -1,4 +1,5 @@ /* Copyright 2014-2015 Samsung Electronics Co., Ltd. + * Copyright 2015 University of Szeged. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -289,11 +290,70 @@ ecma_builtin_object_object_create (ecma_value_t this_arg, /**< 'this' argument * * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t -ecma_builtin_object_object_define_properties (ecma_value_t this_arg, /**< 'this' argument */ +ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */ ecma_value_t arg1, /**< routine's first argument */ ecma_value_t arg2) /**< routine's second argument */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg1, arg2); + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + + if (!ecma_is_value_object (arg1)) + { + ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); + return ret_value; + } + + ecma_object_t *obj_p = ecma_get_object_from_value (arg1); + ecma_object_t *props = ecma_get_object_from_value (arg2); + + ecma_property_t *property_p; + + for (property_p = ecma_get_property_list (props); + property_p != NULL; + property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p)) + { + ecma_string_t *property_name_p; + + if (property_p->type == ECMA_PROPERTY_NAMEDDATA) + { + property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, + property_p->u.named_data_property.name_p); + } + else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR) + { + property_name_p = ECMA_GET_NON_NULL_POINTER(ecma_string_t, + property_p->u.named_accessor_property.name_p); + } + else + { + continue; + } + ecma_value_t val = ecma_get_named_data_property_value (property_p); + ecma_property_descriptor_t prop_desc; + + ECMA_TRY_CATCH (conv_result, + ecma_op_to_property_descriptor (val, &prop_desc), + ret_value); + + ECMA_TRY_CATCH (define_own_prop_ret, + ecma_op_object_define_own_property (obj_p, + property_name_p, + &prop_desc, + true), + ret_value); + + ECMA_FINALIZE (define_own_prop_ret); + ecma_free_property_descriptor (&prop_desc); + ECMA_FINALIZE (conv_result); + + if (ecma_is_completion_value_throw (ret_value)) + { + return ret_value; + } + } + + ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg1, true)); + + return ret_value; } /* ecma_builtin_object_object_define_properties */ /** diff --git a/tests/jerry/object_define_properties.js b/tests/jerry/object_define_properties.js new file mode 100644 index 0000000000..4f62fc278e --- /dev/null +++ b/tests/jerry/object_define_properties.js @@ -0,0 +1,34 @@ +// Copyright 2015 Samsung Electronics Co., Ltd. +// Copyright 2015 University of Szeged. +// +// 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. + +var obj = {}; +Object.defineProperties(obj, { + "foo": { + value: true, + writable: true + }, + "bar": { + value: "baz", + writable: false + }, + "Hello": { + value: "world", + writable: false + } +}); + +assert (obj.foo === true); +assert (obj.bar === "baz"); +assert (obj.Hello === "world"); From a11cbf421096ab165886fb48de55449cb7de6443 Mon Sep 17 00:00:00 2001 From: Kristof Kosztyo Date: Mon, 18 May 2015 12:54:11 +0200 Subject: [PATCH 2/2] Fix implementation of the Object.defineProperties according to the review. JerryScript-DCO-1.0-Signed-off-by: Kristof Kosztyo kkosztyo.u-szeged@partner.samsung.com --- .../ecma/builtin-objects/ecma-builtin-object.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp index 5ed2672d6c..d9de95d047 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp @@ -303,11 +303,11 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse } ecma_object_t *obj_p = ecma_get_object_from_value (arg1); - ecma_object_t *props = ecma_get_object_from_value (arg2); + ecma_object_t *props_p = ecma_get_object_from_value (arg2); ecma_property_t *property_p; - for (property_p = ecma_get_property_list (props); + for (property_p = ecma_get_property_list (props_p); property_p != NULL; property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p)) { @@ -327,11 +327,15 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse { continue; } - ecma_value_t val = ecma_get_named_data_property_value (property_p); ecma_property_descriptor_t prop_desc; + ECMA_TRY_CATCH (descObj, + ecma_op_general_object_get (props_p, property_name_p), + ret_value); + ECMA_TRY_CATCH (conv_result, - ecma_op_to_property_descriptor (val, &prop_desc), + ecma_op_to_property_descriptor (ecma_get_completion_value_value (descObj), + &prop_desc), ret_value); ECMA_TRY_CATCH (define_own_prop_ret, @@ -344,6 +348,7 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse ECMA_FINALIZE (define_own_prop_ret); ecma_free_property_descriptor (&prop_desc); ECMA_FINALIZE (conv_result); + ECMA_FINALIZE (descObj); if (ecma_is_completion_value_throw (ret_value)) {