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
24 changed files with 601 additions and 696 deletions
+44 -113
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 */
+80 -96
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 */
/**
+5 -1
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))
+11 -3
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
/**
+1 -1
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;
+1 -1
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 */
/**
@@ -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 */
/**
+9 -25
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))
{
+2 -2
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);
/**
* @}
@@ -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);
+1 -3
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);
+1 -7
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,
+7 -4
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
+5 -2
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);
/**
* @}
+104 -58
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);
+10 -3
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);
+12 -15
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: