Skip to content
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
95 changes: 75 additions & 20 deletions jerry-core/ecma/base/ecma-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,36 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs - ECMA_OBJECT_REF_ONE);
} /* ecma_deref_object */

/**
* Mark objects referenced by arguments object
*/
static void
ecma_gc_mark_arguments_object (ecma_extended_object_t *ext_object_p) /**< arguments object */
{
JERRY_ASSERT (ecma_get_object_type ((ecma_object_t *) ext_object_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY);

ecma_unmapped_arguments_t *arguments_p = (ecma_unmapped_arguments_t *) ext_object_p;
ecma_value_t *argv_p = (ecma_value_t *) (arguments_p + 1);

if (ext_object_p->u.pseudo_array.extra_info & ECMA_ARGUMENTS_OBJECT_MAPPED)
{
ecma_mapped_arguments_t *mapped_arguments_p = (ecma_mapped_arguments_t *) ext_object_p;
argv_p = (ecma_value_t *) (mapped_arguments_p + 1);

ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, mapped_arguments_p->lex_env));
}

uint32_t arguments_number = arguments_p->header.u.pseudo_array.u2.arguments_number;

for (uint32_t i = 0; i < arguments_number; i++)
{
if (ecma_is_value_object (argv_p[i]))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (argv_p[i]));
}
}
} /* ecma_gc_mark_arguments_object */

/**
* Mark referenced object from property
*/
Expand Down Expand Up @@ -706,10 +736,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
{
JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS);

ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.pseudo_array.u2.lex_env_cp);

ecma_gc_set_object_visited (lex_env_p);
ecma_gc_mark_arguments_object (ext_object_p);
break;
}
}
Expand Down Expand Up @@ -915,6 +942,49 @@ ecma_gc_free_native_pointer (ecma_property_t *property_p) /**< property */
}
} /* ecma_gc_free_native_pointer */

/**
* Free specified arguments object.
*
* @return allocated object's size
*/
static size_t
ecma_free_arguments_object (ecma_extended_object_t *ext_object_p) /**< arguments object */
{
JERRY_ASSERT (ecma_get_object_type ((ecma_object_t *) ext_object_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY);

size_t object_size = sizeof (ecma_unmapped_arguments_t);

if (ext_object_p->u.pseudo_array.extra_info & ECMA_ARGUMENTS_OBJECT_MAPPED)
{
ecma_mapped_arguments_t *mapped_arguments_p = (ecma_mapped_arguments_t *) ext_object_p;
object_size = sizeof (ecma_mapped_arguments_t);

#if ENABLED (JERRY_SNAPSHOT_EXEC)
if (!(mapped_arguments_p->unmapped.header.u.pseudo_array.extra_info & ECMA_ARGUMENTS_OBJECT_STATIC_BYTECODE))
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
{
ecma_compiled_code_t *byte_code_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
mapped_arguments_p->u.byte_code);

ecma_bytecode_deref (byte_code_p);
}
}

ecma_value_t *argv_p = (ecma_value_t *) (((uint8_t *) ext_object_p) + object_size);
ecma_unmapped_arguments_t *arguments_p = (ecma_unmapped_arguments_t *) ext_object_p;
uint32_t arguments_number = arguments_p->header.u.pseudo_array.u2.arguments_number;

for (uint32_t i = 0; i < arguments_number; i++)
{
ecma_free_value_if_not_object (argv_p[i]);
}

uint32_t saved_argument_count = JERRY_MAX (arguments_number,
arguments_p->header.u.pseudo_array.u1.formal_params_number);

return object_size + (saved_argument_count * sizeof (ecma_value_t));
} /* ecma_free_arguments_object */

/**
* Free specified fast access mode array object.
*/
Expand Down Expand Up @@ -1444,22 +1514,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
{
case ECMA_PSEUDO_ARRAY_ARGUMENTS:
{
JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS);

uint32_t formal_params_number = ext_object_p->u.pseudo_array.u1.length;
ecma_value_t *arg_literal_p = (ecma_value_t *) (ext_object_p + 1);

for (uint32_t i = 0; i < formal_params_number; i++)
{
if (arg_literal_p[i] != ECMA_VALUE_EMPTY)
{
ecma_string_t *name_p = ecma_get_string_from_value (arg_literal_p[i]);
ecma_deref_ecma_string (name_p);
}
}

size_t formal_params_size = formal_params_number * sizeof (ecma_value_t);
ext_object_size += formal_params_size;
ext_object_size = ecma_free_arguments_object (ext_object_p);
break;
}
#if ENABLED (JERRY_BUILTIN_TYPEDARRAY)
Expand Down
45 changes: 42 additions & 3 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ enum
* or function call argument list */
ECMA_VALUE_SYNC_ITERATOR = ECMA_MAKE_VALUE (12), /**< option for ecma_op_get_iterator: sync iterator is requested */
ECMA_VALUE_ASYNC_ITERATOR = ECMA_MAKE_VALUE (13), /**< option for ecma_op_get_iterator: async iterator is requested */
ECMA_VALUE_INITIALIZED = ECMA_MAKE_VALUE (14), /**< represents initialized mapped arguments formal parameter */
};

