Reduce memory consumption of property names.
Property names were always required a string reference which consumed a large amount of memory for arrays. This patch reduces this consumption by directly storing the value part of certain strings. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -384,14 +384,7 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
|
||||
{
|
||||
if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED)
|
||||
{
|
||||
ecma_string_t *name_p = ECMA_GET_POINTER (ecma_string_t, prop_pair_p->names_cp[i]);
|
||||
|
||||
ecma_free_property (object_p, name_p, prop_iter_p->types + i);
|
||||
|
||||
if (name_p != NULL)
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], prop_iter_p->types + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -329,6 +329,16 @@ typedef enum
|
||||
*/
|
||||
#define ECMA_PROPERTY_FIXED 0
|
||||
|
||||
/**
|
||||
* Shift for property name part.
|
||||
*/
|
||||
#define ECMA_PROPERTY_NAME_TYPE_SHIFT (ECMA_PROPERTY_FLAG_SHIFT + 4)
|
||||
|
||||
/**
|
||||
* Property name is a generic string.
|
||||
*/
|
||||
#define ECMA_PROPERTY_NAME_TYPE_STRING 3
|
||||
|
||||
/**
|
||||
* Abstract property representation.
|
||||
*
|
||||
@@ -411,6 +421,12 @@ typedef struct
|
||||
#define ECMA_PROPERTY_GET_TYPE(property) \
|
||||
((ecma_property_types_t) ((property) & ECMA_PROPERTY_TYPE_MASK))
|
||||
|
||||
/**
|
||||
* Get property name type.
|
||||
*/
|
||||
#define ECMA_PROPERTY_GET_NAME_TYPE(property) \
|
||||
((property) >> ECMA_PROPERTY_NAME_TYPE_SHIFT)
|
||||
|
||||
/**
|
||||
* Returns true if the property pointer is a property pair.
|
||||
*/
|
||||
@@ -418,6 +434,12 @@ typedef struct
|
||||
(ECMA_PROPERTY_GET_TYPE ((property_header_p)->types[0]) != ECMA_PROPERTY_TYPE_VIRTUAL \
|
||||
&& (property_header_p)->types[0] != ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
|
||||
/**
|
||||
* Returns true if the property is named property.
|
||||
*/
|
||||
#define ECMA_PROPERTY_IS_NAMED_PROPERTY(property) \
|
||||
(ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_SPECIAL)
|
||||
|
||||
/**
|
||||
* Returns the internal property type
|
||||
*/
|
||||
@@ -909,14 +931,14 @@ typedef struct
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string
|
||||
* maximum size is 2^16. */
|
||||
ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string
|
||||
* maximum size is 2^32. */
|
||||
ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number
|
||||
stored locally in the string's descriptor */
|
||||
ECMA_STRING_CONTAINER_MAGIC_STRING, /**< the ecma-string is equal to one of ECMA magic strings */
|
||||
ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */
|
||||
ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string
|
||||
* maximum size is 2^16. */
|
||||
ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string
|
||||
* maximum size is 2^32. */
|
||||
|
||||
ECMA_STRING_LITERAL_NUMBER, /**< a literal number which is used solely by the literal storage
|
||||
* so no string processing function supports this type except
|
||||
@@ -985,10 +1007,10 @@ typedef struct
|
||||
|
||||
lit_utf8_size_t long_utf8_string_size; /**< size of this long utf-8 string in bytes */
|
||||
uint32_t uint32_number; /**< uint32-represented number placed locally in the descriptor */
|
||||
lit_magic_string_id_t magic_string_id; /**< identifier of a magic string */
|
||||
lit_magic_string_ex_id_t magic_string_ex_id; /**< identifier of an external magic string */
|
||||
uint32_t magic_string_id; /**< identifier of a magic string (lit_magic_string_id_t) */
|
||||
uint32_t magic_string_ex_id; /**< identifier of an external magic string (lit_magic_string_ex_id_t) */
|
||||
ecma_value_t lit_number; /**< literal number (note: not a regular string type) */
|
||||
uint32_t common_field; /**< for zeroing and comparison in some cases */
|
||||
uint32_t common_uint32_field; /**< for zeroing and comparison in some cases */
|
||||
} u;
|
||||
} ecma_string_t;
|
||||
|
||||
|
||||
@@ -60,10 +60,8 @@ ecma_init_ecma_string_from_magic_string_id (ecma_string_t *string_p, /**< descri
|
||||
the magic string */
|
||||
{
|
||||
string_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING | ECMA_STRING_REF_ONE;
|
||||
string_p->hash = lit_utf8_string_calc_hash (lit_get_magic_string_utf8 (magic_string_id),
|
||||
lit_get_magic_string_size (magic_string_id));
|
||||
string_p->hash = (lit_string_hash_t) magic_string_id;
|
||||
|
||||
string_p->u.common_field = 0;
|
||||
string_p->u.magic_string_id = magic_string_id;
|
||||
} /* ecma_init_ecma_string_from_magic_string_id */
|
||||
|
||||
@@ -76,10 +74,8 @@ ecma_init_ecma_string_from_magic_string_ex_id (ecma_string_t *string_p, /**< des
|
||||
the external magic string */
|
||||
{
|
||||
string_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING_EX | ECMA_STRING_REF_ONE;
|
||||
string_p->hash = lit_utf8_string_calc_hash (lit_get_magic_string_ex_utf8 (magic_string_ex_id),
|
||||
lit_get_magic_string_ex_size (magic_string_ex_id));
|
||||
string_p->hash = (lit_string_hash_t) (LIT_MAGIC_STRING__COUNT + magic_string_ex_id);
|
||||
|
||||
string_p->u.common_field = 0;
|
||||
string_p->u.magic_string_ex_id = magic_string_ex_id;
|
||||
} /* ecma_init_ecma_string_from_magic_string_ex_id */
|
||||
|
||||
@@ -158,8 +154,9 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri
|
||||
JERRY_ASSERT (string_p != NULL || string_size == 0);
|
||||
JERRY_ASSERT (lit_is_cesu8_string_valid (string_p, string_size));
|
||||
|
||||
lit_magic_string_id_t magic_string_id;
|
||||
if (lit_is_utf8_string_magic (string_p, string_size, &magic_string_id))
|
||||
lit_magic_string_id_t magic_string_id = lit_is_utf8_string_magic (string_p, string_size);
|
||||
|
||||
if (magic_string_id != LIT_MAGIC_STRING__COUNT)
|
||||
{
|
||||
return ecma_get_magic_string (magic_string_id);
|
||||
}
|
||||
@@ -176,10 +173,14 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri
|
||||
}
|
||||
}
|
||||
|
||||
lit_magic_string_ex_id_t magic_string_ex_id;
|
||||
if (lit_is_ex_utf8_string_magic (string_p, string_size, &magic_string_ex_id))
|
||||
if (lit_get_magic_string_ex_count () > 0)
|
||||
{
|
||||
return ecma_get_magic_string_ex (magic_string_ex_id);
|
||||
lit_magic_string_ex_id_t magic_string_ex_id = lit_is_ex_utf8_string_magic (string_p, string_size);
|
||||
|
||||
if (magic_string_ex_id < lit_get_magic_string_ex_count ())
|
||||
{
|
||||
return ecma_get_magic_string_ex (magic_string_ex_id);
|
||||
}
|
||||
}
|
||||
|
||||
ecma_string_t *string_desc_p;
|
||||
@@ -190,7 +191,7 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + string_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.common_uint32_field = 0;
|
||||
string_desc_p->u.utf8_string.size = (uint16_t) string_size;
|
||||
string_desc_p->u.utf8_string.length = (uint16_t) lit_utf8_string_length (string_p, string_size);
|
||||
|
||||
@@ -201,7 +202,7 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + string_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.common_uint32_field = 0;
|
||||
string_desc_p->u.long_utf8_string_size = string_size;
|
||||
|
||||
ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string_desc_p;
|
||||
@@ -278,7 +279,7 @@ ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + converted_string_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.common_uint32_field = 0;
|
||||
string_desc_p->u.utf8_string.size = (uint16_t) converted_string_size;
|
||||
string_desc_p->u.utf8_string.length = (uint16_t) converted_string_length;
|
||||
|
||||
@@ -289,7 +290,7 @@ ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + converted_string_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.common_uint32_field = 0;
|
||||
string_desc_p->u.long_utf8_string_size = converted_string_size;
|
||||
|
||||
ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string_desc_p;
|
||||
@@ -354,7 +355,6 @@ ecma_init_ecma_string_from_uint32 (ecma_string_t *string_desc_p, /**< ecma-strin
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_UINT32_IN_DESC | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->hash = (lit_string_hash_t) uint32_number;
|
||||
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.uint32_number = uint32_number;
|
||||
} /* ecma_init_ecma_string_from_uint32 */
|
||||
|
||||
@@ -364,12 +364,9 @@ ecma_init_ecma_string_from_uint32 (ecma_string_t *string_desc_p, /**< ecma-strin
|
||||
inline void __attr_always_inline___
|
||||
ecma_init_ecma_length_string (ecma_string_t *string_desc_p) /**< ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (lit_utf8_string_calc_hash ((const lit_utf8_byte_t *) "length", 6) == LIT_STRING_LENGTH_HASH);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->hash = LIT_STRING_LENGTH_HASH;
|
||||
string_desc_p->hash = LIT_MAGIC_STRING_LENGTH;
|
||||
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.magic_string_id = LIT_MAGIC_STRING_LENGTH;
|
||||
} /* ecma_init_ecma_length_string */
|
||||
|
||||
@@ -418,18 +415,15 @@ ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */
|
||||
|
||||
JERRY_ASSERT (str_size > 0);
|
||||
#ifndef JERRY_NDEBUG
|
||||
lit_magic_string_id_t magic_string_id;
|
||||
lit_magic_string_ex_id_t magic_string_ex_id;
|
||||
|
||||
JERRY_ASSERT (!lit_is_utf8_string_magic (str_buf, str_size, &magic_string_id)
|
||||
&& !lit_is_ex_utf8_string_magic (str_buf, str_size, &magic_string_ex_id));
|
||||
JERRY_ASSERT (lit_is_utf8_string_magic (str_buf, str_size) == LIT_MAGIC_STRING__COUNT
|
||||
&& lit_is_ex_utf8_string_magic (str_buf, str_size) == lit_get_magic_string_ex_count ());
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + str_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->hash = lit_utf8_string_calc_hash (str_buf, str_size);
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.common_uint32_field = 0;
|
||||
string_desc_p->u.utf8_string.size = (uint16_t) str_size;
|
||||
string_desc_p->u.utf8_string.length = (uint16_t) str_size;
|
||||
|
||||
@@ -515,6 +509,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
|
||||
|
||||
bool string1_is_uint32 = false;
|
||||
bool string1_rehash_needed = false;
|
||||
|
||||
switch (ECMA_STRING_GET_CONTAINER (string1_p))
|
||||
{
|
||||
@@ -542,6 +537,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
utf8_string1_p = uint32_to_string_buffer1;
|
||||
utf8_string1_length = utf8_string1_size;
|
||||
string1_is_uint32 = true;
|
||||
string1_rehash_needed = true;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
@@ -549,6 +545,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
utf8_string1_p = lit_get_magic_string_utf8 (string1_p->u.magic_string_id);
|
||||
utf8_string1_size = lit_get_magic_string_size (string1_p->u.magic_string_id);
|
||||
utf8_string1_length = utf8_string1_size;
|
||||
string1_rehash_needed = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -558,6 +555,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
utf8_string1_p = lit_get_magic_string_ex_utf8 (string1_p->u.magic_string_id);
|
||||
utf8_string1_size = lit_get_magic_string_ex_size (string1_p->u.magic_string_id);
|
||||
utf8_string1_length = utf8_string1_size;
|
||||
string1_rehash_needed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -620,6 +618,17 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
jerry_fatal (ERR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
lit_magic_string_id_t magic_string_id;
|
||||
magic_string_id = lit_is_utf8_string_pair_magic (utf8_string1_p,
|
||||
utf8_string1_size,
|
||||
utf8_string2_p,
|
||||
utf8_string2_size);
|
||||
|
||||
if (magic_string_id != LIT_MAGIC_STRING__COUNT)
|
||||
{
|
||||
return ecma_get_magic_string (magic_string_id);
|
||||
}
|
||||
|
||||
if (string1_is_uint32 && new_size <= ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32)
|
||||
{
|
||||
memcpy (uint32_to_string_buffer1 + utf8_string1_size,
|
||||
@@ -634,6 +643,20 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
}
|
||||
}
|
||||
|
||||
if (lit_get_magic_string_ex_count () > 0)
|
||||
{
|
||||
lit_magic_string_ex_id_t magic_string_ex_id;
|
||||
magic_string_ex_id = lit_is_ex_utf8_string_pair_magic (utf8_string1_p,
|
||||
utf8_string1_size,
|
||||
utf8_string2_p,
|
||||
utf8_string2_size);
|
||||
|
||||
if (magic_string_ex_id < lit_get_magic_string_ex_count ())
|
||||
{
|
||||
return ecma_get_magic_string_ex (magic_string_ex_id);
|
||||
}
|
||||
}
|
||||
|
||||
ecma_string_t *string_desc_p;
|
||||
lit_utf8_byte_t *data_p;
|
||||
|
||||
@@ -642,7 +665,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + new_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.common_uint32_field = 0;
|
||||
string_desc_p->u.utf8_string.size = (uint16_t) new_size;
|
||||
string_desc_p->u.utf8_string.length = (uint16_t) (utf8_string1_length + utf8_string2_length);
|
||||
|
||||
@@ -653,7 +676,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + new_size);
|
||||
|
||||
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE;
|
||||
string_desc_p->u.common_field = 0;
|
||||
string_desc_p->u.common_uint32_field = 0;
|
||||
string_desc_p->u.long_utf8_string_size = new_size;
|
||||
|
||||
ecma_long_string_t *long_string_desc_p = (ecma_long_string_t *) string_desc_p;
|
||||
@@ -664,9 +687,9 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
||||
|
||||
lit_string_hash_t hash_start = string1_p->hash;
|
||||
|
||||
if (string1_is_uint32)
|
||||
if (string1_rehash_needed)
|
||||
{
|
||||
hash_start = lit_utf8_string_calc_hash (uint32_to_string_buffer1, utf8_string1_size);
|
||||
hash_start = lit_utf8_string_calc_hash (utf8_string1_p, utf8_string1_size);
|
||||
}
|
||||
|
||||
string_desc_p->hash = lit_utf8_string_hash_combine (hash_start, utf8_string2_p, utf8_string2_size);
|
||||
@@ -1049,25 +1072,185 @@ ecma_string_is_empty (const ecma_string_t *str_p) /**< ecma-string */
|
||||
inline bool __attr_always_inline___
|
||||
ecma_string_is_length (const ecma_string_t *string_p) /**< property name */
|
||||
{
|
||||
static const char length_str_p[] = "length";
|
||||
|
||||
ecma_string_container_t container = ECMA_STRING_GET_CONTAINER (string_p);
|
||||
|
||||
if (container == ECMA_STRING_CONTAINER_MAGIC_STRING)
|
||||
{
|
||||
return string_p->u.magic_string_id == LIT_MAGIC_STRING_LENGTH;
|
||||
}
|
||||
|
||||
if (container != ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
|
||||
|| string_p->u.utf8_string.size != (sizeof (length_str_p) - 1)
|
||||
|| string_p->hash != LIT_STRING_LENGTH_HASH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !strncmp ((char *) (string_p + 1), length_str_p, (sizeof (length_str_p) - 1));
|
||||
return (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
&& string_p->u.magic_string_id == LIT_MAGIC_STRING_LENGTH);
|
||||
} /* ecma_string_is_length */
|
||||
|
||||
/**
|
||||
* Converts a string into a property name
|
||||
*
|
||||
* @return the compressed pointer part of the name
|
||||
*/
|
||||
inline jmem_cpointer_t __attr_always_inline___
|
||||
ecma_string_to_property_name (ecma_string_t *prop_name_p, /**< property name */
|
||||
ecma_property_t *name_type_p) /**< [out] property name type */
|
||||
{
|
||||
ecma_string_container_t container = ECMA_STRING_GET_CONTAINER (prop_name_p);
|
||||
|
||||
switch (container)
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
|
||||
{
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
|
||||
*name_type_p = (ecma_property_t) (container << ECMA_PROPERTY_NAME_TYPE_SHIFT);
|
||||
return (jmem_cpointer_t) prop_name_p->u.common_uint32_field;
|
||||
|
||||
#else /* !JERRY_CPOINTER_32_BIT */
|
||||
|
||||
if (prop_name_p->u.common_uint32_field < (UINT16_MAX + 1))
|
||||
{
|
||||
*name_type_p = (ecma_property_t) (container << ECMA_PROPERTY_NAME_TYPE_SHIFT);
|
||||
return (jmem_cpointer_t) prop_name_p->u.common_uint32_field;
|
||||
}
|
||||
|
||||
#endif /* JERRY_CPOINTER_32_BIT */
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*name_type_p = ECMA_PROPERTY_NAME_TYPE_STRING << ECMA_PROPERTY_NAME_TYPE_SHIFT;
|
||||
|
||||
ecma_ref_ecma_string (prop_name_p);
|
||||
|
||||
jmem_cpointer_t prop_name_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (prop_name_cp, prop_name_p);
|
||||
return prop_name_cp;
|
||||
} /* ecma_string_to_property_name */
|
||||
|
||||
/**
|
||||
* Converts a property name into a string
|
||||
*
|
||||
* @return the string pointer
|
||||
*/
|
||||
ecma_string_t *
|
||||
ecma_string_from_property_name (ecma_property_t property, /**< property name type */
|
||||
jmem_cpointer_t prop_name_cp) /**< property name compressed pointer */
|
||||
{
|
||||
/* If string_buf_p is NULL this function returns with a new string
|
||||
* instance which needs to be released with ecma_deref_ecma_string. */
|
||||
|
||||
switch (ECMA_PROPERTY_GET_NAME_TYPE (property))
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
return ecma_new_ecma_string_from_uint32 ((uint32_t) prop_name_cp);
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
{
|
||||
return ecma_new_ecma_string_from_magic_string_id ((lit_magic_string_id_t) prop_name_cp);
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
|
||||
{
|
||||
return ecma_new_ecma_string_from_magic_string_ex_id ((lit_magic_string_ex_id_t) prop_name_cp);
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_PROPERTY_NAME_TYPE_STRING);
|
||||
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_name_cp);
|
||||
ecma_ref_ecma_string (prop_name_p);
|
||||
return prop_name_p;
|
||||
}
|
||||
}
|
||||
} /* ecma_string_from_property_name */
|
||||
|
||||
/**
|
||||
* Get hash code of property name
|
||||
*
|
||||
* @return hash code of property name
|
||||
*/
|
||||
inline lit_string_hash_t __attr_always_inline___
|
||||
ecma_string_get_property_name_hash (ecma_property_t property, /**< property name type */
|
||||
jmem_cpointer_t prop_name_cp) /**< property name compressed pointer */
|
||||
{
|
||||
switch (ECMA_PROPERTY_GET_NAME_TYPE (property))
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
|
||||
{
|
||||
return (lit_string_hash_t) (LIT_MAGIC_STRING__COUNT + prop_name_cp);
|
||||
}
|
||||
case ECMA_PROPERTY_NAME_TYPE_STRING:
|
||||
{
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_name_cp);
|
||||
return ecma_string_hash (prop_name_p);
|
||||
}
|
||||
default:
|
||||
{
|
||||
return (lit_string_hash_t) prop_name_cp;
|
||||
}
|
||||
}
|
||||
} /* ecma_string_get_property_name_hash */
|
||||
|
||||
/**
|
||||
* Check if property name is array index.
|
||||
*
|
||||
* @return ECMA_STRING_NOT_ARRAY_INDEX if string is not array index
|
||||
* the array index otherwise
|
||||
*/
|
||||
uint32_t
|
||||
ecma_string_get_property_index (ecma_property_t property, /**< property name type */
|
||||
jmem_cpointer_t prop_name_cp) /**< property name compressed pointer */
|
||||
{
|
||||
switch (ECMA_PROPERTY_GET_NAME_TYPE (property))
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
return (uint32_t) prop_name_cp;
|
||||
}
|
||||
#ifndef JERRY_CPOINTER_32_BIT
|
||||
case ECMA_PROPERTY_NAME_TYPE_STRING:
|
||||
{
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_name_cp);
|
||||
return ecma_string_get_array_index (prop_name_p);
|
||||
}
|
||||
#endif /* !JERRY_CPOINTER_32_BIT */
|
||||
default:
|
||||
{
|
||||
return ECMA_STRING_NOT_ARRAY_INDEX;
|
||||
}
|
||||
}
|
||||
} /* ecma_string_get_property_index */
|
||||
|
||||
/**
|
||||
* Compare a property name to a string
|
||||
*
|
||||
* @return true if they are equals
|
||||
* false otherwise
|
||||
*/
|
||||
inline bool __attr_always_inline___
|
||||
ecma_string_compare_to_property_name (ecma_property_t property, /**< property name type */
|
||||
jmem_cpointer_t prop_name_cp, /**< property name compressed pointer */
|
||||
const ecma_string_t *string_p) /**< other string */
|
||||
{
|
||||
uint32_t property_name_type = ECMA_PROPERTY_GET_NAME_TYPE (property);
|
||||
|
||||
switch (property_name_type)
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
|
||||
{
|
||||
return (ECMA_STRING_GET_CONTAINER (string_p) == property_name_type
|
||||
&& string_p->u.common_uint32_field == (uint32_t) prop_name_cp);
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (property_name_type == ECMA_PROPERTY_NAME_TYPE_STRING);
|
||||
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_name_cp);
|
||||
return ecma_compare_ecma_strings (prop_name_p, string_p);
|
||||
}
|
||||
}
|
||||
} /* ecma_string_compare_to_property_name */
|
||||
|
||||
/**
|
||||
* Long path part of ecma-string to ecma-string comparison routine
|
||||
*
|
||||
@@ -1081,79 +1264,26 @@ static bool __attr_noinline___
|
||||
ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-string */
|
||||
const ecma_string_t *string2_p) /* ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) != ECMA_STRING_GET_CONTAINER (string2_p)
|
||||
|| ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
|
||||
|| ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING);
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_GET_CONTAINER (string2_p));
|
||||
|
||||
const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
|
||||
lit_utf8_size_t utf8_string1_size, utf8_string2_size;
|
||||
|
||||
switch (ECMA_STRING_GET_CONTAINER (string1_p))
|
||||
if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING)
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
|
||||
{
|
||||
utf8_string1_p = (lit_utf8_byte_t *) (string1_p + 1);
|
||||
utf8_string1_size = string1_p->u.utf8_string.size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
utf8_string1_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string1_p) + 1);
|
||||
utf8_string1_size = string1_p->u.long_utf8_string_size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
{
|
||||
utf8_string1_p = lit_get_magic_string_utf8 (string1_p->u.magic_string_id);
|
||||
utf8_string1_size = lit_get_magic_string_size (string1_p->u.magic_string_id);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
|
||||
|
||||
utf8_string1_p = lit_get_magic_string_ex_utf8 (string1_p->u.magic_string_id);
|
||||
utf8_string1_size = lit_get_magic_string_ex_size (string1_p->u.magic_string_id);
|
||||
break;
|
||||
}
|
||||
utf8_string1_p = (lit_utf8_byte_t *) (string1_p + 1);
|
||||
utf8_string1_size = string1_p->u.utf8_string.size;
|
||||
utf8_string2_p = (lit_utf8_byte_t *) (string2_p + 1);
|
||||
utf8_string2_size = string2_p->u.utf8_string.size;
|
||||
}
|
||||
|
||||
switch (ECMA_STRING_GET_CONTAINER (string2_p))
|
||||
else
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
|
||||
{
|
||||
utf8_string2_p = (lit_utf8_byte_t *) (string2_p + 1);
|
||||
utf8_string2_size = string2_p->u.utf8_string.size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING:
|
||||
{
|
||||
utf8_string2_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string2_p) + 1);
|
||||
utf8_string2_size = string2_p->u.long_utf8_string_size;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
{
|
||||
utf8_string2_p = lit_get_magic_string_utf8 (string2_p->u.magic_string_id);
|
||||
utf8_string2_size = lit_get_magic_string_size (string2_p->u.magic_string_id);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING);
|
||||
|
||||
utf8_string2_p = lit_get_magic_string_ex_utf8 (string2_p->u.magic_string_id);
|
||||
utf8_string2_size = lit_get_magic_string_ex_size (string2_p->u.magic_string_id);
|
||||
break;
|
||||
}
|
||||
utf8_string1_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string1_p) + 1);
|
||||
utf8_string1_size = string1_p->u.long_utf8_string_size;
|
||||
utf8_string2_p = (lit_utf8_byte_t *) (((ecma_long_string_t *) string2_p) + 1);
|
||||
utf8_string2_size = string2_p->u.long_utf8_string_size;
|
||||
}
|
||||
|
||||
if (utf8_string1_size != utf8_string2_size)
|
||||
@@ -1161,7 +1291,7 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
|
||||
return false;
|
||||
}
|
||||
|
||||
return !strncmp ((char *) utf8_string1_p, (char *) utf8_string2_p, utf8_string1_size);
|
||||
return !memcmp ((char *) utf8_string1_p, (char *) utf8_string2_p, utf8_string1_size);
|
||||
} /* ecma_compare_ecma_strings_longpath */
|
||||
|
||||
/**
|
||||
@@ -1189,10 +1319,14 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /* ecma-string */
|
||||
|
||||
ecma_string_container_t string1_container = ECMA_STRING_GET_CONTAINER (string1_p);
|
||||
|
||||
if (string1_container > ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING
|
||||
&& string1_container == ECMA_STRING_GET_CONTAINER (string2_p))
|
||||
if (string1_container != ECMA_STRING_GET_CONTAINER (string2_p))
|
||||
{
|
||||
return string1_p->u.common_field == string2_p->u.common_field;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string1_container < ECMA_STRING_CONTAINER_HEAP_UTF8_STRING)
|
||||
{
|
||||
return string1_p->u.common_uint32_field == string2_p->u.common_uint32_field;
|
||||
}
|
||||
|
||||
return ecma_compare_ecma_strings_longpath (string1_p, string2_p);
|
||||
@@ -1443,67 +1577,23 @@ ecma_get_magic_string_ex (lit_magic_string_ex_id_t id) /**< external magic strin
|
||||
return ecma_new_ecma_string_from_magic_string_ex_id (id);
|
||||
} /* ecma_get_magic_string_ex */
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
/**
|
||||
* Long path part of ecma_is_string_magic
|
||||
*
|
||||
* Converts passed ecma-string to zt-string and
|
||||
* checks if it is equal to one of magic string
|
||||
*
|
||||
* @return true - if magic string equal to passed string was found,
|
||||
* false - otherwise.
|
||||
*/
|
||||
static bool
|
||||
ecma_is_string_magic_longpath (const ecma_string_t *string_p, /**< ecma-string */
|
||||
lit_magic_string_id_t *out_id_p) /**< [out] magic string's id */
|
||||
{
|
||||
lit_utf8_size_t utf8_str_size;
|
||||
bool is_ascii;
|
||||
const lit_utf8_byte_t *utf8_str_p = ecma_string_raw_chars (string_p, &utf8_str_size, &is_ascii);
|
||||
|
||||
if (utf8_str_p == NULL || !is_ascii)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return lit_is_utf8_string_magic (utf8_str_p, utf8_str_size, out_id_p);
|
||||
} /* ecma_is_string_magic_longpath */
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
/**
|
||||
* Check if passed string equals to one of magic strings
|
||||
* and if equal magic string was found, return it's id in 'out_id_p' argument.
|
||||
*
|
||||
* @return true - if magic string equal to passed string was found,
|
||||
* false - otherwise.
|
||||
* @return id - if magic string equal to passed string was found,
|
||||
* LIT_MAGIC_STRING__COUNT - otherwise.
|
||||
*/
|
||||
bool
|
||||
ecma_is_string_magic (const ecma_string_t *string_p, /**< ecma-string */
|
||||
lit_magic_string_id_t *out_id_p) /**< [out] magic string's id */
|
||||
lit_magic_string_id_t
|
||||
ecma_get_string_magic (const ecma_string_t *string_p) /**< ecma-string */
|
||||
{
|
||||
if (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING)
|
||||
{
|
||||
JERRY_ASSERT (string_p->u.magic_string_id < LIT_MAGIC_STRING__COUNT);
|
||||
|
||||
*out_id_p = (lit_magic_string_id_t) string_p->u.magic_string_id;
|
||||
|
||||
return true;
|
||||
return (lit_magic_string_id_t) string_p->u.magic_string_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Any ecma-string constructor except ecma_concat_ecma_strings
|
||||
* should return ecma-string with ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
* container type if new ecma-string's content is equal to one of magic strings.
|
||||
*/
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (ecma_string_get_length (string_p) > LIT_MAGIC_STRING_LENGTH_LIMIT
|
||||
|| !ecma_is_string_magic_longpath (string_p, out_id_p));
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
return false;
|
||||
}
|
||||
} /* ecma_is_string_magic */
|
||||
return LIT_MAGIC_STRING__COUNT;
|
||||
} /* ecma_get_string_magic */
|
||||
|
||||
/**
|
||||
* Try to calculate hash of the ecma-string
|
||||
|
||||
@@ -406,10 +406,21 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_DELETED)
|
||||
{
|
||||
first_property_p->types[0] = type_and_flags;
|
||||
|
||||
ecma_property_pair_t *first_property_pair_p = (ecma_property_pair_t *) first_property_p;
|
||||
ECMA_SET_POINTER (first_property_pair_p->names_cp[0], name_p);
|
||||
|
||||
if (name_p == NULL)
|
||||
{
|
||||
first_property_pair_p->names_cp[0] = ECMA_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_property_t name_type;
|
||||
first_property_pair_p->names_cp[0] = ecma_string_to_property_name (name_p,
|
||||
&name_type);
|
||||
type_and_flags = (ecma_property_t) (type_and_flags | name_type);
|
||||
}
|
||||
|
||||
first_property_p->types[0] = type_and_flags;
|
||||
|
||||
ecma_property_t *property_p = first_property_p->types + 0;
|
||||
|
||||
@@ -462,9 +473,21 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
/* Just copy the previous value (no need to decompress, compress). */
|
||||
first_property_pair_p->header.next_property_cp = *property_list_head_p;
|
||||
first_property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
first_property_pair_p->header.types[1] = type_and_flags;
|
||||
first_property_pair_p->names_cp[0] = ECMA_NULL_POINTER;
|
||||
ECMA_SET_POINTER (first_property_pair_p->names_cp[1], name_p);
|
||||
|
||||
if (name_p == NULL)
|
||||
{
|
||||
first_property_pair_p->names_cp[1] = ECMA_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_property_t name_type;
|
||||
first_property_pair_p->names_cp[1] = ecma_string_to_property_name (name_p,
|
||||
&name_type);
|
||||
type_and_flags = (ecma_property_t) (type_and_flags | name_type);
|
||||
}
|
||||
|
||||
first_property_pair_p->header.types[1] = type_and_flags;
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (*property_list_head_p, &first_property_pair_p->header);
|
||||
|
||||
@@ -591,8 +614,6 @@ ecma_create_named_data_property (ecma_object_t *object_p, /**< object */
|
||||
|
||||
uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDDATA | prop_attributes;
|
||||
|
||||
ecma_ref_ecma_string (name_p);
|
||||
|
||||
ecma_property_value_t value;
|
||||
value.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
|
||||
@@ -617,8 +638,6 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
|
||||
|
||||
uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDACCESSOR | prop_attributes;
|
||||
|
||||
ecma_ref_ecma_string (name_p);
|
||||
|
||||
ecma_property_value_t value;
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
@@ -659,15 +678,15 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
|
||||
if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
ecma_string_t *property_real_name_p;
|
||||
jmem_cpointer_t property_real_name_cp;
|
||||
property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p,
|
||||
name_p,
|
||||
&property_real_name_p);
|
||||
&property_real_name_cp);
|
||||
|
||||
if (property_p != NULL
|
||||
&& !ecma_is_property_lcached (property_p))
|
||||
{
|
||||
ecma_lcache_insert (obj_p, property_real_name_p, property_p);
|
||||
ecma_lcache_insert (obj_p, property_real_name_cp, property_p);
|
||||
}
|
||||
|
||||
return property_p;
|
||||
@@ -675,7 +694,7 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
|
||||
|
||||
property_p = NULL;
|
||||
ecma_string_t *property_name_p = NULL;
|
||||
jmem_cpointer_t property_name_cp = ECMA_NULL_POINTER;
|
||||
|
||||
uint32_t steps = 0;
|
||||
|
||||
@@ -687,25 +706,25 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
|
||||
|
||||
if (prop_pair_p->names_cp[0] != ECMA_NULL_POINTER)
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[0]))
|
||||
{
|
||||
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
prop_pair_p->names_cp[0]);
|
||||
|
||||
if (ecma_compare_ecma_strings (name_p, property_name_p))
|
||||
if (ecma_string_compare_to_property_name (prop_iter_p->types[0],
|
||||
prop_pair_p->names_cp[0],
|
||||
name_p))
|
||||
{
|
||||
property_name_cp = prop_pair_p->names_cp[0];
|
||||
property_p = prop_iter_p->types + 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prop_pair_p->names_cp[1] != ECMA_NULL_POINTER)
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[1]))
|
||||
{
|
||||
property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
prop_pair_p->names_cp[1]);
|
||||
|
||||
if (ecma_compare_ecma_strings (name_p, property_name_p))
|
||||
if (ecma_string_compare_to_property_name (prop_iter_p->types[1],
|
||||
prop_pair_p->names_cp[1],
|
||||
name_p))
|
||||
{
|
||||
property_name_cp = prop_pair_p->names_cp[1];
|
||||
property_p = prop_iter_p->types + 1;
|
||||
break;
|
||||
}
|
||||
@@ -725,7 +744,7 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
if (property_p != NULL
|
||||
&& !ecma_is_property_lcached (property_p))
|
||||
{
|
||||
ecma_lcache_insert (obj_p, property_name_p, property_p);
|
||||
ecma_lcache_insert (obj_p, property_name_cp, property_p);
|
||||
}
|
||||
|
||||
return property_p;
|
||||
@@ -791,7 +810,7 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
|
||||
*/
|
||||
void
|
||||
ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */
|
||||
ecma_string_t *name_p, /**< name of the property or NULL */
|
||||
jmem_cpointer_t name_cp, /**< name of the property or ECMA_NULL_POINTER */
|
||||
ecma_property_t *property_p) /**< property */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL && property_p != NULL);
|
||||
@@ -801,11 +820,6 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
case ECMA_PROPERTY_TYPE_NAMEDDATA:
|
||||
{
|
||||
ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
|
||||
if (ecma_is_property_lcached (property_p))
|
||||
{
|
||||
ecma_lcache_invalidate (object_p, name_p, property_p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
|
||||
@@ -816,27 +830,30 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp);
|
||||
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
|
||||
#endif /* JERRY_CPOINTER_32_BIT */
|
||||
|
||||
if (ecma_is_property_lcached (property_p))
|
||||
{
|
||||
ecma_lcache_invalidate (object_p, name_p, property_p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_PROPERTY_TYPE_SPECIAL:
|
||||
{
|
||||
JERRY_ASSERT (name_p == NULL);
|
||||
|
||||
ecma_free_internal_property (property_p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
break;
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_SPECIAL);
|
||||
JERRY_ASSERT (name_cp == ECMA_NULL_POINTER);
|
||||
|
||||
ecma_free_internal_property (property_p);
|
||||
*property_p = ECMA_PROPERTY_TYPE_DELETED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ecma_is_property_lcached (property_p))
|
||||
{
|
||||
ecma_lcache_invalidate (object_p, name_cp, property_p);
|
||||
}
|
||||
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_PROPERTY_NAME_TYPE_STRING)
|
||||
{
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
}
|
||||
|
||||
*property_p = ECMA_PROPERTY_TYPE_DELETED;
|
||||
} /* ecma_free_property */
|
||||
|
||||
@@ -872,23 +889,17 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
|
||||
{
|
||||
if ((prop_pair_p->values + i) == prop_value_p)
|
||||
{
|
||||
ecma_string_t *name_p = ECMA_GET_POINTER (ecma_string_t, prop_pair_p->names_cp[i]);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (cur_prop_p->types[i]) != ECMA_PROPERTY_TYPE_SPECIAL);
|
||||
|
||||
ecma_free_property (object_p, name_p, cur_prop_p->types + i);
|
||||
|
||||
if (name_p != NULL)
|
||||
if (has_hashmap)
|
||||
{
|
||||
if (has_hashmap)
|
||||
{
|
||||
ecma_property_hashmap_delete (object_p,
|
||||
name_p,
|
||||
cur_prop_p->types + i);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
prop_pair_p->names_cp[i] = ECMA_NULL_POINTER;
|
||||
ecma_property_hashmap_delete (object_p,
|
||||
prop_pair_p->names_cp[i],
|
||||
cur_prop_p->types + i);
|
||||
}
|
||||
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i);
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
|
||||
|
||||
if (cur_prop_p->types[1 - i] != ECMA_PROPERTY_TYPE_DELETED)
|
||||
@@ -955,13 +966,11 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
if (prop_pair_p->names_cp[i] != ECMA_NULL_POINTER
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i])
|
||||
&& !ecma_is_property_configurable (current_prop_p->types[i]))
|
||||
{
|
||||
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
uint32_t index = ecma_string_get_property_index (current_prop_p->types[i],
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (index < old_length && index >= new_length)
|
||||
{
|
||||
@@ -1001,29 +1010,24 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
if (prop_pair_p->names_cp[i] != ECMA_NULL_POINTER
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i])
|
||||
&& ecma_is_property_configurable (current_prop_p->types[i]))
|
||||
{
|
||||
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
uint32_t index = ecma_string_get_property_index (current_prop_p->types[i],
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (index < old_length && index >= new_length)
|
||||
{
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
|
||||
ecma_free_property (object_p, property_name_p, current_prop_p->types + i);
|
||||
|
||||
if (has_hashmap)
|
||||
{
|
||||
ecma_property_hashmap_delete (object_p, property_name_p, current_prop_p->types + i);
|
||||
ecma_property_hashmap_delete (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (current_prop_p->types[i] == ECMA_PROPERTY_TYPE_DELETED);
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i);
|
||||
|
||||
ecma_deref_ecma_string (property_name_p);
|
||||
prop_pair_p->names_cp[i] = ECMA_NULL_POINTER;
|
||||
JERRY_ASSERT (current_prop_p->types[i] == ECMA_PROPERTY_TYPE_DELETED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,12 @@ extern void ecma_init_ecma_length_string (ecma_string_t *);
|
||||
extern bool ecma_string_is_empty (const ecma_string_t *);
|
||||
extern bool ecma_string_is_length (const ecma_string_t *);
|
||||
|
||||
extern bool ecma_compare_ecma_strings_equal_hashes (const ecma_string_t *, const ecma_string_t *);
|
||||
extern jmem_cpointer_t ecma_string_to_property_name (ecma_string_t *, ecma_property_t *);
|
||||
extern ecma_string_t *ecma_string_from_property_name (ecma_property_t, jmem_cpointer_t);
|
||||
extern lit_string_hash_t ecma_string_get_property_name_hash (ecma_property_t, jmem_cpointer_t);
|
||||
extern uint32_t ecma_string_get_property_index (ecma_property_t, jmem_cpointer_t);
|
||||
extern bool ecma_string_compare_to_property_name (ecma_property_t, jmem_cpointer_t, const ecma_string_t *);
|
||||
|
||||
extern bool ecma_compare_ecma_strings (const ecma_string_t *, const ecma_string_t *);
|
||||
extern bool ecma_compare_ecma_strings_relational (const ecma_string_t *, const ecma_string_t *);
|
||||
extern ecma_length_t ecma_string_get_length (const ecma_string_t *);
|
||||
@@ -195,7 +200,7 @@ extern ecma_char_t ecma_string_get_char_at_pos (const ecma_string_t *, ecma_leng
|
||||
|
||||
extern ecma_string_t *ecma_get_magic_string (lit_magic_string_id_t);
|
||||
extern ecma_string_t *ecma_get_magic_string_ex (lit_magic_string_ex_id_t);
|
||||
extern bool ecma_is_string_magic (const ecma_string_t *, lit_magic_string_id_t *);
|
||||
extern lit_magic_string_id_t ecma_get_string_magic (const ecma_string_t *);
|
||||
|
||||
extern lit_string_hash_t ecma_string_hash (const ecma_string_t *);
|
||||
extern ecma_string_t *ecma_string_substr (const ecma_string_t *, ecma_length_t, ecma_length_t);
|
||||
@@ -281,7 +286,7 @@ ecma_find_named_property (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_property_value_t *
|
||||
ecma_get_named_data_property (ecma_object_t *, ecma_string_t *);
|
||||
|
||||
extern void ecma_free_property (ecma_object_t *, ecma_string_t *, ecma_property_t *);
|
||||
extern void ecma_free_property (ecma_object_t *, jmem_cpointer_t, ecma_property_t *);
|
||||
|
||||
extern void ecma_delete_property (ecma_object_t *, ecma_property_value_t *);
|
||||
extern uint32_t ecma_delete_array_properties (ecma_object_t *, uint32_t, uint32_t);
|
||||
|
||||
@@ -56,7 +56,6 @@ ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to i
|
||||
{
|
||||
JERRY_ASSERT (entry_p != NULL);
|
||||
JERRY_ASSERT (entry_p->object_cp != ECMA_NULL_POINTER);
|
||||
JERRY_ASSERT (entry_p->prop_name_cp != ECMA_NULL_POINTER);
|
||||
JERRY_ASSERT (entry_p->prop_p != NULL);
|
||||
|
||||
entry_p->object_cp = ECMA_NULL_POINTER;
|
||||
@@ -70,11 +69,11 @@ ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to i
|
||||
*/
|
||||
static inline size_t __attr_always_inline___
|
||||
ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to object */
|
||||
const ecma_string_t *prop_name_p) /**< proeprty name */
|
||||
lit_string_hash_t name_hash) /**< property name hash */
|
||||
{
|
||||
/* Randomize the hash of the property name with the object pointer using a xor operation,
|
||||
* so properties of different objects with the same name can be cached effectively. */
|
||||
return (size_t) ((ecma_string_hash (prop_name_p) ^ object_cp) & ECMA_LCACHE_HASH_MASK);
|
||||
return (size_t) ((name_hash ^ object_cp) & ECMA_LCACHE_HASH_MASK);
|
||||
} /* ecma_lcache_row_index */
|
||||
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
|
||||
|
||||
@@ -83,11 +82,10 @@ ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to obj
|
||||
*/
|
||||
void
|
||||
ecma_lcache_insert (ecma_object_t *object_p, /**< object */
|
||||
ecma_string_t *prop_name_p, /**< property name */
|
||||
jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_property_t *prop_p) /**< property */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
JERRY_ASSERT (prop_name_p != NULL);
|
||||
JERRY_ASSERT (prop_p != NULL && !ecma_is_property_lcached (prop_p));
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|
||||
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|
||||
@@ -97,7 +95,8 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
|
||||
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
|
||||
lit_string_hash_t name_hash = ecma_string_get_property_name_hash (*prop_p, name_cp);
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
|
||||
ecma_lcache_hash_entry_t *entries_p = JERRY_HASH_TABLE_CONTEXT (table)[row_index];
|
||||
|
||||
int32_t entry_index;
|
||||
@@ -125,13 +124,64 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
|
||||
|
||||
ecma_lcache_hash_entry_t *entry_p = entries_p + entry_index;
|
||||
ECMA_SET_NON_NULL_POINTER (entry_p->object_cp, object_p);
|
||||
ECMA_SET_NON_NULL_POINTER (entry_p->prop_name_cp, prop_name_p);
|
||||
entry_p->prop_name_cp = name_cp;
|
||||
entry_p->prop_p = prop_p;
|
||||
|
||||
ecma_set_property_lcached (entry_p->prop_p, true);
|
||||
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
|
||||
} /* ecma_lcache_insert */
|
||||
|
||||
#ifndef CONFIG_ECMA_LCACHE_DISABLE
|
||||
|
||||
/**
|
||||
* Converts a string into a property name
|
||||
*
|
||||
* @return the compressed pointer part of the name
|
||||
*/
|
||||
static inline jmem_cpointer_t __attr_always_inline___
|
||||
ecma_string_to_lcache_property_name (const ecma_string_t *prop_name_p, /**< property name */
|
||||
ecma_property_t *name_type_p) /**< [out] property name type */
|
||||
{
|
||||
ecma_string_container_t container = ECMA_STRING_GET_CONTAINER (prop_name_p);
|
||||
|
||||
switch (container)
|
||||
{
|
||||
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING:
|
||||
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
|
||||
{
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
|
||||
*name_type_p = (ecma_property_t) container;
|
||||
return (jmem_cpointer_t) prop_name_p->u.uint32_number;
|
||||
|
||||
#else /* !JERRY_CPOINTER_32_BIT */
|
||||
|
||||
if (prop_name_p->u.uint32_number < (UINT16_MAX + 1))
|
||||
{
|
||||
*name_type_p = (ecma_property_t) container;
|
||||
return (jmem_cpointer_t) prop_name_p->u.uint32_number;
|
||||
}
|
||||
|
||||
#endif /* JERRY_CPOINTER_32_BIT */
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*name_type_p = ECMA_PROPERTY_NAME_TYPE_STRING;
|
||||
|
||||
jmem_cpointer_t prop_name_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (prop_name_cp, prop_name_p);
|
||||
return prop_name_cp;
|
||||
} /* ecma_string_to_lcache_property_name */
|
||||
|
||||
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
|
||||
|
||||
/**
|
||||
* Lookup property in the LCache
|
||||
*
|
||||
@@ -149,35 +199,32 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t object_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
|
||||
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, ecma_string_hash (prop_name_p));
|
||||
ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
|
||||
ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH;
|
||||
ecma_string_container_t prop_container = ECMA_STRING_GET_CONTAINER (prop_name_p);
|
||||
|
||||
ecma_property_t prop_name_type;
|
||||
jmem_cpointer_t prop_name_cp = ecma_string_to_lcache_property_name (prop_name_p, &prop_name_type);
|
||||
|
||||
while (entry_p < entry_end_p)
|
||||
{
|
||||
if (entry_p->object_cp == object_cp)
|
||||
if (entry_p->object_cp == object_cp
|
||||
&& entry_p->prop_name_cp == prop_name_cp)
|
||||
{
|
||||
ecma_string_t *entry_prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
entry_p->prop_name_cp);
|
||||
ecma_property_t *prop_p = entry_p->prop_p;
|
||||
|
||||
JERRY_ASSERT ((prop_name_p->hash & ECMA_LCACHE_HASH_MASK) == (entry_prop_name_p->hash & ECMA_LCACHE_HASH_MASK));
|
||||
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
|
||||
|
||||
if (prop_name_p == entry_prop_name_p
|
||||
|| (prop_container > ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING
|
||||
&& prop_container == ECMA_STRING_GET_CONTAINER (entry_prop_name_p)
|
||||
&& prop_name_p->u.common_field == entry_prop_name_p->u.common_field))
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*prop_p) == prop_name_type)
|
||||
{
|
||||
ecma_property_t *prop_p = entry_p->prop_p;
|
||||
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
|
||||
|
||||
return prop_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* They can be equal, but generic string comparison is too costly. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* They can be equal, but generic string comparison is too costly. */
|
||||
}
|
||||
|
||||
entry_p++;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
|
||||
@@ -190,11 +237,10 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
|
||||
*/
|
||||
void
|
||||
ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
|
||||
ecma_string_t *prop_name_p, /**< property's name */
|
||||
jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_property_t *prop_p) /**< property */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
JERRY_ASSERT (prop_name_p != NULL);
|
||||
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|
||||
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|
||||
@@ -203,7 +249,8 @@ ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t object_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
|
||||
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
|
||||
lit_string_hash_t name_hash = ecma_string_get_property_name_hash (*prop_p, name_cp);
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
|
||||
ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
|
||||
|
||||
for (uint32_t entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
*/
|
||||
|
||||
extern void ecma_lcache_init (void);
|
||||
extern void ecma_lcache_insert (ecma_object_t *, ecma_string_t *, ecma_property_t *);
|
||||
extern void ecma_lcache_insert (ecma_object_t *, jmem_cpointer_t, ecma_property_t *);
|
||||
extern ecma_property_t *ecma_lcache_lookup (ecma_object_t *, const ecma_string_t *);
|
||||
extern void ecma_lcache_invalidate (ecma_object_t *, ecma_string_t *, ecma_property_t *);
|
||||
extern void ecma_lcache_invalidate (ecma_object_t *, jmem_cpointer_t, ecma_property_t *);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -161,18 +161,15 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]);
|
||||
|
||||
if (!(type == ECMA_PROPERTY_TYPE_NAMEDDATA || type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR))
|
||||
if (!ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ecma_property_pair_t *property_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
ecma_string_t *name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
property_pair_p->names_cp[i]);
|
||||
|
||||
uint32_t entry_index = name_p->hash;
|
||||
uint32_t entry_index = ecma_string_get_property_name_hash (prop_iter_p->types[i],
|
||||
property_pair_p->names_cp[i]);
|
||||
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
|
||||
|
||||
if (mask < LIT_STRING_HASH_LIMIT)
|
||||
@@ -333,7 +330,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
|
||||
*/
|
||||
void
|
||||
ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
ecma_string_t *name_p, /**< name of the property */
|
||||
jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_property_t *property_p) /**< property */
|
||||
{
|
||||
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
|
||||
@@ -342,7 +339,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
|
||||
JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
|
||||
|
||||
uint32_t entry_index = name_p->hash;
|
||||
uint32_t entry_index = ecma_string_get_property_name_hash (*property_p, name_cp);
|
||||
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
|
||||
uint32_t mask = hashmap_p->max_property_count - 1;
|
||||
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
|
||||
@@ -368,6 +365,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
||||
if (ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
|
||||
{
|
||||
offset = 1;
|
||||
@@ -378,9 +376,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
|
||||
if ((property_pair_p->header.types + offset) == property_p)
|
||||
{
|
||||
JERRY_ASSERT (ecma_compare_ecma_strings (ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
property_pair_p->names_cp[offset]),
|
||||
name_p));
|
||||
JERRY_ASSERT (property_pair_p->names_cp[offset] == name_cp);
|
||||
|
||||
pair_list_p[entry_index] = ECMA_NULL_POINTER;
|
||||
ECMA_PROPERTY_HASHMAP_SET_BIT (bits_p, entry_index);
|
||||
@@ -415,7 +411,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
ecma_property_t *
|
||||
ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
ecma_string_t *name_p, /**< property name */
|
||||
ecma_string_t **property_real_name_p) /**< [out] property real name */
|
||||
jmem_cpointer_t *property_real_name_cp) /**< [out] property real name */
|
||||
{
|
||||
#ifndef JERRY_NDEBUG
|
||||
/* A sanity check in debug mode: a named property must be present
|
||||
@@ -434,12 +430,11 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
if (prop_pair_p->names_cp[i] != ECMA_NULL_POINTER)
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i]))
|
||||
{
|
||||
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (ecma_compare_ecma_strings (name_p, property_name_p))
|
||||
if (ecma_string_compare_to_property_name (prop_iter_p->types[i],
|
||||
prop_pair_p->names_cp[i],
|
||||
name_p))
|
||||
{
|
||||
property_found = true;
|
||||
break;
|
||||
@@ -486,16 +481,19 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
ecma_property_pair_t *property_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_property_pair_t,
|
||||
pair_list_p[entry_index]);
|
||||
|
||||
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
property_pair_p->names_cp[offset]);
|
||||
ecma_property_t *property_p = property_pair_p->header.types + offset;
|
||||
|
||||
if (ecma_compare_ecma_strings (name_p, property_name_p))
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*property_p));
|
||||
|
||||
if (ecma_string_compare_to_property_name (*property_p,
|
||||
property_pair_p->names_cp[offset],
|
||||
name_p))
|
||||
{
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (property_found);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
*property_real_name_p = property_name_p;
|
||||
return property_pair_p->header.types + offset;
|
||||
*property_real_name_cp = property_pair_p->names_cp[offset];
|
||||
return property_p;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -56,10 +56,10 @@ typedef struct
|
||||
extern void ecma_property_hashmap_create (ecma_object_t *);
|
||||
extern void ecma_property_hashmap_free (ecma_object_t *);
|
||||
extern void ecma_property_hashmap_insert (ecma_object_t *, ecma_string_t *, ecma_property_pair_t *, int);
|
||||
extern void ecma_property_hashmap_delete (ecma_object_t *, ecma_string_t *, ecma_property_t *);
|
||||
extern void ecma_property_hashmap_delete (ecma_object_t *, jmem_cpointer_t, ecma_property_t *);
|
||||
|
||||
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
|
||||
extern ecma_property_t *ecma_property_hashmap_find (ecma_property_hashmap_t *, ecma_string_t *, ecma_string_t **);
|
||||
extern ecma_property_t *ecma_property_hashmap_find (ecma_property_hashmap_t *, ecma_string_t *, jmem_cpointer_t *);
|
||||
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
|
||||
|
||||
/**
|
||||
|
||||
@@ -387,9 +387,9 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lit_magic_string_id_t magic_string_id;
|
||||
lit_magic_string_id_t magic_string_id = ecma_get_string_magic (string_p);
|
||||
|
||||
if (!ecma_is_string_magic (string_p, &magic_string_id))
|
||||
if (magic_string_id == LIT_MAGIC_STRING__COUNT)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1259,7 +1259,8 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
|| ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
|
||||
{
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
ecma_string_t *name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_pair_p->names_cp[i]);
|
||||
ecma_string_t *name_p = ecma_string_from_property_name (*property_p,
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (!(is_enumerable_only && !ecma_is_property_enumerable (*property_p)))
|
||||
{
|
||||
@@ -1311,6 +1312,8 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column);
|
||||
}
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,9 +139,4 @@ typedef uint16_t lit_string_hash_t;
|
||||
*/
|
||||
#define LIT_STRING_HASH_LIMIT 0x10000u
|
||||
|
||||
/**
|
||||
* Hash of the frequently used "length" string.
|
||||
*/
|
||||
#define LIT_STRING_LENGTH_HASH 0x3615u
|
||||
|
||||
#endif /* !LIT_GLOBALS_H */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* @return number of the strings, if there were registered,
|
||||
* zero - otherwise.
|
||||
*/
|
||||
uint32_t
|
||||
inline uint32_t __attr_always_inline___
|
||||
lit_get_magic_string_ex_count (void)
|
||||
{
|
||||
return JERRY_CONTEXT (lit_magic_string_ex_count);
|
||||
@@ -161,28 +161,24 @@ lit_magic_strings_ex_set (const lit_utf8_byte_t **ex_str_items, /**< character a
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
} /* lit_magic_strings_ex_set */
|
||||
|
||||
|
||||
/**
|
||||
* Check if passed cesu-8 string equals to one of magic strings
|
||||
* and if equal magic string was found, return it's id in 'out_id_p' argument.
|
||||
* Returns the magic string id of the argument string if it is available.
|
||||
*
|
||||
* @return true - if magic string equal to passed string was found,
|
||||
* false - otherwise.
|
||||
* @return id - if magic string id is found,
|
||||
* LIT_MAGIC_STRING__COUNT - otherwise.
|
||||
*/
|
||||
bool
|
||||
lit_magic_string_id_t
|
||||
lit_is_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
|
||||
lit_utf8_size_t string_size, /**< string size in bytes */
|
||||
lit_magic_string_id_t *out_id_p) /**< [out] magic string's id */
|
||||
lit_utf8_size_t string_size) /**< string size in bytes */
|
||||
{
|
||||
*out_id_p = LIT_MAGIC_STRING__COUNT;
|
||||
|
||||
if (string_size > lit_get_magic_string_size (LIT_MAGIC_STRING__COUNT - 1))
|
||||
{
|
||||
return false;
|
||||
return LIT_MAGIC_STRING__COUNT;
|
||||
}
|
||||
|
||||
int first = (int) lit_get_magic_string_size_block_start (string_size); /**< First magic string element */
|
||||
int last = (int) (lit_get_magic_string_size_block_start (string_size + 1) - 1); /**< Last magic string element */
|
||||
/**< The string must be in this id range. */
|
||||
int first = (int) lit_get_magic_string_size_block_start (string_size);
|
||||
int last = (int) (lit_get_magic_string_size_block_start (string_size + 1) - 1);
|
||||
|
||||
while (first <= last)
|
||||
{
|
||||
@@ -191,8 +187,7 @@ lit_is_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
|
||||
|
||||
if (compare == 0)
|
||||
{
|
||||
*out_id_p = (lit_magic_string_id_t) middle;
|
||||
return true;
|
||||
return (lit_magic_string_id_t) middle;
|
||||
}
|
||||
else if (compare > 0)
|
||||
{
|
||||
@@ -204,19 +199,70 @@ lit_is_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return LIT_MAGIC_STRING__COUNT;
|
||||
} /* lit_is_utf8_string_magic */
|
||||
|
||||
/**
|
||||
* Check if passed utf-8 string equals to one of external magic strings
|
||||
* and if equal magic string was found, return it's id in 'out_id_p' argument.
|
||||
* Returns the magic string id of the argument string pair if it is available.
|
||||
*
|
||||
* @return true - if external magic string equal to passed string was found,
|
||||
* false - otherwise.
|
||||
* @return id - if magic string id is found,
|
||||
* LIT_MAGIC_STRING__COUNT - otherwise.
|
||||
*/
|
||||
bool lit_is_ex_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
|
||||
lit_utf8_size_t string_size, /**< string size in bytes */
|
||||
lit_magic_string_ex_id_t *out_id_p) /**< [out] magic string's id */
|
||||
lit_magic_string_id_t
|
||||
lit_is_utf8_string_pair_magic (const lit_utf8_byte_t *string1_p, /**< first utf-8 string */
|
||||
lit_utf8_size_t string1_size, /**< first string size in bytes */
|
||||
const lit_utf8_byte_t *string2_p, /**< second utf-8 string */
|
||||
lit_utf8_size_t string2_size) /**< second string size in bytes */
|
||||
{
|
||||
lit_utf8_size_t total_string_size = string1_size + string2_size;
|
||||
|
||||
if (total_string_size > lit_get_magic_string_size (LIT_MAGIC_STRING__COUNT - 1))
|
||||
{
|
||||
return LIT_MAGIC_STRING__COUNT;
|
||||
}
|
||||
|
||||
/**< The string must be in this id range. */
|
||||
int first = (int) lit_get_magic_string_size_block_start (total_string_size);
|
||||
int last = (int) (lit_get_magic_string_size_block_start (total_string_size + 1) - 1);
|
||||
|
||||
while (first <= last)
|
||||
{
|
||||
int middle = ((first + last) / 2); /**< mid point of search */
|
||||
const lit_utf8_byte_t *middle_string_p = lit_get_magic_string_utf8 (middle);
|
||||
|
||||
int compare = memcmp (middle_string_p, string1_p, string1_size);
|
||||
|
||||
if (compare == 0)
|
||||
{
|
||||
compare = memcmp (middle_string_p + string1_size, string2_p, string2_size);
|
||||
}
|
||||
|
||||
if (compare == 0)
|
||||
{
|
||||
return (lit_magic_string_id_t) middle;
|
||||
}
|
||||
else if (compare > 0)
|
||||
{
|
||||
last = middle - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return LIT_MAGIC_STRING__COUNT;
|
||||
} /* lit_is_utf8_string_pair_magic */
|
||||
|
||||
/**
|
||||
* Returns the ex magic string id of the argument string if it is available.
|
||||
*
|
||||
* @return id - if magic string id is found,
|
||||
* lit_get_magic_string_ex_count () - otherwise.
|
||||
*/
|
||||
lit_magic_string_ex_id_t
|
||||
lit_is_ex_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
|
||||
lit_utf8_size_t string_size) /**< string size in bytes */
|
||||
{
|
||||
/* TODO: Improve performance of search */
|
||||
|
||||
@@ -224,36 +270,51 @@ bool lit_is_ex_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 st
|
||||
id < JERRY_CONTEXT (lit_magic_string_ex_count);
|
||||
id = (lit_magic_string_ex_id_t) (id + 1))
|
||||
{
|
||||
if (lit_compare_utf8_string_and_magic_string_ex (string_p, string_size, id))
|
||||
if (string_size == lit_get_magic_string_ex_size (id))
|
||||
{
|
||||
*out_id_p = id;
|
||||
|
||||
return true;
|
||||
if (memcmp (string_p, lit_get_magic_string_ex_utf8 (id), string_size) == 0)
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*out_id_p = JERRY_CONTEXT (lit_magic_string_ex_count);
|
||||
|
||||
return false;
|
||||
return JERRY_CONTEXT (lit_magic_string_ex_count);
|
||||
} /* lit_is_ex_utf8_string_magic */
|
||||
|
||||
/**
|
||||
* Compare utf-8 string and external magic string for equality
|
||||
* Returns the ex magic string id of the argument string pair if it is available.
|
||||
*
|
||||
* @return true if strings are equal
|
||||
* false otherwise
|
||||
* @return id - if magic string id is found,
|
||||
* lit_get_magic_string_ex_count () - otherwise.
|
||||
*/
|
||||
bool
|
||||
lit_compare_utf8_string_and_magic_string_ex (const lit_utf8_byte_t *string_p, /**< utf-8 string */
|
||||
lit_utf8_size_t string_size, /**< string size in bytes */
|
||||
lit_magic_string_ex_id_t magic_string_ex_id) /**< external magic string's
|
||||
* id */
|
||||
lit_magic_string_ex_id_t
|
||||
lit_is_ex_utf8_string_pair_magic (const lit_utf8_byte_t *string1_p, /**< first utf-8 string */
|
||||
lit_utf8_size_t string1_size, /**< first string size in bytes */
|
||||
const lit_utf8_byte_t *string2_p, /**< second utf-8 string */
|
||||
lit_utf8_size_t string2_size) /**< second string size in bytes */
|
||||
{
|
||||
return lit_compare_utf8_strings (string_p,
|
||||
string_size,
|
||||
lit_get_magic_string_ex_utf8 (magic_string_ex_id),
|
||||
lit_get_magic_string_ex_size (magic_string_ex_id));
|
||||
} /* lit_compare_utf8_string_and_magic_string_ex */
|
||||
/* TODO: Improve performance of search */
|
||||
lit_utf8_size_t total_string_size = string1_size + string2_size;
|
||||
|
||||
for (lit_magic_string_ex_id_t id = (lit_magic_string_ex_id_t) 0;
|
||||
id < JERRY_CONTEXT (lit_magic_string_ex_count);
|
||||
id = (lit_magic_string_ex_id_t) (id + 1))
|
||||
{
|
||||
if (total_string_size == lit_get_magic_string_ex_size (id))
|
||||
{
|
||||
const lit_utf8_byte_t *ex_magic_string_p = lit_get_magic_string_ex_utf8 (id);
|
||||
|
||||
if (memcmp (string1_p, ex_magic_string_p, string1_size) == 0
|
||||
&& memcmp (string2_p, ex_magic_string_p + string1_size, string2_size) == 0)
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JERRY_CONTEXT (lit_magic_string_ex_count);
|
||||
} /* lit_is_ex_utf8_string_pair_magic */
|
||||
|
||||
/**
|
||||
* Copy magic string to buffer
|
||||
|
||||
@@ -53,12 +53,13 @@ extern lit_utf8_size_t lit_get_magic_string_ex_size (lit_magic_string_ex_id_t);
|
||||
|
||||
extern void lit_magic_strings_ex_set (const lit_utf8_byte_t **, uint32_t, const lit_utf8_size_t *);
|
||||
|
||||
extern bool lit_is_utf8_string_magic (const lit_utf8_byte_t *, lit_utf8_size_t, lit_magic_string_id_t *);
|
||||
extern lit_magic_string_id_t lit_is_utf8_string_magic (const lit_utf8_byte_t *, lit_utf8_size_t);
|
||||
extern lit_magic_string_id_t lit_is_utf8_string_pair_magic (const lit_utf8_byte_t *, lit_utf8_size_t,
|
||||
const lit_utf8_byte_t *, lit_utf8_size_t);
|
||||
|
||||
extern bool lit_is_ex_utf8_string_magic (const lit_utf8_byte_t *, lit_utf8_size_t, lit_magic_string_ex_id_t *);
|
||||
|
||||
extern bool lit_compare_utf8_string_and_magic_string_ex (const lit_utf8_byte_t *, lit_utf8_size_t,
|
||||
lit_magic_string_ex_id_t);
|
||||
extern lit_magic_string_ex_id_t lit_is_ex_utf8_string_magic (const lit_utf8_byte_t *, lit_utf8_size_t);
|
||||
extern lit_magic_string_ex_id_t lit_is_ex_utf8_string_pair_magic (const lit_utf8_byte_t *, lit_utf8_size_t,
|
||||
const lit_utf8_byte_t *, lit_utf8_size_t);
|
||||
|
||||
extern lit_utf8_byte_t *lit_copy_magic_string_to_buffer (lit_magic_string_id_t, lit_utf8_byte_t *, lit_utf8_size_t);
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MIN, "min")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NOW, "now")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_POP, "pop")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_POW, "pow")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SIN, "sin")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET, "set")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SIN, "sin")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TAN, "tan")
|
||||
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (4, LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP, "(?:)")
|
||||
|
||||
@@ -739,26 +739,6 @@ lit_convert_surrogate_pair_to_code_point (ecma_char_t high_surrogate, /**< high
|
||||
return code_point;
|
||||
} /* lit_convert_surrogate_pair_to_code_point */
|
||||
|
||||
/**
|
||||
* Compare cesu-8 string to cesu-8 string
|
||||
*
|
||||
* @return true - if strings are equal;
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
lit_compare_utf8_strings (const lit_utf8_byte_t *string1_p, /**< utf-8 string */
|
||||
lit_utf8_size_t string1_size, /**< string size */
|
||||
const lit_utf8_byte_t *string2_p, /**< utf-8 string */
|
||||
lit_utf8_size_t string2_size) /**< string size */
|
||||
{
|
||||
if (string1_size != string2_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return memcmp (string1_p, string2_p, string1_size) == 0;
|
||||
} /* lit_compare_utf8_strings */
|
||||
|
||||
/**
|
||||
* Relational compare of cesu-8 strings
|
||||
*
|
||||
|
||||
@@ -113,9 +113,6 @@ lit_utf8_size_t lit_code_point_to_utf8 (lit_code_point_t, lit_utf8_byte_t *);
|
||||
lit_utf8_size_t lit_code_point_to_cesu8 (lit_code_point_t, lit_utf8_byte_t *);
|
||||
lit_code_point_t lit_convert_surrogate_pair_to_code_point (ecma_char_t, ecma_char_t);
|
||||
|
||||
bool lit_compare_utf8_strings (const lit_utf8_byte_t *, lit_utf8_size_t,
|
||||
const lit_utf8_byte_t *, lit_utf8_size_t);
|
||||
|
||||
bool lit_compare_utf8_strings_relational (const lit_utf8_byte_t *string1_p, lit_utf8_size_t,
|
||||
const lit_utf8_byte_t *string2_p, lit_utf8_size_t);
|
||||
|
||||
|
||||
+7
-1
@@ -62,7 +62,13 @@ vm_op_get_value (ecma_value_t object, /**< base object */
|
||||
{
|
||||
ecma_integer_value_t int_value = ecma_get_integer_from_value (property);
|
||||
|
||||
if (int_value >= 0)
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
bool limit_check = (int_value >= 0);
|
||||
#else /* !JERRY_CPOINTER_32_BIT */
|
||||
bool limit_check = (int_value >= 0 && int_value < (UINT16_MAX + 1));
|
||||
#endif
|
||||
|
||||
if (limit_check)
|
||||
{
|
||||
/* Statically allocated string for searching. */
|
||||
ecma_init_ecma_string_from_uint32 (&uint32_string, (uint32_t) int_value);
|
||||
|
||||
Reference in New Issue
Block a user