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:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user