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:
Robert Fancsik
2019-08-26 17:42:02 +02:00
committed by Dániel Bátyai
parent 97e348528a
commit 47f2f0ea8b
21 changed files with 591 additions and 531 deletions
+11 -8
View File
@@ -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;
+17 -11
View File
@@ -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;
+76 -50
View File
@@ -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);
+26 -16
View File
@@ -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) */