From 6f0391dd667e86f8e5bfb4cef8eaa699e00229cf Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Tue, 12 Jan 2021 13:12:44 +0100 Subject: [PATCH] Unify internal property creation (#4373) Furthermore free up a bit in the property descriptor. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- docs/04.INTERNALS.md | 3 +- jerry-core/debugger/debugger.c | 3 +- jerry-core/ecma/base/ecma-gc.c | 181 +++++++++--------- jerry-core/ecma/base/ecma-globals.h | 170 +++++++--------- .../base/ecma-helpers-external-pointers.c | 11 +- jerry-core/ecma/base/ecma-helpers-string.c | 15 ++ jerry-core/ecma/base/ecma-helpers.c | 96 ++++------ jerry-core/ecma/base/ecma-helpers.h | 1 + jerry-core/ecma/base/ecma-lcache.c | 8 +- jerry-core/ecma/base/ecma-property-hashmap.c | 9 +- .../ecma/builtin-objects/ecma-builtins.c | 2 +- .../ecma/operations/ecma-array-object.c | 13 +- .../ecma/operations/ecma-container-object.c | 12 +- jerry-core/ecma/operations/ecma-lex-env.c | 20 +- .../ecma/operations/ecma-objects-general.c | 59 +++--- jerry-core/ecma/operations/ecma-objects.c | 52 +++-- jerry-core/ecma/operations/ecma-reference.c | 6 +- .../js/js-parser-tagged-template-literal.c | 2 +- jerry-core/vm/opcodes.c | 64 ++++--- jerry-core/vm/vm.c | 9 +- 20 files changed, 344 insertions(+), 392 deletions(-) diff --git a/docs/04.INTERNALS.md b/docs/04.INTERNALS.md index 81ff54f54..8576048d0 100644 --- a/docs/04.INTERNALS.md +++ b/docs/04.INTERNALS.md @@ -284,7 +284,8 @@ The objects are represented as following structure: ![Object properties](img/ecma_object_property.png) Objects have a linked list that contains their properties. This list actually contains property pairs, in order to save memory described in the followings: -A property is 7 bit long and its type field is 2 bit long which consumes 9 bit which does not fit into 1 byte but consumes 2 bytes. Hence, placing together two properties (14 bit) with the 2 bit long type field fits into 2 bytes. +A property has a one byte long descriptor, a two byte long name and four byte long value. Hence 14 bytes consumed by a property pair. Another two bytes is +used to show the next property pair, so the total size (16 byte) is divisible by 8. #### Property Hashmap diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c index adb644f97..1b7d9a6dc 100644 --- a/jerry-core/debugger/debugger.c +++ b/jerry-core/debugger/debugger.c @@ -1482,8 +1482,7 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /** property_p = ecma_find_named_property (ecma_get_object_from_value (exception_obj_value), ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE)); - if (property_p == NULL - || ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA) + if (property_p == NULL || !(*property_p & ECMA_PROPERTY_FLAG_DATA)) { return ecma_stringbuilder_finalize (&builder); } diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index 0e013c1fb..d62c5a1cb 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -25,6 +25,7 @@ #include "ecma-globals.h" #include "ecma-gc.h" #include "ecma-helpers.h" +#include "ecma-lcache.h" #include "ecma-objects.h" #include "ecma-property-hashmap.h" #include "ecma-proxy-object.h" @@ -223,9 +224,9 @@ ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pa { uint8_t property = property_pair_p->header.types[index]; - switch (ECMA_PROPERTY_GET_TYPE (property)) + if (JERRY_LIKELY (ECMA_PROPERTY_IS_RAW (property))) { - case ECMA_PROPERTY_TYPE_NAMEDDATA: + if (property & ECMA_PROPERTY_FLAG_DATA) { ecma_value_t value = property_pair_p->values[index].value; @@ -233,59 +234,53 @@ ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pa { ecma_gc_set_object_visited (ecma_get_object_from_value (value)); } - break; + continue; } - case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: + + ecma_property_value_t *accessor_objs_p = property_pair_p->values + index; + + ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (accessor_objs_p); + + if (get_set_pair_p->getter_cp != JMEM_CP_NULL) { - ecma_property_value_t *accessor_objs_p = property_pair_p->values + index; - - ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (accessor_objs_p); - - if (get_set_pair_p->getter_cp != JMEM_CP_NULL) - { - ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp)); - } - - if (get_set_pair_p->setter_cp != JMEM_CP_NULL) - { - ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp)); - } - break; + ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp)); } - case ECMA_PROPERTY_TYPE_INTERNAL: + + if (get_set_pair_p->setter_cp != JMEM_CP_NULL) { - JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC - && property_pair_p->names_cp[index] >= LIT_INTERNAL_MAGIC_STRING_FIRST_DATA - && property_pair_p->names_cp[index] < LIT_MAGIC_STRING__COUNT); + ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp)); + } + + continue; + } + + if (!ECMA_PROPERTY_IS_INTERNAL (property)) + { + JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_DELETED + || property == ECMA_PROPERTY_TYPE_HASHMAP); + continue; + } + + JERRY_ASSERT (property_pair_p->names_cp[index] >= LIT_INTERNAL_MAGIC_STRING_FIRST_DATA + && property_pair_p->names_cp[index] < LIT_MAGIC_STRING__COUNT); #if ENABLED (JERRY_ESNEXT) - if (property_pair_p->names_cp[index] == LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD) - { - ecma_environment_record_t *environment_record_p; - environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t, - property_pair_p->values[index].value); + if (property_pair_p->names_cp[index] == LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD) + { + ecma_environment_record_t *environment_record_p; + environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t, + property_pair_p->values[index].value); - if (environment_record_p->this_binding != ECMA_VALUE_UNINITIALIZED) - { - JERRY_ASSERT (ecma_is_value_object (environment_record_p->this_binding)); - ecma_gc_set_object_visited (ecma_get_object_from_value (environment_record_p->this_binding)); - } - - JERRY_ASSERT (ecma_is_value_object (environment_record_p->function_object)); - ecma_gc_set_object_visited (ecma_get_object_from_value (environment_record_p->function_object)); - } -#endif /* ENABLED (JERRY_ESNEXT) */ - break; - } - default: + if (environment_record_p->this_binding != ECMA_VALUE_UNINITIALIZED) { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_SPECIAL); - - JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_HASHMAP - || property == ECMA_PROPERTY_TYPE_DELETED); - break; + JERRY_ASSERT (ecma_is_value_object (environment_record_p->this_binding)); + ecma_gc_set_object_visited (ecma_get_object_from_value (environment_record_p->this_binding)); } + + JERRY_ASSERT (ecma_is_value_object (environment_record_p->function_object)); + ecma_gc_set_object_visited (ecma_get_object_from_value (environment_record_p->function_object)); } +#endif /* ENABLED (JERRY_ESNEXT) */ } } /* ecma_gc_mark_properties */ @@ -1311,65 +1306,73 @@ ecma_gc_free_properties (ecma_object_t *object_p) /**< object */ ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i); jmem_cpointer_t name_cp = prop_pair_p->names_cp[i]; - if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL) + if (*property_p == ECMA_PROPERTY_TYPE_DELETED) { - JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC); + continue; + } - /* Call the native's free callback. */ - switch (name_cp) - { + if (!ECMA_PROPERTY_IS_INTERNAL (*property_p)) + { + ecma_free_property (object_p, name_cp, property_p); + continue; + } + + /* Call the native's free callback. */ + switch (name_cp) + { #if ENABLED (JERRY_ESNEXT) - case LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD: - { - ecma_environment_record_t *environment_record_p; - environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t, + case LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD: + { + ecma_environment_record_t *environment_record_p; + environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t, prop_pair_p->values[i].value); - jmem_heap_free_block (environment_record_p, sizeof (ecma_environment_record_t)); - break; - } - case LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED: - { - ecma_value_t *compact_collection_p; - compact_collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t, + jmem_heap_free_block (environment_record_p, sizeof (ecma_environment_record_t)); + break; + } + case LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED: + { + ecma_value_t *compact_collection_p; + compact_collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t, prop_pair_p->values[i].value); - ecma_compact_collection_free (compact_collection_p); - break; - } + ecma_compact_collection_free (compact_collection_p); + break; + } #endif /* ENABLED (JERRY_ESNEXT) */ #if ENABLED (JERRY_BUILTIN_WEAKMAP) || ENABLED (JERRY_BUILTIN_WEAKSET) - case LIT_INTERNAL_MAGIC_STRING_WEAK_REFS: - { - ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, + case LIT_INTERNAL_MAGIC_STRING_WEAK_REFS: + { + ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, prop_pair_p->values[i].value); - for (uint32_t j = 0; j < refs_p->item_count; j++) - { - const ecma_value_t value = refs_p->buffer_p[j]; - if (!ecma_is_value_empty (value)) - { - ecma_object_t *container_p = ecma_get_object_from_value (value); - - ecma_op_container_remove_weak_entry (container_p, - ecma_make_object_value (object_p)); - } - } - - ecma_collection_destroy (refs_p); - break; - } -#endif /* ENABLED (JERRY_BUILTIN_WEAKMAP) || ENABLED (JERRY_BUILTIN_WEAKSET) */ - default: + for (uint32_t j = 0; j < refs_p->item_count; j++) { - JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); - ecma_gc_free_native_pointer (property_p); - break; + const ecma_value_t value = refs_p->buffer_p[j]; + if (!ecma_is_value_empty (value)) + { + ecma_object_t *container_p = ecma_get_object_from_value (value); + + ecma_op_container_remove_weak_entry (container_p, + ecma_make_object_value (object_p)); + } } + + ecma_collection_destroy (refs_p); + break; + } +#endif /* ENABLED (JERRY_BUILTIN_WEAKMAP) || ENABLED (JERRY_BUILTIN_WEAKSET) */ + default: + { + JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); + ecma_gc_free_native_pointer (property_p); + break; } } - if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED) +#if ENABLED (JERRY_LCACHE) + if (ecma_is_property_lcached (property_p)) { - ecma_free_property (object_p, name_cp, property_p); + ecma_lcache_invalidate (object_p, name_cp, property_p); } +#endif /* ENABLED (JERRY_LCACHE) */ } prop_iter_cp = prop_iter_p->next_property_cp; diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 7b5cfac12..d85759f0a 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -349,20 +349,6 @@ typedef struct * Example for other items is property name hash map, or array of items. */ -/** - * Property type list. - */ -typedef enum -{ - ECMA_PROPERTY_TYPE_SPECIAL, /**< special purpose property (deleted / hashmap) */ - ECMA_PROPERTY_TYPE_NAMEDDATA, /**< property is named data */ - ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< property is named accessor */ - ECMA_PROPERTY_TYPE_INTERNAL, /**< internal property with custom data field */ - ECMA_PROPERTY_TYPE_VIRTUAL = ECMA_PROPERTY_TYPE_INTERNAL, /**< property is virtual data property */ - - ECMA_PROPERTY_TYPE__MAX = ECMA_PROPERTY_TYPE_VIRTUAL, /**< highest value for property types. */ -} ecma_property_types_t; - /** * Property name listing options. */ @@ -399,25 +385,20 @@ typedef enum #define ECMA_LIST_ENUMERABLE_PROTOTYPE (ECMA_LIST_ENUMERABLE | ECMA_LIST_PROTOTYPE) /** - * Property type mask. - */ -#define ECMA_PROPERTY_TYPE_MASK 0x3 - -/** - * Property flags base shift. - */ -#define ECMA_PROPERTY_FLAG_SHIFT 2 - -/** - * Property flag list (for ECMA_PROPERTY_TYPE_NAMEDDATA - * and ECMA_PROPERTY_TYPE_NAMEDACCESSOR). + * Property flag list. Several flags are alias */ 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_FLAG_DELETED = 1u << 0, /**< property is deleted */ + ECMA_FAST_ARRAY_FLAG = 1u << 0, /**< array is fast array */ + ECMA_PROPERTY_FLAG_LCACHED = 1u << 1, /**< property is lcached */ +#if ENABLED (JERRY_ESNEXT) + ECMA_ARRAY_TEMPLATE_LITERAL = 1u << 1, /**< array is a template literal constructed by the parser */ +#endif /* ENABLED (JERRY_ESNEXT) */ + ECMA_PROPERTY_FLAG_CONFIGURABLE = 1u << 2, /**< property is configurable */ + ECMA_PROPERTY_FLAG_ENUMERABLE = 1u << 3, /**< property is enumerable */ + ECMA_PROPERTY_FLAG_WRITABLE = 1u << 4, /**< property is writable */ + ECMA_PROPERTY_FLAG_DATA = 1u << 5, /**< property contains data */ } ecma_property_flags_t; /** @@ -461,54 +442,19 @@ typedef enum /** * Shift for property name part. */ -#define ECMA_PROPERTY_NAME_TYPE_SHIFT (ECMA_PROPERTY_FLAG_SHIFT + 4) - -/** - * Convert data property to accessor property or accessor property to data property - */ -#define ECMA_CHANGE_PROPERTY_TYPE(property_p) \ - *(property_p) ^= ECMA_PROPERTY_TYPE_NAMEDACCESSOR ^ ECMA_PROPERTY_TYPE_NAMEDDATA; - -/** - * Convert data property to internal property. - */ -#define ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY(property_p) \ - *(property_p) = (uint8_t) (*(property_p) + (ECMA_PROPERTY_TYPE_INTERNAL - ECMA_PROPERTY_TYPE_NAMEDDATA)) - -/** - * Convert internal property to data property. - */ -#define ECMA_CONVERT_INTERNAL_PROPERTY_TO_DATA_PROPERTY(property_p) \ - *(property_p) = (uint8_t) (*(property_p) - (ECMA_PROPERTY_TYPE_INTERNAL - ECMA_PROPERTY_TYPE_NAMEDDATA)) - -/** - * Special property identifiers. - */ -typedef enum -{ - /* Note: when new special types are added - * ECMA_PROPERTY_IS_PROPERTY_PAIR must be updated as well. */ - ECMA_SPECIAL_PROPERTY_HASHMAP, /**< hashmap property */ - ECMA_SPECIAL_PROPERTY_DELETED, /**< deleted property */ - - ECMA_SPECIAL_PROPERTY__COUNT /**< Number of special property types */ -} ecma_special_property_id_t; - -/** - * Define special property type. - */ -#define ECMA_SPECIAL_PROPERTY_VALUE(type) \ - ((uint8_t) (ECMA_PROPERTY_TYPE_SPECIAL | ((type) << ECMA_PROPERTY_NAME_TYPE_SHIFT))) - -/** - * Type of deleted property. - */ -#define ECMA_PROPERTY_TYPE_DELETED ECMA_SPECIAL_PROPERTY_VALUE (ECMA_SPECIAL_PROPERTY_DELETED) +#define ECMA_PROPERTY_NAME_TYPE_SHIFT 6 /** * Type of hash-map property. */ -#define ECMA_PROPERTY_TYPE_HASHMAP ECMA_SPECIAL_PROPERTY_VALUE (ECMA_SPECIAL_PROPERTY_HASHMAP) +#define ECMA_PROPERTY_TYPE_HASHMAP \ + (ECMA_DIRECT_STRING_SPECIAL << ECMA_PROPERTY_NAME_TYPE_SHIFT) + +/** + * Type of deleted property. + */ +#define ECMA_PROPERTY_TYPE_DELETED \ + (ECMA_PROPERTY_FLAG_DELETED | (ECMA_DIRECT_STRING_SPECIAL << ECMA_PROPERTY_NAME_TYPE_SHIFT)) /** * Type of property not found. @@ -596,12 +542,6 @@ typedef struct jmem_cpointer_t names_cp[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< property name slots */ } ecma_property_pair_t; -/** - * Get property type. - */ -#define ECMA_PROPERTY_GET_TYPE(property) \ - ((ecma_property_types_t) ((property) & ECMA_PROPERTY_TYPE_MASK)) - /** * Get property name type. */ @@ -614,11 +554,55 @@ typedef struct #define ECMA_PROPERTY_IS_PROPERTY_PAIR(property_header_p) \ ((property_header_p)->types[0] != ECMA_PROPERTY_TYPE_HASHMAP) +/** + * Property value of all internal properties + */ +#define ECMA_PROPERTY_INTERNAL \ + (ECMA_PROPERTY_FLAG_DATA | (ECMA_DIRECT_STRING_SPECIAL << ECMA_PROPERTY_NAME_TYPE_SHIFT)) + +/** + * Checks whether a property is internal property + */ +#define ECMA_PROPERTY_IS_INTERNAL(property) ((property) >= ECMA_PROPERTY_INTERNAL) + +/** + * Checks whether a property is raw data or accessor property + */ +#define ECMA_PROPERTY_IS_RAW(property) \ + ((property) < (ECMA_DIRECT_STRING_SPECIAL << ECMA_PROPERTY_NAME_TYPE_SHIFT)) + +/** + * Checks whether a property is raw data property (should only be used in assertions) + */ +#define ECMA_PROPERTY_IS_RAW_DATA(property) \ + (((property) & ECMA_PROPERTY_FLAG_DATA) && (property) < ECMA_PROPERTY_INTERNAL) + +/** + * Create internal property. + */ +#define ECMA_CREATE_INTERNAL_PROPERTY(object_p, name_p, property_p, property_value_p) \ + do \ + { \ + (property_value_p) = ecma_create_named_data_property ((object_p), (name_p), 0, &(property_p)); \ + JERRY_ASSERT (*(property_p) == ECMA_PROPERTY_INTERNAL); \ + } \ + while (0) + +/** + * Property type of all virtual properties + */ +#define ECMA_PROPERTY_VIRTUAL ECMA_PROPERTY_INTERNAL + +/** + * Checks whether a property is virtual property + */ +#define ECMA_PROPERTY_IS_VIRTUAL(property) ECMA_PROPERTY_IS_INTERNAL(property) + /** * Returns true if the property is named property. */ #define ECMA_PROPERTY_IS_NAMED_PROPERTY(property) \ - (ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_SPECIAL) + ((property) < ECMA_PROPERTY_TYPE_HASHMAP || (property) >= ECMA_PROPERTY_INTERNAL) /** * Add the offset part to a property for computing its property data pointer. @@ -1024,17 +1008,6 @@ typedef struct ecma_native_handler_t native_handler_cb; /**< external function */ } ecma_native_function_t; -/** - * Flags for array.length_prop_and_hole_count - */ -typedef enum -{ - ECMA_FAST_ARRAY_FLAG = 1u << (ECMA_PROPERTY_NAME_TYPE_SHIFT + 0), -#if ENABLED (JERRY_ESNEXT) - ECMA_ARRAY_TEMPLATE_LITERAL = 1u << (ECMA_PROPERTY_NAME_TYPE_SHIFT + 1), -#endif /* ENABLED (JERRY_ESNEXT) */ -} ecma_array_length_prop_and_hole_count_flags_t; - /** * Alignment for the fast access mode array length. * The real length is aligned up for allocating the underlying buffer. @@ -1219,19 +1192,24 @@ typedef struct * - is_value_defined : true * - is_configurable_defined, is_writable_defined, is_enumerable_defined : true */ -#define ECMA_NAME_DATA_PROPERTY_DESCRIPTOR_BITS 0x3c0 +#define ECMA_NAME_DATA_PROPERTY_DESCRIPTOR_BITS ((uint16_t) (ECMA_PROP_IS_VALUE_DEFINED \ + | ECMA_PROP_IS_CONFIGURABLE_DEFINED \ + | ECMA_PROP_IS_ENUMERABLE_DEFINED \ + | ECMA_PROP_IS_WRITABLE_DEFINED)) /** * Bitmask to get a the physical property flags from an ecma_property_descriptor */ -#define ECMA_PROPERTY_FLAGS_MASK 0x1c +#define ECMA_PROPERTY_FLAGS_MASK ((uint16_t) (ECMA_PROP_IS_CONFIGURABLE \ + | ECMA_PROP_IS_ENUMERABLE \ + | ECMA_PROP_IS_WRITABLE)) /** * Flag that controls failure handling during defining property * * Note: This flags represents the [[DefineOwnProperty]] (P, Desc, Throw) 3rd argument */ -#define ECMA_IS_THROW (1 << 5) +#define ECMA_IS_THROW ((uint8_t) ECMA_PROP_IS_THROW) #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** @@ -1525,7 +1503,7 @@ typedef enum ECMA_DIRECT_STRING_PTR = 0, /**< string is a string pointer, only used by property names */ ECMA_DIRECT_STRING_MAGIC = 1, /**< string is a magic string */ ECMA_DIRECT_STRING_UINT = 2, /**< string is an unsigned int */ - ECMA_DIRECT_STRING_ECMA_INTEGER = 3, /**< string is an ecma-integer */ + ECMA_DIRECT_STRING_SPECIAL = 3, /**< string is special */ } ecma_direct_string_type_t; /** diff --git a/jerry-core/ecma/base/ecma-helpers-external-pointers.c b/jerry-core/ecma/base/ecma-helpers-external-pointers.c index b79bf1f00..a04a0aaa1 100644 --- a/jerry-core/ecma/base/ecma-helpers-external-pointers.c +++ b/jerry-core/ecma/base/ecma-helpers-external-pointers.c @@ -38,7 +38,7 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create void *native_p, /**< native pointer */ void *info_p) /**< native pointer's type info */ { - ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); + ecma_string_t *name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); if (ecma_op_object_is_fast_array (obj_p)) { @@ -54,12 +54,9 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create if (property_p == NULL) { ecma_property_value_t *value_p; - value_p = ecma_create_named_data_property (obj_p, name_p, ECMA_PROPERTY_CONFIGURABLE_WRITABLE, &property_p); - - ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p); + ECMA_CREATE_INTERNAL_PROPERTY (obj_p, name_p, property_p, value_p); native_pointer_p = jmem_heap_alloc_block (sizeof (ecma_native_pointer_t)); - ECMA_SET_INTERNAL_VALUE_POINTER (value_p->value, native_pointer_p); } else @@ -121,7 +118,7 @@ ecma_get_native_pointer_value (ecma_object_t *obj_p, /**< object to get property return NULL; } - ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); + ecma_string_t *name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p); if (property_p == NULL) @@ -169,7 +166,7 @@ ecma_delete_native_pointer_property (ecma_object_t *obj_p, /**< object to delete return false; } - ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); + ecma_string_t *name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p); if (property_p == NULL) diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 6329b0b8d..89376e7d4 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -668,6 +668,21 @@ ecma_get_magic_string (lit_magic_string_id_t id) /**< identifier of magic string return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_MAGIC, (uintptr_t) id); } /* ecma_get_magic_string */ +/** + * Returns the constant assigned to the internal magic string id. + * + * Note: + * Calling ecma_deref_ecma_string on the returned pointer is optional. + * + * @return pointer to ecma-string descriptor + */ +extern inline ecma_string_t * JERRY_ATTR_ALWAYS_INLINE +ecma_get_internal_string (lit_magic_string_id_t id) /**< identifier of magic string */ +{ + JERRY_ASSERT (id >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT && id < LIT_MAGIC_STRING__COUNT); + return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_SPECIAL, (uintptr_t) id); +} /* ecma_get_internal_string */ + /** * Append a cesu8 string after an ecma-string * diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index d89129824..988fff497 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -37,9 +37,6 @@ * @{ */ -JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_MASK >= ECMA_PROPERTY_TYPE__MAX, - ecma_property_types_must_be_lower_than_the_container_mask); - JERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK >= ECMA_OBJECT_TYPE__MAX - 1, ecma_object_types_must_be_lower_than_the_container_mask); @@ -58,8 +55,8 @@ JERRY_STATIC_ASSERT (ECMA_OBJECT_REF_ONE == (ECMA_OBJECT_FLAG_EXTENSIBLE << 1), JERRY_STATIC_ASSERT (((ECMA_OBJECT_MAX_REF + ECMA_OBJECT_REF_ONE) | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX, ecma_object_max_ref_does_not_fill_the_remaining_bits); -JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_DELETED == (ECMA_DIRECT_STRING_MAGIC << ECMA_PROPERTY_NAME_TYPE_SHIFT), - ecma_property_type_deleted_must_have_magic_string_name_type); +JERRY_STATIC_ASSERT (ECMA_PROPERTY_FLAGS_MASK == ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, + ecma_property_flags_mask_must_use_the_configurable_enumerable_writable_flags); /** * Create an object with specified prototype object @@ -335,7 +332,7 @@ ecma_clone_decl_lexical_environment (ecma_object_t *lex_env_p, /**< declarative { if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED) { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW_DATA (prop_iter_p->types[i])); uint8_t prop_attributes = (uint8_t) (prop_iter_p->types[i] & ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); ecma_string_t *name_p = ecma_string_from_property_name (prop_iter_p->types[i], prop_pair_p->names_cp[i]); @@ -525,7 +522,7 @@ ecma_create_named_data_property (ecma_object_t *object_p, /**< object */ JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) == 0); - uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDDATA | prop_attributes; + uint8_t type_and_flags = ECMA_PROPERTY_FLAG_DATA | prop_attributes; ecma_property_value_t value; value.value = ECMA_VALUE_UNDEFINED; @@ -553,7 +550,7 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */ JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE) == 0); - uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDACCESSOR | prop_attributes; + uint8_t type_and_flags = prop_attributes; ecma_property_value_t value; #if ENABLED (JERRY_CPOINTER_32_BIT) @@ -571,7 +568,7 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */ } /* ecma_create_named_accessor_property */ /** - * Find named data property or named access property in specified object. + * Find named data property or named accessor property in a specified object. * * @return pointer to the property, if it is found, * NULL - otherwise. @@ -745,14 +742,16 @@ 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 - && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_IS_RAW_DATA (*property_p)); return ECMA_PROPERTY_VALUE_PTR (property_p); } /* ecma_get_named_data_property */ /** * Free property values and change their type to deleted. + * + * Note: + * internal properties are not supported */ void ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */ @@ -760,34 +759,20 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to ecma_property_t *property_p) /**< property */ { JERRY_ASSERT (object_p != NULL && property_p != NULL); + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); - switch (ECMA_PROPERTY_GET_TYPE (*property_p)) + if (*property_p & ECMA_PROPERTY_FLAG_DATA) + { + ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value); + } + else { - case ECMA_PROPERTY_TYPE_NAMEDDATA: - { - ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value); - break; - } - case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: - { #if ENABLED (JERRY_CPOINTER_32_BIT) - ecma_getter_setter_pointers_t *getter_setter_pair_p; - getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, - ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp); - jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t)); + ecma_getter_setter_pointers_t *getter_setter_pair_p; + getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, + ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp); + jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t)); #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ - break; - } - default: - { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL); - - /* Must be a native pointer. */ - JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC - && name_cp >= LIT_INTERNAL_MAGIC_STRING_FIRST_DATA - && name_cp < LIT_MAGIC_STRING__COUNT); - break; - } } #if ENABLED (JERRY_LCACHE) @@ -847,7 +832,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */ { if ((prop_pair_p->values + i) == prop_value_p) { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (cur_prop_p->types[i]) != ECMA_PROPERTY_TYPE_SPECIAL); + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (cur_prop_p->types[i])); #if ENABLED (JERRY_PROPRETY_HASHMAP) if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP) @@ -912,7 +897,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */ static void ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ecma-object */ const ecma_property_value_t *prop_value_p, /**< property value */ - ecma_property_types_t type) /**< expected property type */ + bool is_data) /**< property should be data property */ { #ifndef JERRY_NDEBUG jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp; @@ -937,7 +922,7 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec { if ((prop_pair_p->values + i) == prop_value_p) { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_pair_p->header.types[i]) == type); + JERRY_ASSERT (is_data == ((prop_pair_p->header.types[i] & ECMA_PROPERTY_FLAG_DATA) != 0)); return; } } @@ -947,7 +932,7 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec #else /* JERRY_NDEBUG */ JERRY_UNUSED (object_p); JERRY_UNUSED (prop_value_p); - JERRY_UNUSED (type); + JERRY_UNUSED (is_data); #endif /* !JERRY_NDEBUG */ } /* ecma_assert_object_contains_the_property */ @@ -962,7 +947,7 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */ ecma_property_value_t *prop_value_p, /**< property value reference */ ecma_value_t value) /**< value to assign */ { - ecma_assert_object_contains_the_property (obj_p, prop_value_p, ECMA_PROPERTY_TYPE_NAMEDDATA); + ecma_assert_object_contains_the_property (obj_p, prop_value_p, true); ecma_value_assign_value (&prop_value_p->value, value); } /* ecma_named_data_property_assign_value */ @@ -990,7 +975,7 @@ ecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the prope ecma_property_value_t *prop_value_p, /**< property value reference */ ecma_object_t *getter_p) /**< getter object */ { - ecma_assert_object_contains_the_property (object_p, prop_value_p, ECMA_PROPERTY_TYPE_NAMEDACCESSOR); + ecma_assert_object_contains_the_property (object_p, prop_value_p, false); #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; @@ -1010,7 +995,7 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope ecma_property_value_t *prop_value_p, /**< property value reference */ ecma_object_t *setter_p) /**< setter object */ { - ecma_assert_object_contains_the_property (object_p, prop_value_p, ECMA_PROPERTY_TYPE_NAMEDACCESSOR); + ecma_assert_object_contains_the_property (object_p, prop_value_p, false); #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; @@ -1031,8 +1016,7 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope inline bool JERRY_ATTR_ALWAYS_INLINE ecma_is_property_writable (ecma_property_t property) /**< property */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL); + JERRY_ASSERT (property & ECMA_PROPERTY_FLAG_DATA); return (property & ECMA_PROPERTY_FLAG_WRITABLE) != 0; } /* ecma_is_property_writable */ @@ -1044,7 +1028,7 @@ void ecma_set_property_writable_attr (ecma_property_t *property_p, /**< [in,out] property */ bool is_writable) /**< new value for writable flag */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW_DATA (*property_p)); if (is_writable) { @@ -1065,9 +1049,7 @@ ecma_set_property_writable_attr (ecma_property_t *property_p, /**< [in,out] prop inline bool JERRY_ATTR_ALWAYS_INLINE ecma_is_property_enumerable (ecma_property_t property) /**< property */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR - || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL); + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (property)); return (property & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0; } /* ecma_is_property_enumerable */ @@ -1079,8 +1061,7 @@ void ecma_set_property_enumerable_attr (ecma_property_t *property_p, /**< [in,out] property */ bool is_enumerable) /**< new value for enumerable flag */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); if (is_enumerable) { @@ -1101,9 +1082,7 @@ ecma_set_property_enumerable_attr (ecma_property_t *property_p, /**< [in,out] pr inline bool JERRY_ATTR_ALWAYS_INLINE ecma_is_property_configurable (ecma_property_t property) /**< property */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR - || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL); + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (property)); return (property & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0; } /* ecma_is_property_configurable */ @@ -1115,8 +1094,7 @@ void ecma_set_property_configurable_attr (ecma_property_t *property_p, /**< [in,out] property */ bool is_configurable) /**< new value for configurable flag */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); if (is_configurable) { @@ -1138,9 +1116,7 @@ ecma_set_property_configurable_attr (ecma_property_t *property_p, /**< [in,out] inline bool JERRY_ATTR_ALWAYS_INLINE ecma_is_property_lcached (ecma_property_t *property_p) /**< property */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR - || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL); + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*property_p)); return (*property_p & ECMA_PROPERTY_FLAG_LCACHED) != 0; } /* ecma_is_property_lcached */ @@ -1152,9 +1128,7 @@ inline void JERRY_ATTR_ALWAYS_INLINE ecma_set_property_lcached (ecma_property_t *property_p, /**< property */ bool is_lcached) /**< new value for lcached flag */ { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR - || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL); + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*property_p)); if (is_lcached) { diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 4be1c6596..98c4ca532 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -313,6 +313,7 @@ ecma_string_t *ecma_new_non_direct_string_from_uint32 (uint32_t uint32_number); ecma_string_t *ecma_get_ecma_string_from_uint32 (uint32_t uint32_number); ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t num); ecma_string_t *ecma_get_magic_string (lit_magic_string_id_t id); +ecma_string_t *ecma_get_internal_string (lit_magic_string_id_t id); ecma_string_t *ecma_append_chars_to_string (ecma_string_t *string1_p, const lit_utf8_byte_t *cesu8_string2_p, lit_utf8_size_t cesu8_string2_size, diff --git a/jerry-core/ecma/base/ecma-lcache.c b/jerry-core/ecma/base/ecma-lcache.c index 338fe1c66..b8a234cf4 100644 --- a/jerry-core/ecma/base/ecma-lcache.c +++ b/jerry-core/ecma/base/ecma-lcache.c @@ -91,9 +91,7 @@ ecma_lcache_insert (const ecma_object_t *object_p, /**< object */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (prop_p != NULL && !ecma_is_property_lcached (prop_p)); - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR - || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_INTERNAL); + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*prop_p)); jmem_cpointer_t object_cp; @@ -191,9 +189,7 @@ ecma_lcache_invalidate (const ecma_object_t *object_p, /**< object */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p)); - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR - || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_INTERNAL); + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*prop_p)); jmem_cpointer_t object_cp; ECMA_SET_NON_NULL_POINTER (object_cp, object_p); diff --git a/jerry-core/ecma/base/ecma-property-hashmap.c b/jerry-core/ecma/base/ecma-property-hashmap.c index f86829e30..64c9b6d91 100644 --- a/jerry-core/ecma/base/ecma-property-hashmap.c +++ b/jerry-core/ecma/base/ecma-property-hashmap.c @@ -93,10 +93,9 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { - ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]); - - if (type != ECMA_PROPERTY_TYPE_SPECIAL) + if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED) { + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i])); named_property_count++; } } @@ -148,11 +147,13 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { - if (!ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i])) + if (prop_iter_p->types[i] == ECMA_PROPERTY_TYPE_DELETED) { continue; } + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i])); + ecma_property_pair_t *property_pair_p = (ecma_property_pair_t *) prop_iter_p; uint32_t entry_index = ecma_string_get_property_name_hash (prop_iter_p->types[i], diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index f2d8e283b..d4fd5e41b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -485,7 +485,7 @@ ecma_instantiate_builtin (ecma_global_object_t *global_object_p, /**< global obj ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; ext_object_p->u.array.length = 0; - ext_object_p->u.array.length_prop_and_hole_count = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL; + ext_object_p->u.array.length_prop_and_hole_count = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_VIRTUAL; break; } #endif /* ENABLED (JERRY_BUILTIN_ARRAY) */ diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 084350daf..3a20a08a8 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -54,7 +54,8 @@ /** * Property name type flag for array indices. */ -#define ECMA_FAST_ARRAY_UINT32_DIRECT_STRING_PROP_TYPE 0x80 +#define ECMA_FAST_ARRAY_UINT_DIRECT_STRING_PROP_TYPE \ + (ECMA_DIRECT_STRING_UINT << ECMA_PROPERTY_NAME_TYPE_SHIFT) /** * Allocate a new array object with the given length @@ -82,7 +83,7 @@ ecma_op_alloc_array_object (uint32_t length) /**< length of the new array */ ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; ext_obj_p->u.array.length = length; - ext_obj_p->u.array.length_prop_and_hole_count = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL; + ext_obj_p->u.array.length_prop_and_hole_count = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_VIRTUAL; return object_p; } /* ecma_op_alloc_array_object */ @@ -342,9 +343,9 @@ ecma_fast_array_convert_to_normal (ecma_object_t *object_p) /**< fast access mod JERRY_ASSERT (index <= ECMA_DIRECT_STRING_MAX_IMM); property_pair_p->names_cp[prop_index] = (jmem_cpointer_t) index; - property_pair_p->header.types[prop_index] = (ecma_property_t) (ECMA_PROPERTY_TYPE_NAMEDDATA + property_pair_p->header.types[prop_index] = (ecma_property_t) (ECMA_PROPERTY_FLAG_DATA | ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE - | ECMA_FAST_ARRAY_UINT32_DIRECT_STRING_PROP_TYPE); + | ECMA_FAST_ARRAY_UINT_DIRECT_STRING_PROP_TYPE); property_pair_p->values[prop_index].value = values_p[index]; @@ -849,7 +850,7 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { - if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i]) + if (current_prop_p->types[i] != ECMA_PROPERTY_TYPE_DELETED && !ecma_is_property_configurable (current_prop_p->types[i])) { uint32_t index = ecma_string_get_property_index (current_prop_p->types[i], @@ -900,7 +901,7 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { - if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i]) + if (current_prop_p->types[i] != ECMA_PROPERTY_TYPE_DELETED && ecma_is_property_configurable (current_prop_p->types[i])) { uint32_t index = ecma_string_get_property_index (current_prop_p->types[i], diff --git a/jerry-core/ecma/operations/ecma-container-object.c b/jerry-core/ecma/operations/ecma-container-object.c index 6c269e556..bb06e726f 100644 --- a/jerry-core/ecma/operations/ecma-container-object.c +++ b/jerry-core/ecma/operations/ecma-container-object.c @@ -678,17 +678,15 @@ ecma_op_container_set_weak (ecma_object_t *const key_p, /**< key object */ ecma_fast_array_convert_to_normal (key_p); } - ecma_string_t *weak_refs_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_WEAK_REFS); + ecma_string_t *weak_refs_string_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_WEAK_REFS); ecma_property_t *property_p = ecma_find_named_property (key_p, weak_refs_string_p); ecma_collection_t *refs_p; if (property_p == NULL) { - ecma_property_value_t *value_p = ecma_create_named_data_property (key_p, - weak_refs_string_p, - ECMA_PROPERTY_CONFIGURABLE_WRITABLE, - &property_p); - ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p); + ecma_property_value_t *value_p; + ECMA_CREATE_INTERNAL_PROPERTY (key_p, weak_refs_string_p, property_p, value_p); + refs_p = ecma_new_collection (); ECMA_SET_INTERNAL_VALUE_POINTER (value_p->value, refs_p); } @@ -923,7 +921,7 @@ void ecma_op_container_unref_weak (ecma_object_t *object_p, /**< this argument */ ecma_value_t ref_holder) /**< key argument */ { - ecma_string_t *weak_refs_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_WEAK_REFS); + ecma_string_t *weak_refs_string_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_WEAK_REFS); ecma_property_t *property_p = ecma_find_named_property (object_p, weak_refs_string_p); JERRY_ASSERT (property_p != NULL); diff --git a/jerry-core/ecma/operations/ecma-lex-env.c b/jerry-core/ecma/operations/ecma-lex-env.c index 497302c73..db42d0f23 100644 --- a/jerry-core/ecma/operations/ecma-lex-env.c +++ b/jerry-core/ecma/operations/ecma-lex-env.c @@ -245,8 +245,7 @@ ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment { ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); - JERRY_ASSERT (property_p != NULL - && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_IS_RAW_DATA (*property_p)); if (ecma_is_property_writable (*property_p)) { @@ -365,7 +364,7 @@ ecma_op_delete_binding (ecma_object_t *lex_env_p, /**< lexical environment */ } else { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW_DATA (*prop_p)); if (!ecma_is_property_configurable (*prop_p)) { @@ -462,8 +461,7 @@ ecma_op_initialize_binding (ecma_object_t *lex_env_p, /**< lexical environment * JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); ecma_property_t *prop_p = ecma_find_named_property (lex_env_p, name_p); - JERRY_ASSERT (prop_p != NULL); - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (prop_p != NULL && ECMA_PROPERTY_IS_RAW_DATA (*prop_p)); ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (prop_p); JERRY_ASSERT (prop_value_p->value == ECMA_VALUE_UNINITIALIZED); @@ -490,14 +488,12 @@ ecma_op_create_environment_record (ecma_object_t *lex_env_p, /**< lexical enviro environment_record_p->this_binding = this_binding; environment_record_p->function_object = ecma_make_object_value (func_obj_p); - ecma_string_t *property_name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD); + ecma_string_t *property_name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD); ecma_property_t *property_p; - ecma_property_value_t *prop_value_p = ecma_create_named_data_property (lex_env_p, - property_name_p, - ECMA_PROPERTY_FIXED, - &property_p); - ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p); + ecma_property_value_t *prop_value_p; + ECMA_CREATE_INTERNAL_PROPERTY (lex_env_p, property_name_p, property_p, prop_value_p); + ECMA_SET_INTERNAL_VALUE_POINTER (prop_value_p->value, environment_record_p); } /* ecma_op_create_environment_record */ @@ -513,7 +509,7 @@ ecma_op_get_environment_record (ecma_object_t *lex_env_p) /**< lexical environme { JERRY_ASSERT (lex_env_p != NULL); - ecma_string_t *property_name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD); + ecma_string_t *property_name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD); while (true) { if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index 3b87c0ff2..bbc7f7a35 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -310,9 +310,14 @@ ecma_op_general_object_ordinary_value (ecma_object_t *obj_p, /**< the object */ } /* ecma_op_general_object_ordinary_value */ /** - * Special type for ecma_op_general_object_define_own_property. + * Special types for ecma_op_general_object_define_own_property. */ -#define ECMA_PROPERTY_TYPE_GENERIC ECMA_PROPERTY_TYPE_SPECIAL +typedef enum +{ + ECMA_OP_OBJECT_DEFINE_GENERIC = 1, /**< generic property */ + ECMA_OP_OBJECT_DEFINE_ACCESSOR = 0, /**< accessor property */ + ECMA_OP_OBJECT_DEFINE_DATA = ECMA_PROPERTY_FLAG_DATA /**< data property */ +} ecma_op_object_define_own_property_type_t; /** * [[DefineOwnProperty]] ecma general object's operation @@ -342,19 +347,19 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob JERRY_ASSERT (!ecma_op_object_is_fast_array (object_p)); JERRY_ASSERT (property_name_p != NULL); - ecma_property_types_t property_desc_type = ECMA_PROPERTY_TYPE_GENERIC; + uint8_t property_desc_type = ECMA_OP_OBJECT_DEFINE_GENERIC; if (property_desc_p->flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED)) { /* A property descriptor cannot be both named data and named accessor. */ JERRY_ASSERT ((property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) != (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)); - property_desc_type = ECMA_PROPERTY_TYPE_NAMEDDATA; + property_desc_type = ECMA_OP_OBJECT_DEFINE_DATA; } else if (property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) { JERRY_ASSERT (!(property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)); - property_desc_type = ECMA_PROPERTY_TYPE_NAMEDACCESSOR; + property_desc_type = ECMA_OP_OBJECT_DEFINE_ACCESSOR; } /* These three asserts ensures that a new property is created with the appropriate default flags. @@ -387,11 +392,11 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob /* 4. */ uint8_t prop_attributes = (uint8_t) (property_desc_p->flags & ECMA_PROPERTY_FLAGS_MASK); - if (property_desc_type != ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + if (property_desc_type != ECMA_OP_OBJECT_DEFINE_ACCESSOR) { /* a. */ - JERRY_ASSERT (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC - || property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (property_desc_type == ECMA_OP_OBJECT_DEFINE_GENERIC + || property_desc_type == ECMA_OP_OBJECT_DEFINE_DATA); ecma_property_value_t *new_prop_value_p = ecma_create_named_data_property (object_p, property_name_p, @@ -406,7 +411,6 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob else { /* b. */ - ecma_create_named_accessor_property (object_p, property_name_p, property_desc_p->get_p, @@ -419,13 +423,8 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob } /* 6. */ - ecma_property_types_t current_property_type = ECMA_PROPERTY_GET_TYPE (current_prop); const bool is_current_configurable = ecma_is_property_configurable (current_prop); - JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDDATA - || current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR - || current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL); - /* 7. a., b. */ bool is_enumerable = (property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE) != 0; if (!is_current_configurable @@ -433,20 +432,20 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob || ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED) && (is_enumerable != ecma_is_property_enumerable (current_prop))))) { - if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL) + if (ECMA_PROPERTY_IS_VIRTUAL (current_prop)) { ecma_free_value (ext_property_ref.property_ref.virtual_value); } return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); } - if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL) + if (ECMA_PROPERTY_IS_VIRTUAL (current_prop)) { JERRY_ASSERT (!is_current_configurable && !ecma_is_property_writable (current_prop)); ecma_value_t result = ECMA_VALUE_TRUE; - if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR + if (property_desc_type == ECMA_OP_OBJECT_DEFINE_ACCESSOR || (property_desc_p->flags & ECMA_PROP_IS_WRITABLE) || ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) && !ecma_op_same_value (property_desc_p->value, @@ -460,16 +459,16 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob } /* 8. */ - if (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC) + if (property_desc_type == ECMA_OP_OBJECT_DEFINE_GENERIC) { /* No action required. */ } - else if (JERRY_LIKELY (property_desc_type == current_property_type)) + else if (JERRY_LIKELY (property_desc_type == (current_prop & ECMA_PROPERTY_FLAG_DATA))) { /* If property is configurable, there is no need for checks. */ if (JERRY_UNLIKELY (!is_current_configurable)) { - if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (property_desc_type == ECMA_OP_OBJECT_DEFINE_DATA) { /* 10. a. i. & ii. */ if (!ecma_is_property_writable (current_prop) @@ -515,9 +514,9 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p; - if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + if (property_desc_type == ECMA_OP_OBJECT_DEFINE_ACCESSOR) { - JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (current_prop & ECMA_PROPERTY_FLAG_DATA); ecma_free_value_if_not_object (value_p->value); #if ENABLED (JERRY_CPOINTER_32_BIT) @@ -533,7 +532,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob } else { - JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); + JERRY_ASSERT (!(current_prop & ECMA_PROPERTY_FLAG_DATA)); #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, @@ -545,15 +544,15 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob /* Update flags */ ecma_property_t prop_flags = *(ext_property_ref.property_p); - prop_flags = (ecma_property_t) (prop_flags & ~(ECMA_PROPERTY_TYPE_MASK | ECMA_PROPERTY_FLAG_WRITABLE)); - prop_flags = (ecma_property_t) (prop_flags | property_desc_type); + prop_flags = (ecma_property_t) (prop_flags & ~ECMA_PROPERTY_FLAG_WRITABLE); + prop_flags ^= ECMA_PROPERTY_FLAG_DATA; *(ext_property_ref.property_p) = prop_flags; } /* 12. */ - if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (property_desc_type == ECMA_OP_OBJECT_DEFINE_DATA) { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW_DATA (*ext_property_ref.property_p)); if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) { @@ -567,9 +566,9 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob ecma_set_property_writable_attr (ext_property_ref.property_p, (property_desc_p->flags & ECMA_PROP_IS_WRITABLE)); } } - else if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + else if (property_desc_type == ECMA_OP_OBJECT_DEFINE_ACCESSOR) { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); + JERRY_ASSERT (!(*ext_property_ref.property_p & ECMA_PROPERTY_FLAG_DATA)); if (property_desc_p->flags & ECMA_PROP_IS_GET_DEFINED) { @@ -601,8 +600,6 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob return ECMA_VALUE_TRUE; } /* ecma_op_general_object_define_own_property */ -#undef ECMA_PROPERTY_TYPE_GENERIC - #if ENABLED (JERRY_ESNEXT) /** * The IsCompatiblePropertyDescriptor method for Proxy object internal methods diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index cbd0011fc..2dc872fa3 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -104,7 +104,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ property_ref_p->virtual_value = ecma_make_uint32_value (length); } - return ECMA_PROPERTY_TYPE_VIRTUAL; + return ECMA_PROPERTY_VIRTUAL; } uint32_t index = ecma_string_get_array_index (property_name_p); @@ -123,7 +123,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ property_ref_p->virtual_value = ecma_make_string_value (char_str_p); } - return ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_TYPE_VIRTUAL; + return ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_VIRTUAL; } } } @@ -141,7 +141,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ } uint32_t length_prop = ext_object_p->u.array.length_prop_and_hole_count; - return length_prop & (ECMA_PROPERTY_TYPE_VIRTUAL | ECMA_PROPERTY_FLAG_WRITABLE); + return length_prop & (ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_VIRTUAL); } if (ecma_op_array_is_fast_array (ext_object_p)) @@ -164,7 +164,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ property_ref_p->virtual_value = ecma_fast_copy_value (values_p[index]); } - return (ecma_property_t) (ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL); + return ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROPERTY_VIRTUAL; } } @@ -208,7 +208,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ ecma_fast_free_value (value); } - return ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL; + return ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROPERTY_VIRTUAL; } return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP; @@ -281,9 +281,9 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ property_ref_p->virtual_value = ecma_make_uint32_value (len); } - return ECMA_PROPERTY_TYPE_VIRTUAL; + return ECMA_PROPERTY_VIRTUAL; } - #endif /* !ENABLED (JERRY_ESNEXT) */ +#endif /* !ENABLED (JERRY_ESNEXT) */ /* Get prototype physical property. */ property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p); @@ -654,15 +654,15 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ } } + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); + ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); - if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (*property_p & ECMA_PROPERTY_FLAG_DATA) { return ecma_fast_copy_value (prop_value_p->value); } - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p); if (get_set_pair_p->getter_cp == JMEM_CP_NULL) @@ -1445,7 +1445,9 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ if (property_p != NULL) { - if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); + + if (*property_p & ECMA_PROPERTY_FLAG_DATA) { if (ecma_is_property_writable (*property_p)) { @@ -1466,8 +1468,6 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ } else { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - ecma_getter_setter_pointers_t *get_set_pair_p; get_set_pair_p = ecma_get_named_accessor_property (ECMA_PROPERTY_VALUE_PTR (property_p)); setter_cp = get_set_pair_p->setter_cp; @@ -1512,7 +1512,9 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ if (inherited_property != ECMA_PROPERTY_TYPE_NOT_FOUND && inherited_property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP) { - if (ECMA_PROPERTY_GET_TYPE (inherited_property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (inherited_property)); + + if (!(inherited_property & ECMA_PROPERTY_FLAG_DATA)) { setter_cp = ecma_get_named_accessor_property (property_ref.value_p)->setter_cp; create_new_property = false; @@ -1882,17 +1884,14 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob prop_desc_p->flags = (uint16_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE_DEFINED | flags); - ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (property); - - if (type != ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + if (property & ECMA_PROPERTY_FLAG_DATA) { - if (type == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (!ECMA_PROPERTY_IS_VIRTUAL (property)) { prop_desc_p->value = ecma_copy_value (property_ref.value_p->value); } else { - JERRY_ASSERT (type == ECMA_PROPERTY_TYPE_VIRTUAL); prop_desc_p->value = property_ref.virtual_value; } @@ -1902,7 +1901,6 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob } else { - ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (property_ref.value_p); prop_desc_p->flags |= (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED); @@ -2413,18 +2411,14 @@ ecma_op_object_own_property_keys (ecma_object_t *obj_p) /**< object */ { ecma_property_t *property_p = prop_iter_p->types + i; - if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA - || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + if (ECMA_PROPERTY_IS_RAW (*property_p)) { ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; - if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC - && prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT - && prop_pair_p->names_cp[i] < LIT_MAGIC_STRING__COUNT) - { - /* Internal properties are never enumerated. */ - continue; - } + /* Internal properties are special properties so they must not be present. */ + JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) != ECMA_DIRECT_STRING_MAGIC + || prop_pair_p->names_cp[i] < LIT_NON_INTERNAL_MAGIC_STRING__COUNT + || prop_pair_p->names_cp[i] >= LIT_MAGIC_STRING__COUNT); ecma_string_t *name_p = ecma_string_from_property_name (*property_p, prop_pair_p->names_cp[i]); diff --git a/jerry-core/ecma/operations/ecma-reference.c b/jerry-core/ecma/operations/ecma-reference.c index 3eef74aa6..310e8e861 100644 --- a/jerry-core/ecma/operations/ecma-reference.c +++ b/jerry-core/ecma/operations/ecma-reference.c @@ -334,15 +334,15 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical if (property_p != NULL) { + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); + ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); - if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (*property_p & ECMA_PROPERTY_FLAG_DATA) { return ecma_fast_copy_value (prop_value_p->value); } - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p); if (get_set_pair_p->getter_cp == JMEM_CP_NULL) diff --git a/jerry-core/parser/js/js-parser-tagged-template-literal.c b/jerry-core/parser/js/js-parser-tagged-template-literal.c index 90f436087..ae09965df 100644 --- a/jerry-core/parser/js/js-parser-tagged-template-literal.c +++ b/jerry-core/parser/js/js-parser-tagged-template-literal.c @@ -113,7 +113,7 @@ parser_new_tagged_template_literal (ecma_object_t **raw_strings_p) /**< [out] ra ecma_extended_object_t *template_ext_obj_p = (ecma_extended_object_t *) template_obj_p; ecma_extended_object_t *raw_ext_obj_p = (ecma_extended_object_t *) *raw_strings_p; - const uint8_t flags = ECMA_PROPERTY_TYPE_VIRTUAL | ECMA_PROPERTY_FLAG_WRITABLE | ECMA_FAST_ARRAY_FLAG; + const uint8_t flags = ECMA_PROPERTY_VIRTUAL | ECMA_PROPERTY_FLAG_WRITABLE | ECMA_FAST_ARRAY_FLAG; JERRY_ASSERT (template_ext_obj_p->u.array.length_prop_and_hole_count == flags); JERRY_ASSERT (raw_ext_obj_p->u.array.length_prop_and_hole_count == flags); diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 7a7eca434..3028d71bb 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -148,9 +148,11 @@ opfunc_set_data_property (ecma_object_t *object_p, /**< object */ } else { + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); + prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); - if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + if (!(*property_p & ECMA_PROPERTY_FLAG_DATA)) { #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; @@ -159,8 +161,7 @@ opfunc_set_data_property (ecma_object_t *object_p, /**< object */ jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t)); #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ - ECMA_CHANGE_PROPERTY_TYPE (property_p); - *property_p = (uint8_t) (*property_p | ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); + *property_p |= ECMA_PROPERTY_FLAG_DATA | ECMA_PROPERTY_FLAG_WRITABLE; prop_value_p->value = ecma_copy_value_if_not_object (value); return; } @@ -208,9 +209,11 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */ } else { + JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p)); + ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); - if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (*property_p & ECMA_PROPERTY_FLAG_DATA) { #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; @@ -218,8 +221,7 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */ #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ ecma_free_value_if_not_object (prop_value_p->value); - ECMA_CHANGE_PROPERTY_TYPE (property_p); - *property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_WRITABLE); + *property_p = (uint8_t) (*property_p & ~(ECMA_PROPERTY_FLAG_DATA | ECMA_PROPERTY_FLAG_WRITABLE)); #if ENABLED (JERRY_CPOINTER_32_BIT) ECMA_SET_POINTER (getter_setter_pair_p->getter_cp, getter_func_p); @@ -1006,7 +1008,7 @@ opfunc_init_class_fields (ecma_value_t class_object, /**< the function itself */ shared_class_fields.header.status_flags = VM_FRAME_CTX_SHARED_HAS_CLASS_FIELDS; shared_class_fields.computed_class_fields_p = NULL; - name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); + name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); ecma_property_t *class_field_property_p = ecma_find_named_property (class_object_p, name_p); if (class_field_property_p != NULL) @@ -1048,7 +1050,7 @@ opfunc_init_static_class_fields (ecma_value_t function_object, /**< the function shared_class_fields.header.status_flags = VM_FRAME_CTX_SHARED_HAS_CLASS_FIELDS; shared_class_fields.computed_class_fields_p = NULL; - ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); + ecma_string_t *name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); ecma_object_t *function_object_p = ecma_get_object_from_value (function_object); ecma_property_t *class_field_property_p = ecma_find_named_property (function_object_p, name_p); @@ -1097,7 +1099,7 @@ opfunc_add_computed_field (ecma_value_t class_object, /**< class object */ name = ecma_make_string_value (prop_name_p); } - ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); + ecma_string_t *name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); ecma_object_t *class_object_p = ecma_get_object_from_value (class_object); ecma_property_t *property_p = ecma_find_named_property (class_object_p, name_p); @@ -1106,8 +1108,7 @@ opfunc_add_computed_field (ecma_value_t class_object, /**< class object */ if (property_p == NULL) { - property_value_p = ecma_create_named_data_property (class_object_p, name_p, ECMA_PROPERTY_FIXED, &property_p); - ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p); + ECMA_CREATE_INTERNAL_PROPERTY (class_object_p, name_p, property_p, property_value_p); compact_collection_p = ecma_new_compact_collection (); } else @@ -1452,7 +1453,15 @@ opfunc_set_class_attributes (ecma_object_t *obj_p, /**< object */ { uint8_t property = property_pair_p->header.types[index]; - if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (!ECMA_PROPERTY_IS_RAW (property)) + { + JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_DELETED + || (ECMA_PROPERTY_IS_INTERNAL (property) + && property_pair_p->names_cp[index] == LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED)); + continue; + } + + if (property & ECMA_PROPERTY_FLAG_DATA) { if (ecma_is_value_object (property_pair_p->values[index].value) && ecma_is_property_enumerable (property)) @@ -1460,29 +1469,22 @@ opfunc_set_class_attributes (ecma_object_t *obj_p, /**< object */ property_pair_p->header.types[index] = (uint8_t) (property & ~ECMA_PROPERTY_FLAG_ENUMERABLE); opfunc_set_home_object (ecma_get_object_from_value (property_pair_p->values[index].value), parent_env_p); } + continue; } - else if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) + + property_pair_p->header.types[index] = (uint8_t) (property & ~ECMA_PROPERTY_FLAG_ENUMERABLE); + ecma_property_value_t *accessor_objs_p = property_pair_p->values + index; + + ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (accessor_objs_p); + + if (get_set_pair_p->getter_cp != JMEM_CP_NULL) { - property_pair_p->header.types[index] = (uint8_t) (property & ~ECMA_PROPERTY_FLAG_ENUMERABLE); - ecma_property_value_t *accessor_objs_p = property_pair_p->values + index; - - ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (accessor_objs_p); - - if (get_set_pair_p->getter_cp != JMEM_CP_NULL) - { - opfunc_set_home_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp), parent_env_p); - } - - if (get_set_pair_p->setter_cp != JMEM_CP_NULL) - { - opfunc_set_home_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp), parent_env_p); - } + opfunc_set_home_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp), parent_env_p); } - else + + if (get_set_pair_p->setter_cp != JMEM_CP_NULL) { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_SPECIAL - || (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_INTERNAL - && property_pair_p->names_cp[index] == LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED)); + opfunc_set_home_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp), parent_env_p); } } diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index aecfbecf6..f0e32ab44 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -103,9 +103,9 @@ vm_op_get_value (ecma_value_t object, /**< base object */ #if ENABLED (JERRY_LCACHE) ecma_property_t *property_p = ecma_lcache_lookup (object_p, property_name_p); - if (property_p != NULL && - ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) + if (property_p != NULL && (*property_p & ECMA_PROPERTY_FLAG_DATA)) { + JERRY_ASSERT (!ECMA_PROPERTY_IS_INTERNAL (*property_p)); return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); } #endif /* ENABLED (JERRY_LCACHE) */ @@ -1696,8 +1696,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); ecma_property_t *property_p = ecma_find_named_property (frame_ctx_p->lex_env_p, name_p); - JERRY_ASSERT (property_p != NULL - && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); + JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_IS_RAW_DATA (*property_p)); JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p)->value == ECMA_VALUE_UNINITIALIZED); ECMA_PROPERTY_VALUE_PTR (property_p)->value = left_value; @@ -2090,7 +2089,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ NULL); property_value_p->value = left_value; - property_name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); + property_name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); ecma_property_t *property_p = ecma_find_named_property (object_p, property_name_p); if (property_p != NULL)