From 7a2665621bfaedf422652a68eeaad799a9de79ce Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Wed, 10 Mar 2021 08:17:20 +0100 Subject: [PATCH] Reorganize property descriptor flags (#4622) Furthermore rename JERRY_PROP_IS_THROW to JERRY_PROP_SHOULD_THROW and add more invalid descriptor checks. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- docs/02.API-REFERENCE.md | 8 +-- jerry-core/api/jerry.c | 57 ++++++++++--------- jerry-core/ecma/base/ecma-globals.h | 48 +++++++--------- .../ecma-builtin-array-prototype.c | 10 ++-- .../ecma/builtin-objects/ecma-builtin-array.c | 6 +- .../builtin-objects/ecma-builtin-helpers.c | 5 +- .../ecma-builtin-object-prototype.c | 2 +- .../builtin-objects/ecma-builtin-object.c | 8 +-- .../ecma-builtin-regexp-prototype.c | 2 +- .../ecma/operations/ecma-array-object.c | 2 +- jerry-core/ecma/operations/ecma-lex-env.c | 2 +- .../ecma/operations/ecma-objects-general.c | 2 +- jerry-core/ecma/operations/ecma-objects.c | 10 ++-- .../ecma/operations/ecma-regexp-object.c | 2 +- .../ecma/operations/ecma-typedarray-object.c | 6 +- jerry-core/include/jerryscript-core.h | 21 +++---- tests/unit-core/test-api-property.c | 2 +- .../unit-core/test-from-property-descriptor.c | 16 ++++++ 18 files changed, 112 insertions(+), 97 deletions(-) diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index 9f5b42e00..db8753ceb 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -489,16 +489,16 @@ Enum that contains the supported binary operation types Enum that contains the flags of property descriptors. - JERRY_PROP_NO_OPTS - empty property descriptor - - JERRY_PROP_IS_GET_DEFINED - Is [[Get]] defined? - - JERRY_PROP_IS_SET_DEFINED - Is [[Set]] defined? - JERRY_PROP_IS_CONFIGURABLE - [[Configurable]] - JERRY_PROP_IS_ENUMERABLE - [[Enumerable]] - JERRY_PROP_IS_WRITABLE - [[Writable]] - - JERRY_PROP_IS_THROW - Flag that controls failure handling - - JERRY_PROP_IS_VALUE_DEFINED - Is [[Value]] defined? - JERRY_PROP_IS_CONFIGURABLE_DEFINED - Is [[Configurable]] defined? - JERRY_PROP_IS_ENUMERABLE_DEFINED - Is [[Enumerable]] defined? - JERRY_PROP_IS_WRITABLE_DEFINED - Is [[Writable]] defined? + - JERRY_PROP_IS_VALUE_DEFINED - Is [[Value]] defined? + - JERRY_PROP_IS_GET_DEFINED - Is [[Get]] defined? + - JERRY_PROP_IS_SET_DEFINED - Is [[Set]] defined? + - JERRY_PROP_SHOULD_THROW - Should throw on error, instead of returning with false *New in version [[NEXT_RELEASE]]*. diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index ac8132fa2..ce81b44cb 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -70,16 +70,16 @@ JERRY_STATIC_ASSERT ((int) ECMA_INIT_EMPTY == (int) JERRY_INIT_EMPTY ecma_init_flag_t_must_be_equal_to_jerry_init_flag_t); JERRY_STATIC_ASSERT ((int) JERRY_PROP_NO_OPTS == (int) ECMA_PROP_NO_OPTS - && (int) JERRY_PROP_IS_GET_DEFINED == (int) ECMA_PROP_IS_GET_DEFINED - && (int) JERRY_PROP_IS_SET_DEFINED == (int) ECMA_PROP_IS_SET_DEFINED && (int) JERRY_PROP_IS_CONFIGURABLE == (int) ECMA_PROP_IS_CONFIGURABLE && (int) JERRY_PROP_IS_ENUMERABLE == (int) ECMA_PROP_IS_ENUMERABLE && (int) JERRY_PROP_IS_WRITABLE == (int) ECMA_PROP_IS_WRITABLE - && (int) JERRY_PROP_IS_THROW == (int) ECMA_PROP_IS_THROW - && (int) JERRY_PROP_IS_VALUE_DEFINED == (int) ECMA_PROP_IS_VALUE_DEFINED && (int) JERRY_PROP_IS_CONFIGURABLE_DEFINED == (int) ECMA_PROP_IS_CONFIGURABLE_DEFINED && (int) JERRY_PROP_IS_ENUMERABLE_DEFINED == (int) ECMA_PROP_IS_ENUMERABLE_DEFINED - && (int) JERRY_PROP_IS_WRITABLE_DEFINED == (int) ECMA_PROP_IS_WRITABLE_DEFINED, + && (int) JERRY_PROP_IS_WRITABLE_DEFINED == (int) ECMA_PROP_IS_WRITABLE_DEFINED + && (int) JERRY_PROP_IS_VALUE_DEFINED == (int) ECMA_PROP_IS_VALUE_DEFINED + && (int) JERRY_PROP_IS_GET_DEFINED == (int) ECMA_PROP_IS_GET_DEFINED + && (int) JERRY_PROP_IS_SET_DEFINED == (int) ECMA_PROP_IS_SET_DEFINED + && (int) JERRY_PROP_SHOULD_THROW == (int) ECMA_PROP_SHOULD_THROW, jerry_prop_desc_flags_must_be_equal_to_ecma_prop_desc_flags); #if JERRY_BUILTIN_REGEXP @@ -3370,7 +3370,7 @@ jerry_property_descriptor_to_ecma (const jerry_property_descriptor_t *prop_desc_ prop_desc.flags = prop_desc_p->flags; /* Copy data property info. */ - if (prop_desc_p->flags & (JERRY_PROP_IS_VALUE_DEFINED)) + if (prop_desc_p->flags & JERRY_PROP_IS_VALUE_DEFINED) { if (ecma_is_value_error_reference (prop_desc_p->value)) { @@ -3382,7 +3382,7 @@ jerry_property_descriptor_to_ecma (const jerry_property_descriptor_t *prop_desc_ } /* Copy accessor property info. */ - if (prop_desc_p->flags & (JERRY_PROP_IS_GET_DEFINED)) + if (prop_desc_p->flags & JERRY_PROP_IS_GET_DEFINED) { ecma_value_t getter = prop_desc_p->getter; @@ -3403,7 +3403,7 @@ jerry_property_descriptor_to_ecma (const jerry_property_descriptor_t *prop_desc_ } } - if (prop_desc_p->flags & (JERRY_PROP_IS_SET_DEFINED)) + if (prop_desc_p->flags & JERRY_PROP_IS_SET_DEFINED) { ecma_value_t setter = prop_desc_p->setter; @@ -3424,7 +3424,19 @@ jerry_property_descriptor_to_ecma (const jerry_property_descriptor_t *prop_desc_ } } - prop_desc.flags |= (uint16_t) (prop_desc_p->flags | ECMA_PROP_IS_THROW); + const uint16_t configurable_mask = JERRY_PROP_IS_CONFIGURABLE | JERRY_PROP_IS_CONFIGURABLE_DEFINED; + const uint16_t enumerable_mask = JERRY_PROP_IS_ENUMERABLE | JERRY_PROP_IS_ENUMERABLE_DEFINED; + const uint16_t writable_mask = JERRY_PROP_IS_WRITABLE | JERRY_PROP_IS_WRITABLE_DEFINED; + + if ((prop_desc_p->flags & configurable_mask) == JERRY_PROP_IS_CONFIGURABLE + || (prop_desc_p->flags & enumerable_mask) == JERRY_PROP_IS_ENUMERABLE + || (prop_desc_p->flags & writable_mask) == JERRY_PROP_IS_WRITABLE) + { + prop_desc.value = ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)); + return prop_desc; + } + + prop_desc.flags |= (uint16_t) (prop_desc_p->flags | ECMA_PROP_SHOULD_THROW); return prop_desc; } /* jerry_property_descriptor_to_ecma */ @@ -3448,7 +3460,7 @@ jerry_error_or_false (const jerry_value_t err_val, /**< error value */ * returned value must be freed with jerry_release_value, when it is no longer needed. * * @return true value - if the operation was successful - * false value - if the property cannot be defined and JERRY_PROP_IS_THROW is not set + * false value - if the property cannot be defined and JERRY_PROP_SHOULD_THROW is not set * value marked with error flag - otherwise */ jerry_value_t @@ -3462,21 +3474,21 @@ jerry_define_own_property (const jerry_value_t obj_val, /**< object value */ || !ecma_is_value_prop_name (prop_name_val)) { return jerry_error_or_false (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)), - prop_desc_p->flags & JERRY_PROP_IS_THROW); + prop_desc_p->flags & JERRY_PROP_SHOULD_THROW); } if (prop_desc_p->flags & (JERRY_PROP_IS_WRITABLE_DEFINED | JERRY_PROP_IS_VALUE_DEFINED) && prop_desc_p->flags & (JERRY_PROP_IS_GET_DEFINED | JERRY_PROP_IS_SET_DEFINED)) { return jerry_error_or_false (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)), - prop_desc_p->flags & JERRY_PROP_IS_THROW); + prop_desc_p->flags & JERRY_PROP_SHOULD_THROW); } ecma_property_descriptor_t prop_desc = jerry_property_descriptor_to_ecma (prop_desc_p); if (ECMA_IS_VALUE_ERROR (prop_desc.value)) { - return jerry_error_or_false (prop_desc.value, prop_desc_p->flags & JERRY_PROP_IS_THROW); + return jerry_error_or_false (prop_desc.value, prop_desc_p->flags & JERRY_PROP_SHOULD_THROW); } return jerry_return (ecma_op_object_define_own_property (ecma_get_object_from_value (obj_val), @@ -3522,20 +3534,13 @@ jerry_get_own_property_descriptor (const jerry_value_t obj_val, /**< object val return false; } - prop_desc_p->flags = prop_desc.flags; - if (!(prop_desc_p->flags & JERRY_PROP_IS_WRITABLE_DEFINED)) - { - prop_desc_p->flags &= (uint16_t) ~JERRY_PROP_IS_WRITABLE; - } - if (!(prop_desc_p->flags & JERRY_PROP_IS_CONFIGURABLE_DEFINED)) - { - prop_desc_p->flags &= (uint16_t) ~JERRY_PROP_IS_CONFIGURABLE; - } - if (!(prop_desc_p->flags & JERRY_PROP_IS_ENUMERABLE_DEFINED)) - { - prop_desc_p->flags &= (uint16_t) ~JERRY_PROP_IS_ENUMERABLE; - } + /* The flags are always filled in the returned descriptor. */ + JERRY_ASSERT ((prop_desc.flags & ECMA_PROP_IS_CONFIGURABLE_DEFINED) + && (prop_desc.flags & ECMA_PROP_IS_ENUMERABLE_DEFINED) + && ((prop_desc.flags & ECMA_PROP_IS_WRITABLE_DEFINED) + || !(prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED))); + prop_desc_p->flags = prop_desc.flags; prop_desc_p->value = ECMA_VALUE_UNDEFINED; prop_desc_p->getter = ECMA_VALUE_UNDEFINED; prop_desc_p->setter = ECMA_VALUE_UNDEFINED; diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 693729d15..f22bd4a5e 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -396,16 +396,18 @@ typedef enum */ typedef enum { - ECMA_PROPERTY_FLAG_DELETED = 1u << 0, /**< property is deleted */ - ECMA_FAST_ARRAY_FLAG = 1u << 0, /**< array is fast array */ - ECMA_PROPERTY_FLAG_LCACHED = 1u << 1, /**< property is lcached */ + ECMA_PROPERTY_FLAG_CONFIGURABLE = (1u << 0), /**< property is configurable */ + ECMA_PROPERTY_FLAG_ENUMERABLE = (1u << 1), /**< property is enumerable */ + ECMA_PROPERTY_FLAG_WRITABLE = (1u << 2), /**< property is writable */ + + ECMA_PROPERTY_FLAG_DELETED = (1u << 3), /**< property is deleted */ + ECMA_FAST_ARRAY_FLAG = (1u << 3), /**< array is fast array */ + ECMA_PROPERTY_FLAG_LCACHED = (1u << 4), /**< property is lcached */ #if JERRY_ESNEXT - ECMA_ARRAY_TEMPLATE_LITERAL = 1u << 1, /**< array is a template literal constructed by the parser */ + ECMA_ARRAY_TEMPLATE_LITERAL = (1u << 4), /**< array is a template literal constructed by the parser */ #endif /* JERRY_ESNEXT */ - ECMA_PROPERTY_FLAG_CONFIGURABLE = 1u << 2, /**< property is configurable */ - ECMA_PROPERTY_FLAG_ENUMERABLE = 1u << 3, /**< property is enumerable */ - ECMA_PROPERTY_FLAG_WRITABLE = 1u << 4, /**< property is writable */ - ECMA_PROPERTY_FLAG_DATA = 1u << 5, /**< property contains data */ + ECMA_PROPERTY_FLAG_DATA = (1u << 5), /**< property contains data */ + /* The last two bits contains an ECMA_DIRECT_STRING value. */ } ecma_property_flags_t; /** @@ -1181,18 +1183,19 @@ typedef struct typedef enum { ECMA_PROP_NO_OPTS = (0), /** empty property descriptor */ - ECMA_PROP_IS_GET_DEFINED = (1 << 0), /** Is [[Get]] defined? */ - ECMA_PROP_IS_SET_DEFINED = (1 << 1), /** Is [[Set]] defined? */ + ECMA_PROP_IS_CONFIGURABLE = (1 << 0), /** [[Configurable]] */ + ECMA_PROP_IS_ENUMERABLE = (1 << 1), /** [[Enumerable]] */ + ECMA_PROP_IS_WRITABLE = (1 << 2), /** [[Writable]] */ - ECMA_PROP_IS_CONFIGURABLE = (1 << 2), /** [[Configurable]] */ - ECMA_PROP_IS_ENUMERABLE = (1 << 3), /** [[Enumerable]] */ - ECMA_PROP_IS_WRITABLE = (1 << 4), /** [[Writable]] */ - ECMA_PROP_IS_THROW = (1 << 5), /** Flag that controls failure handling */ + ECMA_PROP_IS_CONFIGURABLE_DEFINED = (1 << 3), /** is [[Configurable]] defined? */ + ECMA_PROP_IS_ENUMERABLE_DEFINED = (1 << 4), /** is [[Enumerable]] defined? */ + ECMA_PROP_IS_WRITABLE_DEFINED = (1 << 5), /** is [[Writable]] defined? */ - ECMA_PROP_IS_VALUE_DEFINED = (1 << 6), /** Is [[Value]] defined? */ - ECMA_PROP_IS_CONFIGURABLE_DEFINED = (1 << 7), /** Is [[Configurable]] defined? */ - ECMA_PROP_IS_ENUMERABLE_DEFINED = (1 << 8), /** Is [[Enumerable]] defined? */ - ECMA_PROP_IS_WRITABLE_DEFINED = (1 << 9), /** Is [[Writable]] defined? */ + ECMA_PROP_IS_VALUE_DEFINED = (1 << 6), /** is [[Value]] defined? */ + ECMA_PROP_IS_GET_DEFINED = (1 << 7), /** is [[Get]] defined? */ + ECMA_PROP_IS_SET_DEFINED = (1 << 8), /** is [[Set]] defined? */ + + ECMA_PROP_SHOULD_THROW = (1 << 9), /** should throw on error, instead of returning with false */ } ecma_property_descriptor_status_flags_t; /** @@ -1203,7 +1206,7 @@ typedef enum * Note: * If a component of descriptor is undefined then corresponding * field should contain it's default value. - * The struct members must be in this order or keep in sync with ecma_property_flags_t and ECMA_IS_THROW flag. + * The struct members must be in this order or keep in sync with ecma_property_descriptor_status_flags_t. */ typedef struct { @@ -1242,13 +1245,6 @@ typedef struct | ECMA_PROP_IS_ENUMERABLE \ | ECMA_PROP_IS_WRITABLE)) -/** - * Flag that controls failure handling during defining property - * - * Note: This flags represents the [[DefineOwnProperty]] (P, Desc, Throw) 3rd argument - */ -#define ECMA_IS_THROW ((uint8_t) ECMA_PROP_IS_THROW) - #if !JERRY_NUMBER_TYPE_FLOAT64 /** * Description of an ecma-number diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index 227f8cbf1..1df15a661 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -934,7 +934,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ /* 10.c.ii */ ecma_value_t put_comp; #if JERRY_ESNEXT - const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; #else /* !JERRY_ESNEXT */ const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE; #endif /* JERRY_ESNEXT */ @@ -1328,7 +1328,7 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu if (ecma_is_value_found (from_present)) { #if JERRY_ESNEXT - const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; #else /* !JERRY_ESNEXT */ const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE; #endif /* JERRY_ESNEXT */ @@ -1982,7 +1982,7 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */ /* 8.c.iii */ ecma_value_t put_comp; #if JERRY_ESNEXT - const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; #else /* !JERRY_ESNEXT */ const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE; #endif /* JERRY_ESNEXT */ @@ -2039,7 +2039,7 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn * } /* ES11: 22.1.3.7. 7.c.iii.1 */ - const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; #else /* !JERRY_ESNEXT */ ecma_object_t *new_array_p = ecma_op_new_array_object (0); @@ -2749,7 +2749,7 @@ ecma_builtin_array_flatten_into_array (ecma_value_t target, /**< target will con } /* vi. */ - const uint8_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; ecma_value_t element_temp = ecma_builtin_helper_def_prop_by_index (ecma_get_object_from_value (target), target_index, element, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c index 31079befb..774698ab2 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c @@ -239,7 +239,7 @@ ecma_builtin_array_object_from (ecma_value_t this_arg, /**< 'this' argument */ } /* 6.g.ix */ - const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; ecma_value_t set_status = ecma_builtin_helper_def_prop_by_index (array_obj_p, k, mapped_value, flags); ecma_free_value (mapped_value); @@ -359,7 +359,7 @@ iterator_cleanup: } /* 16.f */ - const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; ecma_value_t set_status = ecma_builtin_helper_def_prop_by_index (array_obj_p, k, mapped_value, flags); ecma_free_value (mapped_value); @@ -433,7 +433,7 @@ ecma_builtin_array_object_of (ecma_value_t this_arg, /**< 'this' argument */ uint32_t k = 0; ecma_object_t *obj_p = ecma_get_object_from_value (ret_val); - const uint32_t prop_status_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t prop_status_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; while (k < arguments_list_len) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index b60b89ad4..e59920681 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -346,7 +346,7 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *array_obj_p, /**< array * bool spread_object = is_spreadable == ECMA_VALUE_TRUE; /* ES11: 22.1.3.1.5.c.iv.3.b */ - const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; #else /* !JERRY_ESNEXT */ /* ES5.1: 15.4.4.4.5.b.iii.3.b */ const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE; @@ -831,8 +831,7 @@ ecma_value_t ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */ ecma_string_t *name_p, /**< name string */ ecma_value_t value, /**< value */ - uint32_t opts) /**< any combination of ecma_property_flag_t bits - * with the optional ECMA_IS_THROW flag */ + uint32_t opts) /**< any combination of ecma_property_descriptor_status_flags_t bits */ { ecma_property_descriptor_t prop_desc; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c index 6eda74eff..e680925e7 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c @@ -251,7 +251,7 @@ ecma_builtin_object_prototype_define_getter_setter (ecma_value_t this_arg, /**< | ECMA_PROP_IS_CONFIGURABLE | ECMA_PROP_IS_ENUMERABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE_DEFINED - | ECMA_PROP_IS_THROW); + | ECMA_PROP_SHOULD_THROW); if (define_getter) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c index 81f9bdd39..c7290d963 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c @@ -371,7 +371,7 @@ ecma_builtin_object_set_integrity_level (ecma_object_t *obj_p, /**< object */ } prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE; - prop_desc.flags |= ECMA_PROP_IS_THROW; + prop_desc.flags |= ECMA_PROP_SHOULD_THROW; /* 8.a.i */ ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, @@ -422,7 +422,7 @@ ecma_builtin_object_set_integrity_level (ecma_object_t *obj_p, /**< object */ } prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE; - prop_desc.flags |= ECMA_PROP_IS_THROW; + prop_desc.flags |= ECMA_PROP_SHOULD_THROW; /* 9.3 */ ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, @@ -881,7 +881,7 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine ecma_value_t conv_result = ecma_op_to_property_descriptor (desc_obj, &property_descriptors[property_descriptor_number]); - property_descriptors[property_descriptor_number].flags |= ECMA_PROP_IS_THROW; + property_descriptors[property_descriptor_number].flags |= ECMA_PROP_SHOULD_THROW; ecma_free_value (desc_obj); @@ -1009,7 +1009,7 @@ ecma_builtin_object_object_define_property (ecma_object_t *obj_p, /**< routine's return conv_result; } - prop_desc.flags |= ECMA_PROP_IS_THROW; + prop_desc.flags |= ECMA_PROP_SHOULD_THROW; ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, name_str_p, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c index a34e745e5..0f5398807 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c @@ -314,7 +314,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this */ ecma_value_t status = ecma_builtin_helper_def_prop (this_obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL), ecma_make_uint32_value (0), - ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROP_IS_THROW); + ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROP_SHOULD_THROW); ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p); diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 2f386d4e8..2ead293fa 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -1165,7 +1165,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra ecma_property_descriptor_t prop_desc; prop_desc = *property_desc_p; - prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_THROW; + prop_desc.flags &= (uint16_t) ~ECMA_PROP_SHOULD_THROW; ecma_value_t completition = ecma_op_general_object_define_own_property (object_p, property_name_p, diff --git a/jerry-core/ecma/operations/ecma-lex-env.c b/jerry-core/ecma/operations/ecma-lex-env.c index 261f9b5f9..b4bb886fd 100644 --- a/jerry-core/ecma/operations/ecma-lex-env.c +++ b/jerry-core/ecma/operations/ecma-lex-env.c @@ -206,7 +206,7 @@ ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environme } #endif /* JERRY_BUILTIN_PROXY && JERRY_BUILTIN_REALMS */ - const uint32_t flags = ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_IS_THROW; + const uint32_t flags = ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; ecma_value_t completion = ecma_builtin_helper_def_prop (binding_obj_p, name_p, diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index 5ff4be55b..78d98cfec 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -367,7 +367,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob if (!ecma_op_ordinary_object_is_extensible (object_p)) { /* 2. */ - return ECMA_REJECT_WITH_FORMAT (property_desc_p->flags & ECMA_PROP_IS_THROW, + return ECMA_REJECT_WITH_FORMAT (property_desc_p->flags & ECMA_PROP_SHOULD_THROW, "Cannot define property '%', object is not extensible", ecma_make_prop_name_value (property_name_p)); } diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 647382ef8..fff988b69 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -1546,10 +1546,8 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS && ext_object_p->u.pseudo_array.extra_info & ECMA_ARGUMENTS_OBJECT_MAPPED) { - return ecma_builtin_helper_def_prop (object_p, - property_name_p, - value, - ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW); + const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROP_SHOULD_THROW; + return ecma_builtin_helper_def_prop (object_p, property_name_p, value, flags); } } @@ -3321,7 +3319,7 @@ ecma_op_object_unref_weak (ecma_object_t *object_p, /**< this argument */ /** * Raise property redefinition error * - * @return ECMA_VALUE_FALSE - if ECMA_IS_THROW is not set + * @return ECMA_VALUE_FALSE - if ECMA_PROP_SHOULD_THROW is not set * raised TypeError - otherwise */ ecma_value_t @@ -3330,7 +3328,7 @@ ecma_raise_property_redefinition (ecma_string_t *property_name_p, /**< property { JERRY_UNUSED (property_name_p); - return ECMA_REJECT_WITH_FORMAT (flags & ECMA_PROP_IS_THROW, + return ECMA_REJECT_WITH_FORMAT (flags & ECMA_PROP_SHOULD_THROW, "Cannot redefine property '%'", ecma_make_prop_name_value (property_name_p)); } /* ecma_raise_property_redefinition */ diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index 87431d196..3ed770755 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -249,7 +249,7 @@ ecma_op_regexp_alloc (ecma_object_t *ctr_obj_p) /**< constructor object pointer ecma_value_t status = ecma_builtin_helper_def_prop (new_object_p, ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL), ecma_make_uint32_value (0), - ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROP_IS_THROW); + ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROP_SHOULD_THROW); JERRY_ASSERT (ecma_is_value_true (status)); diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 68c4e7925..593b1e530 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -1570,7 +1570,7 @@ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedA * See also: ES2015 9.4.5.3 * * @return ECMA_VALUE_TRUE - if the property is successfully defined - * ECMA_VALUE_FALSE - if is ECMA_IS_THROW is not set + * ECMA_VALUE_FALSE - if is ECMA_PROP_SHOULD_THROW is not set * raised TypeError - otherwise */ ecma_value_t @@ -1601,7 +1601,7 @@ ecma_op_typedarray_define_own_property (ecma_object_t *obj_p, /**< TypedArray ob if (array_index >= info.length) { - return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_IS_THROW), "Invalid typed array index"); + return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_SHOULD_THROW), "Invalid typed array index"); } if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) @@ -1625,7 +1625,7 @@ ecma_op_typedarray_define_own_property (ecma_object_t *obj_p, /**< TypedArray ob if (is_same) { - return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_IS_THROW), "Invalid typed array index"); + return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_SHOULD_THROW), "Invalid typed array index"); } } diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 74a525adf..12f4e0c0f 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -173,18 +173,19 @@ typedef uint32_t jerry_value_t; typedef enum { JERRY_PROP_NO_OPTS = (0), /** empty property descriptor */ - JERRY_PROP_IS_GET_DEFINED = (1 << 0), /** Is [[Get]] defined? */ - JERRY_PROP_IS_SET_DEFINED = (1 << 1), /** Is [[Set]] defined? */ + JERRY_PROP_IS_CONFIGURABLE = (1 << 0), /** [[Configurable]] */ + JERRY_PROP_IS_ENUMERABLE = (1 << 1), /** [[Enumerable]] */ + JERRY_PROP_IS_WRITABLE = (1 << 2), /** [[Writable]] */ - JERRY_PROP_IS_CONFIGURABLE = (1 << 2), /** [[Configurable]] */ - JERRY_PROP_IS_ENUMERABLE = (1 << 3), /** [[Enumerable]] */ - JERRY_PROP_IS_WRITABLE = (1 << 4), /** [[Writable]] */ - JERRY_PROP_IS_THROW = (1 << 5), /** Flag that controls failure handling */ + JERRY_PROP_IS_CONFIGURABLE_DEFINED = (1 << 3), /** is [[Configurable]] defined? */ + JERRY_PROP_IS_ENUMERABLE_DEFINED = (1 << 4), /** is [[Enumerable]] defined? */ + JERRY_PROP_IS_WRITABLE_DEFINED = (1 << 5), /** is [[Writable]] defined? */ - JERRY_PROP_IS_VALUE_DEFINED = (1 << 6), /** Is [[Value]] defined? */ - JERRY_PROP_IS_CONFIGURABLE_DEFINED = (1 << 7), /** Is [[Configurable]] defined? */ - JERRY_PROP_IS_ENUMERABLE_DEFINED = (1 << 8), /** Is [[Enumerable]] defined? */ - JERRY_PROP_IS_WRITABLE_DEFINED = (1 << 9), /** Is [[Writable]] defined? */ + JERRY_PROP_IS_VALUE_DEFINED = (1 << 6), /** is [[Value]] defined? */ + JERRY_PROP_IS_GET_DEFINED = (1 << 7), /** is [[Get]] defined? */ + JERRY_PROP_IS_SET_DEFINED = (1 << 8), /** is [[Set]] defined? */ + + JERRY_PROP_SHOULD_THROW = (1 << 9), /** should throw on error, instead of returning with false */ } jerry_property_descriptor_flags_t; /** diff --git a/tests/unit-core/test-api-property.c b/tests/unit-core/test-api-property.c index 38c36276c..9ae8077fc 100644 --- a/tests/unit-core/test-api-property.c +++ b/tests/unit-core/test-api-property.c @@ -45,7 +45,7 @@ main (void) /* Test: define own property with error */ prop_desc = jerry_property_descriptor_create (); - prop_desc.flags |= JERRY_PROP_IS_VALUE_DEFINED | JERRY_PROP_IS_THROW; + prop_desc.flags |= JERRY_PROP_IS_VALUE_DEFINED | JERRY_PROP_SHOULD_THROW; prop_desc.value = jerry_create_number (3.14); res = jerry_define_own_property (global_obj_val, prop_name, &prop_desc); TEST_ASSERT (jerry_value_is_error (res)); diff --git a/tests/unit-core/test-from-property-descriptor.c b/tests/unit-core/test-from-property-descriptor.c index e049febec..c3d538845 100644 --- a/tests/unit-core/test-from-property-descriptor.c +++ b/tests/unit-core/test-from-property-descriptor.c @@ -58,6 +58,22 @@ main (void) jerry_release_value (value); jerry_release_value (from_object); jerry_property_descriptor_free (&prop_desc); + + prop_desc.flags = JERRY_PROP_IS_CONFIGURABLE; + from_object = jerry_from_property_descriptor (&prop_desc); + TEST_ASSERT (jerry_value_is_error (from_object)); + jerry_release_value (from_object); + + prop_desc.flags = JERRY_PROP_IS_ENUMERABLE; + from_object = jerry_from_property_descriptor (&prop_desc); + TEST_ASSERT (jerry_value_is_error (from_object)); + jerry_release_value (from_object); + + prop_desc.flags = JERRY_PROP_IS_WRITABLE; + from_object = jerry_from_property_descriptor (&prop_desc); + TEST_ASSERT (jerry_value_is_error (from_object)); + jerry_release_value (from_object); + jerry_cleanup (); return 0; } /* main */