mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
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:
parent
1c6b18ecdf
commit
6649940ea6
@ -175,6 +175,8 @@ Possible compile time enabled feature types:
|
||||
- JERRY_FEATURE_GLOBAL_THIS - GlobalThisValue support
|
||||
- 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
|
||||
|
||||
*New in version 2.0*.
|
||||
|
||||
@ -183,7 +185,8 @@ Possible compile time enabled feature types:
|
||||
*Changed in version 2.4*: Added `JERRY_FEATURE_BIGINT`, `JERRY_FEATURE_REALM` values.
|
||||
|
||||
*Changed in version [[NEXT_RELEASE]]*: Added `JERRY_FEATURE_VM_THROW`, `JERRY_FEATURE_GLOBAL_THIS`,
|
||||
`JERRY_FEATURE_PROMISE_CALLBACK`, and `JERRY_FEATURE_MODULE` values.
|
||||
`JERRY_FEATURE_PROMISE_CALLBACK`, and `JERRY_FEATURE_MODULE`,
|
||||
`JERRY_FEATURE_WEAKREF`, and `JERRY_FEATURE_FUNCTION_TO_STRING` values.
|
||||
|
||||
## jerry_container_type_t
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
/**
|
||||
|
||||
@ -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
jerry-core/ecma/base/ecma-extended-info.c
Normal file
152
jerry-core/ecma/base/ecma-extended-info.c
Normal 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
jerry-core/ecma/base/ecma-extended-info.h
Normal file
58
jerry-core/ecma/base/ecma-extended-info.h
Normal 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 */
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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--;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 */ }"
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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,
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
188
tests/jerry/es.next/function-prototype-tostring.js
Normal file
188
tests/jerry/es.next/function-prototype-tostring.js
Normal file
@ -0,0 +1,188 @@
|
||||
// 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.
|
||||
|
||||
function check() {}
|
||||
|
||||
if (check.toString() !== "function () { /* ecmascript */ }")
|
||||
{
|
||||
var a, b, o, c, f;
|
||||
|
||||
/* Function statements. */
|
||||
|
||||
a = 6; function f1(a,b=1,c) { return a /* comment */ + b + c } b = 7
|
||||
assert(f1.toString() === "function f1(a,b=1,c) { return a /* comment */ + b + c }")
|
||||
|
||||
a = 6; function * f2(a,b,c=1) {
|
||||
function x() {}
|
||||
} b = 7
|
||||
assert(f2.toString() === "function * f2(a,b,c=1) {\n function x() {}\n }")
|
||||
|
||||
a = 6;async function f3 ( a , b , c ) { } b = 7
|
||||
assert(f3.toString() === "async function f3 ( a , b , c ) { }")
|
||||
|
||||
a = 6;async/**/function*f4(a,b,c){} b = 7
|
||||
assert(f4.toString() === "async/**/function*f4(a,b,c){}")
|
||||
|
||||
/* Object initializers. */
|
||||
|
||||
o = {f(a) { return a }}
|
||||
assert(o.f.toString() === "f(a) { return a }")
|
||||
|
||||
o = {f:function(a){/**/}}
|
||||
assert(o.f.toString() === "function(a){/**/}")
|
||||
|
||||
o = { [function(){ return 'f' }()] (a = function() {}) {} }
|
||||
assert(o.f.toString() === "[function(){ return 'f' }()] (a = function() {}) {}")
|
||||
|
||||
o = {* f(a) {}}
|
||||
assert(o.f.toString() === "* f(a) {}")
|
||||
|
||||
o = {*[function(){ return 'f' }()](a) {}}
|
||||
assert(o.f.toString() === "*[function(){ return 'f' }()](a) {}")
|
||||
|
||||
o = {async/**/f(a) {}}
|
||||
assert(o.f.toString() === "async/**/f(a) {}")
|
||||
|
||||
o = {/**/async [function(){ return 'f' }()](a) {}/**/}
|
||||
assert(o.f.toString() === "async [function(){ return 'f' }()](a) {}")
|
||||
|
||||
o = {a:1,async/**/*/**/f(a) {},b:1}
|
||||
assert(o.f.toString() === "async/**/*/**/f(a) {}")
|
||||
|
||||
o = {async *//
|
||||
[function(){ return 'f' }()](a) {}/**/}
|
||||
assert(o.f.toString() === "async *//\n [function(){ return 'f' }()](a) {}")
|
||||
|
||||
o = { get a() {return/**/6} }
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").get.toString() === "get a() {return/**/6}")
|
||||
|
||||
o = { get[function(){ return 'a' }()](){} }
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").get.toString() === "get[function(){ return 'a' }()](){}")
|
||||
|
||||
o = { set a(v) {/**/} }
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").set.toString() === "set a(v) {/**/}")
|
||||
|
||||
o = {/**/set/**/[function(){ return 'a' }()]/**/(v) {/**/}/**/}
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").set.toString() === "set/**/[function(){ return 'a' }()]/**/(v) {/**/}")
|
||||
|
||||
/* Class static functions. */
|
||||
|
||||
c = class { static/**/f() {}/**/ }
|
||||
assert(c.f.toString() === "f() {}")
|
||||
|
||||
c = class { static[function(){ return 'f' }()]() {} }
|
||||
assert(c.f.toString() === "[function(){ return 'f' }()]() {}")
|
||||
|
||||
c = class { static *f() {} }
|
||||
assert(c.f.toString() === "*f() {}")
|
||||
|
||||
c = class {/**/static * [function(){ return 'f' }()](a=6){}/**/}
|
||||
assert(c.f.toString() === "* [function(){ return 'f' }()](a=6){}")
|
||||
|
||||
c = class { static/**/async f() {} }
|
||||
assert(c.f.toString() === "async f() {}")
|
||||
|
||||
c = class {static async[function(){ return 'f' }()]() {/**/}}
|
||||
assert(c.f.toString() === "async[function(){ return 'f' }()]() {/**/}")
|
||||
|
||||
c = class { static async*f() {}}
|
||||
assert(c.f.toString() === "async*f() {}")
|
||||
|
||||
c = class { static async*/**/[function(){ return 'f' }()](){} }
|
||||
assert(c.f.toString() === "async*/**/[function(){ return 'f' }()](){}")
|
||||
|
||||
c = class { static/**/get/**/a() {}}
|
||||
assert(Object.getOwnPropertyDescriptor(c, "a").get.toString() === "get/**/a() {}")
|
||||
|
||||
c = class {static set a(v){}}
|
||||
assert(Object.getOwnPropertyDescriptor(c, "a").set.toString() === "set a(v){}")
|
||||
|
||||
c = class { static get[function(){ return 'a' }()](){} }
|
||||
assert(Object.getOwnPropertyDescriptor(c, "a").get.toString() === "get[function(){ return 'a' }()](){}")
|
||||
|
||||
c = class { static set[function(){ return 'a' }()](v){}//
|
||||
}
|
||||
assert(Object.getOwnPropertyDescriptor(c, "a").set.toString() === "set[function(){ return 'a' }()](v){}")
|
||||
|
||||
/* Class functions. */
|
||||
|
||||
o = Object.getPrototypeOf(new class {/**/f() {}/**/})
|
||||
assert(o.f.toString() === "f() {}")
|
||||
|
||||
o = Object.getPrototypeOf(new class {[function(){ return 'f' }()](){}})
|
||||
assert(o.f.toString() === "[function(){ return 'f' }()](){}")
|
||||
|
||||
o = Object.getPrototypeOf(new class { * /**/ f() {} })
|
||||
assert(o.f.toString() === "* /**/ f() {}")
|
||||
|
||||
o = Object.getPrototypeOf(new class { * [function(){ return 'f' }()]/**/(){} })
|
||||
assert(o.f.toString() === "* [function(){ return 'f' }()]/**/(){}")
|
||||
|
||||
o = Object.getPrototypeOf(new class {async f() {}})
|
||||
assert(o.f.toString() === "async f() {}")
|
||||
|
||||
o = Object.getPrototypeOf(new class {async[function(){ return 'f' }()](){}})
|
||||
assert(o.f.toString() === "async[function(){ return 'f' }()](){}")
|
||||
|
||||
o = Object.getPrototypeOf(new class {/**/get/**/a() {}/**/})
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").get.toString() === "get/**/a() {}")
|
||||
|
||||
o = Object.getPrototypeOf(new class { set a(v){} })
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").set.toString() === "set a(v){}")
|
||||
|
||||
o = Object.getPrototypeOf(new class {/**/get/**/[function(){ return 'a' }()]() {}/**/})
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").get.toString() === "get/**/[function(){ return 'a' }()]() {}")
|
||||
|
||||
o = Object.getPrototypeOf(new class { set/**/[function(){ return 'a' }()]( v ){} })
|
||||
assert(Object.getOwnPropertyDescriptor(o, "a").set.toString() === "set/**/[function(){ return 'a' }()]( v ){}")
|
||||
|
||||
/* Function creators. */
|
||||
f = Function("a,b", "return a + b")
|
||||
assert(f.toString() === "function anonymous(a,b\n) {\nreturn a + b\n}")
|
||||
|
||||
f = Function("", "")
|
||||
assert(f.toString() === "function anonymous(\n) {\n\n}")
|
||||
|
||||
f = function*(){}.constructor("a,b", "c", "yield a; return b + c")
|
||||
assert(f.toString() === "function* anonymous(a,b,c\n) {\nyield a; return b + c\n}")
|
||||
|
||||
f = async function(){}.constructor("a", "return a + 'x'")
|
||||
assert(f.toString() === "async function anonymous(a\n) {\nreturn a + 'x'\n}")
|
||||
|
||||
f = async function*(){}.constructor("a=3", "return a")
|
||||
assert(f.toString() === "async function* anonymous(a=3\n) {\nreturn a\n}")
|
||||
|
||||
f = Function("a = function(x) { return x + 3 }", "return a")
|
||||
assert(f().toString() === "function(x) { return x + 3 }")
|
||||
|
||||
f = Function("return function(x) { return x + 3 }")
|
||||
assert(f().toString() === "function(x) { return x + 3 }")
|
||||
|
||||
/* Arrow functions. */
|
||||
f = x => x + 1/**/
|
||||
assert(f.toString() === "x => x + 1")
|
||||
|
||||
f =x => { return x + 1 }/**/
|
||||
assert(f.toString() === "x => { return x + 1 }")
|
||||
|
||||
f = (/**/) => 'x' //
|
||||
+ y
|
||||
assert(f.toString() === "(/**/) => 'x' //\n + y")
|
||||
|
||||
f = async x => x + 1
|
||||
assert(f.toString() === "async x => x + 1")
|
||||
|
||||
f =/**/async (x,/**/y)=>/**/null
|
||||
assert(f.toString() === "async (x,/**/y)=>/**/null")
|
||||
}
|
||||
@ -149,7 +149,9 @@ new delete_test ();
|
||||
|
||||
function binary_test_1 () {
|
||||
/*/ new.target is converted to string */
|
||||
assert ((new.target + 1) === "function(){/* ecmascript */}1");
|
||||
var str = (new.target + 1);
|
||||
assert (str.substring(0, 8) === "function"
|
||||
&& str.substring(str.length - 2, str.length) === "}1");
|
||||
}
|
||||
function binary_test_2 () { assert (isNaN (new.target - 3)); }
|
||||
function binary_test_3 () { assert (isNaN (new.target * 2)); }
|
||||
|
||||
@ -14,4 +14,6 @@
|
||||
|
||||
var str = 'for (let i=0; i<(eval("1; function x() { }; 2;")); x - i++) { x += delete x;}'
|
||||
|
||||
assert(eval(str) === 'function(){/* ecmascript */}true');
|
||||
var e = eval(str)
|
||||
assert(e === 'function x() { }true'
|
||||
|| e === 'function () { /* ecmascript */ }true');
|
||||
|
||||
@ -12,16 +12,27 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
assert (Math.cos.toString() === "function(){/* ecmascript */}");
|
||||
assert (Math.cos.toString() === "function () { [native code] }");
|
||||
|
||||
var has_toString = none.toString() != "function () { /* ecmascript */ }"
|
||||
|
||||
function check(f, expected)
|
||||
{
|
||||
assert (f.toString() === (has_toString ? expected : "function () { /* ecmascript */ }"))
|
||||
}
|
||||
|
||||
function none() { return 1; }
|
||||
assert (none.toString() === "function(){/* ecmascript */}");
|
||||
check (none, "function none() { return 1; }")
|
||||
assert (none.bind({}).toString() === "function () { [native code] }")
|
||||
|
||||
function single(b) { return 1; }
|
||||
assert (single.toString() === "function(){/* ecmascript */}");
|
||||
check (single, "function single(b) { return 1; }")
|
||||
assert (single.bind({}).toString() === "function () { [native code] }")
|
||||
|
||||
function multiple(a,b) { return 1; }
|
||||
assert (multiple.toString() === "function(){/* ecmascript */}");
|
||||
check (multiple, "function multiple(a,b) { return 1; }")
|
||||
assert (multiple.bind({}).toString() === "function () { [native code] }")
|
||||
|
||||
function lots(a,b,c,d,e,f,g,h,i,j,k) { return 1; }
|
||||
assert (lots.toString() === "function(){/* ecmascript */}");
|
||||
check (lots, "function lots(a,b,c,d,e,f,g,h,i,j,k) { return 1; }")
|
||||
assert (lots.bind({}).toString() === "function () { [native code] }")
|
||||
|
||||
@ -28,60 +28,9 @@
|
||||
<test id="built-ins/BigInt/asUintN/length.js"><reason></reason></test>
|
||||
<test id="built-ins/BigInt/asUintN/name.js"><reason></reason></test>
|
||||
<test id="built-ins/BigInt/asUintN/order-of-steps.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/AsyncFunction.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/Function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/GeneratorFunction.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/arrow-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-arrow-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-function-declaration.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-function-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-method-class-expression-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-method-class-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-method-class-statement-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-method-class-statement.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-method-object.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/bound-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/built-in-function-object.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/class-declaration-complex-heritage.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/class-declaration-explicit-ctor.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/class-declaration-implicit-ctor.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/class-expression-explicit-ctor.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/class-expression-implicit-ctor.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/function-declaration-non-simple-parameter-list.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/function-declaration.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/function-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/generator-function-declaration.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/generator-function-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/generator-method.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/getter-class-expression-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/getter-class-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/getter-class-statement-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/getter-class-statement.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/getter-object.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/line-terminator-normalisation-CR-LF.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/line-terminator-normalisation-CR.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/line-terminator-normalisation-LF.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/method-class-expression-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/method-class-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/method-class-statement-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/method-class-statement.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/method-computed-property-name.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/method-object.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-arrow-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-async-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-async-method-definition.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-bound-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-class.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-function-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-generator-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-method-definition.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/setter-class-expression-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/setter-class-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/setter-class-statement-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/setter-class-statement.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/setter-object.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/symbol-named-builtins.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/unicode.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/well-known-intrinsic-object-functions.js"><reason></reason></test>
|
||||
<test id="built-ins/GeneratorFunction/instance-yield-expr-in-param.js"><reason></reason></test>
|
||||
<test id="built-ins/GeneratorPrototype/return/from-state-completed.js"><reason></reason></test>
|
||||
@ -6678,16 +6627,6 @@
|
||||
<test id="built-ins/AsyncGeneratorPrototype/throw/this-val-not-object.js"><reason></reason></test>
|
||||
<test id="built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined-with-gc.js"><reason></reason></test>
|
||||
<test id="built-ins/FinalizationRegistry/prototype/cleanupSome/return-undefined.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/AsyncGenerator.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-generator-declaration.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-generator-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-generator-method-class-expression-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-generator-method-class-expression.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-generator-method-class-statement-static.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-generator-method-class-statement.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/async-generator-method-object.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-async-generator-function.js"><reason></reason></test>
|
||||
<test id="built-ins/Function/prototype/toString/proxy-async-generator-method-definition.js"><reason></reason></test>
|
||||
<test id="language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-multiple.js"><reason></reason></test>
|
||||
<test id="language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-null.js"><reason></reason></test>
|
||||
<test id="language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-single-args.js"><reason></reason></test>
|
||||
|
||||
@ -120,6 +120,8 @@ def get_arguments():
|
||||
help='enable the jerry debugger (%(choices)s)')
|
||||
coregrp.add_argument('--js-parser', metavar='X', choices=['ON', 'OFF'], type=str.upper,
|
||||
help='enable js-parser (%(choices)s)')
|
||||
coregrp.add_argument('--function-to-string', metavar='X', choices=['ON', 'OFF'], type=str.upper,
|
||||
help='enable function toString (%(choices)s)')
|
||||
coregrp.add_argument('--line-info', metavar='X', choices=['ON', 'OFF'], type=str.upper,
|
||||
help='provide line info (%(choices)s)')
|
||||
coregrp.add_argument('--logging', metavar='X', choices=['ON', 'OFF'], type=str.upper,
|
||||
@ -208,6 +210,7 @@ def generate_build_options(arguments):
|
||||
build_options_append('JERRY_EXTERNAL_CONTEXT', arguments.external_context)
|
||||
build_options_append('JERRY_DEBUGGER', arguments.jerry_debugger)
|
||||
build_options_append('JERRY_PARSER', arguments.js_parser)
|
||||
build_options_append('JERRY_FUNCTION_TO_STRING', arguments.function_to_string)
|
||||
build_options_append('JERRY_LINE_INFO', arguments.line_info)
|
||||
build_options_append('JERRY_LOGGING', arguments.logging)
|
||||
build_options_append('JERRY_GLOBAL_HEAP_SIZE', arguments.mem_heap)
|
||||
|
||||
@ -42,7 +42,7 @@ def skip_if(condition, desc):
|
||||
OPTIONS_COMMON = ['--lto=off']
|
||||
OPTIONS_PROFILE_MIN = ['--profile=minimal']
|
||||
OPTIONS_PROFILE_ES51 = ['--profile=es5.1']
|
||||
OPTIONS_PROFILE_ESNEXT = ['--profile=es.next']
|
||||
OPTIONS_PROFILE_ESNEXT = ['--profile=es.next', '--function-to-string=on']
|
||||
OPTIONS_STACK_LIMIT = ['--stack-limit=96']
|
||||
OPTIONS_GC_MARK_LIMIT = ['--gc-mark-limit=16']
|
||||
OPTIONS_MEM_STRESS = ['--mem-stress-test=on']
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user