Implement direct strings. (#2196)
Direct strings are a new type of direct ecma-values (no memory allocation is needed for encoding them) in JerryScript. Currently magic strings, external magic strings and uint values are encoded as direct strings. The constant pool of JerryScript byte-code is changed to hold ecma-values rather than cpointers to support direct strings. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -157,7 +157,7 @@ ecma_gc_mark_property (ecma_property_pair_t *property_pair_p, /**< property pair
|
||||
{
|
||||
case ECMA_PROPERTY_TYPE_NAMEDDATA:
|
||||
{
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& property_pair_p->names_cp[index] >= LIT_NEED_MARK_MAGIC_STRING__COUNT)
|
||||
{
|
||||
break;
|
||||
@@ -478,7 +478,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
jmem_cpointer_t name_cp = prop_pair_p->names_cp[i];
|
||||
|
||||
/* Call the native's free callback. */
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER))
|
||||
{
|
||||
@@ -666,18 +666,18 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
case ECMA_PSEUDO_ARRAY_ARGUMENTS:
|
||||
{
|
||||
ecma_length_t formal_params_number = ext_object_p->u.pseudo_array.u1.length;
|
||||
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
|
||||
ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
|
||||
|
||||
for (ecma_length_t i = 0; i < formal_params_number; i++)
|
||||
{
|
||||
if (arg_Literal_p[i] != JMEM_CP_NULL)
|
||||
if (arg_Literal_p[i] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[i]);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (arg_Literal_p[i]);
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
}
|
||||
|
||||
size_t formal_params_size = formal_params_number * sizeof (jmem_cpointer_t);
|
||||
size_t formal_params_size = formal_params_number * sizeof (ecma_value_t);
|
||||
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t) + formal_params_size);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -83,18 +83,20 @@ typedef enum
|
||||
typedef enum
|
||||
{
|
||||
ECMA_TYPE_DIRECT = 0, /**< directly encoded value, a 28 bit signed integer or a simple value */
|
||||
ECMA_TYPE_FLOAT = 1, /**< pointer to a 64 or 32 bit floating point number */
|
||||
ECMA_TYPE_STRING = 2, /**< pointer to description of a string */
|
||||
ECMA_TYPE_STRING = 1, /**< pointer to description of a string */
|
||||
ECMA_TYPE_FLOAT = 2, /**< pointer to a 64 or 32 bit floating point number */
|
||||
ECMA_TYPE_OBJECT = 3, /**< pointer to description of an object */
|
||||
ECMA_TYPE_DIRECT_STRING = 5, /**< directly encoded string values */
|
||||
ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference */
|
||||
ECMA_TYPE_COLLECTION_CHUNK = ECMA_TYPE_ERROR, /**< pointer to description of a collection chunk */
|
||||
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;
|
||||
|
||||
/**
|
||||
* Description of an ecma value
|
||||
*
|
||||
* Bit-field structure: type (2) | error (1) | value (29)
|
||||
* Bit-field structure: type (3) | value (29)
|
||||
*/
|
||||
typedef uint32_t ecma_value_t;
|
||||
|
||||
@@ -113,12 +115,12 @@ typedef int32_t ecma_integer_value_t;
|
||||
#endif /* UINTPTR_MAX <= UINT32_MAX */
|
||||
|
||||
/**
|
||||
* Mask for ecma types in ecma_type_t
|
||||
* Mask for ecma types in ecma_value_t
|
||||
*/
|
||||
#define ECMA_VALUE_TYPE_MASK 0x7u
|
||||
|
||||
/**
|
||||
* Shift for value part in ecma_type_t
|
||||
* Shift for value part in ecma_value_t
|
||||
*/
|
||||
#define ECMA_VALUE_SHIFT 3
|
||||
|
||||
@@ -420,11 +422,6 @@ typedef enum
|
||||
*/
|
||||
#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.
|
||||
*
|
||||
@@ -1058,6 +1055,7 @@ typedef double ecma_number_t;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -1085,19 +1083,90 @@ typedef struct
|
||||
* so the chunk area is enlarged by one for this value */
|
||||
} ecma_collection_chunk_t;
|
||||
|
||||
/**
|
||||
* Direct string types (2 bit).
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_DIRECT_STRING_PTR = 0, /**< string is a string pointer, only used by property names */
|
||||
ECMA_DIRECT_STRING_MAGIC = 1, /**< string is a magic string */
|
||||
ECMA_DIRECT_STRING_UINT = 2, /**< string is an unsigned int */
|
||||
ECMA_DIRECT_STRING_MAGIC_EX = 3, /**< string is an extended magic string */
|
||||
} ecma_direct_string_type_t;
|
||||
|
||||
/**
|
||||
* Maximum value of the immediate part of a direct magic string.
|
||||
* Must be compatible with the immediate property name.
|
||||
*/
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
#define ECMA_DIRECT_STRING_MAX_IMM 0x07ffffff
|
||||
#else /* !JERRY_CPOINTER_32_BIT */
|
||||
#define ECMA_DIRECT_STRING_MAX_IMM 0x0000ffff
|
||||
#endif /* JERRY_CPOINTER_32_BIT */
|
||||
|
||||
/**
|
||||
* Shift for direct string value part in ecma_value_t.
|
||||
*/
|
||||
#define ECMA_DIRECT_STRING_SHIFT (ECMA_VALUE_SHIFT + 2)
|
||||
|
||||
/**
|
||||
* Full mask for direct strings.
|
||||
*/
|
||||
#define ECMA_DIRECT_STRING_MASK ((uintptr_t) (ECMA_DIRECT_TYPE_MASK | (0x3u << ECMA_VALUE_SHIFT)))
|
||||
|
||||
/**
|
||||
* Create an ecma direct string.
|
||||
*/
|
||||
#define ECMA_CREATE_DIRECT_STRING(type, value) \
|
||||
((uintptr_t) (ECMA_TYPE_DIRECT_STRING | ((type) << ECMA_VALUE_SHIFT) | (value) << ECMA_DIRECT_STRING_SHIFT))
|
||||
|
||||
/**
|
||||
* Checks whether the string is direct.
|
||||
*/
|
||||
#define ECMA_IS_DIRECT_STRING(string_p) \
|
||||
((((uintptr_t) (string_p)) & 0x1) != 0)
|
||||
|
||||
/**
|
||||
* Checks whether the string is direct.
|
||||
*/
|
||||
#define ECMA_IS_DIRECT_STRING_WITH_TYPE(string_p, type) \
|
||||
((((uintptr_t) (string_p)) & ECMA_DIRECT_STRING_MASK) == ECMA_CREATE_DIRECT_STRING (type, 0))
|
||||
|
||||
/**
|
||||
* Returns the type of a direct string.
|
||||
*/
|
||||
#define ECMA_GET_DIRECT_STRING_TYPE(string_p) \
|
||||
((((uintptr_t) (string_p)) >> ECMA_VALUE_SHIFT) & 0x3)
|
||||
|
||||
/**
|
||||
* Shift applied to type conversions.
|
||||
*/
|
||||
#define ECMA_STRING_TYPE_CONVERSION_SHIFT (ECMA_PROPERTY_NAME_TYPE_SHIFT - ECMA_VALUE_SHIFT)
|
||||
|
||||
/**
|
||||
* Converts direct string type to property name type.
|
||||
*/
|
||||
#define ECMA_DIRECT_STRING_TYPE_TO_PROP_NAME_TYPE(string_p) \
|
||||
((((uintptr_t) (string_p)) & (0x3 << ECMA_VALUE_SHIFT)) << ECMA_STRING_TYPE_CONVERSION_SHIFT)
|
||||
|
||||
/**
|
||||
* Returns the value of a direct string.
|
||||
*/
|
||||
#define ECMA_GET_DIRECT_STRING_VALUE(string_p) \
|
||||
(((uintptr_t) (string_p)) >> ECMA_DIRECT_STRING_SHIFT)
|
||||
|
||||
/**
|
||||
* Identifier for ecma-string's actual data container
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
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_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number
|
||||
stored locally in the string's descriptor */
|
||||
ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */
|
||||
|
||||
ECMA_STRING_LITERAL_NUMBER, /**< a literal number which is used solely by the literal storage
|
||||
* so no string processing function supports this type except
|
||||
@@ -1166,9 +1235,8 @@ 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 */
|
||||
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) */
|
||||
ecma_value_t lit_number; /**< number (see ECMA_STRING_LITERAL_NUMBER) */
|
||||
uint32_t common_uint32_field; /**< for zeroing and comparison in some cases */
|
||||
} u;
|
||||
} ecma_string_t;
|
||||
|
||||
@@ -45,10 +45,9 @@ ecma_create_native_property (ecma_object_t *obj_p, /**< object to create propert
|
||||
JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
|
||||
ecma_string_t name;
|
||||
ecma_init_ecma_magic_string (&name, id);
|
||||
ecma_string_t *name_p = ecma_get_magic_string (id);
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, &name);
|
||||
bool is_new = (property_p == NULL);
|
||||
|
||||
ecma_native_pointer_t *native_pointer_p;
|
||||
@@ -56,7 +55,7 @@ ecma_create_native_property (ecma_object_t *obj_p, /**< object to create propert
|
||||
if (is_new)
|
||||
{
|
||||
ecma_property_value_t *value_p;
|
||||
value_p = ecma_create_named_data_property (obj_p, &name, ECMA_PROPERTY_FLAG_WRITABLE, NULL);
|
||||
value_p = ecma_create_named_data_property (obj_p, name_p, ECMA_PROPERTY_FLAG_WRITABLE, NULL);
|
||||
|
||||
native_pointer_p = jmem_heap_alloc_block (sizeof (ecma_native_pointer_t));
|
||||
|
||||
@@ -69,8 +68,6 @@ ecma_create_native_property (ecma_object_t *obj_p, /**< object to create propert
|
||||
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (&name));
|
||||
|
||||
native_pointer_p->data_p = data_p;
|
||||
native_pointer_p->u.info_p = info_p;
|
||||
|
||||
@@ -130,12 +127,8 @@ ecma_get_native_pointer_value (ecma_object_t *obj_p, /**< object to get property
|
||||
JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
|
||||
ecma_string_t name;
|
||||
ecma_init_ecma_magic_string (&name, id);
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, &name);
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (&name));
|
||||
ecma_string_t *name_p = ecma_get_magic_string (id);
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -296,6 +296,9 @@ ecma_is_value_number (ecma_value_t value) /**< ecma value */
|
||||
|| ecma_is_value_float_number (value));
|
||||
} /* ecma_is_value_number */
|
||||
|
||||
JERRY_STATIC_ASSERT ((ECMA_TYPE_STRING | 0x4) == ECMA_TYPE_DIRECT_STRING,
|
||||
ecma_type_string_and_direct_string_must_have_one_bit_difference);
|
||||
|
||||
/**
|
||||
* Check if the value is ecma-string.
|
||||
*
|
||||
@@ -305,7 +308,7 @@ ecma_is_value_number (ecma_value_t value) /**< ecma value */
|
||||
inline bool __attr_const___ __attr_always_inline___
|
||||
ecma_is_value_string (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
return (ecma_get_value_type_field (value) == ECMA_TYPE_STRING);
|
||||
return ((value & (ECMA_VALUE_TYPE_MASK - 0x4)) == ECMA_TYPE_STRING);
|
||||
} /* ecma_is_value_string */
|
||||
|
||||
/**
|
||||
@@ -503,6 +506,11 @@ ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to refer
|
||||
{
|
||||
JERRY_ASSERT (ecma_string_p != NULL);
|
||||
|
||||
if ((((uintptr_t) ecma_string_p) & ECMA_VALUE_TYPE_MASK) != 0)
|
||||
{
|
||||
return (ecma_value_t) (uintptr_t) ecma_string_p;
|
||||
}
|
||||
|
||||
return ecma_pointer_to_ecma_value (ecma_string_p) | ECMA_TYPE_STRING;
|
||||
} /* ecma_make_string_value */
|
||||
|
||||
@@ -594,7 +602,12 @@ ecma_get_number_from_value (ecma_value_t value) /**< ecma value */
|
||||
inline ecma_string_t *__attr_pure___ __attr_always_inline___
|
||||
ecma_get_string_from_value (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_STRING);
|
||||
JERRY_ASSERT (ecma_is_value_string (value));
|
||||
|
||||
if ((value & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_DIRECT_STRING)
|
||||
{
|
||||
return (ecma_string_t *) (uintptr_t) value;
|
||||
}
|
||||
|
||||
return (ecma_string_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_string_from_value */
|
||||
@@ -607,7 +620,7 @@ ecma_get_string_from_value (ecma_value_t value) /**< ecma value */
|
||||
inline ecma_object_t *__attr_pure___ __attr_always_inline___
|
||||
ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_OBJECT);
|
||||
JERRY_ASSERT (ecma_is_value_object (value));
|
||||
|
||||
return (ecma_object_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_object_from_value */
|
||||
@@ -666,6 +679,7 @@ ecma_copy_value (ecma_value_t value) /**< value description */
|
||||
switch (ecma_get_value_type_field (value))
|
||||
{
|
||||
case ECMA_TYPE_DIRECT:
|
||||
case ECMA_TYPE_DIRECT_STRING:
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@@ -856,6 +870,7 @@ ecma_free_value (ecma_value_t value) /**< value description */
|
||||
switch (ecma_get_value_type_field (value))
|
||||
{
|
||||
case ECMA_TYPE_DIRECT:
|
||||
case ECMA_TYPE_DIRECT_STRING:
|
||||
{
|
||||
/* no memory is allocated */
|
||||
break;
|
||||
|
||||
@@ -74,8 +74,9 @@ ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection
|
||||
|
||||
do
|
||||
{
|
||||
if (!ecma_is_value_object (*item_p)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS))
|
||||
if (!(flags & ECMA_COLLECTION_NO_COPY)
|
||||
&& (!ecma_is_value_object (*item_p)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
|
||||
{
|
||||
ecma_free_value (*item_p);
|
||||
}
|
||||
@@ -139,8 +140,9 @@ ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< colle
|
||||
}
|
||||
}
|
||||
|
||||
if (!ecma_is_value_object (value)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS))
|
||||
if (!(flags & ECMA_COLLECTION_NO_COPY)
|
||||
&& (!ecma_is_value_object (value)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
|
||||
{
|
||||
value = ecma_copy_value (value);
|
||||
}
|
||||
|
||||
@@ -723,7 +723,7 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
{
|
||||
case ECMA_PROPERTY_TYPE_NAMEDDATA:
|
||||
{
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_STRING_CONTAINER_MAGIC_STRING)
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC)
|
||||
{
|
||||
if (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER)
|
||||
@@ -758,7 +758,7 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
ecma_lcache_invalidate (object_p, name_cp, property_p);
|
||||
}
|
||||
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_PROPERTY_NAME_TYPE_STRING)
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR)
|
||||
{
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
@@ -1475,34 +1475,33 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
{
|
||||
jmem_cpointer_t *literal_start_p = NULL;
|
||||
ecma_value_t *literal_start_p = NULL;
|
||||
uint32_t literal_end;
|
||||
uint32_t const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
|
||||
literal_start_p = (ecma_value_t *) ((uint8_t *) bytecode_p + sizeof (cbc_uint16_arguments_t));
|
||||
literal_start_p -= args_p->register_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
|
||||
literal_start_p = (ecma_value_t *) ((uint8_t *) bytecode_p + sizeof (cbc_uint8_arguments_t));
|
||||
literal_start_p -= args_p->register_end;
|
||||
}
|
||||
|
||||
for (uint32_t i = const_literal_end; i < literal_end; i++)
|
||||
{
|
||||
jmem_cpointer_t bytecode_cpointer = literal_start_p[i];
|
||||
ecma_compiled_code_t *bytecode_literal_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
|
||||
bytecode_cpointer);
|
||||
ecma_compiled_code_t *bytecode_literal_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||
literal_start_p[i]);
|
||||
|
||||
/* Self references are ignored. */
|
||||
if (bytecode_literal_p != bytecode_p)
|
||||
@@ -1554,7 +1553,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
|
||||
re_compiled_code_t *re_bytecode_p = (re_compiled_code_t *) bytecode_p;
|
||||
|
||||
ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, re_bytecode_p->pattern_cp));
|
||||
ecma_deref_ecma_string (ecma_get_string_from_value (re_bytecode_p->pattern));
|
||||
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
|
||||
}
|
||||
|
||||
|
||||
@@ -233,8 +233,6 @@ ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p,
|
||||
void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p,
|
||||
lit_utf8_size_t buffer_size);
|
||||
const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p, lit_utf8_size_t *size_p, bool *is_ascii_p);
|
||||
void ecma_init_ecma_string_from_uint32 (ecma_string_t *string_desc_p, uint32_t uint32_number);
|
||||
void ecma_init_ecma_magic_string (ecma_string_t *string_desc_p, lit_magic_string_id_t id);
|
||||
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
|
||||
bool ecma_string_is_empty (const ecma_string_t *string_p);
|
||||
bool ecma_string_is_length (const ecma_string_t *string_p);
|
||||
|
||||
@@ -143,38 +143,13 @@ 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)
|
||||
if (ECMA_IS_DIRECT_STRING (prop_name_p))
|
||||
{
|
||||
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_t) ECMA_GET_DIRECT_STRING_TYPE (prop_name_p);
|
||||
return (jmem_cpointer_t) ECMA_GET_DIRECT_STRING_VALUE (prop_name_p);
|
||||
}
|
||||
|
||||
*name_type_p = ECMA_PROPERTY_NAME_TYPE_STRING;
|
||||
*name_type_p = ECMA_DIRECT_STRING_PTR;
|
||||
|
||||
jmem_cpointer_t prop_name_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (prop_name_cp, prop_name_p);
|
||||
|
||||
@@ -66,12 +66,17 @@ ecma_finalize_lit_storage (void)
|
||||
*
|
||||
* @return ecma_string_t compressed pointer
|
||||
*/
|
||||
jmem_cpointer_t
|
||||
ecma_value_t
|
||||
ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */
|
||||
lit_utf8_size_t size) /**< size of the string */
|
||||
{
|
||||
ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size);
|
||||
|
||||
if (ECMA_IS_DIRECT_STRING (string_p))
|
||||
{
|
||||
return ecma_make_string_value (string_p);
|
||||
}
|
||||
|
||||
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
jmem_cpointer_t *empty_cpointer_p = NULL;
|
||||
|
||||
@@ -95,7 +100,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
|
||||
{
|
||||
/* Return with string if found in the list. */
|
||||
ecma_deref_ecma_string (string_p);
|
||||
return string_list_p->values[i];
|
||||
return ecma_make_string_value (value_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,7 +114,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
|
||||
if (empty_cpointer_p != NULL)
|
||||
{
|
||||
*empty_cpointer_p = result;
|
||||
return result;
|
||||
return ecma_make_string_value (string_p);
|
||||
}
|
||||
|
||||
ecma_lit_storage_item_t *new_item_p;
|
||||
@@ -124,7 +129,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
|
||||
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (string_list_first_p));
|
||||
JERRY_CONTEXT (string_list_first_p) = new_item_p;
|
||||
|
||||
return result;
|
||||
return ecma_make_string_value (string_p);
|
||||
} /* ecma_find_or_create_literal_string */
|
||||
|
||||
/**
|
||||
@@ -132,11 +137,18 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
|
||||
*
|
||||
* @return ecma_string_t compressed pointer
|
||||
*/
|
||||
jmem_cpointer_t
|
||||
ecma_value_t
|
||||
ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be searched */
|
||||
{
|
||||
ecma_value_t num = ecma_make_number_value (number_arg);
|
||||
|
||||
if (ecma_is_value_integer_number (num))
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_float_number (num));
|
||||
|
||||
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
|
||||
jmem_cpointer_t *empty_cpointer_p = NULL;
|
||||
|
||||
@@ -157,22 +169,12 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
number_list_p->values[i]);
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
|
||||
JERRY_ASSERT (ecma_is_value_float_number (value_p->u.lit_number));
|
||||
|
||||
if (ecma_is_value_integer_number (num))
|
||||
if (ecma_get_float_from_value (value_p->u.lit_number) == number_arg)
|
||||
{
|
||||
if (value_p->u.lit_number == num)
|
||||
{
|
||||
return number_list_p->values[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ecma_is_value_float_number (value_p->u.lit_number)
|
||||
&& ecma_get_float_from_value (value_p->u.lit_number) == ecma_get_float_from_value (num))
|
||||
{
|
||||
ecma_free_value (num);
|
||||
return number_list_p->values[i];
|
||||
}
|
||||
ecma_free_value (num);
|
||||
return value_p->u.lit_number;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +192,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
if (empty_cpointer_p != NULL)
|
||||
{
|
||||
*empty_cpointer_p = result;
|
||||
return result;
|
||||
return num;
|
||||
}
|
||||
|
||||
ecma_lit_storage_item_t *new_item_p;
|
||||
@@ -205,29 +207,153 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (number_list_first_p));
|
||||
JERRY_CONTEXT (number_list_first_p) = new_item_p;
|
||||
|
||||
return result;
|
||||
return num;
|
||||
} /* ecma_find_or_create_literal_number */
|
||||
|
||||
/**
|
||||
* Log2 of snapshot literal alignment.
|
||||
*/
|
||||
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG 2
|
||||
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG 1
|
||||
|
||||
/**
|
||||
* Snapshot literal alignment.
|
||||
*/
|
||||
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT (1u << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG)
|
||||
|
||||
/**
|
||||
* Literal offset shift.
|
||||
*/
|
||||
#define JERRY_SNAPSHOT_LITERAL_SHIFT (ECMA_VALUE_SHIFT + 1)
|
||||
|
||||
/**
|
||||
* Literal value is number.
|
||||
*/
|
||||
#define JERRY_SNAPSHOT_LITERAL_IS_NUMBER (1u << ECMA_VALUE_SHIFT)
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
{
|
||||
/* Unlike direct numbers, direct strings are converted to character literals. */
|
||||
if (!ecma_is_value_string (value) && !ecma_is_value_float_number (value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
|
||||
while (iterator_p != NULL)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
ecma_append_to_values_collection (lit_pool_p, value, ECMA_COLLECTION_NO_COPY);
|
||||
} /* ecma_save_literals_append_value */
|
||||
|
||||
/**
|
||||
* Add names from a byte-code data to a list.
|
||||
*/
|
||||
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_value_t *literal_p;
|
||||
uint32_t argument_end = 0;
|
||||
uint32_t register_end;
|
||||
uint32_t const_literal_end;
|
||||
uint32_t literal_end;
|
||||
|
||||
JERRY_ASSERT (compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) compiled_code_p;
|
||||
uint8_t *byte_p = (uint8_t *) compiled_code_p;
|
||||
|
||||
literal_p = (ecma_value_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
register_end = args_p->register_end;
|
||||
const_literal_end = args_p->const_literal_end - register_end;
|
||||
literal_end = args_p->literal_end - register_end;
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
|
||||
{
|
||||
argument_end = args_p->argument_end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) compiled_code_p;
|
||||
uint8_t *byte_p = (uint8_t *) compiled_code_p;
|
||||
|
||||
literal_p = (ecma_value_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
register_end = args_p->register_end;
|
||||
const_literal_end = args_p->const_literal_end - register_end;
|
||||
literal_end = args_p->literal_end - register_end;
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
|
||||
{
|
||||
argument_end = args_p->argument_end;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < argument_end; i++)
|
||||
{
|
||||
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < const_literal_end; i++)
|
||||
{
|
||||
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
|
||||
}
|
||||
|
||||
for (uint32_t i = const_literal_end; i < literal_end; i++)
|
||||
{
|
||||
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||
literal_p[i]);
|
||||
|
||||
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
&& bytecode_p != compiled_code_p)
|
||||
{
|
||||
ecma_save_literals_add_compiled_code (bytecode_p, lit_pool_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (argument_end != 0)
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) compiled_code_p;
|
||||
byte_p += ((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
literal_p = ((ecma_value_t *) byte_p) - argument_end;
|
||||
|
||||
for (uint32_t i = 0; i < argument_end; i++)
|
||||
{
|
||||
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
|
||||
}
|
||||
}
|
||||
} /* ecma_save_literals_add_compiled_code */
|
||||
|
||||
/**
|
||||
* Save literals to specified snapshot buffer.
|
||||
*
|
||||
* Note:
|
||||
* Frees lit_pool_p regardless of success.
|
||||
*
|
||||
* @return true - if save was performed successfully (i.e. buffer size is sufficient),
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot buffer */
|
||||
ecma_save_literals_for_snapshot (ecma_collection_header_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 */
|
||||
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers
|
||||
@@ -235,145 +361,102 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
* in snapshot */
|
||||
uint32_t *out_map_len_p) /**< [out] number of literals */
|
||||
{
|
||||
/* Count literals and literal space. */
|
||||
uint32_t lit_table_size = sizeof (uint32_t);
|
||||
uint32_t total_count = 0;
|
||||
|
||||
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
|
||||
while (string_list_p != NULL)
|
||||
if (lit_pool_p->item_count == 0)
|
||||
{
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (string_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
string_list_p->values[i]);
|
||||
*out_map_p = NULL;
|
||||
*out_map_len_p = 0;
|
||||
}
|
||||
|
||||
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
total_count++;
|
||||
}
|
||||
uint32_t lit_table_size = 0;
|
||||
size_t max_lit_table_size = buffer_size - *in_out_buffer_offset_p;
|
||||
|
||||
if (max_lit_table_size > (UINT32_MAX >> JERRY_SNAPSHOT_LITERAL_SHIFT))
|
||||
{
|
||||
max_lit_table_size = (UINT32_MAX >> JERRY_SNAPSHOT_LITERAL_SHIFT);
|
||||
}
|
||||
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
|
||||
/* Compute the size of the literal pool. */
|
||||
while (iterator_p != NULL)
|
||||
{
|
||||
if (ecma_is_value_float_number (*iterator_p))
|
||||
{
|
||||
lit_table_size += (uint32_t) sizeof (ecma_number_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
|
||||
|
||||
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
}
|
||||
|
||||
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
|
||||
}
|
||||
|
||||
uint32_t number_offset = lit_table_size;
|
||||
|
||||
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
|
||||
|
||||
while (number_list_p != NULL)
|
||||
{
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
/* Check whether enough space is available and the maximum size is not reached. */
|
||||
if (lit_table_size > max_lit_table_size)
|
||||
{
|
||||
if (number_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
lit_table_size += (uint32_t) sizeof (ecma_number_t);
|
||||
total_count++;
|
||||
}
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
return false;
|
||||
}
|
||||
|
||||
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
|
||||
}
|
||||
|
||||
/* Check whether enough space is available. */
|
||||
if (*in_out_buffer_offset_p + lit_table_size > buffer_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check whether the maximum literal table size is reached. */
|
||||
if ((lit_table_size >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG) > UINT16_MAX)
|
||||
{
|
||||
return false;
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
lit_mem_to_snapshot_id_map_entry_t *map_p;
|
||||
ecma_length_t total_count = lit_pool_p->item_count;
|
||||
|
||||
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
|
||||
|
||||
/* Set return values (no error is possible from here). */
|
||||
JERRY_ASSERT ((*in_out_buffer_offset_p % sizeof (uint32_t)) == 0);
|
||||
buffer_p += *in_out_buffer_offset_p / sizeof (uint32_t);
|
||||
|
||||
uint8_t *destination_p = (uint8_t *) (buffer_p + (*in_out_buffer_offset_p / sizeof (uint32_t)));
|
||||
uint32_t literal_offset = 0;
|
||||
|
||||
*in_out_buffer_offset_p += lit_table_size;
|
||||
*out_map_p = map_p;
|
||||
*out_map_len_p = total_count;
|
||||
|
||||
/* Write data into the buffer. */
|
||||
iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
|
||||
/* The zero value is reserved for NULL (no literal)
|
||||
* constant so the first literal must have offset one. */
|
||||
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
|
||||
|
||||
*buffer_p++ = number_offset;
|
||||
|
||||
string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
|
||||
uint16_t *destination_p = (uint16_t *) buffer_p;
|
||||
|
||||
while (string_list_p != NULL)
|
||||
/* Generate literal pool data. */
|
||||
while (iterator_p != NULL)
|
||||
{
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
map_p->literal_id = *iterator_p;
|
||||
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 (string_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
map_p->literal_id = string_list_p->values[i];
|
||||
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
|
||||
map_p++;
|
||||
map_p->literal_offset |= JERRY_SNAPSHOT_LITERAL_IS_NUMBER;
|
||||
|
||||
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
string_list_p->values[i]);
|
||||
ecma_number_t num = ecma_get_float_from_value (*iterator_p);
|
||||
memcpy (destination_p, &num, sizeof (ecma_number_t));
|
||||
|
||||
ecma_length_t length = ecma_string_get_size (string_p);
|
||||
length = JERRY_ALIGNUP (sizeof (ecma_number_t), JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
|
||||
length = ecma_string_get_size (string_p);
|
||||
|
||||
*destination_p = (uint16_t) length;
|
||||
ecma_string_to_utf8_bytes (string_p, ((lit_utf8_byte_t *) destination_p) + sizeof (uint16_t), length);
|
||||
*(uint16_t *) destination_p = (uint16_t) length;
|
||||
|
||||
length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
ecma_string_to_utf8_bytes (string_p, destination_p + sizeof (uint16_t), length);
|
||||
|
||||
JERRY_ASSERT ((length % sizeof (uint16_t)) == 0);
|
||||
destination_p += length / sizeof (uint16_t);
|
||||
literal_offset += length;
|
||||
}
|
||||
length = JERRY_ALIGNUP (sizeof (uint16_t) + length, JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
}
|
||||
|
||||
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
|
||||
}
|
||||
|
||||
number_list_p = JERRY_CONTEXT (number_list_first_p);
|
||||
|
||||
while (number_list_p != NULL)
|
||||
{
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (number_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
map_p->literal_id = number_list_p->values[i];
|
||||
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
|
||||
map_p++;
|
||||
|
||||
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
number_list_p->values[i]);
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
|
||||
|
||||
ecma_number_t num = ecma_get_number_from_value (value_p->u.lit_number);
|
||||
memcpy (destination_p, &num, sizeof (ecma_number_t));
|
||||
|
||||
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
|
||||
JERRY_ASSERT ((length % sizeof (uint16_t)) == 0);
|
||||
destination_p += length / sizeof (uint16_t);
|
||||
literal_offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
|
||||
JERRY_ASSERT ((length % sizeof (uint16_t)) == 0);
|
||||
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);
|
||||
return true;
|
||||
} /* ecma_save_literals_for_snapshot */
|
||||
|
||||
@@ -381,38 +464,20 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
|
||||
#if defined JERRY_ENABLE_SNAPSHOT_EXEC || defined JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
|
||||
/**
|
||||
* Computes the base pointer of the literals and starting offset of numbers.
|
||||
*
|
||||
* @return the base pointer of the literals
|
||||
*/
|
||||
const uint8_t *
|
||||
ecma_snapshot_get_literals_base (uint32_t *buffer_p, /**< literal buffer start */
|
||||
const uint8_t **number_base_p) /**< [out] literal number start */
|
||||
{
|
||||
*number_base_p = ((uint8_t *) buffer_p) + buffer_p[0];
|
||||
|
||||
return ((uint8_t *) (buffer_p + 1)) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
|
||||
} /* ecma_snapshot_get_literals_base */
|
||||
|
||||
/**
|
||||
* Get the compressed pointer of a given literal.
|
||||
*
|
||||
* @return literal compressed pointer
|
||||
*/
|
||||
jmem_cpointer_t
|
||||
ecma_value_t
|
||||
ecma_snapshot_get_literal (const uint8_t *literal_base_p, /**< literal start */
|
||||
const uint8_t *number_base_p, /**< literal number start */
|
||||
jmem_cpointer_t offset)
|
||||
ecma_value_t literal_value) /**< string / number offset */
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
return ECMA_NULL_POINTER;
|
||||
}
|
||||
JERRY_ASSERT ((literal_value & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET);
|
||||
|
||||
const uint8_t *literal_p = literal_base_p + (((size_t) offset) << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
|
||||
const uint8_t *literal_p = literal_base_p + (literal_value >> JERRY_SNAPSHOT_LITERAL_SHIFT);
|
||||
|
||||
if (literal_p >= number_base_p)
|
||||
if (literal_value & JERRY_SNAPSHOT_LITERAL_IS_NUMBER)
|
||||
{
|
||||
ecma_number_t num;
|
||||
memcpy (&num, literal_p, sizeof (ecma_number_t));
|
||||
|
||||
@@ -27,32 +27,34 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
/**
|
||||
* Snapshot literal - offset map
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jmem_cpointer_t literal_id; /**< literal id */
|
||||
jmem_cpointer_t literal_offset; /**< literal offset */
|
||||
ecma_value_t literal_id; /**< literal id */
|
||||
ecma_value_t literal_offset; /**< literal offset */
|
||||
} lit_mem_to_snapshot_id_map_entry_t;
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
void ecma_finalize_lit_storage (void);
|
||||
|
||||
jmem_cpointer_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, lit_utf8_size_t size);
|
||||
jmem_cpointer_t ecma_find_or_create_literal_number (ecma_number_t number_arg);
|
||||
ecma_value_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, lit_utf8_size_t size);
|
||||
ecma_value_t ecma_find_or_create_literal_number (ecma_number_t number_arg);
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
bool
|
||||
ecma_save_literals_for_snapshot (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);
|
||||
void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_header_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,
|
||||
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 /* JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
#if defined JERRY_ENABLE_SNAPSHOT_EXEC || defined JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
const uint8_t *
|
||||
ecma_snapshot_get_literals_base (uint32_t *buffer_p, const uint8_t **number_base_p);
|
||||
jmem_cpointer_t
|
||||
ecma_snapshot_get_literal (const uint8_t *literal_base_p, const uint8_t *number_base_p,
|
||||
jmem_cpointer_t offset);
|
||||
ecma_value_t
|
||||
ecma_snapshot_get_literal (const uint8_t *literal_base_p, ecma_value_t literal_value);
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC || JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
/**
|
||||
|
||||
@@ -275,7 +275,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
|
||||
|
||||
JERRY_ASSERT (property_index < ECMA_PROPERTY_PAIR_ITEM_COUNT);
|
||||
|
||||
uint32_t entry_index = name_p->hash;
|
||||
uint32_t entry_index = ecma_string_hash (name_p);
|
||||
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;
|
||||
|
||||
@@ -471,7 +471,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
}
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
uint32_t entry_index = name_p->hash;
|
||||
uint32_t entry_index = ecma_string_hash (name_p);
|
||||
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);
|
||||
|
||||
@@ -761,9 +761,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
|
||||
if (!(*bitset_p & bit_for_index) || ecma_op_object_has_own_property (object_p, name_p))
|
||||
{
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_string_value (name_p),
|
||||
0);
|
||||
ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), 0);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
|
||||
@@ -736,11 +736,10 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
|
||||
|
||||
while (k < source_length_uint32 && ecma_is_value_empty (ret_val))
|
||||
{
|
||||
ecma_string_t k_str;
|
||||
ecma_init_ecma_string_from_uint32 (&k_str, k);
|
||||
ecma_string_t *k_str_p = ecma_new_ecma_string_from_uint32 (k);
|
||||
|
||||
ECMA_TRY_CATCH (elem,
|
||||
ecma_op_object_get (source_obj_p, &k_str),
|
||||
ecma_op_object_get (source_obj_p, k_str_p),
|
||||
ret_val);
|
||||
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (elem_num, elem, ret_val);
|
||||
@@ -750,6 +749,8 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (elem_num);
|
||||
ECMA_FINALIZE (elem);
|
||||
|
||||
ecma_deref_ecma_string (k_str_p);
|
||||
|
||||
k++;
|
||||
target_byte_index += element_size;
|
||||
}
|
||||
|
||||
@@ -749,12 +749,11 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
|
||||
ecma_object_t *proto_object_p = ecma_op_create_object_object_noarg ();
|
||||
|
||||
/* 17. */
|
||||
ecma_string_t magic_string_constructor;
|
||||
ecma_init_ecma_magic_string (&magic_string_constructor, LIT_MAGIC_STRING_CONSTRUCTOR);
|
||||
ecma_string_t *magic_string_constructor_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR);
|
||||
|
||||
ecma_property_value_t *constructor_prop_value_p;
|
||||
constructor_prop_value_p = ecma_create_named_data_property (proto_object_p,
|
||||
&magic_string_constructor,
|
||||
magic_string_constructor_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
|
||||
NULL);
|
||||
|
||||
|
||||
@@ -233,15 +233,16 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera
|
||||
ecma_job_promise_resolve_thenable_t *job_p = (ecma_job_promise_resolve_thenable_t *) obj_p;
|
||||
ecma_object_t *promise_p = ecma_get_object_from_value (job_p->promise);
|
||||
ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (promise_p);
|
||||
ecma_string_t str_resolve, str_reject;
|
||||
ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
|
||||
ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
|
||||
|
||||
ecma_string_t *str_resolve_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
|
||||
ecma_string_t *str_reject_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
|
||||
|
||||
ecma_op_object_put (promise_p,
|
||||
&str_resolve,
|
||||
str_resolve_p,
|
||||
funcs->resolve,
|
||||
false);
|
||||
ecma_op_object_put (promise_p,
|
||||
&str_reject,
|
||||
str_reject_p,
|
||||
funcs->reject,
|
||||
false);
|
||||
|
||||
|
||||
@@ -51,23 +51,18 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
||||
|
||||
ecma_length_t formal_params_number;
|
||||
jmem_cpointer_t *literal_p;
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
}
|
||||
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
@@ -76,7 +71,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
|
||||
if (!is_strict && arguments_number > 0 && formal_params_number > 0)
|
||||
{
|
||||
size_t formal_params_size = formal_params_number * sizeof (jmem_cpointer_t);
|
||||
size_t formal_params_size = formal_params_number * sizeof (ecma_value_t);
|
||||
|
||||
obj_p = ecma_create_object (prototype_p,
|
||||
sizeof (ecma_extended_object_t) + formal_params_size,
|
||||
@@ -90,15 +85,19 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
|
||||
ext_object_p->u.pseudo_array.u1.length = (uint16_t) formal_params_number;
|
||||
|
||||
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
|
||||
ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
|
||||
|
||||
memcpy (arg_Literal_p, literal_p, formal_params_size);
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
byte_p += ((size_t) bytecode_data_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
byte_p -= formal_params_size;
|
||||
|
||||
memcpy (arg_Literal_p, byte_p, formal_params_size);
|
||||
|
||||
for (ecma_length_t i = 0; i < formal_params_number; i++)
|
||||
{
|
||||
if (arg_Literal_p[i] != JMEM_CP_NULL)
|
||||
if (arg_Literal_p[i] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[i]);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (arg_Literal_p[i]);
|
||||
ecma_ref_ecma_string (name_p);
|
||||
}
|
||||
}
|
||||
@@ -270,20 +269,20 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *object_p, /**< the
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
|
||||
ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
|
||||
|
||||
if (arg_Literal_p[index] == JMEM_CP_NULL)
|
||||
if (arg_Literal_p[index] == ECMA_VALUE_EMPTY)
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[index]);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (arg_Literal_p[index]);
|
||||
|
||||
if (property_desc_p->is_get_defined
|
||||
|| property_desc_p->is_set_defined)
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
arg_Literal_p[index] = JMEM_CP_NULL;
|
||||
arg_Literal_p[index] = ECMA_VALUE_EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -305,7 +304,7 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *object_p, /**< the
|
||||
&& !property_desc_p->is_writable)
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
arg_Literal_p[index] = JMEM_CP_NULL;
|
||||
arg_Literal_p[index] = ECMA_VALUE_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,13 +346,13 @@ ecma_op_arguments_object_delete (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (index < ext_object_p->u.pseudo_array.u1.length)
|
||||
{
|
||||
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
|
||||
ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
|
||||
|
||||
if (arg_Literal_p[index] != JMEM_CP_NULL)
|
||||
if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, arg_Literal_p[index]);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (arg_Literal_p[index]);
|
||||
ecma_deref_ecma_string (name_p);
|
||||
arg_Literal_p[index] = JMEM_CP_NULL;
|
||||
arg_Literal_p[index] = ECMA_VALUE_EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,9 +142,11 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
|
||||
/* ES2015 9.4.5.1 */
|
||||
if (ecma_is_typedarray (ecma_make_object_value (object_p)))
|
||||
{
|
||||
if (ECMA_STRING_GET_CONTAINER (property_name_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
|
||||
uint32_t array_index = ecma_string_get_array_index (property_name_p);
|
||||
|
||||
if (array_index != ECMA_STRING_NOT_ARRAY_INDEX)
|
||||
{
|
||||
ecma_value_t value = ecma_op_typedarray_get_index_prop (object_p, property_name_p->u.uint32_number);
|
||||
ecma_value_t value = ecma_op_typedarray_get_index_prop (object_p, array_index);
|
||||
|
||||
if (!ecma_is_value_undefined (value))
|
||||
{
|
||||
@@ -269,12 +271,11 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
if (index < ext_object_p->u.pseudo_array.u1.length)
|
||||
{
|
||||
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
|
||||
ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
|
||||
|
||||
if (arg_Literal_p[index] != JMEM_CP_NULL)
|
||||
if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
ecma_string_t *arg_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
arg_Literal_p[index]);
|
||||
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
|
||||
|
||||
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_object_p->u.pseudo_array.u2.lex_env_cp);
|
||||
@@ -462,12 +463,11 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
|
||||
{
|
||||
if (index < ext_object_p->u.pseudo_array.u1.length)
|
||||
{
|
||||
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
|
||||
ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
|
||||
|
||||
if (arg_Literal_p[index] != JMEM_CP_NULL)
|
||||
if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
ecma_string_t *arg_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
arg_Literal_p[index]);
|
||||
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
|
||||
|
||||
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_object_p->u.pseudo_array.u2.lex_env_cp);
|
||||
@@ -484,9 +484,11 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
|
||||
/* ES2015 9.4.5.4 */
|
||||
if (ecma_is_typedarray (ecma_make_object_value (object_p)))
|
||||
{
|
||||
if (ECMA_STRING_GET_CONTAINER (property_name_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
|
||||
uint32_t array_index = ecma_string_get_array_index (property_name_p);
|
||||
|
||||
if (array_index != ECMA_STRING_NOT_ARRAY_INDEX)
|
||||
{
|
||||
return ecma_op_typedarray_get_index_prop (object_p, property_name_p->u.uint32_number);
|
||||
return ecma_op_typedarray_get_index_prop (object_p, array_index);
|
||||
}
|
||||
|
||||
ecma_number_t num = ecma_string_to_number (property_name_p);
|
||||
@@ -722,36 +724,11 @@ ecma_op_object_get (ecma_object_t *object_p, /**< the object */
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
inline ecma_value_t __attr_always_inline___
|
||||
ecma_op_object_get_by_magic_id (ecma_object_t *object_p, /**< the object */
|
||||
lit_magic_string_id_t property_id) /**< property magic string id */
|
||||
{
|
||||
/* Circular reference is possible in JavaScript and testing it is complicated. */
|
||||
int max_depth = ECMA_PROPERTY_SEARCH_DEPTH_LIMIT;
|
||||
|
||||
ecma_string_t property_name;
|
||||
ecma_init_ecma_magic_string (&property_name, property_id);
|
||||
|
||||
ecma_value_t base_value = ecma_make_object_value (object_p);
|
||||
do
|
||||
{
|
||||
ecma_value_t value = ecma_op_object_find_own (base_value, object_p, &property_name);
|
||||
|
||||
if (ecma_is_value_found (value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (--max_depth == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
object_p = ecma_get_object_prototype (object_p);
|
||||
}
|
||||
while (object_p != NULL);
|
||||
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
return ecma_op_object_get (object_p, ecma_get_magic_string (property_id));
|
||||
} /* ecma_op_object_get_by_magic_id */
|
||||
|
||||
/**
|
||||
@@ -814,12 +791,11 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
if (index < ext_object_p->u.pseudo_array.u1.length)
|
||||
{
|
||||
jmem_cpointer_t *arg_Literal_p = (jmem_cpointer_t *) (ext_object_p + 1);
|
||||
ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
|
||||
|
||||
if (arg_Literal_p[index] != JMEM_CP_NULL)
|
||||
if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
ecma_string_t *arg_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
arg_Literal_p[index]);
|
||||
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
|
||||
|
||||
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_object_p->u.pseudo_array.u2.lex_env_cp);
|
||||
@@ -837,9 +813,11 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
|
||||
/* ES2015 9.4.5.5 */
|
||||
if (ecma_is_typedarray (ecma_make_object_value (object_p)))
|
||||
{
|
||||
if (ECMA_STRING_GET_CONTAINER (property_name_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
|
||||
uint32_t array_index = ecma_string_get_array_index (property_name_p);
|
||||
|
||||
if (array_index != ECMA_STRING_NOT_ARRAY_INDEX)
|
||||
{
|
||||
bool set_status = ecma_op_typedarray_set_index_prop (object_p, property_name_p->u.uint32_number, value);
|
||||
bool set_status = ecma_op_typedarray_set_index_prop (object_p, array_index, value);
|
||||
|
||||
if (set_status)
|
||||
{
|
||||
@@ -1179,10 +1157,12 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
||||
/* ES2015 9.4.5.3 */
|
||||
if (ecma_is_typedarray (ecma_make_object_value (obj_p)))
|
||||
{
|
||||
if (ECMA_STRING_GET_CONTAINER (property_name_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
|
||||
uint32_t array_index = ecma_string_get_array_index (property_name_p);
|
||||
|
||||
if (array_index != ECMA_STRING_NOT_ARRAY_INDEX)
|
||||
{
|
||||
bool define_status = ecma_op_typedarray_define_index_prop (obj_p,
|
||||
property_name_p->u.uint32_number,
|
||||
array_index,
|
||||
property_desc_p);
|
||||
|
||||
if (define_status)
|
||||
@@ -1492,7 +1472,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
|
||||
uint8_t hash = (uint8_t) name_p->hash;
|
||||
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);
|
||||
|
||||
@@ -1523,7 +1503,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
{
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT)
|
||||
{
|
||||
/* Internal properties are never enumerated. */
|
||||
@@ -1535,7 +1515,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
|
||||
if (!(is_enumerable_only && !ecma_is_property_enumerable (*property_p)))
|
||||
{
|
||||
uint8_t hash = (uint8_t) name_p->hash;
|
||||
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);
|
||||
|
||||
@@ -1691,7 +1671,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
|
||||
ecma_string_t *name_p = names_p[i];
|
||||
|
||||
uint8_t hash = (uint8_t) name_p->hash;
|
||||
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);
|
||||
|
||||
|
||||
@@ -232,17 +232,16 @@ ecma_promise_reject_handler (const ecma_value_t function, /**< the function itse
|
||||
{
|
||||
JERRY_UNUSED (this);
|
||||
|
||||
ecma_string_t str_promise;
|
||||
ecma_string_t str_already_resolved;
|
||||
ecma_init_ecma_magic_string (&str_promise, LIT_INTERNAL_MAGIC_STRING_PROMISE);
|
||||
ecma_init_ecma_magic_string (&str_already_resolved, LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
|
||||
ecma_string_t *str_promise_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE);
|
||||
ecma_string_t *str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
|
||||
|
||||
ecma_object_t *function_p = ecma_get_object_from_value (function);
|
||||
/* 2. */
|
||||
ecma_value_t promise = ecma_op_object_get (function_p, &str_promise);
|
||||
ecma_value_t promise = ecma_op_object_get (function_p, str_promise_p);
|
||||
/* 1. */
|
||||
JERRY_ASSERT (ecma_is_promise (ecma_get_object_from_value (promise)));
|
||||
/* 3. */
|
||||
ecma_value_t already_resolved = ecma_op_object_get (function_p, &str_already_resolved);
|
||||
ecma_value_t already_resolved = ecma_op_object_get (function_p, str_already_resolved_p);
|
||||
|
||||
/* 4. */
|
||||
if (ecma_get_already_resolved_bool_value (already_resolved))
|
||||
@@ -278,17 +277,16 @@ ecma_promise_resolve_handler (const ecma_value_t function, /**< the function its
|
||||
{
|
||||
JERRY_UNUSED (this);
|
||||
|
||||
ecma_string_t str_promise;
|
||||
ecma_string_t str_already_resolved;
|
||||
ecma_init_ecma_magic_string (&str_promise, LIT_INTERNAL_MAGIC_STRING_PROMISE);
|
||||
ecma_init_ecma_magic_string (&str_already_resolved, LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
|
||||
ecma_string_t *str_promise_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE);
|
||||
ecma_string_t *str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
|
||||
|
||||
ecma_object_t *function_p = ecma_get_object_from_value (function);
|
||||
/* 2. */
|
||||
ecma_value_t promise = ecma_op_object_get (function_p, &str_promise);
|
||||
ecma_value_t promise = ecma_op_object_get (function_p, str_promise_p);
|
||||
/* 1. */
|
||||
JERRY_ASSERT (ecma_is_promise (ecma_get_object_from_value (promise)));
|
||||
/* 3. */
|
||||
ecma_value_t already_resolved = ecma_op_object_get (function_p, &str_already_resolved);
|
||||
ecma_value_t already_resolved = ecma_op_object_get (function_p, str_already_resolved_p);
|
||||
|
||||
/* 4. */
|
||||
if (ecma_get_already_resolved_bool_value (already_resolved))
|
||||
@@ -430,22 +428,21 @@ ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promi
|
||||
/* 1. */
|
||||
ecma_value_t already_resolved = ecma_op_create_boolean_object (ecma_make_boolean_value (false));
|
||||
|
||||
ecma_string_t str_promise;
|
||||
ecma_string_t str_already_resolved;
|
||||
ecma_init_ecma_magic_string (&str_promise, LIT_INTERNAL_MAGIC_STRING_PROMISE);
|
||||
ecma_init_ecma_magic_string (&str_already_resolved, LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
|
||||
ecma_string_t *str_promise_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE);
|
||||
ecma_string_t *str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
|
||||
|
||||
/* 2. */
|
||||
ecma_object_t *resolve_p;
|
||||
resolve_p = ecma_op_create_external_function_object (ecma_promise_resolve_handler);
|
||||
|
||||
/* 3. */
|
||||
ecma_op_object_put (resolve_p,
|
||||
&str_promise,
|
||||
str_promise_p,
|
||||
ecma_make_object_value (object_p),
|
||||
false);
|
||||
/* 4. */
|
||||
ecma_op_object_put (resolve_p,
|
||||
&str_already_resolved,
|
||||
str_already_resolved_p,
|
||||
already_resolved,
|
||||
false);
|
||||
/* 5. */
|
||||
@@ -453,12 +450,12 @@ ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promi
|
||||
reject_p = ecma_op_create_external_function_object (ecma_promise_reject_handler);
|
||||
/* 6. */
|
||||
ecma_op_object_put (reject_p,
|
||||
&str_promise,
|
||||
str_promise_p,
|
||||
ecma_make_object_value (object_p),
|
||||
false);
|
||||
/* 7. */
|
||||
ecma_op_object_put (reject_p,
|
||||
&str_already_resolved,
|
||||
str_already_resolved_p,
|
||||
already_resolved,
|
||||
false);
|
||||
|
||||
@@ -516,15 +513,15 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
|
||||
/* 8. */
|
||||
ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p);
|
||||
|
||||
ecma_string_t str_resolve, str_reject;
|
||||
ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
|
||||
ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
|
||||
ecma_string_t *str_resolve_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
|
||||
ecma_string_t *str_reject_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
|
||||
|
||||
ecma_op_object_put (object_p,
|
||||
&str_resolve,
|
||||
str_resolve_p,
|
||||
funcs->resolve,
|
||||
false);
|
||||
ecma_op_object_put (object_p,
|
||||
&str_reject,
|
||||
str_reject_p,
|
||||
funcs->reject,
|
||||
false);
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**<
|
||||
|
||||
/* Initialize RegExp object properties */
|
||||
re_initialize_props (object_p,
|
||||
ECMA_GET_NON_NULL_POINTER (ecma_string_t, bytecode_p->pattern_cp),
|
||||
ecma_get_string_from_value (bytecode_p->pattern),
|
||||
bytecode_p->header.status_flags);
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
|
||||
Reference in New Issue
Block a user