support top-level await (#5487)

This commit is contained in:
Alex Lam S.L
2022-06-06 04:52:01 +01:00
committed by GitHub
parent 25441d44f6
commit d2bd0d1c1c
3 changed files with 22 additions and 9 deletions

View File

@@ -519,7 +519,8 @@ if (result.error) throw result.error;
Pass an object to specify custom [mangle property options](#mangle-properties-options). Pass an object to specify custom [mangle property options](#mangle-properties-options).
- `module` (default: `false`) — set to `true` if you wish to process input as - `module` (default: `false`) — set to `true` if you wish to process input as
ES module, i.e. implicit `"use strict";` alongside with `toplevel` enabled. ES module, i.e. implicit `"use strict";` and support for top-level `await`,
alongside with `toplevel` enabled.
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously - `nameCache` (default: `null`) — pass an empty object `{}` or a previously
used `nameCache` object if you wish to cache mangled variable and used `nameCache` object if you wish to cache mangled variable and
@@ -632,7 +633,13 @@ to be `false` and all symbol names will be omitted.
- `bare_returns` (default: `false`) — support top level `return` statements - `bare_returns` (default: `false`) — support top level `return` statements
- `html5_comments` (default: `true`) - `expression` (default: `false`) — parse as a single expression, e.g. JSON
- `html5_comments` (default: `true`) — process HTML comment as workaround for
browsers which do not recognise `<script>` tags
- `module` (default: `false`) — set to `true` if you wish to process input as
ES module, i.e. implicit `"use strict";` and support for top-level `await`.
- `shebang` (default: `true`) — support `#!command` as the first line - `shebang` (default: `true`) — support `#!command` as the first line
@@ -1415,9 +1422,10 @@ To allow for better optimizations, the compiler makes various assumptions:
function f() { function f() {
throw 42; throw 42;
} }
} catch (e) {} } catch (e) {
console.log(typeof f); console.log(typeof f, e);
// Expected: "function" }
// Actual: "undefined" // Expected: "function 42"
// Actual: "undefined 42"
``` ```
UglifyJS may modify the input which in turn may suppress those errors. UglifyJS may modify the input which in turn may suppress those errors.

View File

@@ -2541,7 +2541,10 @@ function parse($TEXT, options) {
return function() { return function() {
var start = S.token; var start = S.token;
var body = []; var body = [];
if (options.module) S.input.add_directive("use strict"); if (options.module) {
S.in_async = true;
S.input.add_directive("use strict");
}
S.input.push_directives_stack(); S.input.push_directives_stack();
while (!is("eof")) while (!is("eof"))
body.push(statement()); body.push(statement());

View File

@@ -405,7 +405,7 @@ function createTopLevelCode() {
unique_vars.length = 0; unique_vars.length = 0;
classes.length = 0; classes.length = 0;
allow_this = true; allow_this = true;
async = false; async = SUPPORT.async && rng(200) == 0;
has_await = false; has_await = false;
export_default = false; export_default = false;
generator = false; generator = false;
@@ -413,7 +413,7 @@ function createTopLevelCode() {
funcs = 0; funcs = 0;
clazz = 0; clazz = 0;
imports = 0; imports = 0;
in_class = 0; in_class = async;
called = Object.create(null); called = Object.create(null);
var s = [ var s = [
strictMode(), strictMode(),
@@ -2087,6 +2087,7 @@ if (require.main !== module) {
} }
function run_code(code, toplevel, timeout) { function run_code(code, toplevel, timeout) {
if (async && has_await) code = "(async function(){\n" + code + "\n})();";
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout); return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
} }
@@ -2502,6 +2503,7 @@ for (var round = 1; round <= num_iterations; round++) {
minify_options.forEach(function(options) { minify_options.forEach(function(options) {
var o = JSON.parse(options); var o = JSON.parse(options);
var toplevel = sandbox.has_toplevel(o); var toplevel = sandbox.has_toplevel(o);
if (async && has_await) o.parse = { module: true };
o.validate = true; o.validate = true;
uglify_code = UglifyJS.minify(original_code, o); uglify_code = UglifyJS.minify(original_code, o);
original_result = orig_result[toplevel ? 1 : 0]; original_result = orig_result[toplevel ? 1 : 0];