Support parsing of scripts / functions stored in string values (#4728)

Function arguments must be passed as string values.
Snapshots are generated from compiled code rather than source code.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2021-08-11 17:37:12 +02:00 committed by GitHub
parent b7dead7b05
commit 3ed93cfb51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 601 additions and 696 deletions

View File

@ -243,6 +243,7 @@ Option bits for [jerry_parse_options_t](#jerry_parse_options_t).
- JERRY_PARSE_NO_OPTS - No options passed
- JERRY_PARSE_STRICT_MODE - Enable strict mode
- JERRY_PARSE_MODULE - Parse source as an ECMAScript module
- JERRY_PARSE_HAS_ARGUMENT_LIST - `argument_list` field is valid
- JERRY_PARSE_HAS_RESOURCE - `resource_name` field is valid
- JERRY_PARSE_HAS_START - `start_line` and `start_column` fields are valid
- JERRY_PARSE_HAS_USER_VALUE - `user_value` field is valid
@ -278,8 +279,7 @@ List of backtrace frame types returned by
## jerry_generate_snapshot_opts_t
Flags for [jerry_generate_snapshot](#jerry_generate_snapshot) and
[jerry_generate_function_snapshot](#jerry_generate_function_snapshot) functions:
Flags for [jerry_generate_snapshot](#jerry_generate_snapshot):
- JERRY_SNAPSHOT_SAVE_STATIC - generate static snapshot (see below)
@ -540,8 +540,7 @@ Enum that contains the flags of property descriptors.
**Summary**
Various configuration options for parsing functions such as [jerry_parse](#jerry_parse)
or [jerry_parse_function](#jerry_parse_function)
Various configuration options for parsing functions such as [jerry_parse](#jerry_parse).
**Prototype**
@ -549,9 +548,11 @@ or [jerry_parse_function](#jerry_parse_function)
typedef struct
{
uint32_t options; /**< combination of jerry_parse_option_enable_feature_t values */
jerry_value_t argument_list; /**< function argument list if JERRY_PARSE_HAS_ARGUMENT_LIST is set in options
* Note: must be string value */
jerry_value_t resource_name; /**< resource name string (usually a file name)
* if JERRY_PARSE_HAS_RESOURCE is set in options
* Note: non-string values are ignored */
* Note: must be string value */
uint32_t start_line; /**< start line of the source code if JERRY_PARSE_HAS_START is set in options */
uint32_t start_column; /**< start column of the source code if JERRY_PARSE_HAS_START is set in options */
jerry_value_t user_value; /**< user value assigned to all functions created by this script including eval
@ -564,9 +565,7 @@ typedef struct
**See also**
- [jerry_parse](#jerry_parse)
- [jerry_parse_function](#jerry_parse_function)
- [jerry_generate_snapshot](#jerry_generate_snapshot)
- [jerry_generate_function_snapshot](#jerry_generate_function_snapshot)
- [jerry_exec_snapshot](#jerry_exec_snapshot)
- [jerry_parse_option_enable_feature_t](#jerry_parse_option_enable_feature_t)
@ -1696,9 +1695,7 @@ main (void)
**Summary**
Parse script and construct an EcmaScript function. The lexical environment is
set to the global lexical environment. The resource name can be used by
debugging systems to provide line / backtrace info.
Parse a script, module, or function and create a compiled code using a character string.
*Note*: Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
@ -1734,6 +1731,7 @@ main (void)
{
jerry_init (JERRY_INIT_EMPTY);
/* Parsing a script. */
const jerry_char_t script[] = "print ('Hello, World!');";
jerry_parse_options_t parse_options;
@ -1745,6 +1743,89 @@ main (void)
jerry_value_t parsed_code = jerry_parse (script, sizeof (script) - 1, &parse_options);
jerry_release_value (parse_options.resource_name);
jerry_release_value (jerry_run (parsed_code));
jerry_release_value (parsed_code);
/* Parsing a function. */
parse_options.options = JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_string ((const jerry_char_t *) "a, b");
const jerry_char_t function_code[] = "return a + b;";
jerry_value_t parsed_function = jerry_parse (function_code, sizeof (function_code) - 1, &parse_options);
jerry_release_value (parse_options.argument_list);
jerry_value_t args[] = {
jerry_create_number (3),
jerry_create_number (4),
};
jerry_size_t argc = sizeof (args) / sizeof (args[0]);
jerry_release_value (jerry_call_function (parsed_function,
jerry_create_undefined(),
args,
argc));
jerry_release_value (parsed_function);
jerry_cleanup ();
return 0;
}
```
**See also**
- [jerry_parse_value](#jerry_parse_value)
- [jerry_run](#jerry_run)
- [jerry_parse_options_t](#jerry_parse_options_t)
## jerry_parse_value
**Summary**
Parse a script, module, or function and create a compiled code using a string value.
*Note*: Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
**Prototype**
```c
jerry_value_t
jerry_parse_value (const jerry_value_t source_value,
const jerry_parse_options_t *options_p);
```
- `source_value` - string value, containing source code to parse (only string values are accepted).
- `options_p` - additional parsing options, can be NULL if not used
- return value
- function object value, if script was parsed successfully,
- thrown error, otherwise
*New in version [[NEXT_RELEASE]]*.
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t script_value = jerry_create_string ((const jerry_char_t *) "print ('Hello, World!');");
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_STRICT_MODE | JERRY_PARSE_HAS_RESOURCE | JERRY_PARSE_HAS_START;
parse_options.resource_name = jerry_create_string ((const jerry_char_t *) "hello.js");
/* This example script is extracted from the middle of a file. */
parse_options.start_line = 10;
parse_options.start_column = 1;
jerry_value_t parsed_code = jerry_parse_value (script_value, &parse_options);
jerry_release_value (parse_options.resource_name);
jerry_release_value (script_value);
jerry_release_value (parsed_code);
jerry_cleanup ();
@ -1754,120 +1835,10 @@ main (void)
**See also**
- [jerry_parse](#jerry_parse)
- [jerry_run](#jerry_run)
- [jerry_parse_function](#jerry_parse_function)
- [jerry_parse_options_t](#jerry_parse_options_t)
## jerry_parse_function
**Summary**
Parse function source code and construct an ECMAScript
function. The function arguments and function body are
passed as separated arguments. The lexical environment
is set to the global lexical environment. The resource
name (usually a file name) is also passed to this function
which is used by the debugger to find the source code.
*Note*: The returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
**Prototype**
```c
jerry_value_t
jerry_parse_function (const jerry_char_t *arg_list_p,
size_t arg_list_size,
const jerry_char_t *source_p,
size_t source_size,
const jerry_parse_options_t *options_p);
```
- `arg_list_p` - argument list of the function (must be a valid UTF8 string).
- `arg_list_size` - size of the argument list, in bytes.
- `source_p` - string, containing source code to parse (must be a valid UTF8 string).
- `source_size` - size of the string, in bytes.
- `options_p` - additional parsing options, can be NULL if not used
- return value
- function object value, if script was parsed successfully,
- thrown error, otherwise
*New in version 2.0*.
*Changed in version [[NEXT_RELEASE]]*: The `resource_name_p`, `resource_name_length`, and `parse_opts` arguments are replaced by `options_p`.
**Example**
[doctest]: # (name="02.API-REFERENCE-parse-func.c")
```c
#include <stdio.h>
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
int return_value = 1;
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Parse the 'function (a,b) { return a + b; }' function */
const char function_args[] = "a, b";
const char function_source[] = "return a + b";
jerry_value_t parsed_function = jerry_parse_function ((const jerry_char_t *) function_args,
strlen (function_args),
(const jerry_char_t *) function_source,
strlen (function_source),
NULL);
if (!jerry_value_is_error (parsed_function))
{
/* Run the parsed function */
jerry_value_t args[] = {
jerry_create_number (3),
jerry_create_number (55),
};
jerry_size_t argc = sizeof (args) / sizeof (args[0]);
jerry_value_t ret_value = jerry_call_function (parsed_function,
jerry_create_undefined(),
args,
argc);
/* Process result value */
if (jerry_value_is_number (ret_value)) {
double value = jerry_get_number_value (ret_value);
printf ("Function result: %lf\n", value);
return_value = !(value == (3 + 55));
}
/* Release the function arguments */
for (jerry_size_t idx = 0; idx < argc; idx++) {
jerry_release_value (args[idx]);
}
/* Returned value must be freed */
jerry_release_value (ret_value);
}
/* Parsed function must be freed */
jerry_release_value (parsed_function);
/* Cleanup engine */
jerry_cleanup ();
return return_value;
}
```
**See also**
- [jerry_call_function](#jerry_call_function)
- [jerry_parse_options_t](#jerry_parse_options_t)
## jerry_run
**Summary**
@ -10429,17 +10400,13 @@ Generate snapshot from the specified source code.
```c
jerry_value_t
jerry_generate_snapshot (const jerry_char_t *source_p,
size_t source_size,
const jerry_parse_options_t *options_p,
jerry_generate_snapshot (jerry_value_t compiled_code,
uint32_t generate_snapshot_opts,
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.
- `options_p` - additional parsing options, can be NULL if not used
- `compiled_code` - compiled script or function (see: [jerry_parse](#jerry_parse)).
- `generate_snapshot_opts` - any combination of [jerry_generate_snapshot_opts_t](#jerry_generate_snapshot_opts_t) flags.
- `buffer_p` - output buffer (aligned to 4 bytes) to save snapshot to.
- `buffer_size` - the output buffer's size in bytes.
@ -10450,7 +10417,10 @@ jerry_generate_snapshot (const jerry_char_t *source_p,
- thrown error, otherwise.
*New in version 2.0*.
*Changed in version [[NEXT_RELEASE]]*: The `resource_name_p`, and `resource_name_length` arguments are replaced by `options_p`.
*Changed in version [[NEXT_RELEASE]]*: The `source_p`, `source_size`, `resource_name_p`,
and `resource_name_length` arguments are replaced by `compiled_code`
which should contain a compiled ECMAScript script / function.
**Example**
@ -10467,13 +10437,16 @@ main (void)
static uint32_t global_mode_snapshot_buffer[256];
const jerry_char_t script_to_snapshot[] = "(function () { return 'string from snapshot'; }) ();";
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (script_to_snapshot,
sizeof (script_to_snapshot) - 1,
NULL,
0,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
jerry_value_t parse_result = jerry_parse (script_to_snapshot,
sizeof (script_to_snapshot) - 1,
NULL);
size_t buffer_size = sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t);
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
global_mode_snapshot_buffer,
buffer_size);
jerry_release_value (parse_result);
if (!jerry_value_is_error (generate_result))
{
@ -10489,107 +10462,12 @@ main (void)
**See also**
- [jerry_init](#jerry_init)
- [jerry_cleanup](#jerry_cleanup)
- [jerry_generate_function_snapshot](#jerry_generate_function_snapshot)
- [jerry_parse](#jerry_parse)
- [jerry_parse_value](#jerry_parse_value)
- [jerry_exec_snapshot](#jerry_exec_snapshot)
- [jerry_parse_options_t](#jerry_parse_options_t)
## jerry_generate_function_snapshot
**Summary**
Generate function snapshot from the specified source code
with the given arguments.
The function arguments and function body are
passed as separated arguments.
*Notes*:
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
- This API depends on a build option (`JERRY_SNAPSHOT_SAVE`) and can be checked in runtime with
the `JERRY_FEATURE_SNAPSHOT_SAVE` feature enum value, see [jerry_is_feature_enabled](#jerry_is_feature_enabled).
If the feature is not enabled the function will return an error.
**Prototype**
```c
jerry_value_t
jerry_generate_function_snapshot (const jerry_char_t *source_p,
size_t source_size,
const jerry_char_t *args_p,
size_t args_size,
const jerry_parse_options_t *options_p,
uint32_t generate_snapshot_opts,
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.
- `options_p` - additional parsing options, can be NULL if not used
- `generate_snapshot_opts` - any combination of [jerry_generate_snapshot_opts_t](#jerry_generate_snapshot_opts_t) flags.
- `buffer_p` - buffer (aligned to 4 bytes) to save snapshot to.
- `buffer_size` - the buffer's size in bytes.
- return value
- the size of the generated snapshot in bytes as 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_SNAPSHOT_SAVE)
- thrown error, otherwise.
*New in version 2.0*.
*Changed in version [[NEXT_RELEASE]]*: The `resource_name_p`, and `resource_name_length` arguments are replaced by `options_p`.
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
static uint32_t func_snapshot_buffer[256];
const jerry_char_t args[] = "a, b";
const jerry_char_t src[] = "return a + b;";
jerry_value_t generate_result;
generate_result = jerry_generate_function_snapshot (src,
sizeof (src) - 1,
args,
sizeof (args) - 1,
NULL,
0,
func_snapshot_buffer,
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
if (!jerry_value_is_error (generate_result))
{
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
}
jerry_release_value (generate_result);
jerry_cleanup ();
return 0;
}
```
**See also**
- [jerry_init](#jerry_init)
- [jerry_cleanup](#jerry_cleanup)
- [jerry_generate_snapshot](#jerry_generate_snapshot)
- [jerry_parse_options_t](#jerry_parse_options_t)
## jerry_exec_snapshot
**Summary**
@ -10645,13 +10523,17 @@ main (void)
const jerry_char_t script_to_snapshot[] = "(function () { return 'string from snapshot'; }) ();";
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (script_to_snapshot,
sizeof (script_to_snapshot) - 1,
NULL,
0,
snapshot_buffer,
sizeof (snapshot_buffer) / sizeof (uint32_t));
jerry_value_t parse_result = jerry_parse (script_to_snapshot,
sizeof (script_to_snapshot) - 1,
NULL);
size_t buffer_size = sizeof (snapshot_buffer) / sizeof (uint32_t);
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
snapshot_buffer,
buffer_size);
jerry_release_value (parse_result);
/* 'generate_result' variable should be checked whether it contains an error. */
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
@ -10689,18 +10571,24 @@ main (void)
/* 2nd example: function snapshot. */
jerry_init (JERRY_INIT_EMPTY);
const jerry_char_t function_to_snapshot_args[] = "a, b";
const jerry_char_t function_to_snapshot[] = "return a + b;";
jerry_value_t generate_result;
generate_result = jerry_generate_function_snapshot (function_to_snapshot,
sizeof (function_to_snapshot) - 1,
function_to_snapshot_args,
sizeof (function_to_snapshot_args) - 1,
NULL,
0,
snapshot_buffer,
sizeof (snapshot_buffer) / sizeof (uint32_t));
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_string ((const jerry_char_t *) "a, b");
jerry_value_t parse_result = jerry_parse (function_to_snapshot,
sizeof (function_to_snapshot) - 1,
&parse_options);
size_t buffer_size = sizeof (snapshot_buffer) / sizeof (uint32_t);
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
snapshot_buffer,
buffer_size);
jerry_release_value (parse_result);
jerry_release_value (parse_options.argument_list);
/* 'generate_result' variable should be checked whether it contains an error. */
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
@ -10740,7 +10628,6 @@ main (void)
- [jerry_init](#jerry_init)
- [jerry_cleanup](#jerry_cleanup)
- [jerry_generate_snapshot](#jerry_generate_snapshot)
- [jerry_generate_function_snapshot](#jerry_generate_function_snapshot)
## jerry_get_literals_from_snapshot
@ -10795,12 +10682,17 @@ main (void)
static uint32_t snapshot_buffer[256];
const jerry_char_t script_for_literal_save[] = "var obj = { a:'aa', bb:'Bb' }";
jerry_value_t generate_result = jerry_generate_snapshot (script_for_literal_save,
sizeof (script_for_literal_save) - 1,
NULL,
jerry_value_t parse_result = jerry_parse (script_for_literal_save,
sizeof (script_for_literal_save) - 1,
NULL);
size_t buffer_size = sizeof (snapshot_buffer) / sizeof (uint32_t);
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
snapshot_buffer,
256);
buffer_size);
jerry_release_value (parse_result);
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
jerry_release_value (generate_result);
@ -11667,9 +11559,7 @@ main (void)
**See also**
- [jerry_parse](#jerry_parse)
- [jerry_parse_function](#jerry_parse_function)
- [jerry_generate_snapshot](#jerry_generate_snapshot)
- [jerry_generate_function_snapshot](#jerry_generate_function_snapshot)
- [jerry_exec_snapshot](#jerry_exec_snapshot)

View File

@ -134,7 +134,7 @@ snapshot_write_to_buffer_by_offset (uint8_t *buffer_p, /**< buffer */
* @return start offset
*/
static uint32_t
snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled code */
snapshot_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< compiled code */
uint8_t *snapshot_buffer_p, /**< snapshot buffer */
size_t snapshot_buffer_size, /**< snapshot buffer size */
snapshot_globals_t *globals_p) /**< snapshot globals */
@ -328,7 +328,7 @@ static_snapshot_error_unsupported_literal (snapshot_globals_t *globals_p, /**< s
* @return start offset
*/
static uint32_t
static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled code */
static_snapshot_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< compiled code */
uint8_t *snapshot_buffer_p, /**< snapshot buffer */
size_t snapshot_buffer_size, /**< snapshot buffer size */
snapshot_globals_t *globals_p) /**< snapshot globals */
@ -750,8 +750,6 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
#endif /* JERRY_SNAPSHOT_EXEC */
#if JERRY_SNAPSHOT_SAVE
/**
* Generate snapshot from specified source and arguments
*
@ -760,28 +758,54 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
* and snapshot support is enabled in current configuration through JERRY_SNAPSHOT_SAVE),
* error object otherwise
*/
static jerry_value_t
jerry_generate_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 */
const jerry_parse_options_t *options_p, /**< parsing options,
* can be NULL if not used */
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 */
jerry_value_t
jerry_generate_snapshot (jerry_value_t compiled_code, /**< parsed script or function */
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 */
{
#if JERRY_SNAPSHOT_SAVE
uint32_t allowed_options = JERRY_SNAPSHOT_SAVE_STATIC;
uint32_t allowed_parse_options = (JERRY_PARSE_STRICT_MODE
| JERRY_PARSE_HAS_RESOURCE
| JERRY_PARSE_HAS_START);
if ((generate_snapshot_opts & ~allowed_options) != 0
|| (options_p != NULL && (options_p->options & ~allowed_parse_options) != 0))
if ((generate_snapshot_opts & ~allowed_options) != 0)
{
return jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) ecma_error_snapshot_flag_not_supported);
}
const ecma_compiled_code_t *bytecode_data_p = NULL;
if (ecma_is_value_object (compiled_code))
{
ecma_object_t *object_p = ecma_get_object_from_value (compiled_code);
if (ecma_object_class_is (object_p, ECMA_OBJECT_CLASS_SCRIPT))
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, ext_object_p->u.cls.u3.value);
}
else if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
JERRY_ASSERT (!ecma_get_object_is_builtin (object_p));
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
uint16_t type = CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags);
if (type != CBC_FUNCTION_NORMAL)
{
bytecode_data_p = NULL;
}
}
}
if (JERRY_UNLIKELY (bytecode_data_p == NULL))
{
return jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) ECMA_ERR_MSG ("Unsupported compiled code"));
}
snapshot_globals_t globals;
const uint32_t aligned_header_size = JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t),
JMEM_ALIGNMENT);
@ -791,21 +815,6 @@ jerry_generate_snapshot_with_args (const jerry_char_t *source_p, /**< script sou
globals.regex_found = false;
globals.class_found = false;
uint32_t status_flags = ECMA_PARSE_NO_OPTS;
if (options_p != NULL)
{
status_flags |= (options_p->options & ECMA_PARSE_STRICT_MODE);
}
ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = parser_parse_script (args_p, args_size, source_p, source_size, status_flags, options_p);
if (JERRY_UNLIKELY (bytecode_data_p == NULL))
{
return ecma_create_error_reference_from_context ();
}
if (generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC)
{
static_snapshot_add_compiled_code (bytecode_data_p, (uint8_t *) buffer_p, buffer_size, &globals);
@ -817,7 +826,6 @@ jerry_generate_snapshot_with_args (const jerry_char_t *source_p, /**< script sou
if (!ecma_is_value_empty (globals.snapshot_error))
{
ecma_bytecode_deref (bytecode_data_p);
return globals.snapshot_error;
}
@ -846,7 +854,6 @@ jerry_generate_snapshot_with_args (const jerry_char_t *source_p, /**< script sou
&literals_num))
{
JERRY_ASSERT (lit_map_p == NULL);
ecma_bytecode_deref (bytecode_data_p);
return jerry_create_error (JERRY_ERROR_COMMON, (const jerry_char_t *) ecma_error_cannot_allocate_memory_literals);
}
@ -868,43 +875,9 @@ jerry_generate_snapshot_with_args (const jerry_char_t *source_p, /**< script sou
jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t));
}
ecma_bytecode_deref (bytecode_data_p);
return ecma_make_number_value ((ecma_number_t) globals.snapshot_buffer_write_offset);
} /* jerry_generate_snapshot_with_args */
#endif /* JERRY_SNAPSHOT_SAVE */
/**
* Generate snapshot from specified source and arguments
*
* @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_SNAPSHOT_SAVE),
* error object otherwise
*/
jerry_value_t
jerry_generate_snapshot (const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
const jerry_parse_options_t *options_p, /**< parsing options,
* can be NULL if not used */
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 */
{
#if JERRY_SNAPSHOT_SAVE
return jerry_generate_snapshot_with_args (source_p,
source_size,
NULL,
0,
options_p,
generate_snapshot_opts,
buffer_p,
buffer_size);
#else /* !JERRY_SNAPSHOT_SAVE */
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
JERRY_UNUSED (options_p);
JERRY_UNUSED (compiled_code);
JERRY_UNUSED (generate_snapshot_opts);
JERRY_UNUSED (buffer_p);
JERRY_UNUSED (buffer_size);
@ -1815,45 +1788,3 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
return 0;
#endif /* JERRY_SNAPSHOT_SAVE */
} /* jerry_get_literals_from_snapshot */
/**
* Generate snapshot function from specified source and arguments
*
* @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_SNAPSHOT_SAVE),
* error object otherwise
*/
jerry_value_t
jerry_generate_function_snapshot (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 */
const jerry_parse_options_t *options_p, /**< parsing options,
* can be NULL if not used */
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 */
{
#if JERRY_SNAPSHOT_SAVE
return jerry_generate_snapshot_with_args (source_p,
source_size,
args_p,
args_size,
options_p,
generate_snapshot_opts,
buffer_p,
buffer_size);
#else /* !JERRY_SNAPSHOT_SAVE */
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
JERRY_UNUSED (args_p);
JERRY_UNUSED (args_size);
JERRY_UNUSED (options_p);
JERRY_UNUSED (generate_snapshot_opts);
JERRY_UNUSED (buffer_p);
JERRY_UNUSED (buffer_size);
return jerry_create_error (JERRY_ERROR_COMMON, (const jerry_char_t *) "Snapshot save is not supported");
#endif /* JERRY_SNAPSHOT_SAVE */
} /* jerry_generate_function_snapshot */

View File

@ -376,34 +376,43 @@ jerry_run_simple (const jerry_char_t *script_source_p, /**< script source */
return result;
} /* jerry_run_simple */
#if JERRY_PARSER
/**
* Parse script and construct an EcmaScript function. The lexical
* environment is set to the global lexical environment.
* Common code for parsing a script, module, or function.
*
* @return function object value - if script was parsed successfully,
* thrown error - otherwise
*/
jerry_value_t
jerry_parse (const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
const jerry_parse_options_t *options_p) /**< parsing options, can be NULL if not used */
static jerry_value_t
jerry_parse_common (void *source_p, /**< script source */
const jerry_parse_options_t *options_p, /**< parsing options, can be NULL if not used */
uint32_t parse_opts) /**< internal parsing options */
{
#if JERRY_PARSER
jerry_assert_api_available ();
uint32_t allowed_parse_options = (JERRY_PARSE_STRICT_MODE
| JERRY_PARSE_MODULE
| JERRY_PARSE_HAS_RESOURCE
| JERRY_PARSE_HAS_START
| JERRY_PARSE_HAS_USER_VALUE);
if (options_p != NULL && (options_p->options & ~allowed_parse_options) != 0)
if (options_p != NULL)
{
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
}
#endif /* JERRY_PARSER */
const uint32_t allowed_options = (JERRY_PARSE_STRICT_MODE
| JERRY_PARSE_MODULE
| JERRY_PARSE_HAS_ARGUMENT_LIST
| JERRY_PARSE_HAS_RESOURCE
| JERRY_PARSE_HAS_START
| JERRY_PARSE_HAS_USER_VALUE);
uint32_t options = options_p->options;
#if JERRY_DEBUGGER && JERRY_PARSER
if ((options & ~allowed_options) != 0
|| ((options_p->options & JERRY_PARSE_HAS_ARGUMENT_LIST)
&& ((options_p->options & JERRY_PARSE_MODULE)
|| !ecma_is_value_string (options_p->argument_list)))
|| ((options_p->options & JERRY_PARSE_HAS_RESOURCE)
&& !ecma_is_value_string (options_p->resource_name)))
{
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
}
}
#if JERRY_DEBUGGER
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& options_p != NULL
&& (options_p->options & JERRY_PARSE_HAS_RESOURCE)
@ -418,10 +427,7 @@ jerry_parse (const jerry_char_t *source_p, /**< script source */
resource_name_size);
ECMA_FINALIZE_UTF8_STRING (resource_name_start_p, resource_name_size);
}
#endif /* JERRY_DEBUGGER && JERRY_PARSER */
#if JERRY_PARSER
uint32_t parse_opts = 0;
#endif /* JERRY_DEBUGGER */
if (options_p != NULL)
{
@ -438,7 +444,7 @@ jerry_parse (const jerry_char_t *source_p, /**< script source */
}
ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = parser_parse_script (NULL, 0, source_p, source_size, parse_opts, options_p);
bytecode_data_p = parser_parse_script (source_p, parse_opts, options_p);
if (JERRY_UNLIKELY (bytecode_data_p == NULL))
{
@ -464,6 +470,22 @@ jerry_parse (const jerry_char_t *source_p, /**< script source */
}
#endif /* JERRY_MODULE_SYSTEM */
if (JERRY_UNLIKELY (options_p != NULL
&& (options_p->options & JERRY_PARSE_HAS_ARGUMENT_LIST)))
{
ecma_object_t *global_object_p = ecma_builtin_get_global ();
#if JERRY_BUILTIN_REALMS
JERRY_ASSERT (global_object_p == (ecma_object_t *) ecma_op_function_get_realm (bytecode_data_p));
#endif /* JERRY_BUILTIN_REALMS */
ecma_object_t *lex_env_p = ecma_get_global_environment (global_object_p);
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p);
ecma_bytecode_deref (bytecode_data_p);
return ecma_make_object_value (func_obj_p);
}
ecma_object_t *object_p = ecma_create_object (NULL, sizeof (ecma_extended_object_t), ECMA_OBJECT_TYPE_CLASS);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
@ -471,6 +493,27 @@ jerry_parse (const jerry_char_t *source_p, /**< script source */
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.cls.u3.value, bytecode_data_p);
return ecma_make_object_value (object_p);
} /* jerry_parse_common */
#endif /* JERRY_PARSER */
/**
* Parse a script, module, or function and create a compiled code using a character string
*
* @return function object value - if script was parsed successfully,
* thrown error - otherwise
*/
jerry_value_t
jerry_parse (const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
const jerry_parse_options_t *options_p) /**< parsing options, can be NULL if not used */
{
#if JERRY_PARSER
parser_source_char_t source_char;
source_char.source_p = source_p;
source_char.source_size = source_size;
return jerry_parse_common ((void *) &source_char, options_p, JERRY_PARSE_NO_OPTS);
#else /* !JERRY_PARSER */
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
@ -481,93 +524,32 @@ jerry_parse (const jerry_char_t *source_p, /**< script source */
} /* jerry_parse */
/**
* Parse function and construct an EcmaScript function. The lexical
* environment is set to the global lexical environment.
* Parse a script, module, or function and create a compiled code using a string value
*
* @return function object value - if script was parsed successfully,
* thrown error - otherwise
*/
jerry_value_t
jerry_parse_function (const jerry_char_t *arg_list_p, /**< script source */
size_t arg_list_size, /**< script source size */
const jerry_char_t *source_p, /**< script source */
size_t source_size, /**< script source size */
const jerry_parse_options_t *options_p) /**< parsing options, can be NULL if not used */
jerry_parse_value (const jerry_value_t source_value, /**< script source */
const jerry_parse_options_t *options_p) /**< parsing options, can be NULL if not used */
{
#if JERRY_PARSER
jerry_assert_api_available ();
uint32_t allowed_parse_options = (JERRY_PARSE_STRICT_MODE
| JERRY_PARSE_HAS_RESOURCE
| JERRY_PARSE_HAS_START
| JERRY_PARSE_HAS_USER_VALUE);
if (options_p != NULL && (options_p->options & ~allowed_parse_options) != 0)
if (!ecma_is_value_string (source_value))
{
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
}
#endif /* JERRY_PARSER */
#if JERRY_DEBUGGER && JERRY_PARSER
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& options_p != NULL
&& (options_p->options & JERRY_PARSE_HAS_RESOURCE)
&& ecma_is_value_string (options_p->resource_name))
{
ECMA_STRING_TO_UTF8_STRING (ecma_get_string_from_value (options_p->resource_name),
resource_name_start_p,
resource_name_size);
jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME,
JERRY_DEBUGGER_NO_SUBTYPE,
resource_name_start_p,
resource_name_size);
ECMA_FINALIZE_UTF8_STRING (resource_name_start_p, resource_name_size);
}
#endif /* JERRY_DEBUGGER && JERRY_PARSER */
ecma_value_t source[1];
source[0] = source_value;
#if JERRY_PARSER
uint32_t parse_opts = 0;
if (options_p != NULL)
{
parse_opts |= options_p->options & JERRY_PARSE_STRICT_MODE;
}
if (arg_list_p == NULL)
{
/* Must not be a NULL value. */
arg_list_p = (const jerry_char_t *) "";
}
ecma_compiled_code_t *bytecode_p;
bytecode_p = parser_parse_script (arg_list_p, arg_list_size, source_p, source_size, parse_opts, options_p);
if (JERRY_UNLIKELY (bytecode_p == NULL))
{
return ecma_create_error_reference_from_context ();
}
ecma_object_t *global_object_p = ecma_builtin_get_global ();
#if JERRY_BUILTIN_REALMS
JERRY_ASSERT (global_object_p == (ecma_object_t *) ecma_op_function_get_realm (bytecode_p));
#endif /* JERRY_BUILTIN_REALMS */
ecma_object_t *lex_env_p = ecma_get_global_environment (global_object_p);
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_p);
ecma_bytecode_deref (bytecode_p);
return ecma_make_object_value (func_obj_p);
return jerry_parse_common ((void *) source, options_p, ECMA_PARSE_HAS_SOURCE_VALUE);
#else /* !JERRY_PARSER */
JERRY_UNUSED (arg_list_p);
JERRY_UNUSED (arg_list_size);
JERRY_UNUSED (source_p);
JERRY_UNUSED (source_size);
JERRY_UNUSED (source_value);
JERRY_UNUSED (options_p);
return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG (ecma_error_parser_not_supported_p)));
#endif /* JERRY_PARSER */
} /* jerry_parse_function */
} /* jerry_parse_value */
/**
* Run a Script or Module created by jerry_parse.
@ -632,9 +614,11 @@ jerry_eval (const jerry_char_t *source_p, /**< source code */
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
}
return jerry_return (ecma_op_eval_chars_buffer ((const lit_utf8_byte_t *) source_p,
source_size,
parse_opts));
parser_source_char_t source_char;
source_char.source_p = source_p;
source_char.source_size = source_size;
return jerry_return (ecma_op_eval_chars_buffer ((void *) &source_char, parse_opts));
} /* jerry_eval */
/**

View File

@ -548,7 +548,11 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
memcpy (&chain_index, eval_string_p, sizeof (uint32_t));
uint32_t parse_opts = ECMA_PARSE_DIRECT_EVAL | (chain_index << ECMA_PARSE_CHAIN_INDEX_SHIFT);
ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p + 5, eval_string_size - 5, parse_opts);
parser_source_char_t source_char;
source_char.source_p = eval_string_p + 5;
source_char.source_size = eval_string_size - 5;
ecma_value_t result = ecma_op_eval_chars_buffer ((void *) &source_char, parse_opts);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
if (!ECMA_IS_VALUE_ERROR (result))

View File

@ -115,12 +115,20 @@ typedef enum
ECMA_PARSE_ALLOW_NEW_TARGET = (1u << 8), /**< allow new.target access */
ECMA_PARSE_FUNCTION_CONTEXT = (1u << 9), /**< function context is present (ECMA_PARSE_DIRECT_EVAL must be set) */
ECMA_PARSE_GENERATOR_FUNCTION = (1u << 10), /**< generator function is parsed */
ECMA_PARSE_ASYNC_FUNCTION = (1u << 11), /**< async function is parsed */
ECMA_PARSE_HAS_SOURCE_VALUE = (1u << 10), /**< source_p points to a value list
* and the first value is the source code */
ECMA_PARSE_HAS_ARGUMENT_LIST_VALUE = (1u << 11), /**< source_p points to a value list
* and the second value is the argument list */
#if JERRY_ESNEXT
ECMA_PARSE_GENERATOR_FUNCTION = (1u << 12), /**< generator function is parsed */
ECMA_PARSE_ASYNC_FUNCTION = (1u << 13), /**< async function is parsed */
#endif /* JERRY_ESNEXT */
/* These flags are internally used by the parser. */
ECMA_PARSE_INTERNAL_FREE_SOURCE = (1u << 14), /**< free source_p data */
ECMA_PARSE_INTERNAL_FREE_ARG_LIST = (1u << 15), /**< free arg_list_p data */
#if JERRY_ESNEXT
ECMA_PARSE_INTERNAL_PRE_SCANNING = (1u << 12),
ECMA_PARSE_INTERNAL_PRE_SCANNING = (1u << 16), /**< the parser is in pre-scanning mode */
#endif /* JERRY_ESNEXT */
#ifndef JERRY_NDEBUG
/**

View File

@ -714,7 +714,7 @@ ecma_snapshot_get_literal (const uint8_t *literal_base_p, /**< literal start */
* @return pointer to the beginning of the serializable ecma-values
*/
ecma_value_t *
ecma_snapshot_resolve_serializable_values (ecma_compiled_code_t *compiled_code_p, /**< compiled code */
ecma_snapshot_resolve_serializable_values (const ecma_compiled_code_t *compiled_code_p, /**< compiled code */
uint8_t *bytecode_end_p) /**< end of the bytecode */
{
ecma_value_t *base_p = (ecma_value_t *) bytecode_end_p;

View File

@ -59,7 +59,7 @@ bool ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, uint32_t *b
ecma_value_t
ecma_snapshot_get_literal (const uint8_t *literal_base_p, ecma_value_t literal_value);
ecma_value_t *
ecma_snapshot_resolve_serializable_values (ecma_compiled_code_t *compiled_code_p, uint8_t *byte_code_end_p);
ecma_snapshot_resolve_serializable_values (const ecma_compiled_code_t *compiled_code_p, uint8_t *byte_code_end_p);
#endif /* JERRY_SNAPSHOT_EXEC || JERRY_SNAPSHOT_SAVE */
/**

View File

@ -107,7 +107,7 @@ ecma_builtin_global_object_eval (ecma_value_t x) /**< routine's first argument *
#endif /* JERRY_ESNEXT */
/* steps 2 to 8 */
return ecma_op_eval (ecma_get_string_from_value (x), parse_opts);
return ecma_op_eval (x, parse_opts);
} /* ecma_builtin_global_object_eval */
/**

View File

@ -41,28 +41,18 @@
* @return ecma value
*/
ecma_value_t
ecma_op_eval (ecma_string_t *code_p, /**< code string */
ecma_op_eval (ecma_value_t source_code, /**< source code */
uint32_t parse_opts) /**< ecma_parse_opts_t option bits */
{
ecma_value_t ret_value;
JERRY_ASSERT (ecma_is_value_string (source_code));
lit_utf8_size_t chars_num = ecma_string_get_size (code_p);
if (chars_num == 0)
if (ecma_is_value_magic_string (source_code, LIT_MAGIC_STRING__EMPTY))
{
ret_value = ECMA_VALUE_UNDEFINED;
}
else
{
ECMA_STRING_TO_UTF8_STRING (code_p, code_utf8_buffer_p, code_utf8_buffer_size);
ret_value = ecma_op_eval_chars_buffer (code_utf8_buffer_p,
chars_num,
parse_opts);
ECMA_FINALIZE_UTF8_STRING (code_utf8_buffer_p, code_utf8_buffer_size);
return ECMA_VALUE_UNDEFINED;
}
return ret_value;
return ecma_op_eval_chars_buffer ((void *) &source_code,
parse_opts | ECMA_PARSE_HAS_SOURCE_VALUE);
} /* ecma_op_eval */
/**
@ -75,12 +65,11 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
* @return ecma value
*/
ecma_value_t
ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, /**< code characters buffer */
size_t code_buffer_size, /**< size of the buffer */
ecma_op_eval_chars_buffer (void *source_p, /**< source code */
uint32_t parse_opts) /**< ecma_parse_opts_t option bits */
{
#if JERRY_PARSER
JERRY_ASSERT (code_p != NULL);
JERRY_ASSERT (source_p != NULL);
uint32_t is_strict_call = ECMA_PARSE_STRICT_MODE | ECMA_PARSE_DIRECT_EVAL;
@ -95,12 +84,7 @@ ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, /**< code characters b
ECMA_CLEAR_LOCAL_PARSE_OPTS ();
#endif /* JERRY_ESNEXT */
ecma_compiled_code_t *bytecode_p = parser_parse_script (NULL,
0,
code_p,
code_buffer_size,
parse_opts,
NULL);
ecma_compiled_code_t *bytecode_p = parser_parse_script (source_p, parse_opts, NULL);
if (JERRY_UNLIKELY (bytecode_p == NULL))
{

View File

@ -26,10 +26,10 @@
*/
ecma_value_t
ecma_op_eval (ecma_string_t *code_p, uint32_t parse_opts);
ecma_op_eval (ecma_value_t source_code, uint32_t parse_opts);
ecma_value_t
ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, size_t code_buffer_size, uint32_t parse_opts);
ecma_op_eval_chars_buffer (void *source_p, uint32_t parse_opts);
/**
* @}

View File

@ -454,18 +454,14 @@ ecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p, /**< argu
function_body_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
}
ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size);
ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size);
ecma_value_t source[2];
source[0] = ecma_make_string_value (function_body_str_p);
source[1] = ecma_make_string_value (arguments_str_p);
ecma_compiled_code_t *bytecode_p = parser_parse_script (arguments_buffer_p,
arguments_buffer_size,
function_body_buffer_p,
function_body_buffer_size,
parse_opts,
NULL);
parse_opts |= ECMA_PARSE_HAS_SOURCE_VALUE | ECMA_PARSE_HAS_ARGUMENT_LIST_VALUE;
ecma_compiled_code_t *bytecode_p = parser_parse_script ((void *) source, parse_opts, NULL);
ECMA_FINALIZE_UTF8_STRING (function_body_buffer_p, function_body_buffer_size);
ECMA_FINALIZE_UTF8_STRING (arguments_buffer_p, arguments_buffer_size);
ecma_deref_ecma_string (arguments_str_p);
ecma_deref_ecma_string (function_body_str_p);

View File

@ -46,9 +46,7 @@ bool jerry_get_memory_stats (jerry_heap_stats_t *out_stats_p);
bool jerry_run_simple (const jerry_char_t *script_source_p, size_t script_source_size, jerry_init_flag_t flags);
jerry_value_t jerry_parse (const jerry_char_t *source_p, size_t source_size,
const jerry_parse_options_t *options_p);
jerry_value_t jerry_parse_function (const jerry_char_t *arg_list_p, size_t arg_list_size,
const jerry_char_t *source_p, size_t source_size,
const jerry_parse_options_t *options_p);
jerry_value_t jerry_parse_value (const jerry_value_t source_value, const jerry_parse_options_t *options_p);
jerry_value_t jerry_run (const jerry_value_t func_val);
jerry_value_t jerry_eval (const jerry_char_t *source_p, size_t source_size, uint32_t parse_opts);

View File

@ -70,14 +70,8 @@ typedef struct
/**
* Snapshot functions.
*/
jerry_value_t jerry_generate_snapshot (const jerry_char_t *source_p, size_t source_size,
const jerry_parse_options_t *options_p, uint32_t generate_snapshot_opts,
jerry_value_t jerry_generate_snapshot (jerry_value_t compiled_code, uint32_t generate_snapshot_opts,
uint32_t *buffer_p, size_t buffer_size);
jerry_value_t jerry_generate_function_snapshot (const jerry_char_t *source_p, size_t source_size,
const jerry_char_t *args_p, size_t args_size,
const jerry_parse_options_t *options_p,
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,
size_t func_index, uint32_t exec_snapshot_opts,

View File

@ -167,9 +167,10 @@ typedef enum
JERRY_PARSE_NO_OPTS = 0, /**< no options passed */
JERRY_PARSE_STRICT_MODE = (1 << 0), /**< enable strict mode */
JERRY_PARSE_MODULE = (1 << 1), /**< parse source as an ECMAScript module */
JERRY_PARSE_HAS_RESOURCE = (1 << 2), /**< resource_name field is valid */
JERRY_PARSE_HAS_START = (1 << 3), /**< start_line and start_column fields are valid */
JERRY_PARSE_HAS_USER_VALUE = (1 << 4), /**< user_value field is valid */
JERRY_PARSE_HAS_ARGUMENT_LIST = (1 << 2), /**< argument_list field is valid */
JERRY_PARSE_HAS_RESOURCE = (1 << 3), /**< resource_name field is valid */
JERRY_PARSE_HAS_START = (1 << 4), /**< start_line and start_column fields are valid */
JERRY_PARSE_HAS_USER_VALUE = (1 << 5), /**< user_value field is valid */
} jerry_parse_option_enable_feature_t;
/**
@ -178,9 +179,11 @@ typedef enum
typedef struct
{
uint32_t options; /**< combination of jerry_parse_option_enable_feature_t values */
jerry_value_t argument_list; /**< function argument list if JERRY_PARSE_HAS_ARGUMENT_LIST is set in options
* Note: must be string value */
jerry_value_t resource_name; /**< resource name string (usually a file name)
* if JERRY_PARSE_HAS_RESOURCE is set in options
* Note: non-string values are ignored */
* Note: must be string value */
uint32_t start_line; /**< start line of the source code if JERRY_PARSE_HAS_START is set in options */
uint32_t start_column; /**< start column of the source code if JERRY_PARSE_HAS_START is set in options */
jerry_value_t user_value; /**< user value assigned to all functions created by this script including eval

View File

@ -567,6 +567,10 @@ typedef struct
parser_saved_context_t *last_context_p; /**< last saved context */
parser_stack_iterator_t last_statement; /**< last statement position */
cbc_script_t *script_p; /**< current script */
const uint8_t *source_start_p; /**< source start */
lit_utf8_size_t source_size; /**< source size */
const uint8_t *arguments_start_p; /**< function argument list start */
lit_utf8_size_t arguments_size; /**< function argument list size */
ecma_value_t script_value; /**< current script as value */
ecma_value_t user_value; /**< current user value */
@ -853,8 +857,7 @@ bool scanner_literal_is_created (parser_context_t *context_p, uint16_t literal_i
bool scanner_literal_exists (parser_context_t *context_p, uint16_t literal_index);
#endif /* JERRY_ESNEXT */
void scanner_scan_all (parser_context_t *context_p, const uint8_t *arg_list_p, const uint8_t *arg_list_end_p,
const uint8_t *source_p, const uint8_t *source_end_p);
void scanner_scan_all (parser_context_t *context_p);
/**
* @}

View File

@ -1761,10 +1761,7 @@ JERRY_STATIC_ASSERT (PARSER_SCANNING_SUCCESSFUL == PARSER_HAS_LATE_LIT_INIT,
* @return compiled code
*/
static ecma_compiled_code_t *
parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
size_t arg_list_size, /**< size of function argument list */
const uint8_t *source_p, /**< valid UTF-8 source code */
size_t source_size, /**< size of the source code */
parser_parse_source (void *source_p, /**< source code */
uint32_t parse_opts, /**< ecma_parse_opts_t option bits */
const jerry_parse_options_t *options_p) /**< additional configuration options */
{
@ -1775,6 +1772,16 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
context.status_flags = parse_opts & PARSER_STRICT_MODE_MASK;
context.global_status_flags = parse_opts;
#if JERRY_ESNEXT
context.status_flags |= PARSER_RESTORE_STATUS_FLAGS (parse_opts);
context.tagged_template_literal_cp = JMEM_CP_NULL;
#endif /* JERRY_ESNEXT */
context.stack_depth = 0;
context.stack_limit = 0;
context.options_p = options_p;
context.arguments_start_p = NULL;
context.arguments_size = 0;
#if JERRY_MODULE_SYSTEM
if (context.global_status_flags & ECMA_PARSE_MODULE)
{
@ -1784,8 +1791,23 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
context.module_names_p = NULL;
#endif /* JERRY_MODULE_SYSTEM */
if (arg_list_p != NULL)
ecma_value_t argument_list = ECMA_VALUE_EMPTY;
if (context.options_p != NULL
&& (context.options_p->options & JERRY_PARSE_HAS_ARGUMENT_LIST))
{
argument_list = context.options_p->argument_list;
}
else if (context.global_status_flags & ECMA_PARSE_HAS_ARGUMENT_LIST_VALUE)
{
JERRY_ASSERT (context.global_status_flags & ECMA_PARSE_HAS_SOURCE_VALUE);
argument_list = ((ecma_value_t *) source_p)[1];
}
if (argument_list != ECMA_VALUE_EMPTY)
{
JERRY_ASSERT (ecma_is_value_string (argument_list));
context.status_flags |= PARSER_IS_FUNCTION;
#if JERRY_ESNEXT
if (parse_opts & ECMA_PARSE_GENERATOR_FUNCTION)
@ -1797,20 +1819,49 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
context.status_flags |= PARSER_IS_ASYNC_FUNCTION;
}
#endif /* JERRY_ESNEXT */
ecma_string_t *string_p = ecma_get_string_from_value (argument_list);
uint8_t flags = ECMA_STRING_FLAG_EMPTY;
context.arguments_start_p = ecma_string_get_chars (string_p, &context.arguments_size, NULL, NULL, &flags);
if (flags & ECMA_STRING_FLAG_MUST_BE_FREED)
{
context.global_status_flags |= ECMA_PARSE_INTERNAL_FREE_ARG_LIST;
}
}
#if JERRY_ESNEXT
context.status_flags |= PARSER_RESTORE_STATUS_FLAGS (parse_opts);
context.tagged_template_literal_cp = JMEM_CP_NULL;
#endif /* JERRY_ESNEXT */
if (!(context.global_status_flags & ECMA_PARSE_HAS_SOURCE_VALUE))
{
context.source_start_p = ((parser_source_char_t *) source_p)->source_p;
context.source_size = (lit_utf8_size_t) ((parser_source_char_t *) source_p)->source_size;
}
else
{
ecma_value_t source = ((ecma_value_t *) source_p)[0];
context.stack_depth = 0;
context.stack_limit = 0;
context.options_p = options_p;
context.last_context_p = NULL;
context.last_statement.current_p = NULL;
context.token.flags = 0;
lexer_init_line_info (&context);
JERRY_ASSERT (ecma_is_value_string (source));
ecma_string_t *string_p = ecma_get_string_from_value (source);
uint8_t flags = ECMA_STRING_FLAG_EMPTY;
context.source_start_p = ecma_string_get_chars (string_p, &context.source_size, NULL, NULL, &flags);
if (flags & ECMA_STRING_FLAG_MUST_BE_FREED)
{
context.global_status_flags |= ECMA_PARSE_INTERNAL_FREE_SOURCE;
}
}
#if JERRY_DEBUGGER
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
{
jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE,
JERRY_DEBUGGER_NO_SUBTYPE,
context.source_start_p,
context.source_size);
}
#endif /* JERRY_DEBUGGER */
context.user_value = ECMA_VALUE_EMPTY;
@ -1862,9 +1913,10 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
ecma_value_t resource_name = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
if (context.options_p != NULL
&& (context.options_p->options & JERRY_PARSE_HAS_RESOURCE)
&& ecma_is_value_string (context.options_p->resource_name))
&& (context.options_p->options & JERRY_PARSE_HAS_RESOURCE))
{
JERRY_ASSERT (ecma_is_value_string (context.options_p->resource_name));
ecma_ref_ecma_string (ecma_get_string_from_value (context.options_p->resource_name));
resource_name = context.options_p->resource_name;
}
@ -1878,6 +1930,11 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
ECMA_SET_INTERNAL_VALUE_POINTER (context.script_value, context.script_p);
context.last_context_p = NULL;
context.last_statement.current_p = NULL;
context.token.flags = 0;
lexer_init_line_info (&context);
scanner_info_t scanner_info_end;
scanner_info_end.next_p = NULL;
scanner_info_end.source_p = NULL;
@ -1929,16 +1986,12 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
if (context.is_show_opcodes)
{
JERRY_DEBUG_MSG ("\n--- %s parsing start ---\n\n",
(arg_list_p == NULL) ? "Script"
: "Function");
(context.arguments_start_p == NULL) ? "Script"
: "Function");
}
#endif /* JERRY_PARSER_DUMP_BYTE_CODE */
scanner_scan_all (&context,
arg_list_p,
arg_list_p + arg_list_size,
source_p,
source_p + source_size);
scanner_scan_all (&context);
if (JERRY_UNLIKELY (context.error != PARSER_ERR_NO_ERROR))
{
@ -1950,15 +2003,15 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
return NULL;
}
if (arg_list_p == NULL)
if (context.arguments_start_p == NULL)
{
context.source_p = source_p;
context.source_end_p = source_p + source_size;
context.source_p = context.source_start_p;
context.source_end_p = context.source_start_p + context.source_size;
}
else
{
context.source_p = arg_list_p;
context.source_end_p = arg_list_p + arg_list_size;
context.source_p = context.arguments_start_p;
context.source_end_p = context.arguments_start_p + context.arguments_size;
}
context.u.allocated_buffer_p = NULL;
@ -1989,15 +2042,15 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
* lexer_next_token() must be immediately called. */
lexer_next_token (&context);
if (arg_list_p != NULL)
if (context.arguments_start_p != NULL)
{
parser_parse_function_arguments (&context, LEXER_EOS);
JERRY_ASSERT (context.next_scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS);
scanner_release_next (&context, sizeof (scanner_info_t));
context.source_p = source_p;
context.source_end_p = source_p + source_size;
context.source_p = context.source_start_p;
context.source_end_p = context.source_start_p + context.source_size;
lexer_init_line_info (&context);
lexer_next_token (&context);
@ -2016,7 +2069,7 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
#endif /* JERRY_MODULE_SYSTEM */
else
{
JERRY_ASSERT (context.next_scanner_info_p->source_p == source_p
JERRY_ASSERT (context.next_scanner_info_p->source_p == context.source_start_p
&& context.next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
#if JERRY_ESNEXT
@ -2059,7 +2112,7 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
&& context.stack.first_p->next_p == NULL
&& context.stack.last_p == NULL);
JERRY_ASSERT (arg_list_p != NULL || !(context.status_flags & PARSER_ARGUMENTS_NEEDED));
JERRY_ASSERT (context.arguments_start_p != NULL || !(context.status_flags & PARSER_ARGUMENTS_NEEDED));
context.script_p->refs_and_type -= CBC_SCRIPT_REF_ONE;
@ -2072,8 +2125,8 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
if (context.is_show_opcodes)
{
JERRY_DEBUG_MSG ("\n%s parsing successfully completed. Total byte code size: %d bytes\n",
(arg_list_p == NULL) ? "Script"
: "Function",
(context.arguments_start_p == NULL) ? "Script"
: "Function",
(int) context.total_byte_code_size);
}
#endif /* JERRY_PARSER_DUMP_BYTE_CODE */
@ -2122,13 +2175,23 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
if (context.is_show_opcodes)
{
JERRY_DEBUG_MSG ("\n--- %s parsing end ---\n\n",
(arg_list_p == NULL) ? "Script"
: "Function");
(context.arguments_start_p == NULL) ? "Script"
: "Function");
}
#endif /* JERRY_PARSER_DUMP_BYTE_CODE */
parser_stack_free (&context);
if (context.global_status_flags & ECMA_PARSE_INTERNAL_FREE_SOURCE)
{
jmem_heap_free_block ((void *) context.source_start_p, context.source_size);
}
if (context.global_status_flags & ECMA_PARSE_INTERNAL_FREE_ARG_LIST)
{
jmem_heap_free_block ((void *) context.arguments_start_p, context.arguments_size);
}
if (compiled_code_p != NULL)
{
return compiled_code_p;
@ -2930,29 +2993,12 @@ parser_raise_error (parser_context_t *context_p, /**< context */
* NULL - otherwise
*/
ecma_compiled_code_t *
parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
size_t arg_list_size, /**< size of function argument list */
const uint8_t *source_p, /**< source code */
size_t source_size, /**< size of the source code */
parser_parse_script (void *source_p, /**< source code */
uint32_t parse_opts, /**< ecma_parse_opts_t option bits */
const jerry_parse_options_t *options_p) /**< additional configuration options */
{
#if JERRY_PARSER
#if JERRY_DEBUGGER
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
{
jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE,
JERRY_DEBUGGER_NO_SUBTYPE,
source_p,
source_size);
}
#endif /* JERRY_DEBUGGER */
ecma_compiled_code_t *bytecode_p = parser_parse_source (arg_list_p,
arg_list_size,
source_p,
source_size,
ecma_compiled_code_t *bytecode_p = parser_parse_source (source_p,
parse_opts,
options_p);

View File

@ -192,11 +192,18 @@ typedef enum
*/
typedef uint32_t parser_line_counter_t;
/**
* Source code as character data.
*/
typedef struct
{
const uint8_t *source_p; /**< valid UTF-8 source code */
size_t source_size; /**< size of the source code */
} parser_source_char_t;
/* Note: source must be a valid UTF-8 string */
ecma_compiled_code_t *
parser_parse_script (const uint8_t *arg_list_p, size_t arg_list_size,
const uint8_t *source_p, size_t source_size,
uint32_t parse_opts, const jerry_parse_options_t *options_p);
parser_parse_script (void *source_p, uint32_t parse_opts, const jerry_parse_options_t *options_p);
#if JERRY_ERROR_MESSAGES
const char *parser_error_to_string (parser_error_t);

View File

@ -2463,11 +2463,7 @@ scanner_scan_statement_end (parser_context_t *context_p, /**< context */
* Scan the whole source code.
*/
void JERRY_ATTR_NOINLINE
scanner_scan_all (parser_context_t *context_p, /**< context */
const uint8_t *arg_list_p, /**< function argument list */
const uint8_t *arg_list_end_p, /**< end of argument list */
const uint8_t *source_p, /**< valid UTF-8 source code */
const uint8_t *source_end_p) /**< end of source code */
scanner_scan_all (parser_context_t *context_p) /**< context */
{
scanner_context_t scanner_context;
@ -2507,10 +2503,10 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
PARSER_TRY (context_p->try_buffer)
{
if (arg_list_p == NULL)
if (context_p->arguments_start_p == NULL)
{
context_p->source_p = source_p;
context_p->source_end_p = source_end_p;
context_p->source_p = context_p->source_start_p;
context_p->source_end_p = context_p->source_start_p + context_p->source_size;
uint16_t status_flags = (SCANNER_LITERAL_POOL_FUNCTION
| SCANNER_LITERAL_POOL_NO_ARGUMENTS
@ -2522,7 +2518,7 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
}
scanner_literal_pool_t *literal_pool_p = scanner_push_literal_pool (context_p, &scanner_context, status_flags);
literal_pool_p->source_p = source_p;
literal_pool_p->source_p = context_p->source_start_p;
parser_stack_push_uint8 (context_p, SCAN_STACK_SCRIPT);
@ -2531,8 +2527,8 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
}
else
{
context_p->source_p = arg_list_p;
context_p->source_end_p = arg_list_end_p;
context_p->source_p = context_p->arguments_start_p;
context_p->source_end_p = context_p->arguments_start_p + context_p->arguments_size;
uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
@ -3115,8 +3111,8 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
scanner_context.end_arguments_p = scanner_info_p;
context_p->next_scanner_info_p = scanner_info_p;
context_p->source_p = source_p;
context_p->source_end_p = source_end_p;
context_p->source_p = context_p->source_start_p;
context_p->source_end_p = context_p->source_start_p + context_p->source_size;
lexer_init_line_info (context_p);
#if JERRY_ESNEXT
@ -3525,7 +3521,8 @@ scan_completed:
if (context_p->is_show_opcodes)
{
scanner_info_t *info_p = context_p->next_scanner_info_p;
const uint8_t *source_start_p = (arg_list_p == NULL) ? source_p : arg_list_p;
const uint8_t *source_start_p = (context_p->arguments_start_p == NULL ? context_p->source_start_p
: context_p->arguments_start_p);
while (info_p->type != SCANNER_TYPE_END)
{
@ -3537,7 +3534,7 @@ scan_completed:
case SCANNER_TYPE_END_ARGUMENTS:
{
JERRY_DEBUG_MSG (" END_ARGUMENTS\n");
source_start_p = source_p;
source_start_p = context_p->source_start_p;
break;
}
case SCANNER_TYPE_FUNCTION:

View File

@ -374,32 +374,36 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
}
}
jerry_value_t snapshot_result;
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_RESOURCE;
/* To avoid cppcheck warning. */
parse_options.argument_list = 0;
parse_options.resource_name = jerry_create_string_sz ((const jerry_char_t *) file_name_p,
(jerry_size_t) strlen (file_name_p));
if (function_args_p != NULL)
{
snapshot_result = jerry_generate_function_snapshot ((jerry_char_t *) source_p,
source_length,
(const jerry_char_t *) function_args_p,
strlen (function_args_p),
&parse_options,
snapshot_flags,
output_buffer,
sizeof (output_buffer) / sizeof (uint32_t));
parse_options.options |= JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_string_from_utf8 ((const jerry_char_t *) function_args_p);
}
else
{
snapshot_result = jerry_generate_snapshot ((jerry_char_t *) source_p,
jerry_value_t snapshot_result = jerry_parse ((jerry_char_t *) source_p,
source_length,
&parse_options,
&parse_options);
if (!jerry_value_is_error (snapshot_result))
{
jerry_value_t parse_result = snapshot_result;
snapshot_result = jerry_generate_snapshot (parse_result,
snapshot_flags,
output_buffer,
sizeof (output_buffer) / sizeof (uint32_t));
jerry_release_value (parse_result);
}
if (parse_options.options & JERRY_PARSE_HAS_ARGUMENT_LIST)
{
jerry_release_value (parse_options.argument_list);
}
jerry_release_value (parse_options.resource_name);

View File

@ -844,17 +844,19 @@ main (void)
jerry_release_value (val_t);
/* Test: create function */
const jerry_char_t func_arg_list[] = "a , b,c";
const jerry_char_t func_src[] = " return 5 + a+\nb+c";
jerry_value_t script_source = jerry_create_string ((const jerry_char_t *) " return 5 + a+\nb+c");
jerry_value_t func_val = jerry_parse_function (func_arg_list,
sizeof (func_arg_list) - 1,
func_src,
sizeof (func_src) - 1,
NULL);
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_string ((const jerry_char_t *) "a , b,c");
jerry_value_t func_val = jerry_parse_value (script_source, &parse_options);
TEST_ASSERT (!jerry_value_is_error (func_val));
jerry_release_value (parse_options.argument_list);
jerry_release_value (script_source);
jerry_value_t func_args[3] =
{
jerry_create_number (4),
@ -869,6 +871,24 @@ main (void)
jerry_release_value (val_t);
jerry_release_value (func_val);
parse_options.options = JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_null ();
func_val = jerry_parse ((const jerry_char_t *) "", 0, &parse_options);
jerry_release_value (parse_options.argument_list);
TEST_ASSERT (jerry_value_is_error (func_val)
&& jerry_get_error_type (func_val) == JERRY_ERROR_TYPE);
jerry_release_value (func_val);
script_source = jerry_create_number (4.5);
func_val = jerry_parse_value (script_source, NULL);
jerry_release_value (script_source);
TEST_ASSERT (jerry_value_is_error (func_val)
&& jerry_get_error_type (func_val) == JERRY_ERROR_TYPE);
jerry_release_value (func_val);
jerry_cleanup ();
TEST_ASSERT (test_api_is_free_callback_was_called);
@ -1048,7 +1068,6 @@ main (void)
"SyntaxError: Primary expression expected [<anonymous>:2:10]",
false);
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_RESOURCE;
parse_options.resource_name = jerry_create_string ((const jerry_char_t *) "filename.js");

View File

@ -36,13 +36,14 @@ main (void)
jerry_value_t regex_obj = jerry_create_regexp (pattern2, flags);
TEST_ASSERT (jerry_value_is_object (regex_obj));
const jerry_char_t func_arg_list[] = "regex";
const jerry_char_t func_src2[] = "return [regex.exec('a\\nb'), regex.dotAll, regex.sticky, regex.unicode ];";
jerry_value_t func_val = jerry_parse_function (func_arg_list,
sizeof (func_arg_list) - 1,
func_src2,
sizeof (func_src2) - 1,
NULL);
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_string ((const jerry_char_t *) "regex");
jerry_value_t func_val = jerry_parse (func_src2, sizeof (func_src2) - 1, &parse_options);
jerry_release_value (parse_options.argument_list);
jerry_value_t res = jerry_call_function (func_val, undefined_this_arg, &regex_obj, 1);
jerry_value_t regex_res = jerry_get_property_by_index (res, 0);

View File

@ -30,13 +30,14 @@ main (void)
jerry_value_t regex_obj = jerry_create_regexp (pattern, flags);
TEST_ASSERT (jerry_value_is_object (regex_obj));
const jerry_char_t func_arg_list[] = "regex";
const jerry_char_t func_src[] = "return [regex.exec('something.domain.com'), regex.multiline, regex.global];";
jerry_value_t func_val = jerry_parse_function (func_arg_list,
sizeof (func_arg_list) - 1,
func_src,
sizeof (func_src) - 1,
NULL);
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_string ((const jerry_char_t *) "regex");
jerry_value_t func_val = jerry_parse (func_src, sizeof (func_src) - 1, &parse_options);
jerry_release_value (parse_options.argument_list);
jerry_value_t res = jerry_call_function (func_val, global_obj_val, &regex_obj, 1);
jerry_value_t regex_res = jerry_get_property_by_index (res, 0);

View File

@ -62,15 +62,16 @@ test_parse_function (const char *source_p, /**< source code */
jerry_parse_options_t *options_p, /**< options passed to jerry_parse */
bool run_code) /**< run the code after parsing */
{
options_p->options |= JERRY_PARSE_HAS_ARGUMENT_LIST;
options_p->argument_list = jerry_create_string ((const jerry_char_t *) "");
for (size_t i = 0; i < USER_VALUES_SIZE; i++)
{
options_p->user_value = user_values[i];
jerry_value_t result = jerry_parse_function ((const jerry_char_t *) "",
0,
(const jerry_char_t *) source_p,
strlen (source_p),
options_p);
jerry_value_t result = jerry_parse ((const jerry_char_t *) source_p,
strlen (source_p),
options_p);
TEST_ASSERT (!jerry_value_is_error (result));
if (run_code)
@ -94,6 +95,8 @@ test_parse_function (const char *source_p, /**< source code */
jerry_release_value (user_value);
jerry_release_value (result);
}
jerry_release_value (options_p->argument_list);
} /* test_parse_function */
int

View File

@ -63,19 +63,26 @@ static void test_function_snapshot (void)
const jerry_init_flag_t flags = JERRY_INIT_EMPTY;
static uint32_t function_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
const jerry_char_t func_args[] = "a, b";
const jerry_char_t code_to_snapshot[] = "return a + b";
jerry_init (flags);
jerry_value_t generate_result;
generate_result = jerry_generate_function_snapshot (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
func_args,
sizeof (func_args) - 1,
NULL,
0,
function_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_ARGUMENT_LIST;
parse_options.argument_list = jerry_create_string ((const jerry_char_t *) "a, b");
jerry_value_t parse_result = jerry_parse (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
&parse_options);
TEST_ASSERT (!jerry_value_is_error (parse_result));
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
function_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_release_value (parse_result);
jerry_release_value (parse_options.argument_list);
TEST_ASSERT (!jerry_value_is_error (generate_result)
&& jerry_value_is_number (generate_result));
@ -146,13 +153,16 @@ static void test_function_arguments_snapshot (void)
);
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
NULL,
0,
arguments_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_value_t parse_result = jerry_parse (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
NULL);
TEST_ASSERT (!jerry_value_is_error (parse_result));
jerry_value_t generate_result= jerry_generate_snapshot (parse_result,
0,
arguments_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_release_value (parse_result);
TEST_ASSERT (!jerry_value_is_error (generate_result)
&& jerry_value_is_number (generate_result));
@ -204,18 +214,22 @@ static void test_snapshot_with_user (void)
);
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t result = jerry_generate_snapshot (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
NULL,
0,
snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_value_t parse_result = jerry_parse (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
NULL);
TEST_ASSERT (!jerry_value_is_error (parse_result));
TEST_ASSERT (!jerry_value_is_error (result)
&& jerry_value_is_number (result));
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_release_value (parse_result);
size_t snapshot_size = (size_t) jerry_get_number_value (result);
jerry_release_value (result);
TEST_ASSERT (!jerry_value_is_error (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);
for (int i = 0; i < 3; i++)
{
@ -234,11 +248,11 @@ static void test_snapshot_with_user (void)
snapshot_exec_options.user_value = jerry_create_string ((const jerry_char_t *) "AnyString...");
}
result = jerry_exec_snapshot (snapshot_buffer,
snapshot_size,
0,
JERRY_SNAPSHOT_EXEC_HAS_USER_VALUE,
&snapshot_exec_options);
jerry_value_t result = jerry_exec_snapshot (snapshot_buffer,
snapshot_size,
0,
JERRY_SNAPSHOT_EXEC_HAS_USER_VALUE,
&snapshot_exec_options);
TEST_ASSERT (!jerry_value_is_error (result)
&& jerry_value_is_function (result));
@ -284,13 +298,17 @@ main (void)
sizeof (magic_string_lengths) / sizeof (jerry_length_t),
magic_string_lengths);
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
NULL,
JERRY_SNAPSHOT_SAVE_STATIC,
snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_value_t parse_result = jerry_parse (code_to_snapshot,
sizeof (code_to_snapshot) - 1,
NULL);
TEST_ASSERT (!jerry_value_is_error (parse_result));
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
JERRY_SNAPSHOT_SAVE_STATIC,
snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_release_value (parse_result);
TEST_ASSERT (!jerry_value_is_error (generate_result)
&& jerry_value_is_number (generate_result));
@ -319,13 +337,18 @@ main (void)
const jerry_char_t code_to_snapshot1[] = "var a = 'hello'; 123";
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (code_to_snapshot1,
sizeof (code_to_snapshot1) - 1,
NULL,
0,
snapshot_buffer_0,
SNAPSHOT_BUFFER_SIZE);
jerry_value_t parse_result = jerry_parse (code_to_snapshot1,
sizeof (code_to_snapshot1) - 1,
NULL);
TEST_ASSERT (!jerry_value_is_error (parse_result));
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
snapshot_buffer_0,
SNAPSHOT_BUFFER_SIZE);
jerry_release_value (parse_result);
TEST_ASSERT (!jerry_value_is_error (generate_result)
&& jerry_value_is_number (generate_result));
@ -337,12 +360,18 @@ main (void)
const jerry_char_t code_to_snapshot2[] = "var b = 'hello'; 456";
jerry_init (JERRY_INIT_EMPTY);
generate_result = jerry_generate_snapshot (code_to_snapshot2,
sizeof (code_to_snapshot2) - 1,
NULL,
parse_result = jerry_parse (code_to_snapshot2,
sizeof (code_to_snapshot2) - 1,
NULL);
TEST_ASSERT (!jerry_value_is_error (parse_result));
generate_result = jerry_generate_snapshot (parse_result,
0,
snapshot_buffer_1,
SNAPSHOT_BUFFER_SIZE);
jerry_release_value (parse_result);
TEST_ASSERT (!jerry_value_is_error (generate_result)
&& jerry_value_is_number (generate_result));
@ -402,13 +431,16 @@ main (void)
static uint32_t literal_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
static const jerry_char_t code_for_c_format[] = "var object = { aa:'fo\" o\\n \\\\', Bb:'max', aaa:'xzy0' };";
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (code_for_c_format,
sizeof (code_for_c_format) - 1,
NULL,
0,
literal_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_value_t parse_result = jerry_parse (code_for_c_format,
sizeof (code_for_c_format) - 1,
NULL);
TEST_ASSERT (!jerry_value_is_error (parse_result));
jerry_value_t generate_result = jerry_generate_snapshot (parse_result,
0,
literal_snapshot_buffer,
SNAPSHOT_BUFFER_SIZE);
jerry_release_value (parse_result);
TEST_ASSERT (!jerry_value_is_error (generate_result));
TEST_ASSERT (jerry_value_is_number (generate_result));