Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions jerry-core/api/jerry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

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);
}

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);
const cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);

return ecma_copy_value (script_p->resource_name);
#else /* !JERRY_RESOURCE_NAME */
Expand All @@ -5497,15 +5496,14 @@ jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
jerry_value_t
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;
}

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);
const 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))
{
Expand Down
127 changes: 72 additions & 55 deletions jerry-core/ecma/base/ecma-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,8 @@ ecma_gc_mark_properties (ecma_object_t *object_p, /**< object */
* Mark compiled code.
*/
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);

if (script_p->refs_and_type & CBC_SCRIPT_USER_VALUE_IS_OBJECT)
Expand Down Expand Up @@ -895,7 +892,9 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
const ecma_compiled_code_t *compiled_code_p;
compiled_code_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
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;
}
#endif /* JERRY_PARSER */
Expand Down Expand Up @@ -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)
&& 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;
Expand Down Expand Up @@ -1095,21 +1097,16 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
break;
}
#endif /* JERRY_BUILTIN_PROXY */
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{
ecma_gc_mark_bound_function_object (object_p);
break;
}
case ECMA_OBJECT_TYPE_FUNCTION:
{
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,
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 (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;

Expand All @@ -1126,25 +1123,22 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
#endif /* JERRY_ESNEXT */

#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 */
break;
}
#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;
}
#if JERRY_BUILTIN_REALMS
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
case ECMA_OBJECT_TYPE_BOUND_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));
ecma_gc_mark_bound_function_object (object_p);
break;
}
#endif /* JERRY_BUILTIN_REALMS */
#if JERRY_ESNEXT || JERRY_BUILTIN_REALMS
case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
{
Expand Down Expand Up @@ -1226,6 +1220,22 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
break;
}
#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:
{
break;
Expand Down Expand Up @@ -1974,40 +1984,6 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
#endif /* JERRY_SNAPSHOT_EXEC */
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:
{
ecma_extended_object_t *extended_func_p = (ecma_extended_object_t *) object_p;
Expand Down Expand Up @@ -2071,6 +2047,47 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
#endif /* JERRY_ESNEXT */
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:
{
JERRY_UNREACHABLE ();
Expand Down
30 changes: 25 additions & 5 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,9 +715,10 @@ typedef enum
ECMA_OBJECT_TYPE_PROXY = 6, /**< Proxy object ECMAScript v6 26.2 */
/* 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_BOUND_FUNCTION = 8, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_NATIVE_FUNCTION = 9, /**< Native function object */
ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION = 10, /**< Native built-in function object */
ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION = 8, /**< Native built-in function object */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 9, /**< Function objects (15.3), created through 15.3.4.5 routine */
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_t;
Expand Down Expand Up @@ -1161,6 +1162,17 @@ typedef struct
jmem_cpointer_tag_t target_function; /**< target function */
ecma_value_t args_len_or_this; /**< length of arguments or this value */
} 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;
} ecma_extended_object_t;

Expand Down Expand Up @@ -2477,8 +2489,8 @@ typedef struct
*/
typedef enum
{
ECMA_DATE_TZA_NONE = 0,
ECMA_DATE_TZA_SET = 1 << 0,
ECMA_DATE_TZA_NONE = 0, /**< no time-zone adjustment is set */
ECMA_DATE_TZA_SET = (1 << 0), /**< time-zone adjustment is set */
} ecma_date_object_flags_t;

/**
Expand All @@ -2490,6 +2502,14 @@ typedef struct
ecma_number_t date_value; /**< [[DateValue]] internal property */
} 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 */

/**
Expand Down
Loading