diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md
index 946f98a75..65b20a7b5 100644
--- a/docs/02.API-REFERENCE.md
+++ b/docs/02.API-REFERENCE.md
@@ -212,8 +212,10 @@ Option bits for [jerry_parse](#jerry_parse) and
- JERRY_PARSE_NO_OPTS - no options passed
- JERRY_PARSE_STRICT_MODE - enable strict mode
+ - JERRY_PARSE_MODULE - parse source as an ECMAScript module
*New in version 2.0*.
+*Changed in version 2.4: Added `JERRY_PARSE_MODULE`.*
## jerry_gc_mode_t
diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c
index 61db554c4..e43f786ae 100644
--- a/jerry-core/api/jerry.c
+++ b/jerry-core/api/jerry.c
@@ -246,10 +246,6 @@ jerry_cleanup (void)
}
}
-#if ENABLED (JERRY_MODULE_SYSTEM)
- ecma_module_cleanup ();
-#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
-
#if ENABLED (JERRY_BUILTIN_PROMISE)
ecma_free_all_enqueued_jobs ();
#endif /* ENABLED (JERRY_BUILTIN_PROMISE) */
@@ -456,6 +452,15 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
}
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
+ if ((parse_opts & JERRY_PARSE_MODULE) != 0)
+ {
+#if ENABLED (JERRY_MODULE_SYSTEM)
+ ecma_module_initialize_context (ecma_get_string_from_value (resource_name));
+#else /* !ENABLED (JERRY_MODULE_SYSTEM) */
+ return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("Module system has been disabled.")));
+#endif /* !ENABLED (JERRY_MODULE_SYSTEM) */
+ }
+
ecma_compiled_code_t *bytecode_data_p = parser_parse_script (NULL,
0,
source_p,
@@ -465,9 +470,44 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
if (JERRY_UNLIKELY (bytecode_data_p == NULL))
{
+#if ENABLED (JERRY_MODULE_SYSTEM)
+ if ((parse_opts & JERRY_PARSE_MODULE) != 0)
+ {
+ ecma_module_cleanup_context ();
+ }
+#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
+
return ecma_create_error_reference_from_context ();
}
+#if ENABLED (JERRY_MODULE_SYSTEM)
+ if ((parse_opts & JERRY_PARSE_MODULE) != 0)
+ {
+ if (ECMA_IS_VALUE_ERROR (ecma_module_parse_referenced_modules ()))
+ {
+ ecma_bytecode_deref (bytecode_data_p);
+ ecma_module_cleanup_context ();
+
+ return ecma_create_error_reference_from_context ();
+ }
+
+ ecma_object_t *obj_p = ecma_create_object (NULL, sizeof (ecma_extended_object_t), ECMA_OBJECT_TYPE_CLASS);
+
+ ecma_extended_object_t *wrapper_p = (ecma_extended_object_t *) obj_p;
+ wrapper_p->u.class_prop.class_id = LIT_MAGIC_STRING_RUNNABLE_UL;
+ wrapper_p->u.class_prop.extra_info = ECMA_RUNNABLE_FLAGS_MODULE;
+
+ ecma_module_t *root_module_p = JERRY_CONTEXT (module_current_p);
+ root_module_p->compiled_code_p = bytecode_data_p;
+
+ ECMA_SET_INTERNAL_VALUE_POINTER (wrapper_p->u.class_prop.u.value, root_module_p);
+ JERRY_CONTEXT (module_current_p) = NULL;
+ JERRY_CONTEXT (module_list_p) = NULL;
+
+ return ecma_make_object_value (obj_p);
+ }
+#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
+
ecma_object_t *global_object_p = ecma_builtin_get_global ();
#if ENABLED (JERRY_BUILTIN_REALMS)
@@ -475,6 +515,9 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
ecma_object_t *lex_env_p = ecma_get_global_environment (global_object_p);
+
+ /* TODO(dbatyai): For now Scripts continue to return Function objects due to backwards compatibility. This should be
+ * changed to also return a Runnable object eventually. */
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p);
ecma_bytecode_deref (bytecode_data_p);
@@ -588,15 +631,35 @@ jerry_run (const jerry_value_t func_val) /**< function to run */
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
}
- ecma_object_t *func_obj_p = ecma_get_object_from_value (func_val);
+ ecma_object_t *obj_p = ecma_get_object_from_value (func_val);
- if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_FUNCTION
- || ecma_get_object_is_builtin (func_obj_p))
+#if ENABLED (JERRY_MODULE_SYSTEM)
+ if (ecma_object_class_is (obj_p, LIT_MAGIC_STRING_RUNNABLE_UL))
+ {
+ ecma_extended_object_t *wrapper_p = (ecma_extended_object_t *) obj_p;
+ JERRY_ASSERT (wrapper_p->u.class_prop.extra_info == ECMA_RUNNABLE_FLAGS_MODULE);
+ ecma_module_t *root_module_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_module_t, wrapper_p->u.class_prop.u.value);
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ ecma_object_t *global_object_p = (ecma_object_t *) ecma_op_function_get_realm (root_module_p->compiled_code_p);
+#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
+ ecma_object_t *global_object_p = ecma_builtin_get_global ();
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
+ ecma_create_global_lexical_block (global_object_p);
+ root_module_p->scope_p = ecma_get_global_scope (global_object_p);
+
+ return jerry_return (vm_run_module (root_module_p));
+ }
+#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
+
+ if (ecma_get_object_type (obj_p) != ECMA_OBJECT_TYPE_FUNCTION
+ || ecma_get_object_is_builtin (obj_p))
{
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
}
- ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
+ ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p;
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c
index 96a6f69f5..44a6500bd 100644
--- a/jerry-core/ecma/base/ecma-gc.c
+++ b/jerry-core/ecma/base/ecma-gc.c
@@ -1630,6 +1630,20 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
break;
}
#endif /* ENABLED (JERRY_ESNEXT) */
+#if ENABLED (JERRY_MODULE_SYSTEM)
+ case LIT_MAGIC_STRING_RUNNABLE_UL:
+ {
+ ecma_extended_object_t *wrapper_p = (ecma_extended_object_t *) object_p;
+
+ JERRY_ASSERT (wrapper_p->u.class_prop.extra_info == ECMA_RUNNABLE_FLAGS_MODULE);
+ ecma_module_t *root_module_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_module_t,
+ wrapper_p->u.class_prop.u.value);
+
+ ecma_bytecode_deref (root_module_p->compiled_code_p);
+ ecma_module_cleanup (root_module_p);
+ break;
+ }
+#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
default:
{
/* The undefined id represents an uninitialized class. */
diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h
index d85759f0a..a15bdaa63 100644
--- a/jerry-core/ecma/base/ecma-globals.h
+++ b/jerry-core/ecma/base/ecma-globals.h
@@ -1059,6 +1059,14 @@ typedef struct
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
#if ENABLED (JERRY_ESNEXT)
+/**
+ * Flags for runnable objects.
+ */
+typedef enum
+{
+ ECMA_RUNNABLE_FLAGS_EMPTY = (0), /**< empty flags */
+ ECMA_RUNNABLE_FLAGS_MODULE = (1 << 0) /**< runnable is a module */
+} ecma_runnable_flags_t;
/**
* Description of arrow function objects.
diff --git a/jerry-core/ecma/base/ecma-module.c b/jerry-core/ecma/base/ecma-module.c
index c1302211b..aecc5e250 100644
--- a/jerry-core/ecma/base/ecma-module.c
+++ b/jerry-core/ecma/base/ecma-module.c
@@ -37,8 +37,9 @@
* @return pointer to ecma_string_t containing the normalized and zero terminated path
*/
ecma_string_t *
-ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier */
- prop_length_t size) /**< size of module specifier */
+ecma_module_create_normalized_path (const lit_utf8_byte_t *char_p, /**< module path specifier */
+ lit_utf8_size_t size, /**< size of module specifier */
+ ecma_string_t *const base_path_p) /**< base path for the module specifier */
{
JERRY_ASSERT (size > 0);
ecma_string_t *ret_p = NULL;
@@ -57,16 +58,13 @@ ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier
lit_utf8_byte_t *module_path_p = NULL;
lit_utf8_size_t module_path_size = 0;
- /* Check if we have a current module, and use its path as the base path. */
- JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p) != NULL);
- if (JERRY_CONTEXT (module_top_context_p)->module_p != NULL)
+ if (base_path_p != NULL)
{
- JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p)->module_p->path_p != NULL);
- module_path_size = ecma_string_get_size (JERRY_CONTEXT (module_top_context_p)->module_p->path_p);
+ module_path_size = ecma_string_get_size (base_path_p);
module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
lit_utf8_size_t module_utf8_size;
- module_utf8_size = ecma_string_copy_to_utf8_buffer (JERRY_CONTEXT (module_top_context_p)->module_p->path_p,
+ module_utf8_size = ecma_string_copy_to_utf8_buffer (base_path_p,
module_path_p,
module_path_size);
@@ -96,26 +94,39 @@ ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier
} /* ecma_module_create_normalized_path */
/**
- * Find a module with a specific identifier
+ * Push a new module into the module list. New modules are inserted after the head module, this way in the end the
+ * root module remains the first in the list.
+ */
+static void
+ecma_module_list_push (ecma_module_t *module_p)
+{
+ ecma_module_t *head_p = JERRY_CONTEXT (module_list_p);
+ module_p->next_p = head_p->next_p;
+ head_p->next_p = module_p;
+} /* ecma_module_list_push */
+
+/**
+ * Lookup a module with a specific identifier.
*
* @return pointer to ecma_module_t, if found
* NULL, otherwise
*/
-ecma_module_t *
-ecma_module_find_module (ecma_string_t *const path_p) /**< module identifier */
+static ecma_module_t *
+ecma_module_list_lookup (ecma_string_t *const path_p) /**< module identifier */
{
- ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
+ ecma_module_t *current_p = JERRY_CONTEXT (module_list_p);
while (current_p != NULL)
{
if (ecma_compare_ecma_strings (path_p, current_p->path_p))
{
return current_p;
}
+
current_p = current_p->next_p;
}
- return current_p;
-} /* ecma_module_find_module */
+ return NULL;
+} /* ecma_module_list_lookup */
/**
* Create a new module
@@ -129,8 +140,7 @@ ecma_module_create_module (ecma_string_t *const path_p) /**< module identifier *
memset (module_p, 0, sizeof (ecma_module_t));
module_p->path_p = path_p;
- module_p->next_p = JERRY_CONTEXT (ecma_modules_p);
- JERRY_CONTEXT (ecma_modules_p) = module_p;
+ ecma_module_list_push (module_p);
return module_p;
} /* ecma_module_create_module */
@@ -140,9 +150,10 @@ ecma_module_create_module (ecma_string_t *const path_p) /**< module identifier *
* @return pointer to found or newly created module structure
*/
ecma_module_t *
-ecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path */
+ecma_module_find_module (ecma_string_t *const path_p) /**< module path */
{
- ecma_module_t *module_p = ecma_module_find_module (path_p);
+ ecma_module_t *module_p = ecma_module_list_lookup (path_p);
+
if (module_p)
{
ecma_deref_ecma_string (path_p);
@@ -150,7 +161,7 @@ ecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path
}
return ecma_module_create_module (path_p);
-} /* ecma_module_find_or_create_module */
+} /* ecma_module_find_module */
/**
* Create a new native module
@@ -158,28 +169,83 @@ ecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path
* @return pointer to created module
*/
ecma_module_t *
-ecma_module_create_native_module (ecma_string_t *const path_p, /**< module identifier */
- ecma_object_t *const namespace_p) /**< module namespace */
+ecma_module_find_native_module (ecma_string_t *const path_p)
{
- ecma_module_t *module_p = ecma_module_create_module (path_p);
- module_p->state = ECMA_MODULE_STATE_NATIVE;
- module_p->namespace_object_p = namespace_p;
- return module_p;
-} /* ecma_module_create_native_module */
+ ecma_module_t *module_p = ecma_module_list_lookup (path_p);
+
+ if (module_p != NULL)
+ {
+ return module_p;
+ }
+
+ ecma_value_t native = jerry_port_get_native_module (ecma_make_string_value (path_p));
+
+ if (!ecma_is_value_undefined (native))
+ {
+ JERRY_ASSERT (ecma_is_value_object (native));
+
+ module_p = ecma_module_create_module (path_p);
+ module_p->state = ECMA_MODULE_STATE_NATIVE;
+ module_p->namespace_object_p = ecma_get_object_from_value (native);
+
+ return module_p;
+ }
+
+ return NULL;
+} /* ecma_module_find_native_module */
/**
- * Creates a module context.
- *
- * @return pointer to created module context
+ * Initialize context variables for the root module.
*/
-static ecma_module_context_t *
-ecma_module_create_module_context (void)
+void
+ecma_module_initialize_context (ecma_string_t *root_path_p) /**< root module */
{
- ecma_module_context_t *context_p = (ecma_module_context_t *) jmem_heap_alloc_block (sizeof (ecma_module_context_t));
- memset (context_p, 0, sizeof (ecma_module_context_t));
+ JERRY_ASSERT (JERRY_CONTEXT (module_current_p) == NULL);
+ JERRY_ASSERT (JERRY_CONTEXT (module_list_p) == NULL);
- return context_p;
-} /* ecma_module_create_module_context */
+ lit_utf8_size_t path_str_size;
+ uint8_t flags = ECMA_STRING_FLAG_EMPTY;
+
+ const lit_utf8_byte_t *path_str_chars_p = ecma_string_get_chars (root_path_p,
+ &path_str_size,
+ NULL,
+ NULL,
+ &flags);
+
+ ecma_string_t *path_p = ecma_module_create_normalized_path (path_str_chars_p,
+ path_str_size,
+ NULL);
+
+ if (path_p == NULL)
+ {
+ ecma_ref_ecma_string (root_path_p);
+ path_p = root_path_p;
+ }
+
+ ecma_module_t *module_p = (ecma_module_t *) jmem_heap_alloc_block (sizeof (ecma_module_t));
+ memset (module_p, 0, sizeof (ecma_module_t));
+
+ module_p->path_p = path_p;
+ /* Root modules are handled differently then the rest of the referenced modules, as the scope and compiled code
+ * are handled separately. */
+ module_p->state = ECMA_MODULE_STATE_ROOT;
+
+ JERRY_CONTEXT (module_current_p) = module_p;
+ JERRY_CONTEXT (module_list_p) = module_p;
+} /* ecma_module_initialize_context */
+
+/**
+ * cleanup context variables for the root module.
+ */
+void
+ecma_module_cleanup_context (void)
+{
+ ecma_module_cleanup (JERRY_CONTEXT (module_current_p));
+#ifndef JERRY_NDEBUG
+ JERRY_CONTEXT (module_current_p) = NULL;
+ JERRY_CONTEXT (module_list_p) = NULL;
+#endif /* JERRY_NDEBUG */
+} /* ecma_module_cleanup_context */
/**
* Inserts a {module, export_name} record into a resolve set.
@@ -190,8 +256,8 @@ ecma_module_create_module_context (void)
*/
bool
ecma_module_resolve_set_insert (ecma_module_resolve_set_t **set_p, /**< [in, out] resolve set */
- ecma_module_t * const module_p, /**< module */
- ecma_string_t * const export_name_p) /**< export name */
+ ecma_module_t *const module_p, /**< module */
+ ecma_string_t *const export_name_p) /**< export name */
{
JERRY_ASSERT (set_p != NULL);
ecma_module_resolve_set_t *current_p = *set_p;
@@ -283,8 +349,8 @@ ecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p) /**< [in,
* ECMA_VALUE_EMPTY - otherwise
*/
static ecma_value_t
-ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
- ecma_string_t * const export_name_p, /**< export name */
+ecma_module_resolve_export (ecma_module_t *const module_p, /**< base module */
+ ecma_string_t *const export_name_p, /**< export name */
ecma_module_record_t *out_record_p) /**< [out] found module record */
{
ecma_module_resolve_set_t *resolve_set_p = NULL;
@@ -302,7 +368,6 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
ecma_module_t *current_module_p = current_frame_p->module_p;
JERRY_ASSERT (current_module_p->state >= ECMA_MODULE_STATE_PARSED);
- ecma_module_context_t *context_p = current_module_p->context_p;
ecma_string_t *current_export_name_p = current_frame_p->export_name_p;
if (!current_frame_p->resolving)
@@ -341,11 +406,11 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
continue;
}
- if (context_p->local_exports_p != NULL)
+ if (current_module_p->local_exports_p != NULL)
{
/* 15.2.1.16.3 / 4 */
- JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
- ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
+ JERRY_ASSERT (current_module_p->local_exports_p->next_p == NULL);
+ ecma_module_names_t *export_names_p = current_module_p->local_exports_p->module_names_p;
while (export_names_p != NULL)
{
if (ecma_compare_ecma_strings (current_export_name_p, export_names_p->imex_name_p))
@@ -377,7 +442,7 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
}
/* 15.2.1.16.3 / 5 */
- ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
+ ecma_module_node_t *indirect_export_p = current_module_p->indirect_exports_p;
while (indirect_export_p != NULL)
{
ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
@@ -389,6 +454,7 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
ecma_module_resolve_stack_push (&stack_p,
indirect_export_p->module_request_p,
export_names_p->local_name_p);
+ break;
}
export_names_p = export_names_p->next_p;
@@ -432,7 +498,7 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
ecma_module_resolve_stack_pop (&stack_p);
/* 15.2.1.16.3 / 10 */
- ecma_module_node_t *star_export_p = context_p->star_exports_p;
+ ecma_module_node_t *star_export_p = current_module_p->star_exports_p;
while (star_export_p != NULL)
{
JERRY_ASSERT (star_export_p->module_names_p == NULL);
@@ -493,12 +559,9 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */
module_p->state = ECMA_MODULE_STATE_EVALUATING;
module_p->scope_p = ecma_create_decl_lex_env (ecma_get_global_environment (global_object_p));
- module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
- JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
ecma_value_t ret_value;
- ret_value = vm_run_module (module_p->compiled_code_p,
- module_p->scope_p);
+ ret_value = vm_run_module (module_p);
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
@@ -506,10 +569,11 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */
ret_value = ECMA_VALUE_EMPTY;
}
- JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
-
- ecma_bytecode_deref (module_p->compiled_code_p);
module_p->state = ECMA_MODULE_STATE_EVALUATED;
+ ecma_bytecode_deref (module_p->compiled_code_p);
+#ifndef JERRY_NDEBUG
+ module_p->compiled_code_p = NULL;
+#endif /* JERRY_NDEBUG */
return ret_value;
} /* ecma_module_evaluate */
@@ -597,7 +661,6 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
{
ecma_module_resolve_stack_t *current_frame_p = stack_p;
ecma_module_t *current_module_p = current_frame_p->module_p;
- ecma_module_context_t *context_p = current_module_p->context_p;
ecma_module_resolve_stack_pop (&stack_p);
@@ -617,11 +680,11 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
break;
}
- if (context_p->local_exports_p != NULL)
+ if (current_module_p->local_exports_p != NULL)
{
/* 15.2.1.16.2 / 5 */
- JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
- ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
+ JERRY_ASSERT (current_module_p->local_exports_p->next_p == NULL);
+ ecma_module_names_t *export_names_p = current_module_p->local_exports_p->module_names_p;
while (export_names_p != NULL && ecma_is_value_empty (result))
{
result = ecma_module_namespace_object_add_export_if_needed (module_p,
@@ -631,7 +694,7 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
}
/* 15.2.1.16.2 / 6 */
- ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
+ ecma_module_node_t *indirect_export_p = current_module_p->indirect_exports_p;
while (indirect_export_p != NULL && ecma_is_value_empty (result))
{
ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
@@ -645,7 +708,7 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
}
/* 15.2.1.16.2 / 7 */
- ecma_module_node_t *star_export_p = context_p->star_exports_p;
+ ecma_module_node_t *star_export_p = current_module_p->star_exports_p;
while (star_export_p != NULL && ecma_is_value_empty (result))
{
JERRY_ASSERT (star_export_p->module_names_p == NULL);
@@ -670,20 +733,18 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
} /* ecma_module_create_namespace_object */
/**
- * Connects imported values to the current context.
+ * Connects imported values to the current module scope.
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
static ecma_value_t
-ecma_module_connect_imports (void)
+ecma_module_connect_imports (ecma_module_t *module_p)
{
- ecma_module_context_t *current_context_p = JERRY_CONTEXT (module_top_context_p);
-
- ecma_object_t *local_env_p = current_context_p->module_p->scope_p;
+ ecma_object_t *local_env_p = module_p->scope_p;
JERRY_ASSERT (ecma_is_lexical_environment (local_env_p));
- ecma_module_node_t *import_node_p = current_context_p->imports_p;
+ ecma_module_node_t *import_node_p = module_p->imports_p;
/* Check that the imported bindings don't exist yet. */
while (import_node_p != NULL)
@@ -728,7 +789,7 @@ ecma_module_connect_imports (void)
import_node_p = import_node_p->next_p;
}
- import_node_p = current_context_p->imports_p;
+ import_node_p = module_p->imports_p;
/* Resolve imports and create local bindings. */
while (import_node_p != NULL)
@@ -823,6 +884,48 @@ ecma_module_connect_imports (void)
return ECMA_VALUE_EMPTY;
} /* ecma_module_connect_imports */
+/**
+ * Checks if indirect exports in the current context are resolvable.
+ * Note: See 15.2.1.16.4 / 9.
+ *
+ * @return ECMA_VALUE_ERROR - if an error occured
+ * ECMA_VALUE_EMPTY - otherwise
+ */
+static ecma_value_t
+ecma_module_check_indirect_exports (ecma_module_t *module_p)
+{
+ ecma_module_node_t *indirect_export_p = module_p->indirect_exports_p;
+ while (indirect_export_p != NULL)
+ {
+ ecma_module_names_t *name_p = indirect_export_p->module_names_p;
+ while (name_p != NULL)
+ {
+ ecma_module_record_t record;
+ ecma_value_t result = ecma_module_resolve_export (indirect_export_p->module_request_p,
+ name_p->local_name_p,
+ &record);
+
+ if (ECMA_IS_VALUE_ERROR (result))
+ {
+ return result;
+ }
+
+ JERRY_ASSERT (ecma_is_value_empty (result));
+
+ if (record.module_p == NULL)
+ {
+ return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous indirect export request."));
+ }
+
+ name_p = name_p->next_p;
+ }
+
+ indirect_export_p = indirect_export_p->next_p;
+ }
+
+ return ECMA_VALUE_EMPTY;
+} /* ecma_module_check_indirect_exports */
+
/**
* Initialize the current module by creating the local binding for the imported variables
* and verifying indirect exports.
@@ -831,17 +934,42 @@ ecma_module_connect_imports (void)
* ECMA_VALUE_EMPTY - otherwise
*/
ecma_value_t
-ecma_module_initialize_current (void)
+ecma_module_initialize (ecma_module_t *module_p) /**< module */
{
- ecma_value_t ret_value = ecma_module_connect_imports ();
+ ecma_value_t ret_value = ecma_module_connect_imports (module_p);
if (ecma_is_value_empty (ret_value))
{
- ret_value = ecma_module_check_indirect_exports ();
+ ret_value = ecma_module_check_indirect_exports (module_p);
}
return ret_value;
-} /* ecma_module_initialize_current */
+} /* ecma_module_initialize */
+
+static ecma_value_t ecma_module_parse (ecma_module_t *module_p);
+
+/**
+ * Parses all referenced modules.
+ *
+ * @return ECMA_VALUE_ERROR - if an error occured
+ * ECMA_VALUE_EMPTY - otherwise
+ */
+ecma_value_t
+ecma_module_parse_referenced_modules (void)
+{
+ ecma_module_t *current_p = JERRY_CONTEXT (module_list_p);
+ while (current_p != NULL)
+ {
+ if (ECMA_IS_VALUE_ERROR (ecma_module_parse (current_p)))
+ {
+ return ECMA_VALUE_ERROR;
+ }
+
+ current_p = current_p->next_p;
+ }
+
+ return ECMA_VALUE_EMPTY;
+} /* ecma_module_parse_referenced_modules */
/**
* Parses an EcmaScript module.
@@ -849,7 +977,7 @@ ecma_module_initialize_current (void)
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
-static jerry_value_t
+static ecma_value_t
ecma_module_parse (ecma_module_t *module_p) /**< module */
{
if (module_p->state >= ECMA_MODULE_STATE_PARSING)
@@ -858,7 +986,6 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
}
module_p->state = ECMA_MODULE_STATE_PARSING;
- module_p->context_p = ecma_module_create_module_context ();
lit_utf8_size_t module_path_size = ecma_string_get_size (module_p->path_p);
lit_utf8_byte_t *module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
@@ -878,9 +1005,8 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
return ecma_raise_syntax_error (ECMA_ERR_MSG ("File not found."));
}
- module_p->context_p->module_p = module_p;
- module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
- JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
+ ecma_module_t *prev_module_p = JERRY_CONTEXT (module_current_p);
+ JERRY_CONTEXT (module_current_p) = module_p;
#if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
@@ -899,8 +1025,7 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
ecma_make_string_value (module_p->path_p),
ECMA_PARSE_STRICT_MODE | ECMA_PARSE_MODULE);
- JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
-
+ JERRY_CONTEXT (module_current_p) = prev_module_p;
jerry_port_release_source (source_p);
if (JERRY_UNLIKELY (bytecode_p == NULL))
@@ -908,78 +1033,18 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
return ECMA_VALUE_ERROR;
}
+ if (ECMA_IS_VALUE_ERROR (ecma_module_parse_referenced_modules ()))
+ {
+ ecma_bytecode_deref (bytecode_p);
+ return ECMA_VALUE_ERROR;
+ }
+
module_p->compiled_code_p = bytecode_p;
module_p->state = ECMA_MODULE_STATE_PARSED;
return ECMA_VALUE_EMPTY;
} /* ecma_module_parse */
-/**
- * Parses all referenced modules.
- *
- * @return ECMA_VALUE_ERROR - if an error occured
- * ECMA_VALUE_EMPTY - otherwise
- */
-ecma_value_t
-ecma_module_parse_modules (void)
-{
- ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
-
- while (current_p != NULL)
- {
- ecma_value_t ret_value = ecma_module_parse (current_p);
- if (ECMA_IS_VALUE_ERROR (ret_value))
- {
- return ret_value;
- }
-
- JERRY_ASSERT (ecma_is_value_empty (ret_value));
- current_p = current_p->next_p;
- }
-
- return ECMA_VALUE_EMPTY;
-} /* ecma_module_parse_modules */
-
-/**
- * Checks if indirect exports in the current context are resolvable.
- * Note: See 15.2.1.16.4 / 9.
- *
- * @return ECMA_VALUE_ERROR - if an error occured
- * ECMA_VALUE_EMPTY - otherwise
- */
-ecma_value_t
-ecma_module_check_indirect_exports (void)
-{
- ecma_module_node_t *indirect_export_p = JERRY_CONTEXT (module_top_context_p)->indirect_exports_p;
- while (indirect_export_p != NULL)
- {
- ecma_module_names_t *name_p = indirect_export_p->module_names_p;
- while (name_p != NULL)
- {
- ecma_module_record_t record;
- ecma_value_t result = ecma_module_resolve_export (indirect_export_p->module_request_p,
- name_p->local_name_p,
- &record);
-
- if (ECMA_IS_VALUE_ERROR (result))
- {
- return result;
- }
-
- if (record.module_p == NULL)
- {
- return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous indirect export request."));
- }
-
- name_p = name_p->next_p;
- }
-
- indirect_export_p = indirect_export_p->next_p;
- }
-
- return ECMA_VALUE_EMPTY;
-} /* ecma_module_check_indirect_exports */
-
/**
* Cleans up a list of module names.
*/
@@ -1016,52 +1081,60 @@ ecma_module_release_module_nodes (ecma_module_node_t *module_node_p) /**< first
} /* ecma_module_release_module_nodes */
/**
- * Cleans up a module context.
- */
-static void
-ecma_module_release_module_context (ecma_module_context_t *module_context_p) /**< modle context */
-{
- ecma_module_release_module_nodes (module_context_p->imports_p);
- ecma_module_release_module_nodes (module_context_p->local_exports_p);
- ecma_module_release_module_nodes (module_context_p->indirect_exports_p);
- ecma_module_release_module_nodes (module_context_p->star_exports_p);
-
- jmem_heap_free_block (module_context_p, sizeof (ecma_module_context_t));
-} /* ecma_module_release_module_context */
-
-/**
- * Cleans up a module structure.
+ * Cleans up and releases a module structure including all referenced modules.
*/
static void
ecma_module_release_module (ecma_module_t *module_p) /**< module */
{
+ ecma_module_state_t state = module_p->state;
+
ecma_deref_ecma_string (module_p->path_p);
+#ifndef JERRY_NDEBUG
+ module_p->path_p = NULL;
+#endif /* JERRY_NDEBUG */
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;
+#endif /* JERRY_NDEBUG */
}
- if (module_p->state == ECMA_MODULE_STATE_NATIVE)
+ if (state == ECMA_MODULE_STATE_NATIVE)
{
goto finished;
}
- if (module_p->state >= ECMA_MODULE_STATE_PARSING)
+ if (state >= ECMA_MODULE_STATE_PARSING)
{
- ecma_module_release_module_context (module_p->context_p);
+ ecma_module_release_module_nodes (module_p->imports_p);
+ ecma_module_release_module_nodes (module_p->local_exports_p);
+ ecma_module_release_module_nodes (module_p->indirect_exports_p);
+ ecma_module_release_module_nodes (module_p->star_exports_p);
}
- if (module_p->state >= ECMA_MODULE_STATE_EVALUATING
- && module_p->scope_p != NULL)
+ if (state == ECMA_MODULE_STATE_ROOT)
{
+ goto finished;
+ }
+
+ if (state >= ECMA_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->state >= ECMA_MODULE_STATE_PARSED
- && module_p->state < ECMA_MODULE_STATE_EVALUATED)
+ if (state >= ECMA_MODULE_STATE_PARSED
+ && state < ECMA_MODULE_STATE_EVALUATED)
{
ecma_bytecode_deref (module_p->compiled_code_p);
+#ifndef JERRY_NDEBUG
+ module_p->compiled_code_p = NULL;
+#endif /* JERRY_NDEBUG */
}
finished:
@@ -1069,21 +1142,16 @@ finished:
} /* ecma_module_release_module */
/**
- * Cleans up all modules if the current context is the root context.
+ * Cleans up and releases a module list.
*/
void
-ecma_module_cleanup (void)
+ecma_module_cleanup (ecma_module_t *head_p) /**< module */
{
- ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
- while (current_p != NULL)
+ while (head_p != NULL)
{
- ecma_module_t *next_p = current_p->next_p;
- ecma_module_release_module (current_p);
- current_p = next_p;
+ ecma_module_t *next_p = head_p->next_p;
+ ecma_module_release_module (head_p);
+ head_p = next_p;
}
-
- JERRY_CONTEXT (ecma_modules_p) = NULL;
- JERRY_CONTEXT (module_top_context_p) = NULL;
} /* ecma_module_cleanup */
-
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
diff --git a/jerry-core/ecma/base/ecma-module.h b/jerry-core/ecma/base/ecma-module.h
index 3a564bf22..49df29a95 100644
--- a/jerry-core/ecma/base/ecma-module.h
+++ b/jerry-core/ecma/base/ecma-module.h
@@ -16,11 +16,11 @@
#ifndef ECMA_MODULE_H
#define ECMA_MODULE_H
-#if ENABLED (JERRY_MODULE_SYSTEM)
-
#include "common.h"
#include "ecma-globals.h"
+#if ENABLED (JERRY_MODULE_SYSTEM)
+
#define ECMA_MODULE_MAX_PATH 255u
/**
@@ -35,31 +35,6 @@ typedef struct ecma_module_names
ecma_string_t *local_name_p; /**< Local name of the item */
} ecma_module_names_t;
-typedef struct ecma_module ecma_module_t;
-
-/**
- * Module node to store imports / exports.
- */
-typedef struct ecma_module_node
-{
- struct ecma_module_node *next_p; /**< next linked list node */
- ecma_module_names_t *module_names_p; /**< names of the requested import/export node */
- ecma_module_t *module_request_p; /**< module structure of the requested module */
-} ecma_module_node_t;
-
-/**
- * Module context containing all import and export nodes.
- */
-typedef struct ecma_module_context
-{
- struct ecma_module_context *parent_p; /**< parent context */
- ecma_module_node_t *imports_p; /**< import item of the current context */
- ecma_module_node_t *local_exports_p; /**< export item of the current context */
- ecma_module_node_t *indirect_exports_p; /**< export item of the current context */
- ecma_module_node_t *star_exports_p; /**< export item of the current context */
- ecma_module_t *module_p; /**< module request */
-} ecma_module_context_t;
-
/**
* An enum identifing the current state of the module
*/
@@ -71,21 +46,36 @@ typedef enum
ECMA_MODULE_STATE_EVALUATING = 3, /**< module is currently being evaluated */
ECMA_MODULE_STATE_EVALUATED = 4, /**< module has been evaluated */
ECMA_MODULE_STATE_NATIVE = 5, /**< module is native */
+ ECMA_MODULE_STATE_ROOT = 6, /**< module is a root module */
} ecma_module_state_t;
/**
* Module structure storing an instance of a module
*/
-struct ecma_module
+typedef struct ecma_module
{
- struct ecma_module *next_p; /**< next linked list node */
- ecma_module_state_t state; /**< state of the mode */
- ecma_string_t *path_p; /**< path of the module */
- ecma_module_context_t *context_p; /**< module context of the module */
- ecma_compiled_code_t *compiled_code_p; /**< compiled code of the module */
- ecma_object_t *scope_p; /**< lexica lenvironment of the module */
- ecma_object_t *namespace_object_p; /**< namespace import object of the module */
-};
+ /* TODO(dbatyai): These could be compressed pointers */
+ struct ecma_module *next_p; /**< next module in the list */
+ struct ecma_module_node *imports_p; /**< import requests of the module */
+ struct ecma_module_node *local_exports_p; /**< local exports of the module */
+ struct ecma_module_node *indirect_exports_p; /**< indirect exports of the module */
+ struct ecma_module_node *star_exports_p; /**< star exports of the module*/
+ ecma_string_t *path_p; /**< path of the module */
+ ecma_compiled_code_t *compiled_code_p; /**< compiled code for the module */
+ ecma_object_t *scope_p; /**< lexical lenvironment of the module */
+ ecma_object_t *namespace_object_p; /**< namespace object of the module */
+ ecma_module_state_t state; /**< evaluation state of the module */
+} ecma_module_t;
+
+/**
+ * Module node to store imports / exports.
+ */
+typedef struct ecma_module_node
+{
+ struct ecma_module_node *next_p; /**< next linked list node */
+ ecma_module_names_t *module_names_p; /**< names of the requested import/export node */
+ ecma_module_t *module_request_p; /**< module structure of the requested module */
+} ecma_module_node_t;
/**
* A record that can be used to store {module, identifier} pairs
@@ -126,19 +116,21 @@ void ecma_module_resolve_stack_push (ecma_module_resolve_stack_t **stack_p,
ecma_string_t *const export_name_p);
void ecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p);
-ecma_string_t *ecma_module_create_normalized_path (const uint8_t *char_p,
- prop_length_t size);
-ecma_module_t *ecma_module_find_module (ecma_string_t *const path_p);
-ecma_module_t *ecma_module_create_native_module (ecma_string_t *const path_p,
- ecma_object_t *const namespace_p);
-ecma_module_t *ecma_module_find_or_create_module (ecma_string_t *const path_p);
+ecma_string_t *ecma_module_create_normalized_path (const lit_utf8_byte_t *char_p,
+ lit_utf8_size_t size,
+ ecma_string_t *const base_path_p);
-ecma_value_t ecma_module_initialize_current (void);
-ecma_value_t ecma_module_parse_modules (void);
-ecma_value_t ecma_module_check_indirect_exports (void);
+ecma_module_t *ecma_module_find_module (ecma_string_t *const path_p);
+ecma_module_t *ecma_module_find_native_module (ecma_string_t *const path_p);
+
+ecma_value_t ecma_module_parse_referenced_modules (void);
+ecma_value_t ecma_module_initialize (ecma_module_t *module_p);
+
+void ecma_module_initialize_context (ecma_string_t *root_path_p);
+void ecma_module_cleanup_context (void);
void ecma_module_release_module_nodes (ecma_module_node_t *module_node_p);
-void ecma_module_cleanup (void);
+void ecma_module_cleanup (ecma_module_t *head_p);
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
#endif /* !ECMA_MODULE_H */
diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h
index 5a5097def..b575afa57 100644
--- a/jerry-core/include/jerryscript-core.h
+++ b/jerry-core/include/jerryscript-core.h
@@ -115,7 +115,8 @@ typedef enum
typedef enum
{
JERRY_PARSE_NO_OPTS = 0, /**< no options passed */
- JERRY_PARSE_STRICT_MODE = (1 << 0) /**< enable strict mode */
+ JERRY_PARSE_STRICT_MODE = (1 << 0), /**< enable strict mode */
+ JERRY_PARSE_MODULE = (1 << 1) /**< parse source as an ECMAScript module */
} jerry_parse_opts_t;
/**
diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h
index 983ea1e11..940431a11 100644
--- a/jerry-core/jcontext/jcontext.h
+++ b/jerry-core/jcontext/jcontext.h
@@ -150,8 +150,8 @@ struct jerry_context_t
#endif /* ENABLED (JERRY_ESNEXT) */
#if ENABLED (JERRY_MODULE_SYSTEM)
- ecma_module_t *ecma_modules_p; /**< list of referenced modules */
- ecma_module_context_t *module_top_context_p; /**< top (current) module parser context */
+ ecma_module_t *module_list_p; /**< current module context */
+ ecma_module_t *module_current_p; /**< current module context */
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
vm_frame_ctx_t *vm_top_context_p; /**< top (current) interpreter context */
diff --git a/jerry-core/lit/lit-char-helpers.c b/jerry-core/lit/lit-char-helpers.c
index 0c0a0995d..f235de281 100644
--- a/jerry-core/lit/lit-char-helpers.c
+++ b/jerry-core/lit/lit-char-helpers.c
@@ -16,14 +16,16 @@
#include "config.h"
#include "ecma-helpers.h"
#include "lit-char-helpers.h"
-#include "lit-unicode-ranges.inc.h"
-#include "lit-unicode-ranges-sup.inc.h"
#include "lit-strings.h"
+#include "lit-unicode-ranges.inc.h"
+#if ENABLED (JERRY_ESNEXT)
+#include "lit-unicode-ranges-sup.inc.h"
+#endif /* ENABLED (JERRY_ESNEXT) */
#if ENABLED (JERRY_UNICODE_CASE_CONVERSION)
#include "lit-unicode-conversions.inc.h"
-#include "lit-unicode-conversions-sup.inc.h"
#if ENABLED (JERRY_ESNEXT)
+#include "lit-unicode-conversions-sup.inc.h"
#include "lit-unicode-folding.inc.h"
#endif /* ENABLED (JERRY_ESNEXT) */
#endif /* ENABLED (JERRY_UNICODE_CASE_CONVERSION) */
diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h
index 4c9ac2703..d0f0b23c4 100644
--- a/jerry-core/lit/lit-magic-strings.inc.h
+++ b/jerry-core/lit/lit-magic-strings.inc.h
@@ -549,6 +549,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DATAVIEW_UL, "DataView")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_UL, "Function")
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_INFINITY_UL, "Infinity")
+#if ENABLED (JERRY_MODULE_SYSTEM)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RUNNABLE_UL, "Runnable")
+#endif
#if ENABLED (JERRY_BUILTIN_ERRORS)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_URI_ERROR_UL, "URIError")
#endif
diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini
index 66d80b432..848433b1d 100644
--- a/jerry-core/lit/lit-magic-strings.ini
+++ b/jerry-core/lit/lit-magic-strings.ini
@@ -214,6 +214,7 @@ LIT_MAGIC_STRING_VALUE_OF_UL = "valueOf"
LIT_MAGIC_STRING_WEAKMAP_UL = "WeakMap"
LIT_MAGIC_STRING_WEAKSET_UL = "WeakSet"
LIT_MAGIC_STRING_EPSILON_U = "EPSILON"
+LIT_MAGIC_STRING_RUNNABLE_UL = "Runnable"
LIT_MAGIC_STRING_DATAVIEW_UL = "DataView"
LIT_MAGIC_STRING_FUNCTION_UL = "Function"
LIT_MAGIC_STRING_INFINITY_UL = "Infinity"
diff --git a/jerry-core/parser/js/js-lexer.h b/jerry-core/parser/js/js-lexer.h
index da7b1420c..927723102 100644
--- a/jerry-core/parser/js/js-lexer.h
+++ b/jerry-core/parser/js/js-lexer.h
@@ -16,6 +16,8 @@
#ifndef JS_LEXER_H
#define JS_LEXER_H
+#include "ecma-globals.h"
+
/** \addtogroup parser Parser
* @{
*
diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h
index 9e487ab4e..561806c50 100644
--- a/jerry-core/parser/js/js-parser-internal.h
+++ b/jerry-core/parser/js/js-parser-internal.h
@@ -860,8 +860,8 @@ void parser_free_jumps (parser_stack_iterator_t iterator);
*/
extern const lexer_lit_location_t lexer_default_literal;
-void parser_module_add_export_node_to_context (parser_context_t *context_p);
-void parser_module_add_import_node_to_context (parser_context_t *context_p);
+void parser_module_finalize_export_node (parser_context_t *context_p);
+void parser_module_finalize_import_node (parser_context_t *context_p);
void parser_module_check_request_place (parser_context_t *context_p);
void parser_module_context_init (parser_context_t *context_p);
void parser_module_handle_module_specifier (parser_context_t *context_p);
diff --git a/jerry-core/parser/js/js-parser-module.c b/jerry-core/parser/js/js-parser-module.c
index 26cba3fa8..d8fb7b9af 100644
--- a/jerry-core/parser/js/js-parser-module.c
+++ b/jerry-core/parser/js/js-parser-module.c
@@ -55,7 +55,7 @@ parser_module_check_duplicate_import (parser_context_t *context_p, /**< parser c
module_names_p = module_names_p->next_p;
}
- ecma_module_node_t *module_node_p = JERRY_CONTEXT (module_top_context_p)->imports_p;
+ ecma_module_node_t *module_node_p = JERRY_CONTEXT (module_current_p)->imports_p;
while (module_node_p != NULL)
{
module_names_p = module_node_p->module_names_p;
@@ -124,7 +124,7 @@ parser_module_check_duplicate_export (parser_context_t *context_p, /**< parser c
current_names_p = current_names_p->next_p;
}
- ecma_module_node_t *export_node_p = JERRY_CONTEXT (module_top_context_p)->local_exports_p;
+ ecma_module_node_t *export_node_p = JERRY_CONTEXT (module_current_p)->local_exports_p;
if (export_node_p != NULL)
{
JERRY_ASSERT (export_node_p->next_p == NULL);
@@ -141,7 +141,7 @@ parser_module_check_duplicate_export (parser_context_t *context_p, /**< parser c
}
}
- export_node_p = JERRY_CONTEXT (module_top_context_p)->indirect_exports_p;
+ export_node_p = JERRY_CONTEXT (module_current_p)->indirect_exports_p;
while (export_node_p != NULL)
{
ecma_module_names_t *name_p = export_node_p->module_names_p;
@@ -167,7 +167,7 @@ parser_module_check_duplicate_export (parser_context_t *context_p, /**< parser c
* Add export node to parser context.
*/
void
-parser_module_add_export_node_to_context (parser_context_t *context_p) /**< parser context */
+parser_module_finalize_export_node (parser_context_t *context_p) /**< parser context */
{
ecma_module_node_t *module_node_p = context_p->module_current_node_p;
context_p->module_current_node_p = NULL;
@@ -180,17 +180,17 @@ parser_module_add_export_node_to_context (parser_context_t *context_p) /**< pars
if (!module_node_p->module_names_p)
{
/* If there are no names in the node, then it's a star export. */
- export_list_p = &(JERRY_CONTEXT (module_top_context_p)->star_exports_p);
+ export_list_p = &(JERRY_CONTEXT (module_current_p)->star_exports_p);
}
else
{
- export_list_p = &(JERRY_CONTEXT (module_top_context_p)->indirect_exports_p);
+ export_list_p = &(JERRY_CONTEXT (module_current_p)->indirect_exports_p);
}
}
else
{
/* If there is no module request, then it's a local export. */
- export_list_p = &(JERRY_CONTEXT (module_top_context_p)->local_exports_p);
+ export_list_p = &(JERRY_CONTEXT (module_current_p)->local_exports_p);
}
/* Check if we have a node with the same module request, append to it if we do. */
@@ -213,7 +213,7 @@ parser_module_add_export_node_to_context (parser_context_t *context_p) /**< pars
module_node_p->module_names_p = NULL;
}
- ecma_module_release_module_nodes (module_node_p);
+ jmem_heap_free_block (module_node_p, sizeof (ecma_module_node_t));
return;
}
@@ -222,22 +222,22 @@ parser_module_add_export_node_to_context (parser_context_t *context_p) /**< pars
module_node_p->next_p = *export_list_p;
*export_list_p = module_node_p;
-} /* parser_module_add_export_node_to_context */
+} /* parser_module_finalize_export_node */
/**
* Add import node to parser context.
*/
void
-parser_module_add_import_node_to_context (parser_context_t *context_p) /**< parser context */
+parser_module_finalize_import_node (parser_context_t *context_p) /**< parser context */
{
ecma_module_node_t *module_node_p = context_p->module_current_node_p;
context_p->module_current_node_p = NULL;
- ecma_module_node_t *stored_imports = JERRY_CONTEXT (module_top_context_p)->imports_p;
+ ecma_module_node_t *stored_imports_p = JERRY_CONTEXT (module_current_p)->imports_p;
/* Check if we have a node with the same module request, append to it if we do. */
- while (stored_imports != NULL)
+ while (stored_imports_p != NULL)
{
- if (stored_imports->module_request_p == module_node_p->module_request_p)
+ if (stored_imports_p->module_request_p == module_node_p->module_request_p)
{
ecma_module_names_t *module_names_p = module_node_p->module_names_p;
@@ -248,21 +248,21 @@ parser_module_add_import_node_to_context (parser_context_t *context_p) /**< pars
module_names_p = module_names_p->next_p;
}
- module_names_p->next_p = stored_imports->module_names_p;
- stored_imports->module_names_p = module_node_p->module_names_p;
+ module_names_p->next_p = stored_imports_p->module_names_p;
+ stored_imports_p->module_names_p = module_node_p->module_names_p;
module_node_p->module_names_p = NULL;
}
- ecma_module_release_module_nodes (module_node_p);
+ jmem_heap_free_block (module_node_p, sizeof (ecma_module_node_t));
return;
}
- stored_imports = stored_imports->next_p;
+ stored_imports_p = stored_imports_p->next_p;
}
- module_node_p->next_p = JERRY_CONTEXT (module_top_context_p)->imports_p;
- JERRY_CONTEXT (module_top_context_p)->imports_p = module_node_p;
-} /* parser_module_add_import_node_to_context */
+ module_node_p->next_p = JERRY_CONTEXT (module_current_p)->imports_p;
+ JERRY_CONTEXT (module_current_p)->imports_p = module_node_p;
+} /* parser_module_finalize_import_node */
/**
* Add module names to current module node.
@@ -289,50 +289,6 @@ parser_module_add_names_to_node (parser_context_t *context_p, /**< parser contex
new_names_p->local_name_p = local_name_p;
} /* parser_module_add_names_to_node */
-/**
- * Create module context if needed.
- */
-void
-parser_module_context_init (parser_context_t *context_p)
-{
- if (JERRY_CONTEXT (module_top_context_p) == NULL)
- {
- ecma_module_context_t *module_context_p;
- module_context_p = (ecma_module_context_t *) jmem_heap_alloc_block (sizeof (ecma_module_context_t));
- memset (module_context_p, 0, sizeof (ecma_module_context_t));
- JERRY_CONTEXT (module_top_context_p) = module_context_p;
-
- ecma_string_t *path_str_p = ecma_get_string_from_value (context_p->resource_name);
-
- lit_utf8_size_t path_str_size;
- uint8_t flags = ECMA_STRING_FLAG_EMPTY;
-
- const lit_utf8_byte_t *path_str_chars_p = ecma_string_get_chars (path_str_p,
- &path_str_size,
- NULL,
- NULL,
- &flags);
-
- ecma_string_t *path_p = ecma_module_create_normalized_path (path_str_chars_p,
- (prop_length_t) path_str_size);
-
- if (path_p == NULL)
- {
- ecma_ref_ecma_string (path_str_p);
- path_p = path_str_p;
- }
-
- ecma_module_t *module_p = ecma_module_find_or_create_module (path_p);
-
- module_p->state = ECMA_MODULE_STATE_EVALUATED;
- /* The lexical scope of the root module does not exist yet. */
- module_p->scope_p = NULL;
-
- module_p->context_p = module_context_p;
- module_context_p->module_p = module_p;
- }
-} /* parser_module_context_init */
-
/**
* Create a permanent import/export node from a template node.
* @return - the copy of the template if the second parameter is not NULL.
@@ -567,7 +523,8 @@ parser_module_check_request_place (parser_context_t *context_p) /**< parser cont
if (context_p->last_context_p != NULL
|| context_p->stack_top_uint8 != 0
|| (context_p->status_flags & PARSER_IS_FUNCTION)
- || (context_p->global_status_flags & ECMA_PARSE_EVAL))
+ || (context_p->global_status_flags & ECMA_PARSE_EVAL)
+ || (context_p->global_status_flags & ECMA_PARSE_MODULE) == 0)
{
parser_raise_error (context_p, PARSER_ERR_MODULE_UNEXPECTED);
}
@@ -592,34 +549,25 @@ parser_module_handle_module_specifier (parser_context_t *context_p) /**< parser
ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p,
context_p->lit_object.literal_p->prop.length);
- ecma_module_t *module_p = ecma_module_find_module (name_p);
+ ecma_module_t *module_p = ecma_module_find_native_module (name_p);
+
if (module_p)
{
ecma_deref_ecma_string (name_p);
goto module_found;
}
- ecma_value_t native = jerry_port_get_native_module (ecma_make_string_value (name_p));
-
- if (!ecma_is_value_undefined (native))
- {
- JERRY_ASSERT (ecma_is_value_object (native));
- ecma_object_t *module_object_p = ecma_get_object_from_value (native);
-
- module_p = ecma_module_create_native_module (name_p, module_object_p);
- goto module_found;
- }
-
ecma_deref_ecma_string (name_p);
ecma_string_t *path_p = ecma_module_create_normalized_path (context_p->lit_object.literal_p->u.char_p,
- context_p->lit_object.literal_p->prop.length);
+ context_p->lit_object.literal_p->prop.length,
+ JERRY_CONTEXT (module_current_p)->path_p);
if (path_p == NULL)
{
parser_raise_error (context_p, PARSER_ERR_FILE_NOT_FOUND);
}
- module_p = ecma_module_find_or_create_module (path_p);
+ module_p = ecma_module_find_module (path_p);
module_found:
module_node_p->module_request_p = module_p;
diff --git a/jerry-core/parser/js/js-parser-statm.c b/jerry-core/parser/js/js-parser-statm.c
index c5ba6124f..c29bc234b 100644
--- a/jerry-core/parser/js/js-parser-statm.c
+++ b/jerry-core/parser/js/js-parser-statm.c
@@ -2427,7 +2427,6 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_IMPORT);
parser_module_check_request_place (context_p);
- parser_module_context_init (context_p);
context_p->module_current_node_p = parser_module_create_module_node (context_p);
@@ -2529,7 +2528,7 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
}
parser_module_handle_module_specifier (context_p);
- parser_module_add_import_node_to_context (context_p);
+ parser_module_finalize_import_node (context_p);
context_p->module_current_node_p = NULL;
} /* parser_parse_import_statement */
@@ -2543,7 +2542,6 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_EXPORT);
parser_module_check_request_place (context_p);
- parser_module_context_init (context_p);
context_p->module_current_node_p = parser_module_create_module_node (context_p);
@@ -2656,7 +2654,7 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
}
context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_DEFAULT_CLASS_OR_FUNC | PARSER_MODULE_STORE_IDENT);
- parser_module_add_export_node_to_context (context_p);
+ parser_module_finalize_export_node (context_p);
context_p->module_current_node_p = NULL;
} /* parser_parse_export_statement */
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
diff --git a/jerry-core/parser/js/js-parser-util.c b/jerry-core/parser/js/js-parser-util.c
index de3639fb9..35d6f6b55 100644
--- a/jerry-core/parser/js/js-parser-util.c
+++ b/jerry-core/parser/js/js-parser-util.c
@@ -1396,7 +1396,7 @@ parser_error_to_string (parser_error_t error) /**< error code */
}
case PARSER_ERR_MODULE_UNEXPECTED:
{
- return "Import and export statements must be in the global context.";
+ return "Unexpected import or export statement.";
}
case PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED:
{
diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c
index c7e62ad97..0031dfe0c 100644
--- a/jerry-core/parser/js/js-parser.c
+++ b/jerry-core/parser/js/js-parser.c
@@ -1811,6 +1811,15 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
context.status_flags = parse_opts & PARSER_STRICT_MODE_MASK;
context.global_status_flags = parse_opts;
+#if ENABLED (JERRY_MODULE_SYSTEM)
+ if (context.global_status_flags & ECMA_PARSE_MODULE)
+ {
+ context.status_flags |= PARSER_IS_STRICT;
+ }
+
+ context.module_current_node_p = NULL;
+#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
+
if (arg_list_p != NULL)
{
context.status_flags |= PARSER_IS_FUNCTION;
@@ -1934,15 +1943,6 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
context.breakpoint_info_count = 0;
#endif /* ENABLED (JERRY_DEBUGGER) */
-#if ENABLED (JERRY_MODULE_SYSTEM)
- if (context.global_status_flags & ECMA_PARSE_MODULE)
- {
- context.status_flags |= PARSER_IS_STRICT;
- }
-
- context.module_current_node_p = NULL;
-#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
-
JERRY_ASSERT (context.next_scanner_info_p->source_p == context.source_p);
JERRY_ASSERT (context.next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
@@ -2859,12 +2859,6 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
resource_name,
line_str_val,
col_str_val);
-#if ENABLED (JERRY_MODULE_SYSTEM)
- if (JERRY_CONTEXT (module_top_context_p) != NULL)
- {
- ecma_module_cleanup ();
- }
-#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
ecma_free_value (col_str_val);
ecma_free_value (line_str_val);
@@ -2881,16 +2875,6 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
return NULL;
}
-#if ENABLED (JERRY_MODULE_SYSTEM)
- if (JERRY_CONTEXT (module_top_context_p) != NULL && ECMA_IS_VALUE_ERROR (ecma_module_parse_modules ()))
- {
- ecma_bytecode_deref (bytecode_p);
- ecma_module_cleanup ();
-
- return NULL;
- }
-#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
-
#if ENABLED (JERRY_DEBUGGER)
if ((JERRY_CONTEXT (debugger_flags) & (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT))
== (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT))
diff --git a/jerry-core/parser/js/js-scanner.c b/jerry-core/parser/js/js-scanner.c
index 6052fc02d..2d253f506 100644
--- a/jerry-core/parser/js/js-scanner.c
+++ b/jerry-core/parser/js/js-scanner.c
@@ -1649,8 +1649,6 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
scanner_raise_error (context_p);
}
- context_p->global_status_flags |= ECMA_PARSE_MODULE;
-
scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
lexer_next_token (context_p);
@@ -1801,8 +1799,6 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
scanner_raise_error (context_p);
}
- context_p->global_status_flags |= ECMA_PARSE_MODULE;
-
lexer_next_token (context_p);
if (context_p->token.type == LEXER_KEYW_DEFAULT)
diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c
index c27a9e569..d891f3662 100644
--- a/jerry-core/vm/vm.c
+++ b/jerry-core/vm/vm.c
@@ -272,10 +272,9 @@ static const uint16_t vm_decode_table[] JERRY_ATTR_CONST_DATA =
* @return ecma value
*/
ecma_value_t
-vm_run_module (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode to run */
- ecma_object_t *lex_env_p) /**< pointer to the specified lexenv to run in */
+vm_run_module (ecma_module_t *module_p) /**< module to be executed */
{
- const ecma_value_t module_init_result = ecma_module_initialize_current ();
+ const ecma_value_t module_init_result = ecma_module_initialize (module_p);
if (ECMA_IS_VALUE_ERROR (module_init_result))
{
@@ -283,10 +282,10 @@ vm_run_module (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode
}
vm_frame_ctx_shared_t shared;
- shared.bytecode_header_p = bytecode_p;
+ shared.bytecode_header_p = module_p->compiled_code_p;
shared.status_flags = 0;
- return vm_run (&shared, ECMA_VALUE_UNDEFINED, lex_env_p);
+ return vm_run (&shared, ECMA_VALUE_UNDEFINED, module_p->scope_p);
} /* vm_run_module */
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
@@ -316,27 +315,6 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode
ecma_object_t *const global_scope_p = ecma_get_global_scope (global_obj_p);
-#if ENABLED (JERRY_MODULE_SYSTEM)
- if (JERRY_CONTEXT (module_top_context_p) != NULL)
- {
- JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p)->parent_p == NULL);
- ecma_module_t *module_p = JERRY_CONTEXT (module_top_context_p)->module_p;
-
- JERRY_ASSERT (module_p->scope_p == NULL);
- ecma_ref_object (global_scope_p);
- module_p->scope_p = global_scope_p;
-
- const ecma_value_t module_init_result = ecma_module_initialize_current ();
- JERRY_CONTEXT (module_top_context_p) = NULL;
-
- if (ECMA_IS_VALUE_ERROR (module_init_result))
- {
- ecma_module_cleanup ();
- return module_init_result;
- }
- }
-#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
-
vm_frame_ctx_shared_t shared;
shared.bytecode_header_p = bytecode_p;
shared.status_flags = 0;
diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h
index c2287180f..4a519e5bf 100644
--- a/jerry-core/vm/vm.h
+++ b/jerry-core/vm/vm.h
@@ -17,6 +17,7 @@
#define VM_H
#include "ecma-globals.h"
+#include "ecma-module.h"
#include "jrt.h"
#include "vm-defines.h"
@@ -481,7 +482,7 @@ ecma_value_t vm_run_global (const ecma_compiled_code_t *bytecode_p);
ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, uint32_t parse_opts);
#if ENABLED (JERRY_MODULE_SYSTEM)
-ecma_value_t vm_run_module (const ecma_compiled_code_t *bytecode_p, ecma_object_t *lex_env_p);
+ecma_value_t vm_run_module (ecma_module_t *module_p);
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
ecma_value_t vm_run (vm_frame_ctx_shared_t *shared_p, ecma_value_t this_binding_value, ecma_object_t *lex_env_p);
diff --git a/jerry-main/main-options.c b/jerry-main/main-options.c
index da10a9532..f373a0358 100644
--- a/jerry-main/main-options.c
+++ b/jerry-main/main-options.c
@@ -44,6 +44,7 @@ typedef enum
OPT_DEBUGGER_WAIT_SOURCE,
OPT_EXEC_SNAP,
OPT_EXEC_SNAP_FUNC,
+ OPT_MODULE,
OPT_LOG_LEVEL,
OPT_NO_PROMPT,
OPT_CALL_ON_EXIT,
@@ -85,6 +86,8 @@ static const cli_opt_t main_opts[] =
.help = "execute input snapshot file(s)"),
CLI_OPT_DEF (.id = OPT_EXEC_SNAP_FUNC, .longopt = "exec-snapshot-func", .meta = "FILE NUM",
.help = "execute specific function from input snapshot file(s)"),
+ CLI_OPT_DEF (.id = OPT_MODULE, .opt = "m", .longopt = "module", .meta = "FILE",
+ .help = "execute module file"),
CLI_OPT_DEF (.id = OPT_LOG_LEVEL, .longopt = "log-level", .meta = "NUM",
.help = "set log level (0-3)"),
CLI_OPT_DEF (.id = OPT_NO_PROMPT, .longopt = "no-prompt",
@@ -307,6 +310,19 @@ main_parse_args (int argc, /**< argc */
break;
}
+ case OPT_MODULE:
+ {
+ const uint32_t path_index = cli_consume_path (&cli_state);
+
+ main_source_t *source_p = arguments_p->sources_p + arguments_p->source_count;
+ arguments_p->source_count++;
+
+ source_p->type = SOURCE_MODULE;
+ source_p->path_index = path_index;
+ source_p->snapshot_index = 0;
+
+ break;
+ }
case OPT_LOG_LEVEL:
{
long int log_level = cli_consume_int (&cli_state);
diff --git a/jerry-main/main-options.h b/jerry-main/main-options.h
index 4486e5d12..21afad354 100644
--- a/jerry-main/main-options.h
+++ b/jerry-main/main-options.h
@@ -38,6 +38,7 @@ typedef enum
typedef enum
{
SOURCE_SNAPSHOT,
+ SOURCE_MODULE,
SOURCE_SCRIPT,
} main_source_type_t;
diff --git a/jerry-main/main-unix.c b/jerry-main/main-unix.c
index 08075ce81..abd9e96d7 100644
--- a/jerry-main/main-unix.c
+++ b/jerry-main/main-unix.c
@@ -86,6 +86,8 @@ restart:
goto exit;
}
+ uint32_t parse_opts = JERRY_PARSE_NO_OPTS;
+
switch (source_file_p->type)
{
case SOURCE_SNAPSHOT:
@@ -98,9 +100,15 @@ restart:
jerry_port_release_source (source_p);
break;
}
+ case SOURCE_MODULE:
+ {
+ parse_opts = JERRY_PARSE_MODULE;
+ /* FALLTHRU */
+ }
default:
{
- assert (source_file_p->type == SOURCE_SCRIPT);
+ assert (source_file_p->type == SOURCE_SCRIPT
+ || source_file_p->type == SOURCE_MODULE);
if (!jerry_is_valid_utf8_string ((jerry_char_t *) source_p, (jerry_size_t) source_size))
{
@@ -113,7 +121,7 @@ restart:
strlen (file_path_p),
source_p,
source_size,
- JERRY_PARSE_NO_OPTS);
+ parse_opts);
jerry_port_release_source (source_p);
diff --git a/tests/jerry/es.next/module-export-01.js b/tests/jerry/es.next/module-export-01.mjs
similarity index 100%
rename from tests/jerry/es.next/module-export-01.js
rename to tests/jerry/es.next/module-export-01.mjs
diff --git a/tests/jerry/es.next/module-export-02.js b/tests/jerry/es.next/module-export-02.mjs
similarity index 79%
rename from tests/jerry/es.next/module-export-02.js
rename to tests/jerry/es.next/module-export-02.mjs
index 6fddc5f09..40aa9533e 100644
--- a/tests/jerry/es.next/module-export-02.js
+++ b/tests/jerry/es.next/module-export-02.mjs
@@ -13,8 +13,8 @@
* limitations under the License.
*/
-export {} from "module-export-01.js";
-export {aa,} from "module-export-01.js";
-export {bb as b_, cc as c_} from "module-export-01.js";
-export * from "module-export-01.js";
+export {} from "module-export-01.mjs";
+export {aa,} from "module-export-01.mjs";
+export {bb as b_, cc as c_} from "module-export-01.mjs";
+export * from "module-export-01.mjs";
export default function () {return "default"};
diff --git a/tests/jerry/es.next/module-export-03.js b/tests/jerry/es.next/module-export-03.mjs
similarity index 95%
rename from tests/jerry/es.next/module-export-03.js
rename to tests/jerry/es.next/module-export-03.mjs
index eb8850c36..3f1d28622 100644
--- a/tests/jerry/es.next/module-export-03.js
+++ b/tests/jerry/es.next/module-export-03.mjs
@@ -23,4 +23,4 @@ export default class {
}
}
-export * from "module-export-02.js"
+export * from "module-export-02.mjs"
diff --git a/tests/jerry/es.next/module-export-04.js b/tests/jerry/es.next/module-export-04.mjs
similarity index 100%
rename from tests/jerry/es.next/module-export-04.js
rename to tests/jerry/es.next/module-export-04.mjs
diff --git a/tests/jerry/es.next/module-export-05.js b/tests/jerry/es.next/module-export-05.mjs
similarity index 89%
rename from tests/jerry/es.next/module-export-05.js
rename to tests/jerry/es.next/module-export-05.mjs
index 5a6349c02..d53e54a5b 100644
--- a/tests/jerry/es.next/module-export-05.js
+++ b/tests/jerry/es.next/module-export-05.mjs
@@ -13,6 +13,6 @@
* limitations under the License.
*/
-export * from "module-export-01.js";
-export * from "module-export-04.js";
+export * from "module-export-01.mjs";
+export * from "module-export-04.mjs";
export default a = "str"
diff --git a/tests/jerry/es.next/module-export-06.js b/tests/jerry/es.next/module-export-06.mjs
similarity index 89%
rename from tests/jerry/es.next/module-export-06.js
rename to tests/jerry/es.next/module-export-06.mjs
index 8c614a490..30ea99e64 100644
--- a/tests/jerry/es.next/module-export-06.js
+++ b/tests/jerry/es.next/module-export-06.mjs
@@ -14,6 +14,6 @@
*/
export {}
-export {} from "module-export-01.js";
+export {} from "module-export-01.mjs";
export {};
-export {} from "module-export-04.js"
+export {} from "module-export-04.mjs"
diff --git a/tests/jerry/es.next/module-export-07.js b/tests/jerry/es.next/module-export-07.mjs
similarity index 100%
rename from tests/jerry/es.next/module-export-07.js
rename to tests/jerry/es.next/module-export-07.mjs
diff --git a/tests/jerry/es.next/module-export-08.js b/tests/jerry/es.next/module-export-08.mjs
similarity index 94%
rename from tests/jerry/es.next/module-export-08.js
rename to tests/jerry/es.next/module-export-08.mjs
index 5453c7fb8..a5bc4488f 100644
--- a/tests/jerry/es.next/module-export-08.js
+++ b/tests/jerry/es.next/module-export-08.mjs
@@ -13,5 +13,5 @@
* limitations under the License.
*/
-export * from "./module-export-04.js";
+export * from "./module-export-04.mjs";
export let c = 5;
diff --git a/tests/jerry/es.next/module-export-fail-test.js b/tests/jerry/es.next/module-export-fail-test.mjs
similarity index 100%
rename from tests/jerry/es.next/module-export-fail-test.js
rename to tests/jerry/es.next/module-export-fail-test.mjs
diff --git a/tests/jerry/es.next/module-import-01.js b/tests/jerry/es.next/module-import-01.mjs
similarity index 74%
rename from tests/jerry/es.next/module-import-01.js
rename to tests/jerry/es.next/module-import-01.mjs
index 54f6826f5..daf90d1c1 100644
--- a/tests/jerry/es.next/module-import-01.js
+++ b/tests/jerry/es.next/module-import-01.mjs
@@ -13,13 +13,13 @@
* limitations under the License.
*/
-import "./module-export-01.js";
-import def from "module-export-01.js";
-import {} from "module-export-01.js";
-import {aa as a,} from "module-export-01.js";
-import {bb as b, cc as c} from "module-export-01.js";
-import {x} from "module-export-01.js";
-import * as mod from "module-export-01.js";
+import "./module-export-01.mjs";
+import def from "module-export-01.mjs";
+import {} from "module-export-01.mjs";
+import {aa as a,} from "module-export-01.mjs";
+import {bb as b, cc as c} from "module-export-01.mjs";
+import {x} from "module-export-01.mjs";
+import * as mod from "module-export-01.mjs";
assert (def === "default");
assert (a === "a");
diff --git a/tests/jerry/es.next/module-import-02.js b/tests/jerry/es.next/module-import-02.mjs
similarity index 89%
rename from tests/jerry/es.next/module-import-02.js
rename to tests/jerry/es.next/module-import-02.mjs
index 669c7a49e..3ffb8ef93 100644
--- a/tests/jerry/es.next/module-import-02.js
+++ b/tests/jerry/es.next/module-import-02.mjs
@@ -13,8 +13,8 @@
* limitations under the License.
*/
-import def, * as mod from "module-export-02.js";
-import {b_, c_,} from "module-export-02.js";
+import def, * as mod from "module-export-02.mjs";
+import {b_, c_,} from "module-export-02.mjs";
assert (def() === "default")
assert (mod.aa === "a")
diff --git a/tests/jerry/es.next/module-import-03.js b/tests/jerry/es.next/module-import-03.mjs
similarity index 92%
rename from tests/jerry/es.next/module-import-03.js
rename to tests/jerry/es.next/module-import-03.mjs
index 11214a9e6..7d8c4dd50 100644
--- a/tests/jerry/es.next/module-import-03.js
+++ b/tests/jerry/es.next/module-import-03.mjs
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-import incrementer, {aa, c_, x,} from "module-export-03.js"
+import incrementer, {aa, c_, x,} from "module-export-03.mjs"
var i = new incrementer(3);
assert(i.incr() === 4);
assert(i.incr() === 5);
diff --git a/tests/jerry/es.next/module-import-04.js b/tests/jerry/es.next/module-import-04.mjs
similarity index 83%
rename from tests/jerry/es.next/module-import-04.js
rename to tests/jerry/es.next/module-import-04.mjs
index f0a5181a1..60fd24a6f 100644
--- a/tests/jerry/es.next/module-import-04.js
+++ b/tests/jerry/es.next/module-import-04.mjs
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-import "module-import-01.js";
-import "module-export-05.js";
-import "module-export-06.js";
-import "module-export-07.js";
+import "module-import-01.mjs";
+import "module-export-05.mjs";
+import "module-export-06.mjs";
+import "module-export-07.mjs";
diff --git a/tests/jerry/es.next/module-import-05.js b/tests/jerry/es.next/module-import-05.mjs
similarity index 94%
rename from tests/jerry/es.next/module-import-05.js
rename to tests/jerry/es.next/module-import-05.mjs
index b04277cf7..04658cda3 100644
--- a/tests/jerry/es.next/module-import-05.js
+++ b/tests/jerry/es.next/module-import-05.mjs
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-import * as f from "./module-export-08.js";
+import * as f from "./module-export-08.mjs";
assert (f.c === 5)
assert (f.x === 41)
diff --git a/tests/jerry/es.next/module-resource-name.js b/tests/jerry/es.next/module-resource-name.mjs
similarity index 94%
rename from tests/jerry/es.next/module-resource-name.js
rename to tests/jerry/es.next/module-resource-name.mjs
index 5a3e0d464..33bf743d2 100644
--- a/tests/jerry/es.next/module-resource-name.js
+++ b/tests/jerry/es.next/module-resource-name.mjs
@@ -22,6 +22,6 @@ getNamePromise(collector).then(() => { collector["end"] = resourceName(); });
function __checkAsync() {
assert(collector["start"].endsWith("module-resource-name-export.mjs"));
assert(collector["middle"].endsWith("module-resource-name-export.mjs"));
- assert(collector["end"].endsWith("module-resource-name.js"));
+ assert(collector["end"].endsWith("module-resource-name.mjs"));
assert(Object.keys(collector).length === 3);
}
diff --git a/tests/jerry/es.next/regression-test-issue-2842.js b/tests/jerry/es.next/regression-test-issue-2842.mjs
similarity index 100%
rename from tests/jerry/es.next/regression-test-issue-2842.js
rename to tests/jerry/es.next/regression-test-issue-2842.mjs
diff --git a/tests/jerry/es.next/regression-test-issue-2975.js b/tests/jerry/es.next/regression-test-issue-2975.js
index d7068951a..92d92f86e 100644
--- a/tests/jerry/es.next/regression-test-issue-2975.js
+++ b/tests/jerry/es.next/regression-test-issue-2975.js
@@ -16,7 +16,7 @@
/* Import/export statements must be in the global scope. */
var eval = eval.bind();
try {
- eval('import { c } from "tests/jerry/es.next/module-export-01.js";');
+ eval('import { c } from "tests/jerry/es.next/module-export-01.mjs";');
assert (false);
} catch (e) {
assert (e instanceof SyntaxError);
diff --git a/tests/jerry/fail/module-001.js b/tests/jerry/fail/module-001.mjs
similarity index 94%
rename from tests/jerry/fail/module-001.js
rename to tests/jerry/fail/module-001.mjs
index 7dba7a828..b590983c7 100644
--- a/tests/jerry/fail/module-001.js
+++ b/tests/jerry/fail/module-001.mjs
@@ -14,4 +14,4 @@
*/
// File does not exist.
-import b from "module-exports.js"
+import b from "module-exports.mjs"
diff --git a/tests/jerry/fail/module-002.js b/tests/jerry/fail/module-002.mjs
similarity index 91%
rename from tests/jerry/fail/module-002.js
rename to tests/jerry/fail/module-002.mjs
index c7e266512..b3b3f85e1 100644
--- a/tests/jerry/fail/module-002.js
+++ b/tests/jerry/fail/module-002.mjs
@@ -13,4 +13,4 @@
* limitations under the License.
*/
-import { , as b } from "../es.next/module-export-01.js";
+import { , as b } from "../es.next/module-export-01.mjs";
diff --git a/tests/jerry/fail/module-003.js b/tests/jerry/fail/module-003.mjs
similarity index 92%
rename from tests/jerry/fail/module-003.js
rename to tests/jerry/fail/module-003.mjs
index b4c22d266..9ec4d2023 100644
--- a/tests/jerry/fail/module-003.js
+++ b/tests/jerry/fail/module-003.mjs
@@ -13,4 +13,4 @@
* limitations under the License.
*/
-import , as b from "../es.next/module-export-01.js";
+import , as b from "../es.next/module-export-01.mjs";
diff --git a/tests/jerry/fail/module-004.js b/tests/jerry/fail/module-004.js
deleted file mode 100644
index 732365a12..000000000
--- a/tests/jerry/fail/module-004.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright JS Foundation and other contributors, http://js.foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { b as , } from "../es.next/module-export-01.js";
diff --git a/tests/jerry/fail/module-004.mjs b/tests/jerry/fail/module-004.mjs
new file mode 100644
index 000000000..3aac57984
--- /dev/null
+++ b/tests/jerry/fail/module-004.mjs
@@ -0,0 +1,16 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { b as , } from "../es.next/module-export-01.mjs";
diff --git a/tests/jerry/fail/module-005.js b/tests/jerry/fail/module-005.mjs
similarity index 92%
rename from tests/jerry/fail/module-005.js
rename to tests/jerry/fail/module-005.mjs
index 7b6d7bb5f..1c05584e2 100644
--- a/tests/jerry/fail/module-005.js
+++ b/tests/jerry/fail/module-005.mjs
@@ -14,4 +14,4 @@
*/
/* Named imports must be in a NamedImports block. */
-import b as , from "../es.next/module-export-01.js";
+import b as , from "../es.next/module-export-01.mjs";
diff --git a/tests/jerry/fail/module-006.js b/tests/jerry/fail/module-006.mjs
similarity index 100%
rename from tests/jerry/fail/module-006.js
rename to tests/jerry/fail/module-006.mjs
diff --git a/tests/jerry/fail/module-007.js b/tests/jerry/fail/module-007.mjs
similarity index 95%
rename from tests/jerry/fail/module-007.js
rename to tests/jerry/fail/module-007.mjs
index 5a0ca65f9..8265b1668 100644
--- a/tests/jerry/fail/module-007.js
+++ b/tests/jerry/fail/module-007.mjs
@@ -14,4 +14,4 @@
*/
/* Module requests must always be evaluated. */
-import "./module-sideeffect.js"
+import "./module-sideeffect.mjs"
diff --git a/tests/jerry/fail/module-008.js b/tests/jerry/fail/module-008.mjs
similarity index 100%
rename from tests/jerry/fail/module-008.js
rename to tests/jerry/fail/module-008.mjs
diff --git a/tests/jerry/fail/module-009.js b/tests/jerry/fail/module-009.mjs
similarity index 100%
rename from tests/jerry/fail/module-009.js
rename to tests/jerry/fail/module-009.mjs
diff --git a/tests/jerry/fail/module-010.js b/tests/jerry/fail/module-010.mjs
similarity index 91%
rename from tests/jerry/fail/module-010.js
rename to tests/jerry/fail/module-010.mjs
index ca970f7f0..15af24a8c 100644
--- a/tests/jerry/fail/module-010.js
+++ b/tests/jerry/fail/module-010.mjs
@@ -14,4 +14,4 @@
*/
/* Can't have duplicate local bindings */
-import { c as a, d as a } from "../es.next/module-export-01.js";
+import { c as a, d as a } from "../es.next/module-export-01.mjs";
diff --git a/tests/jerry/fail/module-011.js b/tests/jerry/fail/module-011.mjs
similarity index 100%
rename from tests/jerry/fail/module-011.js
rename to tests/jerry/fail/module-011.mjs
diff --git a/tests/jerry/fail/module-012.js b/tests/jerry/fail/module-012.mjs
similarity index 100%
rename from tests/jerry/fail/module-012.js
rename to tests/jerry/fail/module-012.mjs
diff --git a/tests/jerry/fail/module-013.js b/tests/jerry/fail/module-013.mjs
similarity index 100%
rename from tests/jerry/fail/module-013.js
rename to tests/jerry/fail/module-013.mjs
diff --git a/tests/jerry/fail/module-014.js b/tests/jerry/fail/module-014.mjs
similarity index 92%
rename from tests/jerry/fail/module-014.js
rename to tests/jerry/fail/module-014.mjs
index 5deeeff88..51c620066 100644
--- a/tests/jerry/fail/module-014.js
+++ b/tests/jerry/fail/module-014.mjs
@@ -15,5 +15,5 @@
/* Import/export statements must be in the global scope. */
if (true) {
- import { c } from "../es.next/module-export-01.js";
+ import { c } from "../es.next/module-export-01.mjs";
}
diff --git a/tests/jerry/fail/module-015.js b/tests/jerry/fail/module-015.mjs
similarity index 92%
rename from tests/jerry/fail/module-015.js
rename to tests/jerry/fail/module-015.mjs
index ecf41e7e4..63efbe35d 100644
--- a/tests/jerry/fail/module-015.js
+++ b/tests/jerry/fail/module-015.mjs
@@ -15,5 +15,5 @@
/* Import/export statements must be in the global scope. */
function someFunction() {
- import { c } from "../es.next/module-export-01.js";
+ import { c } from "../es.next/module-export-01.mjs";
}
diff --git a/tests/jerry/fail/module-016.js b/tests/jerry/fail/module-016.mjs
similarity index 91%
rename from tests/jerry/fail/module-016.js
rename to tests/jerry/fail/module-016.mjs
index 100871b08..2e22cb69b 100644
--- a/tests/jerry/fail/module-016.js
+++ b/tests/jerry/fail/module-016.mjs
@@ -14,4 +14,4 @@
*/
/* Import/export statements must be in the global scope. */
-eval ('import { c } from "../es.next/module-export-01.js";');
+eval ('import { c } from "../es.next/module-export-01.mjs";');
diff --git a/tests/jerry/fail/module-017.js b/tests/jerry/fail/module-017.mjs
similarity index 92%
rename from tests/jerry/fail/module-017.js
rename to tests/jerry/fail/module-017.mjs
index 642ef9dea..e038a0173 100644
--- a/tests/jerry/fail/module-017.js
+++ b/tests/jerry/fail/module-017.mjs
@@ -14,4 +14,4 @@
*/
/* NamedImports must always be followed by a FromClause. */
-import { b }, from "../es.next/module-export-01.js"
+import { b }, from "../es.next/module-export-01.mjs"
diff --git a/tests/jerry/fail/module-018.js b/tests/jerry/fail/module-018.mjs
similarity index 91%
rename from tests/jerry/fail/module-018.js
rename to tests/jerry/fail/module-018.mjs
index 5face7e7c..60c9a96db 100644
--- a/tests/jerry/fail/module-018.js
+++ b/tests/jerry/fail/module-018.mjs
@@ -14,4 +14,4 @@
*/
/* An import statement can have either a NameSpaceImport or NamedIpmorts */
-import * as mod, { b } from "../es.next/module-export-01.js"
+import * as mod, { b } from "../es.next/module-export-01.mjs"
diff --git a/tests/jerry/fail/module-019.js b/tests/jerry/fail/module-019.mjs
similarity index 100%
rename from tests/jerry/fail/module-019.js
rename to tests/jerry/fail/module-019.mjs
diff --git a/tests/jerry/fail/module-020.js b/tests/jerry/fail/module-020.mjs
similarity index 92%
rename from tests/jerry/fail/module-020.js
rename to tests/jerry/fail/module-020.mjs
index f99ecf9c3..4a160d547 100644
--- a/tests/jerry/fail/module-020.js
+++ b/tests/jerry/fail/module-020.mjs
@@ -14,4 +14,4 @@
*/
/* '*' is not valid inside NamedImports. */
-import { *, d } from "../es.next/module-imported-01.js"
+import { *, d } from "../es.next/module-imported-01.mjs"
diff --git a/tests/jerry/fail/module-021.js b/tests/jerry/fail/module-021.mjs
similarity index 86%
rename from tests/jerry/fail/module-021.js
rename to tests/jerry/fail/module-021.mjs
index 498273360..016bb3778 100644
--- a/tests/jerry/fail/module-021.js
+++ b/tests/jerry/fail/module-021.mjs
@@ -14,5 +14,5 @@
*/
/* Can't have duplicated local bindings. */
-import { b } from "../es.next/module-export-01.js"
-import { b } from "../es.next/module-export-02.js"
+import { b } from "../es.next/module-export-01.mjs"
+import { b } from "../es.next/module-export-02.mjs"
diff --git a/tests/jerry/fail/module-022.js b/tests/jerry/fail/module-022.mjs
similarity index 93%
rename from tests/jerry/fail/module-022.js
rename to tests/jerry/fail/module-022.mjs
index 3d9f0688f..4ad7d3af0 100644
--- a/tests/jerry/fail/module-022.js
+++ b/tests/jerry/fail/module-022.mjs
@@ -14,4 +14,4 @@
*/
/* FromClause must follow an ImportClause. */
-import from "../es.next/module-export-02.js"
+import from "../es.next/module-export-02.mjs"
diff --git a/tests/jerry/fail/module-023.js b/tests/jerry/fail/module-023.mjs
similarity index 93%
rename from tests/jerry/fail/module-023.js
rename to tests/jerry/fail/module-023.mjs
index 03d072f41..568207778 100644
--- a/tests/jerry/fail/module-023.js
+++ b/tests/jerry/fail/module-023.mjs
@@ -14,4 +14,4 @@
*/
/* Namespace imports must have a local name. */
-import * from "../es.next/module-export-01.js"
+import * from "../es.next/module-export-01.mjs"
diff --git a/tests/jerry/fail/module-024.js b/tests/jerry/fail/module-024.mjs
similarity index 92%
rename from tests/jerry/fail/module-024.js
rename to tests/jerry/fail/module-024.mjs
index be81cf929..1e9f3bad5 100644
--- a/tests/jerry/fail/module-024.js
+++ b/tests/jerry/fail/module-024.mjs
@@ -14,4 +14,4 @@
*/
/* Star exports can't have an export name. */
-export * as star from "../es.next/module-export-01.js"
+export * as star from "../es.next/module-export-01.mjs"
diff --git a/tests/jerry/fail/module-025.js b/tests/jerry/fail/module-025.mjs
similarity index 93%
rename from tests/jerry/fail/module-025.js
rename to tests/jerry/fail/module-025.mjs
index c26d673ad..cb05adc9a 100644
--- a/tests/jerry/fail/module-025.js
+++ b/tests/jerry/fail/module-025.mjs
@@ -14,4 +14,4 @@
*/
/* Indirect exports must be checked if they are resolvable. */
-export { l } from "../es.next/module-export-01.js"
+export { l } from "../es.next/module-export-01.mjs"
diff --git a/tests/jerry/fail/module-026.js b/tests/jerry/fail/module-026.mjs
similarity index 94%
rename from tests/jerry/fail/module-026.js
rename to tests/jerry/fail/module-026.mjs
index b4eef17ba..9d11cfa71 100644
--- a/tests/jerry/fail/module-026.js
+++ b/tests/jerry/fail/module-026.mjs
@@ -14,4 +14,4 @@
*/
/* Can't have circular imports/exports. */
-export { b } from "./module-027.js"
+export { b } from "./module-027.mjs"
diff --git a/tests/jerry/fail/module-027.js b/tests/jerry/fail/module-027.mjs
similarity index 94%
rename from tests/jerry/fail/module-027.js
rename to tests/jerry/fail/module-027.mjs
index 87b62a9da..b50e3475b 100644
--- a/tests/jerry/fail/module-027.js
+++ b/tests/jerry/fail/module-027.mjs
@@ -14,4 +14,4 @@
*/
/* Can't have circular imports/exports. */
-export { b } from "./module-026.js"
+export { b } from "./module-026.mjs"
diff --git a/tests/jerry/fail/module-028.js b/tests/jerry/fail/module-028.mjs
similarity index 92%
rename from tests/jerry/fail/module-028.js
rename to tests/jerry/fail/module-028.mjs
index 8db2d5f04..08ede2d75 100644
--- a/tests/jerry/fail/module-028.js
+++ b/tests/jerry/fail/module-028.mjs
@@ -14,4 +14,4 @@
*/
/* Ambiguous import */
-import { x } from "../es.next/module-export-05.js"
+import { x } from "../es.next/module-export-05.mjs"
diff --git a/tests/jerry/fail/module-029.js b/tests/jerry/fail/module-029.mjs
similarity index 91%
rename from tests/jerry/fail/module-029.js
rename to tests/jerry/fail/module-029.mjs
index 1f4929eab..b04e2a382 100644
--- a/tests/jerry/fail/module-029.js
+++ b/tests/jerry/fail/module-029.mjs
@@ -14,4 +14,4 @@
*/
/* Import/export statements must be in the global scope. */
-Function('','import { c } from "../es.next/module-export-01.js";')
+Function('','import { c } from "../es.next/module-export-01.mjs";')
diff --git a/tests/jerry/fail/module-030.js b/tests/jerry/fail/module-030.mjs
similarity index 93%
rename from tests/jerry/fail/module-030.js
rename to tests/jerry/fail/module-030.mjs
index 3cd2f89b5..d9dc5adc5 100644
--- a/tests/jerry/fail/module-030.js
+++ b/tests/jerry/fail/module-030.mjs
@@ -14,4 +14,4 @@
*/
/* No default export found. */
-import def from "../es.next/module-export-06.js"
+import def from "../es.next/module-export-06.mjs"
diff --git a/tests/jerry/fail/module-031.js b/tests/jerry/fail/module-031.mjs
similarity index 100%
rename from tests/jerry/fail/module-031.js
rename to tests/jerry/fail/module-031.mjs
diff --git a/tests/jerry/fail/module-032.js b/tests/jerry/fail/module-032.mjs
similarity index 91%
rename from tests/jerry/fail/module-032.js
rename to tests/jerry/fail/module-032.mjs
index 6dd05c8c9..fb6898c3a 100644
--- a/tests/jerry/fail/module-032.js
+++ b/tests/jerry/fail/module-032.mjs
@@ -14,4 +14,4 @@
*/
let a;
-import { a } from "../es.next/module-export-fail-test.js";
+import { a } from "../es.next/module-export-fail-test.mjs";
diff --git a/tests/jerry/fail/module-033.js b/tests/jerry/fail/module-033.mjs
similarity index 91%
rename from tests/jerry/fail/module-033.js
rename to tests/jerry/fail/module-033.mjs
index 08dba16ad..235927d9e 100644
--- a/tests/jerry/fail/module-033.js
+++ b/tests/jerry/fail/module-033.mjs
@@ -14,4 +14,4 @@
*/
var a;
-import { a } from "../es.next/module-export-fail-test.js";
+import { a } from "../es.next/module-export-fail-test.mjs";
diff --git a/tests/jerry/fail/module-034.js b/tests/jerry/fail/module-034.mjs
similarity index 91%
rename from tests/jerry/fail/module-034.js
rename to tests/jerry/fail/module-034.mjs
index c4375a426..7723b8c34 100644
--- a/tests/jerry/fail/module-034.js
+++ b/tests/jerry/fail/module-034.mjs
@@ -13,5 +13,5 @@
* limitations under the License.
*/
-import { a } from "../es.next/module-export-fail-test.js";
+import { a } from "../es.next/module-export-fail-test.mjs";
class a {};
diff --git a/tests/jerry/fail/module-035.js b/tests/jerry/fail/module-035.mjs
similarity index 91%
rename from tests/jerry/fail/module-035.js
rename to tests/jerry/fail/module-035.mjs
index e332f5a93..d19fce94b 100644
--- a/tests/jerry/fail/module-035.js
+++ b/tests/jerry/fail/module-035.mjs
@@ -13,5 +13,5 @@
* limitations under the License.
*/
-import { a } from "../es.next/module-export-fail-test.js";
+import { a } from "../es.next/module-export-fail-test.mjs";
function a() {}
diff --git a/tests/jerry/fail/module-036.js b/tests/jerry/fail/module-036.mjs
similarity index 95%
rename from tests/jerry/fail/module-036.js
rename to tests/jerry/fail/module-036.mjs
index 8550de8ad..ef0387abc 100644
--- a/tests/jerry/fail/module-036.js
+++ b/tests/jerry/fail/module-036.mjs
@@ -13,4 +13,4 @@
* limitations under the License.
*/
-import "./module-export-001.js"
+import "./module-await-001.mjs"
diff --git a/tests/jerry/fail/module-037.js b/tests/jerry/fail/module-037.mjs
similarity index 95%
rename from tests/jerry/fail/module-037.js
rename to tests/jerry/fail/module-037.mjs
index 29f3dba46..ef0387abc 100644
--- a/tests/jerry/fail/module-037.js
+++ b/tests/jerry/fail/module-037.mjs
@@ -13,4 +13,4 @@
* limitations under the License.
*/
-import "./module-await-001.js"
+import "./module-await-001.mjs"
diff --git a/tests/jerry/fail/module-await-001.js b/tests/jerry/fail/module-await-001.mjs
similarity index 100%
rename from tests/jerry/fail/module-await-001.js
rename to tests/jerry/fail/module-await-001.mjs
diff --git a/tests/jerry/fail/module-export-001.js b/tests/jerry/fail/module-export-001.mjs
similarity index 100%
rename from tests/jerry/fail/module-export-001.js
rename to tests/jerry/fail/module-export-001.mjs
diff --git a/tests/jerry/fail/module-sideeffect.js b/tests/jerry/fail/module-sideeffect.mjs
similarity index 100%
rename from tests/jerry/fail/module-sideeffect.js
rename to tests/jerry/fail/module-sideeffect.mjs
diff --git a/tests/jerry/fail/regression-test-issue-2896.js b/tests/jerry/fail/regression-test-issue-2896.js
index 94a60abd9..720264eee 100644
--- a/tests/jerry/fail/regression-test-issue-2896.js
+++ b/tests/jerry/fail/regression-test-issue-2896.js
@@ -12,5 +12,5 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-export {} from "dummy.js";
-export {} from "../es.next/module-export-04.js";
+export {} from "dummy.mjs";
+export {} from "../es.next/module-export-04.mjs";
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index 592b78a0c..36f2bb80c 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -328,8 +328,6 @@
-
-
@@ -414,7 +412,6 @@
-
@@ -457,7 +454,6 @@
-
@@ -487,7 +483,6 @@
-
@@ -498,13 +493,6 @@
-
-
-
-
-
-
-
@@ -576,13 +564,9 @@
-
-
-
-
@@ -699,8 +683,6 @@
-
-
@@ -5242,7 +5224,6 @@
-
diff --git a/tools/runners/run-test-suite.py b/tools/runners/run-test-suite.py
index 3c3967c4c..a5718d154 100755
--- a/tools/runners/run-test-suite.py
+++ b/tools/runners/run-test-suite.py
@@ -54,7 +54,9 @@ def get_tests(test_dir, test_list, skip_list):
if test_dir:
tests = []
for root, _, files in os.walk(test_dir):
- tests.extend([os.path.join(root, test_file) for test_file in files if test_file.endswith('.js')])
+ for test_file in files:
+ if test_file.endswith('.js') or test_file.endswith('.mjs'):
+ tests.extend([os.path.join(root, test_file)])
if test_list:
dirname = os.path.dirname(test_list)
@@ -136,7 +138,12 @@ def run_normal_tests(args, tests):
tested += 1
test_path = os.path.relpath(test)
is_expected_to_fail = os.path.join(os.path.sep, 'fail', '') in test
- (returncode, stdout) = execute_test_command(test_cmd + [test])
+
+ test_argument = []
+ if test.endswith('.mjs'):
+ test_argument.extend(['-m'])
+
+ (returncode, stdout) = execute_test_command(test_cmd + test_argument + [test])
if (returncode == 0 and not is_expected_to_fail) or (returncode == 1 and is_expected_to_fail):
passed += 1
diff --git a/tools/runners/test262-harness.py b/tools/runners/test262-harness.py
index f2a36d7ab..a5ce19a67 100755
--- a/tools/runners/test262-harness.py
+++ b/tools/runners/test262-harness.py
@@ -367,6 +367,8 @@ def build_options():
help="Command to print from console")
result.add_option("--list-includes", default=False, action="store_true",
help="List includes required by tests")
+ result.add_option("--module-flag", default="-m",
+ help="List includes required by tests")
return result
@@ -481,7 +483,7 @@ class TestResult(object):
class TestCase(object):
- def __init__(self, suite, name, full_path, strict_mode, command_template):
+ def __init__(self, suite, name, full_path, strict_mode, command_template, module_flag):
self.suite = suite
self.name = name
self.full_path = full_path
@@ -495,6 +497,7 @@ class TestCase(object):
test_record.pop("commentary", None) # do not throw if missing
self.test_record = test_record
self.command_template = command_template
+ self.module_flag = module_flag
self.validate()
@@ -543,6 +546,9 @@ class TestCase(object):
def is_async_test(self):
return 'async' in self.test_record or '$DONE' in self.test
+ def is_module(self):
+ return 'module' in self.test_record
+
def get_include_list(self):
if self.test_record.get('includes'):
return self.test_record['includes']
@@ -618,9 +624,16 @@ class TestCase(object):
def run_test_in(self, tmp):
tmp.write(self.get_source())
tmp.close()
+
+ if self.is_module():
+ arg = self.module_flag + ' ' + tmp.name
+ else:
+ arg = tmp.name
+
command = TestCase.instantiate_template(self.command_template, {
- 'path': tmp.name
+ 'path': arg
})
+
(code, out, err) = TestCase.execute(command)
return TestResult(code, out, err, self)
@@ -695,15 +708,16 @@ def percent_format(partial, total):
class TestSuite(object):
- def __init__(self, root, strict_only, non_strict_only, unmarked_default, print_handle, exclude_list_path):
- self.test_root = path.join(root, 'test')
- self.lib_root = path.join(root, 'harness')
- self.strict_only = strict_only
- self.non_strict_only = non_strict_only
- self.unmarked_default = unmarked_default
- self.print_handle = print_handle
+ def __init__(self, options):
+ self.test_root = path.join(options.tests, 'test')
+ self.lib_root = path.join(options.tests, 'harness')
+ self.strict_only = options.strict_only
+ self.non_strict_only = options.non_strict_only
+ self.unmarked_default = options.unmarked_default
+ self.print_handle = options.print_handle
self.include_cache = {}
- self.exclude_list_path = exclude_list_path
+ self.exclude_list_path = options.exclude_list
+ self.module_flag = options.module_flag
self.logf = None
def _load_excludes(self):
@@ -772,12 +786,12 @@ class TestSuite(object):
print('Excluded: ' + rel_path)
else:
if not self.non_strict_only:
- strict_case = TestCase(self, name, full_path, True, command_template)
+ strict_case = TestCase(self, name, full_path, True, command_template, self.module_flag)
if not strict_case.is_no_strict():
if strict_case.is_only_strict() or self.unmarked_default in ['both', 'strict']:
cases.append(strict_case)
if not self.strict_only:
- non_strict_case = TestCase(self, name, full_path, False, command_template)
+ non_strict_case = TestCase(self, name, full_path, False, command_template, self.module_flag)
if not non_strict_case.is_only_strict():
if non_strict_case.is_no_strict() or self.unmarked_default in ['both', 'non_strict']:
cases.append(non_strict_case)
@@ -901,12 +915,7 @@ def main():
(options, args) = parser.parse_args()
validate_options(options)
- test_suite = TestSuite(options.tests,
- options.strict_only,
- options.non_strict_only,
- options.unmarked_default,
- options.print_handle,
- options.exclude_list)
+ test_suite = TestSuite(options)
test_suite.validate()
if options.loglevel == 'debug':