Support dynamic import calls (#4652)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2021-07-24 09:26:46 +02:00 committed by GitHub
parent d9360f51d0
commit d4178ae386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 698 additions and 114 deletions

View File

@ -830,6 +830,48 @@ typedef jerry_value_t (*jerry_module_resolve_callback_t) (const jerry_value_t sp
- [jerry_module_link](#jerry_module_link)
- [jerry_get_global_object](#jerry_get_global_object)
## jerry_module_import_callback_t
**Summary**
Callback which is called when an import is resolved dynamically to get the referenced module.
*Note*:
- If the function returns with a promise, the import call returns with this promise. The
application should try to resolve the requested module later. If the module is evaluated
successfully, the returned promise should be resolved with the namespace object of the
module. Otherwise, the returned promise should be rejected with an error.
- If the function returns with a resolved module, a promise is created and resolved with the
namespace object of the module. The import call returns with the resolved promise.
- If the function returns with an error, a promise is created and rejected with the
return error. The import call returns with the rejected promise.
- All other return values are considered invalid. In this case the import call returns
with a rejected promise. The rejected promise has a fixed error message, it does not
specify the reason of the fail.
- If realms are enabled, the returned module should be created in the current realm
(see: [jerry_get_global_object](#jerry_get_global_object))
**Prototype**
```c
typedef jerry_value_t (*jerry_module_import_callback_t) (const jerry_value_t specifier,
const jerry_value_t user_value,
void *user_p);
```
- `specifier` - a module specifier string (usually used as a path to the module)
- `user_value` - the user value assigned to the script (see [jerry_parse_options_t](#jerry_parse_options_t))
- `user_p` - pointer passed to [jerry_module_set_import_callback](#jerry_module_set_import_callback).
- return value
- promise or resolved module - if the operation is successful
- an error - otherwise
*New in version [[NEXT_RELEASE]]*.
**See also**
- [jerry_module_set_import_callback](#jerry_module_set_import_callback)
- [jerry_get_global_object](#jerry_get_global_object)
## jerry_module_state_changed_callback_t
**Summary**
@ -5018,6 +5060,132 @@ main (void)
- [jerry_module_link](#jerry_module_link)
- [jerry_module_evaluate](#jerry_module_evaluate)
## jerry_module_set_import_callback
Sets the callback which is called when dynamic imports are resolved. The resolver
receives the `user_value` assigned to the currently executed script, which should
provide all the information that is necessary for the resolve.
*Notes*:
- This API depends on a build option (`JERRY_MODULE_SYSTEM`) and can be checked
in runtime with the `JERRY_FEATURE_MODULE` feature enum value,
see: [jerry_is_feature_enabled](#jerry_is_feature_enabled).
- The possible return values of the callback is explained
in [jerry_module_import_callback_t](#jerry_module_import_callback_t)
**Prototype**
```c
void
jerry_module_set_import_callback (jerry_module_import_callback_t callback_p,
void *user_p)
```
- `callback_p` - a [jerry_module_import_callback_t](#jerry_module_import_callback_t) callback which handles `import()` calls
- `user_p` - user pointer passed to the callback
*New in version [[NEXT_RELEASE]]*.
**Example**
[doctest]: # (test="compile")
```c
#include <jerryscript.h>
#include <stdio.h>
typedef struct {
jerry_value_t specifier;
jerry_value_t user_value;
jerry_value_t promise;
} resolve_module_task_t;
static jerry_value_t
resolve_dynamic (const jerry_value_t specifier, /**< module specifier */
const jerry_value_t user_value, /**< user value assigned to the script */
void *user_p) /**< user data */
{
/* If the specified module has already been evaluated, this callback can
* return with it and the promise creation is automatically done by the engine.
* Otherwise the application usually adds a resolve task to a command queue. */
/* This very simple command queue supports only one task. */
resolve_module_task_t *task_p = (resolve_module_task_t *) user_p;
task_p->specifier = jerry_acquire_value (specifier);
task_p->user_value = jerry_acquire_value (user_value);
/* This Promise should be evaluated later. */
jerry_value_t promise = jerry_create_promise ();
task_p->promise = jerry_acquire_value (promise);
return promise;
}
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
resolve_module_task_t task;
jerry_module_set_import_callback (resolve_dynamic, &task);
const jerry_char_t script[] = "import('modules/my_module.mjs').then(\n"
" function (namespace) { /* use namespace */},\n"
" function (error) { /* handle error */}\n"
")";
const jerry_char_t resource[] = "dir/my_script.js";
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_RESOURCE | JERRY_PARSE_HAS_USER_VALUE;
/* Resource is usually used for debugging purposes, e.g. for generating backtrace. */
parse_options.resource_name_p = resource;
parse_options.resource_name_length = sizeof (resource) - 1;
/* User value should provide information for resolving dynamic imports.
* In this case it contains the full path excluding the filename. */
parse_options.user_value = jerry_create_string ((const jerry_char_t *) "/home/user/dir");
jerry_value_t script_value = jerry_parse (script, sizeof (script) - 1, &parse_options);
jerry_release_value (parse_options.user_value);
jerry_release_value (jerry_run (script_value));
jerry_release_value (script_value);
/* The application resolves both the module and the promise using the specifier
* and the user_value. In this example the specifier is modules/my_module.mjs. */
const jerry_char_t module_script[] = "export var a = 5";
const jerry_char_t module_resource[] = "modules/my_module.mjs";
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_RESOURCE | JERRY_PARSE_HAS_USER_VALUE;
parse_options.resource_name_p = module_resource;
parse_options.resource_name_length = sizeof (module_resource) - 1;
parse_options.user_value = jerry_create_string ((const jerry_char_t *) "/home/user/dir/modules");
jerry_value_t module_value = jerry_parse (module_script, sizeof (module_script) - 1, &parse_options);
jerry_release_value (parse_options.user_value);
jerry_release_value (jerry_module_link (module_value, NULL, NULL));
jerry_release_value (jerry_module_evaluate (module_value));
/* The promise must be resolved with the namespace object, not the module. */
jerry_value_t namespace_value = jerry_module_get_namespace (module_value);
jerry_release_value (jerry_resolve_or_reject_promise (task.promise, namespace_value, true));
jerry_release_value (namespace_value);
jerry_release_value (module_value);
jerry_release_value (task.specifier);
jerry_release_value (task.user_value);
jerry_release_value (task.promise);
/* Process promise handlers. */
jerry_release_value (jerry_run_all_enqueued_jobs ());
jerry_cleanup ();
return 0;
}
```
**See also**
- [jerry_module_import_callback_t](#jerry_module_import_callback_t)
## jerry_native_module_create
Creates a native module with a list of exports. The initial state of the module is linked.

View File

@ -869,6 +869,25 @@ jerry_module_get_namespace (const jerry_value_t module_val) /**< module */
#endif /* JERRY_MODULE_SYSTEM */
} /* jerry_module_get_namespace */
/**
* Sets the callback which is called when dynamic imports are resolved
*/
void
jerry_module_set_import_callback (jerry_module_import_callback_t callback_p, /**< callback which handles
* dynamic import calls */
void *user_p) /**< user pointer passed to the callback */
{
jerry_assert_api_available ();
#if JERRY_MODULE_SYSTEM
JERRY_CONTEXT (module_import_callback_p) = callback_p;
JERRY_CONTEXT (module_import_callback_user_p) = user_p;
#else /* !JERRY_MODULE_SYSTEM */
JERRY_UNUSED (callback_p);
JERRY_UNUSED (user_p);
#endif /* JERRY_MODULE_SYSTEM */
} /* jerry_module_set_import_callback */
/**
* Creates a native module with a list of exports. The initial state of the module is linked.
*

View File

@ -1371,6 +1371,82 @@ error:
return ECMA_VALUE_ERROR;
} /* ecma_module_link */
/**
* Compute the result of 'import()' calls
*
* @return promise object representing the result of the operation
*/
ecma_value_t
ecma_module_import (ecma_value_t specifier, /**< module specifier */
ecma_value_t user_value) /**< user value assigned to the script */
{
ecma_string_t *specifier_p = ecma_op_to_string (specifier);
if (JERRY_UNLIKELY (specifier_p == NULL))
{
goto error;
}
if (JERRY_CONTEXT (module_import_callback_p) == NULL)
{
ecma_deref_ecma_string (specifier_p);
goto error_module_instantiate;
}
jerry_value_t result;
result = JERRY_CONTEXT (module_import_callback_p) (ecma_make_string_value (specifier_p),
user_value,
JERRY_CONTEXT (module_import_callback_user_p));
ecma_deref_ecma_string (specifier_p);
if (JERRY_UNLIKELY (ecma_is_value_error_reference (result)))
{
ecma_raise_error_from_error_reference (result);
goto error;
}
if (ecma_is_value_object (result)
&& ecma_is_promise (ecma_get_object_from_value (result)))
{
return result;
}
ecma_module_t *module_p = ecma_module_get_resolved_module (result);
if (module_p == NULL)
{
ecma_free_value (result);
goto error_module_instantiate;
}
if (module_p->header.u.cls.u1.module_state != JERRY_MODULE_STATE_EVALUATED)
{
ecma_deref_object (&module_p->header.object);
goto error_module_instantiate;
}
result = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_VALUE_UNDEFINED, NULL);
ecma_fulfill_promise (result, ecma_make_object_value (module_p->namespace_object_p));
ecma_deref_object (&module_p->header.object);
return result;
error_module_instantiate:
ecma_raise_range_error (ECMA_ERR_MSG ("Module cannot be instantiated"));
error:
if (jcontext_has_pending_abort ())
{
return ECMA_VALUE_ERROR;
}
ecma_value_t exception = jcontext_take_exception ();
ecma_value_t promise = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_VALUE_UNDEFINED, NULL);
ecma_reject_promise (promise, exception);
ecma_free_value (exception);
return promise;
} /* ecma_module_import */
/**
* Cleans up and releases a module structure including all referenced modules.
*/

View File

@ -120,6 +120,7 @@ ecma_value_t ecma_module_link (ecma_module_t *module_p,
jerry_module_resolve_callback_t callback_p,
void *user_p);
ecma_value_t ecma_module_evaluate (ecma_module_t *module_p);
ecma_value_t ecma_module_import (ecma_value_t specifier, ecma_value_t user_value);
ecma_module_t *ecma_module_create (void);
void ecma_module_cleanup_context (void);

View File

@ -279,6 +279,7 @@ void jerry_module_set_state_changed_callback (jerry_module_state_changed_callbac
size_t jerry_module_get_number_of_requests (const jerry_value_t module_val);
jerry_value_t jerry_module_get_request (const jerry_value_t module_val, size_t request_index);
jerry_value_t jerry_module_get_namespace (const jerry_value_t module_val);
void jerry_module_set_import_callback (jerry_module_import_callback_t callback_p, void *user_p);
jerry_value_t jerry_native_module_create (jerry_native_module_evaluate_callback_t callback,
const jerry_value_t * const exports_p, size_t number_of_exports);

View File

@ -30,7 +30,7 @@ extern "C"
/**
* Jerry snapshot format version.
*/
#define JERRY_SNAPSHOT_VERSION (66u)
#define JERRY_SNAPSHOT_VERSION (67u)
/**
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.

View File

@ -555,6 +555,13 @@ typedef jerry_value_t (*jerry_module_resolve_callback_t) (const jerry_value_t sp
const jerry_value_t referrer,
void *user_p);
/**
* Callback which is called when an import is resolved dynamically to get the referenced module.
*/
typedef jerry_value_t (*jerry_module_import_callback_t) (const jerry_value_t specifier,
const jerry_value_t user_value,
void *user_p);
/**
* Callback which is called after the module enters into linked, evaluated or error state.
*/

View File

@ -152,6 +152,8 @@ struct jerry_context_t
jerry_module_state_changed_callback_t module_state_changed_callback_p; /**< callback which is called after the
* state of a module is changed */
void *module_state_changed_callback_user_p; /**< user pointer for module_state_changed_callback_p */
jerry_module_import_callback_t module_import_callback_p; /**< callback for dynamic module import */
void *module_import_callback_user_p; /**< user pointer for module_import_callback_p */
#endif /* JERRY_MODULE_SYSTEM */
vm_frame_ctx_t *vm_top_context_p; /**< top (current) interpreter context */

View File

@ -31,7 +31,7 @@ JERRY_STATIC_ASSERT (offsetof (cbc_uint8_arguments_t, script_value) == offsetof
*/
JERRY_STATIC_ASSERT (CBC_END == 238,
number_of_cbc_opcodes_changed);
JERRY_STATIC_ASSERT (CBC_EXT_END == 146,
JERRY_STATIC_ASSERT (CBC_EXT_END == 147,
number_of_cbc_ext_opcodes_changed);
#if JERRY_PARSER || JERRY_PARSER_DUMP_BYTE_CODE

View File

@ -598,6 +598,8 @@
VM_OC_COPY_FROM_ARG) \
CBC_OPCODE (CBC_EXT_PUSH_REST_OBJECT, CBC_NO_FLAG, 1, \
VM_OC_PUSH_REST_OBJECT) \
CBC_OPCODE (CBC_EXT_MODULE_IMPORT, CBC_NO_FLAG, 0, \
VM_OC_MODULE_IMPORT) \
CBC_OPCODE (CBC_EXT_STRING_CONCAT, CBC_NO_FLAG, -1, \
VM_OC_STRING_CONCAT | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL, CBC_HAS_LITERAL_ARG, 0, \

View File

@ -1929,6 +1929,16 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
break;
}
#endif /* JERRY_ESNEXT */
#if JERRY_MODULE_SYSTEM
case LEXER_KEYW_IMPORT:
{
if (new_was_seen)
{
parser_raise_error (context_p, PARSER_ERR_IMPORT_AFTER_NEW);
}
break;
}
#endif /* JERRY_MODULE_SYSTEM */
}
/* Bracketed expressions are primary expressions. At this
@ -2303,6 +2313,28 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
&& context_p->token.type != LEXER_COMMA);
}
#endif /* JERRY_ESNEXT */
#if JERRY_MODULE_SYSTEM
case LEXER_KEYW_IMPORT:
{
lexer_next_token (context_p);
if (context_p->token.type != LEXER_LEFT_PAREN)
{
parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED);
}
lexer_next_token (context_p);
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
if (context_p->token.type != LEXER_RIGHT_PAREN)
{
parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
}
parser_emit_cbc_ext (context_p, CBC_EXT_MODULE_IMPORT);
break;
}
#endif /* JERRY_MODULE_SYSTEM */
default:
{
bool is_left_hand_side = (*grouping_level_p == PARSE_EXPR_LEFT_HAND_SIDE);

View File

@ -2424,6 +2424,18 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_IMPORT);
JERRY_ASSERT (context_p->module_names_p == NULL);
if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
{
if (context_p->status_flags & PARSER_IS_FUNCTION)
{
parser_parse_expression_statement (context_p, PARSE_EXPR);
return;
}
parser_parse_block_expression (context_p, PARSE_EXPR);
return;
}
parser_module_check_request_place (context_p);
lexer_next_token (context_p);

View File

@ -1372,8 +1372,11 @@ parser_error_to_string (parser_error_t error) /**< error code */
{
return "Export not defined in module";
}
case PARSER_ERR_IMPORT_AFTER_NEW:
{
return "Module import call is not allowed after new";
}
#endif /* JERRY_MODULE_SYSTEM */
default:
{
JERRY_ASSERT (error == PARSER_ERR_NO_ERROR);

View File

@ -181,6 +181,7 @@ typedef enum
PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER, /**< duplicated export identifier name */
PARSER_ERR_DUPLICATED_IMPORT_BINDING, /**< duplicated import binding name */
PARSER_ERR_EXPORT_NOT_DEFINED, /**< export is not defined in module */
PARSER_ERR_IMPORT_AFTER_NEW, /**< module import call is not allowed after new */
#endif /* JERRY_MODULE_SYSTEM */
PARSER_ERR_NON_STRICT_ARG_DEFINITION /**< non-strict argument definition */

View File

@ -311,6 +311,20 @@ scanner_scan_primary_expression (parser_context_t *context_p, /**< context */
return SCAN_KEEP_TOKEN;
}
#endif /* JERRY_ESNEXT */
#if JERRY_MODULE_SYSTEM
case LEXER_KEYW_IMPORT:
{
lexer_next_token (context_p);
if (context_p->token.type != LEXER_LEFT_PAREN)
{
scanner_raise_error (context_p);
}
scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
return SCAN_KEEP_TOKEN;
}
#endif /* JERRY_MODULE_SYSTEM */
case LEXER_RIGHT_PAREN:
{
if (stack_top == SCAN_STACK_PAREN_EXPRESSION)
@ -1681,13 +1695,20 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
#if JERRY_MODULE_SYSTEM
case LEXER_KEYW_IMPORT:
{
lexer_next_token (context_p);
if (context_p->token.type == LEXER_LEFT_PAREN)
{
scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
return SCAN_KEEP_TOKEN;
}
if (stack_top != SCAN_STACK_SCRIPT)
{
scanner_raise_error (context_p);
}
scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
lexer_next_token (context_p);
if (context_p->token.type == LEXER_LITERAL
&& context_p->token.lit_location.type == LEXER_STRING_LITERAL)

View File

@ -4554,6 +4554,40 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
continue;
}
#if JERRY_MODULE_SYSTEM
case VM_OC_MODULE_IMPORT:
{
left_value = *(--stack_top_p);
ecma_value_t user_value = ECMA_VALUE_UNDEFINED;
ecma_value_t script_value = ((cbc_uint8_arguments_t *) bytecode_header_p)->script_value;
#if JERRY_SNAPSHOT_EXEC
if (JERRY_UNLIKELY (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)))
{
#endif /* JERRY_SNAPSHOT_EXEC */
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
if (CBC_SCRIPT_GET_TYPE (script_p) != CBC_SCRIPT_GENERIC)
{
user_value = ((cbc_script_user_t *) script_p)->user_value;
}
#if JERRY_SNAPSHOT_EXEC
}
#endif /* JERRY_SNAPSHOT_EXEC */
result = ecma_module_import (left_value, user_value);
ecma_free_value (left_value);
if (ECMA_IS_VALUE_ERROR (result))
{
goto error;
}
*stack_top_p++ = result;
continue;
}
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_DEBUGGER
case VM_OC_BREAKPOINT_ENABLED:
{

View File

@ -300,6 +300,10 @@ typedef enum
VM_OC_PUSH_STATIC_FIELD_FUNC, /**< push static field initializer function */
VM_OC_ADD_COMPUTED_FIELD, /**< add computed field name */
#endif /* JERRY_ESNEXT */
#if JERRY_MODULE_SYSTEM
VM_OC_MODULE_IMPORT, /**< module dynamic import */
#endif /* JERRY_MODULE_SYSTEM */
VM_OC_NONE, /**< a special opcode for unsupported byte codes */
} vm_oc_types;
@ -384,6 +388,9 @@ typedef enum
VM_OC_PUSH_STATIC_FIELD_FUNC = VM_OC_NONE, /**< push static field initializer function */
VM_OC_ADD_COMPUTED_FIELD = VM_OC_NONE, /**< add computed field name */
#endif /* !JERRY_ESNEXT */
#if !JERRY_MODULE_SYSTEM
VM_OC_MODULE_IMPORT = VM_OC_NONE, /**< module dynamic import */
#endif /* JERRY_MODULE_SYSTEM */
VM_OC_UNUSED = VM_OC_NONE /**< placeholder if the list is empty */
} vm_oc_unused_types;

View File

@ -0,0 +1,28 @@
/* 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.
*/
function check_syntax_error(code)
{
try {
eval(code);
assert(false);
} catch (e) {
assert(e instanceof SyntaxError);
}
}
check_syntax_error("import('a.mjs',4)");
check_syntax_error("(import('a.mjs',4))");
check_syntax_error("(import 'a.mjs')");

View File

@ -6318,8 +6318,6 @@
features: [dynamic-import]
https://github.com/tc39/proposal-dynamic-import
-->
<test id="language/expressions/dynamic-import/always-create-new-promise.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assign-expr-get-value-abrupt-throws.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/additive-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/array-literal.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/arrow-function.js"><reason></reason></test>
@ -6343,124 +6341,90 @@
<test id="language/expressions/dynamic-import/assignment-expression/tagged-function-call.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/ternary.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/this.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/unary-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/yield-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/yield-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/yield-identifier.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/assignment-expression/yield-star.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/await-import-evaluation.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-arrow-import-catch-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-arrow-import-catch-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-arrow-import-catch-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-arrow-import-catch-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-arrow-import-catch-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-arrow-import-catch-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-arrow-import-catch-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-return-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-return-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-return-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-return-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-return-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-return-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-return-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-function-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-import-catch-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-import-catch-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-import-catch-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-import-catch-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-import-catch-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-import-catch-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-import-catch-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-labeled-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-labeled-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-labeled-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-labeled-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-labeled-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-labeled-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-block-labeled-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-do-while-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-do-while-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-do-while-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-do-while-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-do-while-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-do-while-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-do-while-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-else-import-catch-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-else-import-catch-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-else-import-catch-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-else-import-catch-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-else-import-catch-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-else-import-catch-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-else-import-catch-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-function-import-catch-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-function-import-catch-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-function-import-catch-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-function-import-catch-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-function-import-catch-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-function-import-catch-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-function-import-catch-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-if-import-catch-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-if-import-catch-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-if-import-catch-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-if-import-catch-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-if-import-catch-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-if-import-catch-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-if-import-catch-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-while-import-catch-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-while-import-catch-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-while-import-catch-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-while-import-catch-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-while-import-catch-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-while-import-catch-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-while-import-catch-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/top-level-import-catch-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/top-level-import-catch-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/top-level-import-catch-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/top-level-import-catch-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/top-level-import-catch-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/top-level-import-catch-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/top-level-import-catch-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/custom-primitive.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/eval-export-dflt-cls-anon.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/eval-export-dflt-cls-name-meth.js"><reason></reason></test>
@ -6548,76 +6512,9 @@
<test id="language/expressions/dynamic-import/namespace/promise-then-ns-set-same-values-no-strict.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/namespace/promise-then-ns-set-same-values-strict.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/namespace/promise-then-ns-set-strict.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/returns-promise.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/reuse-namespace-object-from-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/reuse-namespace-object-from-script.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/reuse-namespace-object.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/callexpression-arguments.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/callexpression-templateliteral.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-arrow-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-arrow-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-arrow-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-await-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-await-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-await-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-function-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-block-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-block-labeled-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-block-labeled-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-block-labeled-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-block-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-block-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-do-while-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-do-while-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-do-while-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-else-braceless-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-else-braceless-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-else-braceless-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-else-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-else-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-else-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-function-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-function-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-function-return-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-function-return-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-function-return-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-function-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-if-braceless-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-if-braceless-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-if-braceless-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-if-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-if-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-if-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-while-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-while-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-while-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-with-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-with-expression-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-with-expression-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-with-expression-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-with-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-with-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/new-covered-expression-is-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/top-level-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/top-level-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/top-level-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/update-to-dynamic-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/usage-from-eval.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-eval-gtbndng-indirect-update-dflt.js"><reason></reason></test>
@ -7310,22 +7207,15 @@
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-rqstd-abrupt-typeerror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-rqstd-abrupt-urierror.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-script-code-target.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-file-does-not-exist.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-instn-iee-err-ambiguous-import.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-instn-iee-err-circular.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/catch/nested-async-gen-return-await-specifier-tostring-abrupt-rejects.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/for-await-resolution-and-error-agen-yield.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/for-await-resolution-and-error-agen.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-empty-str-is-valid-assign-expr.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-nested-imports.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-script-code-valid.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/usage/nested-async-gen-await-eval-gtbndng-indirect-update-dflt.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/usage/nested-async-gen-await-eval-gtbndng-indirect-update.js"><reason></reason></test>
<test id="language/expressions/dynamic-import/usage/nested-async-gen-await-eval-script-code-host-resolves-module-code.js"><reason></reason></test>

View File

@ -58,6 +58,7 @@ set(SOURCE_UNIT_TEST_MAIN_MODULES
test-lit-char-helpers.c
test-literal-storage.c
test-mem-stats.c
test-module-dynamic.c
test-module.c
test-native-callback-nested.c
test-native-instanceof.c

View File

@ -0,0 +1,279 @@
/* 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.
*/
#include "jerryscript.h"
#include "jerryscript-port.h"
#include "jerryscript-port-default.h"
#include "test-common.h"
static int mode = 0;
static jerry_value_t global_user_value;
static jerry_value_t
global_assert (const jerry_call_info_t *call_info_p, /**< call information */
const jerry_value_t args_p[], /**< arguments list */
const jerry_length_t args_cnt) /**< arguments length */
{
JERRY_UNUSED (call_info_p);
TEST_ASSERT (args_cnt == 1 && jerry_value_is_true (args_p[0]));
return jerry_create_boolean (true);
} /* global_assert */
static void
register_assert (void)
{
jerry_value_t global_object_value = jerry_get_global_object ();
jerry_value_t function_value = jerry_create_external_function (global_assert);
jerry_value_t function_name_value = jerry_create_string ((const jerry_char_t *) "assert");
jerry_value_t result_value = jerry_set_property (global_object_value, function_name_value, function_value);
jerry_release_value (function_name_value);
jerry_release_value (function_value);
jerry_release_value (global_object_value);
TEST_ASSERT (jerry_value_is_true (result_value));
jerry_release_value (result_value);
} /* register_assert */
static void
compare_specifier (jerry_value_t specifier, /* string value */
int id) /* module id */
{
jerry_char_t string[] = "XX_module.mjs";
TEST_ASSERT (id >= 1 && id <= 99 && string[0] == 'X' && string[1] == 'X');
string[0] = (jerry_char_t) ((id / 10) + '0');
string[1] = (jerry_char_t) ((id % 10) + '0');
jerry_size_t length = (jerry_size_t) (sizeof (string) - 1);
jerry_char_t buffer[sizeof (string) - 1];
TEST_ASSERT (jerry_value_is_string (specifier));
TEST_ASSERT (jerry_get_string_size (specifier) == length);
TEST_ASSERT (jerry_string_to_char_buffer (specifier, buffer, length) == length);
TEST_ASSERT (memcmp (buffer, string, length) == 0);
} /* compare_specifier */
static jerry_value_t
module_import_callback (const jerry_value_t specifier, /* string value */
const jerry_value_t user_value, /* user value assigned to the script */
void *user_p) /* user pointer */
{
TEST_ASSERT (user_p == (void *) &mode);
jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL,
user_value,
global_user_value);
TEST_ASSERT (jerry_value_is_true (compare_value));
jerry_release_value (compare_value);
switch (mode)
{
case 0:
{
compare_specifier (specifier, 1);
return jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) "Err01");
}
case 1:
{
compare_specifier (specifier, 2);
return jerry_create_null ();
}
case 2:
{
compare_specifier (specifier, 3);
jerry_value_t promise_value = jerry_create_promise ();
/* Normally this should be a namespace object. */
jerry_value_t object_value = jerry_create_object ();
jerry_resolve_or_reject_promise (promise_value, object_value, true);
jerry_release_value (object_value);
return promise_value;
}
}
TEST_ASSERT (mode == 3 || mode == 4);
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_MODULE;
jerry_value_t parse_result_value = jerry_parse ((const jerry_char_t *) "", 0, &parse_options);
TEST_ASSERT (!jerry_value_is_error (parse_result_value));
jerry_value_t result_value = jerry_module_link (parse_result_value, NULL, NULL);
TEST_ASSERT (!jerry_value_is_error (result_value));
jerry_release_value (result_value);
if (mode == 3)
{
result_value = jerry_module_evaluate (parse_result_value);
TEST_ASSERT (!jerry_value_is_error (result_value));
jerry_release_value (result_value);
}
return parse_result_value;
} /* module_import_callback */
static void
run_script (const char *source_p, /* source code */
jerry_parse_options_t *parse_options_p) /* parse options */
{
jerry_value_t parse_result_value;
parse_result_value = jerry_parse ((const jerry_char_t *) source_p, strlen (source_p), parse_options_p);
TEST_ASSERT (!jerry_value_is_error (parse_result_value));
jerry_value_t result_value;
if (parse_options_p->options & JERRY_PARSE_MODULE)
{
result_value = jerry_module_link (parse_result_value, NULL, NULL);
TEST_ASSERT (!jerry_value_is_error (result_value));
jerry_release_value (result_value);
result_value = jerry_module_evaluate (parse_result_value);
}
else
{
result_value = jerry_run (parse_result_value);
}
jerry_release_value (parse_result_value);
TEST_ASSERT (!jerry_value_is_error (result_value));
jerry_release_value (result_value);
result_value = jerry_run_all_enqueued_jobs ();
TEST_ASSERT (!jerry_value_is_error (result_value));
jerry_release_value (result_value);
} /* run_script */
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
if (!jerry_is_feature_enabled (JERRY_FEATURE_MODULE))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Module is disabled!\n");
jerry_cleanup ();
return 0;
}
register_assert ();
jerry_module_set_import_callback (module_import_callback, (void *) &mode);
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_NO_OPTS;
if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES))
{
run_script ("var expected_message = 'Module cannot be instantiated'", &parse_options);
}
else
{
run_script ("var expected_message = ''", &parse_options);
}
global_user_value = jerry_create_object ();
const char *source_p = TEST_STRING_LITERAL ("import('01_module.mjs').then(\n"
" function(resolve) { assert(false) },\n"
" function(reject) {\n"
" assert(reject instanceof RangeError\n"
" && reject.message === 'Err01')\n"
" }\n"
")");
mode = 0;
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
parse_options.user_value = global_user_value;
run_script (source_p, &parse_options);
jerry_release_value (global_user_value);
global_user_value = jerry_create_null ();
source_p = TEST_STRING_LITERAL ("var src = \"import('02_module.mjs').then(\\\n"
" function(resolve) { assert(false) },\\\n"
" function(reject) {\\\n"
" assert(reject instanceof RangeError\\\n"
" && reject.message === expected_message)\\\n"
" }\\\n"
")\"\n"
"eval('eval(src)')");
mode = 1;
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
parse_options.user_value = global_user_value;
run_script (source_p, &parse_options);
jerry_release_value (global_user_value);
global_user_value = jerry_create_number (5.6);
source_p = TEST_STRING_LITERAL ("function f() {\n"
" return function () {\n"
" return import('03_module.mjs')\n"
" }\n"
"}\n"
"export var a = f()().then(\n"
" function(resolve) { assert(typeof resolve == 'object') },\n"
" function(reject) { assert(false) }\n"
")");
mode = 2;
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE;
parse_options.user_value = global_user_value;
run_script (source_p, &parse_options);
jerry_release_value (global_user_value);
global_user_value = jerry_create_string ((const jerry_char_t *) "Any string...");
source_p = TEST_STRING_LITERAL ("var src = \"import('02_module.mjs').then(\\\n"
" function(resolve) { assert(typeof resolve == 'object') },\\\n"
" function(reject) { assert(false) }\\\n"
")\"\n"
"function f() {\n"
" eval('(function() { return eval(src) })()')\n"
"}\n"
"f()\n");
mode = 3;
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
parse_options.user_value = global_user_value;
run_script (source_p, &parse_options);
jerry_release_value (global_user_value);
global_user_value = jerry_create_external_function (global_assert);
source_p = TEST_STRING_LITERAL ("var src = \"import('02_module.mjs').then(\\\n"
" function(resolve) { assert(false) },\\\n"
" function(reject) {\\\n"
" assert(reject instanceof RangeError\\\n"
" && reject.message === expected_message)\\\n"
" }\\\n"
")\"\n"
"export function f() {\n"
" eval('(function() { return eval(src) })()')\n"
"}\n"
"f()\n");
mode = 4;
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE;
parse_options.user_value = global_user_value;
run_script (source_p, &parse_options);
jerry_release_value (global_user_value);
jerry_cleanup ();
return 0;
} /* main */