diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index ee64448779..9819f343b2 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -1403,40 +1403,58 @@ opfunc_private_set (ecma_value_t base, /**< this object */ ecma_value_t property, /**< property name */ ecma_value_t value) /**< ecma value */ { - ecma_object_t *obj_p = ecma_get_object_from_value (base); + ecma_value_t base_obj = ecma_op_to_object (base); + + if (ECMA_IS_VALUE_ERROR (base_obj)) + { + return base_obj; + } + + ecma_object_t *obj_p = ecma_get_object_from_value (base_obj); ecma_string_t *prop_name_p = ecma_get_string_from_value (property); ecma_string_t *private_key_p = NULL; ecma_property_t *prop_p = opfunc_find_private_element (obj_p, prop_name_p, &private_key_p, true); + ecma_value_t result; + if (prop_p == NULL) { - return ecma_raise_type_error (ECMA_ERR_CANNOT_WRITE_PRIVATE_MEMBER_TO_AN_OBJECT_WHOSE_CLASS_DID_NOT_DECLARE_IT); + result = ecma_raise_type_error (ECMA_ERR_CANNOT_WRITE_PRIVATE_MEMBER_TO_AN_OBJECT_WHOSE_CLASS_DID_NOT_DECLARE_IT); } - - if (*prop_p & ECMA_PROPERTY_FLAG_DATA) + else if (*prop_p & ECMA_PROPERTY_FLAG_DATA) { JERRY_ASSERT (ecma_prop_name_is_symbol (private_key_p)); if (private_key_p->u.hash & ECMA_SYMBOL_FLAG_PRIVATE_INSTANCE_METHOD) { - return ecma_raise_type_error (ECMA_ERR_PRIVATE_METHOD_IS_NOT_WRITABLE); + result = ecma_raise_type_error (ECMA_ERR_PRIVATE_METHOD_IS_NOT_WRITABLE); + } + else + { + ecma_value_assign_value (&ECMA_PROPERTY_VALUE_PTR (prop_p)->value, value); + result = ecma_copy_value (value); } - - ecma_value_assign_value (&ECMA_PROPERTY_VALUE_PTR (prop_p)->value, value); - return ecma_copy_value (value); } + else + { + ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (ECMA_PROPERTY_VALUE_PTR (prop_p)); - ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (ECMA_PROPERTY_VALUE_PTR (prop_p)); + if (get_set_pair_p->setter_cp == JMEM_CP_NULL) + { + result = ecma_raise_type_error (ECMA_ERR_PRIVATE_FIELD_WAS_DEFINED_WITHOUT_A_SETTER); + } + else + { + ecma_object_t *setter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp); - if (get_set_pair_p->setter_cp == JMEM_CP_NULL) - { - return ecma_raise_type_error (ECMA_ERR_PRIVATE_FIELD_WAS_DEFINED_WITHOUT_A_SETTER); + result = ecma_op_function_call (setter_p, base, &value, 1); + } } - ecma_object_t *setter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp); + ecma_deref_object (obj_p); - return ecma_op_function_call (setter_p, base, &value, 1); + return result; } /* opfunc_private_set */ /** diff --git a/tests/jerry/es.next/regression-test-issue-4936.js b/tests/jerry/es.next/regression-test-issue-4936.js new file mode 100644 index 0000000000..b1be6f69a0 --- /dev/null +++ b/tests/jerry/es.next/regression-test-issue-4936.js @@ -0,0 +1,33 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// 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. + +class JSEtest { + set #m(v) { + this._v = v; + } + + method() { + let self = !this; + self.#m = 'Test262'; + } +} + +let c = new JSEtest(); + +try { + c.method(); + assert(false); +} catch (e) { + assert(e instanceof TypeError); +} diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index da86ba5bc2..742cb67d7c 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -522,7 +522,6 @@ -