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