#if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
Expand Down Expand Up @@ -648,7 +649,6 @@ typedef enum
ECMA_PROPERTY_GET_NO_OPTIONS = 0, /**< no option flags for ecma_op_object_get_property */
ECMA_PROPERTY_GET_VALUE = 1u << 0, /**< fill virtual_value field for virtual properties */
ECMA_PROPERTY_GET_EXT_REFERENCE = 1u << 1, /**< get extended reference to the property */
ECMA_PROPERTY_GET_HAS_OWN_PROP = 1u << 2, /**< internal [[HasOwnProperty]] method */
} ecma_property_get_option_bits_t;

/**
Expand Down Expand Up @@ -937,13 +937,13 @@ typedef struct
* [[IterationKind]] property for %Iterator% */
union
{
uint16_t length; /**< for arguments: length of names */
uint16_t formal_params_number; /**< for arguments: formal parameters number */
uint16_t class_id; /**< for typedarray: the specific class name id */
uint16_t iterator_index; /**< for %Iterator%: [[%Iterator%NextIndex]] property */
} u1;
union
{
ecma_value_t lex_env_cp; /**< for arguments: lexical environment */
uint32_t arguments_number; /**< for arguments: arguments number */
ecma_value_t arraybuffer; /**< for typedarray: internal arraybuffer */
ecma_value_t iterated_value; /**< for %Iterator%: [[IteratedObject]] property */
ecma_value_t spread_value; /**< for spread object: spreaded element */
Expand Down Expand Up @@ -2183,6 +2183,45 @@ typedef struct
uint32_t lazy_string_named_props; /**< number of lazy instantiated properties */
} ecma_property_counter_t;

/**
* Arguments object related status flags
*/
typedef enum
{
ECMA_ARGUMENTS_OBJECT_NO_FLAGS = 0, /* unmapped arguments object */
ECMA_ARGUMENTS_OBJECT_MAPPED = (1 << 0), /* mapped arguments object */
ECMA_ARGUMENTS_OBJECT_STATIC_BYTECODE = (1 << 1), /* static mapped arguments object */
ECMA_ARGUMENTS_OBJECT_CALLEE_INITIALIZED = (1 << 2), /* 'callee' property has been lazy initialized */
ECMA_ARGUMENTS_OBJECT_CALLER_INITIALIZED = (1 << 3), /* 'caller' property has been lazy initialized */
ECMA_ARGUMENTS_OBJECT_LENGTH_INITIALIZED = (1 << 4), /* 'length' property has been lazy initialized */
ECMA_ARGUMENTS_OBJECT_ITERATOR_INITIALIZED = (1 << 5), /* 'Symbol.iterator' property has been lazy initialized */
} ecma_arguments_object_flags_t;

/**
* Definition of unmapped arguments object
*/
typedef struct
{
ecma_extended_object_t header; /**< object header */
ecma_value_t callee; /**< 'callee' property */
} ecma_unmapped_arguments_t;

/**
* Definition of mapped arguments object
*/
typedef struct
{
ecma_unmapped_arguments_t unmapped; /**< unmapped arguments object header */
ecma_value_t lex_env; /**< environment reference */
union
{
ecma_value_t byte_code; /**< callee's compiled code */
#if ENABLED (JERRY_SNAPSHOT_EXEC)
ecma_compiled_code_t *byte_code_p; /**< real byte code pointer */
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
} u;
} ecma_mapped_arguments_t;

/**
* @}
* @}
Expand Down
34 changes: 17 additions & 17 deletions jerry-core/ecma/base/ecma-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1498,23 +1498,6 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG);
} /* ecma_bytecode_deref */

#if ENABLED (JERRY_ESNEXT)
/**
* Get the tagged template collection of the compiled code
*
* @return pointer to the tagged template collection
*/
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_FLAGS_HAS_TAGGED_LITERALS);

ecma_value_t *base_p = ecma_compiled_code_resolve_function_name (bytecode_header_p);

return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, base_p[-1]);
} /* ecma_compiled_code_get_tagged_template_collection */

/**
* Get the number of formal parameters of the compiled code
*
Expand Down Expand Up @@ -1552,6 +1535,23 @@ ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode
return ((ecma_value_t *) byte_p) - ecma_compiled_code_get_formal_params (bytecode_header_p);
} /* ecma_compiled_code_resolve_arguments_start */

#if ENABLED (JERRY_ESNEXT)
/**
* Get the tagged template collection of the compiled code
*
* @return pointer to the tagged template collection
*/
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_FLAGS_HAS_TAGGED_LITERALS);

ecma_value_t *base_p = ecma_compiled_code_resolve_function_name (bytecode_header_p);

return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, base_p[-1]);
} /* ecma_compiled_code_get_tagged_template_collection */

/**
* Resolve the position of the function name of the compiled code
*
Expand Down
6 changes: 2 additions & 4 deletions jerry-core/ecma/base/ecma-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,12 +536,10 @@ void ecma_raise_error_from_error_reference (ecma_value_t value);

void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
#if ENABLED (JERRY_ESNEXT)
ecma_collection_t *ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *bytecode_header_p);
#endif /* ENABLED (JERRY_ESNEXT) */
#if ENABLED (JERRY_ESNEXT)
uint32_t ecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_p);
ecma_value_t *ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode_header_p);
#if ENABLED (JERRY_ESNEXT)
ecma_collection_t *ecma_compiled_code_get_tagged_template_collection (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);
#endif /* ENABLED (JERRY_ESNEXT) */
ecma_value_t ecma_get_resource_name (const ecma_compiled_code_t *bytecode_p);
Expand Down
Loading