Remove vm_helper_for_in_enumerate_properties_names helper; introduce ecma_op_object_get_property_names interface for building list of an object's properties.
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
@@ -17,161 +17,6 @@
|
||||
#include "opcodes.h"
|
||||
#include "opcodes-ecma-support.h"
|
||||
|
||||
/**
|
||||
* Enumerate properties and construct collection with their
|
||||
* names for further iteration in for-in opcode handler.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 12.6.4
|
||||
*
|
||||
* @return header of constructed strings collection (should be freed with ecma_free_values_collection),
|
||||
* or NULL - if there are no properties to enumerate in for-in.
|
||||
*/
|
||||
static ecma_collection_header_t *
|
||||
vm_helper_for_in_enumerate_properties_names (ecma_object_t *obj_p) /**< starting object - result of ToObject
|
||||
* conversion (ECMA-262 v5, 12.6.4, step 4) */
|
||||
{
|
||||
const size_t bitmap_row_size = sizeof (uint32_t) * JERRY_BITSINBYTE;
|
||||
uint32_t names_hashes_bitmap[(1u << LIT_STRING_HASH_BITS) / bitmap_row_size];
|
||||
|
||||
memset (names_hashes_bitmap, 0, sizeof (names_hashes_bitmap));
|
||||
|
||||
ecma_length_t all_properties_count = 0;
|
||||
|
||||
/* First pass: counting properties */
|
||||
for (ecma_object_t *prototype_chain_iter_p = obj_p;
|
||||
prototype_chain_iter_p != NULL;
|
||||
prototype_chain_iter_p = ecma_get_object_prototype (prototype_chain_iter_p))
|
||||
{
|
||||
for (ecma_property_t *prop_iter_p = ecma_get_property_list (prototype_chain_iter_p);
|
||||
prop_iter_p != NULL;
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_t, prop_iter_p->next_property_p))
|
||||
{
|
||||
if (prop_iter_p->type == ECMA_PROPERTY_NAMEDDATA
|
||||
|| prop_iter_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
|
||||
{
|
||||
all_properties_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (prop_iter_p->type == ECMA_PROPERTY_INTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (all_properties_count == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_collection_header_t *ret_p = NULL;
|
||||
|
||||
/* Second pass: collecting properties names */
|
||||
MEM_DEFINE_LOCAL_ARRAY (names_p, all_properties_count, ecma_string_t*);
|
||||
|
||||
ecma_length_t enumerated_properties_count = 0;
|
||||
ecma_length_t non_enumerated_properties_count = 0;
|
||||
|
||||
for (ecma_object_t *prototype_chain_iter_p = obj_p;
|
||||
prototype_chain_iter_p != NULL;
|
||||
prototype_chain_iter_p = ecma_get_object_prototype (prototype_chain_iter_p))
|
||||
{
|
||||
for (ecma_property_t *prop_iter_p = ecma_get_property_list (prototype_chain_iter_p);
|
||||
prop_iter_p != NULL;
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_t, prop_iter_p->next_property_p))
|
||||
{
|
||||
if (prop_iter_p->type == ECMA_PROPERTY_NAMEDDATA
|
||||
|| prop_iter_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
|
||||
{
|
||||
bool is_enumerated;
|
||||
|
||||
ecma_string_t *prop_name_p;
|
||||
|
||||
if (prop_iter_p->type == ECMA_PROPERTY_NAMEDDATA)
|
||||
{
|
||||
prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_iter_p->u.named_data_property.name_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_iter_p->u.named_accessor_property.name_p);
|
||||
}
|
||||
|
||||
lit_string_hash_t hash = prop_name_p->hash;
|
||||
uint32_t bitmap_row = hash / bitmap_row_size;
|
||||
uint32_t bitmap_column = hash % bitmap_row_size;
|
||||
|
||||
if (ecma_is_property_enumerable (prop_iter_p))
|
||||
{
|
||||
if ((names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) == 0)
|
||||
{
|
||||
/* no name with the hash occured during the iteration session */
|
||||
is_enumerated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* name with same hash already occured */
|
||||
bool is_equal_found = false;
|
||||
|
||||
for (uint32_t index = 0;
|
||||
!is_equal_found && index < enumerated_properties_count;
|
||||
index++)
|
||||
{
|
||||
if (ecma_compare_ecma_strings (prop_name_p,
|
||||
names_p[index]))
|
||||
{
|
||||
is_equal_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t index = 0;
|
||||
!is_equal_found && index < non_enumerated_properties_count;
|
||||
index++)
|
||||
{
|
||||
if (ecma_compare_ecma_strings (prop_name_p,
|
||||
names_p[all_properties_count - index - 1]))
|
||||
{
|
||||
is_equal_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
is_enumerated = !is_equal_found;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
is_enumerated = false;
|
||||
}
|
||||
|
||||
names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column);
|
||||
|
||||
if (is_enumerated)
|
||||
{
|
||||
names_p[enumerated_properties_count++] = prop_name_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
names_p[all_properties_count - non_enumerated_properties_count++ - 1] = prop_name_p;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (enumerated_properties_count + non_enumerated_properties_count <= all_properties_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (prop_iter_p->type == ECMA_PROPERTY_INTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enumerated_properties_count != 0)
|
||||
{
|
||||
ret_p = ecma_new_strings_collection (names_p, enumerated_properties_count);
|
||||
}
|
||||
|
||||
MEM_FINALIZE_LOCAL_ARRAY (names_p);
|
||||
|
||||
return ret_p;
|
||||
} /* vm_helper_for_in_enumerate_properties_names */
|
||||
|
||||
/**
|
||||
* 'for-in' opcode handler
|
||||
*
|
||||
@@ -219,7 +64,7 @@ opfunc_for_in (vm_instr_t instr, /**< instruction */
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_expr_value);
|
||||
|
||||
ecma_collection_iterator_t names_iterator;
|
||||
ecma_collection_header_t *names_p = vm_helper_for_in_enumerate_properties_names (obj_p);
|
||||
ecma_collection_header_t *names_p = ecma_op_object_get_property_names (obj_p, false, true, true);
|
||||
|
||||
if (names_p != NULL)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user