Support resource name and user value for implicit class constructors (#4771)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2021-09-17 16:28:10 +02:00
committed by GitHub
parent 430289b27d
commit 053bfa0f9f
13 changed files with 471 additions and 327 deletions
+6 -8
View File
@@ -5468,15 +5468,14 @@ jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
return ecma_copy_value (ecma_get_resource_name (JERRY_CONTEXT (vm_top_context_p)->shared_p->bytecode_header_p)); return ecma_copy_value (ecma_get_resource_name (JERRY_CONTEXT (vm_top_context_p)->shared_p->bytecode_header_p));
} }
const ecma_compiled_code_t *bytecode_p = ecma_bytecode_get_from_value (value); ecma_value_t script_value = ecma_script_get_from_value (value);
if (bytecode_p == NULL) if (script_value == JMEM_CP_NULL)
{ {
return ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON); return ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
} }
ecma_value_t script_value = ((cbc_uint8_arguments_t *) bytecode_p)->script_value; const cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
return ecma_copy_value (script_p->resource_name); return ecma_copy_value (script_p->resource_name);
#else /* !JERRY_RESOURCE_NAME */ #else /* !JERRY_RESOURCE_NAME */
@@ -5497,15 +5496,14 @@ jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
jerry_value_t jerry_value_t
jerry_get_user_value (const jerry_value_t value) /**< jerry api value */ jerry_get_user_value (const jerry_value_t value) /**< jerry api value */
{ {
const ecma_compiled_code_t *bytecode_p = ecma_bytecode_get_from_value (value); ecma_value_t script_value = ecma_script_get_from_value (value);
if (bytecode_p == NULL) if (script_value == JMEM_CP_NULL)
{ {
return ECMA_VALUE_UNDEFINED; return ECMA_VALUE_UNDEFINED;
} }
ecma_value_t script_value = ((cbc_uint8_arguments_t *) bytecode_p)->script_value; const cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
if (!(script_p->refs_and_type & CBC_SCRIPT_HAS_USER_VALUE)) if (!(script_p->refs_and_type & CBC_SCRIPT_HAS_USER_VALUE))
{ {
+72 -55
View File
@@ -421,11 +421,8 @@ ecma_gc_mark_properties (ecma_object_t *object_p, /**< object */
* Mark compiled code. * Mark compiled code.
*/ */
static void static void
ecma_gc_mark_compiled_code (const ecma_compiled_code_t *compiled_code_p) /**< compiled code */ ecma_gc_mark_compiled_code (ecma_value_t script_value) /**< script value */
{ {
JERRY_ASSERT (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
ecma_value_t script_value = ((cbc_uint8_arguments_t *) compiled_code_p)->script_value;
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value); cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
if (script_p->refs_and_type & CBC_SCRIPT_USER_VALUE_IS_OBJECT) if (script_p->refs_and_type & CBC_SCRIPT_USER_VALUE_IS_OBJECT)
@@ -895,7 +892,9 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
const ecma_compiled_code_t *compiled_code_p; const ecma_compiled_code_t *compiled_code_p;
compiled_code_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, compiled_code_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_object_p->u.cls.u3.value); ext_object_p->u.cls.u3.value);
ecma_gc_mark_compiled_code (compiled_code_p);
JERRY_ASSERT (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
ecma_gc_mark_compiled_code (((cbc_uint8_arguments_t *) compiled_code_p)->script_value);
break; break;
} }
#endif /* JERRY_PARSER */ #endif /* JERRY_PARSER */
@@ -934,7 +933,10 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
if (!(module_p->header.u.cls.u2.module_flags & ECMA_MODULE_IS_NATIVE) if (!(module_p->header.u.cls.u2.module_flags & ECMA_MODULE_IS_NATIVE)
&& module_p->u.compiled_code_p != NULL) && module_p->u.compiled_code_p != NULL)
{ {
ecma_gc_mark_compiled_code (module_p->u.compiled_code_p); const ecma_compiled_code_t *compiled_code_p = module_p->u.compiled_code_p;
JERRY_ASSERT (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
ecma_gc_mark_compiled_code (((cbc_uint8_arguments_t *) compiled_code_p)->script_value);
} }
ecma_module_node_t *node_p = module_p->imports_p; ecma_module_node_t *node_p = module_p->imports_p;
@@ -1095,21 +1097,16 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
break; break;
} }
#endif /* JERRY_BUILTIN_PROXY */ #endif /* JERRY_BUILTIN_PROXY */
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{
ecma_gc_mark_bound_function_object (object_p);
break;
}
case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_FUNCTION:
{ {
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
ext_func_p->u.function.scope_cp)); ext_func_p->u.function.scope_cp));
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_p); const ecma_compiled_code_t *compiled_code_p = ecma_op_function_get_compiled_code (ext_func_p);
#if JERRY_ESNEXT #if JERRY_ESNEXT
if (CBC_FUNCTION_IS_ARROW (byte_code_p->status_flags)) if (CBC_FUNCTION_IS_ARROW (compiled_code_p->status_flags))
{ {
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p; ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
@@ -1126,25 +1123,22 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
#endif /* JERRY_ESNEXT */ #endif /* JERRY_ESNEXT */
#if JERRY_SNAPSHOT_EXEC #if JERRY_SNAPSHOT_EXEC
if (JERRY_UNLIKELY (byte_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)) if (JERRY_UNLIKELY (compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
{ {
/* Static snapshot functions have a global realm */ /* Static snapshot functions have a global realm */
break; break;
} }
#endif /* JERRY_SNAPSHOT_EXEC */ #endif /* JERRY_SNAPSHOT_EXEC */
ecma_gc_mark_compiled_code (byte_code_p); JERRY_ASSERT (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
ecma_gc_mark_compiled_code (((cbc_uint8_arguments_t *) compiled_code_p)->script_value);
break; break;
} }
#if JERRY_BUILTIN_REALMS case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{ {
ecma_native_function_t *native_function_p = (ecma_native_function_t *) object_p; ecma_gc_mark_bound_function_object (object_p);
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
native_function_p->realm_value));
break; break;
} }
#endif /* JERRY_BUILTIN_REALMS */
#if JERRY_ESNEXT || JERRY_BUILTIN_REALMS #if JERRY_ESNEXT || JERRY_BUILTIN_REALMS
case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION: case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
{ {
@@ -1226,6 +1220,22 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
break; break;
} }
#endif /* JERRY_ESNEXT || JERRY_BUILTIN_REALMS */ #endif /* JERRY_ESNEXT || JERRY_BUILTIN_REALMS */
#if JERRY_ESNEXT
case ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION:
{
ecma_gc_mark_compiled_code (((ecma_extended_object_t *) object_p)->u.constructor_function.script_value);
break;
}
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_REALMS
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
ecma_native_function_t *native_function_p = (ecma_native_function_t *) object_p;
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
native_function_p->realm_value));
break;
}
#endif /* JERRY_BUILTIN_REALMS */
default: default:
{ {
break; break;
@@ -1974,40 +1984,6 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
#endif /* JERRY_SNAPSHOT_EXEC */ #endif /* JERRY_SNAPSHOT_EXEC */
break; break;
} }
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{
ext_object_size = sizeof (ecma_bound_function_t);
ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
#if JERRY_ESNEXT
ecma_free_value (bound_func_p->target_length);
#endif /* JERRY_ESNEXT */
if (!ecma_is_value_integer_number (args_len_or_this))
{
ecma_free_value_if_not_object (args_len_or_this);
break;
}
ecma_integer_value_t args_length = ecma_get_integer_from_value (args_len_or_this);
ecma_value_t *args_p = (ecma_value_t *) (bound_func_p + 1);
for (ecma_integer_value_t i = 0; i < args_length; i++)
{
ecma_free_value_if_not_object (args_p[i]);
}
size_t args_size = ((size_t) args_length) * sizeof (ecma_value_t);
ext_object_size += args_size;
break;
}
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
ext_object_size = sizeof (ecma_native_function_t);
break;
}
case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION: case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
{ {
ecma_extended_object_t *extended_func_p = (ecma_extended_object_t *) object_p; ecma_extended_object_t *extended_func_p = (ecma_extended_object_t *) object_p;
@@ -2071,6 +2047,47 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
#endif /* JERRY_ESNEXT */ #endif /* JERRY_ESNEXT */
break; break;
} }
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{
ext_object_size = sizeof (ecma_bound_function_t);
ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
#if JERRY_ESNEXT
ecma_free_value (bound_func_p->target_length);
#endif /* JERRY_ESNEXT */
if (!ecma_is_value_integer_number (args_len_or_this))
{
ecma_free_value_if_not_object (args_len_or_this);
break;
}
ecma_integer_value_t args_length = ecma_get_integer_from_value (args_len_or_this);
ecma_value_t *args_p = (ecma_value_t *) (bound_func_p + 1);
for (ecma_integer_value_t i = 0; i < args_length; i++)
{
ecma_free_value_if_not_object (args_p[i]);
}
size_t args_size = ((size_t) args_length) * sizeof (ecma_value_t);
ext_object_size += args_size;
break;
}
#if JERRY_ESNEXT
case ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION:
{
ecma_script_deref (((ecma_extended_object_t *) object_p)->u.constructor_function.script_value);
break;
}
#endif /* JERRY_ESNEXT */
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
ext_object_size = sizeof (ecma_native_function_t);
break;
}
default: default:
{ {
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
+25 -5
View File
@@ -715,9 +715,10 @@ typedef enum
ECMA_OBJECT_TYPE_PROXY = 6, /**< Proxy object ECMAScript v6 26.2 */ ECMA_OBJECT_TYPE_PROXY = 6, /**< Proxy object ECMAScript v6 26.2 */
/* Note: these 4 types must be in this order. See IsCallable operation. */ /* Note: these 4 types must be in this order. See IsCallable operation. */
ECMA_OBJECT_TYPE_FUNCTION = 7, /**< Function objects (15.3), created through 13.2 routine */ ECMA_OBJECT_TYPE_FUNCTION = 7, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 8, /**< Function objects (15.3), created through 15.3.4.5 routine */ ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION = 8, /**< Native built-in function object */
ECMA_OBJECT_TYPE_NATIVE_FUNCTION = 9, /**< Native function object */ ECMA_OBJECT_TYPE_BOUND_FUNCTION = 9, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION = 10, /**< Native built-in function object */ ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION = 10, /**< implicit class constructor function */
ECMA_OBJECT_TYPE_NATIVE_FUNCTION = 11, /**< Native function object */
ECMA_OBJECT_TYPE__MAX /**< maximum value */ ECMA_OBJECT_TYPE__MAX /**< maximum value */
} ecma_object_type_t; } ecma_object_type_t;
@@ -1161,6 +1162,17 @@ typedef struct
jmem_cpointer_tag_t target_function; /**< target function */ jmem_cpointer_tag_t target_function; /**< target function */
ecma_value_t args_len_or_this; /**< length of arguments or this value */ ecma_value_t args_len_or_this; /**< length of arguments or this value */
} bound_function; } bound_function;
#if JERRY_ESNEXT
/**
* Description of implicit class constructor function.
*/
struct
{
ecma_value_t script_value; /**< script value */
uint8_t flags; /**< constructor flags */
} constructor_function;
#endif /* JERRY_ESNEXT */
} u; } u;
} ecma_extended_object_t; } ecma_extended_object_t;
@@ -2477,8 +2489,8 @@ typedef struct
*/ */
typedef enum typedef enum
{ {
ECMA_DATE_TZA_NONE = 0, ECMA_DATE_TZA_NONE = 0, /**< no time-zone adjustment is set */
ECMA_DATE_TZA_SET = 1 << 0, ECMA_DATE_TZA_SET = (1 << 0), /**< time-zone adjustment is set */
} ecma_date_object_flags_t; } ecma_date_object_flags_t;
/** /**
@@ -2490,6 +2502,14 @@ typedef struct
ecma_number_t date_value; /**< [[DateValue]] internal property */ ecma_number_t date_value; /**< [[DateValue]] internal property */
} ecma_date_object_t; } ecma_date_object_t;
/**
* Implicit class constructor flags
*/
typedef enum
{
ECMA_CONSTRUCTOR_FUNCTION_HAS_HERITAGE = (1 << 0), /**< heritage object is present */
} ecma_constructor_function_flags_t;
#endif /* JERRY_ESNEXT */ #endif /* JERRY_ESNEXT */
/** /**
+84 -60
View File
@@ -1406,6 +1406,63 @@ ecma_raise_error_from_error_reference (ecma_value_t value) /**< error reference
JERRY_CONTEXT (error_value) = referenced_value; JERRY_CONTEXT (error_value) = referenced_value;
} /* ecma_raise_error_from_error_reference */ } /* ecma_raise_error_from_error_reference */
/**
* Decrease the reference counter of a script value.
*/
void
ecma_script_deref (ecma_value_t script_value) /**< script value */
{
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
script_p->refs_and_type -= CBC_SCRIPT_REF_ONE;
if (script_p->refs_and_type >= CBC_SCRIPT_REF_ONE)
{
return;
}
size_t script_size = sizeof (cbc_script_t);
uint32_t type = script_p->refs_and_type;
if (type & CBC_SCRIPT_HAS_USER_VALUE)
{
script_size += sizeof (ecma_value_t);
if (!(type & CBC_SCRIPT_USER_VALUE_IS_OBJECT))
{
ecma_value_t user_value = CBC_SCRIPT_GET_USER_VALUE (script_p);
JERRY_ASSERT (!ecma_is_value_object (user_value));
ecma_free_value (user_value);
}
}
#if JERRY_RESOURCE_NAME
ecma_deref_ecma_string (ecma_get_string_from_value (script_p->resource_name));
#endif /* JERRY_RESOURCE_NAME */
#if JERRY_MODULE_SYSTEM
if (type & CBC_SCRIPT_HAS_IMPORT_META)
{
JERRY_ASSERT (!(type & CBC_SCRIPT_HAS_FUNCTION_ARGUMENTS));
JERRY_ASSERT (ecma_is_value_object (CBC_SCRIPT_GET_IMPORT_META (script_p, type)));
script_size += sizeof (ecma_value_t);
}
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_FUNCTION_TO_STRING
ecma_deref_ecma_string (ecma_get_string_from_value (script_p->source_code));
if (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);
} /* ecma_script_deref */
/** /**
* Increase reference counter of Compact * Increase reference counter of Compact
* Byte Code or regexp byte code. * Byte Code or regexp byte code.
@@ -1478,53 +1535,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
} }
} }
ecma_value_t script_value = ((cbc_uint8_arguments_t *) bytecode_p)->script_value; ecma_script_deref (((cbc_uint8_arguments_t *) bytecode_p)->script_value);
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
script_p->refs_and_type -= CBC_SCRIPT_REF_ONE;
if (script_p->refs_and_type < CBC_SCRIPT_REF_ONE)
{
size_t script_size = sizeof (cbc_script_t);
uint32_t type = script_p->refs_and_type;
if (type & CBC_SCRIPT_HAS_USER_VALUE)
{
script_size += sizeof (ecma_value_t);
if (!(type & CBC_SCRIPT_USER_VALUE_IS_OBJECT))
{
ecma_value_t user_value = CBC_SCRIPT_GET_USER_VALUE (script_p);
JERRY_ASSERT (!ecma_is_value_object (user_value));
ecma_free_value (user_value);
}
}
#if JERRY_RESOURCE_NAME
ecma_deref_ecma_string (ecma_get_string_from_value (script_p->resource_name));
#endif /* JERRY_RESOURCE_NAME */
#if JERRY_MODULE_SYSTEM
if (type & CBC_SCRIPT_HAS_IMPORT_META)
{
JERRY_ASSERT (ecma_is_value_object (CBC_SCRIPT_GET_IMPORT_META (script_p, type)));
script_size += sizeof (ecma_value_t);
}
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_FUNCTION_TO_STRING
ecma_deref_ecma_string (ecma_get_string_from_value (script_p->source_code));
if (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);
}
#if JERRY_ESNEXT #if JERRY_ESNEXT
if (bytecode_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS) if (bytecode_p->status_flags & CBC_CODE_FLAGS_HAS_TAGGED_LITERALS)
@@ -1597,19 +1608,20 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
} /* ecma_bytecode_deref */ } /* ecma_bytecode_deref */
/** /**
* Gets the byte code asigned to a script / module / function * Gets the script data asigned to a script / module / function
* *
* @return byte code - if available, NULL - otherwise * @return script data - if available, JMEM_CP_NULL - otherwise
*/ */
const ecma_compiled_code_t * ecma_value_t
ecma_bytecode_get_from_value (ecma_value_t value) /**< compiled code */ ecma_script_get_from_value (ecma_value_t value) /**< compiled code */
{ {
if (!ecma_is_value_object (value)) if (!ecma_is_value_object (value))
{ {
return NULL; return JMEM_CP_NULL;
} }
ecma_object_t *object_p = ecma_get_object_from_value (value); ecma_object_t *object_p = ecma_get_object_from_value (value);
const ecma_compiled_code_t *bytecode_p = NULL;
while (true) while (true)
{ {
@@ -1621,8 +1633,9 @@ ecma_bytecode_get_from_value (ecma_value_t value) /**< compiled code */
if (ext_object_p->u.cls.type == ECMA_OBJECT_CLASS_SCRIPT) if (ext_object_p->u.cls.type == ECMA_OBJECT_CLASS_SCRIPT)
{ {
return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_object_p->u.cls.u3.value); ext_object_p->u.cls.u3.value);
break;
} }
#if JERRY_MODULE_SYSTEM #if JERRY_MODULE_SYSTEM
@@ -1632,15 +1645,17 @@ ecma_bytecode_get_from_value (ecma_value_t value) /**< compiled code */
if (!(module_p->header.u.cls.u2.module_flags & ECMA_MODULE_IS_NATIVE)) if (!(module_p->header.u.cls.u2.module_flags & ECMA_MODULE_IS_NATIVE))
{ {
return module_p->u.compiled_code_p; bytecode_p = module_p->u.compiled_code_p;
break;
} }
} }
#endif /* JERRY_MODULE_SYSTEM */ #endif /* JERRY_MODULE_SYSTEM */
return NULL; return JMEM_CP_NULL;
} }
case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_FUNCTION:
{ {
return ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p); bytecode_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
break;
} }
case ECMA_OBJECT_TYPE_BOUND_FUNCTION: case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{ {
@@ -1648,15 +1663,24 @@ ecma_bytecode_get_from_value (ecma_value_t value) /**< compiled code */
object_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, object_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
ext_object_p->u.bound_function.target_function); ext_object_p->u.bound_function.target_function);
break; continue;
} }
#if JERRY_ESNEXT
case ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION:
{
return ((ecma_extended_object_t *) object_p)->u.constructor_function.script_value;
}
#endif /* JERRY_ESNEXT */
default: default:
{ {
return NULL; return JMEM_CP_NULL;
} }
} }
JERRY_ASSERT (bytecode_p != NULL);
return ((cbc_uint8_arguments_t *) bytecode_p)->script_value;
} }
} /* ecma_bytecode_get_from_value */ } /* ecma_script_get_from_value */
/** /**
* Resolve the position of the arguments list start of the compiled code * Resolve the position of the arguments list start of the compiled code
+2 -1
View File
@@ -531,9 +531,10 @@ ecma_value_t ecma_create_error_reference_from_context (void);
ecma_value_t ecma_create_error_object_reference (ecma_object_t *object_p); ecma_value_t ecma_create_error_object_reference (ecma_object_t *object_p);
void ecma_raise_error_from_error_reference (ecma_value_t value); void ecma_raise_error_from_error_reference (ecma_value_t value);
void ecma_script_deref (ecma_value_t script_value);
void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p); void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p); void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
const ecma_compiled_code_t *ecma_bytecode_get_from_value (ecma_value_t value); ecma_value_t ecma_script_get_from_value (ecma_value_t value);
ecma_value_t *ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode_header_p); ecma_value_t *ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode_header_p);
#if JERRY_ESNEXT #if JERRY_ESNEXT
ecma_value_t *ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_header_p); ecma_value_t *ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_header_p);
+223 -93
View File
@@ -29,6 +29,7 @@
#include "ecma-proxy-object.h" #include "ecma-proxy-object.h"
#include "ecma-symbol-object.h" #include "ecma-symbol-object.h"
#include "jcontext.h" #include "jcontext.h"
#include "opcodes.h"
/** \addtogroup ecma ECMA /** \addtogroup ecma ECMA
* @{ * @{
@@ -224,7 +225,8 @@ ecma_object_check_constructor (ecma_object_t *obj_p) /**< ecma object */
#endif /* JERRY_BUILTIN_PROXY */ #endif /* JERRY_BUILTIN_PROXY */
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION JERRY_ASSERT (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
|| type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION); || type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION
|| type == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION);
if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
{ {
@@ -803,7 +805,17 @@ ecma_op_function_get_function_realm (ecma_object_t *func_obj_p) /**< function ob
native_function_p->realm_value); native_function_p->realm_value);
} }
#if JERRY_BUILTIN_PROXY #if JERRY_ESNEXT
if (type == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION)
{
ecma_value_t script_value = ((ecma_extended_object_t *) func_obj_p)->u.constructor_function.script_value;
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
return (ecma_global_object_t *) script_p->realm_p;
}
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_PROXY
if (ECMA_OBJECT_IS_PROXY (func_obj_p)) if (ECMA_OBJECT_IS_PROXY (func_obj_p))
{ {
ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) func_obj_p; ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) func_obj_p;
@@ -815,7 +827,7 @@ ecma_op_function_get_function_realm (ecma_object_t *func_obj_p) /**< function ob
func_obj_p = ecma_get_object_from_value (proxy_obj_p->target); func_obj_p = ecma_get_object_from_value (proxy_obj_p->target);
continue; continue;
} }
#endif /* JERRY_BUILTIN_PROXY */ #endif /* JERRY_BUILTIN_PROXY */
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION); JERRY_ASSERT (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p; ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p;
@@ -857,8 +869,9 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
} }
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
|| ECMA_OBJECT_IS_PROXY (func_obj_p)); || ECMA_OBJECT_IS_PROXY (func_obj_p));
ecma_object_t *v_obj_p = ecma_get_object_from_value (value); ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
@@ -1389,6 +1402,12 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
{ {
result = ecma_op_function_call_native (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len); result = ecma_op_function_call_native (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
} }
#if JERRY_ESNEXT
else if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION))
{
result = ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_class_constructor_new));
}
#endif /* JERRY_ESNEXT */
else else
{ {
result = ecma_op_function_call_bound (func_obj_p, arguments_list_p, arguments_list_len); result = ecma_op_function_call_bound (func_obj_p, arguments_list_p, arguments_list_len);
@@ -1401,6 +1420,118 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
return result; return result;
} /* ecma_op_function_call */ } /* ecma_op_function_call */
/**
* [[Construct]] internal method for ECMAScript function objects
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
static ecma_value_t
ecma_op_function_construct_simple (ecma_object_t *func_obj_p, /**< Function object */
ecma_object_t *new_target_p, /**< new target */
const ecma_value_t *arguments_list_p, /**< arguments list */
uint32_t arguments_list_len) /**< length of arguments list */
{
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
ecma_object_t *new_this_obj_p = NULL;
ecma_value_t this_arg;
#if JERRY_ESNEXT
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
/* 5. */
if (!ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_obj_p->u.function.scope_cp))
{
#endif /* JERRY_ESNEXT */
/* 5.a */
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
/* 5.b */
if (JERRY_UNLIKELY (proto_p == NULL))
{
return ECMA_VALUE_ERROR;
}
new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (proto_p);
this_arg = ecma_make_object_value (new_this_obj_p);
#if JERRY_ESNEXT
}
else
{
this_arg = ECMA_VALUE_UNDEFINED;
}
/* 6. */
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = new_target_p;
#endif /* JERRY_ESNEXT */
ecma_value_t ret_value = ecma_op_function_call_simple (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
#if JERRY_ESNEXT
JERRY_CONTEXT (current_new_target_p) = old_new_target_p;
#endif /* JERRY_ESNEXT */
/* 13.a */
if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
{
#if JERRY_ESNEXT
if (new_this_obj_p != NULL)
{
ecma_deref_object (new_this_obj_p);
}
#else /* !JERRY_ESNEXT */
ecma_deref_object (new_this_obj_p);
#endif /* JERRY_ESNEXT */
return ret_value;
}
/* 13.b */
ecma_free_value (ret_value);
return this_arg;
} /* ecma_op_function_construct_simple */
/**
* [[Construct]] internal method for built-in function objects
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
static ecma_value_t
ecma_op_function_construct_built_in (ecma_object_t *func_obj_p, /**< Function object */
ecma_object_t *new_target_p, /**< new target */
const ecma_value_t *arguments_list_p, /**< arguments list */
uint32_t arguments_list_len) /**< length of arguments list */
{
JERRY_UNUSED (new_target_p);
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION);
#if JERRY_BUILTIN_REALMS
ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p);
ecma_value_t realm_value = ((ecma_extended_object_t *) func_obj_p)->u.built_in.realm_value;
JERRY_CONTEXT (global_object_p) = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t, realm_value);
#endif /* JERRY_BUILTIN_REALMS */
#if JERRY_ESNEXT
ecma_object_t *old_new_target = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = new_target_p;
#endif /* JERRY_ESNEXT */
ecma_value_t ret_value = ecma_builtin_dispatch_construct (func_obj_p, arguments_list_p, arguments_list_len);
#if JERRY_ESNEXT
JERRY_CONTEXT (current_new_target_p) = old_new_target;
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_REALMS
JERRY_CONTEXT (global_object_p) = saved_global_object_p;
#endif /* JERRY_BUILTIN_REALMS */
return ret_value;
} /* ecma_op_function_construct_built_in */
/** /**
* [[Construct]] internal method for bound function objects * [[Construct]] internal method for bound function objects
* *
@@ -1437,6 +1568,78 @@ ecma_op_function_construct_bound (ecma_object_t *func_obj_p, /**< Function objec
return ret_value; return ret_value;
} /* ecma_op_function_construct_bound */ } /* ecma_op_function_construct_bound */
#if JERRY_ESNEXT
/**
* [[Construct]] internal method for class implicit constructor objects
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
static ecma_value_t
ecma_op_function_construct_constructor (ecma_object_t *func_obj_p, /**< Function object */
ecma_object_t *new_target_p, /**< new target */
const ecma_value_t *arguments_list_p, /**< arguments list */
uint32_t arguments_list_len) /**< length of arguments list */
{
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION);
ecma_extended_object_t *constructor_object_p = (ecma_extended_object_t *) func_obj_p;
if (!(constructor_object_p->u.constructor_function.flags & ECMA_CONSTRUCTOR_FUNCTION_HAS_HERITAGE))
{
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
if (JERRY_UNLIKELY (proto_p == NULL))
{
return ECMA_VALUE_ERROR;
}
ecma_object_t *new_this_object_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (proto_p);
jerry_value_t new_this_value = ecma_make_object_value (new_this_object_p);
jerry_value_t ret_value = opfunc_init_class_fields (func_obj_p, new_this_value);
if (ECMA_IS_VALUE_ERROR (ret_value))
{
ecma_deref_object (new_this_object_p);
return ret_value;
}
return new_this_value;
}
ecma_value_t super_ctor = ecma_op_function_get_super_constructor (func_obj_p);
if (ECMA_IS_VALUE_ERROR (super_ctor))
{
return super_ctor;
}
ecma_object_t *super_ctor_p = ecma_get_object_from_value (super_ctor);
ecma_value_t result = ecma_op_function_construct (super_ctor_p,
new_target_p,
arguments_list_p,
arguments_list_len);
ecma_deref_object (super_ctor_p);
if (ecma_is_value_object (result))
{
ecma_value_t fields_value = opfunc_init_class_fields (func_obj_p, result);
if (ECMA_IS_VALUE_ERROR (fields_value))
{
ecma_free_value (result);
return fields_value;
}
}
return result;
} /* ecma_op_function_construct_constructor */
#endif /* JERRY_ESNEXT */
/** /**
* [[Construct]] internal method for external function objects * [[Construct]] internal method for external function objects
* *
@@ -1503,13 +1706,20 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
const ecma_object_type_t type = ecma_get_object_type (func_obj_p); const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
if (JERRY_LIKELY (type == ECMA_OBJECT_TYPE_FUNCTION))
{
return ecma_op_function_construct_simple (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
}
if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
{
return ecma_op_function_construct_built_in (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
}
#if JERRY_BUILTIN_PROXY #if JERRY_BUILTIN_PROXY
if (ECMA_OBJECT_TYPE_IS_PROXY (type)) if (ECMA_OBJECT_TYPE_IS_PROXY (type))
{ {
return ecma_proxy_object_construct (func_obj_p, return ecma_proxy_object_construct (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
new_target_p,
arguments_list_p,
arguments_list_len);
} }
#endif /* JERRY_BUILTIN_PROXY */ #endif /* JERRY_BUILTIN_PROXY */
@@ -1518,95 +1728,15 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len); return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
} }
if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)) #if JERRY_ESNEXT
if (type == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION)
{ {
#if JERRY_BUILTIN_REALMS return ecma_op_function_construct_constructor (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p);
ecma_value_t realm_value = ((ecma_extended_object_t *) func_obj_p)->u.built_in.realm_value;
JERRY_CONTEXT (global_object_p) = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t, realm_value);
#endif /* JERRY_BUILTIN_REALMS */
#if JERRY_ESNEXT
ecma_object_t *old_new_target = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = new_target_p;
#endif /* JERRY_ESNEXT */
ecma_value_t ret_value = ecma_builtin_dispatch_construct (func_obj_p, arguments_list_p, arguments_list_len);
#if JERRY_ESNEXT
JERRY_CONTEXT (current_new_target_p) = old_new_target;
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_REALMS
JERRY_CONTEXT (global_object_p) = saved_global_object_p;
#endif /* JERRY_BUILTIN_REALMS */
return ret_value;
} }
if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION))
{
return ecma_op_function_construct_native (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
}
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_FUNCTION);
ecma_object_t *new_this_obj_p = NULL;
ecma_value_t this_arg;
#if JERRY_ESNEXT
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
/* 5. */
if (!ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_obj_p->u.function.scope_cp))
{
#endif /* JERRY_ESNEXT */
/* 5.a */
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
/* 5.b */
if (JERRY_UNLIKELY (proto_p == NULL))
{
return ECMA_VALUE_ERROR;
}
new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (proto_p);
this_arg = ecma_make_object_value (new_this_obj_p);
#if JERRY_ESNEXT
}
else
{
this_arg = ECMA_VALUE_UNDEFINED;
}
/* 6. */
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = new_target_p;
#endif /* JERRY_ESNEXT */ #endif /* JERRY_ESNEXT */
ecma_value_t ret_value = ecma_op_function_call_simple (func_obj_p, this_arg, arguments_list_p, arguments_list_len); JERRY_ASSERT (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
return ecma_op_function_construct_native (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
#if JERRY_ESNEXT
JERRY_CONTEXT (current_new_target_p) = old_new_target_p;
#endif /* JERRY_ESNEXT */
/* 13.a */
if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
{
#if JERRY_ESNEXT
if (new_this_obj_p != NULL)
{
ecma_deref_object (new_this_obj_p);
}
#else /* !JERRY_ESNEXT */
ecma_deref_object (new_this_obj_p);
#endif /* JERRY_ESNEXT */
return ret_value;
}
/* 13.b */
ecma_free_value (ret_value);
return this_arg;
} /* ecma_op_function_construct */ } /* ecma_op_function_construct */
/** /**
+2 -1
View File
@@ -2376,7 +2376,8 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */
} }
default: default:
{ {
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_GENERAL); JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_GENERAL
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION);
break; break;
} }
} }
+21 -93
View File
@@ -914,14 +914,12 @@ opfunc_async_create_and_await (vm_frame_ctx_t *frame_ctx_p, /**< frame context *
* ECMA_VALUE_UNDEFINED - otherwise * ECMA_VALUE_UNDEFINED - otherwise
*/ */
ecma_value_t ecma_value_t
opfunc_init_class_fields (ecma_value_t class_object, /**< the function itself */ opfunc_init_class_fields (ecma_object_t *class_object_p, /**< the function itself */
ecma_value_t this_val) /**< this_arg of the function */ ecma_value_t this_val) /**< this_arg of the function */
{ {
JERRY_ASSERT (ecma_is_value_object (class_object));
JERRY_ASSERT (ecma_is_value_object (this_val)); JERRY_ASSERT (ecma_is_value_object (this_val));
ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_INIT); ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_INIT);
ecma_object_t *class_object_p = ecma_get_object_from_value (class_object);
ecma_property_t *property_p = ecma_find_named_property (class_object_p, name_p); ecma_property_t *property_p = ecma_find_named_property (class_object_p, name_p);
if (property_p == NULL) if (property_p == NULL)
@@ -1048,78 +1046,6 @@ opfunc_add_computed_field (ecma_value_t class_object, /**< class object */
return ECMA_VALUE_UNDEFINED; return ECMA_VALUE_UNDEFINED;
} /* opfunc_add_computed_field */ } /* opfunc_add_computed_field */
/**
* Implicit class constructor handler when the classHeritage is not present.
*
* See also: ECMAScript v6, 14.5.14.10.b.i
*
* @return ECMA_VALUE_ERROR - if the function was invoked without 'new'
* ECMA_VALUE_UNDEFINED - otherwise
*/
static ecma_value_t
ecma_op_implicit_constructor_handler_cb (const jerry_call_info_t *call_info_p, /**< call information */
const ecma_value_t args_p[], /**< argument list */
const uint32_t args_count) /**< argument number */
{
JERRY_UNUSED_2 (args_p, args_count);
if (JERRY_CONTEXT (current_new_target_p) == NULL)
{
return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_class_constructor_new));
}
return opfunc_init_class_fields (call_info_p->function, call_info_p->this_value);
} /* ecma_op_implicit_constructor_handler_cb */
/**
* Implicit class constructor handler when the classHeritage is present.
*
* See also: ECMAScript v6, 14.5.14.10.a.i
*
* @return ECMA_VALUE_ERROR - if the operation fails
* result of the super call - otherwise
*/
static ecma_value_t
ecma_op_implicit_constructor_handler_heritage_cb (const jerry_call_info_t *call_info_p, /**< call information */
const ecma_value_t args_p[], /**< argument list */
const uint32_t args_count) /**< argument number */
{
if (JERRY_CONTEXT (current_new_target_p) == NULL)
{
return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_class_constructor_new));
}
ecma_object_t *func_obj_p = ecma_get_object_from_value (call_info_p->function);
ecma_value_t super_ctor = ecma_op_function_get_super_constructor (func_obj_p);
if (ECMA_IS_VALUE_ERROR (super_ctor))
{
return super_ctor;
}
ecma_object_t *super_ctor_p = ecma_get_object_from_value (super_ctor);
ecma_value_t result = ecma_op_function_construct (super_ctor_p,
JERRY_CONTEXT (current_new_target_p),
args_p,
args_count);
if (ecma_is_value_object (result))
{
ecma_value_t fields_value = opfunc_init_class_fields (call_info_p->function, result);
if (ECMA_IS_VALUE_ERROR (fields_value))
{
ecma_free_value (result);
result = ECMA_VALUE_ERROR;
}
}
ecma_deref_object (super_ctor_p);
return result;
} /* ecma_op_implicit_constructor_handler_heritage_cb */
/** /**
* Create implicit class constructor * Create implicit class constructor
* *
@@ -1128,40 +1054,42 @@ ecma_op_implicit_constructor_handler_heritage_cb (const jerry_call_info_t *call_
* @return - new external function ecma-object * @return - new external function ecma-object
*/ */
ecma_value_t ecma_value_t
opfunc_create_implicit_class_constructor (uint8_t opcode) /**< current cbc opcode */ opfunc_create_implicit_class_constructor (uint8_t opcode, /**< current cbc opcode */
const ecma_compiled_code_t *bytecode_p) /**< current byte code */
{ {
/* 8. */ /* 8. */
ecma_object_t *function_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE), ecma_value_t script_value = ((cbc_uint8_arguments_t *) bytecode_p)->script_value;
sizeof (ecma_native_function_t), cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
ecma_native_function_t *native_function_p = (ecma_native_function_t *) function_obj_p; if (JERRY_UNLIKELY (script_p->refs_and_type >= CBC_SCRIPT_REF_MAX))
{
jerry_fatal (ERR_REF_COUNT_LIMIT);
}
#if JERRY_BUILTIN_REALMS ecma_object_t *function_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
ECMA_SET_INTERNAL_VALUE_POINTER (native_function_p->realm_value, sizeof (ecma_extended_object_t),
ecma_builtin_get_global ()); ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION);
#endif /* JERRY_BUILTIN_REALMS */
ecma_extended_object_t *constructor_object_p = (ecma_extended_object_t *) function_object_p;
script_p->refs_and_type += CBC_SCRIPT_REF_ONE;
constructor_object_p->u.constructor_function.script_value = script_value;
constructor_object_p->u.constructor_function.flags = 0;
/* 10.a.i */ /* 10.a.i */
if (opcode == CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE) if (opcode == CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE)
{ {
native_function_p->native_handler_cb = ecma_op_implicit_constructor_handler_heritage_cb; constructor_object_p->u.constructor_function.flags |= ECMA_CONSTRUCTOR_FUNCTION_HAS_HERITAGE;
}
/* 10.b.i */
else
{
native_function_p->native_handler_cb = ecma_op_implicit_constructor_handler_cb;
} }
ecma_property_value_t *prop_value_p; ecma_property_value_t *prop_value_p;
prop_value_p = ecma_create_named_data_property (function_obj_p, prop_value_p = ecma_create_named_data_property (function_object_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
ECMA_PROPERTY_FLAG_CONFIGURABLE, ECMA_PROPERTY_FLAG_CONFIGURABLE,
NULL); NULL);
prop_value_p->value = ecma_make_uint32_value (0); prop_value_p->value = ecma_make_uint32_value (0);
return ecma_make_object_value (function_obj_p); return ecma_make_object_value (function_object_p);
} /* opfunc_create_implicit_class_constructor */ } /* opfunc_create_implicit_class_constructor */
/** /**
+2 -2
View File
@@ -142,7 +142,7 @@ ecma_value_t
opfunc_async_create_and_await (vm_frame_ctx_t *frame_ctx_p, ecma_value_t value, uint16_t extra_flags); opfunc_async_create_and_await (vm_frame_ctx_t *frame_ctx_p, ecma_value_t value, uint16_t extra_flags);
ecma_value_t ecma_value_t
opfunc_init_class_fields (ecma_value_t class_object, ecma_value_t this_val); opfunc_init_class_fields (ecma_object_t *class_object_p, ecma_value_t this_val);
ecma_value_t ecma_value_t
opfunc_init_static_class_fields (ecma_value_t function_object, ecma_value_t this_val); opfunc_init_static_class_fields (ecma_value_t function_object, ecma_value_t this_val);
@@ -151,7 +151,7 @@ ecma_value_t
opfunc_add_computed_field (ecma_value_t class_object, ecma_value_t name); opfunc_add_computed_field (ecma_value_t class_object, ecma_value_t name);
ecma_value_t ecma_value_t
opfunc_create_implicit_class_constructor (uint8_t opcode); opfunc_create_implicit_class_constructor (uint8_t opcode, const ecma_compiled_code_t *bytecode_p);
void void
opfunc_set_home_object (ecma_object_t *func_p, ecma_object_t *parent_env_p); opfunc_set_home_object (ecma_object_t *func_p, ecma_object_t *parent_env_p);
+5 -6
View File
@@ -620,8 +620,7 @@ vm_super_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (ecma_is_value_object (completion_value)) if (ecma_is_value_object (completion_value))
{ {
ecma_value_t current_function = ecma_make_object_value (vm_get_class_function (frame_ctx_p)); ecma_value_t fields_value = opfunc_init_class_fields (vm_get_class_function (frame_ctx_p), completion_value);
ecma_value_t fields_value = opfunc_init_class_fields (current_function, completion_value);
if (ECMA_IS_VALUE_ERROR (fields_value)) if (ECMA_IS_VALUE_ERROR (fields_value))
{ {
@@ -2065,7 +2064,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} }
case VM_OC_PUSH_IMPLICIT_CTOR: case VM_OC_PUSH_IMPLICIT_CTOR:
{ {
*stack_top_p++ = opfunc_create_implicit_class_constructor (opcode); *stack_top_p++ = opfunc_create_implicit_class_constructor (opcode,
frame_ctx_p->shared_p->bytecode_header_p);
continue; continue;
} }
case VM_OC_INIT_CLASS: case VM_OC_INIT_CLASS:
@@ -2120,8 +2120,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
case VM_OC_RUN_FIELD_INIT: case VM_OC_RUN_FIELD_INIT:
{ {
JERRY_ASSERT (frame_ctx_p->shared_p->status_flags & VM_FRAME_CTX_SHARED_NON_ARROW_FUNC); JERRY_ASSERT (frame_ctx_p->shared_p->status_flags & VM_FRAME_CTX_SHARED_NON_ARROW_FUNC);
result = opfunc_init_class_fields (ecma_make_object_value (frame_ctx_p->shared_p->function_object_p), result = opfunc_init_class_fields (frame_ctx_p->shared_p->function_object_p, frame_ctx_p->this_binding);
frame_ctx_p->this_binding);
if (ECMA_IS_VALUE_ERROR (result)) if (ECMA_IS_VALUE_ERROR (result))
{ {
@@ -2279,7 +2278,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ECMA_PROPERTY_FLAG_CONFIGURABLE, ECMA_PROPERTY_FLAG_CONFIGURABLE,
NULL); NULL);
if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_NATIVE_FUNCTION) if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
{ {
ECMA_SET_SECOND_BIT_TO_POINTER_TAG (((ecma_extended_object_t *) func_obj_p)->u.function.scope_cp); ECMA_SET_SECOND_BIT_TO_POINTER_TAG (((ecma_extended_object_t *) func_obj_p)->u.function.scope_cp);
} }
-3
View File
@@ -2469,7 +2469,6 @@
<test id="language/expressions/class/elements/class-name-static-initializer-default-export.js"><reason></reason></test> <test id="language/expressions/class/elements/class-name-static-initializer-default-export.js"><reason></reason></test>
<test id="language/expressions/class/elements/derived-cls-direct-eval-contains-superproperty-1.js"><reason></reason></test> <test id="language/expressions/class/elements/derived-cls-direct-eval-contains-superproperty-1.js"><reason></reason></test>
<test id="language/expressions/class/elements/derived-cls-direct-eval-contains-superproperty-2.js"><reason></reason></test> <test id="language/expressions/class/elements/derived-cls-direct-eval-contains-superproperty-2.js"><reason></reason></test>
<test id="language/expressions/class/elements/direct-eval-err-contains-newtarget.js"><reason></reason></test>
<test id="language/expressions/class/elements/fields-anonymous-function-length.js"><reason></reason></test> <test id="language/expressions/class/elements/fields-anonymous-function-length.js"><reason></reason></test>
<test id="language/expressions/class/elements/fields-multiple-definitions-static-private-methods-proxy.js"><reason></reason></test> <test id="language/expressions/class/elements/fields-multiple-definitions-static-private-methods-proxy.js"><reason></reason></test>
<test id="language/expressions/class/elements/gen-private-method-static/yield-spread-arr-multiple.js"><reason></reason></test> <test id="language/expressions/class/elements/gen-private-method-static/yield-spread-arr-multiple.js"><reason></reason></test>
@@ -4047,7 +4046,6 @@
<test id="language/statements/class/elements/async-gen-private-method/yield-star-sync-throw.js"><reason></reason></test> <test id="language/statements/class/elements/async-gen-private-method/yield-star-sync-throw.js"><reason></reason></test>
<test id="language/statements/class/elements/derived-cls-direct-eval-contains-superproperty-1.js"><reason></reason></test> <test id="language/statements/class/elements/derived-cls-direct-eval-contains-superproperty-1.js"><reason></reason></test>
<test id="language/statements/class/elements/derived-cls-direct-eval-contains-superproperty-2.js"><reason></reason></test> <test id="language/statements/class/elements/derived-cls-direct-eval-contains-superproperty-2.js"><reason></reason></test>
<test id="language/statements/class/elements/direct-eval-err-contains-newtarget.js"><reason></reason></test>
<test id="language/statements/class/elements/fields-anonymous-function-length.js"><reason></reason></test> <test id="language/statements/class/elements/fields-anonymous-function-length.js"><reason></reason></test>
<test id="language/statements/class/elements/gen-private-method-static/yield-spread-arr-multiple.js"><reason></reason></test> <test id="language/statements/class/elements/gen-private-method-static/yield-spread-arr-multiple.js"><reason></reason></test>
<test id="language/statements/class/elements/gen-private-method-static/yield-spread-arr-single.js"><reason></reason></test> <test id="language/statements/class/elements/gen-private-method-static/yield-spread-arr-single.js"><reason></reason></test>
@@ -7952,7 +7950,6 @@
<test id="built-ins/Atomics/waitAsync/was-woken-before-timeout.js"><reason></reason></test> <test id="built-ins/Atomics/waitAsync/was-woken-before-timeout.js"><reason></reason></test>
<test id="built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback.js"><reason></reason></test> <test id="built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback.js"><reason></reason></test>
<test id="built-ins/FinalizationRegistry/proto-from-ctor-realm.js"><reason></reason></test> <test id="built-ins/FinalizationRegistry/proto-from-ctor-realm.js"><reason></reason></test>
<test id="built-ins/Function/internals/Call/class-ctor-realm.js"><reason></reason></test>
<test id="intl402/Collator/proto-from-ctor-realm.js"><reason></reason></test> <test id="intl402/Collator/proto-from-ctor-realm.js"><reason></reason></test>
<test id="intl402/DateTimeFormat/proto-from-ctor-realm.js"><reason></reason></test> <test id="intl402/DateTimeFormat/proto-from-ctor-realm.js"><reason></reason></test>
<test id="intl402/DisplayNames/proto-from-ctor-realm.js"><reason></reason></test> <test id="intl402/DisplayNames/proto-from-ctor-realm.js"><reason></reason></test>
+21
View File
@@ -214,6 +214,27 @@ main (void)
jerry_release_value (parse_options.resource_name); jerry_release_value (parse_options.resource_name);
jerry_release_value (program); jerry_release_value (program);
const char *source_6 = "(class {})";
parse_options.options = JERRY_PARSE_HAS_RESOURCE;
parse_options.resource_name = jerry_create_string ((jerry_char_t *) "demo6.js");
program = jerry_parse ((const jerry_char_t *) source_6,
strlen (source_6),
&parse_options);
if (!jerry_value_is_error (program))
{
resource_value = jerry_get_resource_name (program);
compare_result = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL, resource_value, parse_options.resource_name);
TEST_ASSERT (jerry_value_is_true (compare_result));
jerry_release_value (resource_value);
jerry_release_value (compare_result);
}
jerry_release_value (parse_options.resource_name);
jerry_release_value (program);
jerry_cleanup (); jerry_cleanup ();
return 0; return 0;
+8
View File
@@ -138,6 +138,14 @@ main (void)
parse_options.options = JERRY_PARSE_HAS_USER_VALUE; parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
test_parse_function (source_p, &parse_options, true); test_parse_function (source_p, &parse_options, true);
/* There is no test for ESNEXT, using SYMBOL instead. */
if (jerry_is_feature_enabled (JERRY_FEATURE_SYMBOL))
{
source_p = TEST_STRING_LITERAL ("(class {})");
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
test_parse (source_p, &parse_options, true);
}
source_p = TEST_STRING_LITERAL ("eval('function f() {}')\n" source_p = TEST_STRING_LITERAL ("eval('function f() {}')\n"
"f"); "f");
parse_options.options = JERRY_PARSE_HAS_USER_VALUE; parse_options.options = JERRY_PARSE_HAS_USER_VALUE;