fix reduce_vars on AST_Defun (#2708)
This commit is contained in:
@@ -316,7 +316,7 @@ merge(Compressor.prototype, {
|
||||
if (def.scope.uses_eval || def.scope.uses_with) {
|
||||
def.fixed = false;
|
||||
} else if (!compressor.exposed(def)) {
|
||||
def.fixed = undefined;
|
||||
def.fixed = def.init;
|
||||
} else {
|
||||
def.fixed = false;
|
||||
}
|
||||
@@ -329,10 +329,12 @@ merge(Compressor.prototype, {
|
||||
function reset_variables(tw, compressor, node) {
|
||||
node.variables.each(function(def) {
|
||||
reset_def(compressor, def);
|
||||
if (def.fixed === undefined && def.orig[0].TYPE == "SymbolVar") {
|
||||
def.fixed = null;
|
||||
if (def.fixed === null) {
|
||||
def.safe_ids = tw.safe_ids;
|
||||
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) {
|
||||
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;
|
||||
tw.safe_ids = Object.create(null);
|
||||
reset_variables(tw, compressor, this);
|
||||
|
||||
25
lib/scope.js
25
lib/scope.js
@@ -43,9 +43,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function SymbolDef(scope, orig) {
|
||||
function SymbolDef(scope, orig, init) {
|
||||
this.name = orig.name;
|
||||
this.orig = [ orig ];
|
||||
this.init = init;
|
||||
this.eliminated = 0;
|
||||
this.scope = scope;
|
||||
this.references = [];
|
||||
@@ -158,10 +159,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
// scope when we encounter the AST_Defun node (which is
|
||||
// instanceof AST_Scope) but we get to the symbol a bit
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
(node.scope = defun.parent_scope).def_function(node, defun);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node);
|
||||
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||
if (defun !== scope) {
|
||||
node.mark_enclosed(options);
|
||||
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));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
var def = this.def_variable(symbol);
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
|
||||
var def = this.def_variable(symbol, init);
|
||||
if (!def.init) def.init = init;
|
||||
this.functions.set(symbol.name, def);
|
||||
return def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, symbol);
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
|
||||
var def = this.variables.get(symbol.name);
|
||||
if (def) {
|
||||
def.orig.push(symbol);
|
||||
} else {
|
||||
def = new SymbolDef(this, symbol, init);
|
||||
this.variables.set(symbol.name, def);
|
||||
def.global = !this.parent_scope;
|
||||
} else {
|
||||
def = this.variables.get(symbol.name);
|
||||
def.orig.push(symbol);
|
||||
}
|
||||
return symbol.thedef = def;
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ typeof_defun_1: {
|
||||
g = 42;
|
||||
console.log("YES");
|
||||
"function" == typeof g && g();
|
||||
h();
|
||||
"function" == typeof h && h();
|
||||
}
|
||||
expect_stdout: [
|
||||
"YES",
|
||||
|
||||
Reference in New Issue
Block a user