mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
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:
parent
fbf5c32747
commit
51e3c4455a
@ -154,9 +154,8 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
|
||||
|
||||
globals_p->snapshot_buffer_write_offset += sizeof (ecma_compiled_code_t);
|
||||
|
||||
jmem_cpointer_t pattern_cp = ((re_compiled_code_t *) compiled_code_p)->pattern_cp;
|
||||
ecma_string_t *pattern_string_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
pattern_cp);
|
||||
ecma_value_t pattern = ((re_compiled_code_t *) compiled_code_p)->pattern;
|
||||
ecma_string_t *pattern_string_p = ecma_get_string_from_value (pattern);
|
||||
|
||||
ecma_length_t pattern_size = 0;
|
||||
|
||||
@ -206,34 +205,34 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
|
||||
/* Sub-functions and regular expressions are stored recursively. */
|
||||
uint8_t *src_buffer_p = (uint8_t *) compiled_code_p;
|
||||
uint8_t *dst_buffer_p = (uint8_t *) copied_code_p;
|
||||
jmem_cpointer_t *src_literal_start_p;
|
||||
jmem_cpointer_t *dst_literal_start_p;
|
||||
ecma_value_t *src_literal_start_p;
|
||||
ecma_value_t *dst_literal_start_p;
|
||||
uint32_t const_literal_end;
|
||||
uint32_t literal_end;
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
src_literal_start_p = (jmem_cpointer_t *) (src_buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
dst_literal_start_p = (jmem_cpointer_t *) (dst_buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
src_literal_start_p = (ecma_value_t *) (src_buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
dst_literal_start_p = (ecma_value_t *) (dst_buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) src_buffer_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
src_literal_start_p = (jmem_cpointer_t *) (src_buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
dst_literal_start_p = (jmem_cpointer_t *) (dst_buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
src_literal_start_p = (ecma_value_t *) (src_buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
dst_literal_start_p = (ecma_value_t *) (dst_buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) src_buffer_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
|
||||
for (uint32_t i = const_literal_end; i < literal_end; i++)
|
||||
{
|
||||
ecma_compiled_code_t *bytecode_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
|
||||
src_literal_start_p[i]);
|
||||
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||
src_literal_start_p[i]);
|
||||
|
||||
if (bytecode_p == compiled_code_p)
|
||||
{
|
||||
@ -268,39 +267,55 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
{
|
||||
jmem_cpointer_t *literal_start_p;
|
||||
ecma_value_t *literal_start_p;
|
||||
uint32_t argument_end;
|
||||
uint32_t register_end;
|
||||
uint32_t const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
literal_start_p = (jmem_cpointer_t *) (((uint8_t *) buffer_p) + sizeof (cbc_uint16_arguments_t));
|
||||
literal_start_p = (ecma_value_t *) (((uint8_t *) buffer_p) + sizeof (cbc_uint16_arguments_t));
|
||||
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
|
||||
argument_end = args_p->argument_end;
|
||||
register_end = args_p->register_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
literal_start_p = (jmem_cpointer_t *) (((uint8_t *) buffer_p) + sizeof (cbc_uint8_arguments_t));
|
||||
literal_start_p = (ecma_value_t *) (((uint8_t *) buffer_p) + sizeof (cbc_uint8_arguments_t));
|
||||
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
|
||||
argument_end = args_p->argument_end;
|
||||
register_end = args_p->register_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
|
||||
uint32_t register_clear_start = 0;
|
||||
|
||||
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED)
|
||||
&& !(bytecode_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE))
|
||||
for (uint32_t i = 0; i < const_literal_end; i++)
|
||||
{
|
||||
if (ecma_is_value_string (literal_start_p[i])
|
||||
|| ecma_is_value_float_number (literal_start_p[i]))
|
||||
{
|
||||
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
|
||||
|
||||
while (current_p->literal_id != literal_start_p[i])
|
||||
{
|
||||
current_p++;
|
||||
}
|
||||
|
||||
literal_start_p[i] = current_p->literal_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
literal_start_p = ((ecma_value_t *) byte_p) - argument_end;
|
||||
|
||||
for (uint32_t i = 0; i < argument_end; i++)
|
||||
{
|
||||
if (literal_start_p[i] != JMEM_CP_NULL)
|
||||
if (literal_start_p[i] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_string (literal_start_p[i]));
|
||||
|
||||
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
|
||||
|
||||
while (current_p->literal_id != literal_start_p[i])
|
||||
@ -311,28 +326,6 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
|
||||
literal_start_p[i] = current_p->literal_offset;
|
||||
}
|
||||
}
|
||||
|
||||
register_clear_start = argument_end;
|
||||
}
|
||||
|
||||
for (uint32_t i = register_clear_start; i < register_end; i++)
|
||||
{
|
||||
literal_start_p[i] = JMEM_CP_NULL;
|
||||
}
|
||||
|
||||
for (uint32_t i = register_end; i < const_literal_end; i++)
|
||||
{
|
||||
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
|
||||
|
||||
if (literal_start_p[i] != JMEM_CP_NULL)
|
||||
{
|
||||
while (current_p->literal_id != literal_start_p[i])
|
||||
{
|
||||
current_p++;
|
||||
}
|
||||
|
||||
literal_start_p[i] = current_p->literal_offset;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set reference counter to 1. */
|
||||
@ -367,7 +360,6 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
* current primary function */
|
||||
size_t offset, /**< byte code offset */
|
||||
const uint8_t *literal_base_p, /**< literal start */
|
||||
const uint8_t *number_base_p, /**< literal number start */
|
||||
bool copy_bytecode) /**< byte code should be copied to memory */
|
||||
{
|
||||
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) (base_addr_p + offset);
|
||||
@ -397,23 +389,36 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
}
|
||||
|
||||
size_t header_size;
|
||||
uint32_t literal_end;
|
||||
uint32_t argument_end = 0;
|
||||
uint32_t const_literal_end;
|
||||
uint32_t literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) byte_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
|
||||
{
|
||||
argument_end = args_p->argument_end;
|
||||
}
|
||||
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
|
||||
header_size = sizeof (cbc_uint16_arguments_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) byte_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
|
||||
{
|
||||
argument_end = args_p->argument_end;
|
||||
}
|
||||
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
|
||||
header_size = sizeof (cbc_uint8_arguments_t);
|
||||
}
|
||||
|
||||
@ -430,25 +435,42 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
}
|
||||
else
|
||||
{
|
||||
code_size = (uint32_t) (header_size + literal_end * sizeof (jmem_cpointer_t));
|
||||
uint32_t start_offset = (uint32_t) (header_size + literal_end * sizeof (ecma_value_t));
|
||||
|
||||
uint8_t *real_bytecode_p = ((uint8_t *) bytecode_p) + code_size;
|
||||
uint32_t total_size = JERRY_ALIGNUP (code_size + 1 + sizeof (uint8_t *), JMEM_ALIGNMENT);
|
||||
uint8_t *real_bytecode_p = ((uint8_t *) bytecode_p) + start_offset;
|
||||
uint32_t new_code_size = (uint32_t) (start_offset + 1 + sizeof (uint8_t *));
|
||||
|
||||
bytecode_p = (ecma_compiled_code_t *) jmem_heap_alloc_block (total_size);
|
||||
if (argument_end != 0)
|
||||
{
|
||||
new_code_size += (uint32_t) (argument_end * sizeof (ecma_value_t));
|
||||
}
|
||||
|
||||
new_code_size = JERRY_ALIGNUP (new_code_size, JMEM_ALIGNMENT);
|
||||
|
||||
bytecode_p = (ecma_compiled_code_t *) jmem_heap_alloc_block (new_code_size);
|
||||
|
||||
#ifdef JMEM_STATS
|
||||
jmem_stats_allocate_byte_code_bytes (total_size);
|
||||
jmem_stats_allocate_byte_code_bytes (new_code_size);
|
||||
#endif /* JMEM_STATS */
|
||||
|
||||
memcpy (bytecode_p, base_addr_p + offset, code_size);
|
||||
memcpy (bytecode_p, base_addr_p + offset, start_offset);
|
||||
|
||||
bytecode_p->size = (uint16_t) (total_size >> JMEM_ALIGNMENT_LOG);
|
||||
bytecode_p->size = (uint16_t) (new_code_size >> JMEM_ALIGNMENT_LOG);
|
||||
|
||||
uint8_t *instructions_p = ((uint8_t *) bytecode_p);
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
|
||||
instructions_p[code_size] = CBC_SET_BYTECODE_PTR;
|
||||
memcpy (instructions_p + code_size + 1, &real_bytecode_p, sizeof (uint8_t *));
|
||||
if (argument_end != 0)
|
||||
{
|
||||
uint32_t argument_size = (uint32_t) (argument_end * sizeof (ecma_value_t));
|
||||
memcpy (byte_p + new_code_size - argument_size,
|
||||
base_addr_p + offset + code_size - argument_size,
|
||||
argument_size);
|
||||
}
|
||||
|
||||
byte_p[start_offset] = CBC_SET_BYTECODE_PTR;
|
||||
memcpy (byte_p + start_offset + 1, &real_bytecode_p, sizeof (uint8_t *));
|
||||
|
||||
code_size = new_code_size;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (bytecode_p->refs == 1);
|
||||
@ -457,13 +479,14 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
bytecode_p->status_flags = (uint16_t) (bytecode_p->status_flags | CBC_CODE_FLAGS_DEBUGGER_IGNORE);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
|
||||
jmem_cpointer_t *literal_start_p = (jmem_cpointer_t *) (((uint8_t *) bytecode_p) + header_size);
|
||||
ecma_value_t *literal_start_p = (ecma_value_t *) (((uint8_t *) bytecode_p) + header_size);
|
||||
|
||||
for (uint32_t i = 0; i < const_literal_end; i++)
|
||||
{
|
||||
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p,
|
||||
number_base_p,
|
||||
literal_start_p[i]);
|
||||
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
|
||||
{
|
||||
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = const_literal_end; i < literal_end; i++)
|
||||
@ -473,8 +496,8 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
if (literal_offset == offset)
|
||||
{
|
||||
/* Self reference */
|
||||
ECMA_SET_NON_NULL_POINTER (literal_start_p[i],
|
||||
bytecode_p);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (literal_start_p[i],
|
||||
bytecode_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -482,11 +505,24 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
literal_bytecode_p = snapshot_load_compiled_code (base_addr_p,
|
||||
literal_offset,
|
||||
literal_base_p,
|
||||
number_base_p,
|
||||
copy_bytecode);
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (literal_start_p[i],
|
||||
literal_bytecode_p);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (literal_start_p[i],
|
||||
literal_bytecode_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (argument_end != 0)
|
||||
{
|
||||
literal_start_p = (ecma_value_t *) (((uint8_t *) bytecode_p) + code_size);
|
||||
literal_start_p -= argument_end;
|
||||
|
||||
for (uint32_t i = 0; i < argument_end; i++)
|
||||
{
|
||||
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
|
||||
{
|
||||
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,7 +597,12 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
|
||||
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
|
||||
uint32_t literals_num;
|
||||
|
||||
if (!ecma_save_literals_for_snapshot (buffer_p,
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
|
||||
ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p);
|
||||
|
||||
if (!ecma_save_literals_for_snapshot (lit_pool_p,
|
||||
buffer_p,
|
||||
buffer_size,
|
||||
&globals.snapshot_buffer_write_offset,
|
||||
&lit_map_p,
|
||||
@ -672,34 +713,31 @@ jerry_snapshot_result_at (const uint32_t *snapshot_p, /**< snapshot */
|
||||
|| header_p->version != JERRY_SNAPSHOT_VERSION
|
||||
|| !snapshot_check_global_flags (header_p->global_flags))
|
||||
{
|
||||
return ecma_raise_type_error (invalid_version_error_p);
|
||||
ecma_raise_type_error (invalid_version_error_p);
|
||||
return ecma_create_error_reference_from_context ();
|
||||
}
|
||||
|
||||
if (header_p->lit_table_offset >= snapshot_size)
|
||||
if (header_p->lit_table_offset > snapshot_size)
|
||||
{
|
||||
return ecma_raise_type_error (invalid_version_error_p);
|
||||
ecma_raise_type_error (invalid_version_error_p);
|
||||
return ecma_create_error_reference_from_context ();
|
||||
}
|
||||
|
||||
if (func_index >= header_p->number_of_funcs)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Function index is higher than maximum"));
|
||||
ecma_raise_range_error (ECMA_ERR_MSG ("Function index is higher than maximum"));
|
||||
return ecma_create_error_reference_from_context ();
|
||||
}
|
||||
|
||||
JERRY_ASSERT ((header_p->lit_table_offset % sizeof (uint32_t)) == 0);
|
||||
|
||||
const uint8_t *literal_base_p;
|
||||
const uint8_t *number_base_p;
|
||||
|
||||
literal_base_p = ecma_snapshot_get_literals_base ((uint32_t *) (snapshot_data_p + header_p->lit_table_offset),
|
||||
&number_base_p);
|
||||
|
||||
const uint8_t *literal_base_p = (uint8_t *) (snapshot_data_p + header_p->lit_table_offset);
|
||||
ecma_compiled_code_t *bytecode_p;
|
||||
|
||||
uint32_t func_offset = header_p->func_offsets[func_index] & ~JERRY_SNAPSHOT_EVAL_CONTEXT;
|
||||
bytecode_p = snapshot_load_compiled_code (snapshot_data_p + func_offset,
|
||||
0,
|
||||
literal_base_p,
|
||||
number_base_p,
|
||||
copy_bytecode);
|
||||
|
||||
if (bytecode_p == NULL)
|
||||
@ -813,8 +851,8 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
|
||||
static void
|
||||
scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
const uint8_t *buffer_end_p, /**< snapshot buffer end */
|
||||
const uint8_t *literal_base_p, /**< start of literal data */
|
||||
const uint8_t *number_base_p) /**< start of number data */
|
||||
ecma_collection_header_t *lit_pool_p, /**< list of known values */
|
||||
const uint8_t *literal_base_p) /**< start of literal data */
|
||||
{
|
||||
JERRY_ASSERT (buffer_end_p > buffer_p);
|
||||
|
||||
@ -825,29 +863,51 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
{
|
||||
jmem_cpointer_t *literal_start_p;
|
||||
ecma_value_t *literal_start_p;
|
||||
uint32_t argument_end;
|
||||
uint32_t const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
argument_end = args_p->argument_end;
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
argument_end = args_p->argument_end;
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < const_literal_end; i++)
|
||||
{
|
||||
if (literal_start_p[i] != JMEM_CP_NULL)
|
||||
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
|
||||
{
|
||||
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p, number_base_p, literal_start_p[i]);
|
||||
ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
|
||||
literal_start_p[i] = lit_value;
|
||||
ecma_save_literals_append_value (lit_value, lit_pool_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
literal_start_p = ((ecma_value_t *) byte_p) - argument_end;
|
||||
|
||||
for (uint32_t i = 0; i < argument_end; i++)
|
||||
{
|
||||
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
|
||||
{
|
||||
ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
|
||||
literal_start_p[i] = lit_value;
|
||||
ecma_save_literals_append_value (lit_value, lit_pool_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -862,7 +922,7 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
*/
|
||||
static void
|
||||
update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
const uint8_t *buffer_end_p, /**< snapshot buffer start */
|
||||
const uint8_t *buffer_end_p, /**< snapshot buffer end */
|
||||
lit_mem_to_snapshot_id_map_entry_t *lit_map_p) /**< literal map */
|
||||
{
|
||||
JERRY_ASSERT (buffer_end_p > buffer_p);
|
||||
@ -874,27 +934,31 @@ update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
{
|
||||
jmem_cpointer_t *literal_start_p;
|
||||
ecma_value_t *literal_start_p;
|
||||
uint32_t argument_end;
|
||||
uint32_t const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
argument_end = args_p->argument_end;
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
argument_end = args_p->argument_end;
|
||||
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < const_literal_end; i++)
|
||||
{
|
||||
if (literal_start_p[i] != JMEM_CP_NULL)
|
||||
if (ecma_is_value_string (literal_start_p[i])
|
||||
|| ecma_is_value_float_number (literal_start_p[i]))
|
||||
{
|
||||
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
|
||||
|
||||
@ -906,6 +970,28 @@ update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
literal_start_p[i] = current_p->literal_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
literal_start_p = ((ecma_value_t *) byte_p) - argument_end;
|
||||
|
||||
for (uint32_t i = 0; i < argument_end; i++)
|
||||
{
|
||||
if (literal_start_p[i] != ECMA_VALUE_EMPTY)
|
||||
{
|
||||
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
|
||||
|
||||
while (current_p->literal_id != literal_start_p[i])
|
||||
{
|
||||
current_p++;
|
||||
}
|
||||
|
||||
literal_start_p[i] = current_p->literal_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer_p += code_size;
|
||||
@ -940,11 +1026,14 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
|
||||
for (uint32_t i = 0; i < number_of_snapshots; i++)
|
||||
{
|
||||
if (inp_buffer_sizes_p[i] < sizeof (jerry_snapshot_header_t))
|
||||
{
|
||||
*error_p = "invalid snapshot file";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -955,6 +1044,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
|| !snapshot_check_global_flags (header_p->global_flags))
|
||||
{
|
||||
*error_p = "invalid snapshot version or unsupported features present";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -962,11 +1052,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
|
||||
uint32_t start_offset = header_p->func_offsets[0] & ~JERRY_SNAPSHOT_EVAL_CONTEXT;
|
||||
const uint8_t *data_p = (const uint8_t *) inp_buffers_p[i];
|
||||
const uint8_t *literal_base_p;
|
||||
const uint8_t *number_base_p;
|
||||
|
||||
literal_base_p = ecma_snapshot_get_literals_base ((uint32_t *) (data_p + header_p->lit_table_offset),
|
||||
&number_base_p);
|
||||
const uint8_t *literal_base_p = (uint8_t *) (data_p + header_p->lit_table_offset);
|
||||
|
||||
JERRY_ASSERT (header_p->number_of_funcs > 0);
|
||||
|
||||
@ -975,8 +1061,8 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
|
||||
scan_snapshot_functions (data_p + start_offset,
|
||||
data_p + header_p->lit_table_offset,
|
||||
literal_base_p,
|
||||
number_base_p);
|
||||
lit_pool_p,
|
||||
literal_base_p);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (number_of_funcs > 0);
|
||||
@ -986,6 +1072,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
if (functions_size >= out_buffer_size)
|
||||
{
|
||||
*error_p = "output buffer is too small";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1000,7 +1087,8 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
lit_mem_to_snapshot_id_map_entry_t *lit_map_p;
|
||||
uint32_t literals_num;
|
||||
|
||||
if (!ecma_save_literals_for_snapshot (out_buffer_p,
|
||||
if (!ecma_save_literals_for_snapshot (lit_pool_p,
|
||||
out_buffer_p,
|
||||
out_buffer_size,
|
||||
&functions_size,
|
||||
&lit_map_p,
|
||||
@ -1041,7 +1129,10 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
|
||||
JERRY_ASSERT ((uint32_t) (dst_p - (uint8_t *) out_buffer_p) == header_p->lit_table_offset);
|
||||
|
||||
jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t));
|
||||
if (lit_map_p != NULL)
|
||||
{
|
||||
jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t));
|
||||
}
|
||||
|
||||
*error_p = NULL;
|
||||
return functions_size;
|
||||
@ -1325,35 +1416,35 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
|
||||
|
||||
ecma_free_value (parse_status);
|
||||
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p);
|
||||
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
|
||||
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
lit_utf8_size_t literal_count = 0;
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
|
||||
/* Count the valid and non-magic identifiers in the list. */
|
||||
while (string_list_p != NULL)
|
||||
while (iterator_p != NULL)
|
||||
{
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
if (ecma_is_value_string (*iterator_p))
|
||||
{
|
||||
if (string_list_p->values[i] != JMEM_CP_NULL)
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
|
||||
|
||||
/* We don't save a literal which isn't a valid identifier or it's a magic string. */
|
||||
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
|
||||
&& ecma_string_is_valid_identifier (literal_p))
|
||||
{
|
||||
ecma_string_t *literal_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
string_list_p->values[i]);
|
||||
/* We don't save a literal which isn't a valid identifier
|
||||
or it's a magic string. */
|
||||
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
|
||||
&& ecma_string_is_valid_identifier (literal_p))
|
||||
{
|
||||
literal_count++;
|
||||
}
|
||||
literal_count++;
|
||||
}
|
||||
}
|
||||
|
||||
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
if (literal_count == 0)
|
||||
{
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1365,28 +1456,26 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
|
||||
JMEM_DEFINE_LOCAL_ARRAY (literal_array, literal_count, ecma_string_t *);
|
||||
lit_utf8_size_t literal_idx = 0;
|
||||
|
||||
string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
|
||||
while (string_list_p != NULL)
|
||||
while (iterator_p != NULL)
|
||||
{
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
if (ecma_is_value_string (*iterator_p))
|
||||
{
|
||||
if (string_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_string_t *literal_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
string_list_p->values[i]);
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
|
||||
|
||||
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
|
||||
&& ecma_string_is_valid_identifier (literal_p))
|
||||
{
|
||||
literal_array[literal_idx++] = literal_p;
|
||||
}
|
||||
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
|
||||
&& ecma_string_is_valid_identifier (literal_p))
|
||||
{
|
||||
literal_array[literal_idx++] = literal_p;
|
||||
}
|
||||
}
|
||||
|
||||
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
|
||||
/* Sort the strings by size at first, then lexicographically. */
|
||||
jerry_save_literals_sort (literal_array, literal_count);
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ typedef struct
|
||||
/**
|
||||
* Jerry snapshot format version.
|
||||
*/
|
||||
#define JERRY_SNAPSHOT_VERSION (8u)
|
||||
#define JERRY_SNAPSHOT_VERSION (9u)
|
||||
|
||||
/**
|
||||
* Snapshot configuration flags.
|
||||
|
||||
@ -1846,11 +1846,12 @@ jerry_delete_property_by_index (const jerry_value_t obj_val, /**< object value *
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_string_t str_idx;
|
||||
ecma_init_ecma_string_from_uint32 (&str_idx, index);
|
||||
ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_value),
|
||||
&str_idx,
|
||||
str_idx_p,
|
||||
false);
|
||||
ecma_deref_ecma_string (str_idx_p);
|
||||
|
||||
return ecma_is_value_true (ret_value);
|
||||
} /* jerry_delete_property_by_index */
|
||||
|
||||
@ -1905,9 +1906,9 @@ jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
ecma_string_t str_idx;
|
||||
ecma_init_ecma_string_from_uint32 (&str_idx, index);
|
||||
ecma_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_value), &str_idx);
|
||||
ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
ecma_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_value), str_idx_p);
|
||||
ecma_deref_ecma_string (str_idx_p);
|
||||
|
||||
return jerry_return (ret_value);
|
||||
} /* jerry_get_property_by_index */
|
||||
|
||||
@ -978,12 +978,11 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**
|
||||
lit_utf8_byte_t data[16];
|
||||
memcpy (data, lit_get_magic_string_utf8 (string_id), size);
|
||||
|
||||
ecma_string_t message_string;
|
||||
ecma_init_ecma_magic_string (&message_string, LIT_MAGIC_STRING_MESSAGE);
|
||||
ecma_string_t *message_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);
|
||||
|
||||
ecma_property_t *property_p;
|
||||
property_p = ecma_find_named_property (ecma_get_object_from_value (exception_obj_value),
|
||||
&message_string);
|
||||
message_string_p);
|
||||
|
||||
if (property_p == NULL
|
||||
|| ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -637,9 +637,7 @@ typedef struct
|
||||
uint16_t ident_end; /**< end position of the identifier group */
|
||||
uint16_t const_literal_end; /**< end position of the const literal group */
|
||||
uint16_t literal_end; /**< end position of the literal group */
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
uint16_t padding; /**< an unused value */
|
||||
#endif
|
||||
} cbc_uint16_arguments_t;
|
||||
|
||||
/**
|
||||
@ -652,9 +650,10 @@ typedef enum
|
||||
CBC_CODE_FLAGS_UINT16_ARGUMENTS = (1u << 2), /**< compiled code data is cbc_uint16_arguments_t */
|
||||
CBC_CODE_FLAGS_STRICT_MODE = (1u << 3), /**< strict mode is enabled */
|
||||
CBC_CODE_FLAGS_ARGUMENTS_NEEDED = (1u << 4), /**< arguments object must be constructed */
|
||||
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 5), /**< no need to create a lexical environment */
|
||||
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 6), /**< this function should be ignored by debugger */
|
||||
CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED = (1u << 5), /**< non-strict arguments object must be constructed */
|
||||
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 6), /**< no need to create a lexical environment */
|
||||
CBC_CODE_FLAGS_ARROW_FUNCTION = (1u << 7), /**< this function is an arrow function */
|
||||
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 8), /**< this function should be ignored by debugger */
|
||||
} cbc_code_flags;
|
||||
|
||||
#define CBC_OPCODE(arg1, arg2, arg3, arg4) arg1,
|
||||
|
||||
@ -107,12 +107,8 @@ util_print_literal (lexer_literal_t *literal_p) /**< literal */
|
||||
}
|
||||
else if (literal_p->type == LEXER_NUMBER_LITERAL)
|
||||
{
|
||||
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p->u.value);
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
|
||||
|
||||
JERRY_DEBUG_MSG ("number(");
|
||||
util_print_number (ecma_get_number_from_value (value_p->u.lit_number));
|
||||
util_print_number (ecma_get_number_from_value (literal_p->u.value));
|
||||
}
|
||||
else if (literal_p->type == LEXER_REGEXP_LITERAL)
|
||||
{
|
||||
|
||||
@ -81,7 +81,7 @@ typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
jmem_cpointer_t value; /**< literal value (not processed by the parser) */
|
||||
ecma_value_t value; /**< literal value (not processed by the parser) */
|
||||
const uint8_t *char_p; /**< character value */
|
||||
ecma_compiled_code_t *bytecode_p; /**< compiled function or regexp pointer */
|
||||
uint32_t source_data; /**< encoded source literal */
|
||||
|
||||
@ -1759,13 +1759,13 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
|
||||
num = -num;
|
||||
}
|
||||
|
||||
jmem_cpointer_t lit_cp = ecma_find_or_create_literal_number (num);
|
||||
ecma_value_t lit_value = ecma_find_or_create_literal_number (num);
|
||||
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
|
||||
|
||||
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
|
||||
{
|
||||
if (literal_p->type == LEXER_NUMBER_LITERAL
|
||||
&& literal_p->u.value == lit_cp)
|
||||
&& literal_p->u.value == lit_value)
|
||||
{
|
||||
context_p->lit_object.literal_p = literal_p;
|
||||
context_p->lit_object.index = (uint16_t) literal_index;
|
||||
@ -1790,7 +1790,7 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
|
||||
|
||||
context_p->literal_count++;
|
||||
|
||||
literal_p->u.value = lit_cp;
|
||||
literal_p->u.value = lit_value;
|
||||
literal_p->type = LEXER_NUMBER_LITERAL;
|
||||
|
||||
context_p->lit_object.literal_p = literal_p;
|
||||
|
||||
@ -534,7 +534,7 @@ parser_encode_literal (uint8_t *dst_p, /**< destination buffer */
|
||||
static uint8_t *
|
||||
parser_generate_initializers (parser_context_t *context_p, /**< context */
|
||||
uint8_t *dst_p, /**< destination buffer */
|
||||
jmem_cpointer_t *literal_pool_p, /**< start of literal pool */
|
||||
ecma_value_t *literal_pool_p, /**< start of literal pool */
|
||||
uint16_t uninitialized_var_end, /**< end of the uninitialized var group */
|
||||
uint16_t initialized_var_end, /**< end of the initialized var group */
|
||||
uint16_t const_literal_end, /**< end of the const literal group */
|
||||
@ -543,7 +543,7 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
|
||||
{
|
||||
parser_list_iterator_t literal_iterator;
|
||||
lexer_literal_t *literal_p;
|
||||
uint16_t argument_count;
|
||||
uint16_t argument_count, register_count;
|
||||
|
||||
if (uninitialized_var_end > context_p->register_count)
|
||||
{
|
||||
@ -618,6 +618,7 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
|
||||
|
||||
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
|
||||
argument_count = 0;
|
||||
register_count = context_p->register_count;
|
||||
|
||||
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)))
|
||||
{
|
||||
@ -628,35 +629,42 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
|
||||
if (literal_p->type == LEXER_IDENT_LITERAL
|
||||
|| literal_p->type == LEXER_STRING_LITERAL)
|
||||
{
|
||||
if (literal_p->prop.index >= register_count)
|
||||
{
|
||||
#ifdef PARSER_DUMP_BYTE_CODE
|
||||
if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
|
||||
{
|
||||
jmem_cpointer_t lit_cp = ecma_find_or_create_literal_string (literal_p->u.char_p,
|
||||
literal_p->prop.length);
|
||||
literal_pool_p[literal_p->prop.index] = lit_cp;
|
||||
}
|
||||
if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
|
||||
{
|
||||
ecma_value_t lit_value = ecma_find_or_create_literal_string (literal_p->u.char_p,
|
||||
literal_p->prop.length);
|
||||
literal_pool_p[literal_p->prop.index] = lit_value;
|
||||
}
|
||||
|
||||
if (!context_p->is_show_opcodes
|
||||
&& !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
|
||||
{
|
||||
jmem_heap_free_block ((void *) literal_p->u.char_p, literal_p->prop.length);
|
||||
}
|
||||
if (!context_p->is_show_opcodes
|
||||
&& !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
|
||||
{
|
||||
jmem_heap_free_block ((void *) literal_p->u.char_p, literal_p->prop.length);
|
||||
}
|
||||
#else /* !PARSER_DUMP_BYTE_CODE */
|
||||
if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
|
||||
{
|
||||
literal_pool_p[literal_p->prop.index] = literal_p->u.value;
|
||||
}
|
||||
if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
|
||||
{
|
||||
literal_pool_p[literal_p->prop.index] = literal_p->u.value;
|
||||
}
|
||||
#endif /* PARSER_DUMP_BYTE_CODE */
|
||||
}
|
||||
}
|
||||
else if ((literal_p->type == LEXER_FUNCTION_LITERAL)
|
||||
|| (literal_p->type == LEXER_REGEXP_LITERAL))
|
||||
{
|
||||
ECMA_SET_NON_NULL_POINTER (literal_pool_p[literal_p->prop.index],
|
||||
literal_p->u.bytecode_p);
|
||||
JERRY_ASSERT (literal_p->prop.index >= register_count);
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (literal_pool_p[literal_p->prop.index],
|
||||
literal_p->u.bytecode_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (literal_p->type == LEXER_NUMBER_LITERAL);
|
||||
JERRY_ASSERT (literal_p->type == LEXER_NUMBER_LITERAL
|
||||
&& literal_p->prop.index >= register_count);
|
||||
|
||||
literal_pool_p[literal_p->prop.index] = literal_p->u.value;
|
||||
}
|
||||
}
|
||||
@ -692,9 +700,12 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
|
||||
|
||||
JERRY_ASSERT (literal_p != NULL
|
||||
&& literal_p->type == LEXER_FUNCTION_LITERAL);
|
||||
|
||||
init_index = literal_p->prop.index;
|
||||
ECMA_SET_NON_NULL_POINTER (literal_pool_p[literal_p->prop.index],
|
||||
literal_p->u.bytecode_p);
|
||||
JERRY_ASSERT (init_index >= register_count);
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (literal_pool_p[init_index],
|
||||
literal_p->u.bytecode_p);
|
||||
}
|
||||
|
||||
*dst_p++ = CBC_INITIALIZE_VAR;
|
||||
@ -1216,7 +1227,12 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
|
||||
byte_code_start_p += sizeof (cbc_uint8_arguments_t);
|
||||
}
|
||||
|
||||
byte_code_start_p += literal_end * sizeof (jmem_cpointer_t);
|
||||
byte_code_start_p += (unsigned int) (literal_end - register_end) * sizeof (ecma_value_t);
|
||||
if (unlikely (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED))
|
||||
{
|
||||
byte_code_start_p += argument_end * sizeof (ecma_value_t);
|
||||
}
|
||||
|
||||
byte_code_end_p = byte_code_start_p + length;
|
||||
byte_code_p = byte_code_start_p;
|
||||
|
||||
@ -1378,6 +1394,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
size_t last_position;
|
||||
size_t offset;
|
||||
size_t length;
|
||||
size_t literal_length;
|
||||
size_t total_size;
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
size_t total_size_used;
|
||||
@ -1388,7 +1405,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
bool needs_uint16_arguments;
|
||||
cbc_opcode_t last_opcode = CBC_EXT_OPCODE;
|
||||
ecma_compiled_code_t *compiled_code_p;
|
||||
jmem_cpointer_t *literal_pool_p;
|
||||
ecma_value_t *literal_pool_p;
|
||||
uint8_t *dst_p;
|
||||
|
||||
if ((size_t) context_p->stack_limit + (size_t) context_p->register_count > PARSER_MAXIMUM_STACK_LIMIT)
|
||||
@ -1612,7 +1629,16 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
total_size = sizeof (cbc_uint16_arguments_t);
|
||||
}
|
||||
|
||||
total_size += length + context_p->literal_count * sizeof (jmem_cpointer_t);
|
||||
literal_length = (size_t) (context_p->literal_count - context_p->register_count) * sizeof (ecma_value_t);
|
||||
|
||||
total_size += literal_length + length;
|
||||
|
||||
if ((context_p->status_flags & PARSER_ARGUMENTS_NEEDED)
|
||||
&& !(context_p->status_flags & PARSER_IS_STRICT))
|
||||
{
|
||||
total_size += context_p->argument_count * sizeof (ecma_value_t);
|
||||
}
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
total_size_used = total_size;
|
||||
#endif
|
||||
@ -1678,6 +1704,12 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
if (context_p->status_flags & PARSER_ARGUMENTS_NEEDED)
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_ARGUMENTS_NEEDED;
|
||||
|
||||
if (!(context_p->status_flags & PARSER_IS_STRICT))
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED;
|
||||
}
|
||||
|
||||
/* Arguments is stored in the lexical environment. */
|
||||
context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
|
||||
}
|
||||
@ -1694,8 +1726,9 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||
|
||||
literal_pool_p = (jmem_cpointer_t *) byte_code_p;
|
||||
byte_code_p += context_p->literal_count * sizeof (jmem_cpointer_t);
|
||||
literal_pool_p = (ecma_value_t *) byte_code_p;
|
||||
literal_pool_p -= context_p->register_count;
|
||||
byte_code_p += literal_length;
|
||||
|
||||
dst_p = parser_generate_initializers (context_p,
|
||||
byte_code_p,
|
||||
@ -1896,17 +1929,19 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
{
|
||||
parser_list_iterator_t literal_iterator;
|
||||
lexer_literal_t *literal_p;
|
||||
uint16_t register_count = context_p->register_count;
|
||||
|
||||
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
|
||||
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)))
|
||||
{
|
||||
if (literal_p->status_flags & LEXER_FLAG_LATE_INIT)
|
||||
if ((literal_p->status_flags & LEXER_FLAG_LATE_INIT)
|
||||
&& literal_p->prop.index >= register_count)
|
||||
{
|
||||
uint32_t source_data = literal_p->u.source_data;
|
||||
const uint8_t *char_p = context_p->source_end_p - (source_data & 0xfffff);
|
||||
jmem_cpointer_t lit_cp = ecma_find_or_create_literal_string (char_p,
|
||||
ecma_value_t lit_value = ecma_find_or_create_literal_string (char_p,
|
||||
source_data >> 20);
|
||||
literal_pool_p[literal_p->prop.index] = lit_cp;
|
||||
literal_pool_p[literal_p->prop.index] = lit_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1917,6 +1952,9 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
{
|
||||
parser_list_iterator_t literal_iterator;
|
||||
uint16_t argument_count = 0;
|
||||
uint16_t register_count = context_p->register_count;
|
||||
ecma_value_t *argument_base_p = (ecma_value_t *) (((uint8_t *) compiled_code_p) + total_size);
|
||||
argument_base_p -= context_p->argument_count;
|
||||
|
||||
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
|
||||
while (argument_count < context_p->argument_count)
|
||||
@ -1936,7 +1974,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
{
|
||||
if (literal_p->u.char_p == NULL)
|
||||
{
|
||||
literal_pool_p[argument_count] = JMEM_CP_NULL;
|
||||
argument_base_p[argument_count] = ECMA_VALUE_EMPTY;
|
||||
argument_count++;
|
||||
continue;
|
||||
}
|
||||
@ -1949,17 +1987,17 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
JERRY_ASSERT (literal_p->type == LEXER_IDENT_LITERAL
|
||||
&& (literal_p->status_flags & LEXER_FLAG_VAR));
|
||||
|
||||
JERRY_ASSERT (argument_count < literal_p->prop.index);
|
||||
JERRY_ASSERT (literal_p->prop.index >= register_count);
|
||||
|
||||
literal_pool_p[argument_count] = literal_pool_p[literal_p->prop.index];
|
||||
argument_base_p[argument_count] = literal_pool_p[literal_p->prop.index];
|
||||
argument_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (context_p->status_flags & PARSER_NAMED_FUNCTION_EXP)
|
||||
{
|
||||
ECMA_SET_NON_NULL_POINTER (literal_pool_p[const_literal_end],
|
||||
compiled_code_p);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (literal_pool_p[const_literal_end],
|
||||
compiled_code_p);
|
||||
}
|
||||
|
||||
#ifdef JERRY_DEBUGGER
|
||||
|
||||
@ -85,7 +85,7 @@ typedef enum
|
||||
typedef struct
|
||||
{
|
||||
ecma_compiled_code_t header; /**< compiled code header */
|
||||
jmem_cpointer_t pattern_cp; /**< original RegExp pattern */
|
||||
ecma_value_t pattern; /**< original RegExp pattern */
|
||||
uint32_t num_of_captures; /**< number of capturing brackets */
|
||||
uint32_t num_of_non_captures; /**< number of non capturing brackets */
|
||||
} re_compiled_code_t;
|
||||
|
||||
@ -468,8 +468,7 @@ re_find_bytecode_in_cache (ecma_string_t *pattern_str_p, /**< pattern string */
|
||||
|
||||
if (cached_bytecode_p != NULL)
|
||||
{
|
||||
ecma_string_t *cached_pattern_str_p;
|
||||
cached_pattern_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, cached_bytecode_p->pattern_cp);
|
||||
ecma_string_t *cached_pattern_str_p = ecma_get_string_from_value (cached_bytecode_p->pattern);
|
||||
|
||||
if ((cached_bytecode_p->header.status_flags & RE_FLAGS_MASK) == flags
|
||||
&& ecma_compare_ecma_strings (cached_pattern_str_p, pattern_str_p))
|
||||
@ -580,7 +579,7 @@ re_compile_bytecode (const re_compiled_code_t **out_bytecode_p, /**< [out] point
|
||||
re_compiled_code.header.refs = 1;
|
||||
re_compiled_code.header.status_flags = re_ctx.flags;
|
||||
ecma_ref_ecma_string (pattern_str_p);
|
||||
ECMA_SET_NON_NULL_POINTER (re_compiled_code.pattern_cp, pattern_str_p);
|
||||
re_compiled_code.pattern = ecma_make_string_value (pattern_str_p);
|
||||
re_compiled_code.num_of_captures = re_ctx.num_of_captures * 2;
|
||||
re_compiled_code.num_of_non_captures = re_ctx.num_of_non_captures;
|
||||
|
||||
|
||||
@ -217,12 +217,12 @@ vm_op_delete_prop (ecma_value_t object, /**< base object */
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
vm_op_delete_var (jmem_cpointer_t name_literal, /**< name literal */
|
||||
vm_op_delete_var (ecma_value_t name_literal, /**< name literal */
|
||||
ecma_object_t *lex_env_p) /**< lexical environment */
|
||||
{
|
||||
ecma_value_t completion_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, name_literal);
|
||||
ecma_string_t *var_name_str_p = ecma_get_string_from_value (name_literal);
|
||||
|
||||
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (lex_env_p, var_name_str_p);
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ ecma_value_t
|
||||
vm_op_delete_prop (ecma_value_t object, ecma_value_t property, bool is_strict);
|
||||
|
||||
ecma_value_t
|
||||
vm_op_delete_var (jmem_cpointer_t name_literal, ecma_object_t *lex_env_p);
|
||||
vm_op_delete_var (ecma_value_t name_literal, ecma_object_t *lex_env_p);
|
||||
|
||||
ecma_collection_chunk_t *
|
||||
opfunc_for_in (ecma_value_t left_value, ecma_value_t *result_obj_p);
|
||||
|
||||
@ -46,7 +46,7 @@ typedef struct vm_frame_ctx_t
|
||||
uint8_t *byte_code_start_p; /**< byte code start pointer */
|
||||
ecma_value_t *registers_p; /**< register start pointer */
|
||||
ecma_value_t *stack_top_p; /**< stack top pointer */
|
||||
jmem_cpointer_t *literal_start_p; /**< literal list start pointer */
|
||||
ecma_value_t *literal_start_p; /**< literal list start pointer */
|
||||
ecma_object_t *lex_env_p; /**< current lexical environment */
|
||||
struct vm_frame_ctx_t *prev_context_p; /**< previous context */
|
||||
ecma_value_t this_binding; /**< this binding */
|
||||
|
||||
@ -55,23 +55,15 @@ vm_op_get_value (ecma_value_t object, /**< base object */
|
||||
{
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (object);
|
||||
ecma_string_t *property_name_p = NULL;
|
||||
ecma_string_t uint32_string;
|
||||
|
||||
if (ecma_is_value_integer_number (property))
|
||||
{
|
||||
ecma_integer_value_t int_value = ecma_get_integer_from_value (property);
|
||||
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
bool limit_check = (int_value >= 0);
|
||||
#else /* !JERRY_CPOINTER_32_BIT */
|
||||
bool limit_check = (int_value >= 0 && int_value < (ecma_integer_value_t) (UINT16_MAX + 1));
|
||||
#endif
|
||||
|
||||
if (limit_check)
|
||||
if (int_value >= 0 && int_value <= ECMA_DIRECT_STRING_MAX_IMM)
|
||||
{
|
||||
/* Statically allocated string for searching. */
|
||||
ecma_init_ecma_string_from_uint32 (&uint32_string, (uint32_t) int_value);
|
||||
property_name_p = &uint32_string;
|
||||
property_name_p = (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT,
|
||||
(uintptr_t) int_value);
|
||||
}
|
||||
}
|
||||
else if (ecma_is_value_string (property))
|
||||
@ -295,10 +287,10 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
|
||||
*/
|
||||
static ecma_value_t
|
||||
vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
jmem_cpointer_t lit_cp) /**< literal */
|
||||
ecma_value_t lit_value) /**< literal */
|
||||
{
|
||||
ecma_compiled_code_t *bytecode_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
|
||||
lit_cp);
|
||||
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||
lit_value);
|
||||
bool is_function = ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION) != 0);
|
||||
|
||||
if (is_function)
|
||||
@ -523,8 +515,8 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, \
|
||||
literal_start_p[literal_index]); \
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); \
|
||||
\
|
||||
result = ecma_op_resolve_reference_value (frame_ctx_p->lex_env_p, \
|
||||
name_p); \
|
||||
\
|
||||
@ -537,23 +529,13 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
} \
|
||||
else if (literal_index < const_literal_end) \
|
||||
{ \
|
||||
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, \
|
||||
literal_start_p[literal_index]); \
|
||||
\
|
||||
if (unlikely (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER)) \
|
||||
{ \
|
||||
(target_value) = ecma_fast_copy_value (value_p->u.lit_number); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ecma_ref_ecma_string (value_p); \
|
||||
(target_value) = ecma_make_string_value (value_p); \
|
||||
} \
|
||||
(target_value) = ecma_fast_copy_value (literal_start_p[literal_index]); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Object construction. */ \
|
||||
(target_value) = vm_construct_literal_object (frame_ctx_p, literal_start_p[literal_index]); \
|
||||
(target_value) = vm_construct_literal_object (frame_ctx_p, \
|
||||
literal_start_p[literal_index]); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
@ -571,10 +553,10 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
uint16_t encoding_limit;
|
||||
uint16_t encoding_delta;
|
||||
uint16_t register_end;
|
||||
jmem_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p;
|
||||
ecma_value_t *literal_start_p = frame_ctx_p->literal_start_p;
|
||||
bool is_strict = ((frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0);
|
||||
jmem_cpointer_t self_reference;
|
||||
ECMA_SET_NON_NULL_POINTER (self_reference, bytecode_header_p);
|
||||
ecma_value_t self_reference;
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (self_reference, bytecode_header_p);
|
||||
|
||||
/* Prepare. */
|
||||
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING))
|
||||
@ -613,8 +595,7 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
while (literal_index <= literal_index_end)
|
||||
{
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
literal_start_p[literal_index]);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
|
||||
vm_var_decl (frame_ctx_p, name_p);
|
||||
literal_index++;
|
||||
}
|
||||
@ -663,14 +644,9 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
literal_start_p[literal_index]);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
|
||||
|
||||
if (self_reference == literal_start_p[value_index])
|
||||
{
|
||||
ecma_op_create_immutable_binding (frame_ctx_p->lex_env_p, name_p, lit_value);
|
||||
}
|
||||
else
|
||||
if (likely (value_index < register_end || self_reference != literal_start_p[value_index]))
|
||||
{
|
||||
vm_var_decl (frame_ctx_p, name_p);
|
||||
|
||||
@ -690,6 +666,10 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
ecma_free_value (JERRY_CONTEXT (error_value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_op_create_immutable_binding (frame_ctx_p->lex_env_p, name_p, lit_value);
|
||||
}
|
||||
|
||||
if (value_index >= register_end)
|
||||
{
|
||||
@ -730,7 +710,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
|
||||
uint8_t *byte_code_p = frame_ctx_p->byte_code_p;
|
||||
jmem_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p;
|
||||
ecma_value_t *literal_start_p = frame_ctx_p->literal_start_p;
|
||||
|
||||
ecma_value_t *stack_top_p;
|
||||
uint16_t encoding_limit;
|
||||
@ -1146,10 +1126,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
literal_start_p[literal_index]);
|
||||
ecma_object_t *ref_base_lex_env_p;
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
|
||||
|
||||
ecma_object_t *ref_base_lex_env_p;
|
||||
ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
|
||||
name_p);
|
||||
|
||||
@ -1648,8 +1627,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
literal_start_p[literal_index]);
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
|
||||
|
||||
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
|
||||
name_p);
|
||||
@ -2592,8 +2570,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
literal_start_p[literal_index]);
|
||||
ecma_string_t *var_name_str_p = ecma_get_string_from_value (literal_start_p[literal_index]);
|
||||
|
||||
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
|
||||
var_name_str_p);
|
||||
|
||||
@ -2745,25 +2723,20 @@ error:
|
||||
|
||||
if (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_CATCH)
|
||||
{
|
||||
uint32_t literal_index;
|
||||
ecma_object_t *catch_env_p;
|
||||
ecma_string_t *catch_name_p;
|
||||
|
||||
*stack_top_p++ = JERRY_CONTEXT (error_value);
|
||||
|
||||
JERRY_ASSERT (byte_code_p[0] == CBC_ASSIGN_SET_IDENT);
|
||||
|
||||
literal_index = byte_code_p[1];
|
||||
uint32_t literal_index = byte_code_p[1];
|
||||
|
||||
if (literal_index >= encoding_limit)
|
||||
{
|
||||
literal_index = ((literal_index << 8) | byte_code_p[2]) - encoding_delta;
|
||||
}
|
||||
|
||||
catch_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p);
|
||||
|
||||
catch_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
literal_start_p[literal_index]);
|
||||
ecma_object_t *catch_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p);
|
||||
|
||||
ecma_string_t *catch_name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
|
||||
ecma_op_create_mutable_binding (catch_env_p, catch_name_p, false);
|
||||
|
||||
stack_top_p[-2 - 1] = ecma_make_object_value (frame_ctx_p->lex_env_p);
|
||||
@ -2909,29 +2882,29 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
|
||||
const ecma_value_t *arg_list_p, /**< arguments list */
|
||||
ecma_length_t arg_list_len) /**< length of arguments list */
|
||||
{
|
||||
jmem_cpointer_t *literal_p;
|
||||
ecma_value_t *literal_p;
|
||||
vm_frame_ctx_t frame_ctx;
|
||||
uint32_t call_stack_size;
|
||||
|
||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
|
||||
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);
|
||||
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint16_arguments_t));
|
||||
literal_p -= args_p->register_end;
|
||||
frame_ctx.literal_start_p = literal_p;
|
||||
literal_p += args_p->literal_end;
|
||||
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
|
||||
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);
|
||||
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint8_arguments_t));
|
||||
literal_p -= args_p->register_end;
|
||||
frame_ctx.literal_start_p = literal_p;
|
||||
literal_p += args_p->literal_end;
|
||||
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);
|
||||
}
|
||||
|
||||
frame_ctx.bytecode_header_p = bytecode_header_p;
|
||||
|
||||
@ -104,23 +104,24 @@ main (void)
|
||||
|
||||
for (uint32_t j = 0; j < test_sub_iters; j++)
|
||||
{
|
||||
jmem_cpointer_t lit1;
|
||||
jmem_cpointer_t lit2;
|
||||
ecma_value_t lit1;
|
||||
ecma_value_t lit2;
|
||||
if (ptrs[j])
|
||||
{
|
||||
lit1 = ecma_find_or_create_literal_string (ptrs[j], lengths[j]);
|
||||
lit2 = ecma_find_or_create_literal_string (ptrs[j], lengths[j]);
|
||||
TEST_ASSERT (ecma_is_value_string (lit1));
|
||||
TEST_ASSERT (ecma_is_value_string (lit2));
|
||||
TEST_ASSERT (lit1 == lit2);
|
||||
}
|
||||
else
|
||||
{
|
||||
lit1 = ecma_find_or_create_literal_number (numbers[j]);
|
||||
lit2 = ecma_find_or_create_literal_number (numbers[j]);
|
||||
TEST_ASSERT (ecma_is_value_number (lit1));
|
||||
TEST_ASSERT (ecma_is_value_number (lit2));
|
||||
TEST_ASSERT (lit1 == lit2);
|
||||
}
|
||||
TEST_ASSERT (lit1);
|
||||
TEST_ASSERT (lit2);
|
||||
TEST_ASSERT (lit1 == lit2);
|
||||
}
|
||||
|
||||
/* Check empty string exists. */
|
||||
|
||||
@ -127,18 +127,18 @@ main (void)
|
||||
/* Check the snapshot data. Unused bytes should be filled with zeroes */
|
||||
const uint8_t expected_data[] =
|
||||
{
|
||||
0x4A, 0x52, 0x52, 0x59, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x4A, 0x52, 0x52, 0x59, 0x09, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x28, 0x00,
|
||||
0xB7, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x47, 0x00,
|
||||
0x1C, 0x00, 0x00, 0x00, 0x14, 0x00, 0x73, 0x74,
|
||||
0x72, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x72, 0x6F,
|
||||
0x6D, 0x20, 0x73, 0x6E, 0x61, 0x70, 0x73, 0x68,
|
||||
0x6F, 0x74, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
|
||||
0x28, 0x00, 0xB7, 0x46, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x01, 0x00, 0x41, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x00,
|
||||
0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
|
||||
0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x73, 0x6E,
|
||||
0x61, 0x70, 0x73, 0x68, 0x6F, 0x74
|
||||
};
|
||||
TEST_ASSERT (sizeof (expected_data) == global_mode_snapshot_size);
|
||||
TEST_ASSERT (0 == memcmp (expected_data, global_mode_snapshot_buffer, sizeof (expected_data)));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user