Rework ecma collection. (#2153)

Greatly simplify the iterator part and make it compatible with 32 bit cpointers.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2018-01-10 15:55:56 +01:00
committed by Dániel Bátyai
parent f833da2c13
commit b9560b7c70
23 changed files with 511 additions and 521 deletions
@@ -1180,14 +1180,13 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
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);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
/* Count properties with name that is array index less than len */
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
uint32_t index = ecma_string_get_array_index (property_name_p);
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
@@ -1200,13 +1199,13 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
JMEM_DEFINE_LOCAL_ARRAY (values_buffer, defined_prop_count, ecma_value_t);
ecma_collection_iterator_init (&iter, array_index_props_p);
ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
/* Copy unsorted array into a native c array. */
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
uint32_t index = ecma_string_get_array_index (property_name_p);
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
@@ -1260,12 +1259,12 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
/* Undefined properties should be in the back of the array. */
ecma_collection_iterator_init (&iter, array_index_props_p);
ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
uint32_t index = ecma_string_get_array_index (property_name_p);
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
@@ -26,38 +26,31 @@
*/
/**
* Check the object value existance in the collection.
* Check whether the object is pushed onto the occurence stack
*
* Used by:
* - ecma_builtin_json_object step 1
* - ecma_builtin_json_array step 1
*
* @return true, if the object is already in the collection.
* @return true - if the object is pushed onto the occurence stack
* false - otherwise
*/
bool
ecma_has_object_value_in_collection (ecma_collection_header_t *collection_p, /**< collection */
ecma_value_t object_value) /**< object value */
ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, /**< stack */
ecma_object_t *object_p) /**< object */
{
JERRY_ASSERT (ecma_is_value_object (object_value));
ecma_object_t *obj_p = ecma_get_object_from_value (object_value);
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, collection_p);
while (ecma_collection_iterator_next (&iterator))
while (stack_p != NULL)
{
ecma_value_t value = *iterator.current_value_p;
ecma_object_t *current_p = ecma_get_object_from_value (value);
if (current_p == obj_p)
if (stack_p->object_p == object_p)
{
return true;
}
stack_p = stack_p->next_p;
}
return false;
} /* ecma_has_object_value_in_collection */
} /* ecma_json_has_object_in_stack */
/**
* Check the string value existance in the collection.
@@ -75,18 +68,18 @@ ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, /**
ecma_string_t *string_p = ecma_get_string_from_value (string_value);
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, collection_p);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (collection_p);
while (ecma_collection_iterator_next (&iterator))
while (ecma_value_p != NULL)
{
ecma_value_t value = *iterator.current_value_p;
ecma_string_t *current_p = ecma_get_string_from_value (value);
ecma_string_t *current_p = ecma_get_string_from_value (*ecma_value_p);
if (ecma_compare_ecma_strings (current_p, string_p))
{
return true;
}
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
}
return false;
@@ -111,15 +104,14 @@ ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *
{
ecma_string_t *properties_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, partial_p);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (partial_p);
bool first = true;
while (ecma_collection_iterator_next (&iterator))
while (ecma_value_p != NULL)
{
ecma_value_t name_value = *iterator.current_value_p;
ecma_string_t *current_p = ecma_get_string_from_value (name_value);
ecma_string_t *current_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
if (likely (!first))
{
@@ -203,16 +203,15 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
only_enumerable_properties,
false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
while (ecma_collection_iterator_next (&iter))
while (ecma_value_p != NULL)
{
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_p,
index_string_p,
*iter.current_value_p,
*ecma_value_p,
true, /* Writable */
true, /* Enumerable */
true, /* Configurable */
@@ -222,6 +221,8 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
ecma_deref_ecma_string (index_string_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
index++;
}
@@ -122,6 +122,15 @@ ecma_value_t ecma_date_value_to_time_string (ecma_number_t datetime_number);
/* ecma-builtin-helper-json.c */
/**
* Occurence stack item of JSON.stringify()
*/
typedef struct struct_ecma_json_occurence_stack_item_t
{
struct struct_ecma_json_occurence_stack_item_t *next_p; /**< next stack item */
ecma_object_t *object_p; /**< current object */
} ecma_json_occurence_stack_item_t;
/**
* Context for JSON.stringify()
*/
@@ -131,7 +140,7 @@ typedef struct
ecma_collection_header_t *property_list_p;
/** Collection for traversing objects. */
ecma_collection_header_t *occurence_stack_p;
ecma_json_occurence_stack_item_t *occurence_stack_last_p;
/** The actual indentation text. */
ecma_string_t *indent_str_p;
@@ -143,7 +152,7 @@ typedef struct
ecma_object_t *replacer_function_p;
} ecma_json_stringify_context_t;
bool ecma_has_object_value_in_collection (ecma_collection_header_t *collection_p, ecma_value_t object_value);
bool ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, ecma_object_t *object_p);
bool ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, ecma_value_t string_value);
ecma_string_t *
@@ -728,13 +728,12 @@ ecma_builtin_json_walk (ecma_object_t *reviver_p, /**< reviver function */
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (object_p, false, true, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
ECMA_TRY_CATCH (value_walk,
ecma_builtin_json_walk (reviver_p,
@@ -901,7 +900,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
ecma_json_stringify_context_t context;
/* 1. */
context.occurence_stack_p = ecma_new_values_collection (NULL, 0, false);
context.occurence_stack_last_p = NULL;
/* 2. */
context.indent_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
@@ -1138,7 +1137,6 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
ecma_deref_ecma_string (context.indent_str_p);
ecma_free_values_collection (context.property_list_p, true);
ecma_free_values_collection (context.occurence_stack_p, true);
return ret_value;
} /* ecma_builtin_json_stringify */
@@ -1459,10 +1457,8 @@ static ecma_value_t
ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
ecma_json_stringify_context_t *context_p) /**< context*/
{
ecma_value_t obj_value = ecma_make_object_value (obj_p);
/* 1. */
if (ecma_has_object_value_in_collection (context_p->occurence_stack_p, obj_value))
if (ecma_json_has_object_in_stack (context_p->occurence_stack_last_p, obj_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("The structure is cyclical."));
}
@@ -1470,7 +1466,10 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 2. */
ecma_append_to_values_collection (context_p->occurence_stack_p, obj_value, true);
ecma_json_occurence_stack_item_t stack_item;
stack_item.next_p = context_p->occurence_stack_last_p;
stack_item.object_p = obj_p;
context_p->occurence_stack_last_p = &stack_item;
/* 3. */
ecma_string_t *stepback_p = context_p->indent_str_p;
@@ -1482,7 +1481,7 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
ecma_collection_header_t *property_keys_p;
/* 5. */
if (context_p->property_list_p->unit_number > 0)
if (context_p->property_list_p->item_count > 0)
{
property_keys_p = context_p->property_list_p;
}
@@ -1493,12 +1492,11 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
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);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
while (ecma_collection_iterator_next (&iter))
while (ecma_value_p != NULL)
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_p,
@@ -1509,8 +1507,10 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA)
{
ecma_append_to_values_collection (property_keys_p, *iter.current_value_p, true);
ecma_append_to_values_collection (property_keys_p, *ecma_value_p, true);
}
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
}
ecma_free_values_collection (props_p, true);
@@ -1520,13 +1520,12 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
ecma_collection_header_t *partial_p = ecma_new_values_collection (NULL, 0, true);
/* 8. */
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, property_keys_p);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (property_keys_p);
while (ecma_collection_iterator_next (&iterator) && ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
ecma_value_t value = *iterator.current_value_p;
ecma_string_t *key_p = ecma_get_string_from_value (value);
ecma_string_t *key_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
/* 8.a */
ECMA_TRY_CATCH (str_val,
@@ -1565,7 +1564,7 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
ECMA_FINALIZE (str_val);
}
if (context_p->property_list_p->unit_number == 0)
if (context_p->property_list_p->item_count == 0)
{
ecma_free_values_collection (property_keys_p, true);
}
@@ -1578,7 +1577,7 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
}
/* 9. */
if (partial_p->unit_number == 0)
if (partial_p->item_count == 0)
{
lit_utf8_byte_t chars[2] = { LIT_CHAR_LEFT_BRACE, LIT_CHAR_RIGHT_BRACE };
@@ -1609,7 +1608,7 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
ecma_free_values_collection (partial_p, true);
/* 11. */
ecma_remove_last_value_from_values_collection (context_p->occurence_stack_p);
context_p->occurence_stack_last_p = stack_item.next_p;
/* 12. */
ecma_deref_ecma_string (context_p->indent_str_p);
@@ -1632,10 +1631,8 @@ static ecma_value_t
ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/
ecma_json_stringify_context_t *context_p) /**< context*/
{
ecma_value_t obj_value = ecma_make_object_value (obj_p);
/* 1. */
if (ecma_has_object_value_in_collection (context_p->occurence_stack_p, obj_value))
if (ecma_json_has_object_in_stack (context_p->occurence_stack_last_p, obj_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("The structure is cyclical."));
}
@@ -1643,7 +1640,10 @@ ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 2. */
ecma_append_to_values_collection (context_p->occurence_stack_p, obj_value, true);
ecma_json_occurence_stack_item_t stack_item;
stack_item.next_p = context_p->occurence_stack_last_p;
stack_item.object_p = obj_p;
context_p->occurence_stack_last_p = &stack_item;
/* 3. */
ecma_string_t *stepback_p = context_p->indent_str_p;
@@ -1697,7 +1697,7 @@ ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/
if (ecma_is_value_empty (ret_value))
{
/* 9. */
if (partial_p->unit_number == 0)
if (partial_p->item_count == 0)
{
lit_utf8_byte_t chars[2] = { LIT_CHAR_LEFT_SQUARE, LIT_CHAR_RIGHT_SQUARE };
@@ -1732,7 +1732,7 @@ ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/
ecma_free_values_collection (partial_p, true);
/* 11. */
ecma_remove_last_value_from_values_collection (context_p->occurence_stack_p);
context_p->occurence_stack_last_p = stack_item.next_p;
/* 12. */
ecma_deref_ecma_string (context_p->indent_str_p);
@@ -315,13 +315,12 @@ ecma_builtin_object_object_seal (ecma_value_t this_arg, /**< 'this' argument */
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);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
/* 2.a */
ecma_property_descriptor_t prop_desc;
@@ -389,14 +388,12 @@ ecma_builtin_object_object_freeze (ecma_value_t this_arg, /**< 'this' argument *
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
/* 2.a */
ecma_property_descriptor_t prop_desc;
@@ -513,12 +510,12 @@ ecma_builtin_object_object_is_sealed (ecma_value_t this_arg, /**< 'this' argumen
/* 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);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
while (ecma_collection_iterator_next (&iter))
while (ecma_value_p != NULL)
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
/* 2.a */
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
@@ -583,12 +580,12 @@ ecma_builtin_object_object_is_frozen (ecma_value_t this_arg, /**< 'this' argumen
/* 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);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
while (ecma_collection_iterator_next (&iter))
while (ecma_value_p != NULL)
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
/* 2.a */
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
@@ -829,22 +826,20 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg, /**< 'this'
ecma_object_t *props_p = ecma_get_object_from_value (props);
/* 3. */
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 property_number = prop_names_p->item_count;
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, prop_names_p);
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p);
/* 4. */
JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t);
uint32_t property_descriptor_number = 0;
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
{
/* 5.a */
ECMA_TRY_CATCH (desc_obj,
ecma_op_object_get (props_p, ecma_get_string_from_value (*iter.current_value_p)),
ecma_op_object_get (props_p, ecma_get_string_from_value (*ecma_value_p)),
ret_value);
/* 5.b */
@@ -857,25 +852,27 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg, /**< 'this'
ECMA_FINALIZE (conv_result);
ECMA_FINALIZE (desc_obj);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
}
/* 6. */
ecma_collection_iterator_init (&iter, prop_names_p);
ecma_value_p = ecma_collection_iterator_init (prop_names_p);
for (uint32_t index = 0;
index < property_number && ecma_is_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,
ecma_get_string_from_value (*iter.current_value_p),
ecma_get_string_from_value (*ecma_value_p),
&property_descriptors[index],
true),
ret_value);
ECMA_FINALIZE (define_own_prop_ret);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
}
/* Clean up. */
@@ -141,7 +141,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
ecma_deref_ecma_string (pattern_string_p);
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, *bc_prop_p);
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
if (old_bc_p != NULL)
{
@@ -213,7 +213,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
re_compile_bytecode (&new_bc_p, pattern_string_p, flags),
ret_value);
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, *bc_prop_p);
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
if (old_bc_p != NULL)
{
@@ -275,7 +275,7 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
ecma_value_t *bytecode_prop_p = &(((ecma_extended_object_t *) obj_p)->u.class_prop.u.value);
void *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, *bytecode_prop_p);
void *bytecode_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (void, *bytecode_prop_p);
if (bytecode_p == NULL)
{