Navigation Menu

Skip to content

Commit

Permalink
module: unflag Top-Level Await
Browse files Browse the repository at this point in the history
This unflags Top-Level await so it can be used by default in the module
goal. This is accomplished by manually setting the
--harmony-top-level-await flag. We are allowing this as a one of
approval based on circumstances. It is not a precedent that future
harmony features will be manually enabled.

Refs: #34551

PR-URL: #34558
Reviewed-By: Mary Marchini <oss@mmarchini.me>
Reviewed-By: Zeyu Yang <himself65@outlook.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
  • Loading branch information
MylesBorins committed Aug 3, 2020
1 parent 8d8090b commit 54746bb
Show file tree
Hide file tree
Showing 14 changed files with 33 additions and 28 deletions.
10 changes: 0 additions & 10 deletions doc/api/cli.md
Expand Up @@ -253,16 +253,6 @@ the ability to import a directory that has an index file.

Please see [customizing ESM specifier resolution][] for example usage.

### `--experimental-top-level-await`
<!-- YAML
added: v14.3.0
-->

Enable experimental top-level `await` keyword support, available only in ES
module scripts.

(See also `--experimental-repl-await`.)

### `--experimental-vm-modules`
<!-- YAML
added: v9.6.0
Expand Down
8 changes: 3 additions & 5 deletions doc/api/esm.md
Expand Up @@ -1146,9 +1146,8 @@ would provide the exports interface for the instantiation of `module.wasm`.
## Experimental top-level `await`
When the `--experimental-top-level-await` flag is provided, `await` may be used
in the top level (outside of async functions) within modules. This implements
the [ECMAScript Top-Level `await` proposal][].
The `await` keyword may be used in the top level (outside of async functions)
within modules as per the [ECMAScript Top-Level `await` proposal][].
Assuming an `a.mjs` with
Expand All @@ -1166,8 +1165,7 @@ console.log(five); // Logs `5`
```
```bash
node b.mjs # fails
node --experimental-top-level-await b.mjs # works
node b.mjs # works
```
## Experimental loaders
Expand Down
3 changes: 0 additions & 3 deletions doc/node.1
Expand Up @@ -157,9 +157,6 @@ keyword support in REPL.
.It Fl -experimental-specifier-resolution
Select extension resolution algorithm for ES Modules; either 'explicit' (default) or 'node'
.
.It Fl -experimental-top-level-await
Enable experimental top-level await support in ES modules.
.
.It Fl -experimental-vm-modules
Enable experimental ES module support in VM module.
.
Expand Down
7 changes: 7 additions & 0 deletions src/node.cc
Expand Up @@ -773,6 +773,13 @@ int ProcessGlobalArgs(std::vector<std::string>* args,
return 12;
}

// TODO(mylesborins): remove this when the harmony-top-level-await flag
// is removed in V8
if (std::find(v8_args.begin(), v8_args.end(),
"--no-harmony-top-level-await") == v8_args.end()) {
v8_args.push_back("--harmony-top-level-await");
}

auto env_opts = per_process::cli_options->per_isolate->per_env;
if (std::find(v8_args.begin(), v8_args.end(),
"--abort-on-uncaught-exception") != v8_args.end() ||
Expand Down
3 changes: 2 additions & 1 deletion src/node_options.cc
Expand Up @@ -615,12 +615,13 @@ PerIsolateOptionsParser::PerIsolateOptionsParser(
Implies("--report-signal", "--report-on-signal");

AddOption("--experimental-top-level-await",
"enable experimental support for ECMAScript Top-Level Await",
"",
&PerIsolateOptions::experimental_top_level_await,
kAllowedInEnvironment);
AddOption("--harmony-top-level-await", "", V8Option{});
Implies("--experimental-top-level-await", "--harmony-top-level-await");
Implies("--harmony-top-level-await", "--experimental-top-level-await");
ImpliesNot("--no-harmony-top-level-await", "--experimental-top-level-await");

Insert(eop, &PerIsolateOptions::get_per_env_options);
}
Expand Down
2 changes: 1 addition & 1 deletion src/node_options.h
Expand Up @@ -188,7 +188,7 @@ class PerIsolateOptions : public Options {
bool no_node_snapshot = false;
bool report_uncaught_exception = false;
bool report_on_signal = false;
bool experimental_top_level_await = false;
bool experimental_top_level_await = true;
std::string report_signal = "SIGUSR2";
inline EnvironmentOptions* get_per_env_options();
void CheckOptions(std::vector<std::string>* errors) override;
Expand Down
2 changes: 0 additions & 2 deletions test/es-module/test-esm-tla.mjs
@@ -1,5 +1,3 @@
// Flags: --experimental-top-level-await

import '../common/index.mjs';
import fixtures from '../common/fixtures.js';
import assert from 'assert';
Expand Down
2 changes: 2 additions & 0 deletions test/message/esm_display_syntax_error.mjs
@@ -1,2 +1,4 @@
// Flags: --no-harmony-top-level-await

'use strict';
await async () => 0;
2 changes: 1 addition & 1 deletion test/message/esm_display_syntax_error.out
@@ -1,4 +1,4 @@
file:///*/test/message/esm_display_syntax_error.mjs:2
file:///*/test/message/esm_display_syntax_error.mjs:4
await async () => 0;
^^^^^

Expand Down
4 changes: 2 additions & 2 deletions test/message/esm_display_syntax_error_module.out
@@ -1,6 +1,6 @@
file:///*/test/fixtures/es-module-loaders/syntax-error.mjs:2
await async () => 0;
^^^^^
^^^^^^^^^^^^^

SyntaxError: Unexpected reserved word
SyntaxError: Malformed arrow function parameter list
at Loader.moduleStrategy (internal/modules/esm/translators.js:*:*)
4 changes: 2 additions & 2 deletions test/message/esm_loader_syntax_error.out
Expand Up @@ -2,8 +2,8 @@
(Use `node --trace-warnings ...` to show where the warning was created)
file://*/test/fixtures/es-module-loaders/syntax-error.mjs:2
await async () => 0;
^^^^^
^^^^^^^^^^^^^

SyntaxError: Unexpected reserved word
SyntaxError: Malformed arrow function parameter list
at Loader.moduleStrategy (internal/modules/esm/translators.js:*:*)
at async link (internal/modules/esm/module_job.js:*:*)
2 changes: 1 addition & 1 deletion test/parallel/test-cli-node-options.js
Expand Up @@ -79,7 +79,7 @@ if (!['arm', 'arm64'].includes(process.arch))
expect('--interpreted-frames-native-stack', 'B\n');

// Workers can't eval as ES Modules. https://github.com/nodejs/node/issues/30682
expectNoWorker('--experimental-top-level-await --input-type=module',
expectNoWorker('--input-type=module',
'B\n', 'console.log(await "B")');

function expectNoWorker(opt, want, command, wantsError) {
Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-no-harmony-top-level-await.mjs
@@ -0,0 +1,11 @@
// Flags: --no-harmony-top-level-await

import {
mustCall,
disableCrashOnUnhandledRejection
} from '../common/index.mjs';

disableCrashOnUnhandledRejection();

process.on('unhandledRejection', mustCall());
Promise.reject(new Error('should not be fatal error'));
1 change: 1 addition & 0 deletions tools/code_cache/mkcodecache.cc
Expand Up @@ -27,6 +27,7 @@ int main(int argc, char* argv[]) {
#endif // _WIN32

v8::V8::SetFlagsFromString("--random_seed=42");
v8::V8::SetFlagsFromString("--harmony-top-level-await");

if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <path/to/output.cc>\n";
Expand Down

2 comments on commit 54746bb

@quiquelhappy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@aherstein
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

Please sign in to comment.