fix reduce_vars on AST_Defun (#2708)

This commit is contained in:
Alex Lam S.L 2018-01-03 17:18:38 +08:00 committed by GitHub
parent 446fb0198b
commit 14778e049b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 257 additions and 25 deletions

View File

@ -316,7 +316,7 @@ merge(Compressor.prototype, {
if (def.scope.uses_eval || def.scope.uses_with) { if (def.scope.uses_eval || def.scope.uses_with) {
def.fixed = false; def.fixed = false;
} else if (!compressor.exposed(def)) { } else if (!compressor.exposed(def)) {
def.fixed = undefined; def.fixed = def.init;
} else { } else {
def.fixed = false; def.fixed = false;
} }
@ -329,10 +329,12 @@ merge(Compressor.prototype, {
function reset_variables(tw, compressor, node) { function reset_variables(tw, compressor, node) {
node.variables.each(function(def) { node.variables.each(function(def) {
reset_def(compressor, def); reset_def(compressor, def);
if (def.fixed === undefined && def.orig[0].TYPE == "SymbolVar") { if (def.fixed === null) {
def.fixed = null;
def.safe_ids = tw.safe_ids; def.safe_ids = tw.safe_ids;
mark(tw, def, true); mark(tw, def, true);
} else if (def.fixed) {
tw.loop_ids[def.id] = tw.in_loop;
mark(tw, def, true);
} }
}); });
} }
@ -504,15 +506,6 @@ merge(Compressor.prototype, {
}); });
def(AST_Defun, function(tw, descend, compressor) { def(AST_Defun, function(tw, descend, compressor) {
this.inlined = false; this.inlined = false;
var d = this.name.definition();
if (compressor.exposed(d) || safe_to_read(tw, d)) {
d.fixed = false;
} else {
d.fixed = this;
d.single_use = ref_once(tw, compressor, d);
tw.loop_ids[d.id] = tw.in_loop;
mark(tw, d, true);
}
var save_ids = tw.safe_ids; var save_ids = tw.safe_ids;
tw.safe_ids = Object.create(null); tw.safe_ids = Object.create(null);
reset_variables(tw, compressor, this); reset_variables(tw, compressor, this);

View File

@ -43,9 +43,10 @@
"use strict"; "use strict";
function SymbolDef(scope, orig) { function SymbolDef(scope, orig, init) {
this.name = orig.name; this.name = orig.name;
this.orig = [ orig ]; this.orig = [ orig ];
this.init = init;
this.eliminated = 0; this.eliminated = 0;
this.scope = scope; this.scope = scope;
this.references = []; this.references = [];
@ -158,10 +159,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
// scope when we encounter the AST_Defun node (which is // scope when we encounter the AST_Defun node (which is
// instanceof AST_Scope) but we get to the symbol a bit // instanceof AST_Scope) but we get to the symbol a bit
// later. // later.
(node.scope = defun.parent_scope).def_function(node); (node.scope = defun.parent_scope).def_function(node, defun);
} }
else if (node instanceof AST_SymbolVar) { else if (node instanceof AST_SymbolVar) {
defun.def_variable(node); defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
if (defun !== scope) { if (defun !== scope) {
node.mark_enclosed(options); node.mark_enclosed(options);
var def = scope.find_variable(node); var def = scope.find_variable(node);
@ -306,21 +307,21 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|| (this.parent_scope && this.parent_scope.find_variable(name)); || (this.parent_scope && this.parent_scope.find_variable(name));
}); });
AST_Scope.DEFMETHOD("def_function", function(symbol){ AST_Scope.DEFMETHOD("def_function", function(symbol, init){
var def = this.def_variable(symbol); var def = this.def_variable(symbol, init);
if (!def.init) def.init = init;
this.functions.set(symbol.name, def); this.functions.set(symbol.name, def);
return def; return def;
}); });
AST_Scope.DEFMETHOD("def_variable", function(symbol){ AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
var def; var def = this.variables.get(symbol.name);
if (!this.variables.has(symbol.name)) { if (def) {
def = new SymbolDef(this, symbol); def.orig.push(symbol);
} else {
def = new SymbolDef(this, symbol, init);
this.variables.set(symbol.name, def); this.variables.set(symbol.name, def);
def.global = !this.parent_scope; def.global = !this.parent_scope;
} else {
def = this.variables.get(symbol.name);
def.orig.push(symbol);
} }
return symbol.thedef = def; return symbol.thedef = def;
}); });

View File

@ -4999,3 +4999,241 @@ var_if: {
} }
} }
} }
defun_assign: {
options = {
reduce_vars: true,
toplevel: true,
}
input: {
console.log(typeof a);
a = 42;
console.log(typeof a);
function a() {}
console.log(typeof a);
}
expect: {
console.log(typeof a);
a = 42;
console.log(typeof a);
function a() {}
console.log(typeof a);
}
expect_stdout: [
"function",
"number",
"number",
]
}
defun_var_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
var a = 42, b;
function a() {}
function b() {}
console.log(typeof a, typeof b);
}
expect: {
var a = 42;
function a() {}
console.log(typeof a, "function");
}
expect_stdout: "number function"
}
defun_var_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
function a() {}
function b() {}
var a = 42, b;
console.log(typeof a, typeof b);
}
expect: {
function a() {}
var a = 42;
console.log(typeof a, "function");
}
expect_stdout: "number function"
}
defun_var_3: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
function a() {}
function b() {}
console.log(typeof a, typeof b);
var a = 42, b;
}
expect: {
function a() {}
console.log(typeof a, "function");
var a = 42;
}
expect_stdout: "function function"
}
defun_catch_1: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function a() {}
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}
defun_catch_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
function a() {}
throw 42;
} catch (a) {
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}
defun_catch_3: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
function a() {}
} catch (a) {
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}
defun_catch_4: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
} catch (a) {
function a() {}
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
function a() {}
console.log(a);
}
}
expect_stdout: true
}
defun_catch_5: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
} catch (a) {
console.log(a);
function a() {}
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
function a() {}
}
}
expect_stdout: true
}
defun_catch_6: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
} catch (a) {
console.log(a);
}
function a() {}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}

View File

@ -100,7 +100,7 @@ typeof_defun_1: {
g = 42; g = 42;
console.log("YES"); console.log("YES");
"function" == typeof g && g(); "function" == typeof g && g();
h(); "function" == typeof h && h();
} }
expect_stdout: [ expect_stdout: [
"YES", "YES",