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:
Zoltan Herczeg
2020-06-15 13:40:55 +02:00
committed by GitHub
parent fde0d556ac
commit 1b2e0aec8c
10 changed files with 197 additions and 109 deletions
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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;
+4 -4
View File
@@ -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--;
}
+3 -3
View File
@@ -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;
/**