From d1f6760f01f49c0d019f8000c7348a7476fb2642 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Wed, 18 Feb 2015 17:38:46 +0300 Subject: [PATCH] Accessing getter and setter fields of named data accessor property descriptor through ecma_{get,set}_named_accessor_property_{getter,setter}. --- jerry-core/ecma/base/ecma-gc.cpp | 6 +- jerry-core/ecma/base/ecma-helpers.cpp | 111 ++++++++++++++---- jerry-core/ecma/base/ecma-helpers.h | 8 ++ .../ecma/operations/ecma-get-put-value.cpp | 3 +- .../ecma/operations/ecma-objects-general.cpp | 34 ++---- 5 files changed, 112 insertions(+), 50 deletions(-) diff --git a/jerry-core/ecma/base/ecma-gc.cpp b/jerry-core/ecma/base/ecma-gc.cpp index 44a62bf68..4f02f2d0b 100644 --- a/jerry-core/ecma/base/ecma-gc.cpp +++ b/jerry-core/ecma/base/ecma-gc.cpp @@ -390,10 +390,8 @@ ecma_gc_mark (ecma_object_t *object_p, /**< start object */ case ECMA_PROPERTY_NAMEDACCESSOR: { - ecma_object_t *getter_obj_p = ECMA_GET_POINTER (ecma_object_t, - property_p->u.named_accessor_property.get_p); - ecma_object_t *setter_obj_p = ECMA_GET_POINTER (ecma_object_t, - property_p->u.named_accessor_property.set_p); + ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (property_p); + ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (property_p); if (getter_obj_p != NULL) { diff --git a/jerry-core/ecma/base/ecma-helpers.cpp b/jerry-core/ecma/base/ecma-helpers.cpp index 07053d61f..171f515e6 100644 --- a/jerry-core/ecma/base/ecma-helpers.cpp +++ b/jerry-core/ecma/base/ecma-helpers.cpp @@ -562,12 +562,6 @@ ecma_create_named_accessor_property (ecma_object_t *obj_p, /**< object */ name_p = ecma_copy_or_ref_ecma_string (name_p); ECMA_SET_NON_NULL_POINTER(prop_p->u.named_accessor_property.name_p, name_p); - ECMA_SET_POINTER(prop_p->u.named_accessor_property.get_p, get_p); - ecma_gc_update_may_ref_younger_object_flag_by_object (obj_p, get_p); - - ECMA_SET_POINTER(prop_p->u.named_accessor_property.set_p, set_p); - ecma_gc_update_may_ref_younger_object_flag_by_object (obj_p, set_p); - prop_p->u.named_accessor_property.enumerable = (is_enumerable ? ECMA_PROPERTY_ENUMERABLE : ECMA_PROPERTY_NOT_ENUMERABLE); prop_p->u.named_accessor_property.configurable = (is_configurable ? @@ -581,6 +575,12 @@ ecma_create_named_accessor_property (ecma_object_t *obj_p, /**< object */ ECMA_SET_POINTER(prop_p->next_property_p, list_head_p); ecma_set_property_list (obj_p, prop_p); + /* + * Should be performed after linking the property into object's property list, because the setters assert that. + */ + ecma_set_named_accessor_property_getter (obj_p, prop_p, get_p); + ecma_set_named_accessor_property_setter (obj_p, prop_p, set_p); + return prop_p; } /* ecma_create_named_accessor_property */ @@ -868,6 +868,32 @@ ecma_delete_property (ecma_object_t *obj_p, /**< object */ JERRY_UNREACHABLE(); } /* ecma_delete_property */ +/** + * Check that + */ +static void +ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ecma-object */ + const ecma_property_t *prop_p) /**< ecma-property */ +{ +#ifndef JERRY_NDEBUG + ecma_property_t *prop_iter_p; + for (prop_iter_p = ecma_get_property_list (object_p); + prop_iter_p != NULL; + prop_iter_p = ECMA_GET_POINTER (ecma_property_t, prop_iter_p->next_property_p)) + { + if (prop_iter_p == prop_p) + { + break; + } + } + + JERRY_ASSERT (prop_iter_p != NULL); +#else /* JERRY_NDEBUG */ + (void) object_p; + (void) prop_p; +#endif /* JERRY_NDEBUG */ +} /* ecma_assert_object_contains_the_property */ + /** * Get value field of named data property * @@ -908,20 +934,7 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */ const ecma_value_t& value) /**< value to assign */ { JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDDATA); -#ifndef JERRY_NDEBUG - ecma_property_t *prop_iter_p; - for (prop_iter_p = ecma_get_property_list (obj_p); - prop_iter_p != NULL; - prop_iter_p = ECMA_GET_POINTER (ecma_property_t, prop_iter_p->next_property_p)) - { - if (prop_iter_p == prop_p) - { - break; - } - } - - JERRY_ASSERT (prop_iter_p != NULL); -#endif /* !JERRY_NDEBUG */ + ecma_assert_object_contains_the_property (obj_p, prop_p); if (ecma_is_value_number (value) && ecma_is_value_number (prop_p->u.named_data_property.value)) @@ -942,6 +955,64 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */ } } /* ecma_named_data_property_assign_value */ +/** + * Get getter of named accessor property + * + * @return pointer to object - getter of the property + */ +ecma_object_t* +ecma_get_named_accessor_property_getter (const ecma_property_t *prop_p) /**< named accessor property */ +{ + JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDACCESSOR); + + return ECMA_GET_POINTER (ecma_object_t, prop_p->u.named_accessor_property.get_p); +} /* ecma_named_accessor_property_get_getter */ + +/** + * Get setter of named accessor property + * + * @return pointer to object - setter of the property + */ +ecma_object_t* +ecma_get_named_accessor_property_setter (const ecma_property_t *prop_p) /**< named accessor property */ +{ + JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDACCESSOR); + + return ECMA_GET_POINTER (ecma_object_t, prop_p->u.named_accessor_property.set_p); +} /* ecma_named_accessor_property_get_setter */ + +/** + * Set getter of named accessor property + */ +void +ecma_set_named_accessor_property_getter (ecma_object_t* object_p, /**< the property's container */ + ecma_property_t *prop_p, /**< named accessor property */ + ecma_object_t *getter_p) /**< getter object */ +{ + JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDACCESSOR); + ecma_assert_object_contains_the_property (object_p, prop_p); + + ECMA_SET_POINTER (prop_p->u.named_accessor_property.get_p, getter_p); + + ecma_gc_update_may_ref_younger_object_flag_by_object (object_p, getter_p); +} /* ecma_named_accessor_property_set_getter */ + +/** + * Set setter of named accessor property + */ +void +ecma_set_named_accessor_property_setter (ecma_object_t* object_p, /**< the property's container */ + ecma_property_t *prop_p, /**< named accessor property */ + ecma_object_t *setter_p) /**< setter object */ +{ + JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDACCESSOR); + ecma_assert_object_contains_the_property (object_p, prop_p); + + ECMA_SET_POINTER (prop_p->u.named_accessor_property.set_p, setter_p); + + ecma_gc_update_may_ref_younger_object_flag_by_object (object_p, setter_p); +} /* ecma_named_accessor_property_set_setter */ + /** * Get property's 'Writable' attribute value * diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 5670c57be..b18b74374 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -280,6 +280,14 @@ extern void ecma_named_data_property_assign_value (ecma_object_t *obj_p, ecma_property_t *prop_p, const ecma_value_t& value); +extern ecma_object_t* ecma_get_named_accessor_property_getter (const ecma_property_t *prop_p); +extern ecma_object_t* ecma_get_named_accessor_property_setter (const ecma_property_t *prop_p); +extern void ecma_set_named_accessor_property_getter (ecma_object_t* object_p, + ecma_property_t *prop_p, + ecma_object_t *getter_p); +extern void ecma_set_named_accessor_property_setter (ecma_object_t* object_p, + ecma_property_t *prop_p, + ecma_object_t *setter_p); extern bool ecma_is_property_writable (ecma_property_t* prop_p); extern void ecma_set_property_writable_attr (ecma_property_t* prop_p, bool is_writable); extern bool ecma_is_property_enumerable (ecma_property_t* prop_p); diff --git a/jerry-core/ecma/operations/ecma-get-put-value.cpp b/jerry-core/ecma/operations/ecma-get-put-value.cpp index 460872c85..0858e0efa 100644 --- a/jerry-core/ecma/operations/ecma-get-put-value.cpp +++ b/jerry-core/ecma/operations/ecma-get-put-value.cpp @@ -284,8 +284,7 @@ ecma_op_put_value_object_base (ecma_reference_t ref, /**< ECMA-reference */ // sub_6. JERRY_ASSERT (prop_p != NULL && prop_p->type == ECMA_PROPERTY_NAMEDACCESSOR); - ecma_object_t *setter_p = ECMA_GET_NON_NULL_POINTER(ecma_object_t, - prop_p->u.named_accessor_property.set_p); + ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (prop_p); JERRY_ASSERT (setter_p != NULL); ECMA_TRY_CATCH (call_ret, diff --git a/jerry-core/ecma/operations/ecma-objects-general.cpp b/jerry-core/ecma/operations/ecma-objects-general.cpp index a4d2aaef9..70137f56a 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.cpp +++ b/jerry-core/ecma/operations/ecma-objects-general.cpp @@ -140,8 +140,7 @@ ecma_op_general_object_get (ecma_object_t *obj_p, /**< the object */ else { // 4. - ecma_object_t *getter_p = ECMA_GET_POINTER (ecma_object_t, - prop_p->u.named_accessor_property.get_p); + ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_p); // 5. if (getter_p == NULL) @@ -286,8 +285,7 @@ ecma_op_general_object_put (ecma_object_t *obj_p, /**< the object */ && desc_p->type == ECMA_PROPERTY_NAMEDACCESSOR) { // a. - ecma_object_t *setter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - desc_p->u.named_accessor_property.set_p); + ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (desc_p); JERRY_ASSERT(setter_p != NULL); ecma_completion_value_t ret_value; @@ -362,8 +360,7 @@ ecma_op_general_object_can_put (ecma_object_t *obj_p, /**< the object */ // a. if (prop_p->type == ECMA_PROPERTY_NAMEDACCESSOR) { - ecma_object_t *setter_p = ECMA_GET_POINTER (ecma_object_t, - prop_p->u.named_accessor_property.set_p); + ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (prop_p); // i. if (setter_p == NULL) @@ -405,8 +402,7 @@ ecma_op_general_object_can_put (ecma_object_t *obj_p, /**< the object */ // 7. if (inherited_p->type == ECMA_PROPERTY_NAMEDACCESSOR) { - ecma_object_t *setter_p = ECMA_GET_POINTER (ecma_object_t, - inherited_p->u.named_accessor_property.set_p); + ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (inherited_p); // a. if (setter_p == NULL) @@ -688,8 +684,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec if (property_desc_p->is_get_defined) { if (!is_current_accessor_descriptor - || property_desc_p->get_p != ECMA_GET_POINTER (ecma_object_t, - current_p->u.named_accessor_property.get_p)) + || property_desc_p->get_p != ecma_get_named_accessor_property_getter (current_p)) { is_every_field_in_desc_also_occurs_in_current_desc_with_same_value = false; } @@ -698,8 +693,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec if (property_desc_p->is_set_defined) { if (!is_current_accessor_descriptor - || property_desc_p->set_p != ECMA_GET_POINTER (ecma_object_t, - current_p->u.named_accessor_property.set_p)) + || property_desc_p->set_p != ecma_get_named_accessor_property_setter (current_p)) { is_every_field_in_desc_also_occurs_in_current_desc_with_same_value = false; } @@ -811,11 +805,9 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec // a. if ((property_desc_p->is_get_defined - && property_desc_p->get_p != ECMA_GET_POINTER (ecma_object_t, - current_p->u.named_accessor_property.get_p)) + && property_desc_p->get_p != ecma_get_named_accessor_property_getter (current_p)) || (property_desc_p->is_set_defined - && property_desc_p->set_p != ECMA_GET_POINTER (ecma_object_t, - current_p->u.named_accessor_property.set_p))) + && property_desc_p->set_p != ecma_get_named_accessor_property_setter (current_p))) { // i., ii. return ecma_reject (is_throw); @@ -842,20 +834,14 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec { JERRY_ASSERT(is_current_accessor_descriptor); - ecma_object_t *get_p = property_desc_p->get_p; - - ECMA_SET_POINTER(current_p->u.named_accessor_property.get_p, get_p); - ecma_gc_update_may_ref_younger_object_flag_by_object (obj_p, get_p); + ecma_set_named_accessor_property_getter (obj_p, current_p, property_desc_p->get_p); } if (property_desc_p->is_set_defined) { JERRY_ASSERT(is_current_accessor_descriptor); - ecma_object_t *set_p = property_desc_p->set_p; - - ECMA_SET_POINTER(current_p->u.named_accessor_property.set_p, set_p); - ecma_gc_update_may_ref_younger_object_flag_by_object (obj_p, set_p); + ecma_set_named_accessor_property_setter (obj_p, current_p, property_desc_p->set_p); } if (property_desc_p->is_enumerable_defined)