Compact Byte Code parser and executor for Jerry.

JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: Tamas Gergely tgergely.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: Roland Takacs rtakacs.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: István Kádár ikadar@inf.u-szeged.hu
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-02-05 00:10:10 -08:00
parent db6caf3c48
commit 4d2dd22ced
92 changed files with 17184 additions and 20276 deletions
+474 -114
View File
@@ -1,4 +1,4 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
#include <stdio.h>
#include "bytecode-data.h"
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-builtins.h"
@@ -28,8 +27,12 @@
#include "ecma-objects.h"
#include "ecma-objects-general.h"
#include "ecma-try-catch-macro.h"
#include "jerry-snapshot.h"
#include "lit-literal.h"
#include "lit-magic-strings.h"
#include "lit-snapshot.h"
#include "parser.h"
#include "re-compiler.h"
#define JERRY_INTERNAL
#include "jerry-internal.h"
@@ -685,7 +688,7 @@ jerry_api_create_string (const jerry_api_char_t *v) /**< string value */
*/
jerry_api_string_t *
jerry_api_create_string_sz (const jerry_api_char_t *v, /**< string value */
jerry_api_size_t v_size)
jerry_api_size_t v_size) /**< string size */
{
jerry_assert_api_available ();
@@ -1125,9 +1128,9 @@ jerry_api_delete_object_field (jerry_api_object_t *object_p, /**< object to dele
* - there is field with specified name in the object;
* false - otherwise.
*/
bool jerry_api_get_object_field_value (jerry_api_object_t *object_p,
const jerry_api_char_t *field_name_p,
jerry_api_value_t *field_value_p)
bool jerry_api_get_object_field_value (jerry_api_object_t *object_p, /**< object */
const jerry_api_char_t *field_name_p, /**< field name */
jerry_api_value_t *field_value_p) /**< out: field value */
{
return jerry_api_get_object_field_value_sz (object_p,
field_name_p,
@@ -1672,9 +1675,8 @@ jerry_cleanup (void)
ecma_finalize ();
lit_finalize ();
bc_finalize ();
mem_finalize (is_show_mem_stats);
vm_finalize ();
mem_finalize (is_show_mem_stats);
} /* jerry_cleanup */
/**
@@ -1724,11 +1726,11 @@ jerry_parse (const jerry_api_char_t* source_p, /**< script source */
{
jerry_assert_api_available ();
bool is_show_instructions = ((jerry_flags & JERRY_FLAG_SHOW_OPCODES) != 0);
int is_show_instructions = ((jerry_flags & JERRY_FLAG_SHOW_OPCODES) != 0);
parser_set_show_instrs (is_show_instructions);
const bytecode_data_header_t *bytecode_data_p;
ecma_compiled_code_t *bytecode_data_p;
jsp_status_t parse_status;
parse_status = parser_parse_script (source_p,
@@ -1865,6 +1867,212 @@ jerry_register_external_magic_strings (const jerry_api_char_ptr_t* ex_str_items,
lit_magic_strings_ex_set ((const lit_utf8_byte_t **) ex_str_items, count, (const lit_utf8_size_t *) str_lengths);
} /* jerry_register_external_magic_strings */
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
/*
* Tells whether snapshot taking is in progress.
*/
bool snapshot_report_byte_code_compilation = false;
/*
* Mapping snapshot to offset.
*/
typedef struct
{
mem_cpointer_t next_cp;
mem_cpointer_t compiled_code_cp;
uint16_t offset;
} compiled_code_map_entry_t;
/*
* Variables required to take a snapshot.
*/
static size_t snapshot_buffer_write_offset;
static size_t snapshot_last_compiled_code_offset;
static bool snapshot_error_occured;
static uint8_t *snapshot_buffer_p;
static size_t snapshot_buffer_size;
static compiled_code_map_entry_t *snapshot_map_entries_p;
/**
* Snapshot callback for byte codes.
*/
void
snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled code */
const uint8_t *regexp_pattern, /**< regular expression pattern */
uint32_t size) /**< compiled code or regular expression size */
{
if (snapshot_error_occured)
{
return;
}
JERRY_ASSERT ((snapshot_buffer_write_offset & (MEM_ALIGNMENT - 1)) == 0);
if ((snapshot_buffer_write_offset >> MEM_ALIGNMENT_LOG) > 0xffffu)
{
snapshot_error_occured = true;
return;
}
snapshot_last_compiled_code_offset = snapshot_buffer_write_offset;
compiled_code_map_entry_t *new_entry = (compiled_code_map_entry_t *) mem_pools_alloc ();
if (new_entry == NULL)
{
snapshot_error_occured = true;
return;
}
ECMA_SET_POINTER (new_entry->next_cp, snapshot_map_entries_p);
ECMA_SET_POINTER (new_entry->compiled_code_cp, compiled_code_p);
new_entry->offset = (uint16_t) (snapshot_buffer_write_offset >> MEM_ALIGNMENT_LOG);
snapshot_map_entries_p = new_entry;
const void *data_p = (const void *) compiled_code_p;
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
{
size += (uint32_t) sizeof (uint16_t);
}
else
{
JERRY_ASSERT (regexp_pattern == NULL);
}
if (!jrt_write_to_buffer_by_offset (snapshot_buffer_p,
snapshot_buffer_size,
&snapshot_buffer_write_offset,
&size,
sizeof (uint32_t)))
{
snapshot_error_occured = true;
return;
}
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
{
size -= (uint32_t) sizeof (uint16_t);
if (!jrt_write_to_buffer_by_offset (snapshot_buffer_p,
snapshot_buffer_size,
&snapshot_buffer_write_offset,
&compiled_code_p->status_flags,
sizeof (uint16_t)))
{
snapshot_error_occured = true;
return;
}
data_p = regexp_pattern;
}
if (!jrt_write_to_buffer_by_offset (snapshot_buffer_p,
snapshot_buffer_size,
&snapshot_buffer_write_offset,
data_p,
size))
{
snapshot_error_occured = true;
return;
}
snapshot_buffer_write_offset = JERRY_ALIGNUP (snapshot_buffer_write_offset, MEM_ALIGNMENT);
if (snapshot_buffer_write_offset > snapshot_buffer_size)
{
snapshot_error_occured = true;
return;
}
} /* snapshot_add_compiled_code */
/**
* Set the uint16_t offsets in the code area.
*/
static void
jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
uint32_t size, /**< buffer size */
lit_mem_to_snapshot_id_map_entry_t *lit_map_p) /**< literal map */
{
JERRY_ASSERT (size > 0);
do
{
uint32_t code_size = *(uint32_t *) buffer_p;
buffer_p += sizeof (uint32_t);
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
/* Set reference counter to 1. */
bytecode_p->status_flags &= (1 << ECMA_BYTECODE_REF_SHIFT) - 1;
bytecode_p->status_flags |= 1 << ECMA_BYTECODE_REF_SHIFT;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
{
lit_cpointer_t *literal_start_p;
uint32_t literal_end;
uint32_t const_literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
literal_end = args_p->literal_end;
const_literal_end = args_p->const_literal_end;
}
else
{
literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
literal_end = args_p->literal_end;
const_literal_end = args_p->const_literal_end;
}
for (uint32_t i = 0; i < const_literal_end; i++)
{
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
if (literal_start_p[i].packed_value != MEM_CP_NULL)
{
while (current_p->literal_id.packed_value != literal_start_p[i].packed_value)
{
current_p++;
}
literal_start_p[i].packed_value = (uint16_t) current_p->literal_offset;
}
}
for (uint32_t i = const_literal_end; i < literal_end; i++)
{
compiled_code_map_entry_t *current_p = snapshot_map_entries_p;
while (current_p->compiled_code_cp != literal_start_p[i].value.base_cp)
{
current_p = ECMA_GET_NON_NULL_POINTER (compiled_code_map_entry_t,
current_p->next_cp);
}
literal_start_p[i].packed_value = (uint16_t) current_p->offset;
}
}
code_size += (uint32_t) sizeof (uint32_t);
code_size = JERRY_ALIGNUP (code_size, MEM_ALIGNMENT);
buffer_p += code_size - sizeof (uint32_t);
size -= code_size;
}
while (size > 0);
} /* jerry_snapshot_set_offsets */
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
/**
* Generate snapshot from specified source
*
@@ -1881,9 +2089,41 @@ jerry_parse_and_save_snapshot (const jerry_api_char_t* source_p, /**< script sou
uint8_t *buffer_p, /**< buffer to dump snapshot to */
size_t buffer_size) /**< the buffer's size */
{
#ifdef JERRY_ENABLE_SNAPSHOT
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
jsp_status_t parse_status;
const bytecode_data_header_t *bytecode_data_p;
ecma_compiled_code_t *bytecode_data_p;
snapshot_buffer_write_offset = 0;
snapshot_last_compiled_code_offset = 0;
snapshot_error_occured = false;
snapshot_buffer_p = buffer_p;
snapshot_buffer_size = buffer_size;
snapshot_map_entries_p = NULL;
uint64_t version = JERRY_SNAPSHOT_VERSION;
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
&snapshot_buffer_write_offset,
&version,
sizeof (version)))
{
return 0;
}
snapshot_buffer_write_offset = JERRY_ALIGNUP (snapshot_buffer_write_offset, MEM_ALIGNMENT);
size_t header_offset = snapshot_buffer_write_offset;
snapshot_buffer_write_offset += JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT);
if (snapshot_buffer_write_offset > buffer_size)
{
return 0;
}
size_t compiled_code_start = snapshot_buffer_write_offset;
snapshot_report_byte_code_compilation = true;
if (is_for_global)
{
@@ -1891,88 +2131,81 @@ jerry_parse_and_save_snapshot (const jerry_api_char_t* source_p, /**< script sou
}
else
{
bool code_contains_functions;
parse_status = parser_parse_eval (source_p,
source_size,
false,
&bytecode_data_p,
&code_contains_functions);
&bytecode_data_p);
}
if (parse_status != JSP_STATUS_OK)
snapshot_report_byte_code_compilation = false;
if (parse_status == JSP_STATUS_OK
&& !snapshot_error_occured)
{
return 0;
}
JERRY_ASSERT (snapshot_last_compiled_code_offset != 0);
size_t buffer_write_offset = 0;
jerry_snapshot_header_t header;
header.last_compiled_code_offset = (uint32_t) snapshot_last_compiled_code_offset;
header.is_run_global = is_for_global;
jerry_snapshot_header_t header;
header.is_run_global = is_for_global;
size_t compiled_code_size = snapshot_buffer_write_offset - compiled_code_start;
uint64_t version = JERRY_SNAPSHOT_VERSION;
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
&buffer_write_offset,
&version,
sizeof (version)))
{
return 0;
}
lit_mem_to_snapshot_id_map_entry_t* lit_map_p = NULL;
uint32_t literals_num;
size_t header_offset = buffer_write_offset;
if (!lit_dump_literals_for_snapshot (buffer_p,
buffer_size,
&snapshot_buffer_write_offset,
&lit_map_p,
&literals_num,
&header.lit_table_size))
{
JERRY_ASSERT (lit_map_p == NULL);
snapshot_buffer_write_offset = 0;
}
else
{
if (header.lit_table_size > 0xffff)
{
/* Aligning literals could increase this range, but
* it is not a requirement for low-memory environments. */
snapshot_buffer_write_offset = 0;
}
else
{
jerry_snapshot_set_offsets (buffer_p + compiled_code_start,
(uint32_t) compiled_code_size,
lit_map_p);
if (buffer_write_offset + JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT) > buffer_size)
{
return 0;
}
buffer_write_offset += JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT);
lit_mem_to_snapshot_id_map_entry_t* lit_map_p = NULL;
uint32_t literals_num;
if (!lit_dump_literals_for_snapshot (buffer_p,
jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
&buffer_write_offset,
&lit_map_p,
&literals_num,
&header.lit_table_size))
&header_offset,
&header,
sizeof (header));
}
mem_heap_free_block (lit_map_p);
}
ecma_bytecode_deref (bytecode_data_p);
}
else
{
JERRY_ASSERT (lit_map_p == NULL);
return 0;
snapshot_buffer_write_offset = 0;
}
size_t bytecode_offset = (sizeof (version)
+ JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT)
+ header.lit_table_size);
compiled_code_map_entry_t *current_p = snapshot_map_entries_p;
JERRY_ASSERT (JERRY_ALIGNUP (bytecode_offset, MEM_ALIGNMENT) == bytecode_offset);
bool is_ok = bc_save_bytecode_data (buffer_p,
buffer_size,
&buffer_write_offset,
bytecode_data_p,
lit_map_p,
literals_num,
&header.scopes_num);
JERRY_ASSERT (header.scopes_num != 0);
if (lit_map_p != NULL)
while (current_p != NULL)
{
mem_heap_free_block (lit_map_p);
compiled_code_map_entry_t *next_p = ECMA_GET_POINTER (compiled_code_map_entry_t,
current_p->next_cp);
mem_pools_free ((uint8_t *) current_p);
current_p = next_p;
}
if (!is_ok)
{
return 0;
}
is_ok = jrt_write_to_buffer_by_offset (buffer_p, buffer_size, &header_offset, &header, sizeof (header));
JERRY_ASSERT (is_ok && header_offset < buffer_write_offset);
return buffer_write_offset;
#else /* JERRY_ENABLE_SNAPSHOT */
return snapshot_buffer_write_offset;
#else /* JERRY_ENABLE_SNAPSHOT_SAVE */
(void) source_p;
(void) source_size;
(void) is_for_global;
@@ -1980,9 +2213,144 @@ jerry_parse_and_save_snapshot (const jerry_api_char_t* source_p, /**< script sou
(void) buffer_size;
return 0;
#endif /* !JERRY_ENABLE_SNAPSHOT */
#endif /* !JERRY_ENABLE_SNAPSHOT_SAVE */
} /* jerry_parse_and_save_snapshot */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
* Load byte code from snapshot.
*
* @return byte code
*/
static ecma_compiled_code_t *
snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data */
size_t offset, /**< byte code offset */
lit_mem_to_snapshot_id_map_entry_t *lit_map_p, /**< literal map */
bool copy_bytecode) /**< byte code should be copied to memory */
{
uint32_t code_size = *(uint32_t *) (snapshot_data_p + offset);
ecma_compiled_code_t *bytecode_p;
bytecode_p = (ecma_compiled_code_t *) (snapshot_data_p + offset + sizeof (uint32_t));
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
{
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN
re_compiled_code_t *re_bytecode_p = NULL;
const uint8_t *regex_start_p = ((const uint8_t *) bytecode_p) + sizeof (uint16_t);
code_size -= (uint32_t) sizeof (uint16_t);
ecma_string_t *pattern_str_p = ecma_new_ecma_string_from_utf8 (regex_start_p,
code_size);
re_compile_bytecode (&re_bytecode_p,
pattern_str_p,
bytecode_p->status_flags);
ecma_deref_ecma_string (pattern_str_p);
return (ecma_compiled_code_t *) re_bytecode_p;
#else
JERRY_UNIMPLEMENTED ("RegExp is not supported in compact profile.");
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */
}
size_t header_size;
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;
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;
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;
header_size = sizeof (cbc_uint8_arguments_t);
}
if (copy_bytecode)
{
bytecode_p = (ecma_compiled_code_t *) mem_heap_alloc_block (code_size,
MEM_HEAP_ALLOC_LONG_TERM);
memcpy (bytecode_p, snapshot_data_p + offset + sizeof (uint32_t), code_size);
}
else
{
code_size = (uint32_t) (header_size + literal_end * sizeof (lit_cpointer_t));
uint8_t *real_bytecode_p = ((uint8_t *) bytecode_p) + code_size;
bytecode_p = (ecma_compiled_code_t *) mem_heap_alloc_block (code_size + 1 + sizeof (uint8_t *),
MEM_HEAP_ALLOC_LONG_TERM);
memcpy (bytecode_p, snapshot_data_p + offset + sizeof (uint32_t), code_size);
uint8_t *instructions_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 *));
}
JERRY_ASSERT ((bytecode_p->status_flags >> ECMA_BYTECODE_REF_SHIFT) == 1);
lit_cpointer_t *literal_start_p = (lit_cpointer_t *) (((uint8_t *) bytecode_p) + header_size);
for (uint32_t i = 0; i < const_literal_end; i++)
{
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
if (literal_start_p[i].packed_value != 0)
{
while (current_p->literal_offset != literal_start_p[i].packed_value)
{
current_p++;
}
literal_start_p[i] = current_p->literal_id;
}
}
for (uint32_t i = const_literal_end; i < literal_end; i++)
{
size_t literal_offset = ((size_t) literal_start_p[i].packed_value) << MEM_ALIGNMENT_LOG;
if (literal_offset == offset)
{
/* Self reference */
ECMA_SET_NON_NULL_POINTER (literal_start_p[i].value.base_cp,
bytecode_p);
}
else
{
ecma_compiled_code_t *literal_bytecode_p;
literal_bytecode_p = snapshot_load_compiled_code (snapshot_data_p,
literal_offset,
lit_map_p,
copy_bytecode);
ECMA_SET_NON_NULL_POINTER (literal_start_p[i].value.base_cp,
literal_bytecode_p);
}
}
return bytecode_p;
} /* snapshot_load_compiled_code */
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
/**
* Execute snapshot from specified buffer
*
@@ -1991,19 +2359,19 @@ jerry_parse_and_save_snapshot (const jerry_api_char_t* source_p, /**< script sou
jerry_completion_code_t
jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
size_t snapshot_size, /**< size of snapshot */
bool is_copy, /**< flag, indicating whether the passed snapshot
* buffer should be copied to engine's memory,
* so engine should not reference the buffer
* after the function returns (in the case, the passed
* buffer could be freed after the call);
* otherwise (if flag not set) - the buffer could be freed
* only after engine stops (i.e. after call to jerry_cleanup). */
jerry_api_value_t *retval_p) /**< out: returned value (ECMA-262 'undefined' if code is executed
* as global scope code) */
bool copy_bytecode, /**< flag, indicating whether the passed snapshot
* buffer should be copied to the engine's memory.
* If set the engine should not reference the buffer
* after the function returns (in this case, the passed
* buffer could be freed after the call).
* Otherwise (if the flag is not set) - the buffer could only be
* freed after the engine stops (i.e. after call to jerry_cleanup). */
jerry_api_value_t *retval_p) /**< out: returned value (ECMA-262 'undefined' if
* code is executed as global scope code) */
{
jerry_api_convert_ecma_value_to_api_value (retval_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED));
#ifdef JERRY_ENABLE_SNAPSHOT
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
JERRY_ASSERT (snapshot_p != NULL);
const uint8_t *snapshot_data_p = (uint8_t *) snapshot_p;
@@ -2025,21 +2393,20 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
}
const jerry_snapshot_header_t *header_p = (const jerry_snapshot_header_t *) (snapshot_data_p + snapshot_read);
if (snapshot_read + JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT) > snapshot_size)
{
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT;
}
snapshot_read += JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT);
snapshot_read = header_p->last_compiled_code_offset;
if (snapshot_read + header_p->lit_table_size > snapshot_size)
{
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT;
}
JERRY_ASSERT (snapshot_read == JERRY_ALIGNUP (snapshot_read, MEM_ALIGNMENT));
uint32_t last_code_size = *(uint32_t *) (snapshot_data_p + snapshot_read);
snapshot_read += JERRY_ALIGNUP (last_code_size + sizeof (uint32_t), MEM_ALIGNMENT);
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
uint32_t literals_num;
JERRY_ASSERT (snapshot_read + header_p->lit_table_size <= snapshot_size);
if (!lit_load_literals_from_snapshot (snapshot_data_p + snapshot_read,
header_p->lit_table_size,
&lit_map_p,
@@ -2049,28 +2416,21 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT;
}
snapshot_read += header_p->lit_table_size;
ecma_compiled_code_t *bytecode_p;
if (snapshot_read > snapshot_size)
{
mem_heap_free_block (lit_map_p);
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT;
}
snapshot_read = header_p->last_compiled_code_offset;
const bytecode_data_header_t *bytecode_data_p;
bytecode_data_p = bc_load_bytecode_data (snapshot_data_p + snapshot_read,
snapshot_size - snapshot_read,
lit_map_p,
literals_num,
is_copy,
header_p->scopes_num);
bytecode_p = snapshot_load_compiled_code (snapshot_data_p,
snapshot_read,
lit_map_p,
copy_bytecode);
if (lit_map_p != NULL)
{
mem_heap_free_block (lit_map_p);
}
if (bytecode_data_p == NULL)
if (bytecode_p == NULL)
{
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT;
}
@@ -2079,7 +2439,7 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
if (header_p->is_run_global)
{
vm_init (bytecode_data_p, false);
vm_init (bytecode_p, false);
ret_code = vm_run_global ();
@@ -2088,7 +2448,7 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
else
{
/* vm should be already initialized */
ecma_completion_value_t completion = vm_run_eval (bytecode_data_p, false);
ecma_completion_value_t completion = vm_run_eval (bytecode_p, false);
ret_code = jerry_api_convert_eval_completion_to_retval (retval_p, completion);
@@ -2096,12 +2456,12 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
}
return ret_code;
#else /* JERRY_ENABLE_SNAPSHOT */
#else /* JERRY_ENABLE_SNAPSHOT_EXEC */
(void) snapshot_p;
(void) snapshot_size;
(void) is_copy;
(void) copy_bytecode;
(void) retval_p;
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_VERSION;
#endif /* !JERRY_ENABLE_SNAPSHOT */
#endif /* !JERRY_ENABLE_SNAPSHOT_EXEC */
} /* jerry_exec_snapshot */