From c7dcce4fc75712979937933e623c5c4dd8f99f2d Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Wed, 13 Apr 2016 23:25:16 -0700 Subject: [PATCH] Refactor object property chain to use property pairs. The patch itself seems a step back, but the primary aim is opening future optimization opportunities. The list of changes follows: - Property is changed to be an abstract type, which has type, flags, and a value. It does not have a name anymore and property pointers cannot be compressed. - Full (32 bit) ecma values can be property values. This allows using non-compressed pointers for ecma values in the future. - The property chain is not restricted to the same item anymore, it can contain hash maps, arrays in the future. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-alloc.c | 29 +- jerry-core/ecma/base/ecma-alloc.h | 24 +- jerry-core/ecma/base/ecma-gc.c | 302 ++++++---- jerry-core/ecma/base/ecma-globals.h | 201 +++++-- .../base/ecma-helpers-external-pointers.c | 20 +- jerry-core/ecma/base/ecma-helpers.c | 530 ++++++++++-------- jerry-core/ecma/base/ecma-helpers.h | 9 +- jerry-core/ecma/base/ecma-lcache.c | 63 +-- .../ecma-builtin-boolean-prototype.c | 5 +- .../ecma-builtin-date-prototype.c | 24 +- .../ecma/builtin-objects/ecma-builtin-date.c | 4 +- .../ecma-builtin-function-prototype.c | 10 +- .../ecma-builtin-helpers-date.c | 4 +- ...a-builtin-internal-routines-template.inc.h | 8 +- .../ecma/builtin-objects/ecma-builtin-json.c | 2 +- .../ecma-builtin-number-prototype.c | 5 +- .../builtin-objects/ecma-builtin-object.c | 9 +- .../ecma-builtin-regexp-prototype.c | 10 +- .../ecma-builtin-string-prototype.c | 5 +- .../ecma/builtin-objects/ecma-builtins.c | 26 +- .../ecma/operations/ecma-array-object.c | 2 +- .../ecma/operations/ecma-boolean-object.c | 4 +- jerry-core/ecma/operations/ecma-exceptions.c | 2 +- .../ecma/operations/ecma-function-object.c | 38 +- .../ecma/operations/ecma-get-put-value.c | 10 +- jerry-core/ecma/operations/ecma-lex-env.c | 2 +- .../ecma/operations/ecma-number-object.c | 4 +- .../ecma/operations/ecma-objects-arguments.c | 18 +- .../ecma/operations/ecma-objects-general.c | 27 +- jerry-core/ecma/operations/ecma-objects.c | 105 ++-- .../ecma/operations/ecma-regexp-object.c | 20 +- .../ecma/operations/ecma-string-object.c | 6 +- jerry-core/vm/opcodes.c | 2 +- jerry-core/vm/vm.c | 2 +- 34 files changed, 883 insertions(+), 649 deletions(-) diff --git a/jerry-core/ecma/base/ecma-alloc.c b/jerry-core/ecma/base/ecma-alloc.c index 638d505aa..14277f5da 100644 --- a/jerry-core/ecma/base/ecma-alloc.c +++ b/jerry-core/ecma/base/ecma-alloc.c @@ -21,8 +21,12 @@ #include "jrt.h" #include "mem-poolman.h" -JERRY_STATIC_ASSERT (sizeof (ecma_property_t) <= sizeof (uint64_t), - size_of_ecma_property_t_must_be_less_than_or_equal_to_8_bytes); +JERRY_STATIC_ASSERT (sizeof (ecma_property_value_t) == sizeof (ecma_value_t), + size_of_ecma_property_value_t_must_be_equal_to_size_of_ecma_value_t); +JERRY_STATIC_ASSERT (((sizeof (ecma_property_value_t) - 1) & sizeof (ecma_property_value_t)) == 0, + size_of_ecma_property_value_t_must_be_power_of_2); +JERRY_STATIC_ASSERT (sizeof (ecma_property_pair_t) == sizeof (uint64_t) * 2, + size_of_ecma_property_pair_t_must_be_equal_to_16_bytes); JERRY_STATIC_ASSERT (sizeof (ecma_object_t) <= sizeof (uint64_t), size_of_ecma_object_t_must_be_less_than_or_equal_to_8_bytes); @@ -85,7 +89,6 @@ JERRY_STATIC_ASSERT (sizeof (ecma_getter_setter_pointers_t) <= sizeof (uint64_t) DEALLOC (ecma_type) DECLARE_ROUTINES_FOR (object) -DECLARE_ROUTINES_FOR (property) DECLARE_ROUTINES_FOR (number) DECLARE_ROUTINES_FOR (collection_header) DECLARE_ROUTINES_FOR (collection_chunk) @@ -93,6 +96,26 @@ DECLARE_ROUTINES_FOR (string) DECLARE_ROUTINES_FOR (getter_setter_pointers) DECLARE_ROUTINES_FOR (external_pointer) +/** + * Allocate memory for ecma-property pair + * + * @return pointer to allocated memory + */ +ecma_property_pair_t * +ecma_alloc_property_pair (void) +{ + return mem_heap_alloc_block (sizeof (ecma_property_pair_t)); +} /* ecma_alloc_property_pair */ + +/** + * Dealloc memory from an ecma-property + */ +extern void +ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */ +{ + mem_heap_free_block (property_pair_p, sizeof (ecma_property_pair_t)); +} /* ecma_dealloc_property_pair */ + /** * @} * @} diff --git a/jerry-core/ecma/base/ecma-alloc.h b/jerry-core/ecma/base/ecma-alloc.h index cf7bc5e1a..a7493fb09 100644 --- a/jerry-core/ecma/base/ecma-alloc.h +++ b/jerry-core/ecma/base/ecma-alloc.h @@ -37,18 +37,6 @@ extern ecma_object_t *ecma_alloc_object (void); */ extern void ecma_dealloc_object (ecma_object_t *); -/** - * Allocate memory for ecma-property - * - * @return pointer to allocated memory - */ -extern ecma_property_t *ecma_alloc_property (void); - -/** - * Dealloc memory from an ecma-property - */ -extern void ecma_dealloc_property (ecma_property_t *); - /** * Allocate memory for ecma-number * @@ -121,6 +109,18 @@ extern ecma_external_pointer_t *ecma_alloc_external_pointer (void); */ extern void ecma_dealloc_external_pointer (ecma_external_pointer_t *); +/** + * Allocate memory for ecma-property pair + * + * @return pointer to allocated memory + */ +extern ecma_property_pair_t *ecma_alloc_property_pair (void); + +/** + * Dealloc memory from an ecma-property pair + */ +extern void ecma_dealloc_property_pair (ecma_property_pair_t *); + /** * @} * @} diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index a73a78a4b..d8a93c898 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -199,6 +199,139 @@ ecma_gc_init (void) ecma_gc_new_objects_since_last_gc = 0; } /* ecma_gc_init */ +/** + * Mark referenced object from property + */ +static void +ecma_gc_mark_property (ecma_property_t *property_p) /**< property */ +{ + switch (ECMA_PROPERTY_GET_TYPE (property_p)) + { + case ECMA_PROPERTY_TYPE_NAMEDDATA: + { + ecma_value_t value = ecma_get_named_data_property_value (property_p); + + if (ecma_is_value_object (value)) + { + ecma_object_t *value_obj_p = ecma_get_object_from_value (value); + + ecma_gc_set_object_visited (value_obj_p, true); + } + break; + } + case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: + { + 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) + { + ecma_gc_set_object_visited (getter_obj_p, true); + } + + if (setter_obj_p != NULL) + { + ecma_gc_set_object_visited (setter_obj_p, true); + } + break; + } + case ECMA_PROPERTY_TYPE_INTERNAL: + { + uint32_t property_value = ECMA_PROPERTY_VALUE_PTR (property_p)->value; + + switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p)) + { + case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* a collection of ecma values */ + case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* a collection of ecma values */ + { + JERRY_UNIMPLEMENTED ("Indexed array storage is not implemented yet."); + } + + case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t + * (see above in the routine) */ + case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t + * (see above in the routine) */ + case ECMA_INTERNAL_PROPERTY__COUNT: /* not a real internal property type, + * but number of the real internal property types */ + { + JERRY_UNREACHABLE (); + } + + case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */ + case ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE: /* compressed pointer to a ecma_number_t */ + case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */ + case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ + case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */ + case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */ + case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */ + case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an object's native free callback */ + case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ + case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC: /* an integer */ + case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */ + case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */ + case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */ + case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: + { + break; + } + + case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS: /* an ecma value */ + { + if (ecma_is_value_object (property_value)) + { + ecma_object_t *obj_p = ecma_get_object_from_value (property_value); + + ecma_gc_set_object_visited (obj_p, true); + } + + break; + } + + case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS: /* a collection of ecma values */ + { + ecma_collection_header_t *bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t, + property_value); + + ecma_collection_iterator_t bound_args_iterator; + ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p); + + for (ecma_length_t i = 0; i < bound_arg_list_p->unit_number; i++) + { + bool is_moved = ecma_collection_iterator_next (&bound_args_iterator); + JERRY_ASSERT (is_moved); + + if (ecma_is_value_object (*bound_args_iterator.current_value_p)) + { + ecma_object_t *obj_p = ecma_get_object_from_value (*bound_args_iterator.current_value_p); + + ecma_gc_set_object_visited (obj_p, true); + } + } + + break; + } + + case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: /* an object */ + case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ + case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */ + { + ecma_object_t *obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, property_value); + + ecma_gc_set_object_visited (obj_p, true); + + break; + } + } + break; + } + default: + { + JERRY_UNREACHABLE (); + break; + } + } +} /* ecma_gc_mark_property */ + /** * Mark objects as visited starting from specified object as root */ @@ -237,130 +370,24 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ if (traverse_properties) { - for (ecma_property_t *property_p = ecma_get_property_list (object_p), *next_property_p; - property_p != NULL; - property_p = next_property_p) + ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); + + while (prop_iter_p != NULL) { - next_property_p = ECMA_GET_POINTER (ecma_property_t, - property_p->next_property_p); + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); - if (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + if (prop_iter_p->types[0].type_and_flags != ECMA_PROPERTY_TYPE_DELETED) { - ecma_value_t value = ecma_get_named_data_property_value (property_p); - - if (ecma_is_value_object (value)) - { - ecma_object_t *value_obj_p = ecma_get_object_from_value (value); - - ecma_gc_set_object_visited (value_obj_p, true); - } + ecma_gc_mark_property (prop_iter_p->types + 0); } - else if (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR) + + if (prop_iter_p->types[1].type_and_flags != ECMA_PROPERTY_TYPE_DELETED) { - 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) - { - ecma_gc_set_object_visited (getter_obj_p, true); - } - - if (setter_obj_p != NULL) - { - ecma_gc_set_object_visited (setter_obj_p, true); - } + ecma_gc_mark_property (prop_iter_p->types + 1); } - else - { - JERRY_ASSERT (property_p->flags & ECMA_PROPERTY_FLAG_INTERNAL); - ecma_internal_property_id_t property_id = (ecma_internal_property_id_t) property_p->h.internal_property_type; - uint32_t property_value = property_p->v.internal_property.value; - - switch (property_id) - { - case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* a collection of ecma values */ - case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* a collection of ecma values */ - { - JERRY_UNIMPLEMENTED ("Indexed array storage is not implemented yet."); - } - - case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t - (see above in the routine) */ - case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t - (see above in the routine) */ - case ECMA_INTERNAL_PROPERTY__COUNT: /* not a real internal property type, - * but number of the real internal property types */ - { - JERRY_UNREACHABLE (); - } - - case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */ - case ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE: /* compressed pointer to a ecma_number_t */ - case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */ - case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ - case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */ - case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */ - case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */ - case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an object's native free callback */ - case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ - case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC: /* an integer */ - case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */ - case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */ - case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */ - case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: - { - break; - } - - case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS: /* an ecma value */ - { - if (ecma_is_value_object (property_value)) - { - ecma_object_t *obj_p = ecma_get_object_from_value (property_value); - - ecma_gc_set_object_visited (obj_p, true); - } - - break; - } - - case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS: /* a collection of ecma values */ - { - ecma_collection_header_t *bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t, - property_value); - - ecma_collection_iterator_t bound_args_iterator; - ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p); - - for (ecma_length_t i = 0; i < bound_arg_list_p->unit_number; i++) - { - bool is_moved = ecma_collection_iterator_next (&bound_args_iterator); - JERRY_ASSERT (is_moved); - - if (ecma_is_value_object (*bound_args_iterator.current_value_p)) - { - ecma_object_t *obj_p = ecma_get_object_from_value (*bound_args_iterator.current_value_p); - - ecma_gc_set_object_visited (obj_p, true); - } - } - - break; - } - - case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: /* an object */ - case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ - case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */ - { - ecma_object_t *obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, property_value); - - ecma_gc_set_object_visited (obj_p, true); - - break; - } - } - } + prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, + prop_iter_p->next_property_cp); } } } /* ecma_gc_mark */ @@ -399,14 +426,41 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */ if (!ecma_is_lexical_environment (object_p) || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { - for (ecma_property_t *property = ecma_get_property_list (object_p), *next_property_p; - property != NULL; - property = next_property_p) - { - next_property_p = ECMA_GET_POINTER (ecma_property_t, - property->next_property_p); + ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); - ecma_free_property (object_p, property); + while (prop_iter_p != NULL) + { + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + + /* Both cannot be deleted. */ + JERRY_ASSERT (prop_iter_p->types[0].type_and_flags != ECMA_PROPERTY_TYPE_DELETED + || prop_iter_p->types[1].type_and_flags != ECMA_PROPERTY_TYPE_DELETED); + + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; + + for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) + { + if (prop_iter_p->types[i].type_and_flags != ECMA_PROPERTY_TYPE_DELETED) + { + ecma_string_t *name_p = ECMA_GET_POINTER (ecma_string_t, prop_pair_p->names_cp[i]); + + ecma_free_property (object_p, name_p, prop_iter_p->types + i); + + if (name_p != NULL) + { + ecma_deref_ecma_string (name_p); + } + } + } + + /* Both must be deleted. */ + JERRY_ASSERT (prop_iter_p->types[0].type_and_flags == ECMA_PROPERTY_TYPE_DELETED + && prop_iter_p->types[1].type_and_flags == ECMA_PROPERTY_TYPE_DELETED); + + prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, + prop_iter_p->next_property_cp); + + ecma_dealloc_property_pair (prop_pair_p); } } diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 38ce23752..d32c94db9 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -203,19 +203,101 @@ typedef enum } ecma_property_configurable_value_t; /** - * Property's flag list. + * Property list: + * The property list of an object is a chain list of various items. + * The type of each item is stored in the first byte of the item. + * + * The most common item is the property pair, which contains two + * ecmascript properties. It is also important, that after the + * first property pair, only property pair items are allowed. + * + * Example for other items is property name hash map, or array of items. + */ + +/** + * Property type list. */ typedef enum { - ECMA_PROPERTY_FLAG_NAMEDDATA = 1u << 0, /**< property is named data */ - ECMA_PROPERTY_FLAG_NAMEDACCESSOR = 1u << 1, /**< property is named accessor */ - ECMA_PROPERTY_FLAG_INTERNAL = 1u << 2, /**< property is internal property */ - ECMA_PROPERTY_FLAG_CONFIGURABLE = 1u << 3, /**< property is configurable */ - ECMA_PROPERTY_FLAG_ENUMERABLE = 1u << 4, /**< property is enumerable */ - ECMA_PROPERTY_FLAG_WRITABLE = 1u << 5, /**< property is writable */ - ECMA_PROPERTY_FLAG_LCACHED = 1u << 6, /**< property is lcached */ + ECMA_PROPERTY_TYPE_DELETED, /**< deleted property */ + ECMA_PROPERTY_TYPE_INTERNAL, /**< internal property */ + ECMA_PROPERTY_TYPE_NAMEDDATA, /**< property is named data */ + ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< property is named accessor */ + + ECMA_PROPERTY_TYPE_PROPERTY_PAIR__MAX = ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< highest value for + * property pair types. */ + ECMA_PROPERTY_TYPE__MAX = ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< highest value for property types. */ +} ecma_property_types_t; + +/** + * Property type mask. + */ +#define ECMA_PROPERTY_TYPE_MASK 0x7 + +/** + * Property flags base shift. + */ +#define ECMA_PROPERTY_FLAG_SHIFT 3 + +/** + * Property flag list (for ECMA_PROPERTY_TYPE_NAMEDDATA + * and ECMA_PROPERTY_TYPE_NAMEDACCESSOR). + */ +typedef enum +{ + ECMA_PROPERTY_FLAG_CONFIGURABLE = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 0), /**< property is configurable */ + ECMA_PROPERTY_FLAG_ENUMERABLE = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 1), /**< property is enumerable */ + ECMA_PROPERTY_FLAG_WRITABLE = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 2), /**< property is writable */ + ECMA_PROPERTY_FLAG_LCACHED = 1u << (ECMA_PROPERTY_FLAG_SHIFT + 3), /**< property is lcached */ } ecma_property_flags_t; +/** + * Abstract property representation. + * + * A property is a type_and_flags byte and an ecma_value_t value pair. + * This pair is represented by a single pointer in JerryScript. Although + * a packed struct would only consume sizeof(ecma_value_t)+1 memory + * bytes, accessing such structure is inefficient from the CPU viewpoint + * because the value is not naturally aligned. To improve performance, + * multiple type bytes and values are packed together. The maximum + * number of packed items is sizeof(ecma_value_t). The memory layout is + * the following when the maximum number of items is present: + * + * [type 1, type 2, type 3, type 4][value 1][value 2][value 3][value 4] + * + * This way no memory is wasted and values are naturally aligned. + * + * For property pairs, only two values are used: + * + * [type 1, type 2, unused 1, unused 2][value 1][value 2] + * + * The unused two bytes are used to store a compressed pointer for the + * next property pair. + * + * The advantage of this layout is that the value reference can be computed + * from the property address. However, property pointers cannot be compressed + * anymore. + */ +typedef struct +{ + uint8_t type_and_flags; /**< ecma_property_types_t (3 bit) and ecma_property_flags_t */ +} ecma_property_t; + +/** + * Number of items in a property pair. + */ +#define ECMA_PROPERTY_PAIR_ITEM_COUNT 2 + +/** + * Property header for all items in a property list. + */ +typedef struct +{ + ecma_property_t types[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< two property type slot. The first represent + * the type of this property (e.g. property pair) */ + mem_cpointer_t next_property_cp; /**< next cpointer */ +} ecma_property_header_t; + /** * Pair of pointers - to property's getter and setter */ @@ -226,56 +308,59 @@ typedef struct } ecma_getter_setter_pointers_t; /** - * Description of ecma-property + * Property data. */ -typedef struct ecma_property_t +typedef union { - /** Compressed pointer to next property */ - mem_cpointer_t next_property_p; + ecma_value_t value; /**< value of a property */ + ecma_getter_setter_pointers_t getter_setter_pair; /**< getter setter pair */ +} ecma_property_value_t; - /** Property's flags (ecma_property_flags_t) */ - uint8_t flags; +/** + * Property pair. + */ +typedef struct +{ + ecma_property_header_t header; /**< header of the property */ + ecma_property_value_t values[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< property value slots */ + mem_cpointer_t names_cp[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< property name slots */ +} ecma_property_pair_t; - /** Property's header part (depending on Type) */ - union - { - /** Named data property value upper bits */ - uint8_t named_data_property_value_high; - /** Internal property type */ - uint8_t internal_property_type; - } h; +/** + * Get property type. + */ +#define ECMA_PROPERTY_GET_TYPE(property_p) \ + ((ecma_property_types_t) ((property_p)->type_and_flags & ECMA_PROPERTY_TYPE_MASK)) - /** Property's value part (depending on Type) */ - union - { - /** Description of named data property (second part) */ - struct - { - /** Compressed pointer to property's name (pointer to String) */ - mem_cpointer_t name_p; +/** + * Returns true if the property pointer is a property pair. + */ +#define ECMA_PROPERTY_IS_PROPERTY_PAIR(property_header_p) \ + (ECMA_PROPERTY_GET_TYPE ((property_header_p)->types + 0) <= ECMA_PROPERTY_TYPE_PROPERTY_PAIR__MAX) - /** Lower 16 bits of value */ - uint16_t value_low; - } named_data_property; +/** + * Returns the internal property type + */ +#define ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE(property_p) \ + ((ecma_internal_property_id_t) ((property_p)->type_and_flags >> ECMA_PROPERTY_FLAG_SHIFT)) - /** Description of named accessor property (second part) */ - struct - { - /** Compressed pointer to property's name (pointer to String) */ - mem_cpointer_t name_p; +/** + * Computing the data offset of a property. + */ +#define ECMA_PROPERTY_VALUE_OFFSET(property_p) \ + ((((uintptr_t) (property_p)) & (sizeof (ecma_property_value_t) - 1)) + 1) - /** Compressed pointer to pair of pointers - to property's getter and setter */ - mem_cpointer_t getter_setter_pair_cp; - } named_accessor_property; +/** + * Computing the base address of property data list. + */ +#define ECMA_PROPERTY_VALUE_BASE_PTR(property_p) \ + ((ecma_property_value_t *) (((uintptr_t) (property_p)) & ~(sizeof (ecma_property_value_t) - 1))) - /** Description of internal property (second part) */ - struct - { - /** Value (may be a compressed pointer) */ - uint32_t value; - } internal_property; - } v; -} ecma_property_t; +/** + * Pointer to property data. + */ +#define ECMA_PROPERTY_VALUE_PTR(property_p) \ + (ECMA_PROPERTY_VALUE_BASE_PTR (property_p) + ECMA_PROPERTY_VALUE_OFFSET (property_p)) /** * Internal object types @@ -395,12 +480,21 @@ typedef struct /** Is [[Writable]] defined? */ unsigned int is_writable_defined : 1; + /** [[Writable]] */ + unsigned int is_writable : 1; + /** Is [[Enumerable]] defined? */ unsigned int is_enumerable_defined : 1; + /** [[Enumerable]] */ + unsigned int is_enumerable : 1; + /** Is [[Configurable]] defined? */ unsigned int is_configurable_defined : 1; + /** [[Configurable]] */ + unsigned int is_configurable : 1; + /** [[Value]] */ ecma_value_t value; @@ -409,15 +503,6 @@ typedef struct /** [[Set]] */ ecma_object_t *set_p; - - /** [[Writable]] */ - bool is_writable; - - /** [[Enumerable]] */ - bool is_enumerable; - - /** [[Configurable]] */ - bool is_configurable; } ecma_property_descriptor_t; #if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 diff --git a/jerry-core/ecma/base/ecma-helpers-external-pointers.c b/jerry-core/ecma/base/ecma-helpers-external-pointers.c index d3e7deeae..d46b9c00d 100644 --- a/jerry-core/ecma/base/ecma-helpers-external-pointers.c +++ b/jerry-core/ecma/base/ecma-helpers-external-pointers.c @@ -61,12 +61,12 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea is_new = false; } - JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (prop_p->v.internal_property.value), + JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (ECMA_PROPERTY_VALUE_PTR (prop_p)->value), size_of_internal_property_value_must_be_greater_than_or_equal_to_4_bytes); if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t)) { - prop_p->v.internal_property.value = (uint32_t) ptr_value; + ECMA_PROPERTY_VALUE_PTR (prop_p)->value = (uint32_t) ptr_value; } else { @@ -76,12 +76,12 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea { handler_p = ecma_alloc_external_pointer (); - ECMA_SET_NON_NULL_POINTER (prop_p->v.internal_property.value, handler_p); + ECMA_SET_NON_NULL_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->value, handler_p); } else { handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, - prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (prop_p)->value); } *handler_p = ptr_value; @@ -123,12 +123,12 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t)) { - *out_pointer_p = (ecma_external_pointer_t) prop_p->v.internal_property.value; + *out_pointer_p = ECMA_PROPERTY_VALUE_PTR (prop_p)->value; } else { ecma_external_pointer_t *handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, - prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (prop_p)->value); *out_pointer_p = *handler_p; } @@ -147,9 +147,9 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper void ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal property */ { - JERRY_ASSERT (prop_p->h.internal_property_type == ECMA_INTERNAL_PROPERTY_NATIVE_CODE - || prop_p->h.internal_property_type == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE - || prop_p->h.internal_property_type == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); + JERRY_ASSERT (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_NATIVE_CODE + || ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE + || ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t)) { @@ -158,7 +158,7 @@ ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal p else { ecma_external_pointer_t *handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, - prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (prop_p)->value); ecma_dealloc_external_pointer (handler_p); } diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index d80f12214..b005d922b 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -30,6 +30,12 @@ * @{ */ +/** + * The ecma property types must be lower than the container mask. + */ +JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_MASK >= ECMA_PROPERTY_TYPE__MAX, + ecma_property_types_must_be_lower_than_the_container_mask); + /** * The ecma object types must be lower than the container mask. */ @@ -320,14 +326,14 @@ ecma_get_lex_env_outer_reference (const ecma_object_t *object_p) /**< lexical en * See also: * ecma_op_object_get_property_names */ -inline ecma_property_t *__attr_pure___ +inline ecma_property_header_t *__attr_pure___ ecma_get_property_list (const ecma_object_t *object_p) /**< object or lexical environment */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (!ecma_is_lexical_environment (object_p) || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); - return ECMA_GET_POINTER (ecma_property_t, + return ECMA_GET_POINTER (ecma_property_header_t, object_p->property_list_or_bound_object_cp); } /* ecma_get_property_list */ @@ -339,14 +345,13 @@ ecma_get_property_list (const ecma_object_t *object_p) /**< object or lexical en */ static inline void ecma_set_property_list (ecma_object_t *object_p, /**< object or lexical environment */ - ecma_property_t *property_list_p) /**< properties' list */ + ecma_property_header_t *property_list_p) /**< properties' list */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (!ecma_is_lexical_environment (object_p) || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); - ECMA_SET_POINTER (object_p->property_list_or_bound_object_cp, - property_list_p); + ECMA_SET_POINTER (object_p->property_list_or_bound_object_cp, property_list_p); } /* ecma_set_property_list */ /** @@ -378,6 +383,61 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun object_p->property_list_or_bound_object_cp); } /* ecma_get_lex_env_binding_object */ +/** + * Create a property in an object and link it into + * the object's properties' linked-list (at start of the list). + * + * @return pointer to newly created property + */ +static ecma_property_t * +ecma_create_property (ecma_object_t *object_p, /**< the object */ + ecma_string_t *name_p, /**< property name */ + uint8_t type_and_flags) /**< type and flags, see ecma_property_info_t */ +{ + JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); + + if (object_p->property_list_or_bound_object_cp != ECMA_NULL_POINTER) + { + /* If the first entry is free (deleted), we simply use its value. */ + ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + object_p->property_list_or_bound_object_cp); + + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (first_property_p)); + + if (first_property_p->types[0].type_and_flags == ECMA_PROPERTY_TYPE_DELETED) + { + first_property_p->types[0].type_and_flags = type_and_flags; + + ecma_property_pair_t *first_property_pair_p = (ecma_property_pair_t *) first_property_p; + ECMA_SET_POINTER (first_property_pair_p->names_cp[0], name_p); + + ecma_property_t *property_p = first_property_p->types + 0; + + JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p) == first_property_pair_p->values + 0); + + return property_p; + } + } + + /* Otherwise we create a new property pair and use its second value. */ + ecma_property_pair_t *first_property_pair_p = ecma_alloc_property_pair (); + + /* Just copy the previous value (no need to decompress, compress). */ + first_property_pair_p->header.next_property_cp = object_p->property_list_or_bound_object_cp; + first_property_pair_p->header.types[0].type_and_flags = ECMA_PROPERTY_TYPE_DELETED; + first_property_pair_p->header.types[1].type_and_flags = type_and_flags; + first_property_pair_p->names_cp[0] = ECMA_NULL_POINTER; + ECMA_SET_POINTER (first_property_pair_p->names_cp[1], name_p); + + ecma_set_property_list (object_p, &first_property_pair_p->header); + + ecma_property_t *property_p = first_property_pair_p->header.types + 1; + + JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p) == first_property_pair_p->values + 1); + + return property_p; +} /* ecma_create_property */ + /** * Create internal property in an object and link it into * the object's properties' linked-list (at start of the list). @@ -390,20 +450,14 @@ ecma_create_internal_property (ecma_object_t *object_p, /**< the object */ { JERRY_ASSERT (ecma_find_internal_property (object_p, property_id) == NULL); - ecma_property_t *new_property_p = ecma_alloc_property (); + uint8_t id_byte = (uint8_t) (property_id << ECMA_PROPERTY_FLAG_SHIFT); + uint8_t type_and_flags = (uint8_t) (ECMA_PROPERTY_TYPE_INTERNAL | id_byte); - new_property_p->flags = ECMA_PROPERTY_FLAG_INTERNAL; + ecma_property_t *property_p = ecma_create_property (object_p, NULL, type_and_flags); - ecma_property_t *list_head_p = ecma_get_property_list (object_p); - ECMA_SET_POINTER (new_property_p->next_property_p, list_head_p); - ecma_set_property_list (object_p, new_property_p); + ECMA_PROPERTY_VALUE_PTR (property_p)->value = ECMA_NULL_POINTER; - JERRY_ASSERT (property_id < ECMA_INTERNAL_PROPERTY__COUNT); - - new_property_p->h.internal_property_type = (uint8_t) property_id; - new_property_p->v.internal_property.value = ECMA_NULL_POINTER; - - return new_property_p; + return property_p; } /* ecma_create_internal_property */ /** @@ -421,15 +475,26 @@ ecma_find_internal_property (ecma_object_t *object_p, /**< object descriptor */ JERRY_ASSERT (property_id != ECMA_INTERNAL_PROPERTY_PROTOTYPE && property_id != ECMA_INTERNAL_PROPERTY_EXTENSIBLE); - for (ecma_property_t *property_p = ecma_get_property_list (object_p); - property_p != NULL; - property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p)) + ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); + + while (prop_iter_p != NULL) { - if ((property_p->flags & ECMA_PROPERTY_FLAG_INTERNAL) - && property_p->h.internal_property_type == property_id) + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + + if (ECMA_PROPERTY_GET_TYPE (&prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_INTERNAL + && ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_iter_p->types + 0) == property_id) { - return property_p; + return prop_iter_p->types + 0; } + + if (ECMA_PROPERTY_GET_TYPE (&prop_iter_p->types[1]) == ECMA_PROPERTY_TYPE_INTERNAL + && ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_iter_p->types + 1) == property_id) + { + return prop_iter_p->types + 1; + } + + prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, + prop_iter_p->next_property_cp); } return NULL; @@ -461,48 +526,38 @@ ecma_get_internal_property (ecma_object_t *object_p, /**< object descriptor */ * @return pointer to newly created property */ ecma_property_t * -ecma_create_named_data_property (ecma_object_t *obj_p, /**< object */ +ecma_create_named_data_property (ecma_object_t *object_p, /**< object */ ecma_string_t *name_p, /**< property name */ bool is_writable, /**< 'Writable' attribute */ bool is_enumerable, /**< 'Enumerable' attribute */ bool is_configurable) /**< 'Configurable' attribute */ { - JERRY_ASSERT (obj_p != NULL && name_p != NULL); - JERRY_ASSERT (ecma_find_named_property (obj_p, name_p) == NULL); - - ecma_property_t *prop_p = ecma_alloc_property (); - name_p = ecma_copy_or_ref_ecma_string (name_p); - - prop_p->flags = ECMA_PROPERTY_FLAG_NAMEDDATA; - - ECMA_SET_NON_NULL_POINTER (prop_p->v.named_data_property.name_p, name_p); + JERRY_ASSERT (object_p != NULL && name_p != NULL); + JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); + uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDDATA; if (is_configurable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); + type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); } if (is_enumerable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_ENUMERABLE); + type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_ENUMERABLE); } if (is_writable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_WRITABLE); + type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_WRITABLE); } - ecma_set_named_data_property_value (prop_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)); + name_p = ecma_copy_or_ref_ecma_string (name_p); - /* - * See also: - * ecma_op_object_get_property_names - */ - ecma_property_t *list_head_p = ecma_get_property_list (obj_p); - ECMA_SET_POINTER (prop_p->next_property_p, list_head_p); - ecma_set_property_list (obj_p, prop_p); + ecma_property_t *property_p = ecma_create_property (object_p, name_p, type_and_flags); - ecma_lcache_invalidate (obj_p, name_p, NULL); + ecma_set_named_data_property_value (property_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)); - return prop_p; + ecma_lcache_invalidate (object_p, name_p, NULL); + + return property_p; } /* ecma_create_named_data_property */ /** @@ -511,52 +566,39 @@ ecma_create_named_data_property (ecma_object_t *obj_p, /**< object */ * @return pointer to newly created property */ ecma_property_t * -ecma_create_named_accessor_property (ecma_object_t *obj_p, /**< object */ +ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */ ecma_string_t *name_p, /**< property name */ ecma_object_t *get_p, /**< getter */ ecma_object_t *set_p, /**< setter */ bool is_enumerable, /**< 'enumerable' attribute */ bool is_configurable) /**< 'configurable' attribute */ { - JERRY_ASSERT (obj_p != NULL && name_p != NULL); - JERRY_ASSERT (ecma_find_named_property (obj_p, name_p) == NULL); - - ecma_property_t *prop_p = ecma_alloc_property (); - ecma_getter_setter_pointers_t *getter_setter_pointers_p = ecma_alloc_getter_setter_pointers (); - name_p = ecma_copy_or_ref_ecma_string (name_p); - - prop_p->flags = ECMA_PROPERTY_FLAG_NAMEDACCESSOR; - - ECMA_SET_NON_NULL_POINTER (prop_p->v.named_accessor_property.name_p, name_p); + JERRY_ASSERT (object_p != NULL && name_p != NULL); + JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); + uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDACCESSOR; if (is_configurable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); + type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); } if (is_enumerable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_ENUMERABLE); + type_and_flags = (uint8_t) (type_and_flags | ECMA_PROPERTY_FLAG_ENUMERABLE); } - ECMA_SET_NON_NULL_POINTER (prop_p->v.named_accessor_property.getter_setter_pair_cp, getter_setter_pointers_p); + name_p = ecma_copy_or_ref_ecma_string (name_p); - /* - * See also: - * ecma_op_object_get_property_names - */ - ecma_property_t *list_head_p = ecma_get_property_list (obj_p); - ECMA_SET_POINTER (prop_p->next_property_p, list_head_p); - ecma_set_property_list (obj_p, prop_p); + ecma_property_t *property_p = ecma_create_property (object_p, name_p, type_and_flags); /* * 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); + ecma_set_named_accessor_property_getter (object_p, property_p, get_p); + ecma_set_named_accessor_property_setter (object_p, property_p, set_p); - ecma_lcache_invalidate (obj_p, name_p, NULL); + ecma_lcache_invalidate (object_p, name_p, NULL); - return prop_p; + return property_p; } /* ecma_create_named_accessor_property */ /** @@ -579,33 +621,44 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in return property_p; } - for (property_p = ecma_get_property_list (obj_p); - property_p != NULL; - property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p)) + property_p = NULL; + + ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p); + + while (prop_iter_p != NULL) { - ecma_string_t *property_name_p; + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); - if (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; + + JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); + + if (prop_pair_p->names_cp[0] != ECMA_NULL_POINTER) { - property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, - property_p->v.named_data_property.name_p); - } - else if (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR) - { - property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, - property_p->v.named_accessor_property.name_p); - } - else - { - continue; + ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, + prop_pair_p->names_cp[0]); + + if (ecma_compare_ecma_strings (name_p, property_name_p)) + { + property_p = prop_iter_p->types + 0; + break; + } } - JERRY_ASSERT (property_name_p != NULL); - - if (ecma_compare_ecma_strings (name_p, property_name_p)) + if (prop_pair_p->names_cp[1] != ECMA_NULL_POINTER) { - break; + ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, + prop_pair_p->names_cp[1]); + + if (ecma_compare_ecma_strings (name_p, property_name_p)) + { + property_p = prop_iter_p->types + 1; + break; + } } + + prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, + prop_iter_p->next_property_cp); } ecma_lcache_insert (obj_p, name_p, property_p); @@ -654,7 +707,7 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p); - JERRY_ASSERT (property_p != NULL && (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)); + JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); return property_p; } /* ecma_get_named_data_property */ @@ -667,53 +720,23 @@ ecma_free_named_data_property (ecma_object_t *object_p, /**< object the property ecma_property_t *property_p) /**< the property */ { JERRY_ASSERT (object_p != NULL); - JERRY_ASSERT (property_p != NULL && (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)); - - ecma_lcache_invalidate (object_p, NULL, property_p); - - ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, - property_p->v.named_data_property.name_p)); + JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_value_t v = ecma_get_named_data_property_value (property_p); ecma_free_value_if_not_object (v); - - ecma_dealloc_property (property_p); } /* ecma_free_named_data_property */ -/** - * Free the named accessor property and values it references. - */ -static void -ecma_free_named_accessor_property (ecma_object_t *object_p, /**< object the property belongs to */ - ecma_property_t *property_p) /**< the property */ -{ - JERRY_ASSERT (object_p != NULL); - JERRY_ASSERT (property_p != NULL && (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); - - ecma_lcache_invalidate (object_p, NULL, property_p); - - ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, - property_p->v.named_accessor_property.name_p)); - - ecma_getter_setter_pointers_t *getter_setter_pointers_p; - getter_setter_pointers_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, - property_p->v.named_accessor_property.getter_setter_pair_cp); - ecma_dealloc_getter_setter_pointers (getter_setter_pointers_p); - ecma_dealloc_property (property_p); -} /* ecma_free_named_accessor_property */ - /** * Free the internal property and values it references. */ static void ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ { - JERRY_ASSERT (property_p != NULL && (property_p->flags & ECMA_PROPERTY_FLAG_INTERNAL)); + JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_INTERNAL); - ecma_internal_property_id_t property_id = (ecma_internal_property_id_t) property_p->h.internal_property_type; - uint32_t property_value = property_p->v.internal_property.value; + uint32_t property_value = ECMA_PROPERTY_VALUE_PTR (property_p)->value; - switch (property_id) + switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p)) { case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* a collection */ case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* a collection */ @@ -809,31 +832,45 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ break; } } - - ecma_dealloc_property (property_p); } /* ecma_free_internal_property */ /** - * Free the property and values it references. + * Free property values and change their type to deleted. */ void ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */ - ecma_property_t *prop_p) /**< property */ + ecma_string_t *name_p, /**< name of the property or NULL */ + ecma_property_t *property_p) /**< property */ { - JERRY_ASSERT (object_p != NULL && prop_p != NULL); + JERRY_ASSERT (object_p != NULL && property_p != NULL); - if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + switch (ECMA_PROPERTY_GET_TYPE (property_p)) { - ecma_free_named_data_property (object_p, prop_p); - } - else if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR) - { - ecma_free_named_accessor_property (object_p, prop_p); - } - else - { - ecma_free_internal_property (prop_p); + case ECMA_PROPERTY_TYPE_NAMEDDATA: + { + ecma_free_named_data_property (object_p, property_p); + ecma_lcache_invalidate (object_p, name_p, property_p); + break; + } + case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: + { + ecma_lcache_invalidate (object_p, name_p, property_p); + break; + } + case ECMA_PROPERTY_TYPE_INTERNAL: + { + JERRY_ASSERT (name_p == NULL); + ecma_free_internal_property (property_p); + break; + } + default: + { + JERRY_UNREACHABLE (); + break; + } } + + property_p->type_and_flags = ECMA_PROPERTY_TYPE_DELETED; } /* ecma_free_property */ /** @@ -842,34 +879,62 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to * Warning: specified property must be owned by specified object. */ void -ecma_delete_property (ecma_object_t *obj_p, /**< object */ +ecma_delete_property (ecma_object_t *object_p, /**< object */ ecma_property_t *prop_p) /**< property */ { - for (ecma_property_t *cur_prop_p = ecma_get_property_list (obj_p), *prev_prop_p = NULL, *next_prop_p; - cur_prop_p != NULL; - prev_prop_p = cur_prop_p, cur_prop_p = next_prop_p) + ecma_property_header_t *cur_prop_p = ecma_get_property_list (object_p); + ecma_property_header_t *prev_prop_p = NULL; + + while (true) { - next_prop_p = ECMA_GET_POINTER (ecma_property_t, - cur_prop_p->next_property_p); + JERRY_ASSERT (cur_prop_p != NULL); + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (cur_prop_p)); - if (cur_prop_p == prop_p) + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) cur_prop_p; + + for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { - ecma_free_property (obj_p, prop_p); - - if (prev_prop_p == NULL) + if ((cur_prop_p->types + i) == prop_p) { - ecma_set_property_list (obj_p, next_prop_p); - } - else - { - ECMA_SET_POINTER (prev_prop_p->next_property_p, next_prop_p); - } + ecma_string_t *name_p = ECMA_GET_POINTER (ecma_string_t, prop_pair_p->names_cp[i]); - return; + ecma_free_property (object_p, name_p, cur_prop_p->types + i); + + prop_pair_p->names_cp[i] = ECMA_NULL_POINTER; + + if (name_p != NULL) + { + ecma_deref_ecma_string (name_p); + } + + JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); + + if (cur_prop_p->types[1 - i].type_and_flags != ECMA_PROPERTY_TYPE_DELETED) + { + /* The other property is still valid. */ + return; + } + + JERRY_ASSERT (cur_prop_p->types[i].type_and_flags == ECMA_PROPERTY_TYPE_DELETED); + + if (prev_prop_p == NULL) + { + object_p->property_list_or_bound_object_cp = cur_prop_p->next_property_cp; + } + else + { + prev_prop_p->next_property_cp = cur_prop_p->next_property_cp; + } + + ecma_dealloc_property_pair ((ecma_property_pair_t *) cur_prop_p); + return; + } } - } - JERRY_UNREACHABLE (); + prev_prop_p = cur_prop_p; + cur_prop_p = ECMA_GET_POINTER (ecma_property_header_t, + cur_prop_p->next_property_cp); + } } /* ecma_delete_property */ /** @@ -880,27 +945,34 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec 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)) + ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); + + while (prop_iter_p != NULL) { - if (prop_iter_p == prop_p) + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; + + for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { - break; + if ((prop_pair_p->header.types + i) == prop_p) + { + return; + } } + + prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, + prop_iter_p->next_property_cp); } - JERRY_ASSERT (prop_iter_p != NULL); + JERRY_UNREACHABLE (); + #else /* JERRY_NDEBUG */ (void) object_p; (void) prop_p; #endif /* JERRY_NDEBUG */ } /* ecma_assert_object_contains_the_property */ -JERRY_STATIC_ASSERT (ECMA_VALUE_SIZE <= 24, - maximum_ECMA_VALUE_SIZE_must_be_less_than_or_equal_to_24); - /** * Get value field of named data property * @@ -909,10 +981,9 @@ JERRY_STATIC_ASSERT (ECMA_VALUE_SIZE <= 24, inline ecma_value_t __attr_always_inline___ ecma_get_named_data_property_value (const ecma_property_t *prop_p) /**< property */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); - ecma_value_t upper_bits = prop_p->h.named_data_property_value_high; - return (upper_bits << 16) | (prop_p->v.named_data_property.value_low); + return ECMA_PROPERTY_VALUE_PTR (prop_p)->value; } /* ecma_get_named_data_property_value */ /** @@ -922,12 +993,36 @@ inline void __attr_always_inline___ ecma_set_named_data_property_value (ecma_property_t *prop_p, /**< property */ ecma_value_t value) /**< value to set */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); - prop_p->h.named_data_property_value_high = (uint8_t) (value >> 16); - prop_p->v.named_data_property.value_low = (uint16_t) value; + ECMA_PROPERTY_VALUE_PTR (prop_p)->value = value; } /* ecma_set_named_data_property_value */ +/** + * Get value field of an internal property + * + * @return ecma value + */ +inline ecma_value_t __attr_always_inline___ +ecma_get_internal_property_value (const ecma_property_t *prop_p) /**< property */ +{ + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_INTERNAL); + + return ECMA_PROPERTY_VALUE_PTR (prop_p)->value; +} /* ecma_get_internal_property_value */ + +/** + * Set value field of named data property + */ +inline void __attr_always_inline___ +ecma_set_internal_property_value (ecma_property_t *prop_p, /**< property */ + ecma_value_t value) /**< value to set */ +{ + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_INTERNAL); + + ECMA_PROPERTY_VALUE_PTR (prop_p)->value = value; +} /* ecma_set_internal_property_value */ + /** * Assign value to named data property * @@ -939,7 +1034,7 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */ ecma_property_t *prop_p, /**< property */ ecma_value_t value) /**< value to assign */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_assert_object_contains_the_property (obj_p, prop_p); if (ecma_is_value_number (value) @@ -967,13 +1062,9 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */ ecma_object_t * ecma_get_named_accessor_property_getter (const ecma_property_t *prop_p) /**< named accessor property */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - ecma_getter_setter_pointers_t *getter_setter_pointers_p; - getter_setter_pointers_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_p->v.named_accessor_property.getter_setter_pair_cp); - - return ECMA_GET_POINTER (ecma_object_t, getter_setter_pointers_p->getter_p); + return ECMA_GET_POINTER (ecma_object_t, ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.getter_p); } /* ecma_get_named_accessor_property_getter */ /** @@ -984,13 +1075,9 @@ ecma_get_named_accessor_property_getter (const ecma_property_t *prop_p) /**< nam ecma_object_t * ecma_get_named_accessor_property_setter (const ecma_property_t *prop_p) /**< named accessor property */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - ecma_getter_setter_pointers_t *getter_setter_pointers_p; - getter_setter_pointers_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_p->v.named_accessor_property.getter_setter_pair_cp); - - return ECMA_GET_POINTER (ecma_object_t, getter_setter_pointers_p->setter_p); + return ECMA_GET_POINTER (ecma_object_t, ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.setter_p); } /* ecma_get_named_accessor_property_setter */ /** @@ -1001,14 +1088,10 @@ ecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the prope ecma_property_t *prop_p, /**< named accessor property */ ecma_object_t *getter_p) /**< getter object */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); ecma_assert_object_contains_the_property (object_p, prop_p); - ecma_getter_setter_pointers_t *getter_setter_pointers_p; - getter_setter_pointers_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_p->v.named_accessor_property.getter_setter_pair_cp); - - ECMA_SET_POINTER (getter_setter_pointers_p->getter_p, getter_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.getter_p, getter_p); } /* ecma_set_named_accessor_property_getter */ /** @@ -1019,14 +1102,10 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope ecma_property_t *prop_p, /**< named accessor property */ ecma_object_t *setter_p) /**< setter object */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); ecma_assert_object_contains_the_property (object_p, prop_p); - ecma_getter_setter_pointers_t *getter_setter_pointers_p; - getter_setter_pointers_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_p->v.named_accessor_property.getter_setter_pair_cp); - - ECMA_SET_POINTER (getter_setter_pointers_p->setter_p, setter_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.setter_p, setter_p); } /* ecma_set_named_accessor_property_setter */ /** @@ -1038,9 +1117,9 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope inline bool __attr_always_inline___ ecma_is_property_writable (ecma_property_t *prop_p) /**< property */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); - return (prop_p->flags & ECMA_PROPERTY_FLAG_WRITABLE) != 0; + return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_WRITABLE) != 0; } /* ecma_is_property_writable */ /** @@ -1051,15 +1130,15 @@ ecma_set_property_writable_attr (ecma_property_t *prop_p, /**< property */ bool is_writable) /**< should the property * be writable? */ { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); if (is_writable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_WRITABLE); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_WRITABLE); } else { - prop_p->flags = (uint8_t) (prop_p->flags & ~ECMA_PROPERTY_FLAG_WRITABLE); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_WRITABLE); } } /* ecma_set_property_writable_attr */ @@ -1072,9 +1151,10 @@ ecma_set_property_writable_attr (ecma_property_t *prop_p, /**< property */ inline bool __attr_always_inline___ ecma_is_property_enumerable (ecma_property_t *prop_p) /**< property */ { - JERRY_ASSERT (prop_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - return (prop_p->flags & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0; + return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0; } /* ecma_is_property_enumerable */ /** @@ -1085,15 +1165,16 @@ ecma_set_property_enumerable_attr (ecma_property_t *prop_p, /**< property */ bool is_enumerable) /**< should the property * be enumerable? */ { - JERRY_ASSERT (prop_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); if (is_enumerable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_ENUMERABLE); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_ENUMERABLE); } else { - prop_p->flags = (uint8_t) (prop_p->flags & ~ECMA_PROPERTY_FLAG_ENUMERABLE); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_ENUMERABLE); } } /* ecma_set_property_enumerable_attr */ @@ -1106,9 +1187,10 @@ ecma_set_property_enumerable_attr (ecma_property_t *prop_p, /**< property */ inline bool __attr_always_inline___ ecma_is_property_configurable (ecma_property_t *prop_p) /**< property */ { - JERRY_ASSERT (prop_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - return (prop_p->flags & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0; + return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0; } /* ecma_is_property_configurable */ /** @@ -1119,15 +1201,16 @@ ecma_set_property_configurable_attr (ecma_property_t *prop_p, /**< property */ bool is_configurable) /**< should the property * be configurable? */ { - JERRY_ASSERT (prop_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); if (is_configurable) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_CONFIGURABLE); } else { - prop_p->flags = (uint8_t) (prop_p->flags & ~ECMA_PROPERTY_FLAG_CONFIGURABLE); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_CONFIGURABLE); } } /* ecma_set_property_configurable_attr */ @@ -1139,9 +1222,10 @@ ecma_set_property_configurable_attr (ecma_property_t *prop_p, /**< property */ inline bool __attr_always_inline___ ecma_is_property_lcached (ecma_property_t *prop_p) /**< property */ { - JERRY_ASSERT (prop_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - return (prop_p->flags & ECMA_PROPERTY_FLAG_LCACHED) != 0; + return (prop_p->type_and_flags & ECMA_PROPERTY_FLAG_LCACHED) != 0; } /* ecma_is_property_lcached */ /** @@ -1151,15 +1235,16 @@ void ecma_set_property_lcached (ecma_property_t *prop_p, /**< property */ bool is_lcached) /**< contained (true) or not (false) */ { - JERRY_ASSERT (prop_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); if (is_lcached) { - prop_p->flags = (uint8_t) (prop_p->flags | ECMA_PROPERTY_FLAG_LCACHED); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags | ECMA_PROPERTY_FLAG_LCACHED); } else { - prop_p->flags = (uint8_t) (prop_p->flags & ~ECMA_PROPERTY_FLAG_LCACHED); + prop_p->type_and_flags = (uint8_t) (prop_p->type_and_flags & ~ECMA_PROPERTY_FLAG_LCACHED); } } /* ecma_set_property_lcached */ @@ -1235,15 +1320,16 @@ ecma_get_property_descriptor_from_property (ecma_property_t *prop_p) /**< proper prop_desc.is_configurable = ecma_is_property_configurable (prop_p); prop_desc.is_configurable_defined = true; - if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) { prop_desc.value = ecma_copy_value (ecma_get_named_data_property_value (prop_p)); prop_desc.is_value_defined = true; prop_desc.is_writable = ecma_is_property_writable (prop_p); prop_desc.is_writable_defined = true; } - else if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR) + else { + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); prop_desc.get_p = ecma_get_named_accessor_property_getter (prop_p); prop_desc.is_get_defined = true; if (prop_desc.get_p != NULL) diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index b4d4d7442..c747b20f3 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -213,7 +213,7 @@ extern bool ecma_get_object_is_builtin (const ecma_object_t *) __attr_pure___; extern void ecma_set_object_is_builtin (ecma_object_t *); extern ecma_lexical_environment_type_t ecma_get_lex_env_type (const ecma_object_t *) __attr_pure___; extern ecma_object_t *ecma_get_lex_env_outer_reference (const ecma_object_t *) __attr_pure___; -extern ecma_property_t *ecma_get_property_list (const ecma_object_t *) __attr_pure___; +extern ecma_property_header_t *ecma_get_property_list (const ecma_object_t *) __attr_pure___; extern ecma_object_t *ecma_get_lex_env_binding_object (const ecma_object_t *) __attr_pure___; extern bool ecma_get_lex_env_provide_this (const ecma_object_t *) __attr_pure___; @@ -232,7 +232,7 @@ ecma_get_named_property (ecma_object_t *, ecma_string_t *); extern ecma_property_t * ecma_get_named_data_property (ecma_object_t *, ecma_string_t *); -extern void ecma_free_property (ecma_object_t *, ecma_property_t *); +extern void ecma_free_property (ecma_object_t *, ecma_string_t *, ecma_property_t *); extern void ecma_delete_property (ecma_object_t *, ecma_property_t *); @@ -240,6 +240,9 @@ extern ecma_value_t ecma_get_named_data_property_value (const ecma_property_t *) extern void ecma_set_named_data_property_value (ecma_property_t *, ecma_value_t); extern void ecma_named_data_property_assign_value (ecma_object_t *, ecma_property_t *, ecma_value_t); +extern ecma_value_t ecma_get_internal_property_value (const ecma_property_t *); +extern void ecma_set_internal_property_value (ecma_property_t *, ecma_value_t); + extern ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_t *); extern ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_t *); extern void ecma_set_named_accessor_property_getter (ecma_object_t *, ecma_property_t *, ecma_object_t *); @@ -258,6 +261,8 @@ extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void); extern void ecma_free_property_descriptor (ecma_property_descriptor_t *); extern ecma_property_descriptor_t ecma_get_property_descriptor_from_property (ecma_property_t *); +extern ecma_property_t *ecma_get_next_property_pair (ecma_property_pair_t *); + extern void ecma_bytecode_ref (ecma_compiled_code_t *); extern void ecma_bytecode_deref (ecma_compiled_code_t *); diff --git a/jerry-core/ecma/base/ecma-lcache.c b/jerry-core/ecma/base/ecma-lcache.c index 00de72bb9..fa2e47323 100644 --- a/jerry-core/ecma/base/ecma-lcache.c +++ b/jerry-core/ecma/base/ecma-lcache.c @@ -33,22 +33,16 @@ */ typedef struct { + /** Pointer to a property of the object */ + ecma_property_t *prop_p; + /** Compressed pointer to object (ECMA_NULL_POINTER marks record empty) */ mem_cpointer_t object_cp; /** Compressed pointer to property's name */ mem_cpointer_t prop_name_cp; - - /** Compressed pointer to a property of the object */ - mem_cpointer_t prop_cp; - - /** Padding structure to 8 bytes size */ - uint16_t padding; } ecma_lcache_hash_entry_t; -JERRY_STATIC_ASSERT (sizeof (ecma_lcache_hash_entry_t) == sizeof (uint64_t), - size_of_ecma_lcache_hash_entry_t_must_be_equal_to_8_bytes); - /** * LCache hash value length, in bits */ @@ -98,11 +92,9 @@ ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to i ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, entry_p->prop_name_cp)); - if (entry_p->prop_cp != ECMA_NULL_POINTER) + if (entry_p->prop_p != NULL) { - ecma_set_property_lcached (ECMA_GET_NON_NULL_POINTER (ecma_property_t, - entry_p->prop_cp), - false); + ecma_set_property_lcached (entry_p->prop_p, false); } } /* ecma_lcache_invalidate_entry */ #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ @@ -135,14 +127,13 @@ static void ecma_lcache_invalidate_row_for_object_property_pair (uint32_t row_index, /**< index of the row */ unsigned int object_cp, /**< compressed pointer * to an object */ - unsigned property_cp) /**< compressed pointer - * to the object's - * property */ + ecma_property_t *property_p) /**< pointer to the + * object's property */ { for (uint32_t entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++) { if (ecma_lcache_hash_table[ row_index ][ entry_index ].object_cp == object_cp - && ecma_lcache_hash_table[ row_index ][ entry_index ].prop_cp == property_cp) + && ecma_lcache_hash_table[ row_index ][ entry_index ].prop_p == property_p) { ecma_lcache_invalidate_entry (&ecma_lcache_hash_table[ row_index ][ entry_index ]); } @@ -172,14 +163,11 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */ { if (unlikely (ecma_is_property_lcached (prop_p))) { - mem_cpointer_t prop_cp; - ECMA_SET_NON_NULL_POINTER (prop_cp, prop_p); - int32_t entry_index; for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++) { if (ecma_lcache_hash_table[hash_key][entry_index].object_cp != ECMA_NULL_POINTER - && ecma_lcache_hash_table[hash_key][entry_index].prop_cp == prop_cp) + && ecma_lcache_hash_table[hash_key][entry_index].prop_p == prop_p) { #ifndef JERRY_NDEBUG ecma_object_t *obj_in_entry_p; @@ -222,7 +210,7 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */ ecma_ref_object (object_p); ECMA_SET_NON_NULL_POINTER (ecma_lcache_hash_table[ hash_key ][ entry_index ].object_cp, object_p); ECMA_SET_NON_NULL_POINTER (ecma_lcache_hash_table[ hash_key ][ entry_index ].prop_name_cp, prop_name_p); - ECMA_SET_POINTER (ecma_lcache_hash_table[ hash_key ][ entry_index ].prop_cp, prop_p); + ecma_lcache_hash_table[ hash_key ][ entry_index ].prop_p = prop_p; #else /* CONFIG_ECMA_LCACHE_DISABLE */ (void) prop_p; #endif /* CONFIG_ECMA_LCACHE_DISABLE */ @@ -262,7 +250,7 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */ if (ECMA_STRING_GET_CONTAINER (prop_name_p) == ECMA_STRING_GET_CONTAINER (entry_prop_name_p) && prop_name_p->u.common_field == entry_prop_name_p->u.common_field) { - ecma_property_t *prop_p = ECMA_GET_POINTER (ecma_property_t, ecma_lcache_hash_table[hash_key][i].prop_cp); + ecma_property_t *prop_p = ecma_lcache_hash_table[hash_key][i].prop_p; JERRY_ASSERT (prop_p == NULL || ecma_is_property_lcached (prop_p)); *prop_p_p = prop_p; @@ -295,18 +283,17 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */ */ void ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */ - ecma_string_t *prop_name_arg_p, /**< property's name (See also: Note) */ + ecma_string_t *prop_name_p, /**< property's name (See also: Note) */ ecma_property_t *prop_p) /**< property (See also: Note) */ { JERRY_ASSERT (object_p != NULL); - JERRY_ASSERT (prop_p != NULL || prop_name_arg_p != NULL); + JERRY_ASSERT (prop_name_p != NULL); #ifndef CONFIG_ECMA_LCACHE_DISABLE - ecma_string_t *prop_name_p = NULL; - if (prop_p != NULL) { - JERRY_ASSERT (prop_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); bool is_cached = ecma_is_property_lcached (prop_p); @@ -316,33 +303,17 @@ ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */ } ecma_set_property_lcached (prop_p, false); - - if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) - { - prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, - prop_p->v.named_data_property.name_p); - } - else - { - prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, - prop_p->v.named_accessor_property.name_p); - } - } - else - { - prop_name_p = prop_name_arg_p; } - unsigned int object_cp, prop_cp; + unsigned int object_cp; ECMA_SET_NON_NULL_POINTER (object_cp, object_p); - ECMA_SET_POINTER (prop_cp, prop_p); lit_string_hash_t hash_key = ecma_string_hash (prop_name_p); /* Property's name has was computed. * Given (object, property name) pair should be in the row corresponding to computed hash. */ - ecma_lcache_invalidate_row_for_object_property_pair (hash_key, object_cp, prop_cp); + ecma_lcache_invalidate_row_for_object_property_pair (hash_key, object_cp, prop_p); #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ } /* ecma_lcache_invalidate */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c index 982aa1b57..5e128fedf 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-boolean-prototype.c @@ -107,9 +107,10 @@ ecma_builtin_boolean_prototype_object_value_of (ecma_value_t this_arg) /**< this ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE); - JERRY_ASSERT (prim_value_prop_p->v.internal_property.value < ECMA_SIMPLE_VALUE__COUNT); + JERRY_ASSERT (ecma_get_internal_property_value (prim_value_prop_p) < ECMA_SIMPLE_VALUE__COUNT); - ecma_simple_value_t prim_simple_value = (ecma_simple_value_t) prim_value_prop_p->v.internal_property.value; + ecma_simple_value_t prim_simple_value; + prim_simple_value = (ecma_simple_value_t) ecma_get_internal_property_value (prim_value_prop_p); ecma_value_t ret_boolean_value = ecma_make_simple_value (prim_simple_value); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c index 8e4da2765..35fa8f408 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c @@ -105,10 +105,10 @@ ecma_builtin_date_prototype_to_date_string (ecma_value_t this_arg) /**< this arg ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_property_t *prim_value_prop_p; - prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); + ecma_property_t *prim_prop_p = ecma_get_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, - prim_value_prop_p->v.internal_property.value); + ecma_get_internal_property_value (prim_prop_p)); if (ecma_number_is_nan (*prim_value_num_p)) { @@ -152,10 +152,10 @@ ecma_builtin_date_prototype_to_time_string (ecma_value_t this_arg) /**< this arg ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_property_t *prim_value_prop_p; - prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); + ecma_property_t *prim_prop_p = ecma_get_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, - prim_value_prop_p->v.internal_property.value); + ecma_get_internal_property_value (prim_prop_p)); if (ecma_number_is_nan (*prim_value_num_p)) { @@ -250,11 +250,11 @@ ecma_builtin_date_prototype_get_time (ecma_value_t this_arg) /**< this argument ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_DATE_UL) { - ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); + ecma_property_t *prim_prop_p = ecma_get_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, - prim_value_prop_p->v.internal_property.value); + ecma_get_internal_property_value (prim_prop_p)); ecma_number_t *ret_num_p = ecma_alloc_number (); *ret_num_p = *prim_value_num_p; @@ -363,11 +363,11 @@ ecma_builtin_date_prototype_set_time (ecma_value_t this_arg, /**< this argument /* 2. */ ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, - ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); + ecma_property_t *prim_prop_p = ecma_get_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, - prim_value_prop_p->v.internal_property.value); + ecma_get_internal_property_value (prim_prop_p)); *prim_value_num_p = *value_p; /* 3. */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c index e7d3eaedf..73829b9c9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c @@ -579,11 +579,11 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - class_prop_p->v.internal_property.value = LIT_MAGIC_STRING_DATE_UL; + ecma_set_internal_property_value (class_prop_p, LIT_MAGIC_STRING_DATE_UL); ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); - ECMA_SET_POINTER (prim_value_prop_p->v.internal_property.value, prim_value_num_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_value_num_p); ret_value = ecma_make_object_value (obj_p); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c index 2c7cdcd5c..42653fea8 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c @@ -247,7 +247,7 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION); ecma_object_t *this_arg_obj_p = ecma_get_object_from_value (this_arg); - ECMA_SET_NON_NULL_POINTER (target_function_prop_p->v.internal_property.value, this_arg_obj_p); + ECMA_SET_NON_NULL_POINTER (ECMA_PROPERTY_VALUE_PTR (target_function_prop_p)->value, this_arg_obj_p); /* 8. */ ecma_property_t *bound_this_prop_p; @@ -256,11 +256,13 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar if (arg_count > 0) { - bound_this_prop_p->v.internal_property.value = ecma_copy_value_if_not_object (arguments_list_p[0]); + ecma_set_internal_property_value (bound_this_prop_p, + ecma_copy_value_if_not_object (arguments_list_p[0])); } else { - bound_this_prop_p->v.internal_property.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); + ecma_set_internal_property_value (bound_this_prop_p, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)); } if (arg_count > 1) @@ -270,7 +272,7 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar ecma_property_t *bound_args_prop_p; bound_args_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS); - ECMA_SET_NON_NULL_POINTER (bound_args_prop_p->v.internal_property.value, bound_args_collection_p); + ECMA_SET_NON_NULL_POINTER (ECMA_PROPERTY_VALUE_PTR (bound_args_prop_p)->value, bound_args_collection_p); } /* diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c index 20ef8e272..ae679f749 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c @@ -922,7 +922,7 @@ ecma_date_set_internal_property (ecma_value_t this_arg, /**< this argument */ ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, - prim_value_prop_p->v.internal_property.value); + ecma_get_internal_property_value (prim_value_prop_p)); *prim_value_num_p = *value_p; return ecma_make_number_value (value_p); @@ -1349,7 +1349,7 @@ ecma_date_get_primitive_value (ecma_value_t this_arg) /**< this argument */ ecma_number_t *prim_value_num_p = ecma_alloc_number (); *prim_value_num_p = *ECMA_GET_NON_NULL_POINTER (ecma_number_t, - prim_value_prop_p->v.internal_property.value); + ecma_get_internal_property_value (prim_value_prop_p)); ret_value = ecma_make_number_value (prim_value_num_p); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h index f48805111..bb34d58ef 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h @@ -194,10 +194,10 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (ecma_object_t *obj_p, /**< object */ if (mask_prop_p == NULL) { mask_prop_p = ecma_create_internal_property (obj_p, mask_prop_id); - mask_prop_p->v.internal_property.value = 0; + ecma_set_internal_property_value (mask_prop_p, 0); } - uint32_t bit_mask = mask_prop_p->v.internal_property.value; + uint32_t bit_mask = ecma_get_internal_property_value (mask_prop_p); if (bit_mask & bit) { @@ -206,7 +206,7 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (ecma_object_t *obj_p, /**< object */ bit_mask |= bit; - mask_prop_p->v.internal_property.value = bit_mask; + ecma_set_internal_property_value (mask_prop_p, bit_mask); ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ecma_property_writable_value_t writable; @@ -379,7 +379,7 @@ LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (ecma_object_t *object_p, /**< a built-in } else { - uint32_t bit_mask = mask_prop_p->v.internal_property.value; + uint32_t bit_mask = ecma_get_internal_property_value (mask_prop_p); if (bit_mask & bit) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index 32d55f834..4e2582db2 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -1440,7 +1440,7 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/ JERRY_ASSERT (ecma_is_property_enumerable (property_p)); - if (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) { ecma_append_to_values_collection (property_keys_p, *iter.current_value_p, true); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c index 09fdaee20..bfa4c20f0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c @@ -358,8 +358,9 @@ ecma_builtin_number_prototype_object_value_of (ecma_value_t this_arg) /**< this ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); - ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, - prim_value_prop_p->v.internal_property.value); + ecma_number_t *prim_value_num_p; + prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, + ecma_get_internal_property_value (prim_value_prop_p)); ecma_number_t *ret_num_p = ecma_alloc_number (); *ret_num_p = *prim_value_num_p; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c index 330364fef..1114d325f 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c @@ -278,7 +278,8 @@ ecma_builtin_object_object_freeze (ecma_value_t this_arg __attr_unused___, /**< ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (property_p); // 2.b - if ((property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) && ecma_is_property_writable (property_p)) + if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + && ecma_is_property_writable (property_p)) { prop_desc.is_writable = false; } @@ -462,10 +463,12 @@ ecma_builtin_object_object_is_frozen (ecma_value_t this_arg __attr_unused___, /* // 2.a ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p); - JERRY_ASSERT (property_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); // 2.b - if ((property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) && ecma_is_property_writable (property_p)) + if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + && ecma_is_property_writable (property_p)) { is_frozen = false; break; 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 477d422d4..29442b9c5 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c @@ -137,14 +137,14 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument JERRY_ASSERT (ecma_is_value_empty (bc_comp)); re_compiled_code_t *old_bc_p = ECMA_GET_POINTER (re_compiled_code_t, - bc_prop_p->v.internal_property.value); + ecma_get_internal_property_value (bc_prop_p)); if (old_bc_p != NULL) { /* Free the old bytecode */ ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p); } - ECMA_SET_POINTER (bc_prop_p->v.internal_property.value, new_bc_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (bc_prop_p)->value, new_bc_p); re_initialize_props (this_obj_p, pattern_string_p, flags); @@ -206,7 +206,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument ret_value); re_compiled_code_t *old_bc_p = ECMA_GET_POINTER (re_compiled_code_t, - bc_prop_p->v.internal_property.value); + ecma_get_internal_property_value (bc_prop_p)); if (old_bc_p != NULL) { @@ -214,7 +214,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p); } - ECMA_SET_POINTER (bc_prop_p->v.internal_property.value, new_bc_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (bc_prop_p)->value, new_bc_p); re_initialize_props (this_obj_p, pattern_string_p, flags); ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); @@ -269,7 +269,7 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */ ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); bytecode_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); - void *bytecode_p = ECMA_GET_POINTER (void, bytecode_prop_p->v.internal_property.value); + void *bytecode_p = ECMA_GET_POINTER (void, ecma_get_internal_property_value (bytecode_prop_p)); if (bytecode_p == NULL) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index e88b8676c..d15820757 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -79,8 +79,9 @@ ecma_builtin_string_prototype_object_to_string (ecma_value_t this_arg) /**< this ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE); - ecma_string_t *prim_value_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, - prim_value_prop_p->v.internal_property.value); + ecma_string_t *prim_value_str_p; + prim_value_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, + ecma_get_internal_property_value (prim_value_prop_p)); prim_value_str_p = ecma_copy_or_ref_ecma_string (prim_value_str_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index a8789cc88..c12bd7cb8 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -111,7 +111,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_property_t *built_in_id_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); - built_in_id_prop_p->v.internal_property.value = obj_builtin_id; + ecma_set_internal_property_value (built_in_id_prop_p, obj_builtin_id); ecma_set_object_is_builtin (object_obj_p); @@ -126,7 +126,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE); - ECMA_SET_POINTER (prim_value_prop_p->v.internal_property.value, prim_prop_str_value_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_prop_str_value_p); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */ @@ -140,7 +140,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); - ECMA_SET_POINTER (prim_value_prop_p->v.internal_property.value, prim_prop_num_value_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_prop_num_value_p); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ @@ -151,7 +151,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE); - prim_value_prop_p->v.internal_property.value = ECMA_SIMPLE_VALUE_FALSE; + ecma_set_internal_property_value (prim_value_prop_p, ECMA_SIMPLE_VALUE_FALSE); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */ @@ -165,7 +165,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); - ECMA_SET_POINTER (prim_value_prop_p->v.internal_property.value, prim_prop_num_value_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_prop_num_value_p); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN */ @@ -176,7 +176,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_property_t *bytecode_prop_p; bytecode_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); - bytecode_prop_p->v.internal_property.value = ECMA_NULL_POINTER; + ecma_set_internal_property_value (bytecode_prop_p, ECMA_NULL_POINTER); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */ @@ -309,7 +309,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * ecma_property_t *desc_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); - uint64_t builtin_routine_desc = desc_prop_p->v.internal_property.value; + uint64_t builtin_routine_desc = ecma_get_internal_property_value (desc_prop_p); JERRY_STATIC_ASSERT (sizeof (uint8_t) * JERRY_BITSINBYTE == ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH, bits_in_uint8_t_must_be_equal_to_ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH); @@ -337,7 +337,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * { ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); - ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->v.internal_property.value; + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); @@ -411,7 +411,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in { ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); - ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->v.internal_property.value; + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); @@ -493,7 +493,7 @@ ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /** ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); JERRY_ASSERT ((uint32_t) packed_value == packed_value); - routine_desc_prop_p->v.internal_property.value = (uint32_t) packed_value; + ecma_set_internal_property_value (routine_desc_prop_p, (uint32_t) packed_value); return func_obj_p; } /* ecma_builtin_make_function_object_for_routine */ @@ -517,7 +517,7 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ { ecma_property_t *desc_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); - uint64_t builtin_routine_desc = desc_prop_p->v.internal_property.value; + uint64_t builtin_routine_desc = ecma_get_internal_property_value (desc_prop_p); uint64_t built_in_id_field = JRT_EXTRACT_BIT_FIELD (uint64_t, builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS, @@ -544,7 +544,7 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); - ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->v.internal_property.value; + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p); JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); @@ -605,7 +605,7 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); - ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->v.internal_property.value; + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p); JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 38d90ea8c..b09f03c2d 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -157,7 +157,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o // 1. ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p); - JERRY_ASSERT (len_prop_p != NULL && (len_prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)); + JERRY_ASSERT (len_prop_p != NULL && ECMA_PROPERTY_GET_TYPE (len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); // 2. ecma_value_t old_len_value = ecma_get_named_data_property_value (len_prop_p); diff --git a/jerry-core/ecma/operations/ecma-boolean-object.c b/jerry-core/ecma/operations/ecma-boolean-object.c index 97cb34218..0b42f3211 100644 --- a/jerry-core/ecma/operations/ecma-boolean-object.c +++ b/jerry-core/ecma/operations/ecma-boolean-object.c @@ -63,11 +63,11 @@ ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boo ecma_deref_object (prototype_obj_p); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - class_prop_p->v.internal_property.value = LIT_MAGIC_STRING_BOOLEAN_UL; + ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_BOOLEAN_UL; ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE); - prim_value_prop_p->v.internal_property.value = bool_value; + ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value = bool_value; return ecma_make_object_value (obj_p); } /* ecma_op_create_boolean_object */ diff --git a/jerry-core/ecma/operations/ecma-exceptions.c b/jerry-core/ecma/operations/ecma-exceptions.c index 9b04ca0df..5bd86f0d8 100644 --- a/jerry-core/ecma/operations/ecma-exceptions.c +++ b/jerry-core/ecma/operations/ecma-exceptions.c @@ -95,7 +95,7 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ ecma_property_t *class_prop_p = ecma_create_internal_property (new_error_obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - class_prop_p->v.internal_property.value = LIT_MAGIC_STRING_ERROR_UL; + ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_ERROR_UL; return new_error_obj_p; #else /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS */ diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 99cb625dc..de556526f 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -168,11 +168,11 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */ // 9. ecma_property_t *scope_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_SCOPE); - ECMA_SET_POINTER (scope_prop_p->v.internal_property.value, scope_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value, scope_p); // 10., 11., 12. ecma_property_t *bytecode_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE); - MEM_CP_SET_NON_NULL_POINTER (bytecode_prop_p->v.internal_property.value, bytecode_data_p); + MEM_CP_SET_NON_NULL_POINTER (ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value, bytecode_data_p); ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p); // 14., 15., 16., 17., 18. @@ -294,7 +294,8 @@ ecma_op_function_try_lazy_instantiate_property (ecma_object_t *obj_p, /**< the f ecma_property_t *bytecode_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE); const ecma_compiled_code_t *bytecode_data_p; - bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t, bytecode_prop_p->v.internal_property.value); + bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t, + ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value); if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { @@ -527,8 +528,9 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object * target_function_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION); - ecma_object_t *target_func_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - target_function_prop_p->v.internal_property.value); + ecma_object_t *target_func_obj_p; + target_func_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, + ECMA_PROPERTY_VALUE_PTR (target_function_prop_p)->value); /* 3. */ ret_value = ecma_op_object_has_instance (target_func_obj_p, value); @@ -575,7 +577,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ ecma_property_t *bytecode_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE); ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - scope_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value); // 8. ecma_value_t this_binding; @@ -583,7 +585,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ bool is_no_lex_env; const ecma_compiled_code_t *bytecode_data_p; - bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t, bytecode_prop_p->v.internal_property.value); + bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t, + ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value); is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false; is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false; @@ -681,19 +684,20 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ target_function_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION); - ecma_object_t *target_func_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - target_function_prop_p->v.internal_property.value); + ecma_object_t *target_func_obj_p; + target_func_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, + ECMA_PROPERTY_VALUE_PTR (target_function_prop_p)->value); /* 4. */ ecma_property_t *bound_args_prop_p; - ecma_value_t bound_this_value = bound_this_prop_p->v.internal_property.value; + ecma_value_t bound_this_value = ECMA_PROPERTY_VALUE_PTR (bound_this_prop_p)->value; bound_args_prop_p = ecma_find_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS); if (bound_args_prop_p != NULL) { ecma_collection_header_t *bound_arg_list_p; bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t, - bound_args_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (bound_args_prop_p)->value); JERRY_ASSERT (bound_arg_list_p->unit_number > 0); @@ -865,8 +869,9 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */ target_function_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION); - ecma_object_t *target_func_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - target_function_prop_p->v.internal_property.value); + ecma_object_t *target_func_obj_p; + target_func_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, + ECMA_PROPERTY_VALUE_PTR (target_function_prop_p)->value); /* 2. */ if (!ecma_is_constructor (ecma_make_object_value (target_func_obj_p))) @@ -883,8 +888,7 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */ { ecma_collection_header_t *bound_arg_list_p; bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t, - bound_args_prop_p->v.internal_property.value); - + ECMA_PROPERTY_VALUE_PTR (bound_args_prop_p)->value); JERRY_ASSERT (bound_arg_list_p->unit_number > 0); @@ -973,13 +977,13 @@ ecma_op_function_declaration (ecma_object_t *lex_env_p, /**< lexical environment JERRY_ASSERT (ecma_is_value_true (completion)); } - else if (existing_prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR) + else if (ECMA_PROPERTY_GET_TYPE (existing_prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("")); } else { - JERRY_ASSERT (existing_prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (existing_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); if (!ecma_is_property_writable (existing_prop_p) || !ecma_is_property_enumerable (existing_prop_p)) diff --git a/jerry-core/ecma/operations/ecma-get-put-value.c b/jerry-core/ecma/operations/ecma-get-put-value.c index 77c8a537f..ac19893a1 100644 --- a/jerry-core/ecma/operations/ecma-get-put-value.c +++ b/jerry-core/ecma/operations/ecma-get-put-value.c @@ -124,7 +124,7 @@ ecma_op_get_value_object_base (ecma_reference_t ref) /**< ECMA-reference */ // 3. ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); } - else if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + else if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) { // 4. ret_value = ecma_copy_value (ecma_get_named_data_property_value (prop_p)); @@ -132,7 +132,7 @@ ecma_op_get_value_object_base (ecma_reference_t ref) /**< ECMA-reference */ else { // 5. - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); ecma_object_t *obj_p = ecma_get_named_accessor_property_getter (prop_p); @@ -304,16 +304,16 @@ ecma_op_put_value_object_base (ecma_reference_t ref, /**< ECMA-reference */ ecma_property_t *prop_p = ecma_op_object_get_property (obj_p, referenced_name_p); // sub_4., sub_7 - if ((own_prop_p != NULL && (own_prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)) + if ((own_prop_p != NULL && ECMA_PROPERTY_GET_TYPE (own_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) || (prop_p == NULL) - || !(prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR)) + || ECMA_PROPERTY_GET_TYPE (prop_p) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { ret_value = ecma_reject_put (ref.is_strict); } else { // sub_6. - JERRY_ASSERT (prop_p != NULL && (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR)); + JERRY_ASSERT (prop_p != NULL && ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (prop_p); JERRY_ASSERT (setter_p != NULL); diff --git a/jerry-core/ecma/operations/ecma-lex-env.c b/jerry-core/ecma/operations/ecma-lex-env.c index c764e5e04..6587624bf 100644 --- a/jerry-core/ecma/operations/ecma-lex-env.c +++ b/jerry-core/ecma/operations/ecma-lex-env.c @@ -331,7 +331,7 @@ ecma_op_delete_binding (ecma_object_t *lex_env_p, /**< lexical environment */ } else { - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); if (!ecma_is_property_configurable (prop_p)) { diff --git a/jerry-core/ecma/operations/ecma-number-object.c b/jerry-core/ecma/operations/ecma-number-object.c index 473575903..0204b94b6 100644 --- a/jerry-core/ecma/operations/ecma-number-object.c +++ b/jerry-core/ecma/operations/ecma-number-object.c @@ -62,11 +62,11 @@ ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Numb ecma_deref_object (prototype_obj_p); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - class_prop_p->v.internal_property.value = LIT_MAGIC_STRING_NUMBER_UL; + ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_NUMBER_UL; ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); - ECMA_SET_POINTER (prim_value_prop_p->v.internal_property.value, prim_value_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_value_p); return ecma_make_object_value (obj_p); } /* ecma_op_create_number_object */ diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.c b/jerry-core/ecma/operations/ecma-objects-arguments.c index 037cd0ec7..f14f308e0 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.c +++ b/jerry-core/ecma/operations/ecma-objects-arguments.c @@ -84,7 +84,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function // 4. ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - class_prop_p->v.internal_property.value = LIT_MAGIC_STRING_ARGUMENTS_UL; + ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_ARGUMENTS_UL; // 7. ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); @@ -174,11 +174,11 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_property_t *parameters_map_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); - ECMA_SET_POINTER (parameters_map_prop_p->v.internal_property.value, map_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (parameters_map_prop_p)->value, map_p); ecma_property_t *scope_prop_p = ecma_create_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE); - ECMA_SET_POINTER (scope_prop_p->v.internal_property.value, lex_env_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value, lex_env_p); ecma_deref_object (map_p); } @@ -286,7 +286,7 @@ ecma_arguments_get_mapped_arg_value (ecma_object_t *map_p, /**< [[ParametersMap] { ecma_property_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE); ecma_object_t *lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - scope_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value); JERRY_ASSERT (lex_env_p != NULL && ecma_is_lexical_environment (lex_env_p)); @@ -317,7 +317,7 @@ ecma_op_arguments_object_get (ecma_object_t *obj_p, /**< the object */ // 1. ecma_property_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ecma_object_t *map_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - map_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (map_prop_p)->value); // 2. ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); @@ -363,7 +363,7 @@ ecma_op_arguments_object_get_own_property (ecma_object_t *obj_p, /**< the object // 3. ecma_property_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ecma_object_t *map_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - map_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (map_prop_p)->value); // 4. ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); @@ -403,7 +403,7 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the obj // 1. ecma_property_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ecma_object_t *map_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - map_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (map_prop_p)->value); // 2. ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); @@ -444,7 +444,7 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the obj /* emulating execution of function described by MakeArgSetter */ ecma_property_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE); ecma_object_t *lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - scope_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value); ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); ecma_value_t arg_name_prop_value = ecma_get_named_data_property_value (mapped_prop_p); @@ -501,7 +501,7 @@ ecma_op_arguments_object_delete (ecma_object_t *obj_p, /**< the object */ // 1. ecma_property_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ecma_object_t *map_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - map_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (map_prop_p)->value); // 2. ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index f94ac4bfa..28b1f54d2 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -157,7 +157,7 @@ ecma_op_general_object_get (ecma_object_t *obj_p, /**< the object */ } // 3. - if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) { return ecma_copy_value (ecma_get_named_data_property_value (prop_p)); } @@ -284,7 +284,7 @@ ecma_op_general_object_put (ecma_object_t *obj_p, /**< the object */ ecma_property_t *own_desc_p = ecma_op_object_get_own_property (obj_p, property_name_p); // 3. - if (own_desc_p != NULL && (own_desc_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)) + if (own_desc_p != NULL && ECMA_PROPERTY_GET_TYPE (own_desc_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) { // a. ecma_property_descriptor_t value_desc = ecma_make_empty_property_descriptor (); @@ -304,7 +304,7 @@ ecma_op_general_object_put (ecma_object_t *obj_p, /**< the object */ ecma_property_t *desc_p = ecma_op_object_get_property (obj_p, property_name_p); // 5. - if (desc_p != NULL && (desc_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR)) + if (desc_p != NULL && ECMA_PROPERTY_GET_TYPE (desc_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { // a. ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (desc_p); @@ -365,7 +365,7 @@ ecma_op_general_object_can_put (ecma_object_t *obj_p, /**< the object */ if (prop_p != NULL) { // a. - if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR) + if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (prop_p); @@ -381,7 +381,7 @@ ecma_op_general_object_can_put (ecma_object_t *obj_p, /**< the object */ else { // b. - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); return ecma_is_property_writable (prop_p); } @@ -406,7 +406,7 @@ ecma_op_general_object_can_put (ecma_object_t *obj_p, /**< the object */ } // 7. - if (inherited_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR) + if (ECMA_PROPERTY_GET_TYPE (inherited_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { ecma_object_t *setter_p = ecma_get_named_accessor_property_setter (inherited_p); @@ -422,7 +422,7 @@ ecma_op_general_object_can_put (ecma_object_t *obj_p, /**< the object */ else { // 8. - JERRY_ASSERT (inherited_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (inherited_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); // a. if (!ecma_get_object_extensible (obj_p)) @@ -655,8 +655,9 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec } // 6. - const bool is_current_data_descriptor = (current_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); - const bool is_current_accessor_descriptor = (current_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + ecma_property_types_t current_type = ECMA_PROPERTY_GET_TYPE (current_p); + const bool is_current_data_descriptor = (current_type == ECMA_PROPERTY_TYPE_NAMEDDATA); + const bool is_current_accessor_descriptor = (current_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); JERRY_ASSERT (is_current_data_descriptor || is_current_accessor_descriptor); @@ -820,28 +821,28 @@ ecma_op_general_object_define_own_property (ecma_object_t *obj_p, /**< the objec // 12. if (property_desc_p->is_value_defined) { - JERRY_ASSERT (current_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (current_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_named_data_property_assign_value (obj_p, current_p, property_desc_p->value); } if (property_desc_p->is_writable_defined) { - JERRY_ASSERT (current_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (current_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_set_property_writable_attr (current_p, property_desc_p->is_writable); } if (property_desc_p->is_get_defined) { - JERRY_ASSERT (current_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (current_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); ecma_set_named_accessor_property_getter (obj_p, current_p, property_desc_p->get_p); } if (property_desc_p->is_set_defined) { - JERRY_ASSERT (current_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (current_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); ecma_set_named_accessor_property_setter (obj_p, current_p, property_desc_p->set_p); } diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index aecd791dc..38962a350 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -624,80 +624,77 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ } } - for (ecma_property_t *prop_iter_p = ecma_get_property_list (prototype_chain_iter_p); - prop_iter_p != NULL; - prop_iter_p = ECMA_GET_POINTER (ecma_property_t, prop_iter_p->next_property_p)) + ecma_property_header_t *prop_iter_p = ecma_get_property_list (prototype_chain_iter_p); + + while (prop_iter_p != NULL) { - if (prop_iter_p->flags & (ECMA_PROPERTY_FLAG_NAMEDDATA | ECMA_PROPERTY_FLAG_NAMEDACCESSOR)) + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + + for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { - ecma_string_t *name_p; + ecma_property_t *property_p = prop_iter_p->types + i; - if (prop_iter_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA) + if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + || ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { - name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_iter_p->v.named_data_property.name_p); - } - else - { - JERRY_ASSERT (prop_iter_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR); + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; + ecma_string_t *name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_pair_p->names_cp[i]); - name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_iter_p->v.named_accessor_property.name_p); - } - - if (!(is_enumerable_only && !ecma_is_property_enumerable (prop_iter_p))) - { - lit_string_hash_t hash = name_p->hash; - uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); - uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); - - bool is_add = true; - - if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0) + if (!(is_enumerable_only && !ecma_is_property_enumerable (property_p))) { - ecma_collection_iterator_init (&iter, prop_names_p); + lit_string_hash_t hash = name_p->hash; + uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); + uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); - while (ecma_collection_iterator_next (&iter)) + bool is_add = true; + + if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0) { - ecma_string_t *name2_p = ecma_get_string_from_value (*iter.current_value_p); + ecma_collection_iterator_init (&iter, prop_names_p); - if (ecma_compare_ecma_strings (name_p, name2_p)) + while (ecma_collection_iterator_next (&iter)) { - is_add = false; - break; + ecma_string_t *name2_p = ecma_get_string_from_value (*iter.current_value_p); + + if (ecma_compare_ecma_strings (name_p, name2_p)) + { + is_add = false; + break; + } } } + + if (is_add) + { + own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); + + ecma_append_to_values_collection (prop_names_p, + ecma_make_string_value (name_p), + true); + } } - - if (is_add) + else { - own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); + JERRY_ASSERT (is_enumerable_only && !ecma_is_property_enumerable (property_p)); - ecma_append_to_values_collection (prop_names_p, + ecma_append_to_values_collection (skipped_non_enumerable_p, ecma_make_string_value (name_p), true); - } - } - else - { - JERRY_ASSERT (is_enumerable_only && !ecma_is_property_enumerable (prop_iter_p)); - ecma_append_to_values_collection (skipped_non_enumerable_p, - ecma_make_string_value (name_p), - true); + lit_string_hash_t hash = name_p->hash; + uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); + uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); - lit_string_hash_t hash = name_p->hash; - uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); - uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); - - if ((names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) == 0) - { - names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); + if ((names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) == 0) + { + names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); + } } } } - else - { - JERRY_ASSERT (prop_iter_p->flags & ECMA_PROPERTY_FLAG_INTERNAL); - } + + prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, + prop_iter_p->next_property_cp); } ecma_collection_iterator_init (&iter, prop_names_p); @@ -902,7 +899,7 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ { ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); - ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->v.internal_property.value; + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ECMA_PROPERTY_VALUE_PTR (built_in_id_prop_p)->value; switch (builtin_id) { @@ -983,7 +980,7 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ } else { - return (lit_magic_string_id_t) class_name_prop_p->v.internal_property.value; + return ECMA_PROPERTY_VALUE_PTR (class_name_prop_p)->value; } } } diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index 037334ede..46eeb6e0d 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -146,7 +146,7 @@ re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */ } ecma_deref_ecma_string (magic_string_p); - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_named_data_property_assign_value (re_obj_p, prop_p, ecma_make_string_value (source_p)); @@ -166,7 +166,7 @@ re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */ ecma_deref_ecma_string (magic_string_p); prop_value = (flags & RE_FLAG_GLOBAL) ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE; - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_set_named_data_property_value (prop_p, ecma_make_simple_value (prop_value)); /* Set ignoreCase property. ECMA-262 v5, 15.10.7.3 */ @@ -182,7 +182,7 @@ re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */ ecma_deref_ecma_string (magic_string_p); prop_value = (flags & RE_FLAG_IGNORE_CASE) ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE; - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_set_named_data_property_value (prop_p, ecma_make_simple_value (prop_value)); /* Set multiline property. ECMA-262 v5, 15.10.7.4 */ @@ -198,7 +198,7 @@ re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */ ecma_deref_ecma_string (magic_string_p); prop_value = (flags & RE_FLAG_MULTILINE) ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE; - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_set_named_data_property_value (prop_p, ecma_make_simple_value (prop_value)); /* Set lastIndex property. ECMA-262 v5, 15.10.7.5 */ @@ -216,7 +216,7 @@ re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */ ecma_number_t *lastindex_num_p = ecma_alloc_number (); *lastindex_num_p = ECMA_NUMBER_ZERO; - JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); ecma_named_data_property_assign_value (re_obj_p, prop_p, ecma_make_number_value (lastindex_num_p)); ecma_dealloc_number (lastindex_num_p); } /* re_initialize_props */ @@ -241,12 +241,12 @@ ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**< /* Set the internal [[Class]] property */ ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - class_prop_p->v.internal_property.value = LIT_MAGIC_STRING_REGEXP_UL; + ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_REGEXP_UL; /* Set bytecode internal property. */ ecma_property_t *bytecode_prop_p; bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); - ECMA_SET_NON_NULL_POINTER (bytecode_prop_p->v.internal_property.value, bytecode_p); + ECMA_SET_NON_NULL_POINTER (ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value, bytecode_p); ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_p); /* Initialize RegExp object properties */ @@ -293,7 +293,7 @@ ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */ /* Set the internal [[Class]] property */ ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); - class_prop_p->v.internal_property.value = LIT_MAGIC_STRING_REGEXP_UL; + ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_REGEXP_UL; re_initialize_props (obj_p, pattern_p, flags); @@ -305,7 +305,7 @@ ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */ const re_compiled_code_t *bc_p = NULL; ECMA_TRY_CATCH (empty, re_compile_bytecode (&bc_p, pattern_p, flags), ret_value); - ECMA_SET_POINTER (bytecode_prop_p->v.internal_property.value, bc_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value, bc_p); ret_value = ecma_make_object_value (obj_p); ECMA_FINALIZE (empty); @@ -1263,7 +1263,7 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */ ecma_property_t *bytecode_prop_p = ecma_get_internal_property (regexp_object_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); re_compiled_code_t *bc_p = ECMA_GET_POINTER (re_compiled_code_t, - bytecode_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value); if (bc_p == NULL) { diff --git a/jerry-core/ecma/operations/ecma-string-object.c b/jerry-core/ecma/operations/ecma-string-object.c index fe83eeade..e12d9a53e 100644 --- a/jerry-core/ecma/operations/ecma-string-object.c +++ b/jerry-core/ecma/operations/ecma-string-object.c @@ -95,7 +95,7 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE); - ECMA_SET_POINTER (prim_value_prop_p->v.internal_property.value, prim_prop_str_value_p); + ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_prop_str_value_p); // 15.5.5.1 ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); @@ -170,7 +170,7 @@ ecma_op_string_object_get_own_property (ecma_object_t *obj_p, /**< a String obje ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE); ecma_string_t *prim_value_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, - prim_value_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value); // 6. ecma_length_t length = ecma_string_get_length (prim_value_str_p); @@ -237,7 +237,7 @@ ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obj ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE); ecma_string_t *prim_value_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, - prim_value_prop_p->v.internal_property.value); + ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value); ecma_length_t length = ecma_string_get_length (prim_value_str_p); diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 35a109d2c..3d79905cb 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -157,7 +157,7 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */ ecma_string_t *accessor_name_p = ecma_get_string_from_value (accessor_name); ecma_property_t *property_p = ecma_find_named_property (object_p, accessor_name_p); - if (property_p != NULL && !(property_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR)) + if (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { ecma_delete_property (object_p, property_p); property_p = NULL; diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index c2dfa2ca0..5de3924b9 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -1013,7 +1013,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ property_p = ecma_find_named_property (object_p, prop_name_p); } - if (property_p != NULL && !(property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)) + if (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA) { ecma_delete_property (object_p, property_p); property_p = NULL;