[Pkg-javascript-commits] [uglifyjs] 113/491: introduce `unsafe_Func` (#2033)
Jonas Smedegaard
dr at jones.dk
Wed Feb 14 19:51:27 UTC 2018
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.
commit e9645e017f297e06506cc139922ff012fb763139
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Wed May 31 03:38:00 2017 +0800
introduce `unsafe_Func` (#2033)
Separate flag for #203 functionality.
---
README.md | 2 +
bin/uglifyjs | 2 +-
lib/compress.js | 115 +++++++++++++++++++++++----------------------
test/compress/functions.js | 22 +++++++++
4 files changed, 83 insertions(+), 58 deletions(-)
diff --git a/README.md b/README.md
index d7e65b2..d9a0162 100644
--- a/README.md
+++ b/README.md
@@ -572,6 +572,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
comparison are switching. Compression only works if both `comparisons` and
`unsafe_comps` are both set to true.
+- `unsafe_Func` (default: false) -- compress and mangle `Function(args, code)`.
+
- `unsafe_math` (default: false) -- optimize numerical expressions like
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
diff --git a/bin/uglifyjs b/bin/uglifyjs
index ef2020c..f2aeb08 100755
--- a/bin/uglifyjs
+++ b/bin/uglifyjs
@@ -225,7 +225,7 @@ function run() {
col = line.length;
}
if (line) {
- var limit = 78;
+ var limit = 70;
if (col > limit) {
line = line.slice(col - limit);
col = limit;
diff --git a/lib/compress.js b/lib/compress.js
index 374d14d..32a4d60 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -81,6 +81,7 @@ function Compressor(options, false_by_default) {
toplevel : !!(options && options["top_retain"]),
unsafe : false,
unsafe_comps : false,
+ unsafe_Func : false,
unsafe_math : false,
unsafe_proto : false,
unsafe_regexp : false,
@@ -2973,63 +2974,6 @@ merge(Compressor.prototype, {
operator: "!"
}).optimize(compressor);
break;
- case "Function":
- // new Function() => function(){}
- if (self.args.length == 0) return make_node(AST_Function, self, {
- argnames: [],
- body: []
- });
- if (all(self.args, function(x){ return x instanceof AST_String })) {
- // quite a corner-case, but we can handle it:
- // https://github.com/mishoo/UglifyJS2/issues/203
- // if the code argument is a constant, then we can minify it.
- try {
- var code = "(function(" + self.args.slice(0, -1).map(function(arg){
- return arg.value;
- }).join(",") + "){" + self.args[self.args.length - 1].value + "})()";
- var ast = parse(code);
- var mangle = { ie8: compressor.option("ie8") };
- ast.figure_out_scope(mangle);
- var comp = new Compressor(compressor.options);
- ast = ast.transform(comp);
- ast.figure_out_scope(mangle);
- ast.mangle_names();
- var fun;
- try {
- ast.walk(new TreeWalker(function(node){
- if (node instanceof AST_Lambda) {
- fun = node;
- throw ast;
- }
- }));
- } catch(ex) {
- if (ex !== ast) throw ex;
- };
- if (!fun) return self;
- var args = fun.argnames.map(function(arg, i){
- return make_node(AST_String, self.args[i], {
- value: arg.print_to_string()
- });
- });
- var code = OutputStream();
- AST_BlockStatement.prototype._codegen.call(fun, fun, code);
- code = code.toString().replace(/^\{|\}$/g, "");
- args.push(make_node(AST_String, self.args[self.args.length - 1], {
- value: code
- }));
- self.args = args;
- return self;
- } catch(ex) {
- if (ex instanceof JS_Parse_Error) {
- compressor.warn("Error parsing code passed to new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start);
- compressor.warn(ex.toString());
- } else {
- console.log(ex);
- throw ex;
- }
- }
- }
- break;
}
}
else if (exp instanceof AST_Dot && exp.property == "toString" && self.args.length == 0) {
@@ -3112,6 +3056,63 @@ merge(Compressor.prototype, {
}
}
}
+ if (compressor.option("unsafe_Func")
+ && exp instanceof AST_SymbolRef
+ && exp.undeclared()
+ && exp.name == "Function") {
+ // new Function() => function(){}
+ if (self.args.length == 0) return make_node(AST_Function, self, {
+ argnames: [],
+ body: []
+ });
+ if (all(self.args, function(x) {
+ return x instanceof AST_String;
+ })) {
+ // quite a corner-case, but we can handle it:
+ // https://github.com/mishoo/UglifyJS2/issues/203
+ // if the code argument is a constant, then we can minify it.
+ try {
+ var code = "NaN(function(" + self.args.slice(0, -1).map(function(arg) {
+ return arg.value;
+ }).join(",") + "){" + self.args[self.args.length - 1].value + "})";
+ var ast = parse(code);
+ var mangle = { ie8: compressor.option("ie8") };
+ ast.figure_out_scope(mangle);
+ var comp = new Compressor(compressor.options);
+ ast = ast.transform(comp);
+ ast.figure_out_scope(mangle);
+ ast.mangle_names();
+ var fun;
+ ast.walk(new TreeWalker(function(node) {
+ if (fun) return true;
+ if (node instanceof AST_Lambda) {
+ fun = node;
+ return true;
+ }
+ }));
+ var args = fun.argnames.map(function(arg, i) {
+ return make_node(AST_String, self.args[i], {
+ value: arg.print_to_string()
+ });
+ });
+ var code = OutputStream();
+ AST_BlockStatement.prototype._codegen.call(fun, fun, code);
+ code = code.toString().replace(/^\{|\}$/g, "");
+ args.push(make_node(AST_String, self.args[self.args.length - 1], {
+ value: code
+ }));
+ self.args = args;
+ return self;
+ } catch (ex) {
+ if (ex instanceof JS_Parse_Error) {
+ compressor.warn("Error parsing code passed to new Function [{file}:{line},{col}]", self.args[self.args.length - 1].start);
+ compressor.warn(ex.toString());
+ } else {
+ throw ex;
+ }
+ }
+ }
+ }
if (exp instanceof AST_Function) {
if (exp.body[0] instanceof AST_Return) {
var value = exp.body[0].value;
diff --git a/test/compress/functions.js b/test/compress/functions.js
index 5ebd9d1..6a9f2ae 100644
--- a/test/compress/functions.js
+++ b/test/compress/functions.js
@@ -245,3 +245,25 @@ hoist_funs_strict: {
]
node_version: ">=4"
}
+
+issue_203: {
+ options = {
+ keep_fargs: false,
+ side_effects: true,
+ unsafe_Func: true,
+ unused: true,
+ }
+ input: {
+ var m = {};
+ var fn = Function("require", "module", "exports", "module.exports = 42;");
+ fn(null, m, m.exports);
+ console.log(m.exports);
+ }
+ expect: {
+ var m = {};
+ var fn = Function("a", "b", "b.exports=42");
+ fn(null, m, m.exports);
+ console.log(m.exports);
+ }
+ expect_stdout: "42"
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list