-
Notifications
You must be signed in to change notification settings - Fork 682
Implement ES2015 module system #2599
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement ES2015 module system #2599
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, please add the missing:
- Function
- Function argument
- Structure
- Structure member
documentations.
Also, please try the avoid the layer violations and please use the JERRY_ASSERT
macro to ensure prerequisites at certain points.
@@ -308,7 +313,8 @@ parser_parse_enclosed_expr (parser_context_t *context_p) /**< context */ | |||
* Parse var statement. | |||
*/ | |||
static void | |||
parser_parse_var_statement (parser_context_t *context_p) /**< context */ | |||
parser_parse_var_statement (parser_context_t *context_p, /**< context */ | |||
lexer_literal_t *variable_name) /**< variable name */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we return with that value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (informal)
docs/14.MODULE-SYSTEM.md
Outdated
# ES6 module support for JerryScript | ||
|
||
The module system allows users to write import and export statements in scripts. Therefore the logic of the application could be separated in custom modules. | ||
The standard's relevant part can be found [here]( https://www.ecma-international.org/ecma-262/6.0/#sec-modules). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 space before http
jerry-core/config.h
Outdated
@@ -50,6 +50,12 @@ | |||
# define CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN | |||
#endif /* CONFIG_DISABLE_ES2015 */ | |||
|
|||
#if (defined (CONFIG_DISABLE_ES2015) || !defined (JERRY_ENABLE_MODULE_SYSTEM)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add this to the ifdef CONFIG_DISABLE_ES2015 above.
jerry-core/module/module.c
Outdated
for (uint16_t i = 0; i < export_node_p->module_request_count; i++) | ||
{ | ||
parser_module_names_t *next_p = current_p->next_p; | ||
ecma_string_t *import_name_p = ecma_new_ecma_string_from_utf8 (current_p->local_name.value_p, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these not strings? Magic strings could be used and no conversion would be needed here.
JERRY_ASSERT (lex_env_p != NULL); | ||
JERRY_ASSERT (ecma_is_lexical_environment (lex_env_p)); | ||
|
||
ecma_module_lex_envs_t *new_wrapper_p; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new_module_lex_env.
typedef struct parser_module_names | ||
{ | ||
parser_module_utf8_string_t import_name; /**< local name of the import - export item */ | ||
parser_module_utf8_string_t local_name; /**< import name of the import - export item */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a local->import map? If yes, what about using objects for this (for faster property search).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your review, I’ve updated the patch.
import { a as b } from 'module.js';
If a specific module (module.js
) has been run, its lexical environment is being checked. If that lexical environment contains a property with the given name (a
), then a new property is created in the parent context with the imported name (b
) and assigned with the value of a
.
If objects are being used for the local name -> import name mapping, the key should be the module path. This object should contain as many key-value pairs as many import items were in the import statement.
I think in this scenario objects won’t worth it, because we now have 1 property search per import item (in the lexical environment), then we should have min. 2 (in the object too).
jerry-core/parser/js/js-parser.h
Outdated
@@ -90,6 +90,8 @@ typedef enum | |||
PARSER_ERR_LEFT_BRACE_EXPECTED, /**< left brace expected */ | |||
PARSER_ERR_RIGHT_PAREN_EXPECTED, /**< right paren expected */ | |||
PARSER_ERR_RIGHT_SQUARE_EXPECTED, /**< right square expected */ | |||
PARSER_ERR_LEFT_PAREN_MULTIPLY_LITERAL_EXPECTED, /**< left paren or multiply or literal expected */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this module specific?
|
||
if (current_p != NULL && current_length == import_name_p->prop.length) | ||
{ | ||
if (memcmp (current_p, import_name_p->u.char_p, current_length) == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge these two if
statements
while (stored_imports != NULL) | ||
{ | ||
if (stored_imports->script_path.length == module_node_p->script_path.length | ||
&& memcmp (stored_imports->script_path.value_p, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong indentation
bool is_import_item) /**< given item is import item */ | ||
{ | ||
if (is_import_item && | ||
parser_module_check_for_duplicates (context_p, module_node_p, import_name_p)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move &&
to this line
|
||
parser_module_context_t *parent_context_p = JERRY_CONTEXT (module_top_context_p); | ||
if ((parent_context_p == NULL || parent_context_p->exports_p == NULL || parent_context_p->imports_p == NULL) | ||
&& module_context_p->exports_p != NULL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong indentation
|
||
if (context_p->token.type == LEXER_RIGHT_BRACE | ||
|| (context_p->token.type == LEXER_LITERAL | ||
&& lexer_compare_raw_identifier_to_current (context_p, "from", 4))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong indentation
jerry-port/default/default-io.c
Outdated
* @return the source of the file | ||
*/ | ||
uint8_t * | ||
jerry_port_module_read_source (const char *file_name_p, /**< file name */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation update is missing for the new port API functions. BTW, why are these needed? Might be better to put the port API changes into a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review, I’ve updated the port API documentation. The port functions are necessary for the modules, because without these Jerry could not open custom files (source files). For this reason, the changes can’t be separated into another PR.
|
||
int request_count = exports_p->module_request_count + module_node_p->module_request_count; | ||
|
||
if (request_count < MAX_IMPORT_COUNT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ((uint16_t) request_count < MAX_IMPORT_COUNT) // error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
stored_imports->module_names_p = module_node_p->module_names_p; | ||
|
||
int request_count = stored_imports->module_request_count + module_node_p->module_request_count; | ||
if (request_count < MAX_IMPORT_COUNT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ((uint16_t) request_count < MAX_IMPORT_COUNT) // error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
Other notes:
|
Thank you @rtakacs for your review. I've moved and renamed the The paths in the test files are adjusted to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only minor changes. Good for a first patch.
jerry-core/ecma/base/ecma-module.c
Outdated
size_t path_size, /**< length of the path */ | ||
const char *source_p, /**< module source */ | ||
size_t source_size, /**< length of the source */ | ||
parser_module_node_t *module_node_p) /**< module node */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misaligned arguments
jerry-core/ecma/base/ecma-module.c
Outdated
path_length, | ||
(const char *) buffer_p, | ||
size, | ||
current_p); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto. Please fix all of them.
JerryScript-DCO-1.0-Signed-off-by: Daniel Vince vinced@inf.u-szeged.hu
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This patch is the first part of the ES2015 module system implementation.
The language specification can be found here
The implemented feature is documented here
JerryScript-DCO-1.0-Signed-off-by: Daniel Vince vinced@inf.u-szeged.hu