Rework snapshot generation API. (#2259)

Also remove eval context support. It provides no practical advantage.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2018-04-05 13:43:55 +02:00 committed by GitHub
parent 35926f3f85
commit 7b226f53e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 477 additions and 569 deletions

View File

@ -59,6 +59,34 @@ Possible compile time enabled feature types:
- JERRY_FEATURE_DATE - Date support
- JERRY_FEATURE_REGEXP - RegExp support
## jerry_generate_snapshot_opts_t
Flags for [jerry_generate_snapshot](#jerry_generate_snapshot) and
[jerry_generate_function_snapshot](#jerry_generate_function_snapshot) functions:
- JERRY_SNAPSHOT_SAVE_STATIC - generate static snapshot (see below)
- JERRY_SNAPSHOT_SAVE_STRICT - strict source code provided
**Generate static snapshots**
Snapshots contain literal pools, and these literal pools contain references
to constant literals (strings, numbers, etc.). When a snapshot is executed,
these literals are converted to jerry values and the literal pool entries
are changed to their corresponding jerry value. To support this conversion,
the literals and literal pools are copied into RAM even if the `copy_bytecode`
flag passed to [jerry_exec_snapshot_at](#jerry_exec_snapshot_at) is set to
`false`. This non-negligible memory consumption can be avoided by using
static snapshots. The literals of these snapshots are limited to magic
strings, and 28 bit signed integers, so their constant pools do not need
to be loaded into the memory. Hence these snapshots can be executed from
ROM.
***Important note:*** the magic strings set by
[jerry_register_magic_strings](#jerry_register_magic_strings) must be the
same when the snapshot is generated and executed. Furthermore the
`copy_bytecode` flag of [jerry_exec_snapshot_at](#jerry_exec_snapshot_at)
must be set to `false`.
## jerry_char_t
**Summary**
@ -4923,7 +4951,7 @@ main (void)
# Snapshot functions
## jerry_parse_and_save_snapshot
## jerry_generate_snapshot
**Summary**
@ -4932,26 +4960,28 @@ Generate snapshot from the specified source code.
**Prototype**
```c
size_t
jerry_parse_and_save_snapshot (const jerry_char_t *source_p,
size_t source_size,
bool is_for_global,
bool is_strict,
uint32_t *buffer_p,
size_t buffer_size);
jerry_value_t
jerry_generate_snapshot (const jerry_char_t *resource_name_p,
size_t resource_name_length,
const jerry_char_t *source_p,
size_t source_size,
uint32_t generate_snapshot_opts,
uint32_t *buffer_p,
size_t buffer_size);
```
- `resource_name_p` - resource (file) name of the source code. Currently unused, the debugger may use it in the future.
- `resource_name_length` - length of resource name.
- `source_p` - script source, it must be a valid utf8 string.
- `source_size` - script source size, in bytes.
- `is_for_global` - snapshot would be executed as global (true) or eval (false).
- `is_strict` - strict mode
- `generate_snapshot_opts` - any combination of [jerry_generate_snapshot_opts_t](#jerry_generate_snapshot_opts_t) flags.
- `buffer_p` - buffer to save snapshot to.
- `buffer_size` - the buffer's size.
- return value
- the size of snapshot, if it was generated succesfully (i.e. there are no syntax errors in source
code, buffer size is sufficient, and snapshot support is enabled in current configuration through
JERRY_ENABLE_SNAPSHOT_SAVE)
- 0 otherwise.
- the size of the snapshot as a number value, if it was generated succesfully (i.e. there are no syntax
errors in source code, buffer size is sufficient, and snapshot support is enabled in current configuration
through JERRY_ENABLE_SNAPSHOT_SAVE)
- thrown error, otherwise.
**Example**
@ -4969,12 +4999,17 @@ main (void)
static uint32_t global_mode_snapshot_buffer[256];
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
size_t global_mode_snapshot_size = jerry_parse_and_save_snapshot (code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
true,
false,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
0,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
}
@ -4984,81 +5019,11 @@ main (void)
- [jerry_init](#jerry_init)
- [jerry_cleanup](#jerry_cleanup)
- [jerry_generate_function_snapshot](#jerry_generate_function_snapshot)
- [jerry_exec_snapshot](#jerry_exec_snapshot)
- [jerry_parse_and_save_static_snapshot](#jerry_parse_and_save_static_snapshot)
## jerry_parse_and_save_static_snapshot
**Summary**
Generate static snapshot from the specified source code.
Unlike normal snaphots static snaphots are fully executed from ROM. Not
even their header is loaded into the RAM. However they can only depend
on magic strings and 28 bit integer numbers. Regular expression literals
are not supported as well.
**Prototype**
```c
size_t
jerry_parse_and_save_static_snapshot (const jerry_char_t *source_p,
size_t source_size,
bool is_for_global,
bool is_strict,
uint32_t *buffer_p,
size_t buffer_size);
```
- `source_p` - script source, it must be a valid utf8 string.
- `source_size` - script source size, in bytes.
- `is_for_global` - snapshot would be executed as global (true) or eval (false).
- `is_strict` - strict mode
- `buffer_p` - buffer to save snapshot to.
- `buffer_size` - the buffer's size.
- return value
- the size of snapshot, if it was generated succesfully (i.e. there are no syntax errors in source
code, buffer size is sufficient, only magic strings are used by the snapshot, and snapshot support
is enabled in current configuration through JERRY_ENABLE_SNAPSHOT_SAVE)
- 0 otherwise.
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
static uint32_t global_mode_snapshot_buffer[256];
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string'; }) ();";
size_t global_mode_snapshot_size = jerry_parse_and_save_static_snapshot (code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
true,
false,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
jerry_cleanup ();
}
```
**See also**
- [jerry_init](#jerry_init)
- [jerry_cleanup](#jerry_cleanup)
- [jerry_exec_snapshot](#jerry_exec_snapshot)
- [jerry_parse_and_save_snapshot](#jerry_parse_and_save_snapshot)
## jerry_parse_and_save_function_snapshot
## jerry_generate_function_snapshot
**Summary**
@ -5071,28 +5036,32 @@ passed as separated arguments.
**Prototype**
```c
size_t
jerry_parse_and_save_function_snapshot (const jerry_char_t *source_p,
size_t source_size,
const jerry_char_t *args_p,
size_t args_size,
bool is_strict,
uint32_t *buffer_p,
size_t buffer_size)
jerry_value_t
jerry_generate_function_snapshot (const jerry_char_t *resource_name_p,
size_t resource_name_length,
const jerry_char_t *source_p,
size_t source_size,
const jerry_char_t *args_p,
size_t args_size,
uint32_t generate_snapshot_opts,
uint32_t *buffer_p,
size_t buffer_size)
```
- `resource_name_p` - resource (file) name of the source code. Currently unused, the debugger may use it in the future.
- `resource_name_length` - length of resource name.
- `source_p` - script source, it must be a valid utf8 string.
- `source_size` - script source size, in bytes.
- `args_p` - function arguments, it must be a valid utf8 string.
- `args_size` - function argument size, in bytes.
- `is_strict` - strict mode
- `generate_snapshot_opts` - any combination of [jerry_generate_snapshot_opts_t](#jerry_generate_snapshot_opts_t) flags.
- `buffer_p` - buffer to save snapshot to.
- `buffer_size` - the buffer's size.
- return value
- the size of snapshot, if it was generated succesfully (i.e. there are no syntax errors in source
code, buffer size is sufficient, and snapshot support is enabled in current configuration through
JERRY_ENABLE_SNAPSHOT_SAVE)
- 0 otherwise.
- the size of the snapshot as a number value, if it was generated succesfully (i.e. there are no syntax
errors in source code, buffer size is sufficient, and snapshot support is enabled in current configuration
through JERRY_ENABLE_SNAPSHOT_SAVE)
- thrown error, otherwise.
**Example**
@ -5111,13 +5080,19 @@ main (void)
const jerry_char_t *args_p = (const jerry_char_t *) "a, b";
const jerry_char_t *src_p = (const jerry_char_t *) "return a + b;";
size_t func_snapshot_size = jerry_parse_and_save_function_snapshot (src_p,
strlen ((const char *) src_p),
args_p,
strlen ((const char *) args_p),
false,
func_snapshot_buffer,
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
jerry_value_t generate_result;
generate_result = jerry_generate_function_snapshot (NULL,
0,
src_p,
strlen ((const char *) src_p),
args_p,
strlen ((const char *) args_p),
0,
func_snapshot_buffer,
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
}
@ -5127,83 +5102,8 @@ main (void)
- [jerry_init](#jerry_init)
- [jerry_cleanup](#jerry_cleanup)
- [jerry_generate_snapshot](#jerry_generate_snapshot)
- [jerry_load_function_snapshot_at](#jerry_load_function_snapshot_at)
- [jerry_parse_and_save_static_function_snapshot](#jerry_parse_and_save_static_function_snapshot)
## jerry_parse_and_save_static_function_snapshot
**Summary**
Generate static function snapshot from the specified source code
with the given function body and arguments.
Unlike normal snaphots static snaphots are fully executed from ROM. Not
even their header is loaded into the RAM. However they can only depend
on magic strings and 28 bit integer numbers. Regular expression literals
are not supported as well.
**Prototype**
```c
size_t
jerry_parse_and_save_static_function_snapshot (const jerry_char_t *source_p,
size_t source_size,
const jerry_char_t *args_p,
size_t args_size,
bool is_strict,
uint32_t *buffer_p,
size_t buffer_size)
```
- `source_p` - script source, it must be a valid utf8 string.
- `source_size` - script source size, in bytes.
- `args_p` - function arguments, it must be a valid utf8 string.
- `args_size` - function argument size, in bytes.
- `is_strict` - strict mode
- `buffer_p` - buffer to save snapshot to.
- `buffer_size` - the buffer's size.
- return value
- the size of snapshot, if it was generated succesfully (i.e. there are no syntax errors in source
code, buffer size is sufficient, only magic strings are used by the snapshot, and snapshot support
is enabled in current configuration through JERRY_ENABLE_SNAPSHOT_SAVE)
- 0 otherwise.
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
static uint32_t func_snapshot_buffer[256];
const jerry_char_t *args_p = (const jerry_char_t *) "string, bind";
const jerry_char_t *src_p = (const jerry_char_t *) "return bind(string)";
size_t func_snapshot_size = jerry_parse_and_save_static_function_snapshot (src_p,
strlen ((const char *) src_p),
args_p,
strlen ((const char *) args_p),
false,
func_snapshot_buffer,
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
jerry_cleanup ();
}
```
**See also**
- [jerry_init](#jerry_init)
- [jerry_cleanup](#jerry_cleanup)
- [jerry_load_function_snapshot_at](#jerry_load_function_snapshot_at)
- [jerry_parse_and_save_function_snapshot](#jerry_parse_and_save_function_snapshot)
## jerry_exec_snapshot
@ -5249,12 +5149,19 @@ main (void)
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
jerry_init (JERRY_INIT_EMPTY);
size_t global_mode_snapshot_size = jerry_parse_and_save_snapshot (code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
true,
false,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
0,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
size_t global_mode_snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
jerry_init (JERRY_INIT_EMPTY);
@ -5324,12 +5231,19 @@ main (void)
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
jerry_init (JERRY_INIT_EMPTY);
size_t global_mode_snapshot_size = jerry_parse_and_save_snapshot (code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
true,
false,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
0,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
size_t global_mode_snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
jerry_init (JERRY_INIT_EMPTY);
@ -5402,13 +5316,21 @@ main (void)
const jerry_char_t *src_p = (const jerry_char_t *) "return a + b;";
jerry_init (JERRY_INIT_EMPTY);
size_t snapshot_size = jerry_parse_and_save_function_snapshot (src_p,
strlen ((const char *) src_p),
args_p,
strlen ((const char *) args_p),
false,
snapshot_buffer,
sizeof (snapshot_buffer) / sizeof (uint32_t));
jerry_value_t generate_result;
generate_result = jerry_generate_function_snapshot (NULL,
0,
src_p,
strlen ((const char *) src_p),
args_p,
strlen ((const char *) args_p),
false,
snapshot_buffer,
sizeof (snapshot_buffer) / sizeof (uint32_t));
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
jerry_init (JERRY_INIT_EMPTY);

View File

@ -13,15 +13,16 @@
* limitations under the License.
*/
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-helpers.h"
#include "ecma-lex-env.h"
#include "ecma-literal-storage.h"
#include "jcontext.h"
#include "jerryscript.h"
#include "jerry-snapshot.h"
#include "js-parser.h"
#include "ecma-lex-env.h"
#include "lit-char-helpers.h"
#include "re-compiler.h"
@ -74,7 +75,7 @@ snapshot_check_global_flags (uint32_t global_flags) /**< global flags */
typedef struct
{
size_t snapshot_buffer_write_offset;
bool snapshot_error_occured;
ecma_value_t snapshot_error;
bool regex_found;
} snapshot_globals_t;
@ -110,6 +111,15 @@ snapshot_write_to_buffer_by_offset (uint8_t *buffer_p, /**< buffer */
return true;
} /* snapshot_write_to_buffer_by_offset */
/**
* Maximum snapshot write buffer offset.
*/
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
#define JERRY_SNAPSHOT_MAXIMUM_WRITE_OFFSET (0x7fffff >> 1)
#else
#define JERRY_SNAPSHOT_MAXIMUM_WRITE_OFFSET (UINT32_MAX >> 1)
#endif
/**
* Save snapshot helper.
*
@ -121,16 +131,19 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
size_t snapshot_buffer_size, /**< snapshot buffer size */
snapshot_globals_t *globals_p) /**< snapshot globals */
{
if (globals_p->snapshot_error_occured)
const jerry_char_t *error_buffer_too_small_p = (const jerry_char_t *) "Snapshot buffer too small.";
if (!ecma_is_value_empty (globals_p->snapshot_error))
{
return 0;
}
JERRY_ASSERT ((globals_p->snapshot_buffer_write_offset & (JMEM_ALIGNMENT - 1)) == 0);
if (globals_p->snapshot_buffer_write_offset > (UINT32_MAX >> 1))
if (globals_p->snapshot_buffer_write_offset > JERRY_SNAPSHOT_MAXIMUM_WRITE_OFFSET)
{
globals_p->snapshot_error_occured = true;
const char *error_message_p = "Maximum snapshot size reached.";
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
return 0;
}
@ -147,7 +160,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
/* Regular expression. */
if (globals_p->snapshot_buffer_write_offset + sizeof (ecma_compiled_code_t) > snapshot_buffer_size)
{
globals_p->snapshot_error_occured = true;
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, error_buffer_too_small_p);
return 0;
}
@ -168,11 +181,17 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
buffer_p,
buffer_size))
{
globals_p->snapshot_error_occured = true;
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, error_buffer_too_small_p);
/* cannot return inside ECMA_FINALIZE_UTF8_STRING */
}
ECMA_FINALIZE_UTF8_STRING (buffer_p, buffer_size);
if (!ecma_is_value_empty (globals_p->snapshot_error))
{
return 0;
}
globals_p->regex_found = true;
globals_p->snapshot_buffer_write_offset = JERRY_ALIGNUP (globals_p->snapshot_buffer_write_offset,
JMEM_ALIGNMENT);
@ -197,7 +216,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
compiled_code_p,
((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG))
{
globals_p->snapshot_error_occured = true;
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, error_buffer_too_small_p);
return 0;
}
@ -240,7 +259,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
snapshot_buffer_size,
globals_p);
JERRY_ASSERT (globals_p->snapshot_error_occured || offset > start_offset);
JERRY_ASSERT (!ecma_is_value_empty (globals_p->snapshot_error) || offset > start_offset);
literal_start_p[i] = offset - start_offset;
}
@ -249,6 +268,31 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
return start_offset;
} /* snapshot_add_compiled_code */
/**
* Create unsupported literal error.
*/
static void
static_snapshot_error_unsupported_literal (snapshot_globals_t *globals_p, /**< snapshot globals */
ecma_value_t literal) /**< literal form the literal pool */
{
const char *error_prefix_p = "Unsupported static snapshot literal: ";
ecma_string_t *error_message_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) error_prefix_p,
(lit_utf8_size_t) strlen (error_prefix_p));
literal = ecma_op_to_string (literal);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (literal));
ecma_string_t *literal_string_p = ecma_get_string_from_value (literal);
error_message_p = ecma_concat_ecma_strings (error_message_p, literal_string_p);
ecma_deref_ecma_string (literal_string_p);
ecma_object_t *error_object_p = ecma_new_standard_error_with_message (ECMA_ERROR_RANGE, error_message_p);
ecma_deref_ecma_string (error_message_p);
globals_p->snapshot_error = ecma_create_error_object_reference (error_object_p);
} /* static_snapshot_error_unsupported_literal */
/**
* Save static snapshot helper.
*
@ -260,16 +304,17 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
size_t snapshot_buffer_size, /**< snapshot buffer size */
snapshot_globals_t *globals_p) /**< snapshot globals */
{
if (globals_p->snapshot_error_occured)
if (!ecma_is_value_empty (globals_p->snapshot_error))
{
return 0;
}
JERRY_ASSERT ((globals_p->snapshot_buffer_write_offset & (JMEM_ALIGNMENT - 1)) == 0);
if (globals_p->snapshot_buffer_write_offset >= UINT32_MAX)
if (globals_p->snapshot_buffer_write_offset >= JERRY_SNAPSHOT_MAXIMUM_WRITE_OFFSET)
{
globals_p->snapshot_error_occured = true;
const char *error_message_p = "Maximum snapshot size reached.";
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
return 0;
}
@ -283,7 +328,8 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
{
/* Regular expression literals are not supported. */
globals_p->snapshot_error_occured = true;
const char *error_message_p = "Regular expression literals are not supported.";
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
return 0;
}
@ -293,7 +339,8 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
compiled_code_p,
((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG))
{
globals_p->snapshot_error_occured = true;
const char *error_message_p = "Snapshot buffer too small.";
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
return 0;
}
@ -330,7 +377,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
if (!ecma_is_value_direct (literal_start_p[i])
&& !ecma_is_value_direct_string (literal_start_p[i]))
{
globals_p->snapshot_error_occured = true;
static_snapshot_error_unsupported_literal (globals_p, literal_start_p[i]);
return 0;
}
}
@ -351,7 +398,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
snapshot_buffer_size,
globals_p);
JERRY_ASSERT (globals_p->snapshot_error_occured || offset > start_offset);
JERRY_ASSERT (!ecma_is_value_empty (globals_p->snapshot_error) || offset > start_offset);
literal_start_p[i] = offset - start_offset;
}
@ -366,7 +413,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
{
if (!ecma_is_value_direct_string (literal_start_p[i]))
{
globals_p->snapshot_error_occured = true;
static_snapshot_error_unsupported_literal (globals_p, literal_start_p[i]);
return 0;
}
}
@ -656,33 +703,29 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
/**
* jerry_parse_and_save_snapshot_with_args flags.
*/
typedef enum
{
JERRY_SNAPSHOT_SAVE_STATIC = (1u << 0), /**< static snapshot */
JERRY_SNAPSHOT_SAVE_STRICT = (1u << 1), /**< strict mode code */
JERRY_SNAPSHOT_SAVE_EVAL = (1u << 2), /**< eval context code */
} jerry_parse_and_save_snapshot_flags_t;
/**
* Generate snapshot from specified source and arguments
*
* @return size of snapshot, if it was generated succesfully
* @return size of snapshot (a number value), if it was generated succesfully
* (i.e. there are no syntax errors in source code, buffer size is sufficient,
* and snapshot support is enabled in current configuration through JERRY_ENABLE_SNAPSHOT_SAVE),
* 0 - otherwise.
* error object otherwise
*/
static size_t
jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
const jerry_char_t *args_p, /**< arguments string */
size_t args_size, /**< arguments string size */
uint32_t flags, /**< jerry_parse_and_save_snapshot_flags_t flags */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
static jerry_value_t
jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< script resource name */
size_t resource_name_length, /**< script resource name length */
const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
const jerry_char_t *args_p, /**< arguments string */
size_t args_size, /**< arguments string size */
uint32_t generate_snapshot_opts, /**< jerry_generate_snapshot_opts_t option bits */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
{
/* Currently unused arguments. */
JERRY_UNUSED (resource_name_p);
JERRY_UNUSED (resource_name_length);
snapshot_globals_t globals;
ecma_value_t parse_status;
ecma_compiled_code_t *bytecode_data_p;
@ -690,23 +733,22 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
JMEM_ALIGNMENT);
globals.snapshot_buffer_write_offset = aligned_header_size;
globals.snapshot_error_occured = false;
globals.snapshot_error = ECMA_VALUE_EMPTY;
globals.regex_found = false;
parse_status = parser_parse_script (args_p,
args_size,
source_p,
source_size,
(flags & JERRY_SNAPSHOT_SAVE_STRICT) != 0,
(generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STRICT) != 0,
&bytecode_data_p);
if (ECMA_IS_VALUE_ERROR (parse_status))
{
ecma_free_value (JERRY_CONTEXT (error_value));
return 0;
return ecma_create_error_reference (JERRY_CONTEXT (error_value), true);
}
if (flags & JERRY_SNAPSHOT_SAVE_STATIC)
if (generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC)
{
static_snapshot_add_compiled_code (bytecode_data_p, (uint8_t *) buffer_p, buffer_size, &globals);
}
@ -715,9 +757,9 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
snapshot_add_compiled_code (bytecode_data_p, (uint8_t *) buffer_p, buffer_size, &globals);
}
if (globals.snapshot_error_occured)
if (!ecma_is_value_empty (globals.snapshot_error))
{
return 0;
return globals.snapshot_error;
}
jerry_snapshot_header_t header;
@ -728,15 +770,10 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
header.number_of_funcs = 1;
header.func_offsets[0] = aligned_header_size;
if (flags & JERRY_SNAPSHOT_SAVE_EVAL)
{
header.func_offsets[0] |= JERRY_SNAPSHOT_EVAL_CONTEXT;
}
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
uint32_t literals_num = 0;
if (!(flags & JERRY_SNAPSHOT_SAVE_STATIC))
if (!(generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC))
{
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
@ -750,7 +787,8 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
&literals_num))
{
JERRY_ASSERT (lit_map_p == NULL);
return 0;
const char *error_message_p = "Cannot allocate memory for literals.";
return jerry_create_error (JERRY_ERROR_COMMON, (const jerry_char_t *) error_message_p);
}
jerry_snapshot_set_offsets (buffer_p + (aligned_header_size / sizeof (uint32_t)),
@ -773,92 +811,58 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
ecma_bytecode_deref (bytecode_data_p);
return globals.snapshot_buffer_write_offset;
} /* jerry_parse_and_save_snapshot_with_args */
return ecma_make_number_value ((ecma_number_t) globals.snapshot_buffer_write_offset);
} /* jerry_generate_snapshot_with_args */
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
/**
* Generate snapshot from specified source
* Generate snapshot from specified source and arguments
*
* @return size of snapshot, if it was generated succesfully
* @return size of snapshot (a number value), if it was generated succesfully
* (i.e. there are no syntax errors in source code, buffer size is sufficient,
* and snapshot support is enabled in current configuration through JERRY_ENABLE_SNAPSHOT_SAVE),
* 0 - otherwise.
* error object otherwise
*/
size_t
jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
bool is_for_global, /**< snapshot would be executed as global (true)
* or eval (false) */
bool is_strict, /**< strict mode */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
jerry_value_t
jerry_generate_snapshot (const jerry_char_t *resource_name_p, /**< script resource name */
size_t resource_name_length, /**< script resource name length */
const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
uint32_t generate_snapshot_opts, /**< jerry_generate_snapshot_opts_t option bits */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
{
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
uint32_t flags = (!is_for_global ? JERRY_SNAPSHOT_SAVE_EVAL : 0);
flags |= (is_strict ? JERRY_SNAPSHOT_SAVE_STRICT : 0);
uint32_t allowed_opts = (JERRY_SNAPSHOT_SAVE_STATIC | JERRY_SNAPSHOT_SAVE_STRICT);
return jerry_parse_and_save_snapshot_with_args (source_p,
source_size,
NULL,
0,
flags,
buffer_p,
buffer_size);
if ((generate_snapshot_opts & ~(allowed_opts)) != 0)
{
const char *error_message_p = "Unsupported generate snapshot flags specified.";
return jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
}
return jerry_generate_snapshot_with_args (resource_name_p,
resource_name_length,
source_p,
source_size,
NULL,
0,
generate_snapshot_opts,
buffer_p,
buffer_size);
#else /* !JERRY_ENABLE_SNAPSHOT_SAVE */
JERRY_UNUSED (resource_name_p);
JERRY_UNUSED (resource_name_length);
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
JERRY_UNUSED (is_for_global);
JERRY_UNUSED (is_strict);
JERRY_UNUSED (generate_snapshot_opts);
JERRY_UNUSED (buffer_p);
JERRY_UNUSED (buffer_size);
return 0;
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
} /* jerry_parse_and_save_snapshot */
/**
* Generate static snapshot from specified source
*
* @return size of snapshot, if it was generated succesfully
* (i.e. there are no syntax errors in source code, all static snapshot requirements
* are satisfied, buffer size is sufficient, and snapshot support is enabled in
* current configuration through JERRY_ENABLE_SNAPSHOT_SAVE),
* 0 - otherwise.
*/
size_t
jerry_parse_and_save_static_snapshot (const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
bool is_for_global, /**< snapshot would be executed as global (true)
* or eval (false) */
bool is_strict, /**< strict mode */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
{
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
uint32_t flags = JERRY_SNAPSHOT_SAVE_STATIC;
flags |= (!is_for_global ? JERRY_SNAPSHOT_SAVE_EVAL : 0);
flags |= (is_strict ? JERRY_SNAPSHOT_SAVE_STRICT : 0);
return jerry_parse_and_save_snapshot_with_args (source_p,
source_size,
NULL,
0,
flags,
buffer_p,
buffer_size);
#else /* !JERRY_ENABLE_SNAPSHOT_SAVE */
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
JERRY_UNUSED (is_for_global);
JERRY_UNUSED (is_strict);
JERRY_UNUSED (buffer_p);
JERRY_UNUSED (buffer_size);
return 0;
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
} /* jerry_parse_and_save_static_snapshot */
} /* jerry_generate_snapshot */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
@ -918,7 +922,7 @@ jerry_snapshot_result_at (const uint32_t *snapshot_p, /**< snapshot */
JERRY_ASSERT ((header_p->lit_table_offset % sizeof (uint32_t)) == 0);
uint32_t func_offset = header_p->func_offsets[func_index] & ~JERRY_SNAPSHOT_EVAL_CONTEXT;
uint32_t func_offset = header_p->func_offsets[func_index];
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) (snapshot_data_p + func_offset);
if (bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
@ -957,10 +961,6 @@ jerry_snapshot_result_at (const uint32_t *snapshot_p, /**< snapshot */
}
ret_val = ecma_make_object_value (func_obj_p);
}
else if (header_p->func_offsets[func_index] & JERRY_SNAPSHOT_EVAL_CONTEXT)
{
ret_val = vm_run_eval (bytecode_p, false);
}
else
{
ret_val = vm_run_global (bytecode_p);
@ -1256,7 +1256,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
merged_global_flags |= header_p->global_flags;
uint32_t start_offset = header_p->func_offsets[0] & ~JERRY_SNAPSHOT_EVAL_CONTEXT;
uint32_t start_offset = header_p->func_offsets[0];
const uint8_t *data_p = (const uint8_t *) inp_buffers_p[i];
const uint8_t *literal_base_p = (uint8_t *) (data_p + header_p->lit_table_offset);
@ -1312,7 +1312,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
{
const jerry_snapshot_header_t *current_header_p = (const jerry_snapshot_header_t *) inp_buffers_p[i];
uint32_t start_offset = current_header_p->func_offsets[0] & ~JERRY_SNAPSHOT_EVAL_CONTEXT;
uint32_t start_offset = current_header_p->func_offsets[0];
memcpy (dst_p,
((const uint8_t *) inp_buffers_p[i]) + start_offset,
@ -1781,84 +1781,56 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
} /* jerry_parse_and_save_literals */
/**
* Generate snapshot from specified function source
* Generate snapshot function from specified source and arguments
*
* @return size of snapshot, if it was generated succesfully
* @return size of snapshot (a number value), if it was generated succesfully
* (i.e. there are no syntax errors in source code, buffer size is sufficient,
* and snapshot support is enabled in current configuration through JERRY_ENABLE_SNAPSHOT_SAVE),
* 0 - otherwise.
* error object otherwise
*/
size_t jerry_parse_and_save_function_snapshot (const jerry_char_t *source_p, /**< function body source */
size_t source_size, /**< function body size */
const jerry_char_t *args_p, /**< arguments string */
size_t args_size, /**< arguments string size */
bool is_strict, /**< strict mode */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
jerry_value_t
jerry_generate_function_snapshot (const jerry_char_t *resource_name_p, /**< script resource name */
size_t resource_name_length, /**< script resource name length */
const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
const jerry_char_t *args_p, /**< arguments string */
size_t args_size, /**< arguments string size */
uint32_t generate_snapshot_opts, /**< jerry_generate_snapshot_opts_t option bits */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
{
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
uint32_t flags = (is_strict ? JERRY_SNAPSHOT_SAVE_STRICT : 0);
uint32_t allowed_opts = (JERRY_SNAPSHOT_SAVE_STATIC | JERRY_SNAPSHOT_SAVE_STRICT);
return jerry_parse_and_save_snapshot_with_args (source_p,
source_size,
args_p,
args_size,
flags,
buffer_p,
buffer_size);
if ((generate_snapshot_opts & ~(allowed_opts)) != 0)
{
const char *error_message_p = "Unsupported generate snapshot flags specified.";
return jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
}
return jerry_generate_snapshot_with_args (resource_name_p,
resource_name_length,
source_p,
source_size,
args_p,
args_size,
generate_snapshot_opts,
buffer_p,
buffer_size);
#else /* !JERRY_ENABLE_SNAPSHOT_SAVE */
JERRY_UNUSED (resource_name_p);
JERRY_UNUSED (resource_name_length);
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
JERRY_UNUSED (args_p);
JERRY_UNUSED (args_size);
JERRY_UNUSED (is_strict);
JERRY_UNUSED (generate_snapshot_opts);
JERRY_UNUSED (buffer_p);
JERRY_UNUSED (buffer_size);
return 0;
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
} /* jerry_parse_and_save_function_snapshot */
/**
* Generate static snapshot from specified function source
*
* @return size of snapshot, if it was generated succesfully
* (i.e. there are no syntax errors in source code, all static snapshot requirements
* are satisfied, buffer size is sufficient, and snapshot support is enabled in
* current configuration through JERRY_ENABLE_SNAPSHOT_SAVE),
* 0 - otherwise.
*/
size_t jerry_parse_and_save_static_function_snapshot (const jerry_char_t *source_p, /**< function body source */
size_t source_size, /**< function body size */
const jerry_char_t *args_p, /**< arguments string */
size_t args_size, /**< arguments string size */
bool is_strict, /**< strict mode */
uint32_t *buffer_p, /**< buffer to save snapshot to */
size_t buffer_size) /**< the buffer's size */
{
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
uint32_t flags = JERRY_SNAPSHOT_SAVE_STATIC;
flags |= (is_strict ? JERRY_SNAPSHOT_SAVE_STRICT : 0);
return jerry_parse_and_save_snapshot_with_args (source_p,
source_size,
args_p,
args_size,
flags,
buffer_p,
buffer_size);
#else /* !JERRY_ENABLE_SNAPSHOT_SAVE */
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
JERRY_UNUSED (args_p);
JERRY_UNUSED (args_size);
JERRY_UNUSED (is_strict);
JERRY_UNUSED (buffer_p);
JERRY_UNUSED (buffer_size);
return 0;
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
} /* jerry_parse_and_save_static_function_snapshot */
} /* jerry_generate_function_snapshot */
/**
* Load function from specified snapshot buffer

View File

@ -33,11 +33,6 @@ typedef struct
uint32_t func_offsets[1]; /**< function offsets (lowest bit: global(0) or eval(1) context) */
} jerry_snapshot_header_t;
/**
* Evaluate this function on the top of the scope chain.
*/
#define JERRY_SNAPSHOT_EVAL_CONTEXT 0x1u
/**
* Jerry snapshot magic marker.
*/
@ -46,7 +41,7 @@ typedef struct
/**
* Jerry snapshot format version.
*/
#define JERRY_SNAPSHOT_VERSION (10u)
#define JERRY_SNAPSHOT_VERSION (11u)
/**
* Snapshot configuration flags.

View File

@ -27,13 +27,27 @@ extern "C"
* @{
*/
/**
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
*/
typedef enum
{
JERRY_SNAPSHOT_SAVE_STATIC = (1u << 0), /**< static snapshot */
JERRY_SNAPSHOT_SAVE_STRICT = (1u << 1), /**< strict mode code */
} jerry_generate_snapshot_opts_t;
/**
* Snapshot functions.
*/
size_t jerry_parse_and_save_snapshot (const jerry_char_t *source_p, size_t source_size, bool is_for_global,
bool is_strict, uint32_t *buffer_p, size_t buffer_size);
size_t jerry_parse_and_save_static_snapshot (const jerry_char_t *source_p, size_t source_size, bool is_for_global,
bool is_strict, uint32_t *buffer_p, size_t buffer_size);
jerry_value_t jerry_generate_snapshot (const jerry_char_t *resource_name_p, size_t resource_name_length,
const jerry_char_t *source_p, size_t source_size,
uint32_t generate_snapshot_opts, uint32_t *buffer_p, size_t buffer_size);
jerry_value_t jerry_generate_function_snapshot (const jerry_char_t *resource_name_p, size_t resource_name_length,
const jerry_char_t *source_p, size_t source_size,
const jerry_char_t *args_p, size_t args_size,
uint32_t generate_snapshot_opts, uint32_t *buffer_p,
size_t buffer_size);
jerry_value_t jerry_exec_snapshot (const uint32_t *snapshot_p, size_t snapshot_size, bool copy_bytecode);
jerry_value_t jerry_exec_snapshot_at (const uint32_t *snapshot_p, size_t snapshot_size,
size_t func_index, bool copy_bytecode);
@ -41,13 +55,6 @@ size_t jerry_merge_snapshots (const uint32_t **inp_buffers_p, size_t *inp_buffer
uint32_t *out_buffer_p, size_t out_buffer_size, const char **error_p);
size_t jerry_parse_and_save_literals (const jerry_char_t *source_p, size_t source_size, bool is_strict,
uint32_t *buffer_p, size_t buffer_size, bool is_c_format);
size_t jerry_parse_and_save_function_snapshot (const jerry_char_t *source_p, size_t source_size,
const jerry_char_t *args_p, size_t args_size,
bool is_strict, uint32_t *buffer_p, size_t buffer_size);
size_t jerry_parse_and_save_static_function_snapshot (const jerry_char_t *source_p, size_t source_size,
const jerry_char_t *args_p, size_t args_size,
bool is_strict, uint32_t *buffer_p, size_t buffer_size);
jerry_value_t jerry_load_function_snapshot_at (const uint32_t *function_snapshot_p,
const size_t function_snapshot_size,
size_t func_index,

View File

@ -13,6 +13,7 @@
* limitations under the License.
*/
#include <assert.h>
#include <string.h>
#include "jerryscript.h"
@ -120,6 +121,42 @@ read_file (uint8_t *input_pos_p, /**< next position in the input buffer */
return bytes_read;
} /* read_file */
/**
* Print error value
*/
static void
print_unhandled_exception (jerry_value_t error_value) /**< error value */
{
assert (!jerry_value_has_error_flag (error_value));
jerry_value_t err_str_val = jerry_value_to_string (error_value);
if (jerry_value_has_error_flag (err_str_val))
{
/* Avoid recursive error throws. */
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: [value cannot be converted to string]\n");
jerry_release_value (err_str_val);
return;
}
jerry_size_t err_str_size = jerry_get_string_size (err_str_val);
if (err_str_size >= 256)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: [value cannot be converted to string]\n");
jerry_release_value (err_str_val);
return;
}
jerry_char_t err_str_buf[256];
jerry_size_t string_end = jerry_string_to_char_buffer (err_str_val, err_str_buf, err_str_size);
assert (string_end == err_str_size);
err_str_buf[string_end] = 0;
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: %s\n", (char *) err_str_buf);
jerry_release_value (err_str_val);
} /* print_unhandled_exception */
/**
* Generate command line option IDs
*/
@ -127,7 +164,6 @@ typedef enum
{
OPT_GENERATE_HELP,
OPT_GENERATE_STATIC,
OPT_GENERATE_CONTEXT,
OPT_GENERATE_LITERAL_LIST,
OPT_GENERATE_LITERAL_C,
OPT_GENERATE_SHOW_OP,
@ -143,10 +179,6 @@ static const cli_opt_t generate_opts[] =
.help = "print this help and exit"),
CLI_OPT_DEF (.id = OPT_GENERATE_STATIC, .opt = "s", .longopt = "static",
.help = "generate static snapshot"),
CLI_OPT_DEF (.id = OPT_GENERATE_CONTEXT, .opt = "c", .longopt = "context",
.meta = "MODE",
.help = "specify the execution context of the snapshot: "
"global or eval (default: global)."),
CLI_OPT_DEF (.id = OPT_GENERATE_LITERAL_LIST, .longopt = "save-literals-list-format",
.meta = "FILE",
.help = "export literals found in parsed JS input (in list format)"),
@ -174,14 +206,13 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
(void) argc;
bool is_save_literals_mode_in_c_format = false;
bool is_snapshot_mode_for_global = true;
uint32_t snapshot_flags = 0;
jerry_init_flag_t flags = JERRY_INIT_EMPTY;
uint32_t number_of_files = 0;
const char *file_name_p = NULL;
uint8_t *source_p = input_buffer;
size_t source_length = 0;
const char *save_literals_file_name_p = NULL;
bool static_snapshot = false;
cli_change_opts (cli_state_p, generate_opts);
@ -196,31 +227,7 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
}
case OPT_GENERATE_STATIC:
{
static_snapshot = true;
break;
}
case OPT_GENERATE_CONTEXT:
{
const char *mode_str_p = cli_consume_string (cli_state_p);
if (cli_state_p->error != NULL)
{
break;
}
if (!strcmp ("global", mode_str_p))
{
is_snapshot_mode_for_global = true;
}
else if (!strcmp ("eval", mode_str_p))
{
is_snapshot_mode_for_global = false;
}
else
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Incorrect argument for context mode: %s\n", mode_str_p);
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
snapshot_flags |= JERRY_SNAPSHOT_SAVE_STATIC;
break;
}
case OPT_GENERATE_LITERAL_LIST:
@ -252,7 +259,13 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
}
case CLI_OPT_DEFAULT:
{
const char *file_name_p = cli_consume_string (cli_state_p);
if (file_name_p != NULL)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
file_name_p = cli_consume_string (cli_state_p);
if (cli_state_p->error == NULL)
{
@ -263,8 +276,6 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Input file is empty\n");
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
number_of_files++;
}
break;
}
@ -281,7 +292,7 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
if (number_of_files != 1)
if (file_name_p == NULL)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
return JERRY_STANDALONE_EXIT_CODE_FAIL;
@ -295,33 +306,31 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
size_t snapshot_size;
jerry_value_t snapshot_result;
if (static_snapshot)
{
snapshot_size = jerry_parse_and_save_static_snapshot ((jerry_char_t *) source_p,
source_length,
is_snapshot_mode_for_global,
false,
output_buffer,
sizeof (output_buffer) / sizeof (uint32_t));
}
else
{
snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) source_p,
source_length,
is_snapshot_mode_for_global,
false,
output_buffer,
sizeof (output_buffer) / sizeof (uint32_t));
}
snapshot_result = jerry_generate_snapshot ((jerry_char_t *) file_name_p,
(size_t) strlen (file_name_p),
(jerry_char_t *) source_p,
source_length,
snapshot_flags,
output_buffer,
sizeof (output_buffer) / sizeof (uint32_t));
if (snapshot_size == 0)
if (jerry_value_has_error_flag (snapshot_result))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n");
jerry_value_clear_error_flag (&snapshot_result);
print_unhandled_exception (snapshot_result);
jerry_release_value (snapshot_result);
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
size_t snapshot_size = (size_t) jerry_get_number_value (snapshot_result);
jerry_release_value (snapshot_result);
FILE *snapshot_file_p = fopen (output_file_name_p, "w");
if (snapshot_file_p == NULL)
{

View File

@ -97,13 +97,13 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
{
const char msg[] = "[Error message too long]";
err_str_size = sizeof (msg) / sizeof (char) - 1;
memcpy (err_str_buf, msg, err_str_size);
memcpy (err_str_buf, msg, err_str_size + 1);
}
else
{
jerry_size_t sz = jerry_string_to_char_buffer (err_str_val, err_str_buf, err_str_size);
assert (sz == err_str_size);
err_str_buf[err_str_size] = 0;
jerry_size_t string_end = jerry_string_to_char_buffer (err_str_val, err_str_buf, err_str_size);
assert (string_end == err_str_size);
err_str_buf[string_end] = 0;
if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES)
&& jerry_get_error_type (error_value) == JERRY_ERROR_SYNTAX)
@ -112,7 +112,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
unsigned int err_col = 0;
/* 1. parse column and line information */
for (jerry_size_t i = 0; i < sz; i++)
for (jerry_size_t i = 0; i < string_end; i++)
{
if (!strncmp ((char *) (err_str_buf + i), "[line: ", 7))
{
@ -121,7 +121,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
char num_str[8];
unsigned int j = 0;
while (i < sz && err_str_buf[i] != ',')
while (i < string_end && err_str_buf[i] != ',')
{
num_str[j] = (char) err_str_buf[i];
j++;
@ -139,7 +139,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
i += 10;
j = 0;
while (i < sz && err_str_buf[i] != ']')
while (i < string_end && err_str_buf[i] != ']')
{
num_str[j] = (char) err_str_buf[i];
j++;

View File

@ -62,14 +62,22 @@ static void test_function_snapshot (void)
const char *code_to_snapshot_p = "return a + b";
jerry_init (flags);
size_t function_snapshot_size = jerry_parse_and_save_function_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
(jerry_char_t *) args_p,
strlen (args_p),
false,
function_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (function_snapshot_size != 0);
jerry_value_t generate_result;
generate_result = jerry_generate_function_snapshot (NULL,
0,
(const jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
(jerry_char_t *) args_p,
strlen (args_p),
0,
function_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
&& jerry_value_is_number (generate_result));
size_t function_snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
jerry_init (flags);
@ -122,8 +130,8 @@ static void test_function_arguments_snapshot (void)
if (jerry_is_feature_enabled (JERRY_FEATURE_SNAPSHOT_SAVE)
&& jerry_is_feature_enabled (JERRY_FEATURE_SNAPSHOT_EXEC))
{
static uint32_t global_arguments_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
static uint32_t eval_arguments_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
static uint32_t arguments_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
const char *code_to_snapshot_p = ("function f(a,b,c) {"
" arguments[0]++;"
" arguments[1]++;"
@ -132,30 +140,26 @@ static void test_function_arguments_snapshot (void)
"}"
"f(3,4,5);");
jerry_init (JERRY_INIT_EMPTY);
size_t global_mode_snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
true,
false,
global_arguments_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (global_mode_snapshot_size != 0);
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
(jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
0,
arguments_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
&& jerry_value_is_number (generate_result));
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
jerry_init (JERRY_INIT_EMPTY);
size_t eval_mode_snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
false,
false,
eval_arguments_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (eval_mode_snapshot_size != 0);
jerry_cleanup ();
arguments_test_exec_snapshot (eval_arguments_snapshot_buffer, eval_mode_snapshot_size, false);
arguments_test_exec_snapshot (eval_arguments_snapshot_buffer, eval_mode_snapshot_size, true);
arguments_test_exec_snapshot (global_arguments_snapshot_buffer, global_mode_snapshot_size, false);
arguments_test_exec_snapshot (global_arguments_snapshot_buffer, global_mode_snapshot_size, true);
arguments_test_exec_snapshot (arguments_snapshot_buffer, snapshot_size, false);
arguments_test_exec_snapshot (arguments_snapshot_buffer, snapshot_size, true);
}
} /* test_function_arguments_snapshot */
@ -188,8 +192,7 @@ static void test_exec_snapshot (uint32_t *snapshot_p, size_t snapshot_size, bool
int
main (void)
{
static uint32_t global_mode_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
static uint32_t eval_mode_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
static uint32_t snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
TEST_INIT ();
@ -200,18 +203,24 @@ main (void)
const char *code_to_snapshot_p = "(function () { return 'string from snapshot'; }) ();";
jerry_init (JERRY_INIT_EMPTY);
size_t global_mode_snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
true,
false,
global_mode_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (global_mode_snapshot_size != 0);
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
(const jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
0,
snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
&& jerry_value_is_number (generate_result));
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
/* Check the snapshot data. Unused bytes should be filled with zeroes */
const uint8_t expected_data[] =
{
0x4A, 0x52, 0x52, 0x59, 0x0A, 0x00, 0x00, 0x00,
0x4A, 0x52, 0x52, 0x59, 0x0B, 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,
@ -224,36 +233,13 @@ main (void)
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)));
TEST_ASSERT (sizeof (expected_data) == snapshot_size);
TEST_ASSERT (0 == memcmp (expected_data, snapshot_buffer, sizeof (expected_data)));
jerry_cleanup ();
jerry_init (JERRY_INIT_EMPTY);
size_t eval_mode_snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
false,
false,
eval_mode_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (eval_mode_snapshot_size != 0);
jerry_cleanup ();
test_exec_snapshot (global_mode_snapshot_buffer,
global_mode_snapshot_size,
false);
test_exec_snapshot (global_mode_snapshot_buffer,
global_mode_snapshot_size,
true);
test_exec_snapshot (eval_mode_snapshot_buffer,
eval_mode_snapshot_size,
false);
test_exec_snapshot (eval_mode_snapshot_buffer,
eval_mode_snapshot_size,
true);
test_exec_snapshot (snapshot_buffer, snapshot_size, false);
test_exec_snapshot (snapshot_buffer, snapshot_size, true);
}
/* Static snapshot */
@ -271,19 +257,23 @@ main (void)
sizeof (magic_string_lengths) / sizeof (jerry_length_t),
magic_string_lengths);
size_t global_mode_snapshot_size = jerry_parse_and_save_static_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
true,
false,
global_mode_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (global_mode_snapshot_size != 0);
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
(jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
JERRY_SNAPSHOT_SAVE_STATIC,
snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
&& jerry_value_is_number (generate_result));
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
test_exec_snapshot (global_mode_snapshot_buffer,
global_mode_snapshot_size,
false);
test_exec_snapshot (snapshot_buffer, snapshot_size, false);
}
/* Merge snapshot */
@ -298,25 +288,38 @@ main (void)
const char *code_to_snapshot_p = "123";
jerry_init (JERRY_INIT_EMPTY);
snapshot_sizes[0] = jerry_parse_and_save_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
true,
false,
snapshot_buffer_0,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (snapshot_sizes[0] != 0);
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
(const jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
0,
snapshot_buffer_0,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
&& jerry_value_is_number (generate_result));
snapshot_sizes[0] = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
code_to_snapshot_p = "456";
jerry_init (JERRY_INIT_EMPTY);
snapshot_sizes[1] = jerry_parse_and_save_snapshot ((jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
true,
false,
snapshot_buffer_1,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (snapshot_sizes[1] != 0);
generate_result = jerry_generate_snapshot (NULL,
0,
(const jerry_char_t *) code_to_snapshot_p,
strlen (code_to_snapshot_p),
0,
snapshot_buffer_1,
SNAPSHOT_BUFFER_SIZE);
TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
&& jerry_value_is_number (generate_result));
snapshot_sizes[1] = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
jerry_cleanup ();
jerry_init (JERRY_INIT_EMPTY);

View File

@ -148,8 +148,8 @@ do
# Testing snapshot
SNAPSHOT_TEMP=`mktemp $(basename -s .js $test).snapshot.XXXXXXXXXX`
cmd_line="${SNAPSHOT_TOOL#$ROOT_DIR} generate --context global -o $SNAPSHOT_TEMP ${full_test#$ROOT_DIR}"
$TIMEOUT_CMD $TIMEOUT $SNAPSHOT_TOOL generate --context global -o $SNAPSHOT_TEMP $full_test &> $ENGINE_TEMP
cmd_line="${SNAPSHOT_TOOL#$ROOT_DIR} generate -o $SNAPSHOT_TEMP ${full_test#$ROOT_DIR}"
$TIMEOUT_CMD $TIMEOUT $SNAPSHOT_TOOL generate -o $SNAPSHOT_TEMP $full_test &> $ENGINE_TEMP
status_code=$?
if [ $status_code -eq 0 ]