diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index d1ba37917..78b80cee5 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -2519,13 +2519,15 @@ jerry_get_prototype (const jerry_value_t obj_val) /**< object value */ return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); } - ecma_object_t *proto_obj_p = ecma_get_object_prototype (ecma_get_object_from_value (obj_val)); + ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); - if (proto_obj_p == NULL) + if (obj_p->u2.prototype_cp == JMEM_CP_NULL) { return ECMA_VALUE_NULL; } + ecma_object_t *proto_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_p->u2.prototype_cp); + return ecma_make_object_value (proto_obj_p); } /* jerry_get_prototype */ @@ -2547,15 +2549,15 @@ jerry_set_prototype (const jerry_value_t obj_val, /**< object value */ { return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); } + ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); if (ecma_is_value_null (proto_obj_val)) { - ECMA_SET_POINTER (ecma_get_object_from_value (obj_val)->prototype_or_outer_reference_cp, NULL); + obj_p->u2.prototype_cp = JMEM_CP_NULL; } else { - ECMA_SET_POINTER (ecma_get_object_from_value (obj_val)->prototype_or_outer_reference_cp, - ecma_get_object_from_value (proto_obj_val)); + ECMA_SET_NON_NULL_POINTER (obj_p->u2.prototype_cp, ecma_get_object_from_value (proto_obj_val)); } return ECMA_VALUE_TRUE; @@ -2575,15 +2577,19 @@ jerry_objects_foreach (jerry_objects_foreach_t foreach_p, /**< function pointer JERRY_ASSERT (foreach_p != NULL); - for (ecma_object_t *iter_p = ECMA_GET_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_gc_objects_cp)); - iter_p != NULL; - iter_p = ECMA_GET_POINTER (ecma_object_t, iter_p->gc_next_cp)) + jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp); + + while (iter_cp != JMEM_CP_NULL) { + ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp); + if (!ecma_is_lexical_environment (iter_p) && !foreach_p (ecma_make_object_value (iter_p), user_data_p)) { return true; } + + iter_cp = iter_p->gc_next_cp; } return false; @@ -2609,10 +2615,13 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i ecma_native_pointer_t *native_pointer_p; - for (ecma_object_t *iter_p = ECMA_GET_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_gc_objects_cp)); - iter_p != NULL; - iter_p = ECMA_GET_POINTER (ecma_object_t, iter_p->gc_next_cp)) + + jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp); + + while (iter_cp != JMEM_CP_NULL) { + ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp); + if (!ecma_is_lexical_environment (iter_p)) { native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p); @@ -2622,6 +2631,8 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i return true; } } + + iter_cp = iter_p->gc_next_cp; } return false; diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c index b306d39f8..3cd79e013 100644 --- a/jerry-core/debugger/debugger.c +++ b/jerry-core/debugger/debugger.c @@ -250,7 +250,7 @@ jerry_debugger_send_scope_chain (void) } else if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) { - if (ecma_get_lex_env_outer_reference (lex_env_p) == NULL) + if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL) { message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_GLOBAL; break; @@ -261,7 +261,8 @@ jerry_debugger_send_scope_chain (void) } } - lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); } message_type_p->type = JERRY_DEBUGGER_SCOPE_CHAIN_END; @@ -430,14 +431,14 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer while (chain_index != 0) { - lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); - - if (JERRY_UNLIKELY (lex_env_p == NULL)) + if (JERRY_UNLIKELY (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)) { jerry_debugger_send_type (JERRY_DEBUGGER_SCOPE_VARIABLES_END); return; } + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); + if ((ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) || (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)) { @@ -445,17 +446,17 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer } } - ecma_property_header_t *prop_iter_p; + jmem_cpointer_t prop_iter_cp; if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { - prop_iter_p = ecma_get_property_list (lex_env_p); + prop_iter_cp = lex_env_p->u1.property_list_cp; } else { JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); - prop_iter_p = ecma_get_property_list (binding_obj_p); + prop_iter_cp = binding_obj_p->u1.property_list_cp; } JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_string_p); @@ -463,8 +464,9 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer size_t buffer_pos = 0; - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; @@ -513,8 +515,7 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES_END; @@ -1409,10 +1410,16 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /** { ecma_object_t *object_p = ecma_get_object_from_value (exception_obj_value); - ecma_object_t *prototype_p = ecma_get_object_prototype (object_p); + jmem_cpointer_t prototype_cp = object_p->u2.prototype_cp; - if (prototype_p == NULL - || ecma_get_object_type (prototype_p) != ECMA_OBJECT_TYPE_GENERAL + if (prototype_cp == JMEM_CP_NULL) + { + return NULL; + } + + ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp); + + if (ecma_get_object_type (prototype_p) != ECMA_OBJECT_TYPE_GENERAL || !ecma_get_object_is_builtin (prototype_p)) { return NULL; diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index ec6f3c9a4..d40c3c3f6 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -53,20 +53,6 @@ * the object is marked at the first time. */ -/** - * Get next object in list of objects with same generation. - * - * @return pointer to the next ecma-object - * NULL - if there is no next ecma-object - */ -static inline ecma_object_t * -ecma_gc_get_object_next (ecma_object_t *object_p) /**< object */ -{ - JERRY_ASSERT (object_p != NULL); - - return ECMA_GET_POINTER (ecma_object_t, object_p->gc_next_cp); -} /* ecma_gc_get_object_next */ - /** * Get visited flag of the object. * @@ -141,59 +127,61 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */ /** * Mark referenced object from property */ -static void -ecma_gc_mark_property (ecma_property_pair_t *property_pair_p, /**< property pair */ - uint32_t index) /**< property index */ +static inline void JERRY_ATTR_ALWAYS_INLINE +ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pair */ { - uint8_t property = property_pair_p->header.types[index]; - - switch (ECMA_PROPERTY_GET_TYPE (property)) + for (uint32_t index = 0; index < ECMA_PROPERTY_PAIR_ITEM_COUNT; index++) { - case ECMA_PROPERTY_TYPE_NAMEDDATA: - { - ecma_value_t value = property_pair_p->values[index].value; + uint8_t property = property_pair_p->header.types[index]; - if (ecma_is_value_object (value)) + switch (ECMA_PROPERTY_GET_TYPE (property)) + { + case ECMA_PROPERTY_TYPE_NAMEDDATA: { - ecma_object_t *value_obj_p = ecma_get_object_from_value (value); + ecma_value_t value = property_pair_p->values[index].value; - ecma_gc_set_object_visited (value_obj_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); + } + break; } - break; - } - case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: - { - ecma_property_value_t *accessor_objs_p = property_pair_p->values + index; - ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (accessor_objs_p); - ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (accessor_objs_p); - - if (getter_obj_p != NULL) + case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: { - ecma_gc_set_object_visited (getter_obj_p); - } + ecma_property_value_t *accessor_objs_p = property_pair_p->values + index; - if (setter_obj_p != NULL) + 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; + } + case ECMA_PROPERTY_TYPE_INTERNAL: { - ecma_gc_set_object_visited (setter_obj_p); + JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC + && property_pair_p->names_cp[index] >= LIT_FIRST_INTERNAL_MAGIC_STRING); + break; } - break; - } - case ECMA_PROPERTY_TYPE_INTERNAL: - { - JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC - && property_pair_p->names_cp[index] >= LIT_FIRST_INTERNAL_MAGIC_STRING); - break; - } - default: - { - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_SPECIAL); + default: + { + 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 (property == ECMA_PROPERTY_TYPE_HASHMAP + || property == ECMA_PROPERTY_TYPE_DELETED); + break; + } } } -} /* ecma_gc_mark_property */ +} /* ecma_gc_mark_properties */ #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) @@ -244,24 +232,32 @@ ecma_gc_mark_container_object (ecma_object_t *object_p) /**< object */ ecma_gc_set_object_visited (internal_obj_p); - ecma_property_header_t *prop_iter_p = ecma_get_property_list (internal_obj_p); + jmem_cpointer_t prop_iter_cp = internal_obj_p->u1.property_list_cp; - if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) +#if ENABLED (JERRY_PROPRETY_HASHMAP) + if (prop_iter_cp != JMEM_CP_NULL) { - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + prop_iter_cp); + if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + { + prop_iter_cp = prop_iter_p->next_property_cp; + } } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + ecma_gc_mark_properties ((ecma_property_pair_t *) prop_iter_p); + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; for (uint32_t i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) { ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i); - ecma_gc_mark_property ((ecma_property_pair_t *) prop_iter_p, i); if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR) { @@ -280,8 +276,7 @@ ecma_gc_mark_container_object (ecma_object_t *object_p) /**< object */ } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } } /* ecma_gc_mark_container_object */ @@ -298,10 +293,11 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ if (ecma_is_lexical_environment (object_p)) { - ecma_object_t *lex_env_p = ecma_get_lex_env_outer_reference (object_p); - if (lex_env_p != NULL) + jmem_cpointer_t outer_lex_env_cp = object_p->u2.outer_reference_cp; + + if (outer_lex_env_cp != JMEM_CP_NULL) { - ecma_gc_set_object_visited (lex_env_p); + ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, outer_lex_env_cp)); } if (ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) @@ -314,10 +310,11 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ } else { - ecma_object_t *proto_p = ecma_get_object_prototype (object_p); - if (proto_p != NULL) + jmem_cpointer_t proto_cp = object_p->u2.prototype_cp; + + if (proto_cp != JMEM_CP_NULL) { - ecma_gc_set_object_visited (proto_p); + ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp)); } switch (ecma_get_object_type (object_p)) @@ -478,23 +475,27 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ } } - ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); + jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp; - if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) +#if ENABLED (JERRY_PROPRETY_HASHMAP) + if (prop_iter_cp != JMEM_CP_NULL) { - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); + if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + { + prop_iter_cp = prop_iter_p->next_property_cp; + } } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); - ecma_gc_mark_property ((ecma_property_pair_t *) prop_iter_p, 0); - ecma_gc_mark_property ((ecma_property_pair_t *) prop_iter_p, 1); + ecma_gc_mark_properties ((ecma_property_pair_t *) prop_iter_p); - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } } /* ecma_gc_mark */ @@ -555,16 +556,24 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */ if (obj_is_not_lex_env || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { - ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); + jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp; - if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) +#if ENABLED (JERRY_PROPRETY_HASHMAP) + if (prop_iter_cp != JMEM_CP_NULL) { - ecma_property_hashmap_free (object_p); - prop_iter_p = ecma_get_property_list (object_p); + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + prop_iter_cp); + if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + { + ecma_property_hashmap_free (object_p); + prop_iter_cp = object_p->u1.property_list_cp; + } } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); /* Both cannot be deleted. */ @@ -591,8 +600,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */ } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; ecma_dealloc_property_pair (prop_pair_p); } @@ -910,7 +918,7 @@ ecma_gc_run (void) const jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp; JERRY_ASSERT (obj_prev_p == NULL - || ecma_gc_get_object_next (obj_prev_p) == obj_iter_p); + || ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_prev_p->gc_next_cp) == obj_iter_p); if (ecma_gc_is_object_visited (obj_iter_p)) { @@ -928,14 +936,15 @@ ecma_gc_run (void) obj_iter_cp = obj_next_cp; } - ecma_object_t *first_root_object_p = JMEM_CP_GET_POINTER (ecma_object_t, black_objects_cp); + jmem_cpointer_t first_root_object_cp = black_objects_cp; /* Mark root objects. */ - obj_iter_p = first_root_object_p; - while (obj_iter_p != NULL) + obj_iter_cp = first_root_object_cp; + while (obj_iter_cp != JMEM_CP_NULL) { + obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp); ecma_gc_mark (obj_iter_p); - obj_iter_p = ecma_gc_get_object_next (obj_iter_p); + obj_iter_cp = obj_iter_p->gc_next_cp; } /* Mark non-root objects. */ @@ -954,7 +963,7 @@ ecma_gc_run (void) const jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp; JERRY_ASSERT (obj_prev_p == NULL - || ecma_gc_get_object_next (obj_prev_p) == obj_iter_p); + || ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_prev_p->gc_next_cp) == obj_iter_p); if (ecma_gc_is_object_visited (obj_iter_p)) { @@ -978,29 +987,31 @@ ecma_gc_run (void) while (marked_anything_during_current_iteration); /* Sweep objects that are currently unmarked. */ - obj_iter_p = ecma_gc_get_object_next (&white_gray_list_head); + obj_iter_cp = white_gray_list_head.gc_next_cp; - while (obj_iter_p != NULL) + while (obj_iter_cp != JMEM_CP_NULL) { - ecma_object_t *obj_next_p = ecma_gc_get_object_next (obj_iter_p); + obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp); + jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp; JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p)); ecma_gc_free_object (obj_iter_p); - obj_iter_p = obj_next_p; + obj_iter_cp = obj_next_cp; } /* Reset the reference counter of non-root black objects. */ - obj_iter_p = JMEM_CP_GET_POINTER (ecma_object_t, black_objects_cp); + obj_iter_cp = black_objects_cp; JERRY_CONTEXT (ecma_gc_objects_cp) = black_objects_cp; - while (obj_iter_p != first_root_object_p) + while (obj_iter_cp != first_root_object_cp) { /* The reference counter must be 1. */ + obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp); ecma_deref_object (obj_iter_p); JERRY_ASSERT (obj_iter_p->type_flags_refs < ECMA_OBJECT_REF_ONE); - obj_iter_p = ecma_gc_get_object_next (obj_iter_p); + obj_iter_cp = obj_iter_p->gc_next_cp; } #if ENABLED (JERRY_BUILTIN_REGEXP) @@ -1065,23 +1076,34 @@ ecma_free_unused_memory (jmem_pressure_t pressure) /**< current pressure */ ecma_gc_run (); +#if ENABLED (JERRY_PROPRETY_HASHMAP) /* Free hashmaps of remaining objects. */ - ecma_object_t *obj_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_gc_objects_cp)); - while (obj_iter_p != NULL) + jmem_cpointer_t obj_iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp); + + while (obj_iter_cp != JMEM_CP_NULL) { + ecma_object_t *obj_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp); + if (!ecma_is_lexical_environment (obj_iter_p) || ecma_get_lex_env_type (obj_iter_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { - ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p); + jmem_cpointer_t prop_iter_cp = obj_iter_p->u1.property_list_cp; - if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + if (prop_iter_cp != JMEM_CP_NULL) { - ecma_property_hashmap_free (obj_iter_p); + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); + + if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + { + ecma_property_hashmap_free (obj_iter_p); + } } + } - obj_iter_p = ecma_gc_get_object_next (obj_iter_p); + obj_iter_cp = obj_iter_p->gc_next_cp; } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ jmem_pools_collect_empty (); return; diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 27720904f..8a7e77728 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -494,8 +494,8 @@ typedef struct */ typedef struct { - jmem_cpointer_t getter_p; /**< pointer to getter object */ - jmem_cpointer_t setter_p; /**< pointer to setter object */ + jmem_cpointer_t getter_cp; /**< compressed pointer to getter object */ + jmem_cpointer_t setter_cp; /**< compressed pointer to setter object */ } ecma_getter_setter_pointers_t; /** @@ -564,11 +564,6 @@ typedef struct #define ECMA_PROPERTY_VALUE_PTR(property_p) \ ((ecma_property_value_t *) ECMA_PROPERTY_VALUE_DATA_PTR (property_p)) -/** - * Depth limit for property search (maximum prototype chain depth). - */ -#define ECMA_PROPERTY_SEARCH_DEPTH_LIMIT 128 - /** * Property reference. It contains the value pointer * for real, and the value itself for virtual properties. @@ -744,10 +739,19 @@ typedef struct jmem_cpointer_t gc_next_cp; /** compressed pointer to property list or bound object */ - jmem_cpointer_t property_list_or_bound_object_cp; + union + { + jmem_cpointer_t property_list_cp; /**< compressed pointer to object's + * or declerative lexical environments's property list */ + jmem_cpointer_t bound_object_cp; /**< compressed pointer to lexical environments's the bound object */ + } u1; /** object prototype or outer reference */ - jmem_cpointer_t prototype_or_outer_reference_cp; + union + { + jmem_cpointer_t prototype_cp; /**< compressed pointer to the object's prototype */ + jmem_cpointer_t outer_reference_cp; /**< compressed pointer to the lexical environments's outer reference */ + } u2; } ecma_object_t; /** diff --git a/jerry-core/ecma/base/ecma-helpers-values-collection.c b/jerry-core/ecma/base/ecma-helpers-values-collection.c index 56cd5accb..14ba80119 100644 --- a/jerry-core/ecma/base/ecma-helpers-values-collection.c +++ b/jerry-core/ecma/base/ecma-helpers-values-collection.c @@ -56,16 +56,17 @@ void ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection's header */ uint32_t flags) /**< combination of ecma_collection_flag_t flags */ { - ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t, - header_p->first_chunk_cp); + jmem_cpointer_t chunk_cp = header_p->first_chunk_cp; jmem_pools_free (header_p, sizeof (ecma_collection_header_t)); - if (chunk_p == NULL) + if (chunk_cp == JMEM_CP_NULL) { return; } + ecma_collection_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t, chunk_cp); + do { ecma_value_t *item_p = chunk_p->items; @@ -110,7 +111,7 @@ ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< colle item_index = 0; chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t)); - ECMA_SET_POINTER (header_p->first_chunk_cp, chunk_p); + ECMA_SET_NON_NULL_POINTER (header_p->first_chunk_cp, chunk_p); header_p->last_chunk_cp = header_p->first_chunk_cp; } else @@ -129,7 +130,7 @@ ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< colle next_chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t)); chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS] = ecma_make_pointer_value ((void *) next_chunk_p); - ECMA_SET_POINTER (header_p->last_chunk_cp, next_chunk_p); + ECMA_SET_NON_NULL_POINTER (header_p->last_chunk_cp, next_chunk_p); chunk_p = next_chunk_p; } diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index 662a18e81..5fb085679 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -89,10 +89,9 @@ ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe ecma_init_gc_info (new_object_p); - new_object_p->property_list_or_bound_object_cp = JMEM_CP_NULL; + new_object_p->u1.property_list_cp = JMEM_CP_NULL; - ECMA_SET_POINTER (new_object_p->prototype_or_outer_reference_cp, - prototype_object_p); + ECMA_SET_POINTER (new_object_p->u2.prototype_cp, prototype_object_p); return new_object_p; } /* ecma_create_object */ @@ -117,10 +116,9 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer ecma_init_gc_info (new_lexical_environment_p); - new_lexical_environment_p->property_list_or_bound_object_cp = JMEM_CP_NULL; + new_lexical_environment_p->u1.property_list_cp = JMEM_CP_NULL; - ECMA_SET_POINTER (new_lexical_environment_p->prototype_or_outer_reference_cp, - outer_lexical_environment_p); + ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p); return new_lexical_environment_p; } /* ecma_create_decl_lex_env */ @@ -156,11 +154,10 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out ecma_init_gc_info (new_lexical_environment_p); - ECMA_SET_NON_NULL_POINTER (new_lexical_environment_p->property_list_or_bound_object_cp, + ECMA_SET_NON_NULL_POINTER (new_lexical_environment_p->u1.bound_object_cp, binding_obj_p); - ECMA_SET_POINTER (new_lexical_environment_p->prototype_or_outer_reference_cp, - outer_lexical_environment_p); + ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p); return new_lexical_environment_p; } /* ecma_create_object_lex_env */ @@ -230,22 +227,6 @@ ecma_get_object_type (const ecma_object_t *object_p) /**< object */ return (ecma_object_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK); } /* ecma_get_object_type */ -/** - * Get object's prototype. - * - * @return pointer to the prototype object - * NULL if there is no prototype - */ -inline ecma_object_t *JERRY_ATTR_PURE -ecma_get_object_prototype (const ecma_object_t *object_p) /**< object */ -{ - JERRY_ASSERT (object_p != NULL); - JERRY_ASSERT (!ecma_is_lexical_environment (object_p)); - - return ECMA_GET_POINTER (ecma_object_t, - object_p->prototype_or_outer_reference_cp); -} /* ecma_get_object_prototype */ - /** * Check if the object is a built-in object * @@ -317,40 +298,6 @@ ecma_get_lex_env_type (const ecma_object_t *object_p) /**< lexical environment * return (ecma_lexical_environment_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK); } /* ecma_get_lex_env_type */ -/** - * Get outer reference of lexical environment. - * - * @return pointer to the outer reference - */ -inline ecma_object_t *JERRY_ATTR_PURE -ecma_get_lex_env_outer_reference (const ecma_object_t *object_p) /**< lexical environment */ -{ - JERRY_ASSERT (object_p != NULL); - JERRY_ASSERT (ecma_is_lexical_environment (object_p)); - - return ECMA_GET_POINTER (ecma_object_t, - object_p->prototype_or_outer_reference_cp); -} /* ecma_get_lex_env_outer_reference */ - -/** - * Get object's/lexical environment's property list. - * - * See also: - * ecma_op_object_get_property_names - * - * @return pointer to the head of the property list - */ -inline ecma_property_header_t *JERRY_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_header_t, - object_p->property_list_or_bound_object_cp); -} /* ecma_get_property_list */ - /** * Get lexical environment's bound object. * @@ -368,8 +315,7 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); #endif /* ENABLED (JERRY_ES2015_CLASS) */ - return ECMA_GET_NON_NULL_POINTER (ecma_object_t, - object_p->property_list_or_bound_object_cp); + return ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u1.bound_object_cp); } /* ecma_get_lex_env_binding_object */ /** @@ -387,14 +333,18 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ * if this field is non-NULL */ { JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); + JERRY_ASSERT (name_p != NULL); + JERRY_ASSERT (object_p != NULL); - jmem_cpointer_t *property_list_head_p = &object_p->property_list_or_bound_object_cp; + jmem_cpointer_t *property_list_head_p = &object_p->u1.property_list_cp; if (*property_list_head_p != ECMA_NULL_POINTER) { /* If the first entry is free (deleted), it is reused. */ ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, *property_list_head_p); + +#if ENABLED (JERRY_PROPRETY_HASHMAP) bool has_hashmap = false; if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) @@ -404,6 +354,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ *property_list_head_p); has_hashmap = true; } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (first_property_p)); @@ -411,19 +362,10 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ { ecma_property_pair_t *first_property_pair_p = (ecma_property_pair_t *) first_property_p; - if (name_p == NULL) - { - first_property_pair_p->names_cp[0] = ECMA_NULL_POINTER; - } - else - { - ecma_property_t name_type; - first_property_pair_p->names_cp[0] = ecma_string_to_property_name (name_p, - &name_type); - type_and_flags = (ecma_property_t) (type_and_flags | name_type); - } - - first_property_p->types[0] = type_and_flags; + ecma_property_t name_type; + first_property_pair_p->names_cp[0] = ecma_string_to_property_name (name_p, + &name_type); + first_property_p->types[0] = (ecma_property_t) (type_and_flags | name_type); ecma_property_t *property_p = first_property_p->types + 0; @@ -436,18 +378,20 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ first_property_pair_p->values[0] = value; +#if ENABLED (JERRY_PROPRETY_HASHMAP) /* The property must be fully initialized before ecma_property_hashmap_insert * is called, because the insert operation may reallocate the hashmap, and * that triggers garbage collection which scans all properties of all objects. * A not fully initialized but queued property may cause a crash. */ - if (has_hashmap && name_p != NULL) + if (has_hashmap) { ecma_property_hashmap_insert (object_p, name_p, first_property_pair_p, 0); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ return first_property_pair_p->values + 0; } @@ -458,7 +402,8 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ /* Need to query property_list_head_p again and recheck the existennce * of property hasmap, because ecma_alloc_property_pair may delete them. */ - property_list_head_p = &object_p->property_list_or_bound_object_cp; + property_list_head_p = &object_p->u1.property_list_cp; +#if ENABLED (JERRY_PROPRETY_HASHMAP) bool has_hashmap = false; if (*property_list_head_p != ECMA_NULL_POINTER) @@ -472,25 +417,18 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ has_hashmap = true; } } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ /* Just copy the previous value (no need to decompress, compress). */ first_property_pair_p->header.next_property_cp = *property_list_head_p; first_property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED; first_property_pair_p->names_cp[0] = LIT_INTERNAL_MAGIC_STRING_DELETED; - if (name_p == NULL) - { - first_property_pair_p->names_cp[1] = ECMA_NULL_POINTER; - } - else - { - ecma_property_t name_type; - first_property_pair_p->names_cp[1] = ecma_string_to_property_name (name_p, - &name_type); - type_and_flags = (ecma_property_t) (type_and_flags | name_type); - } + ecma_property_t name_type; + first_property_pair_p->names_cp[1] = ecma_string_to_property_name (name_p, + &name_type); - first_property_pair_p->header.types[1] = type_and_flags; + first_property_pair_p->header.types[1] = (ecma_property_t) (type_and_flags | name_type); ECMA_SET_NON_NULL_POINTER (*property_list_head_p, &first_property_pair_p->header); @@ -505,15 +443,17 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ first_property_pair_p->values[1] = value; +#if ENABLED (JERRY_PROPRETY_HASHMAP) /* See the comment before the other ecma_property_hashmap_insert above. */ - if (has_hashmap && name_p != NULL) + if (has_hashmap) { ecma_property_hashmap_insert (object_p, name_p, first_property_pair_p, 1); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ return first_property_pair_p->values + 1; } /* ecma_create_property */ @@ -567,12 +507,12 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */ #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t)); - ECMA_SET_POINTER (getter_setter_pair_p->getter_p, get_p); - ECMA_SET_POINTER (getter_setter_pair_p->setter_p, set_p); - ECMA_SET_POINTER (value.getter_setter_pair_cp, getter_setter_pair_p); + ECMA_SET_POINTER (getter_setter_pair_p->getter_cp, get_p); + ECMA_SET_POINTER (getter_setter_pair_p->setter_cp, set_p); + ECMA_SET_NON_NULL_POINTER (value.getter_setter_pair_cp, getter_setter_pair_p); #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ - ECMA_SET_POINTER (value.getter_setter_pair.getter_p, get_p); - ECMA_SET_POINTER (value.getter_setter_pair.setter_p, set_p); + ECMA_SET_POINTER (value.getter_setter_pair.getter_cp, get_p); + ECMA_SET_POINTER (value.getter_setter_pair.setter_cp, set_p); #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p); @@ -601,31 +541,34 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in } #endif /* ENABLED (JERRY_LCACHE) */ - ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p); + jmem_cpointer_t prop_iter_cp = obj_p->u1.property_list_cp; #if ENABLED (JERRY_PROPRETY_HASHMAP) - if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + if (prop_iter_cp != JMEM_CP_NULL) { - jmem_cpointer_t property_real_name_cp; - property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p, - name_p, - &property_real_name_cp); - -#if ENABLED (JERRY_LCACHE) - if (property_p != NULL - && !ecma_is_property_lcached (property_p)) + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + prop_iter_cp); + if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { - ecma_lcache_insert (obj_p, property_real_name_cp, property_p); - } + jmem_cpointer_t property_real_name_cp; + property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p, + name_p, + &property_real_name_cp); +#if ENABLED (JERRY_LCACHE) + if (property_p != NULL + && !ecma_is_property_lcached (property_p)) + { + ecma_lcache_insert (obj_p, property_real_name_cp, property_p); + } #endif /* ENABLED (JERRY_LCACHE) */ - - return property_p; + return property_p; + } } #endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); - +#if ENABLED (JERRY_PROPRETY_HASHMAP) uint32_t steps = 0; +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ jmem_cpointer_t property_name_cp = ECMA_NULL_POINTER; if (ECMA_IS_DIRECT_STRING (name_p)) @@ -635,8 +578,11 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in JERRY_ASSERT (prop_name_type > 0); - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + prop_iter_cp); + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; @@ -659,16 +605,19 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in break; } +#if ENABLED (JERRY_PROPRETY_HASHMAP) steps++; - - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ + prop_iter_cp = prop_iter_p->next_property_cp; } } else { - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + prop_iter_cp); + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; @@ -697,17 +646,19 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in } } +#if ENABLED (JERRY_PROPRETY_HASHMAP) steps++; - - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ + prop_iter_cp = prop_iter_p->next_property_cp; } } +#if ENABLED (JERRY_PROPRETY_HASHMAP) if (steps >= (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 2)) { ecma_property_hashmap_create (obj_p); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ #if ENABLED (JERRY_LCACHE) if (property_p != NULL @@ -765,8 +716,8 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to { #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; - getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp); + 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; @@ -805,21 +756,32 @@ void ecma_delete_property (ecma_object_t *object_p, /**< object */ ecma_property_value_t *prop_value_p) /**< property value reference */ { - ecma_property_header_t *cur_prop_p = ecma_get_property_list (object_p); + jmem_cpointer_t cur_prop_cp = object_p->u1.property_list_cp; + ecma_property_header_t *prev_prop_p = NULL; + +#if ENABLED (JERRY_PROPRETY_HASHMAP) ecma_property_hashmap_delete_status hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_NO_HASHMAP; - if (cur_prop_p != NULL && cur_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + if (cur_prop_cp != JMEM_CP_NULL) { - prev_prop_p = cur_prop_p; - cur_prop_p = ECMA_GET_POINTER (ecma_property_header_t, - cur_prop_p->next_property_cp); - hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP; - } + ecma_property_header_t *cur_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + cur_prop_cp); - while (true) + if (cur_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + { + prev_prop_p = cur_prop_p; + cur_prop_cp = cur_prop_p->next_property_cp; + hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP; + } + } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ + + while (cur_prop_cp != JMEM_CP_NULL) { - JERRY_ASSERT (cur_prop_p != NULL); + ecma_property_header_t *cur_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + cur_prop_cp); + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (cur_prop_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) cur_prop_p; @@ -830,12 +792,14 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */ { JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (cur_prop_p->types[i]) != ECMA_PROPERTY_TYPE_SPECIAL); +#if ENABLED (JERRY_PROPRETY_HASHMAP) if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP) { hashmap_status = ecma_property_hashmap_delete (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i); cur_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED; @@ -845,12 +809,14 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */ if (cur_prop_p->types[1 - i] != ECMA_PROPERTY_TYPE_DELETED) { +#if ENABLED (JERRY_PROPRETY_HASHMAP) /* The other property is still valid. */ if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP) { ecma_property_hashmap_free (object_p); ecma_property_hashmap_create (object_p); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ return; } @@ -858,7 +824,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */ if (prev_prop_p == NULL) { - object_p->property_list_or_bound_object_cp = cur_prop_p->next_property_cp; + object_p->u1.property_list_cp = cur_prop_p->next_property_cp; } else { @@ -867,18 +833,19 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */ ecma_dealloc_property_pair ((ecma_property_pair_t *) cur_prop_p); +#if ENABLED (JERRY_PROPRETY_HASHMAP) if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP) { ecma_property_hashmap_free (object_p); ecma_property_hashmap_create (object_p); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ return; } } prev_prop_p = cur_prop_p; - cur_prop_p = ECMA_GET_POINTER (ecma_property_header_t, - cur_prop_p->next_property_cp); + cur_prop_cp = cur_prop_p->next_property_cp; } } /* ecma_delete_property */ @@ -897,21 +864,27 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ JERRY_ASSERT (new_length < old_length); /* First the minimum value of new_length is updated. */ - ecma_property_header_t *current_prop_p = ecma_get_property_list (object_p); + jmem_cpointer_t current_prop_cp = object_p->u1.property_list_cp; - if (current_prop_p == NULL) + if (current_prop_cp == JMEM_CP_NULL) { return new_length; } + ecma_property_header_t *current_prop_p; + +#if ENABLED (JERRY_PROPRETY_HASHMAP) + current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp); + if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { - current_prop_p = ECMA_GET_POINTER (ecma_property_header_t, - current_prop_p->next_property_cp); + current_prop_cp = current_prop_p->next_property_cp; } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - while (current_prop_p != NULL) + while (current_prop_cp != JMEM_CP_NULL) { + current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (current_prop_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) current_prop_p; @@ -939,25 +912,32 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ } } - current_prop_p = ECMA_GET_POINTER (ecma_property_header_t, - current_prop_p->next_property_cp); + current_prop_cp = current_prop_p->next_property_cp; } /* Second all properties between new_length and old_length are deleted. */ - current_prop_p = ecma_get_property_list (object_p); + current_prop_cp = object_p->u1.property_list_cp; ecma_property_header_t *prev_prop_p = NULL; + +#if ENABLED (JERRY_PROPRETY_HASHMAP) + JERRY_ASSERT (current_prop_cp != JMEM_CP_NULL); + ecma_property_hashmap_delete_status hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_NO_HASHMAP; + current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp); if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { prev_prop_p = current_prop_p; - current_prop_p = ECMA_GET_POINTER (ecma_property_header_t, - current_prop_p->next_property_cp); + current_prop_cp = current_prop_p->next_property_cp; hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP; } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - while (current_prop_p != NULL) + while (current_prop_cp != JMEM_CP_NULL) { + current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp); + + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (current_prop_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) current_prop_p; for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) @@ -972,12 +952,14 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ { JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX); +#if ENABLED (JERRY_PROPRETY_HASHMAP) if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP) { hashmap_status = ecma_property_hashmap_delete (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ ecma_free_property (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i); current_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED; @@ -991,31 +973,31 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ { if (prev_prop_p == NULL) { - object_p->property_list_or_bound_object_cp = current_prop_p->next_property_cp; + object_p->u1.property_list_cp = current_prop_p->next_property_cp; } else { prev_prop_p->next_property_cp = current_prop_p->next_property_cp; } - ecma_property_header_t *next_prop_p = ECMA_GET_POINTER (ecma_property_header_t, - current_prop_p->next_property_cp); + jmem_cpointer_t next_prop_cp = current_prop_p->next_property_cp; ecma_dealloc_property_pair ((ecma_property_pair_t *) current_prop_p); - current_prop_p = next_prop_p; + current_prop_cp = next_prop_cp; } else { prev_prop_p = current_prop_p; - current_prop_p = ECMA_GET_POINTER (ecma_property_header_t, - current_prop_p->next_property_cp); + current_prop_cp = current_prop_p->next_property_cp; } } +#if ENABLED (JERRY_PROPRETY_HASHMAP) if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP) { ecma_property_hashmap_free (object_p); ecma_property_hashmap_create (object_p); } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ return new_length; } /* ecma_delete_array_properties */ @@ -1029,19 +1011,20 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec ecma_property_types_t type) /**< expected property type */ { #ifndef JERRY_NDEBUG - ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); + jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp; + JERRY_ASSERT (prop_iter_cp != JMEM_CP_NULL); - JERRY_ASSERT (prop_iter_p != NULL); + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } - while (true) + while (prop_iter_cp != JMEM_CP_NULL) { - JERRY_ASSERT (prop_iter_p != NULL); + prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; @@ -1055,8 +1038,7 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } #else /* JERRY_NDEBUG */ JERRY_UNUSED (object_p); @@ -1082,40 +1064,19 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */ } /* ecma_named_data_property_assign_value */ /** - * Get getter of named accessor property + * Get named accessor property getter-setter-pair * - * @return pointer to object - getter of the property + * @return pointer to object's getter-setter pair */ -ecma_object_t * -ecma_get_named_accessor_property_getter (const ecma_property_value_t *prop_value_p) /**< property value reference */ +ecma_getter_setter_pointers_t * +ecma_get_named_accessor_property (const ecma_property_value_t *prop_value_p) /**< property value reference */ { #if ENABLED (JERRY_CPOINTER_32_BIT) - ecma_getter_setter_pointers_t *getter_setter_pair_p; - getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_value_p->getter_setter_pair_cp); - return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->getter_p); + return ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, prop_value_p->getter_setter_pair_cp); #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ - return ECMA_GET_POINTER (ecma_object_t, prop_value_p->getter_setter_pair.getter_p); + return (ecma_getter_setter_pointers_t *) &prop_value_p->getter_setter_pair; #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ -} /* ecma_get_named_accessor_property_getter */ - -/** - * Get setter of named accessor property - * - * @return pointer to object - setter of the property - */ -ecma_object_t * -ecma_get_named_accessor_property_setter (const ecma_property_value_t *prop_value_p) /**< property value reference */ -{ -#if ENABLED (JERRY_CPOINTER_32_BIT) - ecma_getter_setter_pointers_t *getter_setter_pair_p; - getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_value_p->getter_setter_pair_cp); - return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->setter_p); -#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ - return ECMA_GET_POINTER (ecma_object_t, prop_value_p->getter_setter_pair.setter_p); -#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ -} /* ecma_get_named_accessor_property_setter */ +} /* ecma_get_named_accessor_property */ /** * Set getter of named accessor property @@ -1129,11 +1090,11 @@ ecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the prope #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; - getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_value_p->getter_setter_pair_cp); - ECMA_SET_POINTER (getter_setter_pair_p->getter_p, getter_p); + getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, + prop_value_p->getter_setter_pair_cp); + ECMA_SET_POINTER (getter_setter_pair_p->getter_cp, getter_p); #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ - ECMA_SET_POINTER (prop_value_p->getter_setter_pair.getter_p, getter_p); + ECMA_SET_POINTER (prop_value_p->getter_setter_pair.getter_cp, getter_p); #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ } /* ecma_set_named_accessor_property_getter */ @@ -1149,11 +1110,11 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; - getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t, - prop_value_p->getter_setter_pair_cp); - ECMA_SET_POINTER (getter_setter_pair_p->setter_p, setter_p); + getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, + prop_value_p->getter_setter_pair_cp); + ECMA_SET_POINTER (getter_setter_pair_p->setter_cp, setter_p); #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ - ECMA_SET_POINTER (prop_value_p->getter_setter_pair.setter_p, setter_p); + ECMA_SET_POINTER (prop_value_p->getter_setter_pair.setter_cp, setter_p); #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ } /* ecma_set_named_accessor_property_setter */ diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index a3a047664..40d7dd35d 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -349,13 +349,11 @@ bool JERRY_ATTR_PURE ecma_is_lexical_environment (const ecma_object_t *object_p) bool JERRY_ATTR_PURE ecma_get_object_extensible (const ecma_object_t *object_p); void ecma_set_object_extensible (ecma_object_t *object_p, bool is_extensible); ecma_object_type_t JERRY_ATTR_PURE ecma_get_object_type (const ecma_object_t *object_p); -ecma_object_t JERRY_ATTR_PURE *ecma_get_object_prototype (const ecma_object_t *object_p); bool JERRY_ATTR_PURE ecma_get_object_is_builtin (const ecma_object_t *object_p); void ecma_set_object_is_builtin (ecma_object_t *object_p); uint8_t ecma_get_object_builtin_id (ecma_object_t *object_p); ecma_lexical_environment_type_t JERRY_ATTR_PURE ecma_get_lex_env_type (const ecma_object_t *object_p); ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_outer_reference (const ecma_object_t *object_p); -ecma_property_header_t JERRY_ATTR_PURE *ecma_get_property_list (const ecma_object_t *object_p); ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_binding_object (const ecma_object_t *object_p); ecma_property_value_t * @@ -377,8 +375,8 @@ uint32_t ecma_delete_array_properties (ecma_object_t *object_p, uint32_t new_len void ecma_named_data_property_assign_value (ecma_object_t *obj_p, ecma_property_value_t *prop_value_p, ecma_value_t value); -ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_value_t *prop_value_p); -ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_value_t *prop_value_p); +ecma_getter_setter_pointers_t * +ecma_get_named_accessor_property (const ecma_property_value_t *prop_value_p); void ecma_set_named_accessor_property_getter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p, ecma_object_t *getter_p); void ecma_set_named_accessor_property_setter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p, diff --git a/jerry-core/ecma/base/ecma-property-hashmap.c b/jerry-core/ecma/base/ecma-property-hashmap.c index c9434a1ce..74bfc39fa 100644 --- a/jerry-core/ecma/base/ecma-property-hashmap.c +++ b/jerry-core/ecma/base/ecma-property-hashmap.c @@ -65,8 +65,6 @@ static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF #define ECMA_PROPERTY_HASHMAP_SET_BIT(byte_p, index) \ ((byte_p)[(index) >> 3] = (uint8_t) ((byte_p)[(index) >> 3] | (1 << ((index) & 0x7)))) -#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - /** * Create a new property hashmap for the object. * The object must not have a property hashmap. @@ -74,25 +72,23 @@ static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF void ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ { -#if ENABLED (JERRY_PROPRETY_HASHMAP) if (JERRY_CONTEXT (ecma_prop_hashmap_alloc_state) != ECMA_PROP_HASHMAP_ALLOC_ON) { return; } - ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); + jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp; - if (prop_iter_p == NULL) + if (prop_iter_cp == JMEM_CP_NULL) { return; } - JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); - uint32_t named_property_count = 0; - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) @@ -104,8 +100,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ named_property_count++; } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } if (named_property_count < (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 2)) @@ -135,7 +130,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ hashmap_p->header.types[0] = ECMA_PROPERTY_TYPE_HASHMAP; hashmap_p->header.types[1] = 0; - hashmap_p->header.next_property_cp = object_p->property_list_or_bound_object_cp; + hashmap_p->header.next_property_cp = object_p->u1.property_list_cp; hashmap_p->max_property_count = max_property_count; hashmap_p->null_count = max_property_count - named_property_count; hashmap_p->unused_count = max_property_count - named_property_count; @@ -154,11 +149,12 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ hashmap_p->header.types[1] = shift_counter; - prop_iter_p = ecma_get_property_list (object_p); - ECMA_SET_POINTER (object_p->property_list_or_bound_object_cp, hashmap_p); + prop_iter_cp = object_p->u1.property_list_cp; + ECMA_SET_NON_NULL_POINTER (object_p->u1.property_list_cp, hashmap_p); - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) @@ -203,7 +199,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ #endif /* !JERRY_NDEBUG */ } - ECMA_SET_POINTER (pair_list_p[entry_index], property_pair_p); + ECMA_SET_NON_NULL_POINTER (pair_list_p[entry_index], property_pair_p); if (i != 0) { @@ -211,12 +207,8 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } -#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */ - JERRY_UNUSED (object_p); -#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ } /* ecma_property_hashmap_create */ /** @@ -226,21 +218,20 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ void ecma_property_hashmap_free (ecma_object_t *object_p) /**< object */ { -#if ENABLED (JERRY_PROPRETY_HASHMAP) /* Property hash must be exists and must be the first property. */ - ecma_property_header_t *property_p = ecma_get_property_list (object_p); + JERRY_ASSERT (object_p->u1.property_list_cp != JMEM_CP_NULL); - JERRY_ASSERT (property_p != NULL && property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP); + ecma_property_header_t *property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + object_p->u1.property_list_cp); + + JERRY_ASSERT (property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP); ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) property_p; - object_p->property_list_or_bound_object_cp = property_p->next_property_cp; + object_p->u1.property_list_cp = property_p->next_property_cp; jmem_heap_free_block (hashmap_p, ECMA_PROPERTY_HASHMAP_GET_TOTAL_SIZE (hashmap_p->max_property_count)); -#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */ - JERRY_UNUSED (object_p); -#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ } /* ecma_property_hashmap_free */ /** @@ -252,9 +243,10 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */ ecma_property_pair_t *property_pair_p, /**< property pair */ int property_index) /**< property index in the pair (0 or 1) */ { -#if ENABLED (JERRY_PROPRETY_HASHMAP) + JERRY_ASSERT (property_pair_p != NULL); + ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t, - object_p->property_list_or_bound_object_cp); + object_p->u1.property_list_cp); JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP); @@ -297,7 +289,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */ #endif /* !JERRY_NDEBUG */ } - ECMA_SET_POINTER (pair_list_p[entry_index], property_pair_p); + ECMA_SET_NON_NULL_POINTER (pair_list_p[entry_index], property_pair_p); uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count); bits_p += (entry_index >> 3); @@ -322,12 +314,6 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */ { *bits_p = (uint8_t) ((*bits_p) | mask); } -#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */ - JERRY_UNUSED (object_p); - JERRY_UNUSED (name_p); - JERRY_UNUSED (property_pair_p); - JERRY_UNUSED (property_index); -#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ } /* ecma_property_hashmap_insert */ /** @@ -341,9 +327,8 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */ jmem_cpointer_t name_cp, /**< property name */ ecma_property_t *property_p) /**< property */ { -#if ENABLED (JERRY_PROPRETY_HASHMAP) ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t, - object_p->property_list_or_bound_object_cp); + object_p->u1.property_list_cp); JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP); @@ -411,16 +396,8 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */ JERRY_ASSERT (entry_index != start_entry_index); #endif /* !JERRY_NDEBUG */ } -#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */ - JERRY_UNUSED (object_p); - JERRY_UNUSED (name_cp); - JERRY_UNUSED (property_p); - - return ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP; -#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ } /* ecma_property_hashmap_delete */ -#if ENABLED (JERRY_PROPRETY_HASHMAP) /** * Find a named property. * @@ -437,11 +414,12 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */ * from both data collection. The following code checks the property * chain, and sets the property_found variable. */ bool property_found = false; - ecma_property_header_t *prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - hashmap_p->header.next_property_cp); - while (prop_iter_p != NULL && !property_found) + jmem_cpointer_t prop_iter_cp = hashmap_p->header.next_property_cp; + + while (prop_iter_cp != JMEM_CP_NULL && !property_found) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; @@ -454,14 +432,14 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */ prop_pair_p->names_cp[i], name_p)) { + /* Property is found */ property_found = true; break; } } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } #endif /* !JERRY_NDEBUG */ diff --git a/jerry-core/ecma/base/ecma-property-hashmap.h b/jerry-core/ecma/base/ecma-property-hashmap.h index a22752af9..13b417468 100644 --- a/jerry-core/ecma/base/ecma-property-hashmap.h +++ b/jerry-core/ecma/base/ecma-property-hashmap.h @@ -53,6 +53,8 @@ typedef struct */ } ecma_property_hashmap_t; +#if ENABLED (JERRY_PROPRETY_HASHMAP) + /** * Simple ecma values */ @@ -70,7 +72,7 @@ void ecma_property_hashmap_insert (ecma_object_t *object_p, ecma_string_t *name_ ecma_property_hashmap_delete_status ecma_property_hashmap_delete (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *property_p); -#if ENABLED (JERRY_PROPRETY_HASHMAP) + ecma_property_t *ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, ecma_string_t *name_p, jmem_cpointer_t *property_real_name_cp); #endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c index 2a6539a9b..f5260043e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c @@ -143,10 +143,11 @@ ecma_builtin_object_object_get_prototype_of (ecma_value_t arg) /**< routine's ar } /* 2. */ ecma_object_t *obj_p = ecma_get_object_from_value (arg); - ecma_object_t *prototype_p = ecma_get_object_prototype (obj_p); + jmem_cpointer_t prototype_cp = obj_p->u2.prototype_cp; - if (prototype_p) + if (prototype_cp != JMEM_CP_NULL) { + ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp); ret_value = ecma_make_object_value (prototype_p); ecma_ref_object (prototype_p); } @@ -184,10 +185,21 @@ ecma_set_prototype_of (ecma_value_t o_value, /**< O */ JERRY_ASSERT (ecma_is_value_object (v_value) || ecma_is_value_null (v_value)); ecma_object_t *o_p = ecma_get_object_from_value (o_value); - ecma_object_t *v_p = ecma_is_value_null (v_value) ? NULL : ecma_get_object_from_value (v_value); + + jmem_cpointer_t v_cp; + + if (ecma_is_value_null (v_value)) + { + v_cp = JMEM_CP_NULL; + } + else + { + ECMA_SET_NON_NULL_POINTER (v_cp, ecma_get_object_from_value (v_value)); + } + /* 3., 4. */ - if (v_p == ecma_get_object_prototype (o_p)) + if (v_cp == o_p->u2.prototype_cp) { ecma_ref_object (o_p); return ecma_make_object_value (o_p); @@ -200,14 +212,10 @@ ecma_set_prototype_of (ecma_value_t o_value, /**< O */ } /* 6., 7., 8. */ - ecma_object_t *p_p = v_p; - while (true) + jmem_cpointer_t p_cp = v_cp; + while (p_cp != JMEM_CP_NULL) { - /* a. */ - if (p_p == NULL) - { - break; - } + ecma_object_t *p_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, p_cp); /* b. */ if (p_p == o_p) @@ -219,11 +227,11 @@ ecma_set_prototype_of (ecma_value_t o_value, /**< O */ * [[GetPrototypeOf]] internal method */ /* c.ii. */ - p_p = ecma_get_object_prototype (p_p); + p_cp = p_p->u2.prototype_cp; } /* 9. */ - ECMA_SET_POINTER (o_p->prototype_or_outer_reference_cp, v_p); + o_p->u2.prototype_cp = v_cp; /* 10. */ ecma_ref_object (o_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index d58403d3b..fd98cd8db 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -276,7 +276,9 @@ ecma_builtin_is (ecma_object_t *obj_p, /**< pointer to an object */ /* If a built-in object is not instantiated, its value is NULL, hence it cannot be equal to a valid object. */ - return (obj_p == ECMA_GET_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_builtin_objects)[builtin_id])); + jmem_cpointer_t builtin_cp = JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]; + + return (builtin_cp != JMEM_CP_NULL && (obj_p == ECMA_GET_NON_NULL_POINTER (ecma_object_t, builtin_cp))); } /* ecma_builtin_is */ /** diff --git a/jerry-core/ecma/operations/ecma-exceptions.c b/jerry-core/ecma/operations/ecma-exceptions.c index f1d34825a..19c013c6b 100644 --- a/jerry-core/ecma/operations/ecma-exceptions.c +++ b/jerry-core/ecma/operations/ecma-exceptions.c @@ -170,17 +170,20 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ ecma_standard_error_t ecma_get_error_type (ecma_object_t *error_object) /**< possible error object */ { - ecma_object_t *prototype_p = ecma_get_object_prototype (error_object); - if (prototype_p != NULL) + if (error_object->u2.prototype_cp == JMEM_CP_NULL) { - uint8_t builtin_id = ecma_get_object_builtin_id (prototype_p); + return ECMA_ERROR_NONE; + } - for (uint8_t idx = 0; idx < sizeof (ecma_error_mappings) / sizeof (ecma_error_mappings[0]); idx++) + ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, error_object->u2.prototype_cp); + + uint8_t builtin_id = ecma_get_object_builtin_id (prototype_p); + + for (uint8_t idx = 0; idx < sizeof (ecma_error_mappings) / sizeof (ecma_error_mappings[0]); idx++) + { + if (ecma_error_mappings[idx].error_prototype_id == builtin_id) { - if (ecma_error_mappings[idx].error_prototype_id == builtin_id) - { - return ecma_error_mappings[idx].error_type; - } + return ecma_error_mappings[idx].error_type; } } diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 22fd3270d..35bd9db8b 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -361,13 +361,15 @@ ecma_op_implicit_class_constructor_has_instance (ecma_object_t *func_obj_p, /**< while (true) { - v_obj_p = ecma_get_object_prototype (v_obj_p); + jmem_cpointer_t v_obj_cp = v_obj_p->u2.prototype_cp; - if (v_obj_p == NULL) + if (v_obj_cp == JMEM_CP_NULL) { break; } + v_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, v_obj_cp); + if (v_obj_p == prototype_obj_p) { ecma_deref_object (prototype_obj_p); @@ -451,13 +453,15 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object * while (true) { - v_obj_p = ecma_get_object_prototype (v_obj_p); + jmem_cpointer_t v_obj_cp = v_obj_p->u2.prototype_cp; - if (v_obj_p == NULL) + if (v_obj_cp == JMEM_CP_NULL) { break; } + v_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, v_obj_cp); + if (v_obj_p == prototype_obj_p) { result = ECMA_VALUE_TRUE; @@ -535,24 +539,30 @@ ecma_op_function_has_construct_flag (const ecma_value_t *arguments_list_p) /**< static ecma_object_t * ecma_op_find_super_declerative_lex_env (ecma_object_t *lex_env_p) /**< starting lexical enviroment */ { - JERRY_ASSERT (lex_env_p); + JERRY_ASSERT (lex_env_p != NULL); JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) != ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND); - while (lex_env_p != NULL) + while (true) { - ecma_object_t *lex_env_outer_p = ecma_get_lex_env_outer_reference (lex_env_p); + jmem_cpointer_t lex_env_outer_cp = lex_env_p->u2.outer_reference_cp; - if (lex_env_outer_p != NULL && - ecma_get_lex_env_type (lex_env_outer_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND) + if (lex_env_outer_cp != JMEM_CP_NULL) { - JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); - return lex_env_p; + ecma_object_t *lex_env_outer_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_outer_cp); + + if (ecma_get_lex_env_type (lex_env_outer_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND) + { + JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); + return lex_env_p; + } + + lex_env_p = lex_env_outer_p; + } + else + { + return NULL; } - - lex_env_p = lex_env_outer_p; } - - return NULL; } /* ecma_op_find_super_declerative_lex_env */ /** @@ -673,10 +683,11 @@ ecma_op_set_class_prototype (ecma_value_t completion_value, /**< completion_valu JERRY_ASSERT (ecma_is_value_object (this_arg)); ecma_object_t *completion_obj_p = ecma_get_object_from_value (completion_value); - ecma_object_t *prototype_obj_p = ecma_get_object_prototype (ecma_get_object_from_value (this_arg)); + jmem_cpointer_t prototype_obj_cp = ecma_get_object_from_value (this_arg)->u2.prototype_cp; - JERRY_ASSERT (prototype_obj_p); - ECMA_SET_POINTER (completion_obj_p->prototype_or_outer_reference_cp, prototype_obj_p); + JERRY_ASSERT (prototype_obj_cp != JMEM_CP_NULL); + + completion_obj_p->u2.prototype_cp = prototype_obj_cp; } /* ecma_op_set_class_prototype */ #endif /* ENABLED (JERRY_ES2015_CLASS) */ @@ -1143,7 +1154,9 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */ /* Catch the special case when a the class extends value in null and the class has no explicit constructor to raise TypeError.*/ JERRY_ASSERT (!ecma_op_function_has_construct_flag (arguments_list_p)); - JERRY_ASSERT (ecma_get_object_prototype (func_obj_p) == ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE)); + JERRY_ASSERT (func_obj_p->u2.prototype_cp != JMEM_CP_NULL); + JERRY_ASSERT ((ECMA_GET_NON_NULL_POINTER (ecma_object_t, func_obj_p->u2.prototype_cp) \ + == ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE))); ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Super constructor null is not a constructor.")); break; diff --git a/jerry-core/ecma/operations/ecma-get-put-value.c b/jerry-core/ecma/operations/ecma-get-put-value.c index de3982974..44b7f73da 100644 --- a/jerry-core/ecma/operations/ecma-get-put-value.c +++ b/jerry-core/ecma/operations/ecma-get-put-value.c @@ -50,7 +50,7 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme JERRY_ASSERT (lex_env_p != NULL && ecma_is_lexical_environment (lex_env_p)); - while (lex_env_p != NULL) + while (true) { switch (ecma_get_lex_env_type (lex_env_p)) { @@ -89,7 +89,12 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme } } - lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL) + { + break; + } + + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); } *ref_base_lex_env_p = NULL; @@ -147,10 +152,7 @@ ecma_op_get_value_object_base (ecma_value_t base_value, /**< base value */ ecma_value_t ret_value = ECMA_VALUE_UNDEFINED; - /* Circular reference is possible in JavaScript and testing it is complicated. */ - int max_depth = ECMA_PROPERTY_SEARCH_DEPTH_LIMIT; - - do + while (true) { ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p); @@ -160,14 +162,13 @@ ecma_op_get_value_object_base (ecma_value_t base_value, /**< base value */ break; } - if (--max_depth == 0) + if (object_p->u2.prototype_cp == JMEM_CP_NULL) { break; } - object_p = ecma_get_object_prototype (object_p); + object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp); } - while (object_p != NULL); ecma_free_value (object_base); @@ -191,7 +192,7 @@ ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme JERRY_ASSERT (lex_env_p != NULL && ecma_is_lexical_environment (lex_env_p)); - while (lex_env_p != NULL) + while (true) { switch (ecma_get_lex_env_type (lex_env_p)) { @@ -245,7 +246,12 @@ ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme } } - lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL) + { + break; + } + + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); } if (is_strict) diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index 7b1a7b983..d82042be5 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -448,10 +448,15 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob /* a. */ ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p; + ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (value_p); + jmem_cpointer_t prop_desc_getter_cp, prop_desc_setter_cp; + ECMA_SET_POINTER (prop_desc_getter_cp, property_desc_p->get_p); + ECMA_SET_POINTER (prop_desc_setter_cp, property_desc_p->set_p); + if ((property_desc_p->is_get_defined - && property_desc_p->get_p != ecma_get_named_accessor_property_getter (value_p)) + && prop_desc_getter_cp != get_set_pair_p->getter_cp) || (property_desc_p->is_set_defined - && property_desc_p->set_p != ecma_get_named_accessor_property_setter (value_p))) + && prop_desc_setter_cp != get_set_pair_p->setter_cp)) { /* i., ii. */ return ecma_reject (is_throw); @@ -478,12 +483,12 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob #if ENABLED (JERRY_CPOINTER_32_BIT) ecma_getter_setter_pointers_t *getter_setter_pair_p; getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t)); - getter_setter_pair_p->getter_p = JMEM_CP_NULL; - getter_setter_pair_p->setter_p = JMEM_CP_NULL; - ECMA_SET_POINTER (value_p->getter_setter_pair_cp, getter_setter_pair_p); + getter_setter_pair_p->getter_cp = JMEM_CP_NULL; + getter_setter_pair_p->setter_cp = JMEM_CP_NULL; + ECMA_SET_NON_NULL_POINTER (value_p->getter_setter_pair_cp, getter_setter_pair_p); #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ - value_p->getter_setter_pair.getter_p = JMEM_CP_NULL; - value_p->getter_setter_pair.setter_p = JMEM_CP_NULL; + value_p->getter_setter_pair.getter_cp = JMEM_CP_NULL; + value_p->getter_setter_pair.setter_cp = JMEM_CP_NULL; #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ } else @@ -491,8 +496,8 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob JERRY_ASSERT (current_property_type == 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_POINTER (ecma_getter_setter_pointers_t, - value_p->getter_setter_pair_cp); + getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, + value_p->getter_setter_pair_cp); jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t)); #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ value_p->value = ECMA_VALUE_UNDEFINED; diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 626905da4..d040f5f55 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -324,10 +324,7 @@ ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */ ecma_property_ref_t *property_ref_p, /**< property reference */ uint32_t options) /**< option bits */ { - /* Circular reference is possible in JavaScript and testing it is complicated. */ - int max_depth = ECMA_PROPERTY_SEARCH_DEPTH_LIMIT; - - do + while (true) { ecma_property_t property = ecma_op_object_get_own_property (object_p, property_name_p, @@ -339,14 +336,18 @@ ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */ return property; } - if (--max_depth == 0 || property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP) + if (property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP) { break; } - object_p = ecma_get_object_prototype (object_p); + if (object_p->u2.prototype_cp == JMEM_CP_NULL) + { + break; + } + + object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp); } - while (object_p != NULL); return ECMA_PROPERTY_TYPE_NOT_FOUND; } /* ecma_op_object_get_property */ @@ -592,13 +593,15 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_value_p); + ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p); - if (getter_p == NULL) + if (get_set_pair_p->getter_cp == JMEM_CP_NULL) { return ECMA_VALUE_UNDEFINED; } + ecma_object_t *getter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp); + return ecma_op_function_call (getter_p, base_value, NULL, 0); } /* ecma_op_object_find_own */ @@ -660,11 +663,9 @@ ecma_value_t ecma_op_object_find (ecma_object_t *object_p, /**< the object */ ecma_string_t *property_name_p) /**< property name */ { - /* Circular reference is possible in JavaScript and testing it is complicated. */ - int max_depth = ECMA_PROPERTY_SEARCH_DEPTH_LIMIT; - ecma_value_t base_value = ecma_make_object_value (object_p); - do + + while (true) { ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p); @@ -673,14 +674,13 @@ ecma_op_object_find (ecma_object_t *object_p, /**< the object */ return value; } - if (--max_depth == 0) + if (object_p->u2.prototype_cp == JMEM_CP_NULL) { break; } - object_p = ecma_get_object_prototype (object_p); + object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp); } - while (object_p != NULL); return ECMA_VALUE_NOT_FOUND; } /* ecma_op_object_find */ @@ -733,11 +733,9 @@ ecma_value_t ecma_op_object_get (ecma_object_t *object_p, /**< the object */ ecma_string_t *property_name_p) /**< property name */ { - /* Circular reference is possible in JavaScript and testing it is complicated. */ - int max_depth = ECMA_PROPERTY_SEARCH_DEPTH_LIMIT; - ecma_value_t base_value = ecma_make_object_value (object_p); - do + + while (true) { ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p); @@ -746,14 +744,13 @@ ecma_op_object_get (ecma_object_t *object_p, /**< the object */ return value; } - if (--max_depth == 0) + if (object_p->u2.prototype_cp == JMEM_CP_NULL) { break; } - object_p = ecma_get_object_prototype (object_p); + object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp); } - while (object_p != NULL); return ECMA_VALUE_UNDEFINED; } /* ecma_op_object_get */ @@ -931,7 +928,6 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ && !ecma_is_lexical_environment (object_p)); JERRY_ASSERT (property_name_p != NULL); - ecma_object_t *setter_p = NULL; ecma_object_type_t type = ecma_get_object_type (object_p); switch (type) @@ -1074,6 +1070,8 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ } } + jmem_cpointer_t setter_cp = JMEM_CP_NULL; + if (property_p != NULL) { if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) @@ -1092,17 +1090,19 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ { JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - setter_p = ecma_get_named_accessor_property_setter (ECMA_PROPERTY_VALUE_PTR (property_p)); + 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; } } else { - ecma_object_t *proto_p = ecma_get_object_prototype (object_p); bool create_new_property = true; - if (proto_p != NULL) + if (object_p->u2.prototype_cp != JMEM_CP_NULL) { ecma_property_ref_t property_ref = { NULL }; + ecma_object_t *proto_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp); ecma_property_t inherited_property = ecma_op_object_get_property (proto_p, property_name_p, @@ -1113,7 +1113,7 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ { if (ECMA_PROPERTY_GET_TYPE (inherited_property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { - setter_p = ecma_get_named_accessor_property_setter (property_ref.value_p); + setter_cp = ecma_get_named_accessor_property (property_ref.value_p)->setter_cp; create_new_property = false; } else @@ -1173,12 +1173,12 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ } } - if (setter_p == NULL) + if (setter_cp == JMEM_CP_NULL) { return ecma_reject (is_throw); } - ecma_value_t ret_value = ecma_op_function_call (setter_p, + ecma_value_t ret_value = ecma_op_function_call (ECMA_GET_NON_NULL_POINTER (ecma_object_t, setter_cp), ecma_make_object_value (object_p), &value, 1); @@ -1491,19 +1491,27 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob } else { - prop_desc_p->get_p = ecma_get_named_accessor_property_getter (property_ref.value_p); prop_desc_p->is_get_defined = true; + prop_desc_p->is_set_defined = true; + ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (property_ref.value_p); - if (prop_desc_p->get_p != NULL) + if (get_set_pair_p->getter_cp == JMEM_CP_NULL) { + prop_desc_p->get_p = NULL; + } + else + { + prop_desc_p->get_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp); ecma_ref_object (prop_desc_p->get_p); } - prop_desc_p->set_p = ecma_get_named_accessor_property_setter (property_ref.value_p); - prop_desc_p->is_set_defined = true; - - if (prop_desc_p->set_p != NULL) + if (get_set_pair_p->setter_cp == JMEM_CP_NULL) { + prop_desc_p->set_p = NULL; + } + else + { + prop_desc_p->set_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp); ecma_ref_object (prop_desc_p->set_p); } } @@ -1556,12 +1564,16 @@ ecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */ { do { - target_p = ecma_get_object_prototype (target_p); - if (target_p == NULL) + jmem_cpointer_t target_cp = target_p->u2.prototype_cp; + + if (target_cp == JMEM_CP_NULL) { return false; } - else if (target_p == base_p) + + target_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, target_cp); + + if (target_p == base_p) { return true; } @@ -1607,10 +1619,9 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ memset (names_hashes_bitmap, 0, names_hashes_bitmap_size * sizeof (names_hashes_bitmap[0])); - for (ecma_object_t *prototype_chain_iter_p = obj_p; - prototype_chain_iter_p != NULL; - prototype_chain_iter_p = is_with_prototype_chain ? ecma_get_object_prototype (prototype_chain_iter_p) - : NULL) + ecma_object_t *prototype_chain_iter_p = obj_p; + + while (true) { ecma_length_t string_named_properties_count = 0; ecma_length_t array_index_named_properties_count = 0; @@ -1729,16 +1740,23 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ } } - ecma_property_header_t *prop_iter_p = ecma_get_property_list (prototype_chain_iter_p); + jmem_cpointer_t prop_iter_cp = prototype_chain_iter_p->u1.property_list_cp; - if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) +#if ENABLED (JERRY_PROPRETY_HASHMAP) + if (prop_iter_cp != JMEM_CP_NULL) { - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); + + if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) + { + prop_iter_cp = prop_iter_p->next_property_cp; + } } +#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ - while (prop_iter_p != NULL) + while (prop_iter_cp != JMEM_CP_NULL) { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) @@ -1821,8 +1839,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ } } - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); + prop_iter_cp = prop_iter_p->next_property_cp; } ecma_value_p = ecma_collection_iterator_init (prop_names_p); @@ -1987,6 +2004,15 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ } JMEM_FINALIZE_LOCAL_ARRAY (names_p); + + + if (!is_with_prototype_chain || prototype_chain_iter_p->u2.prototype_cp == JMEM_CP_NULL) + { + break; + } + + prototype_chain_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, + prototype_chain_iter_p->u2.prototype_cp); } ecma_free_values_collection (skipped_non_enumerable_p, 0); diff --git a/jerry-core/ecma/operations/ecma-reference.c b/jerry-core/ecma/operations/ecma-reference.c index 5aec3a333..30ecf3aaa 100644 --- a/jerry-core/ecma/operations/ecma-reference.c +++ b/jerry-core/ecma/operations/ecma-reference.c @@ -44,27 +44,28 @@ ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical { JERRY_ASSERT (lex_env_p != NULL); - ecma_object_t *lex_env_iter_p = lex_env_p; - - while (lex_env_iter_p != NULL) + while (true) { #if ENABLED (JERRY_ES2015_CLASS) - if (ecma_get_lex_env_type (lex_env_iter_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND) + if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND) { - lex_env_iter_p = ecma_get_lex_env_outer_reference (lex_env_iter_p); - JERRY_ASSERT (lex_env_iter_p != NULL); + JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); } #endif /* ENABLED (JERRY_ES2015_CLASS) */ - if (ecma_op_has_binding (lex_env_iter_p, name_p)) + if (ecma_op_has_binding (lex_env_p, name_p)) { - return lex_env_iter_p; + return lex_env_p; } - lex_env_iter_p = ecma_get_lex_env_outer_reference (lex_env_iter_p); - } + if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL) + { + return NULL; + } - return NULL; + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); + } } /* ecma_op_resolve_reference_base */ #if ENABLED (JERRY_ES2015_CLASS) @@ -85,7 +86,9 @@ ecma_op_resolve_super_reference_value (ecma_object_t *lex_env_p) /**< starting l return ecma_get_lex_env_binding_object (lex_env_p); } - lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); + + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); } } /* ecma_op_resolve_super_reference_value */ #endif /* ENABLED (JERRY_ES2015_CLASS) */ @@ -101,7 +104,7 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical { JERRY_ASSERT (lex_env_p != NULL); - while (lex_env_p != NULL) + while (true) { ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p); @@ -132,13 +135,15 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); - ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_value_p); + ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p); - if (getter_p == NULL) + if (get_set_pair_p->getter_cp == JMEM_CP_NULL) { return ECMA_VALUE_UNDEFINED; } + ecma_object_t *getter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp); + ecma_value_t base_value = ecma_make_object_value (binding_obj_p); return ecma_op_function_call (getter_p, base_value, NULL, 0); } @@ -160,7 +165,12 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical #endif /* ENABLED (JERRY_ES2015_CLASS) */ } - lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL) + { + break; + } + + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); } #if ENABLED (JERRY_ERROR_MESSAGES) diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index a2d476047..bb0d0e56b 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -1015,7 +1015,7 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed #if ENABLED (JERRY_ES2015_CLASS) ecma_object_t *constructor_prototype_object_p = ecma_get_object_from_value (constructor_prototype); ecma_object_t *new_obj_p = ecma_get_object_from_value (new_obj); - ECMA_SET_POINTER (new_obj_p->prototype_or_outer_reference_cp, constructor_prototype_object_p); + ECMA_SET_NON_NULL_POINTER (new_obj_p->u2.prototype_cp, constructor_prototype_object_p); ecma_deref_object (constructor_prototype_object_p); #endif /* ENABLED (JERRY_ES2015_CLASS) */ diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 73b29945e..e4f9657e7 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -245,8 +245,8 @@ opfunc_for_in (ecma_value_t left_value, /**< left value */ if (prop_names_coll_p->item_count != 0) { - prop_names_p = ECMA_GET_POINTER (ecma_collection_chunk_t, - prop_names_coll_p->first_chunk_cp); + prop_names_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t, + prop_names_coll_p->first_chunk_cp); ecma_ref_object (obj_p); *result_obj_p = ecma_make_object_value (obj_p); diff --git a/jerry-core/vm/vm-stack.c b/jerry-core/vm/vm-stack.c index 7add98589..a3b76a36c 100644 --- a/jerry-core/vm/vm-stack.c +++ b/jerry-core/vm/vm-stack.c @@ -72,7 +72,8 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ #endif /* ENABLED (JERRY_ES2015_CLASS) */ { ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; - frame_ctx_p->lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); + frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); ecma_deref_object (lex_env_p); VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION); @@ -244,7 +245,8 @@ vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ else { ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; - frame_ctx_p->lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); + frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); ecma_deref_object (lex_env_p); if (byte_code_p[0] == CBC_CONTEXT_END) diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index d816f065c..f8195c6ec 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -294,13 +294,13 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */ while (chain_index != 0) { - lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); - - if (JERRY_UNLIKELY (lex_env_p == NULL)) + if (JERRY_UNLIKELY (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)) { return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid scope chain index for eval")); } + lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); + if ((ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) || (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)) { @@ -1387,7 +1387,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_object_t *super_class_p = ecma_get_lex_env_binding_object (frame_ctx_p->lex_env_p); - if (ecma_get_object_prototype (super_class_p)) + if (super_class_p->u2.prototype_cp != JMEM_CP_NULL) { ecma_value_t super_prototype_value = ecma_op_object_get_by_magic_id (super_class_p, LIT_MAGIC_STRING_PROTOTYPE); @@ -1403,8 +1403,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_object_t *super_prototype_class_p = ecma_get_object_from_value (super_prototype_value); - ECMA_SET_POINTER (child_prototype_class_p->prototype_or_outer_reference_cp, super_prototype_class_p); - ECMA_SET_POINTER (child_class_p->prototype_or_outer_reference_cp, super_class_p); + ECMA_SET_NON_NULL_POINTER (child_prototype_class_p->u2.prototype_cp, super_prototype_class_p); + ECMA_SET_NON_NULL_POINTER (child_class_p->u2.prototype_cp, super_class_p); } ecma_free_value (super_prototype_value); @@ -3063,7 +3063,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ if (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_CATCH) { ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; - frame_ctx_p->lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p); + JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); + frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); ecma_deref_object (lex_env_p); }