Create namespace with references for modules (#4646)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2021-04-12 15:58:56 +02:00
committed by GitHub
parent ef35c0329c
commit b3ec217b50
27 changed files with 1378 additions and 479 deletions
+11 -1
View File
@@ -138,12 +138,22 @@ const char * const ecma_error_local_variable_is_redeclared = "Local variable is
*/
const char * const ecma_error_expected_a_function = "Expected a function";
#if JERRY_ESNEXT
/**
* Error message, class constructor invoked without new keyword
*/
const char * const ecma_error_class_constructor_new = "Class constructor cannot be invoked without 'new'";
#endif /* JERRY_ERROR_MESSAGES */
/**
* Error message, variables declared by let/const must be initialized before reading their value
*/
const char * const ecma_error_let_const_not_initialized = ("Variables declared by let/const must be"
" initialized before reading their value");
#endif /* JERRY_ESNEXT */
#endif /* JERRY_ERROR_MESSAGES */
#if JERRY_SNAPSHOT_SAVE || JERRY_SNAPSHOT_EXEC
+8
View File
@@ -18,6 +18,8 @@
#ifndef ECMA_ERRORS_H
#define ECMA_ERRORS_H
#if JERRY_ERROR_MESSAGES
extern const char * const ecma_error_value_msg_p;
extern const char * const ecma_error_wrong_args_msg_p;
@@ -65,7 +67,13 @@ extern const char * const ecma_error_argument_is_not_an_regexp;
extern const char * const ecma_error_invalid_array_length;
extern const char * const ecma_error_local_variable_is_redeclared;
extern const char * const ecma_error_expected_a_function;
#if JERRY_ESNEXT
extern const char * const ecma_error_class_constructor_new;
extern const char * const ecma_error_let_const_not_initialized;
#endif /* JERRY_ESNEXT */
#endif /* JERRY_ERROR_MESSAGES */
/* snapshot errors */
extern const char * const ecma_error_maximum_snapshot_size;
+247 -100
View File
@@ -293,6 +293,55 @@ ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pa
}
} /* ecma_gc_mark_properties */
#if JERRY_MODULE_SYSTEM
/**
* Mark objects with references (e.g. namespace objects)
*/
static void
ecma_gc_mark_properties_with_references (ecma_object_t *object_p) /**< object */
{
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
#if JERRY_PROPRETY_HASHMAP
if (prop_iter_cp != JMEM_CP_NULL)
{
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
prop_iter_cp);
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
{
prop_iter_cp = object_p->u1.property_list_cp;
}
}
#endif /* JERRY_PROPRETY_HASHMAP */
while (prop_iter_cp != JMEM_CP_NULL)
{
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i);
if (ECMA_PROPERTY_IS_RAW (*property_p)
&& (*property_p & ECMA_PROPERTY_FLAG_DATA))
{
ecma_value_t value = ((ecma_property_pair_t *) prop_iter_p)->values[i].value;
if (ecma_is_value_object (value))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (value));
}
}
}
prop_iter_cp = prop_iter_p->next_property_cp;
}
} /* ecma_gc_mark_properties_with_references */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Mark objects referenced by bound function object.
*/
@@ -659,11 +708,32 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, outer_lex_env_cp));
}
if (ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
switch (ecma_get_lex_env_type (object_p))
{
ecma_object_t *binding_object_p = ecma_get_lex_env_binding_object (object_p);
ecma_gc_set_object_visited (binding_object_p);
return;
#if JERRY_ESNEXT
case ECMA_LEXICAL_ENVIRONMENT_CLASS:
{
#if JERRY_MODULE_SYSTEM
if (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA)
{
ecma_gc_mark_properties_with_references (object_p);
ecma_gc_set_object_visited (((ecma_lexical_environment_class_t *) object_p)->module_p);
return;
}
#endif /* JERRY_MODULE_SYSTEM */
/* FALLTHRU */
}
#endif /* JERRY_ESNEXT */
case ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND:
{
ecma_object_t *binding_object_p = ecma_get_lex_env_binding_object (object_p);
ecma_gc_set_object_visited (binding_object_p);
return;
}
default:
{
break;
}
}
}
else
@@ -733,10 +803,32 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
break;
}
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE_NAMESPACE:
{
JERRY_ASSERT (proto_cp == JMEM_CP_NULL);
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.cls.u3.value));
ecma_gc_mark_properties_with_references (object_p);
return;
}
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE:
{
ecma_module_node_t *node_p = ((ecma_module_t *) ext_object_p)->imports_p;
ecma_module_t *module_p = ((ecma_module_t *) ext_object_p);
if (module_p->scope_p != NULL)
{
ecma_gc_set_object_visited (((ecma_module_t *) ext_object_p)->scope_p);
}
if (module_p->namespace_object_p != NULL)
{
ecma_gc_set_object_visited (((ecma_module_t *) ext_object_p)->namespace_object_p);
}
ecma_module_node_t *node_p = module_p->imports_p;
while (node_p != NULL)
{
@@ -1083,21 +1175,16 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
* Free the native handle/pointer by calling its free callback.
*/
static void
ecma_gc_free_native_pointer (ecma_property_t *property_p) /**< property */
ecma_gc_free_native_pointer (ecma_value_t value) /**< property value */
{
JERRY_ASSERT (property_p != NULL);
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (value_p->value == JMEM_CP_NULL)
if (value == JMEM_CP_NULL)
{
return;
}
ecma_native_pointer_t *native_pointer_p;
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t,
value_p->value);
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value);
JERRY_ASSERT (native_pointer_p != NULL);
do
@@ -1317,11 +1404,132 @@ ecma_gc_free_executable_object (ecma_object_t *object_p) /**< object */
#endif /* JERRY_ESNEXT */
JERRY_STATIC_ASSERT (!ECMA_PROPERTY_IS_RAW (ECMA_PROPERTY_TYPE_DELETED),
ecma_property_type_deleted_must_not_be_raw_property);
JERRY_STATIC_ASSERT ((ECMA_PROPERTY_TYPE_DELETED & ECMA_PROPERTY_FLAG_LCACHED) == 0,
ecma_property_type_deleted_must_not_have_lcached_flag);
JERRY_STATIC_ASSERT (ECMA_GC_FREE_SECOND_PROPERTY == 1,
ecma_gc_free_second_must_be_one);
/**
* Free property of an object
*/
void
ecma_gc_free_property (ecma_object_t *object_p, /**< object */
ecma_property_pair_t *prop_pair_p, /**< property pair */
uint32_t options) /**< option bits including property index */
{
/* Both cannot be deleted. */
JERRY_ASSERT (prop_pair_p->header.types[0] != ECMA_PROPERTY_TYPE_DELETED
|| prop_pair_p->header.types[1] != ECMA_PROPERTY_TYPE_DELETED);
JERRY_ASSERT (prop_pair_p->header.types[0] != ECMA_PROPERTY_TYPE_HASHMAP);
uint32_t index = (options & ECMA_GC_FREE_SECOND_PROPERTY);
jmem_cpointer_t name_cp = prop_pair_p->names_cp[index];
ecma_property_t *property_p = prop_pair_p->header.types + index;
ecma_property_t property = *property_p;
#if JERRY_LCACHE
if ((property & ECMA_PROPERTY_FLAG_LCACHED) != 0)
{
ecma_lcache_invalidate (object_p, name_cp, property_p);
}
#endif /* JERRY_LCACHE */
if (ECMA_PROPERTY_IS_RAW (property))
{
if (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_PTR)
{
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
ecma_deref_ecma_string (prop_name_p);
}
if (property & ECMA_PROPERTY_FLAG_DATA)
{
ecma_free_value_if_not_object (prop_pair_p->values[index].value);
return;
}
if (JERRY_UNLIKELY (options & ECMA_GC_FREE_REFERENCES))
{
return;
}
#if JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
prop_pair_p->values[index].getter_setter_pair_cp);
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
#endif /* JERRY_CPOINTER_32_BIT */
return;
}
if (property == ECMA_PROPERTY_TYPE_DELETED)
{
return;
}
ecma_value_t value = prop_pair_p->values[index].value;
switch (name_cp)
{
#if JERRY_ESNEXT
case LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD:
{
ecma_environment_record_t *environment_record_p;
environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t, value);
jmem_heap_free_block (environment_record_p, sizeof (ecma_environment_record_t));
break;
}
case LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED:
{
ecma_value_t *compact_collection_p;
compact_collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t, value);
ecma_compact_collection_free (compact_collection_p);
break;
}
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF
case LIT_INTERNAL_MAGIC_STRING_WEAK_REFS:
{
ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, value);
for (uint32_t j = 0; j < refs_p->item_count; j++)
{
const ecma_value_t reference_value = refs_p->buffer_p[j];
if (!ecma_is_value_empty (reference_value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (reference_value);
if (ecma_object_class_is (obj_p, ECMA_OBJECT_CLASS_WEAKREF))
{
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ext_obj_p->u.cls.u3.target = ECMA_VALUE_UNDEFINED;
continue;
}
ecma_op_container_remove_weak_entry (obj_p, ecma_make_object_value (object_p));
}
}
ecma_collection_destroy (refs_p);
break;
}
#endif /* JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF */
default:
{
JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_gc_free_native_pointer (value);
break;
}
}
} /* ecma_gc_free_property */
/**
* Free properties of an object
*/
void
ecma_gc_free_properties (ecma_object_t *object_p) /**< object */
ecma_gc_free_properties (ecma_object_t *object_p, /**< object */
uint32_t options) /**< option bits */
{
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
@@ -1343,89 +1551,11 @@ ecma_gc_free_properties (ecma_object_t *object_p) /**< object */
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
/* Both cannot be deleted. */
JERRY_ASSERT (prop_iter_p->types[0] != ECMA_PROPERTY_TYPE_DELETED
|| prop_iter_p->types[1] != ECMA_PROPERTY_TYPE_DELETED);
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
for (uint32_t i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i);
jmem_cpointer_t name_cp = prop_pair_p->names_cp[i];
if (*property_p == ECMA_PROPERTY_TYPE_DELETED)
{
continue;
}
if (!ECMA_PROPERTY_IS_INTERNAL (*property_p))
{
ecma_free_property (object_p, name_cp, property_p);
continue;
}
/* Call the native's free callback. */
switch (name_cp)
{
#if JERRY_ESNEXT
case LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD:
{
ecma_environment_record_t *environment_record_p;
environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t,
prop_pair_p->values[i].value);
jmem_heap_free_block (environment_record_p, sizeof (ecma_environment_record_t));
break;
}
case LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED:
{
ecma_value_t *compact_collection_p;
compact_collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t,
prop_pair_p->values[i].value);
ecma_compact_collection_free (compact_collection_p);
break;
}
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF
case LIT_INTERNAL_MAGIC_STRING_WEAK_REFS:
{
ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
prop_pair_p->values[i].value);
for (uint32_t j = 0; j < refs_p->item_count; j++)
{
const ecma_value_t value = refs_p->buffer_p[j];
if (!ecma_is_value_empty (value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (value);
if (ecma_object_class_is (obj_p, ECMA_OBJECT_CLASS_WEAKREF))
{
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ext_obj_p->u.cls.u3.target = ECMA_VALUE_UNDEFINED;
continue;
}
ecma_op_container_remove_weak_entry (obj_p, ecma_make_object_value (object_p));
}
}
ecma_collection_destroy (refs_p);
break;
}
#endif /* JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF */
default:
{
JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_gc_free_native_pointer (property_p);
break;
}
}
#if JERRY_LCACHE
if (ecma_is_property_lcached (property_p))
{
ecma_lcache_invalidate (object_p, name_cp, property_p);
}
#endif /* JERRY_LCACHE */
ecma_gc_free_property (object_p, prop_pair_p, i | options);
}
prop_iter_cp = prop_iter_p->next_property_cp;
@@ -1447,9 +1577,19 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
if (ecma_is_lexical_environment (object_p))
{
#if JERRY_MODULE_SYSTEM
if (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA))
{
ecma_gc_free_properties (object_p, ECMA_GC_FREE_REFERENCES);
ecma_dealloc_extended_object (object_p, sizeof (ecma_lexical_environment_class_t));
return;
}
#endif /* JERRY_MODULE_SYSTEM */
if (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
ecma_gc_free_properties (object_p);
ecma_gc_free_properties (object_p, ECMA_GC_FREE_NO_OPTIONS);
}
ecma_dealloc_object (object_p);
@@ -1538,9 +1678,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
ext_object_size += sizeof (uint64_t) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
}
ecma_gc_free_properties (object_p);
ecma_dealloc_extended_object (object_p, ext_object_size);
return;
goto free_properties;
}
}
@@ -1548,7 +1686,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
{
case ECMA_OBJECT_TYPE_GENERAL:
{
ecma_gc_free_properties (object_p);
ecma_gc_free_properties (object_p, ECMA_GC_FREE_NO_OPTIONS);
ecma_dealloc_object (object_p);
return;
}
@@ -1599,6 +1737,14 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
break;
}
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE_NAMESPACE:
{
ecma_gc_free_properties (object_p, ECMA_GC_FREE_REFERENCES);
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
return;
}
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_PARSER
case ECMA_OBJECT_CLASS_SCRIPT:
{
@@ -1832,7 +1978,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
}
}
ecma_gc_free_properties (object_p);
free_properties:
ecma_gc_free_properties (object_p, ECMA_GC_FREE_NO_OPTIONS);
ecma_dealloc_extended_object (object_p, ext_object_size);
} /* ecma_gc_free_object */
+12 -1
View File
@@ -26,11 +26,22 @@
* @{
*/
/**
* Free option flags
*/
typedef enum
{
ECMA_GC_FREE_NO_OPTIONS = 0, /**< no options */
ECMA_GC_FREE_SECOND_PROPERTY = (1 << 0), /**< free second property of a property pair */
ECMA_GC_FREE_REFERENCES = (1 << 1), /**< free references */
} ecma_gc_free_options_t;
void ecma_init_gc_info (ecma_object_t *object_p);
void ecma_ref_object (ecma_object_t *object_p);
void ecma_ref_object_inline (ecma_object_t *object_p);
void ecma_deref_object (ecma_object_t *object_p);
void ecma_gc_free_properties (ecma_object_t *object_p);
void ecma_gc_free_property (ecma_object_t *object_p, ecma_property_pair_t *prop_pair_p, uint32_t options);
void ecma_gc_free_properties (ecma_object_t *object_p, uint32_t options);
void ecma_gc_run (void);
void ecma_free_unused_memory (jmem_pressure_t pressure);
+24 -6
View File
@@ -711,6 +711,9 @@ typedef enum
#if JERRY_BUILTIN_TYPEDARRAY
ECMA_OBJECT_CLASS_TYPEDARRAY, /**< TypedArray which does NOT need extra space to store length and offset */
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
ECMA_OBJECT_CLASS_MODULE_NAMESPACE, /**< Module Namespace (ECMAScript v11, 9.4.6) */
#endif /* JERRY_MODULE_SYSTEM */
/* These objects are marked by Garbage Collector. */
#if JERRY_ESNEXT
@@ -776,14 +779,14 @@ typedef enum
/* Types between 0 - 12 are ecma_object_type_t which can have a built-in flag. */
ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE = 13, /**< declarative lexical environment */
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 14, /**< object-bound lexical environment
* with provideThis flag */
ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND = 15, /**< object-bound lexical environment
* with provided home object reference */
#if JERRY_ESNEXT
ECMA_LEXICAL_ENVIRONMENT_CLASS = 14, /**< lexical environment with class */
#endif /* JERRY_ESNEXT */
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 15, /**< object-bound lexical environment */
ECMA_LEXICAL_ENVIRONMENT_TYPE_START = ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE, /**< first lexical
* environment type */
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND /**< maximum value */
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND /**< maximum value */
} ecma_lexical_environment_type_t;
#if JERRY_ESNEXT
@@ -848,10 +851,15 @@ typedef enum
#define ECMA_OBJECT_FLAG_EXTENSIBLE 0x20
/**
* Lexical environments created for non-closure code blocks
* Declarative lexical environments created for non-closure code blocks
*/
#define ECMA_OBJECT_FLAG_BLOCK ECMA_OBJECT_FLAG_EXTENSIBLE
/**
* Lexical environments with class has extra data
*/
#define ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA ECMA_OBJECT_FLAG_EXTENSIBLE
/**
* Bitshift index for an ecma-object reference count field
*/
@@ -1142,6 +1150,16 @@ typedef struct
#define ECMA_BUILTIN_IS_EXTENDED_BUILT_IN(object_type) \
((object_type) == ECMA_OBJECT_TYPE_CLASS || (object_type) == ECMA_OBJECT_TYPE_ARRAY)
/**
* Description of lexical environment with class
*/
typedef struct
{
ecma_object_t lexical_env; /**< lexical environment header */
ecma_object_t *module_p; /**< module reference */
} ecma_lexical_environment_class_t;
/**
* Description of native functions
*/
+145 -57
View File
@@ -123,7 +123,7 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
/**
* Create a object lexical environment with specified outer lexical environment
* (or NULL if the environment is not nested), binding object and provided type flag.
* (or NULL if the environment is not nested), and binding object.
*
* See also: ECMA-262 v5, 10.2.1.2
*
@@ -133,23 +133,15 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
*/
ecma_object_t *
ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< outer lexical environment */
ecma_object_t *binding_obj_p, /**< binding object */
ecma_lexical_environment_type_t type) /**< type of the new lexical environment */
ecma_object_t *binding_obj_p) /**< binding object */
{
#if JERRY_ESNEXT
JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
|| type == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
#else /* !JERRY_ESNEXT */
JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
#endif /* JERRY_ESNEXT */
JERRY_ASSERT (binding_obj_p != NULL
&& !ecma_is_lexical_environment (binding_obj_p));
ecma_object_t *new_lexical_environment_p = ecma_alloc_object ();
const ecma_object_descriptor_t lexical_env_flag = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV;
new_lexical_environment_p->type_flags_refs = (ecma_object_descriptor_t) (type | lexical_env_flag);
new_lexical_environment_p->type_flags_refs = (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV
| ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_init_gc_info (new_lexical_environment_p);
@@ -161,6 +153,45 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out
return new_lexical_environment_p;
} /* ecma_create_object_lex_env */
#if JERRY_ESNEXT
/**
* Create a lexical environment with a specified size.
*
* @return pointer to the descriptor of the lexical environment
*/
ecma_object_t *
ecma_create_lex_env_class (ecma_object_t *outer_lexical_environment_p, /**< outer lexical environment */
size_t lexical_env_size) /**< size of the lexical environment */
{
ecma_object_t *new_lexical_environment_p;
ecma_object_descriptor_t type_flags_refs = (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV
| ECMA_LEXICAL_ENVIRONMENT_CLASS);
if (lexical_env_size > 0)
{
new_lexical_environment_p = (ecma_object_t *) ecma_alloc_extended_object (lexical_env_size);
type_flags_refs |= ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA;
}
else
{
new_lexical_environment_p = ecma_alloc_object ();
}
new_lexical_environment_p->type_flags_refs = type_flags_refs;
ecma_init_gc_info (new_lexical_environment_p);
new_lexical_environment_p->u1.property_list_cp = JMEM_CP_NULL;
ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p);
return new_lexical_environment_p;
} /* ecma_create_lex_env_class */
#endif /* JERRY_ESNEXT */
/**
* Check if the object is lexical environment.
*
@@ -203,6 +234,29 @@ ecma_get_object_type (const ecma_object_t *object_p) /**< object */
return (ecma_object_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK);
} /* ecma_get_object_type */
/**
* Get value of an object if the class matches
*
* @return value of the object if the class matches
* ECMA_VALUE_NOT_FOUND otherwise
*/
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_object_class_is (ecma_object_t *object_p, /**< object */
ecma_object_class_type_t class_id) /**< class id */
{
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
if (ext_object_p->u.cls.type == (uint8_t) class_id)
{
return true;
}
}
return false;
} /* ecma_object_class_is */
/**
* Check if the object is a built-in object
*
@@ -286,7 +340,8 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun
JERRY_ASSERT (ecma_is_lexical_environment (object_p));
#if JERRY_ESNEXT
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
|| (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA) == 0));
#else /* !JERRY_ESNEXT */
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
#endif /* JERRY_ESNEXT */
@@ -568,6 +623,51 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p);
} /* ecma_create_named_accessor_property */
#if JERRY_MODULE_SYSTEM
/**
* Create property reference
*/
void
ecma_create_named_reference_property (ecma_object_t *object_p, /**< object */
ecma_string_t *name_p, /**< property name */
ecma_property_t *property_p) /**< referenced property */
{
JERRY_ASSERT (object_p != NULL && name_p != NULL && property_p != NULL);
JERRY_ASSERT (*property_p & ECMA_PROPERTY_FLAG_DATA);
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
JERRY_ASSERT ((ecma_is_lexical_environment (object_p)
&& ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA))
|| ecma_object_class_is (object_p, ECMA_OBJECT_CLASS_MODULE_NAMESPACE));
uint8_t type_and_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE;
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
jmem_cpointer_tag_t offset = (jmem_cpointer_tag_t) (((uintptr_t) property_p) & 0x1);
#if JERRY_CPOINTER_32_BIT
if (offset != 0)
{
--value_p;
}
#else /* !JERRY_CPOINTER_32_BIT */
if (offset == 0)
{
++value_p;
}
#endif /* JERRY_CPOINTER_32_BIT */
JERRY_ASSERT ((((uintptr_t) value_p) & (((uintptr_t) 1 << JMEM_ALIGNMENT_LOG) - 1)) == 0);
ecma_property_value_t value;
ECMA_SET_NON_NULL_POINTER_TAG (value.value, value_p, offset);
ecma_create_property (object_p, name_p, type_and_flags, value, NULL);
} /* ecma_create_named_reference_property */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Find named data property or named accessor property in a specified object.
*
@@ -748,48 +848,6 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property
return ECMA_PROPERTY_VALUE_PTR (property_p);
} /* ecma_get_named_data_property */
/**
* Free property values and change their type to deleted.
*
* Note:
* internal properties are not supported
*/
void
ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */
jmem_cpointer_t name_cp, /**< name of the property or ECMA_NULL_POINTER */
ecma_property_t *property_p) /**< property */
{
JERRY_ASSERT (object_p != NULL && property_p != NULL);
JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p));
if (*property_p & ECMA_PROPERTY_FLAG_DATA)
{
ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
}
else
{
#if JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp);
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
#endif /* JERRY_CPOINTER_32_BIT */
}
#if JERRY_LCACHE
if (ecma_is_property_lcached (property_p))
{
ecma_lcache_invalidate (object_p, name_cp, property_p);
}
#endif /* JERRY_LCACHE */
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR)
{
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
ecma_deref_ecma_string (prop_name_p);
}
} /* ecma_free_property */
/**
* Delete the object's property referenced by its value pointer.
*
@@ -829,7 +887,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) cur_prop_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
for (uint32_t i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if ((prop_pair_p->values + i) == prop_value_p)
{
@@ -844,7 +902,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
}
#endif /* JERRY_PROPRETY_HASHMAP */
ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i);
ecma_gc_free_property (object_p, prop_pair_p, i);
cur_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED;
@@ -1008,6 +1066,36 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_set_named_accessor_property_setter */
#if JERRY_MODULE_SYSTEM
/**
* Gets the referenced property value
*
* @return pointer to the value
*/
extern inline ecma_property_value_t * JERRY_ATTR_ALWAYS_INLINE
ecma_get_property_value_from_named_reference (ecma_property_value_t *reference_p) /**< data property reference */
{
ecma_value_t value = reference_p->value;
reference_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_property_value_t, value);
#if JERRY_CPOINTER_32_BIT
if (ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (value))
{
++reference_p;
}
#else /* !JERRY_CPOINTER_32_BIT */
if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (value))
{
--reference_p;
}
#endif /* JERRY_CPOINTER_32_BIT */
return reference_p;
} /* ecma_get_property_value_from_named_reference */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Get property's 'Writable' attribute value
*
+16 -4
View File
@@ -358,6 +358,9 @@ const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p,
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
bool ecma_string_is_empty (const ecma_string_t *string_p);
bool ecma_string_is_length (const ecma_string_t *string_p);
#if JERRY_ESNEXT
bool ecma_compare_ecma_string_to_global_symbol (ecma_string_t *string_p, lit_magic_string_id_t property_id);
#endif /* JERRY_ESNEXT */
jmem_cpointer_t ecma_string_to_property_name (ecma_string_t *prop_name_p, ecma_property_t *name_type_p);
ecma_string_t *ecma_string_from_property_name (ecma_property_t property, jmem_cpointer_t prop_name_cp);
@@ -457,11 +460,14 @@ void ecma_compact_collection_free (ecma_value_t *compact_collection_p);
/* ecma-helpers.c */
ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type);
ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p);
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, ecma_object_t *binding_obj_p,
ecma_lexical_environment_type_t type);
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, ecma_object_t *binding_obj_p);
#if JERRY_ESNEXT
ecma_object_t *ecma_create_lex_env_class (ecma_object_t *outer_lexical_environment_p, size_t lexical_env_size);
#endif /* JERRY_ESNEXT */
bool JERRY_ATTR_PURE ecma_is_lexical_environment (const ecma_object_t *object_p);
void ecma_op_ordinary_object_set_extensible (ecma_object_t *object_p);
ecma_object_type_t JERRY_ATTR_PURE ecma_get_object_type (const ecma_object_t *object_p);
bool JERRY_ATTR_PURE ecma_object_class_is (ecma_object_t *object_p, ecma_object_class_type_t class_id);
bool JERRY_ATTR_PURE ecma_get_object_is_builtin (const ecma_object_t *object_p);
void ecma_set_object_is_builtin (ecma_object_t *object_p);
uint8_t ecma_get_object_builtin_id (ecma_object_t *object_p);
@@ -475,13 +481,15 @@ ecma_create_named_data_property (ecma_object_t *object_p, ecma_string_t *name_p,
ecma_property_value_t *
ecma_create_named_accessor_property (ecma_object_t *object_p, ecma_string_t *name_p, ecma_object_t *get_p,
ecma_object_t *set_p, uint8_t prop_attributes, ecma_property_t **out_prop_p);
#if JERRY_MODULE_SYSTEM
void ecma_create_named_reference_property (ecma_object_t *object_p, ecma_string_t *name_p,
ecma_property_t *property_p);
#endif /* JERRY_MODULE_SYSTEM */
ecma_property_t *
ecma_find_named_property (ecma_object_t *obj_p, ecma_string_t *name_p);
ecma_property_value_t *
ecma_get_named_data_property (ecma_object_t *obj_p, ecma_string_t *name_p);
void ecma_free_property (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *property_p);
void ecma_delete_property (ecma_object_t *object_p, ecma_property_value_t *prop_value_p);
void ecma_named_data_property_assign_value (ecma_object_t *obj_p, ecma_property_value_t *prop_value_p,
@@ -493,6 +501,10 @@ void ecma_set_named_accessor_property_getter (ecma_object_t *object_p, ecma_prop
ecma_object_t *getter_p);
void ecma_set_named_accessor_property_setter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p,
ecma_object_t *setter_p);
#if JERRY_MODULE_SYSTEM
ecma_property_value_t *
ecma_get_property_value_from_named_reference (ecma_property_value_t *reference_p);
#endif /* JERRY_MODULE_SYSTEM */
bool ecma_is_property_writable (ecma_property_t property);
void ecma_set_property_writable_attr (ecma_property_t *property_p, bool is_writable);
bool ecma_is_property_enumerable (ecma_property_t property);
+59 -81
View File
@@ -393,15 +393,9 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */
}
JERRY_ASSERT (module_p->header.u.cls.u1.module_state == JERRY_MODULE_STATE_LINKED);
#if JERRY_BUILTIN_REALMS
ecma_object_t *global_object_p = (ecma_object_t *) ecma_op_function_get_realm (module_p->compiled_code_p);
#else /* !JERRY_BUILTIN_REALMS */
ecma_object_t *global_object_p = ecma_builtin_get_global ();
#endif /* JERRY_BUILTIN_REALMS */
JERRY_ASSERT (module_p->scope_p != NULL);
module_p->header.u.cls.u1.module_state = JERRY_MODULE_STATE_EVALUATING;
module_p->scope_p = ecma_create_decl_lex_env (ecma_get_global_environment (global_object_p));
ecma_value_t ret_value;
ret_value = vm_run_module (module_p);
@@ -457,21 +451,11 @@ ecma_module_namespace_object_add_export_if_needed (ecma_module_t *module_p, /**<
return result;
}
ecma_object_t *ref_base_lex_env_p;
ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
&ref_base_lex_env_p,
record.name_p);
ecma_property_t *new_property_p;
ecma_create_named_data_property (module_p->namespace_object_p,
export_name_p,
ECMA_PROPERTY_FIXED,
&new_property_p);
ecma_property_t *property_p = ecma_find_named_property (record.module_p->scope_p, record.name_p);
ecma_named_data_property_assign_value (module_p->namespace_object_p,
ECMA_PROPERTY_VALUE_PTR (new_property_p),
prop_value);
ecma_free_value (prop_value);
ecma_create_named_reference_property (module_p->namespace_object_p,
export_name_p,
property_p);
return result;
} /* ecma_module_namespace_object_add_export_if_needed */
@@ -491,13 +475,23 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
return result;
}
JERRY_ASSERT (module_p->header.u.cls.u1.module_state == JERRY_MODULE_STATE_EVALUATED);
JERRY_ASSERT (module_p->header.u.cls.u1.module_state >= JERRY_MODULE_STATE_LINKED
&& module_p->header.u.cls.u1.module_state <= JERRY_MODULE_STATE_EVALUATED);
ecma_module_resolve_set_t *resolve_set_p = NULL;
ecma_module_resolve_stack_t *stack_p = NULL;
module_p->namespace_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
0,
ECMA_OBJECT_TYPE_GENERAL);
ecma_object_t *namespace_object_p = ecma_create_object (NULL,
sizeof (ecma_extended_object_t),
ECMA_OBJECT_TYPE_CLASS);
namespace_object_p->type_flags_refs &= (ecma_object_descriptor_t) ~ECMA_OBJECT_FLAG_EXTENSIBLE;
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) namespace_object_p;
ext_object_p->u.cls.type = ECMA_OBJECT_CLASS_MODULE_NAMESPACE;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.cls.u3.value, module_p);
module_p->namespace_object_p = namespace_object_p;
ecma_deref_object (namespace_object_p);
ecma_module_resolve_stack_push (&stack_p, module_p, ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR));
while (stack_p != NULL)
@@ -516,13 +510,6 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
continue;
}
result = ecma_module_evaluate (current_module_p);
if (ECMA_IS_VALUE_ERROR (result))
{
break;
}
ecma_module_names_t *export_names_p = current_module_p->local_exports_p;
if (export_names_p != NULL)
@@ -569,6 +556,11 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
star_export_p = star_export_p->next_p;
}
if (ECMA_IS_VALUE_ERROR (result))
{
break;
}
}
/* Clean up. */
@@ -659,8 +651,6 @@ ecma_module_connect_imports (ecma_module_t *module_p)
const bool is_namespace_import = ecma_compare_ecma_string_to_magic_id (import_names_p->imex_name_p,
LIT_MAGIC_STRING_ASTERIX_CHAR);
ecma_value_t prop_value;
if (is_namespace_import)
{
result = ecma_module_create_namespace_object (imported_module_p);
@@ -670,8 +660,12 @@ ecma_module_connect_imports (ecma_module_t *module_p)
return result;
}
ecma_ref_object (imported_module_p->namespace_object_p);
prop_value = ecma_make_object_value (imported_module_p->namespace_object_p);
ecma_property_value_t *value_p;
value_p = ecma_create_named_data_property (module_p->scope_p,
import_names_p->local_name_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
value_p->value = ecma_make_object_value (imported_module_p->namespace_object_p);
}
else /* !is_namespace_import */
{
@@ -691,46 +685,28 @@ ecma_module_connect_imports (ecma_module_t *module_p)
if (record.module_p->header.u.cls.u1.module_state == JERRY_MODULE_STATE_NATIVE)
{
ecma_object_t *object_p = record.module_p->namespace_object_p;
ecma_value_t prop_value;
prop_value = ecma_op_object_find_own (ecma_make_object_value (object_p), object_p, record.name_p);
JERRY_ASSERT (ecma_is_value_found (prop_value));
ecma_property_value_t *value_p;
value_p = ecma_create_named_data_property (module_p->scope_p,
import_names_p->local_name_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
value_p->value = ecma_copy_value_if_not_object (prop_value);
}
else
{
result = ecma_module_evaluate (record.module_p);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
ecma_object_t *ref_base_lex_env_p;
prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
&ref_base_lex_env_p,
record.name_p);
ecma_property_t *property_p = ecma_find_named_property (record.module_p->scope_p, record.name_p);
ecma_create_named_reference_property (module_p->scope_p,
import_names_p->local_name_p,
property_p);
}
}
ecma_property_t *prop_p = ecma_op_create_mutable_binding (local_env_p,
import_names_p->local_name_p,
true /* is_deletable */);
JERRY_ASSERT (prop_p != ECMA_PROPERTY_POINTER_ERROR);
if (prop_p != NULL)
{
JERRY_ASSERT (ecma_is_value_undefined (ECMA_PROPERTY_VALUE_PTR (prop_p)->value));
ECMA_PROPERTY_VALUE_PTR (prop_p)->value = prop_value;
ecma_deref_if_object (prop_value);
}
else
{
ecma_op_set_mutable_binding (local_env_p,
import_names_p->local_name_p,
prop_value,
false /* is_strict */);
ecma_free_value (prop_value);
}
import_names_p = import_names_p->next_p;
}
@@ -975,6 +951,20 @@ restart:
node_p = node_p->next_p;
}
if (current_module_p->scope_p == NULL)
{
/* Initialize scope for handling circular references. */
ecma_value_t result = vm_init_module_scope (current_module_p);
if (ECMA_IS_VALUE_ERROR (result))
{
module_p->header.u.cls.u1.module_state = JERRY_MODULE_STATE_ERROR;
goto error;
}
JERRY_ASSERT (result == ECMA_VALUE_EMPTY);
}
if (current_module_p->header.u.cls.u3.dfs_ancestor_index != current_p->dfs_index)
{
current_p = current_p->parent_p;
@@ -1079,15 +1069,10 @@ ecma_module_release_module (ecma_module_t *module_p) /**< module */
JERRY_ASSERT (state != JERRY_MODULE_STATE_INVALID);
if (module_p->namespace_object_p != NULL)
{
/* The module structure keeps a strong reference to the namespace object, which will require an extra GC call. */
JERRY_CONTEXT (ecma_gc_new_objects)++;
ecma_deref_object (module_p->namespace_object_p);
#ifndef JERRY_NDEBUG
module_p->namespace_object_p = NULL;
module_p->scope_p = NULL;
module_p->namespace_object_p = NULL;
#endif /* JERRY_NDEBUG */
}
if (state == JERRY_MODULE_STATE_NATIVE)
{
@@ -1099,13 +1084,6 @@ ecma_module_release_module (ecma_module_t *module_p) /**< module */
ecma_module_release_module_nodes (module_p->indirect_exports_p, false);
ecma_module_release_module_nodes (module_p->star_exports_p, false);
if (state >= JERRY_MODULE_STATE_EVALUATING)
{
/* The module structure keeps a strong reference to the module scope, which will require an extra GC call. */
JERRY_CONTEXT (ecma_gc_new_objects)++;
ecma_deref_object (module_p->scope_p);
}
if (module_p->compiled_code_p != NULL)
{
ecma_bytecode_deref (module_p->compiled_code_p);