Rework module linking (#4632)

The module linking process from jerry_parse is moved out into
a new jerry_module_link function, and jerry_parse is limited to
create unlinked modules.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2021-03-30 15:40:09 +02:00
committed by GitHub
parent 874a6a49d5
commit 6c484f3529
22 changed files with 1574 additions and 789 deletions
+121
View File
@@ -747,6 +747,37 @@ typedef void (*jerry_error_object_created_callback_t) (const jerry_value_t error
- [jerry_set_error_object_created_callback](#jerry_set_error_object_created_callback)
## jerry_module_resolve_callback_t
**Summary**
Callback which is called by [jerry_module_link](#jerry_module_link) to get the referenced module.
*Note*:
- 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_resolve_callback_t) (const jerry_value_t specifier,
const jerry_value_t referrer,
void *user_p);
```
- `specifier` - a module specifier string (usually used as a path to the module)
- `referrer` - a module object which contains the `specifier` in its source code
- `user_p` - pointer passed to [jerry_module_link](#jerry_module_link).
- return value
- a module object - if it can be resolved successfully
- an error - otherwise
*New in version [[NEXT_RELEASE]]*.
**See also**
- [jerry_module_link](#jerry_module_link)
- [jerry_get_global_object](#jerry_get_global_object)
## jerry_backtrace_callback_t
**Summary**
@@ -4244,6 +4275,96 @@ jerry_value_as_uint32 (const jerry_value_t value);
}
```
# Functions for module objects
These APIs all depend on module support.
## jerry_module_link
**Summary**
Link modules to their dependencies. The dependencies are resolved by a user callback.
*Notes*:
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
- 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).
**Prototype**
```c
jerry_value_t jerry_module_link (const jerry_value_t module_val,
jerry_module_resolve_callback_t callback, void *user_p)
```
- `module_val` - module object in unlinked state
- `callback` - user callback which is called to resolve dependencies,
uses `jerry_port_module_resolve` when NULL is passed
- `user_p` - user pointer passed to the callback
- return
- true - if linking is successful
- error - otherwise
*New in version [[NEXT_RELEASE]]*.
**Example**
[doctest]: # (test="compile")
```c
#include <jerryscript.h>
static jerry_value_t
module_resolve_callback (const jerry_value_t specifier,
const jerry_value_t referrer,
void *user_data_p)
{
/* In this case, the specifier contains 'b.mjs', and the referrer is the module
* created in the main() function below. Normally the specifier string should be
* extended to a full file system path, and it should be checked whether a module
* corresponding to this path has been loaded already. For simplicity, this function
* returns with a new module. */
const jerry_char_t script[] = "export var a = 5";
const jerry_char_t file[] = "b.mjs";
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_RESOURCE;
parse_options.resource_name_p = file;
parse_options.resource_name_length = sizeof (file) - 1;
return jerry_parse (script, sizeof (script) - 1, &parse_options);
} /* module_resolve_callback */
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
const jerry_char_t script[] = "import a from 'b.mjs'";
const jerry_char_t file[] = "a.mjs";
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_RESOURCE;
parse_options.resource_name_p = file;
parse_options.resource_name_length = sizeof (file) - 1;
jerry_value_t ret_value = jerry_parse (script, sizeof (script) - 1, &parse_options);
jerry_module_link (ret_value, module_resolve_callback, NULL);
jerry_release_value (ret_value);
jerry_cleanup ();
return 0;
}
```
**See also**
- [jerry_module_resolve_callback_t](#jerry_module_resolve_callback_t)
# Functions for promise objects
These APIs all depend on the es.next profile (or on some build options).