From d8d5c2a9add5a16b9964371c017b22d941dd0696 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sun, 25 Mar 2018 20:13:54 -0700 Subject: [PATCH 1/5] repl: hide top-level await feature behind a flag Refs: https://github.com/nodejs/node/pull/17807 Refs: https://github.com/nodejs/node/pull/15566#issuecomment-353428430 --- doc/api/repl.md | 19 +++++++++++++++++++ lib/repl.js | 10 ++++++++-- src/node.cc | 12 ++++++++++++ src/node_config.cc | 3 +++ src/node_internals.h | 5 +++++ test/parallel/test-repl-top-level-await.js | 2 +- 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/doc/api/repl.md b/doc/api/repl.md index 46f3e1e0acb509..26a33af21ffe19 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -179,6 +179,25 @@ Error: foo 'foo' ``` +#### `await` keyword + +With the `--experimental-repl-await` command line option specified, +experimental support for the `await` keyword is enabled. + + +```js +> await Promise.resolve(123) +123 +> await Promise.reject(new Error('REPL await')) +Error: REPL await + at repl:1:45 +> timeout = util.promisify(setTimeout) +[Function] +> old = Date.now(); await timeout(1000); console.log(Date.now() - old); +1002 +undefined +``` + ### Custom Evaluation Functions When a new `repl.REPLServer` is created, a custom evaluation function may be diff --git a/lib/repl.js b/lib/repl.js index 06703da131c301..c7ddff48a3c23a 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -47,7 +47,6 @@ const { makeRequireFunction, addBuiltinLibsToObject } = require('internal/modules/cjs/helpers'); -const { processTopLevelAwait } = require('internal/repl/await'); const internalUtil = require('internal/util'); const { isTypedArray } = require('internal/util/types'); const util = require('util'); @@ -69,6 +68,10 @@ const { ERR_SCRIPT_EXECUTION_INTERRUPTED } = require('internal/errors').codes; const { sendInspectorCommand } = require('internal/util/inspector'); +const { experimentalREPLAwait } = process.binding('config'); + +// Lazy-loaded. +let processTopLevelAwait; const parentModule = module; const replMap = new WeakMap(); @@ -226,7 +229,10 @@ function REPLServer(prompt, wrappedCmd = true; } - if (code.includes('await')) { + if (experimentalREPLAwait && code.includes('await')) { + if (processTopLevelAwait === undefined) + ({ processTopLevelAwait } = require('internal/repl/await')); + const potentialWrappedCode = processTopLevelAwait(code); if (potentialWrappedCode !== null) { code = potentialWrappedCode; diff --git a/src/node.cc b/src/node.cc index 6f946ab3ad1cc7..462728c4af358a 100644 --- a/src/node.cc +++ b/src/node.cc @@ -244,6 +244,11 @@ bool config_experimental_modules = false; // that is used by lib/vm.js bool config_experimental_vm_modules = false; +// Set in node.cc by ParseArgs when --experimental-repl-await is used. +// Used in node_config.cc to set a constant on process.binding('config') +// that is used by lib/repl.js. +bool config_experimental_repl_await = false; + // Set in node.cc by ParseArgs when --loader is used. // Used in node_config.cc to set a constant on process.binding('config') // that is used by lib/internal/bootstrap/node.js @@ -3468,6 +3473,10 @@ static void PrintHelp() { #if defined(NODE_HAVE_I18N_SUPPORT) " --experimental-modules experimental ES Module support\n" " and caching modules\n" +#endif // defined(NODE_HAVE_I18N_SUPPORT) + " --experimental-repl-await experimental await keyword support\n" + " in REPL\n" +#if defined(NODE_HAVE_I18N_SUPPORT) " --experimental-vm-modules experimental ES Module support\n" " in vm module\n" #endif // defined(NODE_HAVE_I18N_SUPPORT) @@ -3627,6 +3636,7 @@ static void CheckIfAllowedInEnv(const char* exe, bool is_env, // Node options, sorted in `node --help` order for ease of comparison. "--enable-fips", "--experimental-modules", + "--experimental-repl-await", "--experimental-vm-modules", "--expose-http2", // keep as a non-op through v9.x "--force-fips", @@ -3823,6 +3833,8 @@ static void ParseArgs(int* argc, new_v8_argc += 1; } else if (strcmp(arg, "--experimental-vm-modules") == 0) { config_experimental_vm_modules = true; + } else if (strcmp(arg, "--experimental-repl-await") == 0) { + config_experimental_repl_await = true; } else if (strcmp(arg, "--loader") == 0) { const char* module = argv[index + 1]; if (!config_experimental_modules) { diff --git a/src/node_config.cc b/src/node_config.cc index 0542bff1d65186..35ac019c53df11 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -85,6 +85,9 @@ static void Initialize(Local target, if (config_experimental_vm_modules) READONLY_BOOLEAN_PROPERTY("experimentalVMModules"); + if (config_experimental_repl_await) + READONLY_BOOLEAN_PROPERTY("experimentalREPLAwait"); + if (config_pending_deprecation) READONLY_BOOLEAN_PROPERTY("pendingDeprecation"); diff --git a/src/node_internals.h b/src/node_internals.h index 8cc1aa1a8fec40..492a36296fb498 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -181,6 +181,11 @@ extern bool config_experimental_modules; // that is used by lib/vm.js extern bool config_experimental_vm_modules; +// Set in node.cc by ParseArgs when --experimental-repl-await is used. +// Used in node_config.cc to set a constant on process.binding('config') +// that is used by lib/repl.js. +extern bool config_experimental_repl_await; + // Set in node.cc by ParseArgs when --loader is used. // Used in node_config.cc to set a constant on process.binding('config') // that is used by lib/internal/bootstrap/node.js diff --git a/test/parallel/test-repl-top-level-await.js b/test/parallel/test-repl-top-level-await.js index a7edb66a81a1f8..91f5758c210a36 100644 --- a/test/parallel/test-repl-top-level-await.js +++ b/test/parallel/test-repl-top-level-await.js @@ -7,7 +7,7 @@ const repl = require('repl'); common.crashOnUnhandledRejection(); -// Flags: --expose-internals +// Flags: --expose-internals --experimental-repl-await const PROMPT = 'await repl > '; From ce1f2d54542f1535b93338f34ae070900ff86985 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sat, 14 Apr 2018 16:21:35 -0700 Subject: [PATCH 2/5] fixup! repl: hide top-level await feature behind a flag --- doc/api/repl.md | 4 ++-- lib/repl.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/repl.md b/doc/api/repl.md index 26a33af21ffe19..00366071eba64d 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -191,9 +191,9 @@ experimental support for the `await` keyword is enabled. > await Promise.reject(new Error('REPL await')) Error: REPL await at repl:1:45 -> timeout = util.promisify(setTimeout) +> const timeout = util.promisify(setTimeout) [Function] -> old = Date.now(); await timeout(1000); console.log(Date.now() - old); +> const old = Date.now(); await timeout(1000); console.log(Date.now() - old); 1002 undefined ``` diff --git a/lib/repl.js b/lib/repl.js index c7ddff48a3c23a..37bb0d72011c52 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -231,7 +231,7 @@ function REPLServer(prompt, if (experimentalREPLAwait && code.includes('await')) { if (processTopLevelAwait === undefined) - ({ processTopLevelAwait } = require('internal/repl/await')); + ;({ processTopLevelAwait } = require('internal/repl/await')); const potentialWrappedCode = processTopLevelAwait(code); if (potentialWrappedCode !== null) { From 7dfd6607657a5a5498016ad5f0b0fbadabf512f2 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sat, 14 Apr 2018 16:23:43 -0700 Subject: [PATCH 3/5] fixup! repl: hide top-level await feature behind a flag --- doc/api/repl.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/repl.md b/doc/api/repl.md index 00366071eba64d..3a5134d1e24c0e 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -191,8 +191,8 @@ experimental support for the `await` keyword is enabled. > await Promise.reject(new Error('REPL await')) Error: REPL await at repl:1:45 -> const timeout = util.promisify(setTimeout) -[Function] +> const timeout = util.promisify(setTimeout); +undefined > const old = Date.now(); await timeout(1000); console.log(Date.now() - old); 1002 undefined From 96206f9591baf61c182cad884476539780e93a54 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sat, 14 Apr 2018 16:24:18 -0700 Subject: [PATCH 4/5] fixup! fixup! repl: hide top-level await feature behind a flag --- lib/repl.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/repl.js b/lib/repl.js index 37bb0d72011c52..c9f531384f9872 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -230,8 +230,9 @@ function REPLServer(prompt, } if (experimentalREPLAwait && code.includes('await')) { - if (processTopLevelAwait === undefined) + if (processTopLevelAwait === undefined) { ;({ processTopLevelAwait } = require('internal/repl/await')); + } const potentialWrappedCode = processTopLevelAwait(code); if (potentialWrappedCode !== null) { From 45d2205d133aafdc61665eeba0a4234931795962 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sat, 14 Apr 2018 16:40:23 -0700 Subject: [PATCH 5/5] fixup! fixup! repl: hide top-level await feature behind a flag --- lib/repl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/repl.js b/lib/repl.js index c9f531384f9872..a7977dc72fb781 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -231,7 +231,7 @@ function REPLServer(prompt, if (experimentalREPLAwait && code.includes('await')) { if (processTopLevelAwait === undefined) { - ;({ processTopLevelAwait } = require('internal/repl/await')); + ({ processTopLevelAwait } = require('internal/repl/await')); } const potentialWrappedCode = processTopLevelAwait(code);