Create extend byte code flags with function types. (#3802)
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -161,21 +161,21 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
|
||||
ecma_compiled_code_t *copied_code_p = (ecma_compiled_code_t *) copied_code_start_p;
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
|
||||
{
|
||||
const char * const error_message_p = "Unsupported feature: tagged template literals.";
|
||||
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR)
|
||||
if (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags) == CBC_FUNCTION_CONSTRUCTOR)
|
||||
{
|
||||
globals_p->class_found = true;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
|
||||
if (!CBC_IS_FUNCTION (compiled_code_p->status_flags))
|
||||
{
|
||||
/* Regular expression. */
|
||||
if (globals_p->snapshot_buffer_write_offset + sizeof (ecma_compiled_code_t) > snapshot_buffer_size)
|
||||
@@ -228,7 +228,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
|
||||
JERRY_ASSERT (compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
|
||||
JERRY_ASSERT (CBC_IS_FUNCTION (compiled_code_p->status_flags));
|
||||
|
||||
if (!snapshot_write_to_buffer_by_offset (snapshot_buffer_p,
|
||||
snapshot_buffer_size,
|
||||
@@ -345,7 +345,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
|
||||
uint8_t *copied_code_start_p = snapshot_buffer_p + globals_p->snapshot_buffer_write_offset;
|
||||
ecma_compiled_code_t *copied_code_p = (ecma_compiled_code_t *) copied_code_start_p;
|
||||
|
||||
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
|
||||
if (!CBC_IS_FUNCTION (compiled_code_p->status_flags))
|
||||
{
|
||||
/* Regular expression literals are not supported. */
|
||||
const char * const error_message_p = "Regular expression literals are not supported.";
|
||||
@@ -454,7 +454,7 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
|
||||
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
|
||||
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
if (CBC_IS_FUNCTION (bytecode_p->status_flags))
|
||||
{
|
||||
ecma_value_t *literal_start_p;
|
||||
uint32_t const_literal_end;
|
||||
@@ -549,9 +549,8 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
|
||||
if (!CBC_IS_FUNCTION (bytecode_p->status_flags))
|
||||
{
|
||||
|
||||
const uint8_t *regex_start_p = ((const uint8_t *) bytecode_p) + sizeof (ecma_compiled_code_t);
|
||||
|
||||
/* Real size is stored in refs. */
|
||||
@@ -564,10 +563,10 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
|
||||
return (ecma_compiled_code_t *) re_bytecode_p;
|
||||
}
|
||||
#else /* !ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
JERRY_ASSERT (CBC_IS_FUNCTION (bytecode_p->status_flags));
|
||||
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
|
||||
JERRY_ASSERT (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
|
||||
|
||||
size_t header_size;
|
||||
uint32_t argument_end;
|
||||
uint32_t const_literal_end;
|
||||
@@ -620,13 +619,13 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
/* function name */
|
||||
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
|
||||
if (CBC_FUNCTION_GET_TYPE (bytecode_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
|
||||
{
|
||||
extra_bytes += (uint32_t) sizeof (ecma_value_t);
|
||||
}
|
||||
|
||||
/* tagged template literals */
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
|
||||
{
|
||||
extra_bytes += (uint32_t) sizeof (ecma_value_t);
|
||||
}
|
||||
@@ -1083,7 +1082,7 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
const ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
|
||||
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
|
||||
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
if (CBC_IS_FUNCTION (bytecode_p->status_flags)
|
||||
&& !(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
|
||||
{
|
||||
const ecma_value_t *literal_start_p;
|
||||
@@ -1149,7 +1148,7 @@ update_literal_offsets (uint8_t *buffer_p, /**< [in,out] snapshot buffer start *
|
||||
const ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
|
||||
uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
|
||||
|
||||
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
if (CBC_IS_FUNCTION (bytecode_p->status_flags)
|
||||
&& !(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
|
||||
{
|
||||
ecma_value_t *literal_start_p;
|
||||
|
||||
@@ -683,7 +683,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_p);
|
||||
|
||||
if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
|
||||
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ARROW)
|
||||
{
|
||||
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
|
||||
|
||||
@@ -1201,7 +1201,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
ext_func_p->u.function.bytecode_cp));
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
|
||||
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ARROW)
|
||||
{
|
||||
ecma_free_value_if_not_object (((ecma_arrow_function_t *) object_p)->this_binding);
|
||||
ecma_free_value_if_not_object (((ecma_arrow_function_t *) object_p)->new_target);
|
||||
|
||||
@@ -963,8 +963,8 @@ typedef struct
|
||||
uint16_t size; /**< real size >> JMEM_ALIGNMENT_LOG */
|
||||
uint16_t refs; /**< reference counter for the byte code */
|
||||
uint16_t status_flags; /**< various status flags:
|
||||
* CBC_CODE_FLAGS_FUNCTION flag tells whether
|
||||
* the byte code is function or regular expression.
|
||||
* CBC_IS_FUNCTION check tells whether the byte code
|
||||
* is function or regular expression.
|
||||
* If function, the other flags must be CBC_CODE_FLAGS...
|
||||
* If regexp, the other flags must be RE_FLAG... */
|
||||
} ecma_compiled_code_t;
|
||||
|
||||
@@ -1367,7 +1367,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
if (CBC_IS_FUNCTION (bytecode_p->status_flags))
|
||||
{
|
||||
ecma_value_t *literal_start_p = NULL;
|
||||
uint32_t literal_end;
|
||||
@@ -1439,7 +1439,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
#endif /* ENABLED (JERRY_DEBUGGER) */
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
|
||||
{
|
||||
ecma_collection_t *collection_p = ecma_compiled_code_get_tagged_template_collection (bytecode_p);
|
||||
|
||||
@@ -1477,7 +1477,7 @@ ecma_collection_t *
|
||||
ecma_compiled_code_get_tagged_template_collection (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_FLAG_HAS_TAGGED_LITERALS);
|
||||
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);
|
||||
|
||||
@@ -1539,7 +1539,7 @@ ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_h
|
||||
ecma_value_t *base_p = ecma_compiled_code_resolve_arguments_start (bytecode_header_p);
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
|
||||
if (CBC_FUNCTION_GET_TYPE (bytecode_header_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
|
||||
{
|
||||
base_p--;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
|
||||
uint32_t const_literal_end;
|
||||
uint32_t literal_end;
|
||||
|
||||
JERRY_ASSERT (compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
|
||||
JERRY_ASSERT (CBC_IS_FUNCTION (compiled_code_p->status_flags));
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
@@ -377,7 +377,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
|
||||
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||
literal_p[i]);
|
||||
|
||||
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
if (CBC_IS_FUNCTION (bytecode_p->status_flags)
|
||||
&& bytecode_p != compiled_code_p)
|
||||
{
|
||||
ecma_save_literals_add_compiled_code (bytecode_p, lit_pool_p);
|
||||
@@ -570,7 +570,7 @@ ecma_snapshot_resolve_serializable_values (ecma_compiled_code_t *compiled_code_p
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
/* function name */
|
||||
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
|
||||
if (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
|
||||
{
|
||||
base_p--;
|
||||
}
|
||||
|
||||
@@ -602,9 +602,9 @@ ecma_op_function_is_generator (ecma_object_t *obj_p) /**< object */
|
||||
&& !ecma_get_object_is_builtin (obj_p))
|
||||
{
|
||||
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
|
||||
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
|
||||
|
||||
return (bytecode_data_p->status_flags & CBC_CODE_FLAGS_GENERATOR) != 0;
|
||||
return CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_GENERATOR;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -844,18 +844,12 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
uint16_t status_flags = bytecode_data_p->status_flags;
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
bool is_construct_call = JERRY_CONTEXT (current_new_target) != NULL;
|
||||
if (JERRY_UNLIKELY (status_flags & (CBC_CODE_FLAGS_CLASS_CONSTRUCTOR | CBC_CODE_FLAGS_GENERATOR)))
|
||||
{
|
||||
if (!is_construct_call && (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
|
||||
}
|
||||
uint16_t function_type = CBC_FUNCTION_GET_TYPE (status_flags);
|
||||
|
||||
if ((status_flags & CBC_CODE_FLAGS_GENERATOR) && is_construct_call)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'."));
|
||||
}
|
||||
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_CONSTRUCTOR)
|
||||
&& JERRY_CONTEXT (current_new_target) == NULL)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
@@ -863,7 +857,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ecma_object_t *old_function_object_p = JERRY_CONTEXT (current_function_obj_p);
|
||||
|
||||
if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
|
||||
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_ARROW))
|
||||
{
|
||||
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
|
||||
|
||||
@@ -921,7 +915,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
}
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
// ECMAScript v6, 9.2.2.8
|
||||
if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
|
||||
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_CONSTRUCTOR))
|
||||
{
|
||||
ecma_value_t lexical_this;
|
||||
lexical_this = (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp) ? ECMA_VALUE_UNINITIALIZED
|
||||
@@ -1279,20 +1273,39 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
|
||||
|
||||
ecma_object_t *new_this_obj_p = NULL;
|
||||
ecma_value_t this_arg;
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
|
||||
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
|
||||
|
||||
if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
|
||||
if (!CBC_FUNCTION_IS_CONSTRUCTABLE (byte_code_p->status_flags))
|
||||
{
|
||||
if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
|
||||
const char *message_p;
|
||||
|
||||
switch (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor."));
|
||||
case CBC_FUNCTION_GENERATOR:
|
||||
{
|
||||
message_p = ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'.");
|
||||
break;
|
||||
}
|
||||
case CBC_FUNCTION_ARROW:
|
||||
{
|
||||
message_p = ECMA_ERR_MSG ("Arrow functions cannot be invoked with 'new'.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ACCESSOR);
|
||||
|
||||
message_p = ECMA_ERR_MSG ("Accessor functions cannot be invoked with 'new'.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
|
||||
return ecma_raise_type_error (message_p);
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
/* 6. */
|
||||
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
|
||||
JERRY_CONTEXT (current_new_target) = new_target_p;
|
||||
@@ -1367,17 +1380,18 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun
|
||||
{
|
||||
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
|
||||
|
||||
if (byte_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
|
||||
if (!CBC_FUNCTION_HAS_PROTOTYPE (byte_code_p->status_flags))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_GENERATOR)
|
||||
{
|
||||
proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
|
||||
0,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
init_constructor = false;
|
||||
}
|
||||
else if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
@@ -1475,7 +1489,7 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
|
||||
ECMA_SET_SECOND_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp);
|
||||
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
|
||||
|
||||
if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
|
||||
if (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR)
|
||||
{
|
||||
ecma_value_t value = *ecma_compiled_code_resolve_function_name (bytecode_data_p);
|
||||
if (value != ECMA_VALUE_EMPTY)
|
||||
@@ -1695,7 +1709,7 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
|
||||
bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (bytecode_data_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
|
||||
if (!CBC_FUNCTION_HAS_PROTOTYPE (bytecode_data_p->status_flags))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ typedef enum
|
||||
RE_FLAG_MULTILINE = (1u << 3), /**< ECMA-262 v5, 15.10.7.4 */
|
||||
RE_FLAG_STICKY = (1u << 4), /**< ECMA-262 v6, 21.2.5.12 */
|
||||
RE_FLAG_UNICODE = (1u << 5) /**< ECMA-262 v6, 21.2.5.15 */
|
||||
|
||||
/* Bits from bit 13 is reserved for function types (see CBC_FUNCTION_TYPE_SHIFT). */
|
||||
} ecma_regexp_flags_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -814,23 +814,75 @@ typedef struct
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CBC_CODE_FLAGS_FUNCTION = (1u << 0), /**< compiled code is JavaScript function */
|
||||
CBC_CODE_FLAGS_FULL_LITERAL_ENCODING = (1u << 1), /**< full literal encoding mode is enabled */
|
||||
CBC_CODE_FLAGS_UINT16_ARGUMENTS = (1u << 2), /**< compiled code data is cbc_uint16_arguments_t */
|
||||
CBC_CODE_FLAGS_STRICT_MODE = (1u << 3), /**< strict mode is enabled */
|
||||
CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED = (1u << 4), /**< mapped arguments object must be constructed */
|
||||
CBC_CODE_FLAGS_UNMAPPED_ARGUMENTS_NEEDED = (1u << 5), /**< mapped arguments object must be constructed */
|
||||
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 6), /**< no need to create a lexical environment */
|
||||
CBC_CODE_FLAGS_ARROW_FUNCTION = (1u << 7), /**< this function is an arrow function */
|
||||
CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 8), /**< this function is a static snapshot function */
|
||||
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 9), /**< this function should be ignored by debugger */
|
||||
CBC_CODE_FLAGS_CLASS_CONSTRUCTOR = (1u << 10), /**< this function is a class constructor */
|
||||
CBC_CODE_FLAGS_GENERATOR = (1u << 11), /**< this function is a generator */
|
||||
CBC_CODE_FLAGS_REST_PARAMETER = (1u << 12), /**< this function has rest parameter */
|
||||
CBC_CODE_FLAG_HAS_TAGGED_LITERALS = (1u << 13), /**< this function has tagged template literal list */
|
||||
CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED = (1u << 14), /**< compiled code needs a lexical block */
|
||||
CBC_CODE_FLAGS_ACCESSOR = (1u << 15) /**< accessor propety 'get' and 'set' functions */
|
||||
} cbc_code_flags;
|
||||
CBC_CODE_FLAGS_FULL_LITERAL_ENCODING = (1u << 0), /**< full literal encoding mode is enabled */
|
||||
CBC_CODE_FLAGS_UINT16_ARGUMENTS = (1u << 1), /**< compiled code data is cbc_uint16_arguments_t */
|
||||
CBC_CODE_FLAGS_STRICT_MODE = (1u << 2), /**< strict mode is enabled */
|
||||
CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED = (1u << 3), /**< mapped arguments object must be constructed */
|
||||
CBC_CODE_FLAGS_UNMAPPED_ARGUMENTS_NEEDED = (1u << 4), /**< mapped arguments object must be constructed */
|
||||
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 5), /**< no need to create a lexical environment */
|
||||
CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 6), /**< this function is a static snapshot function */
|
||||
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 7), /**< this function should be ignored by debugger */
|
||||
CBC_CODE_FLAGS_REST_PARAMETER = (1u << 8), /**< this function has rest parameter */
|
||||
CBC_CODE_FLAGS_HAS_TAGGED_LITERALS = (1u << 9), /**< this function has tagged template literal list */
|
||||
CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED = (1u << 10), /**< compiled code needs a lexical block */
|
||||
|
||||
/* Bits from bit 13 is reserved for function types (see CBC_FUNCTION_TYPE_SHIFT).
|
||||
* Note: the last bits are used for type flags because < and >= operators can be used to
|
||||
check a range of types without decoding the actual type. */
|
||||
} cbc_code_flags_t;
|
||||
|
||||
/**
|
||||
* Compact byte code function types.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/* The first type must be regular expression (see CBC_IS_FUNCTION) */
|
||||
CBC_REGULAR_EXPRESSION, /**< regular expression literal */
|
||||
CBC_FUNCTION_NORMAL, /**< function without special properties */
|
||||
CBC_FUNCTION_CONSTRUCTOR, /**< constructor function */
|
||||
|
||||
/* The following functions cannot be constructed (see CBC_FUNCTION_IS_CONSTRUCTABLE) */
|
||||
CBC_FUNCTION_GENERATOR, /**< generator function */
|
||||
|
||||
/* The following functions has no prototype (see CBC_FUNCTION_HAS_PROTOTYPE) */
|
||||
CBC_FUNCTION_ARROW, /**< arrow function */
|
||||
CBC_FUNCTION_ACCESSOR, /**< property accessor function */
|
||||
} cbc_code_function_types_t;
|
||||
|
||||
/**
|
||||
* Shift for getting / setting the function type of a byte code.
|
||||
*/
|
||||
#define CBC_FUNCTION_TYPE_SHIFT 13
|
||||
|
||||
/**
|
||||
* Compute function type bits in code flags.
|
||||
*/
|
||||
#define CBC_FUNCTION_TO_TYPE_BITS(name) \
|
||||
((name) << CBC_FUNCTION_TYPE_SHIFT)
|
||||
|
||||
/**
|
||||
* Get function type from code flags.
|
||||
*/
|
||||
#define CBC_FUNCTION_GET_TYPE(flags) \
|
||||
((uint16_t) ((flags) >> CBC_FUNCTION_TYPE_SHIFT))
|
||||
|
||||
/**
|
||||
* Checks whether the byte code is a function or a regular expression.
|
||||
*/
|
||||
#define CBC_IS_FUNCTION(flags) \
|
||||
((flags) >= (CBC_FUNCTION_NORMAL << CBC_FUNCTION_TYPE_SHIFT))
|
||||
|
||||
/**
|
||||
* Checks whether the function can be constructed with new operator.
|
||||
*/
|
||||
#define CBC_FUNCTION_IS_CONSTRUCTABLE(flags) \
|
||||
((flags) < (CBC_FUNCTION_GENERATOR << CBC_FUNCTION_TYPE_SHIFT))
|
||||
|
||||
/**
|
||||
* Checks whether the function has prototype property.
|
||||
*/
|
||||
#define CBC_FUNCTION_HAS_PROTOTYPE(flags) \
|
||||
((flags) < (CBC_FUNCTION_ARROW << CBC_FUNCTION_TYPE_SHIFT))
|
||||
|
||||
/**
|
||||
* Any arguments object is needed
|
||||
|
||||
@@ -675,19 +675,28 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
|
||||
switch (CBC_FUNCTION_GET_TYPE (compiled_code_p->status_flags))
|
||||
{
|
||||
JERRY_DEBUG_MSG (",arrow");
|
||||
}
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR)
|
||||
{
|
||||
JERRY_DEBUG_MSG (",constructor");
|
||||
}
|
||||
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
|
||||
{
|
||||
JERRY_DEBUG_MSG (",generator");
|
||||
case CBC_FUNCTION_CONSTRUCTOR:
|
||||
{
|
||||
JERRY_DEBUG_MSG (",constructor");
|
||||
break;
|
||||
}
|
||||
case CBC_FUNCTION_GENERATOR:
|
||||
{
|
||||
JERRY_DEBUG_MSG (",generator");
|
||||
break;
|
||||
}
|
||||
case CBC_FUNCTION_ARROW:
|
||||
{
|
||||
JERRY_DEBUG_MSG (",arrow");
|
||||
break;
|
||||
}
|
||||
case CBC_FUNCTION_ACCESSOR:
|
||||
{
|
||||
JERRY_DEBUG_MSG (",accessor");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
@@ -1238,7 +1247,12 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
byte_code_p = (uint8_t *) compiled_code_p;
|
||||
compiled_code_p->size = (uint16_t) (total_size >> JMEM_ALIGNMENT_LOG);
|
||||
compiled_code_p->refs = 1;
|
||||
compiled_code_p->status_flags = CBC_CODE_FLAGS_FUNCTION;
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
compiled_code_p->status_flags = 0;
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
compiled_code_p->status_flags = CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_NORMAL);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM)
|
||||
@@ -1319,22 +1333,23 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (context_p->status_flags & (PARSER_IS_PROPERTY_GETTER | PARSER_IS_PROPERTY_SETTER))
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_ACCESSOR;
|
||||
compiled_code_p->status_flags |= CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_ACCESSOR);
|
||||
}
|
||||
|
||||
if (context_p->status_flags & PARSER_IS_ARROW_FUNCTION)
|
||||
else if (context_p->status_flags & PARSER_IS_ARROW_FUNCTION)
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_ARROW_FUNCTION;
|
||||
compiled_code_p->status_flags |= CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_ARROW);
|
||||
}
|
||||
|
||||
if (context_p->status_flags & PARSER_CLASS_CONSTRUCTOR)
|
||||
else if (context_p->status_flags & PARSER_CLASS_CONSTRUCTOR)
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_CLASS_CONSTRUCTOR;
|
||||
compiled_code_p->status_flags |= CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_CONSTRUCTOR);
|
||||
}
|
||||
|
||||
if (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
|
||||
else if (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_GENERATOR;
|
||||
compiled_code_p->status_flags |= CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_GENERATOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_NORMAL);
|
||||
}
|
||||
|
||||
if (context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM)
|
||||
@@ -1344,7 +1359,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
|
||||
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
||||
{
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAG_HAS_TAGGED_LITERALS;
|
||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_HAS_TAGGED_LITERALS;
|
||||
}
|
||||
|
||||
if (context_p->status_flags & PARSER_LEXICAL_BLOCK_NEEDED)
|
||||
|
||||
+22
-16
@@ -456,7 +456,7 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
|
||||
if (JERRY_UNLIKELY (!CBC_IS_FUNCTION (bytecode_p->status_flags)))
|
||||
{
|
||||
ecma_object_t *regexp_obj_p = ecma_op_regexp_alloc (NULL);
|
||||
|
||||
@@ -465,30 +465,36 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
return ecma_op_create_regexp_from_bytecode (regexp_obj_p, (re_compiled_code_t *) bytecode_p);;
|
||||
return ecma_op_create_regexp_from_bytecode (regexp_obj_p, (re_compiled_code_t *) bytecode_p);
|
||||
}
|
||||
#else /* !ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
JERRY_ASSERT (CBC_IS_FUNCTION (bytecode_p->status_flags));
|
||||
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
|
||||
JERRY_ASSERT (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
|
||||
|
||||
ecma_object_t *func_obj_p;
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
|
||||
{
|
||||
func_obj_p = ecma_op_create_arrow_function_object (frame_ctx_p->lex_env_p,
|
||||
bytecode_p,
|
||||
frame_ctx_p->this_binding);
|
||||
}
|
||||
else if (bytecode_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
|
||||
{
|
||||
func_obj_p = ecma_op_create_generator_function_object (frame_ctx_p->lex_env_p, bytecode_p);
|
||||
}
|
||||
else
|
||||
switch (CBC_FUNCTION_GET_TYPE (bytecode_p->status_flags))
|
||||
{
|
||||
case CBC_FUNCTION_GENERATOR:
|
||||
{
|
||||
func_obj_p = ecma_op_create_generator_function_object (frame_ctx_p->lex_env_p, bytecode_p);
|
||||
break;
|
||||
}
|
||||
case CBC_FUNCTION_ARROW:
|
||||
{
|
||||
func_obj_p = ecma_op_create_arrow_function_object (frame_ctx_p->lex_env_p,
|
||||
bytecode_p,
|
||||
frame_ctx_p->this_binding);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
func_obj_p = ecma_op_create_simple_function_object (frame_ctx_p->lex_env_p, bytecode_p);
|
||||
func_obj_p = ecma_op_create_simple_function_object (frame_ctx_p->lex_env_p, bytecode_p);
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user