mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
General optimizations around compressed pointer management (#3019)
ECMA_GET_POINTER is removed from:
- property list iteration
- lexical environment chain iteration
- prototype chain iteration
For all these iteration the compressed pointer can be used to get the elements and only decompressed them if it is necessary.
- Properly guard ecma property hashmap routines
- Remove the redundant NULL pointer check from ecma_create_property
- Remove ecma_gc_get_object_next since it became unnecessary
- Substitute ECMA_{GET,SET}_POINTER with ECMA_{GET,SET}_NON_NULL pointer when we can assume the pointer is not NULL
- Remove ecma_get_object_prototype and ecma_get_lex_env_outer_reference helper function the reduce the number of NULL pointer checks during decompressing the pointers
- Remove ecma_get_named_accessor_property_{getter,setter} helper functions for also reduce the number of NULL pointer check/decompressions
- Remove ECMA_PROPERTY_SEARCH_DEPTH_LIMIT since in ES5 there is no way to create circular prototype chain, and the ES2015 setPrototypeOf method can resolve this error so this check during the property lookup can be eliminated.
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
parent
97e348528a
commit
47f2f0ea8b
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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) */
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
/**
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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) */
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user