Implement function.toString operation (#4752)

May increase the memory consumtpion heavily.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2021-08-31 13:37:25 +02:00
committed by GitHub
parent 1c6b18ecdf
commit 6649940ea6
37 changed files with 1002 additions and 192 deletions
+58 -12
View File
@@ -895,6 +895,27 @@ typedef enum
check a range of types without decoding the actual type. */
} cbc_code_flags_t;
/**
* Optional byte code fields. These fields are stored in a reversed
* order from the end of the byte code data.
*
* Value fields:
* - when CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED is set:
* argument_end number of argument names encoded as strings
* - when function type is not CBC_FUNCTION_CONSTRUCTOR:
* function name encoded as string
* - when CBC_CODE_FLAGS_HAS_TAGGED_LITERALS is set:
* pointer to the tagged template collection encoded as value
*
* Byte fields when CBC_CODE_FLAGS_HAS_EXTENDED_INFO is set:
* - always available:
* a byte which contains a combination of CBC_EXTENDED_CODE_FLAGS bits
* - when CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH is set:
* a vlq encoded default value for function length
* - when CBC_EXTENDED_CODE_FLAGS_HAS_SOURCE_CODE_RANGE is set:
* a pair of vlq encoded values, representing the start and size of the range
*/
/**
* Compact byte code function types.
*/
@@ -962,9 +983,15 @@ typedef enum
((flags) >= (CBC_FUNCTION_ARROW << CBC_FUNCTION_TYPE_SHIFT))
/**
* Get length property from extended info
* Compact byte code extended status flags.
*/
#define CBC_EXTENDED_INFO_GET_LENGTH(extended_info) (extended_info)
typedef enum
{
CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH = (1u << 0), /**< has argument length */
CBC_EXTENDED_CODE_FLAGS_HAS_SOURCE_CODE_RANGE = (1u << 1), /**< has source code range (start, end) */
CBC_EXTENDED_CODE_FLAGS_SOURCE_CODE_IN_ARGUMENTS = (1u << 2), /**< source code range is inside
* the function arguments */
} cbc_extended_code_flags_t;
/**
* Shared script data.
@@ -977,20 +1004,25 @@ typedef enum
} cbc_script_type;
/**
* Value for increasing or decreasing the script reference counter.
* Script is a function with arguments source code.
*/
#define CBC_SCRIPT_REF_ONE 0x4
#define CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS 0x4
/**
* Get the type of a script.
* Value for increasing or decreasing the script reference counter.
*/
#define CBC_SCRIPT_GET_TYPE(script_p) ((script_p)->refs_and_type & (CBC_SCRIPT_REF_ONE - 1))
#define CBC_SCRIPT_REF_ONE 0x8
/**
* Maximum value of script reference counter.
*/
#define CBC_SCRIPT_REF_MAX (UINT32_MAX - CBC_SCRIPT_REF_ONE + 1)
/**
* Get the type of a script.
*/
#define CBC_SCRIPT_GET_TYPE(script_p) ((script_p)->refs_and_type & 0x3)
/**
* Sets the type of a script using the user_value.
*/
@@ -1018,16 +1050,30 @@ typedef struct
#if JERRY_RESOURCE_NAME
ecma_value_t resource_name; /**< resource name */
#endif /* JERRY_RESOURCE_NAME */
#if JERRY_FUNCTION_TO_STRING
ecma_value_t source_code; /**< source code */
#endif /* JERRY_FUNCTION_TO_STRING */
} cbc_script_t;
/**
* Script data with user value.
* Get the array of optional values assigned to a script.
*
* First value: user value
* Second value: function arguments value
*/
typedef struct
{
cbc_script_t header; /**< script header */
ecma_value_t user_value; /**< user value */
} cbc_script_user_t;
#define CBC_SCRIPT_GET_OPTIONAL_VALUES(script_p) ((ecma_value_t *) ((script_p) + 1))
/**
* Get user value.
*/
#define CBC_SCRIPT_GET_USER_VALUE(script_p) \
(CBC_SCRIPT_GET_OPTIONAL_VALUES (script_p)[0])
/**
* Get function arguments.
*/
#define CBC_SCRIPT_GET_FUNCTION_ARGUMENTS(script_p, type) \
(CBC_SCRIPT_GET_OPTIONAL_VALUES (script_p)[(type) != CBC_SCRIPT_GENERIC ? 1 : 0])
#define CBC_OPCODE(arg1, arg2, arg3, arg4) arg1,
+21 -5
View File
@@ -15,6 +15,7 @@
#include "common.h"
#include "ecma-helpers.h"
#include "ecma-extended-info.h"
#include "ecma-big-uint.h"
#include "ecma-bigint.h"
#include "js-parser-internal.h"
@@ -396,16 +397,31 @@ util_print_cbc (ecma_compiled_code_t *compiled_code_p) /**< compiled code */
JERRY_DEBUG_MSG (" Const literal range end: %d\n", (int) const_literal_end);
JERRY_DEBUG_MSG (" Literal range end: %d\n\n", (int) literal_end);
#if JERRY_ESNEXT
#if JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO)
{
uint32_t extended_info = ecma_compiled_code_resolve_extended_info (compiled_code_p);
uint8_t *extended_info_p = ecma_compiled_code_resolve_extended_info (compiled_code_p);
uint8_t *extended_info_start_p = extended_info_p + sizeof (uint8_t);
uint8_t extended_info = *extended_info_p;
JERRY_DEBUG_MSG (" [Extended] Argument length: %d\n\n", (int) CBC_EXTENDED_INFO_GET_LENGTH (extended_info));
if (extended_info & CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH)
{
uint32_t argument_length = ecma_extended_info_decode_vlq (&extended_info_p);
JERRY_DEBUG_MSG (" [Extended] Argument length: %d\n", (int) argument_length);
}
size -= sizeof (ecma_value_t);
if (extended_info & CBC_EXTENDED_CODE_FLAGS_HAS_SOURCE_CODE_RANGE)
{
uint32_t range_start = ecma_extended_info_decode_vlq (&extended_info_p);
uint32_t range_end = ecma_extended_info_decode_vlq (&extended_info_p) + range_start;
JERRY_DEBUG_MSG (" [Extended] Source code range: %d - %d\n", (int) range_start, (int) range_end);
}
JERRY_DEBUG_MSG ("\n");
size -= (size_t) (extended_info_start_p - extended_info_p);
}
#endif /* JERRY_ESNEXT */
#endif /* JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING */
byte_code_start_p = (uint8_t *) compiled_code_p;
+28 -2
View File
@@ -741,6 +741,9 @@ lexer_parse_identifier (parser_context_t *context_p, /**< context */
{
decoded_length = 2 * 3;
status_flags = LEXER_LIT_LOCATION_HAS_ESCAPE;
#if JERRY_FUNCTION_TO_STRING
context_p->global_status_flags |= ECMA_PARSE_INTERNAL_HAS_4_BYTE_MARKER;
#endif /* JERRY_FUNCTION_TO_STRING */
}
#else /* !JERRY_ESNEXT */
if (code_point < LIT_UTF8_4_BYTE_MARKER)
@@ -1171,6 +1174,9 @@ lexer_parse_string (parser_context_t *context_p, /**< context */
raw_length_adjust += 2;
#endif /* JERRY_ESNEXT */
column++;
#if JERRY_FUNCTION_TO_STRING
context_p->global_status_flags |= ECMA_PARSE_INTERNAL_HAS_4_BYTE_MARKER;
#endif /* JERRY_FUNCTION_TO_STRING */
continue;
}
else if (*source_p == LIT_CHAR_TAB)
@@ -1605,6 +1611,11 @@ lexer_next_token (parser_context_t *context_p) /**< context */
{
size_t length;
#if JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
/* Needed by arrow functions with expression body */
context_p->function_end_p = context_p->source_p;
#endif /* JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING */
lexer_skip_spaces (context_p);
context_p->token.keyword_type = LEXER_EOS;
@@ -3069,7 +3080,7 @@ lexer_construct_regexp_object (parser_context_t *context_p, /**< context */
}
else
{
JERRY_ASSERT (lit_is_valid_utf8_string (regex_start_p, length));
JERRY_ASSERT (lit_is_valid_utf8_string (regex_start_p, length, false));
pattern_str_p = ecma_new_ecma_string_from_utf8_converted_to_cesu8 (regex_start_p, length);
}
@@ -3189,6 +3200,13 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
JERRY_ASSERT ((ident_opts & LEXER_OBJ_IDENT_CLASS_IDENTIFIER)
|| !(ident_opts & LEXER_OBJ_IDENT_CLASS_NO_STATIC));
#if JERRY_FUNCTION_TO_STRING
if (ident_opts & LEXER_OBJ_IDENT_SET_FUNCTION_START)
{
context_p->function_start_p = context_p->source_p;
}
#endif /* JERRY_FUNCTION_TO_STRING */
if (lexer_parse_identifier (context_p, LEXER_PARSE_NO_OPTS))
{
if (!(ident_opts & (LEXER_OBJ_IDENT_ONLY_IDENTIFIERS | LEXER_OBJ_IDENT_OBJECT_PATTERN)))
@@ -3253,6 +3271,10 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
#if JERRY_ESNEXT
case LIT_CHAR_LEFT_SQUARE:
{
#if JERRY_FUNCTION_TO_STRING
const uint8_t *function_start_p = context_p->function_start_p;
#endif /* JERRY_FUNCTION_TO_STRING */
lexer_consume_next_character (context_p);
lexer_next_token (context_p);
@@ -3262,6 +3284,10 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
{
parser_raise_error (context_p, PARSER_ERR_RIGHT_SQUARE_EXPECTED);
}
#if JERRY_FUNCTION_TO_STRING
context_p->function_start_p = function_start_p;
#endif /* JERRY_FUNCTION_TO_STRING */
return;
}
case LIT_CHAR_ASTERISK:
@@ -3277,7 +3303,7 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
}
case LIT_CHAR_DOT:
{
if ((ident_opts & ((uint32_t) ~LEXER_OBJ_IDENT_OBJECT_PATTERN))
if ((ident_opts & ((uint32_t) ~(LEXER_OBJ_IDENT_OBJECT_PATTERN | LEXER_OBJ_IDENT_SET_FUNCTION_START)))
|| context_p->source_p + 2 >= context_p->source_end_p
|| context_p->source_p[1] != LIT_CHAR_DOT
|| context_p->source_p[2] != LIT_CHAR_DOT)
+10 -5
View File
@@ -275,11 +275,16 @@ typedef enum
*/
typedef enum
{
LEXER_OBJ_IDENT_NO_OPTS = 0, /**< no options */
LEXER_OBJ_IDENT_ONLY_IDENTIFIERS = (1u << 0), /**< only identifiers are accepted */
LEXER_OBJ_IDENT_CLASS_IDENTIFIER = (1u << 1), /**< expect identifier inside a class body */
LEXER_OBJ_IDENT_CLASS_NO_STATIC = (1u << 2), /**< static keyword was not present before the identifier */
LEXER_OBJ_IDENT_OBJECT_PATTERN = (1u << 3), /**< parse "get"/"set" as string literal in object pattern */
LEXER_OBJ_IDENT_NO_OPTS = 0, /**< no options */
LEXER_OBJ_IDENT_ONLY_IDENTIFIERS = (1u << 0), /**< only identifiers are accepted */
LEXER_OBJ_IDENT_CLASS_IDENTIFIER = (1u << 1), /**< expect identifier inside a class body */
LEXER_OBJ_IDENT_CLASS_NO_STATIC = (1u << 2), /**< static keyword was not present before the identifier */
LEXER_OBJ_IDENT_OBJECT_PATTERN = (1u << 3), /**< parse "get"/"set" as string literal in object pattern */
#if JERRY_FUNCTION_TO_STRING
LEXER_OBJ_IDENT_SET_FUNCTION_START = (1u << 4), /**< set function start */
#else /* !JERRY_FUNCTION_TO_STRING */
LEXER_OBJ_IDENT_SET_FUNCTION_START = 0, /**< set function start (disabled) */
#endif /* JERRY_FUNCTION_TO_STRING */
} lexer_obj_ident_opts_t;
/**
+13 -1
View File
@@ -562,6 +562,7 @@ parser_parse_class_body (parser_context_t *context_p, /**< context */
}
lexer_expect_object_literal_id (context_p, (LEXER_OBJ_IDENT_CLASS_IDENTIFIER
| LEXER_OBJ_IDENT_SET_FUNCTION_START
| (is_static ? 0 : LEXER_OBJ_IDENT_CLASS_NO_STATIC)));
if (context_p->token.type == LEXER_RIGHT_BRACE)
@@ -1167,7 +1168,7 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
while (true)
{
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS);
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_SET_FUNCTION_START);
switch (context_p->token.type)
{
@@ -2011,6 +2012,10 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
{
JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
#if JERRY_FUNCTION_TO_STRING
context_p->function_start_p = context_p->token.lit_location.char_p;
#endif /* JERRY_FUNCTION_TO_STRING */
uint32_t arrow_status_flags = (PARSER_IS_FUNCTION
| PARSER_IS_ARROW_FUNCTION
| (context_p->status_flags & PARSER_INSIDE_CLASS_FIELD));
@@ -2124,6 +2129,9 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
}
case LEXER_KEYW_FUNCTION:
{
#if JERRY_FUNCTION_TO_STRING
context_p->function_start_p = context_p->token.lit_location.char_p;
#endif /* JERRY_FUNCTION_TO_STRING */
parser_parse_function_expression (context_p, PARSER_FUNCTION_CLOSURE | PARSER_IS_FUNC_EXPRESSION);
break;
}
@@ -2270,6 +2278,10 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
parser_check_assignment_expr (context_p);
#if JERRY_FUNCTION_TO_STRING
context_p->function_start_p = context_p->source_p - 1;
#endif /* JERRY_FUNCTION_TO_STRING */
uint32_t arrow_status_flags = (PARSER_IS_FUNCTION
| PARSER_IS_ARROW_FUNCTION
| (context_p->status_flags & PARSER_INSIDE_CLASS_FIELD));
+10
View File
@@ -539,6 +539,10 @@ typedef struct parser_saved_context_t
#if JERRY_LINE_INFO
parser_line_info_data_t *line_info_p; /**< line info data */
#endif /* JERRY_LINE_INFO */
#if JERRY_FUNCTION_TO_STRING
const uint8_t *function_start_p; /**< start position of the current function */
#endif /* JERRY_FUNCTION_TO_STRING */
} parser_saved_context_t;
/**
@@ -571,6 +575,7 @@ typedef struct
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 argument_list; /**< current argument list as value */
ecma_value_t user_value; /**< current user value */
#if JERRY_MODULE_SYSTEM
@@ -639,6 +644,11 @@ typedef struct
#if JERRY_LINE_INFO
parser_line_info_data_t *line_info_p; /**< line info data */
#endif /* JERRY_LINE_INFO */
#if JERRY_FUNCTION_TO_STRING
const uint8_t *function_start_p; /**< start position of the function which will be parsed */
const uint8_t *function_end_p; /**< end position of the current function */
#endif /* JERRY_FUNCTION_TO_STRING */
} parser_context_t;
/**
+21
View File
@@ -656,6 +656,17 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
}
#endif /* JERRY_ESNEXT */
#if JERRY_FUNCTION_TO_STRING
#if JERRY_ESNEXT
if (!(context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC))
{
context_p->function_start_p = context_p->token.lit_location.char_p;
}
#else /* !JERRY_ESNEXT */
context_p->function_start_p = context_p->token.lit_location.char_p;
#endif /* JERRY_ESNEXT */
#endif /* JERRY_FUNCTION_TO_STRING */
#if JERRY_DEBUGGER
parser_line_counter_t debugger_line = context_p->token.line;
parser_line_counter_t debugger_column = context_p->token.column;
@@ -2560,6 +2571,9 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
&& context_p->next_scanner_info_p->source_p == context_p->source_p
&& context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION)
{
#if JERRY_FUNCTION_TO_STRING
context_p->function_start_p = context_p->token.lit_location.char_p;
#endif /* JERRY_FUNCTION_TO_STRING */
lexer_next_token (context_p);
}
@@ -3246,6 +3260,9 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT);
}
#if JERRY_FUNCTION_TO_STRING
context_p->function_start_p = context_p->token.lit_location.char_p;
#endif /* JERRY_FUNCTION_TO_STRING */
lexer_next_token (context_p);
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FUNCTION);
continue;
@@ -3343,6 +3360,10 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
}
#endif /* JERRY_LINE_INFO */
#if JERRY_FUNCTION_TO_STRING
context_p->function_end_p = context_p->source_p;
#endif /* JERRY_FUNCTION_TO_STRING */
parser_stack_pop_uint8 (context_p);
context_p->last_statement.current_p = NULL;
/* There is no lexer_next_token here, since the
+148 -25
View File
@@ -15,6 +15,7 @@
#include "debugger.h"
#include "ecma-exceptions.h"
#include "ecma-extended-info.h"
#include "ecma-helpers.h"
#include "ecma-literal-storage.h"
#include "ecma-module.h"
@@ -910,11 +911,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
total_size += sizeof (ecma_value_t);
}
if (context_p->argument_length != UINT16_MAX)
{
total_size += sizeof (ecma_value_t);
}
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
{
total_size += sizeof (ecma_value_t);
@@ -925,6 +921,48 @@ parser_post_processing (parser_context_t *context_p) /**< context */
total_size += sizeof (ecma_value_t);
#endif /* JERRY_LINE_INFO */
#if JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING
uint8_t extended_info = 0;
#endif /* JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING */
#if JERRY_ESNEXT
if (context_p->argument_length != UINT16_MAX)
{
extended_info |= CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH;
total_size += ecma_extended_info_get_encoded_length (context_p->argument_length);
}
#endif /* JERRY_ESNEXT */
#if JERRY_FUNCTION_TO_STRING
if (context_p->last_context_p != NULL)
{
extended_info |= CBC_EXTENDED_CODE_FLAGS_HAS_SOURCE_CODE_RANGE;
const uint8_t *start_p = context_p->source_start_p;
const uint8_t *function_start_p = context_p->last_context_p->function_start_p;
if (function_start_p < start_p || function_start_p >= start_p + context_p->source_size)
{
JERRY_ASSERT (context_p->arguments_start_p != NULL
&& function_start_p >= context_p->arguments_start_p
&& function_start_p < context_p->arguments_start_p + context_p->arguments_size);
start_p = context_p->arguments_start_p;
extended_info |= CBC_EXTENDED_CODE_FLAGS_SOURCE_CODE_IN_ARGUMENTS;
}
total_size += ecma_extended_info_get_encoded_length ((uint32_t) (function_start_p - start_p));
total_size += ecma_extended_info_get_encoded_length ((uint32_t) (context_p->function_end_p - function_start_p));
}
#endif /* JERRY_FUNCTION_TO_STRING */
#if JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING
if (extended_info != 0)
{
total_size += sizeof (uint8_t);
}
#endif /* JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING */
total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT);
compiled_code_p = (ecma_compiled_code_t *) parser_malloc (context_p, total_size);
@@ -1327,19 +1365,10 @@ parser_post_processing (parser_context_t *context_p) /**< context */
*(--base_p) = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
}
if (context_p->argument_length != UINT16_MAX)
{
compiled_code_p->status_flags |= CBC_CODE_FLAGS_HAS_EXTENDED_INFO;
*(--base_p) = context_p->argument_length;
}
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
{
compiled_code_p->status_flags |= CBC_CODE_FLAGS_HAS_TAGGED_LITERALS;
base_p[-1] = (ecma_value_t) context_p->tagged_template_literal_cp;
#if JERRY_LINE_INFO
--base_p;
#endif /* JERRY_LINE_INFO */
*(--base_p) = (ecma_value_t) context_p->tagged_template_literal_cp;
}
#endif /* JERRY_ESNEXT */
@@ -1347,6 +1376,44 @@ parser_post_processing (parser_context_t *context_p) /**< context */
ECMA_SET_INTERNAL_VALUE_POINTER (base_p[-1], line_info_p);
#endif /* JERRY_LINE_INFO */
#if JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING
if (extended_info != 0)
{
#if JERRY_LINE_INFO
base_p--;
#endif /* JERRY_LINE_INFO */
uint8_t *extended_info_p = ((uint8_t *) base_p) - 1;
compiled_code_p->status_flags |= CBC_CODE_FLAGS_HAS_EXTENDED_INFO;
*extended_info_p = extended_info;
#if JERRY_ESNEXT
if (context_p->argument_length != UINT16_MAX)
{
ecma_extended_info_encode_vlq (&extended_info_p, context_p->argument_length);
}
#endif /* JERRY_ESNEXT */
#if JERRY_FUNCTION_TO_STRING
if (context_p->last_context_p != NULL)
{
const uint8_t *start_p = context_p->source_start_p;
if (extended_info & CBC_EXTENDED_CODE_FLAGS_SOURCE_CODE_IN_ARGUMENTS)
{
start_p = context_p->arguments_start_p;
}
const uint8_t *function_start_p = context_p->last_context_p->function_start_p;
ecma_extended_info_encode_vlq (&extended_info_p, (uint32_t) (function_start_p - start_p));
ecma_extended_info_encode_vlq (&extended_info_p, (uint32_t) (context_p->function_end_p - function_start_p));
}
#endif /* JERRY_FUNCTION_TO_STRING */
}
#endif /* JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING */
#if JERRY_PARSER_DUMP_BYTE_CODE
if (context_p->is_show_opcodes)
{
@@ -1793,22 +1860,22 @@ parser_parse_source (void *source_p, /**< source code */
context.module_names_p = NULL;
#endif /* JERRY_MODULE_SYSTEM */
ecma_value_t argument_list = ECMA_VALUE_EMPTY;
context.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;
context.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];
context.argument_list = ((ecma_value_t *) source_p)[1];
}
if (argument_list != ECMA_VALUE_EMPTY)
if (context.argument_list != ECMA_VALUE_EMPTY)
{
JERRY_ASSERT (ecma_is_value_string (argument_list));
JERRY_ASSERT (ecma_is_value_string (context.argument_list));
context.status_flags |= PARSER_IS_FUNCTION;
#if JERRY_ESNEXT
@@ -1822,7 +1889,7 @@ parser_parse_source (void *source_p, /**< source code */
}
#endif /* JERRY_ESNEXT */
ecma_string_t *string_p = ecma_get_string_from_value (argument_list);
ecma_string_t *string_p = ecma_get_string_from_value (context.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);
@@ -1881,7 +1948,7 @@ parser_parse_source (void *source_p, /**< source code */
if (CBC_SCRIPT_GET_TYPE (parent_script_p) != CBC_SCRIPT_GENERIC)
{
context.user_value = ((cbc_script_user_t *) parent_script_p)->user_value;
context.user_value = CBC_SCRIPT_GET_USER_VALUE (parent_script_p);
}
#if JERRY_SNAPSHOT_EXEC
}
@@ -1893,8 +1960,20 @@ parser_parse_source (void *source_p, /**< source code */
context.user_value = context.options_p->user_value;
}
uint32_t script_size = (context.user_value != ECMA_VALUE_EMPTY ? sizeof (cbc_script_user_t)
: sizeof (cbc_script_t));
size_t script_size = sizeof (cbc_script_t);
if (context.user_value != ECMA_VALUE_EMPTY)
{
script_size += sizeof (ecma_value_t);
}
#if JERRY_FUNCTION_TO_STRING
if (context.argument_list != ECMA_VALUE_EMPTY)
{
script_size += sizeof (ecma_value_t);
}
#endif /* JERRY_FUNCTION_TO_STRING */
context.script_p = jmem_heap_alloc_block_null_on_error (script_size);
if (JERRY_UNLIKELY (context.script_p == NULL))
@@ -1977,6 +2056,11 @@ parser_parse_source (void *source_p, /**< source code */
context.line_info_p = NULL;
#endif /* JERRY_LINE_INFO */
#if JERRY_FUNCTION_TO_STRING
context.function_start_p = NULL;
context.function_end_p = NULL;
#endif /* JERRY_FUNCTION_TO_STRING */
#if JERRY_PARSER_DUMP_BYTE_CODE
context.is_show_opcodes = (JERRY_CONTEXT (jerry_init_flags) & JERRY_INIT_SHOW_OPCODES);
context.total_byte_code_size = 0;
@@ -2116,9 +2200,44 @@ parser_parse_source (void *source_p, /**< source code */
if (context.user_value != ECMA_VALUE_EMPTY)
{
((cbc_script_user_t *) context.script_p)->user_value = ecma_copy_value_if_not_object (context.user_value);
CBC_SCRIPT_GET_USER_VALUE (context.script_p) = ecma_copy_value_if_not_object (context.user_value);
}
#if JERRY_FUNCTION_TO_STRING
if (!(context.global_status_flags & ECMA_PARSE_HAS_SOURCE_VALUE))
{
ecma_string_t *string_p;
if (context.global_status_flags & ECMA_PARSE_INTERNAL_HAS_4_BYTE_MARKER)
{
string_p = ecma_new_ecma_string_from_utf8_converted_to_cesu8 (context.source_start_p, context.source_size);
}
else
{
string_p = ecma_new_ecma_string_from_utf8 (context.source_start_p, context.source_size);
}
context.script_p->source_code = ecma_make_string_value (string_p);
}
else
{
ecma_value_t source = ((ecma_value_t *) source_p)[0];
ecma_ref_ecma_string (ecma_get_string_from_value (source));
context.script_p->source_code = source;
}
if (context.argument_list != ECMA_VALUE_EMPTY)
{
int idx = (context.user_value != ECMA_VALUE_EMPTY) ? 1 : 0;
CBC_SCRIPT_GET_OPTIONAL_VALUES (context.script_p)[idx] = context.argument_list;
ecma_ref_ecma_string (ecma_get_string_from_value (context.argument_list));
context.script_p->refs_and_type |= CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS;
}
#endif /* JERRY_FUNCTION_TO_STRING */
#if JERRY_PARSER_DUMP_BYTE_CODE
if (context.is_show_opcodes)
{
@@ -2315,6 +2434,10 @@ parser_save_context (parser_context_t *context_p, /**< context */
saved_context_p->line_info_p = context_p->line_info_p;
#endif /* JERRY_LINE_INFO */
#if JERRY_FUNCTION_TO_STRING
saved_context_p->function_start_p = context_p->function_start_p;
#endif /* JERRY_FUNCTION_TO_STRING */
/* Reset private part of the context. */
context_p->status_flags &= PARSER_IS_STRICT;