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
+6
View File
@@ -24,6 +24,7 @@ set(JERRY_DEBUGGER OFF CACHE BOOL "Enable JerryScrip
set(JERRY_ERROR_MESSAGES OFF CACHE BOOL "Enable error messages?")
set(JERRY_EXTERNAL_CONTEXT OFF CACHE BOOL "Enable external context?")
set(JERRY_PARSER ON CACHE BOOL "Enable javascript-parser?")
set(JERRY_FUNCTION_TO_STRING OFF CACHE BOOL "Enable function toString operation?")
set(JERRY_LINE_INFO OFF CACHE BOOL "Enable line info?")
set(JERRY_LOGGING OFF CACHE BOOL "Enable logging?")
set(JERRY_MEM_STATS OFF CACHE BOOL "Enable memory statistics?")
@@ -83,6 +84,7 @@ message(STATUS "JERRY_DEBUGGER " ${JERRY_DEBUGGER})
message(STATUS "JERRY_ERROR_MESSAGES " ${JERRY_ERROR_MESSAGES})
message(STATUS "JERRY_EXTERNAL_CONTEXT " ${JERRY_EXTERNAL_CONTEXT})
message(STATUS "JERRY_PARSER " ${JERRY_PARSER})
message(STATUS "JERRY_FUNCTION_TO_STRING " ${JERRY_FUNCTION_TO_STRING})
message(STATUS "JERRY_LINE_INFO " ${JERRY_LINE_INFO})
message(STATUS "JERRY_LOGGING " ${JERRY_LOGGING} ${JERRY_LOGGING_MESSAGE})
message(STATUS "JERRY_MEM_STATS " ${JERRY_MEM_STATS})
@@ -135,6 +137,7 @@ set(SOURCE_CORE_FILES
ecma/base/ecma-alloc.c
ecma/base/ecma-gc.c
ecma/base/ecma-errors.c
ecma/base/ecma-extended-info.c
ecma/base/ecma-helpers-collection.c
ecma/base/ecma-helpers-conversion.c
ecma/base/ecma-helpers-errol.c
@@ -559,6 +562,9 @@ jerry_add_define01(JERRY_EXTERNAL_CONTEXT)
# JS-Parser
jerry_add_define01(JERRY_PARSER)
# JS function toString
jerry_add_define01(JERRY_FUNCTION_TO_STRING)
# JS line info
jerry_add_define01(JERRY_LINE_INFO)
+12 -3
View File
@@ -979,8 +979,13 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
user_value = option_values_p->user_value;
}
uint32_t script_size = (user_value != ECMA_VALUE_EMPTY ? sizeof (cbc_script_user_t)
: sizeof (cbc_script_t));
size_t script_size = sizeof (cbc_script_t);
if (user_value != ECMA_VALUE_EMPTY)
{
script_size += sizeof (ecma_value_t);
}
cbc_script_t *script_p = jmem_heap_alloc_block (script_size);
CBC_SCRIPT_SET_TYPE (script_p, user_value, CBC_SCRIPT_REF_ONE);
@@ -1003,6 +1008,10 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
script_p->resource_name = resource_name;
#endif /* JERRY_RESOURCE_NAME */
#if JERRY_FUNCTION_TO_STRING
script_p->source_code = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
#endif /* JERRY_FUNCTION_TO_STRING */
const uint8_t *literal_base_p = snapshot_data_p + header_p->lit_table_offset;
bytecode_p = snapshot_load_compiled_code ((const uint8_t *) bytecode_p,
@@ -1021,7 +1030,7 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
if (user_value != ECMA_VALUE_EMPTY)
{
((cbc_script_user_t *) script_p)->user_value = ecma_copy_value_if_not_object (user_value);
CBC_SCRIPT_GET_USER_VALUE (script_p) = ecma_copy_value_if_not_object (user_value);
}
}
+7 -3
View File
@@ -1841,6 +1841,9 @@ jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check *
#if JERRY_MODULE_SYSTEM
|| feature == JERRY_FEATURE_MODULE
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_FUNCTION_TO_STRING
|| feature == JERRY_FEATURE_FUNCTION_TO_STRING
#endif /* JERRY_FUNCTION_TO_STRING */
);
} /* jerry_is_feature_enabled */
@@ -2801,7 +2804,7 @@ jerry_create_regexp_sz (const jerry_char_t *pattern_p, /**< zero-terminated UTF-
jerry_assert_api_available ();
#if JERRY_BUILTIN_REGEXP
if (!lit_is_valid_utf8_string (pattern_p, pattern_size))
if (!lit_is_valid_utf8_string (pattern_p, pattern_size, true))
{
return jerry_throw (ecma_raise_common_error (ECMA_ERR_MSG ("Input must be a valid utf8 string")));
}
@@ -5130,7 +5133,8 @@ jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, /**< UTF-8 string */
jerry_size_t buf_size) /**< string size */
{
return lit_is_valid_utf8_string ((lit_utf8_byte_t *) utf8_buf_p,
(lit_utf8_size_t) buf_size);
(lit_utf8_size_t) buf_size,
true);
} /* jerry_is_valid_utf8_string */
/**
@@ -5490,7 +5494,7 @@ jerry_get_user_value (const jerry_value_t value) /**< jerry api value */
return ECMA_VALUE_UNDEFINED;
}
return ecma_copy_value (((cbc_script_user_t *) script_p)->user_value);
return ecma_copy_value (CBC_SCRIPT_GET_USER_VALUE (script_p));
} /* jerry_get_user_value */
/**
+17
View File
@@ -231,6 +231,19 @@
# define JERRY_LCACHE 1
#endif /* !defined (JERRY_LCACHE) */
/**
* Enable/Disable function toString operation.
*
* Allowed values:
* 0: Disable function toString operation.
* 1: Enable function toString operation.
*
* Default value: 0
*/
#ifndef JERRY_FUNCTION_TO_STRING
# define JERRY_FUNCTION_TO_STRING 0
#endif /* !defined (JERRY_FUNCTION_TO_STRING) */
/**
* Enable/Disable line-info management inside the engine.
*
@@ -634,6 +647,10 @@
|| ((JERRY_LCACHE != 0) && (JERRY_LCACHE != 1))
# error "Invalid value for 'JERRY_LCACHE' macro."
#endif
#if !defined (JERRY_FUNCTION_TO_STRING) \
|| ((JERRY_FUNCTION_TO_STRING != 0) && (JERRY_FUNCTION_TO_STRING != 1))
# error "Invalid value for 'JERRY_FUNCTION_TO_STRING' macro."
#endif
#if !defined (JERRY_LINE_INFO) \
|| ((JERRY_LINE_INFO != 0) && (JERRY_LINE_INFO != 1))
# error "Invalid value for 'JERRY_LINE_INFO' macro."
+152
View File
@@ -0,0 +1,152 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "byte-code.h"
#include "ecma-helpers.h"
#include "ecma-extended-info.h"
#if JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmaextendedinfo Extended info
* @{
*/
/**
* Decodes an uint32_t number, and updates the buffer position.
*
* @return the decoded value
*/
uint32_t
ecma_extended_info_decode_vlq (uint8_t **buffer_p) /**< [in/out] target buffer */
{
uint8_t *source_p = *buffer_p;
uint32_t value = 0;
do
{
source_p--;
value = (value << ECMA_EXTENDED_INFO_VLQ_SHIFT) | (*source_p & ECMA_EXTENDED_INFO_VLQ_MASK);
}
while (*source_p & ECMA_EXTENDED_INFO_VLQ_CONTINUE);
*buffer_p = source_p;
return value;
} /* ecma_extended_info_decode_vlq */
/**
* Encodes an uint32_t number into a buffer.
*/
void
ecma_extended_info_encode_vlq (uint8_t **buffer_p, /**< target buffer */
uint32_t value) /**< encoded value */
{
uint8_t *destination_p = *buffer_p - 1;
if (value <= ECMA_EXTENDED_INFO_VLQ_MASK)
{
*destination_p = (uint8_t) value;
*buffer_p = destination_p;
return;
}
uint32_t length = 0;
uint32_t current_value = value >> ECMA_EXTENDED_INFO_VLQ_SHIFT;
do
{
current_value >>= ECMA_EXTENDED_INFO_VLQ_SHIFT;
length++;
}
while (current_value > 0);
destination_p -= length;
*buffer_p = destination_p;
do
{
*destination_p++ = (uint8_t) (value | ECMA_EXTENDED_INFO_VLQ_CONTINUE);
value >>= ECMA_EXTENDED_INFO_VLQ_SHIFT;
}
while (value > 0);
**buffer_p &= ECMA_EXTENDED_INFO_VLQ_MASK;
} /* ecma_extended_info_encode_vlq */
/**
* Gets the encoded length of a number.
*
* @return encoded length
*/
uint32_t
ecma_extended_info_get_encoded_length (uint32_t value) /**< encoded value */
{
uint32_t length = 0;
do
{
value >>= ECMA_EXTENDED_INFO_VLQ_SHIFT;
length++;
}
while (value > 0);
return length;
} /* ecma_extended_info_get_encoded_length */
/**
* Get the extended info from a byte code
*
* @return pointer to the extended info
*/
uint8_t *
ecma_compiled_code_resolve_extended_info (const ecma_compiled_code_t *bytecode_header_p) /**< compiled code */
{
JERRY_ASSERT (bytecode_header_p != NULL);
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO);
ecma_value_t *base_p = ecma_compiled_code_resolve_arguments_start (bytecode_header_p);
#if JERRY_ESNEXT
if (CBC_FUNCTION_GET_TYPE (bytecode_header_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
{
base_p--;
}
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
{
base_p--;
}
#endif /* JERRY_ESNEXT */
#if JERRY_LINE_INFO
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_LINE_INFO)
{
base_p--;
}
#endif /* JERRY_LINE_INFO */
JERRY_ASSERT (((uint8_t *) base_p)[-1] != 0);
return ((uint8_t *) base_p) - 1;
} /* ecma_compiled_code_resolve_extended_info */
#endif /* JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING */
/**
* @}
* @}
*/
+58
View File
@@ -0,0 +1,58 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMA_EXTENDED_INFO_H
#define ECMA_EXTENDED_INFO_H
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmaextendedinfo Extended info
* @{
*/
#if JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING
#include "ecma-globals.h"
/**
* Vlq encoding: flag which is set for all bytes except the last one.
*/
#define ECMA_EXTENDED_INFO_VLQ_CONTINUE 0x80
/**
* Vlq encoding: mask to decode the number fragment.
*/
#define ECMA_EXTENDED_INFO_VLQ_MASK 0x7f
/**
* Vlq encoding: number of bits stored in a byte.
*/
#define ECMA_EXTENDED_INFO_VLQ_SHIFT 7
uint32_t ecma_extended_info_decode_vlq (uint8_t **buffer_p);
void ecma_extended_info_encode_vlq (uint8_t **buffer_p, uint32_t value);
uint32_t ecma_extended_info_get_encoded_length (uint32_t value);
uint8_t *ecma_compiled_code_resolve_extended_info (const ecma_compiled_code_t *bytecode_header_p);
#endif /* JERRY_ESNEXT || JERRY_FUNCTION_TO_STRING */
/**
* @}
* @}
*/
#endif /* !ECMA_EXTENDED_INFO_H */
+3 -3
View File
@@ -430,10 +430,10 @@ ecma_gc_mark_compiled_code (const ecma_compiled_code_t *compiled_code_p) /**< co
if (CBC_SCRIPT_GET_TYPE (script_p) == CBC_SCRIPT_USER_OBJECT)
{
cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p;
ecma_value_t user_value = CBC_SCRIPT_GET_USER_VALUE (script_p);
JERRY_ASSERT (ecma_is_value_object (script_user_p->user_value));
ecma_gc_set_object_visited (ecma_get_object_from_value (script_user_p->user_value));
JERRY_ASSERT (ecma_is_value_object (user_value));
ecma_gc_set_object_visited (ecma_get_object_from_value (user_value));
}
#if JERRY_BUILTIN_REALMS
+3
View File
@@ -130,6 +130,9 @@ typedef enum
#if JERRY_ESNEXT
ECMA_PARSE_INTERNAL_PRE_SCANNING = (1u << 16), /**< the parser is in pre-scanning mode */
#endif /* JERRY_ESNEXT */
#if JERRY_FUNCTION_TO_STRING
ECMA_PARSE_INTERNAL_HAS_4_BYTE_MARKER = (1u << 17), /**< source has 4 byte marker */
#endif /* JERRY_FUNCTION_TO_STRING */
#ifndef JERRY_NDEBUG
/**
* This flag represents an error in for in/of statements, which cannot be set
+1 -1
View File
@@ -443,7 +443,7 @@ ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string
converted_string_size += string_size;
JERRY_ASSERT (lit_is_valid_utf8_string (string_p, string_size));
JERRY_ASSERT (lit_is_valid_utf8_string (string_p, string_size, false));
lit_utf8_byte_t *data_p;
ecma_string_t *string_desc_p = ecma_new_ecma_string_from_utf8_buffer (converted_string_length,
+15 -27
View File
@@ -1527,14 +1527,14 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
if (type != CBC_SCRIPT_GENERIC)
{
script_size = sizeof (cbc_script_user_t);
script_size += sizeof (ecma_value_t);
if (type == CBC_SCRIPT_USER_VALUE)
{
cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p;
ecma_value_t user_value = CBC_SCRIPT_GET_USER_VALUE (script_p);
JERRY_ASSERT (!ecma_is_value_object (script_user_p->user_value));
ecma_free_value (script_user_p->user_value);
JERRY_ASSERT (!ecma_is_value_object (user_value));
ecma_free_value (user_value);
}
}
@@ -1542,6 +1542,16 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
ecma_deref_ecma_string (ecma_get_string_from_value (script_p->resource_name));
#endif /* JERRY_RESOURCE_NAME */
#if JERRY_FUNCTION_TO_STRING
ecma_deref_ecma_string (ecma_get_string_from_value (script_p->source_code));
if (script_p->refs_and_type & CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS)
{
ecma_deref_ecma_string (ecma_get_string_from_value (CBC_SCRIPT_GET_FUNCTION_ARGUMENTS (script_p, type)));
script_size += sizeof (ecma_value_t);
}
#endif /* JERRY_FUNCTION_TO_STRING */
jmem_heap_free_block (script_p, script_size);
}
@@ -1728,21 +1738,6 @@ ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_h
return base_p;
} /* ecma_compiled_code_resolve_function_name */
/**
* Get the extended info from a byte code
*
* @return extended info value
*/
uint32_t
ecma_compiled_code_resolve_extended_info (const ecma_compiled_code_t *bytecode_header_p) /**< compiled code */
{
JERRY_ASSERT (bytecode_header_p != NULL);
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO);
ecma_value_t *base_p = ecma_compiled_code_resolve_function_name (bytecode_header_p);
return base_p[-1];
} /* ecma_compiled_code_resolve_extended_info */
/**
* Get the tagged template collection of the compiled code
*
@@ -1755,9 +1750,7 @@ ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *b
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS);
ecma_value_t *base_p = ecma_compiled_code_resolve_function_name (bytecode_header_p);
int offset = (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO) ? -2 : -1;
return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, base_p[offset]);
return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, base_p[-1]);
} /* ecma_compiled_code_get_tagged_template_collection */
#endif /* JERRY_ESNEXT */
@@ -1783,11 +1776,6 @@ ecma_compiled_code_get_line_info (const ecma_compiled_code_t *bytecode_header_p)
base_p--;
}
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO)
{
base_p--;
}
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
{
base_p--;
-1
View File
@@ -539,7 +539,6 @@ const ecma_compiled_code_t *ecma_bytecode_get_from_value (ecma_value_t value);
ecma_value_t *ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode_header_p);
#if JERRY_ESNEXT
ecma_value_t *ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_header_p);
uint32_t ecma_compiled_code_resolve_extended_info (const ecma_compiled_code_t *bytecode_header_p);
ecma_collection_t *ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *bytecode_header_p);
#endif /* JERRY_ESNEXT */
#if JERRY_LINE_INFO
@@ -18,6 +18,7 @@
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-extended-info.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
@@ -79,9 +80,116 @@ enum
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_function_prototype_object_to_string (void)
ecma_builtin_function_prototype_object_to_string (ecma_object_t *func_obj_p) /**< this argument object */
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING__FUNCTION_TO_STRING);
if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_FUNCTION)
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE);
}
#if JERRY_FUNCTION_TO_STRING
const ecma_compiled_code_t *bytecode_p;
bytecode_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) func_obj_p);
ecma_value_t script_value = ((cbc_uint8_arguments_t *) bytecode_p)->script_value;
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
if (bytecode_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO)
{
uint8_t *extended_info_p = ecma_compiled_code_resolve_extended_info (bytecode_p);
uint8_t extended_info = *extended_info_p;
if (extended_info & CBC_EXTENDED_CODE_FLAGS_HAS_SOURCE_CODE_RANGE)
{
#if JERRY_ESNEXT
if (extended_info & CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH)
{
ecma_extended_info_decode_vlq (&extended_info_p);
}
#endif /* JERRY_ESNEXT */
uint32_t range_start = ecma_extended_info_decode_vlq (&extended_info_p);
uint32_t range_size = ecma_extended_info_decode_vlq (&extended_info_p);
ecma_value_t source_code;
if (!(extended_info & CBC_EXTENDED_CODE_FLAGS_SOURCE_CODE_IN_ARGUMENTS))
{
source_code = script_p->source_code;
#if JERRY_SNAPSHOT_EXEC
if (ecma_is_value_magic_string (source_code, LIT_MAGIC_STRING__EMPTY))
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA);
}
#endif /* JERRY_SNAPSHOT_EXEC */
}
else
{
#if JERRY_SNAPSHOT_EXEC
if (!(script_p->refs_and_type & CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS))
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA);
}
#else /* !JERRY_SNAPSHOT_EXEC */
JERRY_ASSERT (script_p->refs_and_type & CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS);
#endif /* JERRY_SNAPSHOT_EXEC */
source_code = CBC_SCRIPT_GET_FUNCTION_ARGUMENTS (script_p, CBC_SCRIPT_GET_TYPE (script_p));
}
ecma_string_t *result_string_p;
ECMA_STRING_TO_UTF8_STRING (ecma_get_string_from_value (source_code), source_p, source_size);
result_string_p = ecma_new_ecma_string_from_utf8 (source_p + range_start, range_size);
ECMA_FINALIZE_UTF8_STRING (source_p, source_size);
return ecma_make_string_value (result_string_p);
}
}
#if JERRY_SNAPSHOT_EXEC
if (!(script_p->refs_and_type & CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS))
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA);
}
#else /* !JERRY_SNAPSHOT_EXEC */
JERRY_ASSERT (script_p->refs_and_type & CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS);
#endif /* JERRY_SNAPSHOT_EXEC */
lit_magic_string_id_t header_id = LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON;
#if JERRY_ESNEXT
switch (CBC_FUNCTION_GET_TYPE (bytecode_p->status_flags))
{
case CBC_FUNCTION_GENERATOR:
{
header_id = LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_GENERATOR;
break;
}
case CBC_FUNCTION_ASYNC_GENERATOR:
{
header_id = LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC_GENERATOR;
break;
}
case CBC_FUNCTION_ASYNC:
{
header_id = LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC;
break;
}
}
#endif /* JERRY_ESNEXT */
ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (ecma_get_magic_string (header_id));
ecma_value_t function_arguments = CBC_SCRIPT_GET_FUNCTION_ARGUMENTS (script_p, CBC_SCRIPT_GET_TYPE (script_p));
ecma_stringbuilder_append (&builder, ecma_get_string_from_value (function_arguments));
ecma_stringbuilder_append_raw (&builder, (const lit_utf8_byte_t *) "\n) {\n", 5);
ecma_stringbuilder_append (&builder, ecma_get_string_from_value (script_p->source_code));
ecma_stringbuilder_append_raw (&builder, (const lit_utf8_byte_t *) "\n}", 2);
return ecma_make_string_value (ecma_stringbuilder_finalize (&builder));
#else /* !JERRY_FUNCTION_TO_STRING */
return ecma_make_magic_string_value (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA);
#endif /* JERRY_FUNCTION_TO_STRING */
} /* ecma_builtin_function_prototype_object_to_string */
/**
@@ -440,7 +548,7 @@ ecma_builtin_function_prototype_dispatch_routine (uint8_t builtin_routine_id, /*
{
case ECMA_FUNCTION_PROTOTYPE_TO_STRING:
{
return ecma_builtin_function_prototype_object_to_string ();
return ecma_builtin_function_prototype_object_to_string (func_obj_p);
}
case ECMA_FUNCTION_PROTOTYPE_APPLY:
{
@@ -284,7 +284,7 @@ ecma_builtin_global_object_decode_uri_helper (lit_utf8_byte_t *input_start_p, /*
}
if (!is_valid
|| !lit_is_valid_utf8_string (octets, bytes_count))
|| !lit_is_valid_utf8_string (octets, bytes_count, true))
{
ecma_stringbuilder_destroy (&builder);
return ecma_raise_uri_error (ECMA_ERR_MSG ("Invalid UTF8 string"));
@@ -17,6 +17,7 @@
#include "ecma-builtin-helpers.h"
#include "ecma-builtin-handlers.h"
#include "ecma-exceptions.h"
#include "ecma-extended-info.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
#include "ecma-helpers.h"
@@ -1739,11 +1740,7 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
uint32_t len;
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO)
{
len = CBC_EXTENDED_INFO_GET_LENGTH (ecma_compiled_code_resolve_extended_info (bytecode_data_p));
}
else if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
len = args_p->argument_end;
@@ -1754,6 +1751,16 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
len = args_p->argument_end;
}
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO)
{
uint8_t *extended_info_p = ecma_compiled_code_resolve_extended_info (bytecode_data_p);
if (*extended_info_p & CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH)
{
len = ecma_extended_info_decode_vlq (&extended_info_p);
}
}
/* Set tag bit to represent initialized 'length' property */
ECMA_SET_FIRST_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp);
ecma_property_t *value_prop_p;
+1 -1
View File
@@ -30,7 +30,7 @@ extern "C"
/**
* Jerry snapshot format version.
*/
#define JERRY_SNAPSHOT_VERSION (67u)
#define JERRY_SNAPSHOT_VERSION (68u)
/**
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
+1
View File
@@ -112,6 +112,7 @@ typedef enum
JERRY_FEATURE_PROMISE_CALLBACK, /**< Promise callback support */
JERRY_FEATURE_MODULE, /**< Module support */
JERRY_FEATURE_WEAKREF, /**< WeakRef support */
JERRY_FEATURE_FUNCTION_TO_STRING, /**< function toString support */
JERRY_FEATURE__COUNT /**< number of features. NOTE: must be at the end of the list */
} jerry_feature_t;
+51 -6
View File
@@ -1003,7 +1003,13 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UTC_MILLISECONDS_UL, "setUTCMilliseco
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_LOCALE_DATE_STRING_UL, "toLocaleDateString")
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_LOCALE_TIME_STRING_UL, "toLocaleTimeString")
#endif
#if JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON, "function anonymous(")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_OWN_PROPERTY_NAMES_UL, "getOwnPropertyNames")
#if JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_GENERATOR, "function* anonymous(")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PROPERTY_IS_ENUMERABLE_UL, "propertyIsEnumerable")
#if JERRY_ESNEXT
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_OWN_PROPERTY_SYMBOLS_UL, "getOwnPropertySymbols")
@@ -1011,10 +1017,20 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ASYNC_GENERATOR_FUNCTION_UL, "AsyncGenera
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REGEXP_STRING_ITERATOR_UL, "RegExp String Iterator")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL, "getOwnPropertyDescriptor")
#if JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC, "async function anonymous(")
#endif
#if JERRY_ESNEXT
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTORS_UL, "getOwnPropertyDescriptors")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING__FUNCTION_TO_STRING, "function(){/* ecmascript */}")
#if JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC_GENERATOR, "async function* anonymous(")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE, "function () { [native code] }")
#if JERRY_FUNCTION_TO_STRING && JERRY_SNAPSHOT_EXEC \
|| !(JERRY_FUNCTION_TO_STRING)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA, "function () { /* ecmascript */ }")
#endif
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (0, LIT_MAGIC_STRING__EMPTY)
#if JERRY_ESNEXT
@@ -1213,8 +1229,16 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (17, LIT_MAGIC_STRING_GET_TIMEZONE_OFFSE
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (17, LIT_MAGIC_STRING_PREVENT_EXTENSIONS_UL)
#endif
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (18, LIT_MAGIC_STRING_DECODE_URI_COMPONENT)
#if JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (19, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON)
#else
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (19, LIT_MAGIC_STRING_GET_OWN_PROPERTY_NAMES_UL)
#endif
#if JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (20, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_GENERATOR)
#else
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (20, LIT_MAGIC_STRING_PROPERTY_IS_ENUMERABLE_UL)
#endif
#if JERRY_ESNEXT
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (21, LIT_MAGIC_STRING_GET_OWN_PROPERTY_SYMBOLS_UL)
#else
@@ -1227,11 +1251,32 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (22, LIT_MAGIC_STRING_GET_OWN_PROPERTY_D
#endif
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (23, LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (24, LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL)
#if JERRY_ESNEXT
#if JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (25, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC)
#elif JERRY_ESNEXT
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (25, LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTORS_UL)
#elif JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (25, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC_GENERATOR)
#else
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (25, LIT_MAGIC_STRING__FUNCTION_TO_STRING)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (25, LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE)
#endif
#if JERRY_ESNEXT && JERRY_FUNCTION_TO_STRING
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (26, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC_GENERATOR)
#else
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (26, LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE)
#endif
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (27, LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (28, LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (29, LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE)
#if JERRY_FUNCTION_TO_STRING && JERRY_SNAPSHOT_EXEC \
|| !(JERRY_FUNCTION_TO_STRING)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (30, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA)
#endif
#if JERRY_FUNCTION_TO_STRING && JERRY_SNAPSHOT_EXEC \
|| !(JERRY_FUNCTION_TO_STRING)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (31, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA)
#endif
#if JERRY_FUNCTION_TO_STRING && JERRY_SNAPSHOT_EXEC \
|| !(JERRY_FUNCTION_TO_STRING)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (32, LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA)
#endif
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (26, LIT_MAGIC_STRING__FUNCTION_TO_STRING)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (27, LIT_MAGIC_STRING__FUNCTION_TO_STRING)
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (28, LIT_MAGIC_STRING__FUNCTION_TO_STRING)
+6 -1
View File
@@ -406,10 +406,15 @@ LIT_MAGIC_STRING_SET_UTC_MILLISECONDS_UL = "setUTCMilliseconds"
LIT_MAGIC_STRING_TO_LOCALE_DATE_STRING_UL = "toLocaleDateString"
LIT_MAGIC_STRING_TO_LOCALE_TIME_STRING_UL = "toLocaleTimeString"
LIT_MAGIC_STRING_GET_OWN_PROPERTY_NAMES_UL = "getOwnPropertyNames"
LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON = "function anonymous("
LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_GENERATOR = "function* anonymous("
LIT_MAGIC_STRING_PROPERTY_IS_ENUMERABLE_UL = "propertyIsEnumerable"
LIT_MAGIC_STRING_GET_OWN_PROPERTY_SYMBOLS_UL = "getOwnPropertySymbols"
LIT_MAGIC_STRING_REGEXP_STRING_ITERATOR_UL = "RegExp String Iterator"
LIT_MAGIC_STRING_ASYNC_GENERATOR_FUNCTION_UL = "AsyncGeneratorFunction"
LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL = "getOwnPropertyDescriptor"
LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC = "async function anonymous("
LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTORS_UL = "getOwnPropertyDescriptors"
LIT_MAGIC_STRING__FUNCTION_TO_STRING = "function(){/* ecmascript */}"
LIT_MAGIC_STRING_FUNCTION_TO_STRING_ANON_ASYNC_GENERATOR = "async function* anonymous("
LIT_MAGIC_STRING_FUNCTION_TO_STRING_NATIVE = "function () { [native code] }"
LIT_MAGIC_STRING_FUNCTION_TO_STRING_ECMA = "function () { /* ecmascript */ }"
+16 -15
View File
@@ -22,14 +22,14 @@
*
* NOTE:
* Isolated surrogates are allowed.
* Correct pair of surrogates is not allowed, it should be represented as 4-byte utf-8 character.
*
* @return true if utf-8 string is well-formed
* false otherwise
*/
bool
lit_is_valid_utf8_string (const lit_utf8_byte_t *utf8_buf_p, /**< utf-8 string */
lit_utf8_size_t buf_size) /**< string size */
lit_utf8_size_t buf_size, /**< string size */
bool is_strict) /**< true if surrogate pairs are not allowed */
{
lit_utf8_size_t idx = 0;
@@ -95,21 +95,22 @@ lit_is_valid_utf8_string (const lit_utf8_byte_t *utf8_buf_p, /**< utf-8 string *
return false;
}
if (code_point >= LIT_UTF16_HIGH_SURROGATE_MIN
&& code_point <= LIT_UTF16_HIGH_SURROGATE_MAX)
{
is_prev_code_point_high_surrogate = true;
}
else if (code_point >= LIT_UTF16_LOW_SURROGATE_MIN
&& code_point <= LIT_UTF16_LOW_SURROGATE_MAX
&& is_prev_code_point_high_surrogate)
{
/* sequence of high and low surrogate is not allowed */
return false;
}
else
if (is_strict)
{
is_prev_code_point_high_surrogate = false;
if (code_point >= LIT_UTF16_HIGH_SURROGATE_MIN
&& code_point <= LIT_UTF16_HIGH_SURROGATE_MAX)
{
is_prev_code_point_high_surrogate = true;
}
else if (code_point >= LIT_UTF16_LOW_SURROGATE_MIN
&& code_point <= LIT_UTF16_LOW_SURROGATE_MAX
&& is_prev_code_point_high_surrogate)
{
/* sequence of high and low surrogate is not allowed */
return false;
}
}
idx += extra_bytes_count;
+1 -1
View File
@@ -84,7 +84,7 @@
#define LIT_UTF8_FIRST_BYTE_MAX (0xF8)
/* validation */
bool lit_is_valid_utf8_string (const lit_utf8_byte_t *utf8_buf_p, lit_utf8_size_t buf_size);
bool lit_is_valid_utf8_string (const lit_utf8_byte_t *utf8_buf_p, lit_utf8_size_t buf_size, bool strict);
bool lit_is_valid_cesu8_string (const lit_utf8_byte_t *cesu8_buf_p, lit_utf8_size_t buf_size);
/* checks */
+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;
+1 -1
View File
@@ -4573,7 +4573,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (CBC_SCRIPT_GET_TYPE (script_p) != CBC_SCRIPT_GENERIC)
{
user_value = ((cbc_script_user_t *) script_p)->user_value;
user_value = CBC_SCRIPT_GET_USER_VALUE (script_p);
}
#if JERRY_SNAPSHOT_EXEC
}