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:
Zoltan Herczeg 2018-02-23 00:21:46 +01:00 committed by yichoi
parent fbf5c32747
commit 51e3c4455a
37 changed files with 1493 additions and 1148 deletions

View File

@ -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);

View File

@ -46,7 +46,7 @@ typedef struct
/**
* Jerry snapshot format version.
*/
#define JERRY_SNAPSHOT_VERSION (8u)
#define JERRY_SNAPSHOT_VERSION (9u)
/**
* Snapshot configuration flags.

View File

@ -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 */

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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 */
}

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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 */
/**

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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)
{

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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. */

View File

@ -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)));