Use ecma_op_object_get_property_names for property enumeration in built-ins implementation.

JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
Ruben Ayrapetyan 2015-10-30 15:25:58 +03:00
parent 72208a61ee
commit 09b4d20718
6 changed files with 232 additions and 363 deletions

View File

@ -1222,73 +1222,58 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
uint32_t len = ecma_number_to_uint32 (len_number);
uint32_t defined_prop_count = 0;
/* Count number of array index properties. */
for (ecma_property_t *property_p = ecma_get_property_list (obj_p);
property_p != NULL;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
{
ecma_string_t *property_name_p;
ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, true, false, false);
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
}
else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_accessor_property.name_p);
}
else
{
continue;
}
uint32_t defined_prop_count = 0;
uint32_t copied_num = 0;
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, array_index_props_p);
/* Count properties with name that is array index less than len */
while (ecma_collection_iterator_next (&iter)
&& ecma_is_completion_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
uint32_t index;
if (ecma_string_get_array_index (property_name_p, &index) && index < len)
bool is_index = ecma_string_get_array_index (property_name_p, &index);
JERRY_ASSERT (is_index);
if (index < len)
{
defined_prop_count++;
}
}
MEM_DEFINE_LOCAL_ARRAY (values_buffer, defined_prop_count, ecma_value_t);
uint32_t copied_num = 0;
ecma_collection_iterator_init (&iter, array_index_props_p);
/* Copy unsorted array into a native c array. */
for (ecma_property_t *property_p = ecma_get_property_list (obj_p);
property_p != NULL && ecma_is_completion_value_empty (ret_value);
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
while (ecma_collection_iterator_next (&iter)
&& ecma_is_completion_value_empty (ret_value))
{
ecma_string_t *property_name_p;
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
}
else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_accessor_property.name_p);
}
else
{
continue;
}
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
uint32_t index;
if (ecma_string_get_array_index (property_name_p, &index) && index < len)
bool is_index = ecma_string_get_array_index (property_name_p, &index);
JERRY_ASSERT (is_index);
if (index >= len)
{
ECMA_TRY_CATCH (index_value, ecma_op_object_get (obj_p, property_name_p), ret_value);
values_buffer[copied_num++] = ecma_copy_value (index_value, true);
ECMA_FINALIZE (index_value);
break;
}
ECMA_TRY_CATCH (index_value, ecma_op_object_get (obj_p, property_name_p), ret_value);
values_buffer[copied_num++] = ecma_copy_value (index_value, true);
ECMA_FINALIZE (index_value);
}
JERRY_ASSERT (copied_num == defined_prop_count || !ecma_is_completion_value_empty (ret_value));
JERRY_ASSERT (copied_num == defined_prop_count
|| !ecma_is_completion_value_empty (ret_value));
/* Sorting. */
if (copied_num > 1 && ecma_is_completion_value_empty (ret_value))
@ -1302,7 +1287,9 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
}
/* Put sorted values to the front of the array. */
for (uint32_t index = 0; index < copied_num && ecma_is_completion_value_empty (ret_value); index++)
for (uint32_t index = 0;
index < copied_num && ecma_is_completion_value_empty (ret_value);
index++)
{
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ECMA_TRY_CATCH (put_value,
@ -1312,51 +1299,41 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
ecma_deref_ecma_string (index_string_p);
}
/* Undefined properties should be in the back of the array. */
ecma_property_t *next_prop;
for (ecma_property_t *property_p = ecma_get_property_list (obj_p);
property_p != NULL && ecma_is_completion_value_empty (ret_value);
property_p = next_prop)
{
ecma_string_t *property_name_p;
next_prop = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p);
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
}
else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_accessor_property.name_p);
}
else
{
continue;
}
uint32_t index;
if (ecma_string_get_array_index (property_name_p, &index) && index < len && index >= copied_num)
{
ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, property_name_p, true), ret_value);
ECMA_FINALIZE (del_value);
}
}
/* Free values that were copied to the local array. */
for (uint32_t index = 0; index < copied_num; index++)
{
ecma_free_value (values_buffer[index], true);
}
MEM_FINALIZE_LOCAL_ARRAY (values_buffer);
/* Undefined properties should be in the back of the array. */
ecma_collection_iterator_init (&iter, array_index_props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_completion_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
uint32_t index;
bool is_index = ecma_string_get_array_index (property_name_p, &index);
JERRY_ASSERT (is_index);
if (index >= copied_num && index < len)
{
ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, property_name_p, true), ret_value);
ECMA_FINALIZE (del_value);
}
}
ecma_free_values_collection (array_index_props_p, true);
if (ecma_is_completion_value_empty (ret_value))
{
ret_value = ecma_make_normal_completion_value (ecma_copy_value (this_arg, true));
}
MEM_FINALIZE_LOCAL_ARRAY (values_buffer);
ECMA_OP_TO_NUMBER_FINALIZE (len_number);
ECMA_FINALIZE (len_value);
ecma_deref_ecma_string (magic_string_length_p);

