stay safe with constants in IE8- (#1547)
- `undefined` etc. can be redefined at top-level for IE8-, so disable related optimisations - fixed `--support-ie8` catch mangle bug
This commit is contained in:
@@ -75,8 +75,6 @@ The available options are:
|
|||||||
--support-ie8 Use this flag to support Internet Explorer 6/7/8.
|
--support-ie8 Use this flag to support Internet Explorer 6/7/8.
|
||||||
Equivalent to setting `screw_ie8: false` in `minify()`
|
Equivalent to setting `screw_ie8: false` in `minify()`
|
||||||
for `compress`, `mangle` and `output` options.
|
for `compress`, `mangle` and `output` options.
|
||||||
Note: `--support-ie8` may generate incorrect code
|
|
||||||
for `try`/`catch` in ES5 compliant browsers.
|
|
||||||
--expr Parse a single expression, rather than a
|
--expr Parse a single expression, rather than a
|
||||||
program (for parsing JSON)
|
program (for parsing JSON)
|
||||||
-p, --prefix Skip prefix for original filenames that appear
|
-p, --prefix Skip prefix for original filenames that appear
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ mangling you need to use `-c` and `-m`.\
|
|||||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
||||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||||
.describe("screw-ie8", "Do not support Internet Explorer 6/7/8. This flag is enabled by default.")
|
.describe("screw-ie8", "Do not support Internet Explorer 6/7/8. This flag is enabled by default.")
|
||||||
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript. Note: may generate incorrect code for try/catch in ES5 compliant browsers.")
|
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript.")
|
||||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
||||||
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
||||||
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
||||||
|
|||||||
@@ -3348,7 +3348,9 @@ merge(Compressor.prototype, {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
// testing against !self.scope.uses_with first is an optimization
|
// testing against !self.scope.uses_with first is an optimization
|
||||||
if (self.undeclared() && !isLHS(self, compressor.parent())
|
if (compressor.option("screw_ie8")
|
||||||
|
&& self.undeclared()
|
||||||
|
&& !isLHS(self, compressor.parent())
|
||||||
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
||||||
switch (self.name) {
|
switch (self.name) {
|
||||||
case "undefined":
|
case "undefined":
|
||||||
|
|||||||
22
lib/scope.js
22
lib/scope.js
@@ -97,7 +97,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
var labels = new Dictionary();
|
var labels = new Dictionary();
|
||||||
var defun = null;
|
var defun = null;
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (options.screw_ie8 && node instanceof AST_Catch) {
|
if (node instanceof AST_Catch) {
|
||||||
var save_scope = scope;
|
var save_scope = scope;
|
||||||
scope = new AST_Scope(node);
|
scope = new AST_Scope(node);
|
||||||
scope.init_scope_vars();
|
scope.init_scope_vars();
|
||||||
@@ -158,8 +158,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
def.init = tw.parent().value;
|
def.init = tw.parent().value;
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolCatch) {
|
else if (node instanceof AST_SymbolCatch) {
|
||||||
(options.screw_ie8 ? scope : defun)
|
scope.def_variable(node);
|
||||||
.def_variable(node);
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_LabelRef) {
|
else if (node instanceof AST_LabelRef) {
|
||||||
var sym = labels.get(node.name);
|
var sym = labels.get(node.name);
|
||||||
@@ -209,6 +208,23 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
|
// pass 3: fix up any scoping issue with IE8
|
||||||
|
if (!options.screw_ie8) {
|
||||||
|
self.walk(new TreeWalker(function(node, descend) {
|
||||||
|
if (node instanceof AST_SymbolCatch) {
|
||||||
|
var name = node.name;
|
||||||
|
var scope = node.thedef.scope.parent_scope;
|
||||||
|
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||||
|
node.thedef.references.forEach(function(ref) {
|
||||||
|
ref.thedef = def;
|
||||||
|
ref.reference(options);
|
||||||
|
});
|
||||||
|
node.thedef = def;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.cname = options.cache.cname;
|
this.cname = options.cache.cname;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,26 @@ dont_screw: {
|
|||||||
expect_exact: 'f("\\x0B");';
|
expect_exact: 'f("\\x0B");';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_screw_constants: {
|
||||||
|
options = {
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
f(undefined, Infinity);
|
||||||
|
}
|
||||||
|
expect_exact: "f(void 0,1/0);"
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_screw_constants: {
|
||||||
|
options = {
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
f(undefined, Infinity);
|
||||||
|
}
|
||||||
|
expect_exact: "f(undefined,Infinity);"
|
||||||
|
}
|
||||||
|
|
||||||
do_screw_try_catch: {
|
do_screw_try_catch: {
|
||||||
options = { screw_ie8: true };
|
options = { screw_ie8: true };
|
||||||
mangle = { screw_ie8: true };
|
mangle = { screw_ie8: true };
|
||||||
@@ -46,8 +66,6 @@ do_screw_try_catch: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch: {
|
dont_screw_try_catch: {
|
||||||
// This test is known to generate incorrect code for screw_ie8=false.
|
|
||||||
// Update expected result in the event this bug is ever fixed.
|
|
||||||
options = { screw_ie8: false };
|
options = { screw_ie8: false };
|
||||||
mangle = { screw_ie8: false };
|
mangle = { screw_ie8: false };
|
||||||
beautify = { screw_ie8: false };
|
beautify = { screw_ie8: false };
|
||||||
@@ -64,11 +82,11 @@ dont_screw_try_catch: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
bad = function(n){
|
bad = function(n){
|
||||||
return function(n){
|
return function(t){
|
||||||
try{
|
try{
|
||||||
t()
|
n()
|
||||||
} catch(t) {
|
} catch(n) {
|
||||||
n(t)
|
t(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -104,8 +122,6 @@ do_screw_try_catch_undefined: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch_undefined: {
|
dont_screw_try_catch_undefined: {
|
||||||
// This test is known to generate incorrect code for screw_ie8=false.
|
|
||||||
// Update expected result in the event this bug is ever fixed.
|
|
||||||
options = { screw_ie8: false };
|
options = { screw_ie8: false };
|
||||||
mangle = { screw_ie8: false };
|
mangle = { screw_ie8: false };
|
||||||
beautify = { screw_ie8: false };
|
beautify = { screw_ie8: false };
|
||||||
@@ -121,14 +137,14 @@ dont_screw_try_catch_undefined: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function a(o){
|
function a(n){
|
||||||
try{
|
try{
|
||||||
throw "Stuff"
|
throw "Stuff"
|
||||||
} catch (n) {
|
} catch (undefined) {
|
||||||
console.log("caught: "+n)
|
console.log("caught: " + undefined)
|
||||||
}
|
}
|
||||||
console.log("undefined is " + n);
|
console.log("undefined is " + undefined);
|
||||||
return o === n
|
return n === undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user