mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Rework ecma collection (#3086)
After this patch the ecma value collection is a resizable buffer of ecma-values where the adjacent elements are allocated next to each other. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
parent
f3d3c34c30
commit
fc30f003ba
@ -795,7 +795,7 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
|
||||
|
||||
if (!(generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC))
|
||||
{
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *lit_pool_p = ecma_new_collection ();
|
||||
|
||||
ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p);
|
||||
|
||||
@ -1048,7 +1048,7 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
|
||||
static void
|
||||
scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
const uint8_t *buffer_end_p, /**< snapshot buffer end */
|
||||
ecma_collection_header_t *lit_pool_p, /**< list of known values */
|
||||
ecma_collection_t *lit_pool_p, /**< list of known values */
|
||||
const uint8_t *literal_base_p) /**< start of literal data */
|
||||
{
|
||||
JERRY_ASSERT (buffer_end_p > buffer_p);
|
||||
@ -1225,14 +1225,14 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *lit_pool_p = ecma_new_collection ();
|
||||
|
||||
for (uint32_t i = 0; i < number_of_snapshots; i++)
|
||||
{
|
||||
if (inp_buffer_sizes_p[i] < sizeof (jerry_snapshot_header_t))
|
||||
{
|
||||
*error_p = "invalid snapshot file";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1243,7 +1243,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
|| !snapshot_check_global_flags (header_p->global_flags))
|
||||
{
|
||||
*error_p = "invalid snapshot version or unsupported features present";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1271,7 +1271,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
if (functions_size >= out_buffer_size)
|
||||
{
|
||||
*error_p = "output buffer is too small";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1615,21 +1615,21 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
JERRY_ASSERT ((header_p->lit_table_offset % sizeof (uint32_t)) == 0);
|
||||
const uint8_t *literal_base_p = snapshot_data_p + header_p->lit_table_offset;
|
||||
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *lit_pool_p = ecma_new_collection ();
|
||||
scan_snapshot_functions (snapshot_data_p + header_p->func_offsets[0],
|
||||
literal_base_p,
|
||||
lit_pool_p,
|
||||
literal_base_p);
|
||||
|
||||
lit_utf8_size_t literal_count = 0;
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
ecma_value_t *buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
/* Count the valid and non-magic identifiers in the list. */
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_string (*iterator_p))
|
||||
if (ecma_is_value_string (buffer_p[i]))
|
||||
{
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* NOTE:
|
||||
* We don't save a literal (in C format) which isn't a valid
|
||||
@ -1643,13 +1643,11 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
literal_count++;
|
||||
}
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
if (literal_count == 0)
|
||||
{
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1659,13 +1657,14 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
JMEM_DEFINE_LOCAL_ARRAY (literal_array, literal_count, ecma_string_t *);
|
||||
lit_utf8_size_t literal_idx = 0;
|
||||
|
||||
iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
while (iterator_p != NULL)
|
||||
/* Count the valid and non-magic identifiers in the list. */
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_string (*iterator_p))
|
||||
if (ecma_is_value_string (buffer_p[i]))
|
||||
{
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* NOTE:
|
||||
* We don't save a literal (in C format) which isn't a valid
|
||||
@ -1679,11 +1678,9 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
literal_array[literal_idx++] = literal_p;
|
||||
}
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
|
||||
/* Sort the strings by size at first, then lexicographically. */
|
||||
jerry_save_literals_sort (literal_array, literal_count);
|
||||
|
||||
@ -2765,16 +2765,16 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
|
||||
ecma_collection_header_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (names_p);
|
||||
ecma_collection_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
ecma_value_t *buffer_p = names_p->buffer_p;
|
||||
|
||||
ecma_value_t property_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
bool continuous = true;
|
||||
|
||||
while (continuous && ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; continuous && (i < names_p->item_count); i++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
property_value = ecma_op_object_get (object_p, property_name_p);
|
||||
|
||||
@ -2783,13 +2783,11 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
|
||||
break;
|
||||
}
|
||||
|
||||
continuous = foreach_p (*ecma_value_p, property_value, user_data_p);
|
||||
continuous = foreach_p (buffer_p[i], property_value, user_data_p);
|
||||
ecma_free_value (property_value);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (names_p, 0);
|
||||
ecma_collection_free (names_p);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (property_value))
|
||||
{
|
||||
|
||||
@ -200,21 +200,29 @@ ecma_gc_mark_promise_object (ecma_extended_object_t *ext_object_p) /**< extended
|
||||
}
|
||||
|
||||
/* Mark all reactions. */
|
||||
ecma_value_t *ecma_value_p;
|
||||
ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->fulfill_reactions);
|
||||
ecma_promise_object_t *promise_object_p = (ecma_promise_object_t *) ext_object_p;
|
||||
ecma_collection_t *collection_p = promise_object_p->fulfill_reactions;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
if (collection_p != NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i]));
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->reject_reactions);
|
||||
collection_p = promise_object_p->reject_reactions;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
if (collection_p != NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i]));
|
||||
}
|
||||
}
|
||||
} /* ecma_gc_mark_promise_object */
|
||||
|
||||
@ -768,10 +776,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
case LIT_MAGIC_STRING_PROMISE_UL:
|
||||
{
|
||||
ecma_free_value_if_not_object (ext_object_p->u.class_prop.u.value);
|
||||
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->fulfill_reactions,
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->reject_reactions,
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->fulfill_reactions);
|
||||
ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->reject_reactions);
|
||||
ecma_dealloc_extended_object (object_p, sizeof (ecma_promise_object_t));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -76,7 +76,6 @@ typedef enum
|
||||
ECMA_TYPE_SYMBOL = 4, /**< pointer to description of a symbol */
|
||||
ECMA_TYPE_DIRECT_STRING = 5, /**< directly encoded string values */
|
||||
ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference (only supported by C API) */
|
||||
ECMA_TYPE_POINTER = ECMA_TYPE_ERROR, /**< a generic aligned pointer */
|
||||
ECMA_TYPE_SNAPSHOT_OFFSET = ECMA_TYPE_ERROR, /**< offset to a snapshot number/string */
|
||||
ECMA_TYPE___MAX = ECMA_TYPE_ERROR /** highest value for ecma types */
|
||||
} ecma_type_t;
|
||||
@ -1216,57 +1215,36 @@ typedef double ecma_number_t;
|
||||
*/
|
||||
#define ECMA_STRING_NOT_ARRAY_INDEX UINT32_MAX
|
||||
|
||||
/*
|
||||
* Ecma-collection: a growable list of ecma-values. Currently the list is
|
||||
* a chain list, where appending new items at the end is cheap operation.
|
||||
*
|
||||
* Enumerating elements is also cheap, since each page is terminated by a
|
||||
* special ecma-value: collection-type. This type has a pointer to the next
|
||||
* chunk. The last chunk is terminated by a NULL pointer. There when the
|
||||
* next value is requested from the iterator it simply checks the next
|
||||
* memory location. If it is not a collection-type value, it returns with
|
||||
* the value. Otherwise it gets the start address of the next chunk, and
|
||||
* return the value there.
|
||||
*
|
||||
* The collection-type value is always the last item of a collection chunk,
|
||||
* even if the chunk is not completely filled with values (this is only true
|
||||
* for the last chunk). Each chunk must have at least one non collection-type
|
||||
* value as well.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Collection flags.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS = (1u << 0), /**< do not increase the refcount of objects */
|
||||
ECMA_COLLECTION_NO_COPY = (1u << 1), /**< do not copy values */
|
||||
} ecma_collection_flag_t;
|
||||
|
||||
/**
|
||||
* Description of a collection's header.
|
||||
* Ecma-collection: a growable list of ecma-values.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jmem_cpointer_t first_chunk_cp; /**< compressed pointer to first chunk with collection's data */
|
||||
jmem_cpointer_t last_chunk_cp; /**< compressed pointer to last chunk with collection's data */
|
||||
ecma_length_t item_count; /**< number of items in the collection */
|
||||
} ecma_collection_header_t;
|
||||
uint32_t item_count; /**< number of items in the collection */
|
||||
uint32_t capacity; /**< number of items can be stored in the underlying buffer */
|
||||
ecma_value_t *buffer_p; /**< underlying data buffer */
|
||||
} ecma_collection_t;
|
||||
|
||||
/**
|
||||
* Maximum number of items stored by a collection chunk (excluding the last collection-type value).
|
||||
* Initial capacity of an ecma-collection
|
||||
*/
|
||||
#define ECMA_COLLECTION_CHUNK_ITEMS 5
|
||||
#define ECMA_COLLECTION_INITIAL_CAPACITY 4
|
||||
|
||||
/**
|
||||
* Collection chunk item.
|
||||
* Ecma-collenction grow factor when the collection underlying buffer need to be reallocated
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_value_t items[ECMA_COLLECTION_CHUNK_ITEMS + 1]; /**< ecma-value list, where the last value is a special
|
||||
* collection-type value which points to the next chunk,
|
||||
* so the chunk area is enlarged by one for this value */
|
||||
} ecma_collection_chunk_t;
|
||||
#define ECMA_COLLECTION_GROW_FACTOR (ECMA_COLLECTION_INITIAL_CAPACITY * 2)
|
||||
|
||||
/**
|
||||
* Compute the total allocated size of the collection based on it's capacity
|
||||
*/
|
||||
#define ECMA_COLLECTION_ALLOCATED_SIZE(capacity) \
|
||||
(uint32_t) (sizeof (ecma_collection_t) + (capacity * sizeof (ecma_value_t)))
|
||||
|
||||
/**
|
||||
* Initial allocated size of an ecma-collection
|
||||
*/
|
||||
#define ECMA_COLLECTION_INITIAL_SIZE ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY)
|
||||
|
||||
/**
|
||||
* Direct string types (2 bit).
|
||||
|
||||
150
jerry-core/ecma/base/ecma-helpers-collection.c
Normal file
150
jerry-core/ecma/base/ecma-helpers-collection.c
Normal file
@ -0,0 +1,150 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate a collection of ecma values.
|
||||
*
|
||||
* @return pointer to the collection
|
||||
*/
|
||||
ecma_collection_t *
|
||||
ecma_new_collection (void)
|
||||
{
|
||||
ecma_collection_t *collection_p;
|
||||
collection_p = (ecma_collection_t *) jmem_heap_alloc_block (sizeof (ecma_collection_t));
|
||||
|
||||
collection_p->item_count = 0;
|
||||
collection_p->capacity = ECMA_COLLECTION_INITIAL_CAPACITY;
|
||||
const uint32_t size = ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY);
|
||||
collection_p->buffer_p = (ecma_value_t *) jmem_heap_alloc_block (size);
|
||||
|
||||
return collection_p;
|
||||
} /* ecma_new_collection */
|
||||
|
||||
/**
|
||||
* Deallocate a collection of ecma values without freeing it's values
|
||||
*/
|
||||
inline void JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_collection_destroy (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
jmem_heap_free_block (collection_p->buffer_p, ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity));
|
||||
jmem_heap_free_block (collection_p, sizeof (ecma_collection_t));
|
||||
} /* ecma_collection_destroy */
|
||||
|
||||
/**
|
||||
* Free the object collection elements and deallocate the collection
|
||||
*/
|
||||
void
|
||||
ecma_collection_free_objects (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_object (buffer_p[i]))
|
||||
{
|
||||
ecma_deref_object (ecma_get_object_from_value (buffer_p[i]));
|
||||
}
|
||||
}
|
||||
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free_objects */
|
||||
|
||||
/**
|
||||
* Free the non-object collection elements and deallocate the collection
|
||||
*/
|
||||
void
|
||||
ecma_collection_free_if_not_object (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_free_value_if_not_object (buffer_p[i]);
|
||||
}
|
||||
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free_if_not_object */
|
||||
|
||||
/**
|
||||
* Free the collection elements and deallocate the collection
|
||||
*/
|
||||
void
|
||||
ecma_collection_free (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_free_value (buffer_p[i]);
|
||||
}
|
||||
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free */
|
||||
|
||||
/**
|
||||
* Append new value to ecma values collection
|
||||
*
|
||||
* Note: The reference count of the values are not increased
|
||||
*/
|
||||
void
|
||||
ecma_collection_push_back (ecma_collection_t *collection_p, /**< value collection */
|
||||
ecma_value_t value) /**< ecma value to append */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
if (JERRY_LIKELY (collection_p->item_count < collection_p->capacity))
|
||||
{
|
||||
buffer_p[collection_p->item_count++] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t new_capacity = collection_p->capacity + ECMA_COLLECTION_GROW_FACTOR;
|
||||
const uint32_t old_size = ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity);
|
||||
const uint32_t new_size = ECMA_COLLECTION_ALLOCATED_SIZE (new_capacity);
|
||||
|
||||
buffer_p = jmem_heap_realloc_block (buffer_p, old_size, new_size);
|
||||
buffer_p[collection_p->item_count++] = value;
|
||||
collection_p->capacity = new_capacity;
|
||||
|
||||
collection_p->buffer_p = buffer_p;
|
||||
} /* ecma_collection_push_back */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
@ -389,18 +389,6 @@ ecma_is_value_error_reference (ecma_value_t value) /**< ecma value */
|
||||
return (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
|
||||
} /* ecma_is_value_error_reference */
|
||||
|
||||
/**
|
||||
* Check if the value is an aligned pointer.
|
||||
*
|
||||
* @return true - if the value contains an aligned pointer,
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_is_value_pointer (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
return (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER);
|
||||
} /* ecma_is_value_pointer */
|
||||
|
||||
/**
|
||||
* Debug assertion that specified value's type is one of ECMA-defined
|
||||
* script-visible types, i.e.: undefined, null, boolean, number, string, object.
|
||||
@ -658,29 +646,6 @@ ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) /**<
|
||||
return ecma_pointer_to_ecma_value (error_ref_p) | ECMA_TYPE_ERROR;
|
||||
} /* ecma_make_error_reference_value */
|
||||
|
||||
/**
|
||||
* Create an ecma value from an aligned pointer
|
||||
*
|
||||
* @return ecma-value representation of the aligned pointer
|
||||
*/
|
||||
inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_make_pointer_value (const void *any_p) /**< any aligned pointer */
|
||||
{
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
|
||||
uintptr_t uint_ptr = (uintptr_t) any_p;
|
||||
JERRY_ASSERT ((uint_ptr & ECMA_VALUE_TYPE_MASK) == 0);
|
||||
return ((ecma_value_t) uint_ptr) | ECMA_TYPE_POINTER;
|
||||
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
|
||||
jmem_cpointer_t ptr_cp;
|
||||
ECMA_SET_POINTER (ptr_cp, any_p);
|
||||
return (((ecma_value_t) ptr_cp) << ECMA_VALUE_SHIFT) | ECMA_TYPE_POINTER;
|
||||
|
||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
} /* ecma_make_pointer_value */
|
||||
|
||||
/**
|
||||
* Get integer value from an integer ecma value
|
||||
*
|
||||
@ -813,23 +778,6 @@ ecma_get_error_reference_from_value (ecma_value_t value) /**< ecma value */
|
||||
return (ecma_error_reference_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_error_reference_from_value */
|
||||
|
||||
/**
|
||||
* Get an aligned pointer from an ecma value
|
||||
*
|
||||
* @return pointer value
|
||||
*/
|
||||
inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_get_pointer_from_value (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER);
|
||||
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
return (void *) (uintptr_t) ((value) & ~ECMA_VALUE_TYPE_MASK);
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
return ECMA_GET_POINTER (void, value >> ECMA_VALUE_SHIFT);
|
||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
} /* ecma_get_pointer_from_value */
|
||||
|
||||
/**
|
||||
* Invert a boolean value
|
||||
*
|
||||
|
||||
@ -1,201 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The type of ecma error and ecma collection chunk must be the same.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_TYPE_ERROR == ECMA_TYPE_POINTER,
|
||||
ecma_type_error_must_be_the_same_as_ecma_type_pointer);
|
||||
|
||||
/**
|
||||
* Allocate a collection of ecma values.
|
||||
*
|
||||
* @return pointer to the collection's header
|
||||
*/
|
||||
ecma_collection_header_t *
|
||||
ecma_new_values_collection (void)
|
||||
{
|
||||
ecma_collection_header_t *header_p;
|
||||
header_p = (ecma_collection_header_t *) jmem_pools_alloc (sizeof (ecma_collection_header_t));
|
||||
|
||||
header_p->item_count = 0;
|
||||
header_p->first_chunk_cp = ECMA_NULL_POINTER;
|
||||
header_p->last_chunk_cp = ECMA_NULL_POINTER;
|
||||
|
||||
return header_p;
|
||||
} /* ecma_new_values_collection */
|
||||
|
||||
/**
|
||||
* Free the collection of ecma values.
|
||||
*/
|
||||
void
|
||||
ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
|
||||
uint32_t flags) /**< combination of ecma_collection_flag_t flags */
|
||||
{
|
||||
jmem_cpointer_t chunk_cp = header_p->first_chunk_cp;
|
||||
|
||||
jmem_pools_free (header_p, sizeof (ecma_collection_header_t));
|
||||
|
||||
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;
|
||||
|
||||
JERRY_ASSERT (!ecma_is_value_pointer (*item_p));
|
||||
|
||||
do
|
||||
{
|
||||
if (!(flags & ECMA_COLLECTION_NO_COPY)
|
||||
&& (!ecma_is_value_object (*item_p)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
|
||||
{
|
||||
ecma_free_value (*item_p);
|
||||
}
|
||||
|
||||
item_p++;
|
||||
}
|
||||
while (!ecma_is_value_pointer (*item_p));
|
||||
|
||||
ecma_collection_chunk_t *next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (*item_p);
|
||||
|
||||
jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
|
||||
|
||||
chunk_p = next_chunk_p;
|
||||
}
|
||||
while (chunk_p != NULL);
|
||||
} /* ecma_free_values_collection */
|
||||
|
||||
/**
|
||||
* Append new value to ecma values collection
|
||||
*/
|
||||
void
|
||||
ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
|
||||
ecma_value_t value, /**< ecma value to append */
|
||||
uint32_t flags) /**< combination of ecma_collection_flag_t flags */
|
||||
{
|
||||
ecma_length_t item_index;
|
||||
ecma_collection_chunk_t *chunk_p;
|
||||
|
||||
if (JERRY_UNLIKELY (header_p->item_count == 0))
|
||||
{
|
||||
item_index = 0;
|
||||
chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t));
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (header_p->first_chunk_cp, chunk_p);
|
||||
header_p->last_chunk_cp = header_p->first_chunk_cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
item_index = header_p->item_count % ECMA_COLLECTION_CHUNK_ITEMS;
|
||||
|
||||
chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
|
||||
header_p->last_chunk_cp);
|
||||
|
||||
if (JERRY_UNLIKELY (item_index == 0))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS])
|
||||
&& ecma_get_pointer_from_value (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS]) == NULL);
|
||||
|
||||
ecma_collection_chunk_t *next_chunk_p;
|
||||
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_NON_NULL_POINTER (header_p->last_chunk_cp, next_chunk_p);
|
||||
|
||||
chunk_p = next_chunk_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[item_index])
|
||||
&& ecma_get_pointer_from_value (chunk_p->items[item_index]) == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & ECMA_COLLECTION_NO_COPY)
|
||||
&& (!ecma_is_value_object (value)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
|
||||
{
|
||||
value = ecma_copy_value (value);
|
||||
}
|
||||
|
||||
chunk_p->items[item_index] = value;
|
||||
chunk_p->items[item_index + 1] = ecma_make_pointer_value (NULL);
|
||||
header_p->item_count++;
|
||||
} /* ecma_append_to_values_collection */
|
||||
|
||||
/**
|
||||
* Initialize new collection iterator for the collection
|
||||
*
|
||||
* @return pointer to the first item
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_init (ecma_collection_header_t *header_p) /**< header of collection */
|
||||
{
|
||||
if (JERRY_UNLIKELY (!header_p || header_p->item_count == 0))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_collection_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
|
||||
header_p->first_chunk_cp);
|
||||
|
||||
return chunk_p->items;
|
||||
} /* ecma_collection_iterator_init */
|
||||
|
||||
/**
|
||||
* Move collection iterator to next element if there is any.
|
||||
*
|
||||
* @return pointer to the next item
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_next (ecma_value_t *ecma_value_p) /**< current value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_value_p != NULL);
|
||||
|
||||
ecma_value_p++;
|
||||
|
||||
if (JERRY_UNLIKELY (ecma_is_value_pointer (*ecma_value_p)))
|
||||
{
|
||||
ecma_value_p = ((ecma_collection_chunk_t *) ecma_get_pointer_from_value (*ecma_value_p))->items;
|
||||
|
||||
JERRY_ASSERT (ecma_value_p == NULL || !ecma_is_value_pointer (*ecma_value_p));
|
||||
return ecma_value_p;
|
||||
}
|
||||
|
||||
return ecma_value_p;
|
||||
} /* ecma_collection_iterator_next */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
@ -184,7 +184,6 @@ bool JERRY_ATTR_CONST ecma_is_value_direct_string (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_non_direct_string (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_object (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_error_reference (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_pointer (ecma_value_t value);
|
||||
|
||||
void ecma_check_value_type_is_spec_defined (ecma_value_t value);
|
||||
|
||||
@ -203,7 +202,6 @@ ecma_value_t JERRY_ATTR_PURE ecma_make_prop_name_value (const ecma_string_t *ecm
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_magic_string_value (lit_magic_string_id_t id);
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_object_value (const ecma_object_t *object_p);
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p);
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_pointer_value (const void *any_p);
|
||||
ecma_integer_value_t JERRY_ATTR_CONST ecma_get_integer_from_value (ecma_value_t value);
|
||||
ecma_number_t JERRY_ATTR_PURE ecma_get_float_from_value (ecma_value_t value);
|
||||
ecma_number_t * ecma_get_pointer_from_float_value (ecma_value_t value);
|
||||
@ -215,7 +213,6 @@ ecma_string_t JERRY_ATTR_PURE *ecma_get_symbol_from_value (ecma_value_t value);
|
||||
ecma_string_t JERRY_ATTR_PURE *ecma_get_prop_name_from_value (ecma_value_t value);
|
||||
ecma_object_t JERRY_ATTR_PURE *ecma_get_object_from_value (ecma_value_t value);
|
||||
ecma_error_reference_t JERRY_ATTR_PURE *ecma_get_error_reference_from_value (ecma_value_t value);
|
||||
void * JERRY_ATTR_PURE ecma_get_pointer_from_value (ecma_value_t value);
|
||||
ecma_value_t JERRY_ATTR_CONST ecma_invert_boolean_value (ecma_value_t value);
|
||||
ecma_value_t ecma_copy_value (ecma_value_t value);
|
||||
ecma_value_t ecma_fast_copy_value (ecma_value_t value);
|
||||
@ -351,15 +348,13 @@ lit_utf8_size_t ecma_number_to_binary_floating_point_number (ecma_number_t num,
|
||||
lit_utf8_byte_t *out_digits_p,
|
||||
int32_t *out_decimal_exp_p);
|
||||
|
||||
/* ecma-helpers-values-collection.c */
|
||||
ecma_collection_header_t *ecma_new_values_collection (void);
|
||||
void ecma_free_values_collection (ecma_collection_header_t *header_p, uint32_t flags);
|
||||
void ecma_append_to_values_collection (ecma_collection_header_t *header_p, ecma_value_t v, uint32_t flags);
|
||||
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_init (ecma_collection_header_t *header_p);
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_next (ecma_value_t *iterator_p);
|
||||
/* ecma-helpers-collection.c */
|
||||
ecma_collection_t *ecma_new_collection (void);
|
||||
void ecma_collection_push_back (ecma_collection_t *collection_p, ecma_value_t value);
|
||||
void ecma_collection_destroy (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free_if_not_object (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free_objects (ecma_collection_t *collection_p);
|
||||
|
||||
/* ecma-helpers.c */
|
||||
ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type);
|
||||
|
||||
@ -298,7 +298,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
* Append the value at the end of the appropriate list if it is not present there.
|
||||
*/
|
||||
void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appended */
|
||||
ecma_collection_header_t *lit_pool_p) /**< list of known values */
|
||||
ecma_collection_t *lit_pool_p) /**< list of known values */
|
||||
{
|
||||
/* Unlike direct numbers, direct strings are converted to character literals. */
|
||||
if (!ecma_is_value_string (value) && !ecma_is_value_float_number (value))
|
||||
@ -306,21 +306,19 @@ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appen
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
ecma_value_t *buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
/* Strings / numbers are direct strings or stored in the literal storage.
|
||||
* Therefore direct comparison is enough to find the same strings / numbers. */
|
||||
if (*iterator_p == value)
|
||||
if (buffer_p[i] == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
ecma_append_to_values_collection (lit_pool_p, value, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_push_back (lit_pool_p, value);
|
||||
} /* ecma_save_literals_append_value */
|
||||
|
||||
/**
|
||||
@ -328,7 +326,7 @@ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appen
|
||||
*/
|
||||
void
|
||||
ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< byte-code data */
|
||||
ecma_collection_header_t *lit_pool_p) /**< list of known values */
|
||||
ecma_collection_t *lit_pool_p) /**< list of known values */
|
||||
{
|
||||
ecma_value_t *literal_p;
|
||||
uint32_t argument_end = 0;
|
||||
@ -414,7 +412,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list of known values */
|
||||
ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, /**< list of known values */
|
||||
uint32_t *buffer_p, /**< [out] output snapshot buffer */
|
||||
size_t buffer_size, /**< size of the buffer */
|
||||
size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */
|
||||
@ -437,18 +435,18 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
max_lit_table_size = (UINT32_MAX >> JERRY_SNAPSHOT_LITERAL_SHIFT);
|
||||
}
|
||||
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
ecma_value_t *lit_buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
/* Compute the size of the literal pool. */
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_float_number (*iterator_p))
|
||||
if (ecma_is_value_float_number (lit_buffer_p[i]))
|
||||
{
|
||||
lit_table_size += (uint32_t) sizeof (ecma_number_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (lit_buffer_p[i]);
|
||||
|
||||
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
@ -457,11 +455,9 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
/* Check whether enough space is available and the maximum size is not reached. */
|
||||
if (lit_table_size > max_lit_table_size)
|
||||
{
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return false;
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
lit_mem_to_snapshot_id_map_entry_t *map_p;
|
||||
@ -479,28 +475,28 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
*out_map_p = map_p;
|
||||
*out_map_len_p = total_count;
|
||||
|
||||
iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
lit_buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
/* Generate literal pool data. */
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
map_p->literal_id = *iterator_p;
|
||||
map_p->literal_id = lit_buffer_p[i];
|
||||
map_p->literal_offset = (literal_offset << JERRY_SNAPSHOT_LITERAL_SHIFT) | ECMA_TYPE_SNAPSHOT_OFFSET;
|
||||
|
||||
ecma_length_t length;
|
||||
|
||||
if (ecma_is_value_float_number (*iterator_p))
|
||||
if (ecma_is_value_float_number (lit_buffer_p[i]))
|
||||
{
|
||||
map_p->literal_offset |= JERRY_SNAPSHOT_LITERAL_IS_NUMBER;
|
||||
|
||||
ecma_number_t num = ecma_get_float_from_value (*iterator_p);
|
||||
ecma_number_t num = ecma_get_float_from_value (lit_buffer_p[i]);
|
||||
memcpy (destination_p, &num, sizeof (ecma_number_t));
|
||||
|
||||
length = JERRY_ALIGNUP (sizeof (ecma_number_t), JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (lit_buffer_p[i]);
|
||||
length = ecma_string_get_size (string_p);
|
||||
|
||||
*(uint16_t *) destination_p = (uint16_t) length;
|
||||
@ -514,11 +510,10 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
destination_p += length;
|
||||
literal_offset += length;
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
map_p++;
|
||||
}
|
||||
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return true;
|
||||
} /* ecma_save_literals_for_snapshot */
|
||||
|
||||
|
||||
@ -44,10 +44,10 @@ ecma_value_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p,
|
||||
ecma_value_t ecma_find_or_create_literal_number (ecma_number_t number_arg);
|
||||
|
||||
#if ENABLED (JERRY_SNAPSHOT_SAVE)
|
||||
void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_header_t *lit_pool_p);
|
||||
void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_t *lit_pool_p);
|
||||
void ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p,
|
||||
ecma_collection_header_t *lit_pool_p);
|
||||
bool ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, uint32_t *buffer_p, size_t buffer_size,
|
||||
ecma_collection_t *lit_pool_p);
|
||||
bool ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, uint32_t *buffer_p, size_t buffer_size,
|
||||
size_t *in_out_buffer_offset_p, lit_mem_to_snapshot_id_map_entry_t **out_map_p,
|
||||
uint32_t *out_map_len_p);
|
||||
#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
|
||||
|
||||
@ -952,17 +952,16 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Compare function is not callable."));
|
||||
}
|
||||
|
||||
ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ARRAY_INDICES);
|
||||
ecma_collection_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ARRAY_INDICES);
|
||||
|
||||
uint32_t defined_prop_count = 0;
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
|
||||
ecma_value_t *buffer_p = array_index_props_p->buffer_p;
|
||||
|
||||
/* Count properties with name that is array index less than len */
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < array_index_props_p->item_count; i++)
|
||||
{
|
||||
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_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
@ -977,13 +976,12 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
|
||||
uint32_t copied_num = 0;
|
||||
JMEM_DEFINE_LOCAL_ARRAY (values_buffer, defined_prop_count, ecma_value_t);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
|
||||
buffer_p = array_index_props_p->buffer_p;
|
||||
|
||||
/* Copy unsorted array into a native c array. */
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < array_index_props_p->item_count; i++)
|
||||
{
|
||||
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_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
@ -1045,7 +1043,7 @@ clean_up:
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
ecma_free_values_collection (array_index_props_p, 0);
|
||||
ecma_collection_free (array_index_props_p);
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
@ -1053,12 +1051,11 @@ clean_up:
|
||||
|
||||
/* Undefined properties should be in the back of the array. */
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
|
||||
buffer_p = array_index_props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < array_index_props_p->item_count; i++)
|
||||
{
|
||||
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_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
@ -1069,13 +1066,13 @@ clean_up:
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (del_value))
|
||||
{
|
||||
ecma_free_values_collection (array_index_props_p, 0);
|
||||
ecma_collection_free (array_index_props_p);
|
||||
return del_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ecma_free_values_collection (array_index_props_p, 0);
|
||||
ecma_collection_free (array_index_props_p);
|
||||
|
||||
return ecma_copy_value (this_arg);
|
||||
} /* ecma_builtin_array_prototype_object_sort */
|
||||
|
||||
@ -63,21 +63,19 @@ ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, /**< s
|
||||
* @return true, if the string is already in the collection.
|
||||
*/
|
||||
bool
|
||||
ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, /**< collection */
|
||||
ecma_has_string_value_in_collection (ecma_collection_t *collection_p, /**< collection */
|
||||
ecma_string_t *string_p) /**< string */
|
||||
{
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (collection_p);
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *current_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *current_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
if (ecma_compare_ecma_strings (current_p, string_p))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -278,29 +278,22 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
|
||||
uint32_t index = 0;
|
||||
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, opts);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, opts);
|
||||
|
||||
if (props_p->item_count == 0)
|
||||
{
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_destroy (props_p);
|
||||
return new_array;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (((ecma_extended_object_t *) new_array_p)->u.array.is_fast_mode);
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
ecma_value_t *values_p = ecma_fast_array_extend (new_array_p, props_p->item_count);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
memcpy (values_p, buffer_p, props_p->item_count * sizeof (ecma_value_t));
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
{
|
||||
values_p[index++] = ecma_copy_value_if_not_object (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free_objects (props_p);
|
||||
|
||||
return new_array;
|
||||
} /* ecma_builtin_helper_object_get_properties */
|
||||
|
||||
@ -153,7 +153,7 @@ typedef struct struct_ecma_json_occurence_stack_item_t
|
||||
typedef struct
|
||||
{
|
||||
/** Collection for property keys. */
|
||||
ecma_collection_header_t *property_list_p;
|
||||
ecma_collection_t *property_list_p;
|
||||
|
||||
/** Collection for traversing objects. */
|
||||
ecma_json_occurence_stack_item_t *occurence_stack_last_p;
|
||||
@ -175,15 +175,11 @@ ecma_value_t ecma_builtin_json_parse_buffer (const lit_utf8_byte_t * str_start_p
|
||||
lit_utf8_size_t string_size);
|
||||
ecma_value_t ecma_builtin_json_string_from_object (const ecma_value_t arg1);
|
||||
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_string_t *string_p);
|
||||
bool ecma_has_string_value_in_collection (ecma_collection_t *collection_p, ecma_string_t *string_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_json_create_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket,
|
||||
ecma_string_t *stepback_p, ecma_collection_header_t *partial_p,
|
||||
ecma_json_stringify_context_t *context_p);
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_json_create_non_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket,
|
||||
ecma_collection_header_t *partial_p);
|
||||
ecma_collection_t *partial_p);
|
||||
#endif /* ENABLED (JERRY_BUILTIN_JSON) */
|
||||
|
||||
/* ecma-builtin-helper-error.c */
|
||||
|
||||
@ -636,15 +636,14 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f
|
||||
{
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (value);
|
||||
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
/* 3.d.iii */
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
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_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 3.d.iii.1 */
|
||||
ecma_value_t result = ecma_builtin_json_internalize_property (reviver_p, object_p, property_name_p);
|
||||
@ -652,7 +651,7 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f
|
||||
/* 3.d.iii.2 */
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
ecma_deref_object (object_p);
|
||||
|
||||
return result;
|
||||
@ -676,7 +675,7 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f
|
||||
}
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
}
|
||||
|
||||
ecma_value_t arguments_list[2];
|
||||
@ -898,7 +897,7 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /*
|
||||
const bool has_gap = !ecma_compare_ecma_string_to_magic_id (context_p->gap_str_p, LIT_MAGIC_STRING__EMPTY);
|
||||
const lit_utf8_size_t separator_size = ecma_stringbuilder_get_size (&context_p->indent_builder);
|
||||
|
||||
ecma_collection_header_t *property_keys_p;
|
||||
ecma_collection_t *property_keys_p;
|
||||
/* 5. */
|
||||
if (context_p->property_list_p->item_count > 0)
|
||||
{
|
||||
@ -911,14 +910,14 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /*
|
||||
}
|
||||
|
||||
/* 8. */
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (property_keys_p);
|
||||
ecma_value_t *buffer_p = property_keys_p->buffer_p;
|
||||
|
||||
ecma_stringbuilder_append_byte (&context_p->result_builder, LIT_CHAR_LEFT_BRACE);
|
||||
const lit_utf8_size_t left_brace = ecma_stringbuilder_get_size (&context_p->result_builder);
|
||||
lit_utf8_size_t last_prop = left_brace;
|
||||
|
||||
ecma_value_t result = ECMA_VALUE_EMPTY;
|
||||
while (ecma_value_p != NULL)
|
||||
|
||||
for (uint32_t i = 0; i < property_keys_p->item_count; i++)
|
||||
{
|
||||
if (has_gap)
|
||||
{
|
||||
@ -927,7 +926,7 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /*
|
||||
separator_size);
|
||||
}
|
||||
|
||||
ecma_string_t *key_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *key_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
ecma_builtin_json_quote (&context_p->result_builder, key_p);
|
||||
ecma_stringbuilder_append_byte (&context_p->result_builder, LIT_CHAR_COLON);
|
||||
|
||||
@ -958,8 +957,6 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /*
|
||||
/* The property should not be appended, we must backtrack. */
|
||||
ecma_stringbuilder_revert (&context_p->result_builder, last_prop);
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
if (last_prop != left_brace)
|
||||
@ -988,7 +985,7 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /*
|
||||
cleanup:
|
||||
if (context_p->property_list_p->item_count == 0)
|
||||
{
|
||||
ecma_free_values_collection (property_keys_p, 0);
|
||||
ecma_collection_free (property_keys_p);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1334,7 +1331,7 @@ ecma_builtin_json_string_from_object (const ecma_value_t arg1) /**< object argum
|
||||
ecma_json_stringify_context_t context;
|
||||
context.occurence_stack_last_p = NULL;
|
||||
context.indent_builder = ecma_stringbuilder_create ();
|
||||
context.property_list_p = ecma_new_values_collection ();
|
||||
context.property_list_p = ecma_new_collection ();
|
||||
context.replacer_function_p = NULL;
|
||||
context.gap_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
|
||||
|
||||
@ -1342,7 +1339,7 @@ ecma_builtin_json_string_from_object (const ecma_value_t arg1) /**< object argum
|
||||
|
||||
ecma_deref_ecma_string (context.gap_str_p);
|
||||
ecma_stringbuilder_destroy (&context.indent_builder);
|
||||
ecma_free_values_collection (context.property_list_p, 0);
|
||||
ecma_collection_free (context.property_list_p);
|
||||
return ret_value;
|
||||
} /*ecma_builtin_json_string_from_object*/
|
||||
|
||||
@ -1365,7 +1362,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
ecma_json_stringify_context_t context;
|
||||
context.replacer_function_p = NULL;
|
||||
context.property_list_p = ecma_new_values_collection ();
|
||||
context.property_list_p = ecma_new_collection ();
|
||||
|
||||
/* 4. */
|
||||
if (ecma_is_value_object (arg2))
|
||||
@ -1393,7 +1390,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (value))
|
||||
{
|
||||
ecma_free_values_collection (context.property_list_p, 0);
|
||||
ecma_collection_free (context.property_list_p);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1422,7 +1419,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (str_val))
|
||||
{
|
||||
ecma_free_values_collection (context.property_list_p, 0);
|
||||
ecma_collection_free (context.property_list_p);
|
||||
ecma_free_value (value);
|
||||
return str_val;
|
||||
}
|
||||
@ -1440,7 +1437,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
if (!ecma_has_string_value_in_collection (context.property_list_p, string_p))
|
||||
{
|
||||
ecma_append_to_values_collection (context.property_list_p, item, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_push_back (context.property_list_p, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1468,7 +1465,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (value))
|
||||
{
|
||||
ecma_free_values_collection (context.property_list_p, 0);
|
||||
ecma_collection_free (context.property_list_p);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1481,7 +1478,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (value))
|
||||
{
|
||||
ecma_free_values_collection (context.property_list_p, 0);
|
||||
ecma_collection_free (context.property_list_p);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1554,7 +1551,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
ecma_deref_ecma_string (context.gap_str_p);
|
||||
ecma_stringbuilder_destroy (&context.indent_builder);
|
||||
ecma_free_values_collection (context.property_list_p, 0);
|
||||
ecma_collection_free (context.property_list_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_json_stringify */
|
||||
|
||||
@ -321,14 +321,13 @@ ecma_builtin_object_object_get_own_property_symbols (ecma_object_t *obj_p) /**<
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
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_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
@ -351,14 +350,14 @@ ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument *
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
/* 3. */
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
@ -380,14 +379,13 @@ ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument *
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
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_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
@ -417,14 +415,14 @@ ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
/* 3. */
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
@ -478,14 +476,13 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
ecma_value_t ret_value = ECMA_VALUE_TRUE;
|
||||
|
||||
/* 2. */
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
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_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
|
||||
@ -510,7 +507,7 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
}
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_object_frozen_or_sealed_helper */
|
||||
@ -597,21 +594,20 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine
|
||||
|
||||
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, ECMA_LIST_CONVERT_FAST_ARRAYS
|
||||
| ECMA_LIST_ENUMERABLE);
|
||||
uint32_t property_number = prop_names_p->item_count;
|
||||
ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (props_p, ECMA_LIST_CONVERT_FAST_ARRAYS
|
||||
| ECMA_LIST_ENUMERABLE);
|
||||
ecma_value_t ret_value = ECMA_VALUE_ERROR;
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
ecma_value_t *buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
/* 4. */
|
||||
JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t);
|
||||
JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, prop_names_p->item_count, ecma_property_descriptor_t);
|
||||
uint32_t property_descriptor_number = 0;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < prop_names_p->item_count; i++)
|
||||
{
|
||||
/* 5.a */
|
||||
ecma_value_t desc_obj = ecma_op_object_get (props_p, ecma_get_string_from_value (*ecma_value_p));
|
||||
ecma_value_t desc_obj = ecma_op_object_get (props_p, ecma_get_string_from_value (buffer_p[i]));
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (desc_obj))
|
||||
{
|
||||
@ -634,26 +630,22 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine
|
||||
property_descriptor_number++;
|
||||
|
||||
ecma_free_value (conv_result);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
for (uint32_t index = 0; index < property_number; index++)
|
||||
for (uint32_t i = 0; i < prop_names_p->item_count; i++)
|
||||
{
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_string_from_value (*ecma_value_p),
|
||||
&property_descriptors[index]);
|
||||
ecma_get_string_from_value (buffer_p[i]),
|
||||
&property_descriptors[i]);
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_ref_object (obj_p);
|
||||
@ -670,7 +662,7 @@ cleanup:
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (property_descriptors);
|
||||
|
||||
ecma_free_values_collection (prop_names_p, 0);
|
||||
ecma_collection_free (prop_names_p);
|
||||
|
||||
ecma_deref_object (props_p);
|
||||
|
||||
@ -821,14 +813,14 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a
|
||||
|
||||
/* 5.b.iii */
|
||||
/* TODO: extends this collection if symbols will be supported */
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS
|
||||
| ECMA_LIST_ENUMERABLE);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS
|
||||
| ECMA_LIST_ENUMERABLE);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
|
||||
for (uint32_t j = 0; (j < props_p->item_count) && ecma_is_value_empty (ret_value); j++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[j]);
|
||||
|
||||
/* 5.c.i-ii */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
@ -866,12 +858,10 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a
|
||||
ecma_free_value (prop_value);
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_deref_object (from_obj_p);
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
|
||||
@ -898,24 +898,22 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
* properties,
|
||||
* false - list all properties into main collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_is_builtin (object_p));
|
||||
|
||||
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
|
||||
&& ecma_builtin_function_is_routine (object_p))
|
||||
{
|
||||
ecma_collection_header_t *for_enumerable_p = main_collection_p;
|
||||
ecma_collection_t *for_enumerable_p = main_collection_p;
|
||||
JERRY_UNUSED (for_enumerable_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'length' property is non-enumerable (ECMA-262 v5, 15) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -941,7 +939,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
ecma_length_t index = 0;
|
||||
uint32_t *bitset_p = built_in_props_p->instantiated_bitset;
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p
|
||||
ecma_collection_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p
|
||||
: main_collection_p);
|
||||
|
||||
while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT)
|
||||
@ -969,11 +967,9 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
{
|
||||
ecma_value_t name = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->magic_string_id);
|
||||
|
||||
ecma_append_to_values_collection (for_non_enumerable_p, name, 0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, name);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
|
||||
curr_property_p++;
|
||||
index++;
|
||||
}
|
||||
|
||||
@ -92,8 +92,8 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t
|
||||
void
|
||||
ecma_builtin_list_lazy_property_names (ecma_object_t *object_p,
|
||||
bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
bool
|
||||
ecma_builtin_is (ecma_object_t *obj_p, ecma_builtin_id_t builtin_id);
|
||||
ecma_object_t *
|
||||
|
||||
@ -492,7 +492,7 @@ ecma_fast_array_set_length (ecma_object_t *object_p, /**< fast access mode array
|
||||
*
|
||||
* @return collection of strings - property names
|
||||
*/
|
||||
ecma_collection_header_t *
|
||||
ecma_collection_t *
|
||||
ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mode array object */
|
||||
uint32_t opts) /**< any combination of ecma_list_properties_options_t values */
|
||||
{
|
||||
@ -501,7 +501,7 @@ ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mo
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
|
||||
ecma_collection_header_t *ret_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *ret_p = ecma_new_collection ();
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
if (opts & ECMA_LIST_SYMBOLS)
|
||||
@ -518,7 +518,7 @@ ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mo
|
||||
{
|
||||
if (append_length)
|
||||
{
|
||||
ecma_append_to_values_collection (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), 0);
|
||||
ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
}
|
||||
|
||||
return ret_p;
|
||||
@ -535,12 +535,12 @@ ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mo
|
||||
|
||||
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i);
|
||||
|
||||
ecma_append_to_values_collection (ret_p, ecma_make_string_value (index_str_p), ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_push_back (ret_p, ecma_make_string_value (index_str_p));
|
||||
}
|
||||
|
||||
if (append_length)
|
||||
{
|
||||
ecma_append_to_values_collection (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), 0);
|
||||
ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
}
|
||||
|
||||
if (opts & ECMA_LIST_CONVERT_FAST_ARRAYS)
|
||||
@ -1094,19 +1094,16 @@ ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obje
|
||||
* false - list all properties into main
|
||||
* collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
} /* ecma_op_array_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
|
||||
@ -62,7 +62,7 @@ void
|
||||
ecma_array_object_delete_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_property_value_t *prop_value_p);
|
||||
|
||||
ecma_collection_header_t *
|
||||
ecma_collection_t *
|
||||
ecma_fast_array_get_property_names (ecma_object_t *object_p, uint32_t opts);
|
||||
|
||||
void
|
||||
@ -87,8 +87,8 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, ecma_string_t
|
||||
|
||||
void
|
||||
ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@ -457,23 +457,22 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
|
||||
|
||||
ecma_object_t *internal_obj_p = ecma_get_object_from_value (map_object_p->header.u.class_prop.u.value);
|
||||
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
ecma_ref_object (internal_obj_p);
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[i]);
|
||||
ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p);
|
||||
JERRY_ASSERT (property_p != NULL);
|
||||
|
||||
if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value))
|
||||
{
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -497,7 +496,7 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
else
|
||||
{
|
||||
key_arg = *ecma_value_p;
|
||||
key_arg = buffer_p[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -514,12 +513,10 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
|
||||
ecma_free_value (call_value);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_deref_object (internal_obj_p);
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_container_foreach */
|
||||
@ -664,7 +661,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
ecma_map_object_t *map_object_p = (ecma_map_object_t *) (ecma_get_object_from_value (iterated_value));
|
||||
|
||||
ecma_object_t *internal_obj_p = ecma_get_object_from_value (map_object_p->header.u.class_prop.u.value);
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
|
||||
uint32_t length = props_p->item_count;
|
||||
uint32_t index = ext_obj_p->u.pseudo_array.u1.iterator_index;
|
||||
@ -698,34 +695,31 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
if (index >= length)
|
||||
{
|
||||
ext_obj_p->u.pseudo_array.u2.iterated_value = ECMA_VALUE_EMPTY;
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE);
|
||||
}
|
||||
|
||||
uint8_t iterator_kind = ext_obj_p->u.pseudo_array.extra_info;
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
index--;
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
continue;
|
||||
}
|
||||
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[i]);
|
||||
ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p);
|
||||
JERRY_ASSERT (property_p != NULL);
|
||||
|
||||
if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value))
|
||||
{
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
|
||||
if (ecma_value_p == NULL)
|
||||
if (i == props_p->item_count - 1)
|
||||
{
|
||||
ret_value = ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE);
|
||||
}
|
||||
@ -752,7 +746,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
}
|
||||
else
|
||||
{
|
||||
key_arg = *ecma_value_p;
|
||||
key_arg = buffer_p[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -779,7 +773,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
break;
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_container_iterator_next */
|
||||
|
||||
@ -1416,24 +1416,20 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
|
||||
* false - list all properties into main
|
||||
* collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_UNUSED (main_collection_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
|
||||
/* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
|
||||
|
||||
const ecma_compiled_code_t *bytecode_data_p;
|
||||
|
||||
@ -1453,14 +1449,10 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
|
||||
{
|
||||
/* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
|
||||
|
||||
/* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
|
||||
}
|
||||
} /* ecma_op_function_list_lazy_property_names */
|
||||
|
||||
@ -1480,19 +1472,16 @@ ecma_op_external_function_list_lazy_property_names (bool separate_enumerable, /*
|
||||
* false - list all properties into
|
||||
* main collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* collection */
|
||||
{
|
||||
JERRY_UNUSED (main_collection_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
|
||||
} /* ecma_op_external_function_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
@ -1511,30 +1500,23 @@ ecma_op_bound_function_list_lazy_property_names (bool separate_enumerable, /**<
|
||||
* false - list all properties into
|
||||
* main collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_UNUSED (main_collection_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
|
||||
/* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
|
||||
|
||||
/* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
|
||||
} /* ecma_op_bound_function_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
|
||||
@ -97,18 +97,18 @@ ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p
|
||||
void
|
||||
ecma_op_function_list_lazy_property_names (ecma_object_t *object_p,
|
||||
bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
void
|
||||
ecma_op_external_function_list_lazy_property_names (bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
void
|
||||
ecma_op_bound_function_list_lazy_property_names (bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@ -1654,7 +1654,7 @@ ecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */
|
||||
*
|
||||
* @return collection of strings - property names
|
||||
*/
|
||||
ecma_collection_header_t *
|
||||
ecma_collection_t *
|
||||
ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
uint32_t opts) /**< any combination of ecma_list_properties_options_t values */
|
||||
{
|
||||
@ -1671,8 +1671,8 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
}
|
||||
}
|
||||
|
||||
ecma_collection_header_t *ret_p = ecma_new_values_collection ();
|
||||
ecma_collection_header_t *skipped_non_enumerable_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *ret_p = ecma_new_collection ();
|
||||
ecma_collection_t *skipped_non_enumerable_p = ecma_new_collection ();
|
||||
|
||||
const ecma_object_type_t type = ecma_get_object_type (obj_p);
|
||||
const bool obj_is_builtin = ecma_get_object_is_builtin (obj_p);
|
||||
@ -1696,7 +1696,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
ecma_length_t string_named_properties_count = 0;
|
||||
ecma_length_t array_index_named_properties_count = 0;
|
||||
|
||||
ecma_collection_header_t *prop_names_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *prop_names_p = ecma_new_collection ();
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
if (JERRY_LIKELY (!is_symbols_only))
|
||||
@ -1783,23 +1783,21 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
ecma_value_t *buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
const size_t own_names_hashes_bitmap_size = ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size;
|
||||
JERRY_VLA (uint32_t, own_names_hashes_bitmap, own_names_hashes_bitmap_size);
|
||||
memset (own_names_hashes_bitmap, 0, own_names_hashes_bitmap_size * sizeof (own_names_hashes_bitmap[0]));
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < prop_names_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
/* Symbols are never lazy listed */
|
||||
JERRY_ASSERT (!ecma_prop_name_is_symbol (name_p));
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
|
||||
uint8_t hash = (uint8_t) ecma_string_hash (name_p);
|
||||
uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size);
|
||||
uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size);
|
||||
@ -1839,12 +1837,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
|
||||
if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0)
|
||||
{
|
||||
ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t j = 0; j < prop_names_p->item_count; j++)
|
||||
{
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]);
|
||||
|
||||
if (ecma_compare_ecma_strings (index_str_p, current_name_p))
|
||||
{
|
||||
@ -1858,9 +1855,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
{
|
||||
own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column);
|
||||
|
||||
ecma_append_to_values_collection (prop_names_p,
|
||||
ecma_make_string_value (index_str_p),
|
||||
ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_push_back (prop_names_p, ecma_make_string_value (index_str_p));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1926,12 +1921,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
|
||||
if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0)
|
||||
{
|
||||
ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t j = 0; j < prop_names_p->item_count; j++)
|
||||
{
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]);
|
||||
|
||||
if (ecma_compare_ecma_strings (name_p, current_name_p))
|
||||
{
|
||||
@ -1945,21 +1939,19 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
{
|
||||
own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column);
|
||||
|
||||
ecma_append_to_values_collection (prop_names_p,
|
||||
ecma_make_prop_name_value (name_p),
|
||||
0);
|
||||
ecma_collection_push_back (prop_names_p, ecma_make_prop_name_value (name_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (is_enumerable_only && !ecma_is_property_enumerable (*property_p));
|
||||
|
||||
ecma_append_to_values_collection (skipped_non_enumerable_p,
|
||||
ecma_make_prop_name_value (name_p),
|
||||
0);
|
||||
ecma_collection_push_back (skipped_non_enumerable_p, ecma_make_prop_name_value (name_p));
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1967,12 +1959,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < prop_names_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *name_p = ecma_get_prop_name_from_value (buffer_p[i]);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (name_p);
|
||||
|
||||
@ -1996,12 +1987,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
uint32_t name_pos = array_index_named_properties_count + string_named_properties_count;
|
||||
uint32_t array_index_name_pos = 0;
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < prop_names_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *name_p = ecma_get_prop_name_from_value (buffer_p[i]);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (name_p);
|
||||
|
||||
@ -2062,7 +2052,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (array_index_names_p);
|
||||
|
||||
ecma_free_values_collection (prop_names_p, 0);
|
||||
ecma_collection_free (prop_names_p);
|
||||
|
||||
/* Third pass:
|
||||
* embedding own property names of current object of prototype chain to aggregate property names collection */
|
||||
@ -2086,12 +2076,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
else
|
||||
{
|
||||
/* Name with same hash has already occured. */
|
||||
ecma_value_p = ecma_collection_iterator_init (ret_p);
|
||||
buffer_p = ret_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t j = 0; j < ret_p->item_count; j++)
|
||||
{
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]);
|
||||
|
||||
if (ecma_compare_ecma_strings (name_p, current_name_p))
|
||||
{
|
||||
@ -2103,12 +2092,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
|
||||
if (is_append)
|
||||
{
|
||||
ecma_value_p = ecma_collection_iterator_init (skipped_non_enumerable_p);
|
||||
buffer_p = skipped_non_enumerable_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t j = 0; j < skipped_non_enumerable_p->item_count; j++)
|
||||
{
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]);
|
||||
|
||||
if (ecma_compare_ecma_strings (name_p, current_name_p))
|
||||
{
|
||||
@ -2122,10 +2110,13 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
{
|
||||
JERRY_ASSERT ((names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0);
|
||||
|
||||
ecma_append_to_values_collection (ret_p, ecma_make_prop_name_value (names_p[i]), 0);
|
||||
ecma_collection_push_back (ret_p, ecma_make_prop_name_value (name_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (names_p);
|
||||
@ -2140,7 +2131,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
prototype_chain_iter_p->u2.prototype_cp);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (skipped_non_enumerable_p, 0);
|
||||
ecma_collection_free (skipped_non_enumerable_p);
|
||||
|
||||
return ret_p;
|
||||
} /* ecma_op_object_get_property_names */
|
||||
|
||||
@ -57,7 +57,7 @@ bool ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, ecma_s
|
||||
ecma_property_descriptor_t *prop_desc_p);
|
||||
ecma_value_t ecma_op_object_has_instance (ecma_object_t *obj_p, ecma_value_t value);
|
||||
bool ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p);
|
||||
ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts);
|
||||
ecma_collection_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts);
|
||||
|
||||
lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p);
|
||||
bool ecma_object_class_is (ecma_object_t *object_p, uint32_t class_id);
|
||||
|
||||
@ -145,15 +145,14 @@ ecma_set_already_resolved_value (ecma_value_t already_resolved, /**< the already
|
||||
* See also: ES2015 25.4.1.8
|
||||
*/
|
||||
static void
|
||||
ecma_promise_trigger_reactions (ecma_collection_header_t *reactions, /**< lists of reactions */
|
||||
ecma_promise_trigger_reactions (ecma_collection_t *reactions, /**< lists of reactions */
|
||||
ecma_value_t value) /**< value for resolve or reject */
|
||||
{
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (reactions);
|
||||
ecma_value_t *buffer_p = reactions->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < reactions->item_count; i++)
|
||||
{
|
||||
ecma_enqueue_promise_reaction_job (*ecma_value_p, value);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_enqueue_promise_reaction_job (buffer_p[i], value);
|
||||
}
|
||||
} /* ecma_promise_trigger_reactions */
|
||||
|
||||
@ -174,19 +173,19 @@ ecma_reject_promise (ecma_value_t promise, /**< promise */
|
||||
ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (reason));
|
||||
ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p;
|
||||
|
||||
/* GC can be triggered by ecma_new_values_collection so freeing the collection
|
||||
/* GC can be triggered by ecma_new_collection so freeing the collection
|
||||
first and creating a new one might cause a heap after use event. */
|
||||
ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
ecma_collection_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
|
||||
/* Fulfill reactions will never be triggered. */
|
||||
ecma_promise_trigger_reactions (reject_reactions, reason);
|
||||
|
||||
promise_p->reject_reactions = ecma_new_values_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_values_collection ();
|
||||
promise_p->reject_reactions = ecma_new_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_collection ();
|
||||
|
||||
ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_free_if_not_object (reject_reactions);
|
||||
ecma_collection_free_if_not_object (fulfill_reactions);
|
||||
} /* ecma_reject_promise */
|
||||
|
||||
/**
|
||||
@ -206,19 +205,19 @@ ecma_fulfill_promise (ecma_value_t promise, /**< promise */
|
||||
ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (value));
|
||||
ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p;
|
||||
|
||||
/* GC can be triggered by ecma_new_values_collection so freeing the collection
|
||||
/* GC can be triggered by ecma_new_collection so freeing the collection
|
||||
first and creating a new one might cause a heap after use event. */
|
||||
ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
ecma_collection_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
|
||||
/* Reject reactions will never be triggered. */
|
||||
ecma_promise_trigger_reactions (fulfill_reactions, value);
|
||||
|
||||
promise_p->reject_reactions = ecma_new_values_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_values_collection ();
|
||||
promise_p->reject_reactions = ecma_new_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_collection ();
|
||||
|
||||
ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_free_if_not_object (reject_reactions);
|
||||
ecma_collection_free_if_not_object (fulfill_reactions);
|
||||
} /* ecma_fulfill_promise */
|
||||
|
||||
/**
|
||||
@ -502,8 +501,8 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
|
||||
/* 5 */
|
||||
ecma_promise_set_state (object_p, ECMA_PROMISE_STATE_PENDING);
|
||||
/* 6-7. */
|
||||
promise_object_p->fulfill_reactions = ecma_new_values_collection ();
|
||||
promise_object_p->reject_reactions = ecma_new_values_collection ();
|
||||
promise_object_p->fulfill_reactions = ecma_new_collection ();
|
||||
promise_object_p->reject_reactions = ecma_new_collection ();
|
||||
/* 8. */
|
||||
ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p);
|
||||
|
||||
@ -706,13 +705,8 @@ ecma_promise_do_then (ecma_value_t promise, /**< the promise which call 'then' *
|
||||
if (ecma_promise_get_state (obj_p) == ECMA_PROMISE_STATE_PENDING)
|
||||
{
|
||||
/* 7. */
|
||||
ecma_append_to_values_collection (promise_p->fulfill_reactions,
|
||||
ecma_make_object_value (fulfill_reaction_p),
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
|
||||
ecma_append_to_values_collection (promise_p->reject_reactions,
|
||||
ecma_make_object_value (reject_reaction_p),
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_push_back (promise_p->fulfill_reactions, ecma_make_object_value (fulfill_reaction_p));
|
||||
ecma_collection_push_back (promise_p->reject_reactions, ecma_make_object_value (reject_reaction_p));
|
||||
}
|
||||
else if (ecma_promise_get_state (obj_p) == ECMA_PROMISE_STATE_FULFILLED)
|
||||
{
|
||||
|
||||
@ -64,8 +64,8 @@ typedef struct
|
||||
{
|
||||
ecma_extended_object_t ecma_extended_object_t; /**< extended object part */
|
||||
uint8_t state; /**< promise state, see ecma_promise_state_t */
|
||||
ecma_collection_header_t *fulfill_reactions; /**< list of PromiseFullfillReactions */
|
||||
ecma_collection_header_t *reject_reactions; /**< list of PromiseRejectReactions */
|
||||
ecma_collection_t *fulfill_reactions; /**< list of PromiseFullfillReactions */
|
||||
ecma_collection_t *reject_reactions; /**< list of PromiseRejectReactions */
|
||||
} ecma_promise_object_t;
|
||||
|
||||
bool ecma_is_promise (ecma_object_t *obj_p);
|
||||
|
||||
@ -91,17 +91,16 @@ ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obj
|
||||
* false - list all properties into main
|
||||
* collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_collection_header_t *for_enumerable_p = main_collection_p;
|
||||
ecma_collection_t *for_enumerable_p = main_collection_p;
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL);
|
||||
@ -115,14 +114,10 @@ ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obj
|
||||
ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i);
|
||||
|
||||
/* the properties are enumerable (ECMA-262 v5, 15.5.5.2.9) */
|
||||
ecma_append_to_values_collection (for_enumerable_p, ecma_make_string_value (name_p), 0);
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
ecma_collection_push_back (for_enumerable_p, ecma_make_string_value (name_p));
|
||||
}
|
||||
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
} /* ecma_op_string_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
|
||||
@ -31,8 +31,8 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, ecma_length_
|
||||
void
|
||||
ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p,
|
||||
bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -765,8 +765,7 @@ ecma_is_typedarray (ecma_value_t value) /**< the target need to be checked */
|
||||
*/
|
||||
void
|
||||
ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedArray object */
|
||||
ecma_collection_header_t *main_collection_p) /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p) /**< 'main' collection */
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p)));
|
||||
|
||||
@ -776,9 +775,7 @@ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedA
|
||||
{
|
||||
ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i);
|
||||
|
||||
ecma_append_to_values_collection (main_collection_p, ecma_make_string_value (name_p), 0);
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
ecma_collection_push_back (main_collection_p, ecma_make_string_value (name_p));
|
||||
}
|
||||
} /* ecma_op_typedarray_list_lazy_property_names */
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ void ecma_set_typedarray_element (lit_utf8_byte_t *dst_p,
|
||||
ecma_number_t ecma_get_typedarray_element (lit_utf8_byte_t *src,
|
||||
lit_magic_string_id_t class_id);
|
||||
void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p,
|
||||
ecma_collection_header_t *main_collection_p);
|
||||
ecma_collection_t *main_collection_p);
|
||||
ecma_value_t ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, uint32_t index);
|
||||
bool ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p,
|
||||
uint32_t index,
|
||||
|
||||
@ -226,17 +226,15 @@ vm_op_delete_var (ecma_value_t name_literal, /**< name literal */
|
||||
*
|
||||
* @return chain list of property names
|
||||
*/
|
||||
ecma_collection_chunk_t *
|
||||
ecma_collection_t *
|
||||
opfunc_for_in (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t *result_obj_p) /**< expression object */
|
||||
{
|
||||
ecma_collection_chunk_t *prop_names_p = NULL;
|
||||
|
||||
/* 3. */
|
||||
if (ecma_is_value_undefined (left_value)
|
||||
|| ecma_is_value_null (left_value))
|
||||
{
|
||||
return prop_names_p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 4. */
|
||||
@ -244,24 +242,18 @@ opfunc_for_in (ecma_value_t left_value, /**< left value */
|
||||
/* ecma_op_to_object will only raise error on null/undefined values but those are handled above. */
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (obj_expr_value));
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_expr_value);
|
||||
ecma_collection_header_t *prop_names_coll_p;
|
||||
prop_names_coll_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
|
||||
if (prop_names_coll_p->item_count != 0)
|
||||
if (prop_names_p->item_count != 0)
|
||||
{
|
||||
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);
|
||||
return prop_names_p;
|
||||
}
|
||||
|
||||
/* Note: We release the collection header here, and return the chunk list of the collection, which will
|
||||
* be handled and released by the vm loop. */
|
||||
jmem_pools_free (prop_names_coll_p, sizeof (ecma_collection_header_t));
|
||||
ecma_free_value (obj_expr_value);
|
||||
ecma_deref_object (obj_p);
|
||||
ecma_collection_destroy (prop_names_p);
|
||||
|
||||
return prop_names_p;
|
||||
return NULL;
|
||||
} /* opfunc_for_in */
|
||||
|
||||
/**
|
||||
|
||||
@ -90,7 +90,7 @@ vm_op_delete_prop (ecma_value_t object, ecma_value_t property, bool is_strict);
|
||||
ecma_value_t
|
||||
vm_op_delete_var (ecma_value_t name_literal, ecma_object_t *lex_env_p);
|
||||
|
||||
ecma_collection_chunk_t *
|
||||
ecma_collection_t *
|
||||
opfunc_for_in (ecma_value_t left_value, ecma_value_t *result_obj_p);
|
||||
|
||||
/**
|
||||
|
||||
@ -94,31 +94,19 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
{
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]) == VM_CONTEXT_FOR_IN);
|
||||
|
||||
ecma_collection_chunk_t *chunk_p;
|
||||
chunk_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (ecma_collection_chunk_t, vm_stack_top_p[-2]);
|
||||
uint32_t index = vm_stack_top_p[-3];
|
||||
ecma_collection_t *collection_p;
|
||||
collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, vm_stack_top_p[-2]);
|
||||
|
||||
while (chunk_p != NULL)
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t index = vm_stack_top_p[-3]; index < collection_p->item_count; index++)
|
||||
{
|
||||
ecma_value_t value = chunk_p->items[index];
|
||||
|
||||
if (JERRY_UNLIKELY (ecma_is_value_pointer (value)))
|
||||
{
|
||||
ecma_collection_chunk_t *next_chunk_p;
|
||||
next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (value);
|
||||
jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
|
||||
|
||||
chunk_p = next_chunk_p;
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_free_value (value);
|
||||
index++;
|
||||
}
|
||||
ecma_free_value (buffer_p[index]);
|
||||
}
|
||||
|
||||
ecma_free_value (vm_stack_top_p[-4]);
|
||||
ecma_collection_destroy (collection_p);
|
||||
|
||||
ecma_deref_object (ecma_get_object_from_value (vm_stack_top_p[-4]));
|
||||
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION);
|
||||
vm_stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION;
|
||||
|
||||
@ -2872,11 +2872,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
ecma_value_t expr_obj_value = ECMA_VALUE_UNDEFINED;
|
||||
ecma_collection_chunk_t *prop_names_p = opfunc_for_in (value, &expr_obj_value);
|
||||
ecma_collection_t *prop_names_p = opfunc_for_in (value, &expr_obj_value);
|
||||
ecma_free_value (value);
|
||||
|
||||
if (prop_names_p == NULL)
|
||||
{
|
||||
/* The collection is already released */
|
||||
byte_code_p = byte_code_start_p + branch_offset;
|
||||
continue;
|
||||
}
|
||||
@ -2896,56 +2897,34 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
ecma_value_t *context_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
|
||||
|
||||
ecma_collection_chunk_t *chunk_p;
|
||||
chunk_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (ecma_collection_chunk_t, context_top_p[-2]);
|
||||
ecma_collection_t *collection_p;
|
||||
collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_top_p[-2]);
|
||||
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (context_top_p[-1]) == VM_CONTEXT_FOR_IN);
|
||||
|
||||
uint32_t index = context_top_p[-3];
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
JERRY_ASSERT (!ecma_is_value_pointer (chunk_p->items[index]));
|
||||
|
||||
/* TODO: use collection iterator instead of directly accessing the collection chunks. */
|
||||
*stack_top_p++ = chunk_p->items[index];
|
||||
index++;
|
||||
|
||||
if (JERRY_LIKELY (!ecma_is_value_pointer (chunk_p->items[index])))
|
||||
{
|
||||
context_top_p[-3] = index;
|
||||
continue;
|
||||
}
|
||||
|
||||
context_top_p[-3] = 0;
|
||||
|
||||
ecma_collection_chunk_t *next_chunk_p;
|
||||
next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (chunk_p->items[index]);
|
||||
ECMA_SET_INTERNAL_VALUE_ANY_POINTER (context_top_p[-2], next_chunk_p);
|
||||
|
||||
jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
|
||||
*stack_top_p++ = buffer_p[index];
|
||||
context_top_p[-3]++;
|
||||
continue;
|
||||
}
|
||||
case VM_OC_FOR_IN_HAS_NEXT:
|
||||
{
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
ecma_collection_chunk_t *chunk_p;
|
||||
chunk_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (ecma_collection_chunk_t, stack_top_p[-2]);
|
||||
ecma_collection_t *collection_p;
|
||||
collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, stack_top_p[-2]);
|
||||
|
||||
uint32_t index = stack_top_p[-3];
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FOR_IN);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[-4]);
|
||||
uint32_t index = stack_top_p[-3];
|
||||
|
||||
while (true)
|
||||
while (index < collection_p->item_count)
|
||||
{
|
||||
if (chunk_p == NULL)
|
||||
{
|
||||
ecma_deref_object (object_p);
|
||||
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION);
|
||||
stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION;
|
||||
break;
|
||||
}
|
||||
|
||||
ecma_string_t *prop_name_p = ecma_get_string_from_value (chunk_p->items[index]);
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[index]);
|
||||
|
||||
if (JERRY_LIKELY (ecma_op_object_has_property (object_p, prop_name_p)))
|
||||
{
|
||||
@ -2953,27 +2932,20 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
ecma_value_t value = chunk_p->items[index];
|
||||
|
||||
if (JERRY_LIKELY (!ecma_is_value_pointer (value)))
|
||||
{
|
||||
stack_top_p[-3] = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = 0;
|
||||
stack_top_p[-3] = 0;
|
||||
|
||||
ecma_collection_chunk_t *next_chunk_p;
|
||||
next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (value);
|
||||
ECMA_SET_INTERNAL_VALUE_ANY_POINTER (stack_top_p[-2], next_chunk_p);
|
||||
|
||||
jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
|
||||
chunk_p = next_chunk_p;
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index == collection_p->item_count)
|
||||
{
|
||||
ecma_deref_object (object_p);
|
||||
ecma_collection_destroy (collection_p);
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION);
|
||||
stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
stack_top_p[-3] = index;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user