View File

@ -185,7 +185,7 @@ ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /** < t
/**
* The Object.keys and Object.getOwnPropertyName routine's common part.
* The Object.keys and Object.getOwnPropertyNames routine's common part.
*
* See also:
* ECMA-262 v5, 15.2.3.4 steps 2-5
@ -206,39 +206,21 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /** < object */
uint32_t index = 0;
for (ecma_property_t *property_p = ecma_get_property_list (obj_p);
property_p != NULL;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p,
false,
only_enumerable_properties,
false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter))
{
ecma_string_t *property_name_p;
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
}
else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_accessor_property.name_p);
}
else
{
continue;
}
if (only_enumerable_properties && !ecma_is_property_enumerable (property_p))
{
continue;
}
JERRY_ASSERT (property_name_p != NULL);
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ecma_completion_value_t completion = ecma_builtin_helper_def_prop (new_array_p,
index_string_p,
ecma_make_string_value (property_name_p),
*iter.current_value_p,
true, /* Writable */
true, /* Enumerable */
true, /* Configurable */
@ -246,12 +228,13 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /** < object */
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
ecma_free_completion_value (completion);
ecma_deref_ecma_string (index_string_p);
index++;
}
ecma_free_values_collection (props_p, true);
return new_array;
} /* ecma_builtin_helper_object_get_properties */

View File

@ -625,91 +625,45 @@ ecma_builtin_json_walk (ecma_object_t *reviver_p, /**< reviver function */
{
ecma_object_t *object_p = ecma_get_object_from_value (value_get);
uint32_t no_properties = 0;
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (object_p, false, true, false);
/*
* The following algorithm works with arrays and objects as well.
*/
for (ecma_property_t *property_p = ecma_get_property_list (object_p);
property_p != NULL;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_completion_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ECMA_TRY_CATCH (value_walk,
ecma_builtin_json_walk (reviver_p,
object_p,
property_name_p),
ret_value);
/*
* All properties must be named data or internal properties, since we constructed them.
* We cannot optimize this function since any members
* can be changed (deleted) by the reviver function.
*/
JERRY_ASSERT (property_p->type == ECMA_PROPERTY_NAMEDDATA
|| property_p->type == ECMA_PROPERTY_INTERNAL);
if (property_p->type == ECMA_PROPERTY_NAMEDDATA
&& ecma_is_property_enumerable (property_p))
if (ecma_is_value_undefined (value_walk))
{
no_properties++;
ecma_completion_value_t delete_val = ecma_op_general_object_delete (object_p,
property_name_p,
false);
JERRY_ASSERT (ecma_is_completion_value_normal_true (delete_val)
|| ecma_is_completion_value_normal_false (delete_val));
}
else
{
ecma_builtin_json_define_value_property (object_p,
property_name_p,
value_walk);
}
ECMA_FINALIZE (value_walk);
}
if (no_properties > 0)
{
MEM_DEFINE_LOCAL_ARRAY (property_names_p, no_properties, ecma_string_t *);
uint32_t property_index = no_properties;
for (ecma_property_t *property_p = ecma_get_property_list (object_p);
property_p != NULL;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
{
if (property_p->type == ECMA_PROPERTY_NAMEDDATA
&& ecma_is_property_enumerable (property_p))
{
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
/*
* The property list must be in creation order.
*/
property_index--;
property_names_p[property_index] = ecma_copy_or_ref_ecma_string (property_name_p);
}
}
JERRY_ASSERT (property_index == 0);
for (property_index = 0;
property_index < no_properties && ecma_is_completion_value_empty (ret_value);
property_index++)
{
ECMA_TRY_CATCH (value_walk,
ecma_builtin_json_walk (reviver_p,
object_p,
property_names_p[property_index]),
ret_value);
/*
* We cannot optimize this function since any members
* can be changed (deleted) by the reviver function.
*/
if (ecma_is_value_undefined (value_walk))
{
ecma_completion_value_t delete_val = ecma_op_general_object_delete (object_p,
property_names_p[property_index],
false);
JERRY_ASSERT (ecma_is_completion_value_normal_true (delete_val)
|| ecma_is_completion_value_normal_false (delete_val));
}
else
{
ecma_builtin_json_define_value_property (object_p,
property_names_p[property_index],
value_walk);
}
ECMA_FINALIZE (value_walk);
}
for (uint32_t i = 0; i < no_properties; i++)
{
ecma_deref_ecma_string (property_names_p[i]);
}
MEM_FINALIZE_LOCAL_ARRAY (property_names_p);
}
ecma_free_values_collection (props_p, true);
}
if (ecma_is_completion_value_empty (ret_value))
@ -1492,20 +1446,25 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
{
property_keys_p = ecma_new_values_collection (NULL, 0, true);
for (ecma_property_t *property_p = ecma_get_property_list (obj_p);
property_p != NULL;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, true, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter))
{
if (property_p->type == ECMA_PROPERTY_NAMEDDATA && ecma_is_property_enumerable (property_p))
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
JERRY_ASSERT (ecma_is_property_enumerable (property_p));
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
ecma_string_t *prop_key = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
JERRY_ASSERT (prop_key != NULL);
ecma_append_to_values_collection (property_keys_p, ecma_make_string_value (prop_key), true);
ecma_append_to_values_collection (property_keys_p, *iter.current_value_p, true);
}
}
ecma_free_values_collection (props_p, true);
}
/* 7. */

View File

@ -199,27 +199,16 @@ ecma_builtin_object_object_seal (ecma_value_t this_arg __attr_unused___, /**< 't
// 2.
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_property_t *property_p;
for (property_p = ecma_get_property_list (obj_p);
property_p != NULL && ecma_is_completion_value_empty (ret_value);
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
{
ecma_string_t *property_name_p;
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
}
else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_accessor_property.name_p);
}
else
{
continue;
}
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_completion_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
// 2.a
ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (property_p);
@ -242,6 +231,8 @@ ecma_builtin_object_object_seal (ecma_value_t this_arg __attr_unused___, /**< 't
ecma_free_property_descriptor (&prop_desc);
}
ecma_free_values_collection (props_p, true);
if (ecma_is_completion_value_empty (ret_value))
{
// 3.
@ -280,28 +271,17 @@ ecma_builtin_object_object_freeze (ecma_value_t this_arg __attr_unused___, /**<
// 2.
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_property_t *property_p;
for (property_p = ecma_get_property_list (obj_p);
property_p != NULL && ecma_is_completion_value_empty (ret_value);
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
{
ecma_string_t *property_name_p;
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
}
else
if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_accessor_property.name_p);
}
else
{
continue;
}
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_completion_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
// 2.a
ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (property_p);
@ -330,6 +310,8 @@ ecma_builtin_object_object_freeze (ecma_value_t this_arg __attr_unused___, /**<
ecma_free_property_descriptor (&prop_desc);
}
ecma_free_values_collection (props_p, true);
if (ecma_is_completion_value_empty (ret_value))
{
// 3.
@ -396,41 +378,45 @@ ecma_builtin_object_object_is_sealed (ecma_value_t this_arg __attr_unused___, /*
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_property_t *property_p;
// This will be the result if the other steps doesn't change it.
bool sealed = false;
bool is_sealed;
// 3.
// The pseudo code contains multiple early return but this way we get the same
// result.
if (!ecma_get_object_extensible (obj_p))
if (ecma_get_object_extensible (obj_p))
{
sealed = true;
is_sealed = false;
}
// 2.
for (property_p = ecma_get_property_list (obj_p);
property_p != NULL && sealed;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
else
{
if (property_p->type == ECMA_PROPERTY_INTERNAL)
/* the value can be updated in the loop below */
is_sealed = true;
// 2.
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter))
{
continue;
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
// 2.b
if (ecma_is_property_configurable (property_p))
{
is_sealed = false;
break;
}
}
JERRY_ASSERT (property_p->type == ECMA_PROPERTY_NAMEDDATA || property_p->type == ECMA_PROPERTY_NAMEDACCESSOR);
// 2.b
if (ecma_is_property_configurable (property_p))
{
sealed = false;
break;
}
ecma_free_values_collection (props_p, true);
}
// 4.
ret_value = ecma_make_simple_completion_value (sealed
ret_value = ecma_make_simple_completion_value (is_sealed
? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
}
@ -461,48 +447,53 @@ ecma_builtin_object_object_is_frozen (ecma_value_t this_arg __attr_unused___, /*
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_property_t *property_p;
// This will be the result if the other steps doesn't change it.
bool frozen = false;
bool is_frozen;
// 3.
// The pseudo code contains multiple early return but this way we get the same
// result.
if (!ecma_get_object_extensible (obj_p))
if (ecma_get_object_extensible (obj_p))
{
frozen = true;
is_frozen = false;
}
// 2.
for (property_p = ecma_get_property_list (obj_p);
property_p != NULL && frozen;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
else
{
if (property_p->type == ECMA_PROPERTY_INTERNAL)
is_frozen = true;
// 2.
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter))
{
continue;
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);
JERRY_ASSERT (property_p->type == ECMA_PROPERTY_NAMEDDATA || property_p->type == ECMA_PROPERTY_NAMEDACCESSOR);
// 2.b
if (property_p->type == ECMA_PROPERTY_NAMEDDATA && ecma_is_property_writable (property_p))
{
is_frozen = false;
break;
}
// 2.c
if (ecma_is_property_configurable (property_p))
{
is_frozen = false;
break;
}
}
JERRY_ASSERT (property_p->type == ECMA_PROPERTY_NAMEDDATA || property_p->type == ECMA_PROPERTY_NAMEDACCESSOR);
// 2.b
if (property_p->type == ECMA_PROPERTY_NAMEDDATA && ecma_is_property_writable (property_p))
{
frozen = false;
break;
}
// 2.c
if (ecma_is_property_configurable (property_p))
{
frozen = false;
break;
}
ecma_free_values_collection (props_p, true);
}
// 4.
ret_value = ecma_make_simple_completion_value (frozen
ret_value = ecma_make_simple_completion_value (is_frozen
? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
}
@ -716,69 +707,30 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse
ret_value);
ecma_object_t *props_p = ecma_get_object_from_value (props);
ecma_property_t *property_p;
// First we need to know how many properties should be stored
uint32_t property_number = 0;
for (property_p = ecma_get_property_list (props_p);
property_p != NULL;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
{
if ((property_p->type == ECMA_PROPERTY_NAMEDDATA || property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
&& ecma_is_property_enumerable (property_p))
{
property_number++;
}
}
// 3.
MEM_DEFINE_LOCAL_ARRAY (property_names_p, property_number, ecma_string_t*);
ecma_collection_header_t *prop_names_p = ecma_op_object_get_property_names (props_p, false, true, false);
uint32_t property_number = prop_names_p->unit_number;
uint32_t index = 0;
for (property_p = ecma_get_property_list (props_p);
property_p != NULL;
property_p = ECMA_GET_POINTER (ecma_property_t, property_p->next_property_p))
{
ecma_string_t *property_name_p;
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_data_property.name_p);
}
else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
{
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_p->u.named_accessor_property.name_p);
}
else
{
continue;
}
if (ecma_is_property_enumerable (property_p))
{
property_names_p[index++] = ecma_copy_or_ref_ecma_string (property_name_p);
}
}
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, prop_names_p);
// 4.
MEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t);
uint32_t property_descriptor_number = 0;
for (index = 0;
index < property_number && ecma_is_completion_value_empty (ret_value);
index++)
while (ecma_collection_iterator_next (&iter)
&& ecma_is_completion_value_empty (ret_value))
{
// 5.a
ECMA_TRY_CATCH (desc_obj,
ecma_op_object_get (props_p, property_names_p[index]),
ecma_op_object_get (props_p, ecma_get_string_from_value (*iter.current_value_p)),
ret_value);
// 5.b
ECMA_TRY_CATCH (conv_result,
ecma_op_to_property_descriptor (desc_obj,
&property_descriptors[index]),
&property_descriptors[property_descriptor_number]),
ret_value);
property_descriptor_number++;
@ -788,13 +740,17 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse
}
// 6.
for (index = 0;
ecma_collection_iterator_init (&iter, prop_names_p);
for (uint32_t index = 0;
index < property_number && ecma_is_completion_value_empty (ret_value);
index++)
{
bool is_next = ecma_collection_iterator_next (&iter);
JERRY_ASSERT (is_next);
ECMA_TRY_CATCH (define_own_prop_ret,
ecma_op_object_define_own_property (obj_p,
property_names_p[index],
ecma_get_string_from_value (*iter.current_value_p),
&property_descriptors[index],
true),
ret_value);
@ -803,7 +759,7 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse
}
// Clean up
for (index = 0;
for (uint32_t index = 0;
index < property_descriptor_number;
index++)
{
@ -812,14 +768,7 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse
MEM_FINALIZE_LOCAL_ARRAY (property_descriptors);
for (index = 0;
index < property_number;
index++)
{
ecma_deref_ecma_string (property_names_p[index]);
}
MEM_FINALIZE_LOCAL_ARRAY (property_names_p);
ecma_free_values_collection (prop_names_p, true);
// 7.
if (ecma_is_completion_value_empty (ret_value))

View File

@ -644,7 +644,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
uint32_t insertion_pos = 0;
while (insertion_pos < array_index_name_pos
&& index <= array_index_names_p[insertion_pos])
&& index < array_index_names_p[insertion_pos])
{
insertion_pos++;
}
@ -656,6 +656,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
else
{
JERRY_ASSERT (insertion_pos < array_index_name_pos);
JERRY_ASSERT (index < array_index_names_p[insertion_pos]);
uint32_t move_pos = ++array_index_name_pos;

View File

@ -52,15 +52,15 @@ empty_object.a = undefined;
assert (JSON.stringify (empty_object) == '{}');
p_object = { "a": 1, "b": true, "c": "foo", "d": null, "e": undefined };
assert (JSON.stringify (p_object) == '{"d":null,"c":"foo","b":true,"a":1}');
assert (JSON.stringify (p_object) == '{"a":1,"b":true,"c":"foo","d":null}');
o_object = { "a": new Number(1), "b": new Boolean(true), "c": new String("foo") };
assert (JSON.stringify (o_object) == '{"c":"foo","b":true,"a":1}');
assert (JSON.stringify (o_object) == '{"a":1,"b":true,"c":"foo"}');
child = { "a": 1, "b": new String("\nfoo"), "c": undefined };
parent = { "a": true, "b": child, "c": null};
assert (JSON.stringify (parent) == '{"c":null,"b":{"b":"\\nfoo","a":1},"a":true}');
assert (JSON.stringify (parent) == '{"a":true,"b":{"a":1,"b":"\\nfoo"},"c":null}');
recursive_object = {};
recursive_object.a = 2;
@ -105,13 +105,13 @@ try {
}
object = {"a": 1, "b": [1, true, {"a": "foo"}]};
assert (JSON.stringify (object) == '{"b":[1,true,{"a":"foo"}],"a":1}');
assert (JSON.stringify (object) == '{"a":1,"b":[1,true,{"a":"foo"}]}');
object = {"a": [1], "b": {}};
assert (JSON.stringify(object) === '{"b":{},"a":[1]}');
assert (JSON.stringify(object) === '{"a":[1],"b":{}}');
array = [1, {"a": 2, "b": true, c: [3]}];
assert (JSON.stringify (array) == '[1,{"c":[3],"b":true,"a":2}]');
assert (JSON.stringify (array) == '[1,{"a":2,"b":true,"c":[3]}]');
// Filtering / replacing
to_json_object = {};
@ -128,7 +128,7 @@ function replacer_function (key, value)
}
object = { "a": "JSON", "b": new String("JSON"), "c": 3 };
assert (JSON.stringify (object, replacer_function) == '{"c":3,"b":"JSON","a":"FOO"}');
assert (JSON.stringify (object, replacer_function) == '{"a":"FOO","b":"JSON","c":3}');
filter = ["a", "b"];
assert (JSON.stringify (object, filter) == '{"a":"JSON","b":"JSON"}');
@ -198,7 +198,7 @@ assert (JSON.stringify (array, null, 100) == '[\n 2\n]');
assert (JSON.stringify (array, null, -5) == '[2]');
nested_object = {"a": 2, "b": {"c": 1, "d": true}};
assert (JSON.stringify (nested_object, null, 2) == '{\n "b": {\n "d": true,\n "c": 1\n },\n "a": 2\n}');
assert (JSON.stringify (nested_object, null, 2) == '{\n "a": 2,\n "b": {\n "c": 1,\n "d": true\n }\n}');
nested_array = [2, [1,true]];
assert (JSON.stringify (nested_array, null, 2) == '[\n 2,\n [\n 1,\n true\n ]\n]');