bug 584787, r=pcwalton: Node shouldn't subclass Array

This commit is contained in:
Dave Herman 2010-10-07 10:59:45 -07:00
Родитель e2941e77c7
Коммит b3fd89a22a
5 изменённых файлов: 243 добавлений и 147 удалений

Просмотреть файл

@ -313,8 +313,8 @@ Narcissus.interpreter = (function() {
return;
for (var i = 0, j = ps.length; i < j; i++) {
// If the thing we're valuating is already equal to the thing we want
// to valuate it to, we have fully saturated (and have a cycle), and
// If the thing we're evaluating is already equal to the thing we want
// to evaluate it to, we have fully saturated (and have a cycle), and
// thus we should break.
if (ps[i].v === v)
break;
@ -324,7 +324,7 @@ Narcissus.interpreter = (function() {
}
function execute(n, x) {
var a, f, i, j, r, s, t, u, v;
var a, c, f, i, j, r, s, t, u, v;
switch (n.type) {
case FUNCTION:
@ -370,8 +370,9 @@ Narcissus.interpreter = (function() {
// FALL THROUGH
case BLOCK:
for (i = 0, j = n.length; i < j; i++)
execute(n[i], x);
c = n.children;
for (i = 0, j = c.length; i < j; i++)
execute(c[i], x);
break;
case IF:
@ -405,7 +406,7 @@ Narcissus.interpreter = (function() {
}
if (u === s) {
for (;;) { // this loop exits switch_loop
if (t.statements.length) {
if (t.statements.children.length) {
try {
execute(t.statements, x);
} catch (e if e === BREAK && x.target === n) {
@ -532,11 +533,12 @@ Narcissus.interpreter = (function() {
case VAR:
case CONST:
for (i = 0, j = n.length; i < j; i++) {
u = n[i].initializer;
c = n.children;
for (i = 0, j = c.length; i < j; i++) {
u = c[i].initializer;
if (!u)
continue;
t = n[i].name;
t = c[i].name;
for (s = x.scope; s; s = s.parent) {
if (hasDirectProperty(s.object, t))
break;
@ -565,16 +567,18 @@ Narcissus.interpreter = (function() {
break;
case COMMA:
for (i = 0, j = n.length; i < j; i++)
v = getValue(execute(n[i], x));
c = n.children;
for (i = 0, j = c.length; i < j; i++)
v = getValue(execute(c[i], x));
break;
case ASSIGN:
r = execute(n[0], x);
c = n.children;
r = execute(c[0], x);
t = n.assignOp;
if (t)
u = getValue(r);
v = getValue(execute(n[1], x));
v = getValue(execute(c[1], x));
if (t) {
switch (t) {
case BITWISE_OR: v = u | v; break;
@ -590,73 +594,89 @@ Narcissus.interpreter = (function() {
case MOD: v = u % v; break;
}
}
putValue(r, v, n[0]);
putValue(r, v, c[0]);
break;
case HOOK:
v = getValue(execute(n[0], x)) ? getValue(execute(n[1], x))
: getValue(execute(n[2], x));
c = n.children;
v = getValue(execute(c[0], x)) ? getValue(execute(c[1], x))
: getValue(execute(c[2], x));
break;
case OR:
v = getValue(execute(n[0], x)) || getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) || getValue(execute(c[1], x));
break;
case AND:
v = getValue(execute(n[0], x)) && getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) && getValue(execute(c[1], x));
break;
case BITWISE_OR:
v = getValue(execute(n[0], x)) | getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) | getValue(execute(c[1], x));
break;
case BITWISE_XOR:
v = getValue(execute(n[0], x)) ^ getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) ^ getValue(execute(c[1], x));
break;
case BITWISE_AND:
v = getValue(execute(n[0], x)) & getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) & getValue(execute(c[1], x));
break;
case EQ:
v = getValue(execute(n[0], x)) == getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) == getValue(execute(c[1], x));
break;
case NE:
v = getValue(execute(n[0], x)) != getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) != getValue(execute(c[1], x));
break;
case STRICT_EQ:
v = getValue(execute(n[0], x)) === getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) === getValue(execute(c[1], x));
break;
case STRICT_NE:
v = getValue(execute(n[0], x)) !== getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) !== getValue(execute(c[1], x));
break;
case LT:
v = getValue(execute(n[0], x)) < getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) < getValue(execute(c[1], x));
break;
case LE:
v = getValue(execute(n[0], x)) <= getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) <= getValue(execute(c[1], x));
break;
case GE:
v = getValue(execute(n[0], x)) >= getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) >= getValue(execute(c[1], x));
break;
case GT:
v = getValue(execute(n[0], x)) > getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) > getValue(execute(c[1], x));
break;
case IN:
v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) in getValue(execute(c[1], x));
break;
case INSTANCEOF:
t = getValue(execute(n[0], x));
u = getValue(execute(n[1], x));
c = n.children;
t = getValue(execute(c[0], x));
u = getValue(execute(c[1], x));
if (isObject(u) && typeof u.__hasInstance__ === "function")
v = u.__hasInstance__(t);
else
@ -664,111 +684,122 @@ Narcissus.interpreter = (function() {
break;
case LSH:
v = getValue(execute(n[0], x)) << getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) << getValue(execute(c[1], x));
break;
case RSH:
v = getValue(execute(n[0], x)) >> getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) >> getValue(execute(c[1], x));
break;
case URSH:
v = getValue(execute(n[0], x)) >>> getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) >>> getValue(execute(c[1], x));
break;
case PLUS:
v = getValue(execute(n[0], x)) + getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) + getValue(execute(c[1], x));
break;
case MINUS:
v = getValue(execute(n[0], x)) - getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) - getValue(execute(c[1], x));
break;
case MUL:
v = getValue(execute(n[0], x)) * getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) * getValue(execute(c[1], x));
break;
case DIV:
v = getValue(execute(n[0], x)) / getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) / getValue(execute(c[1], x));
break;
case MOD:
v = getValue(execute(n[0], x)) % getValue(execute(n[1], x));
c = n.children;
v = getValue(execute(c[0], x)) % getValue(execute(c[1], x));
break;
case DELETE:
t = execute(n[0], x);
t = execute(n.children[0], x);
v = !(t instanceof Reference) || delete t.base[t.propertyName];
break;
case VOID:
getValue(execute(n[0], x));
getValue(execute(n.children[0], x));
break;
case TYPEOF:
t = execute(n[0], x);
t = execute(n.children[0], x);
if (t instanceof Reference)
t = t.base ? t.base[t.propertyName] : undefined;
v = typeof t;
break;
case NOT:
v = !getValue(execute(n[0], x));
v = !getValue(execute(n.children[0], x));
break;
case BITWISE_NOT:
v = ~getValue(execute(n[0], x));
v = ~getValue(execute(n.children[0], x));
break;
case UNARY_PLUS:
v = +getValue(execute(n[0], x));
v = +getValue(execute(n.children[0], x));
break;
case UNARY_MINUS:
v = -getValue(execute(n[0], x));
v = -getValue(execute(n.children[0], x));
break;
case INCREMENT:
case DECREMENT:
t = execute(n[0], x);
t = execute(n.children[0], x);
u = Number(getValue(t));
if (n.postfix)
v = u;
putValue(t, (n.type === INCREMENT) ? ++u : --u, n[0]);
putValue(t, (n.type === INCREMENT) ? ++u : --u, n.children[0]);
if (!n.postfix)
v = u;
break;
case DOT:
r = execute(n[0], x);
c = n.children;
r = execute(c[0], x);
t = getValue(r);
u = n[1].value;
v = new Reference(toObject(t, r, n[0]), u, n);
u = c[1].value;
v = new Reference(toObject(t, r, c[0]), u, n);
break;
case INDEX:
r = execute(n[0], x);
c = n.children;
r = execute(c[0], x);
t = getValue(r);
u = getValue(execute(n[1], x));
v = new Reference(toObject(t, r, n[0]), String(u), n);
u = getValue(execute(c[1], x));
v = new Reference(toObject(t, r, c[0]), String(u), n);
break;
case LIST:
// Curse ECMA for specifying that arguments is not an Array object!
v = {};
for (i = 0, j = n.length; i < j; i++) {
u = getValue(execute(n[i], x));
c = n.children;
for (i = 0, j = c.length; i < j; i++) {
u = getValue(execute(c[i], x));
definitions.defineProperty(v, i, u, false, false, true);
}
definitions.defineProperty(v, "length", i, false, false, true);
break;
case CALL:
r = execute(n[0], x);
a = execute(n[1], x);
c = n.children;
r = execute(c[0], x);
a = execute(c[1], x);
f = getValue(r);
if (isPrimitive(f) || typeof f.__call__ !== "function") {
throw new TypeError(r + " is not callable",
n[0].filename, n[0].lineno);
throw new TypeError(r + " is not callable", c[0].filename, c[0].lineno);
}
t = (r instanceof Reference) ? r.base : null;
if (t instanceof Activation)
@ -778,36 +809,39 @@ Narcissus.interpreter = (function() {
case NEW:
case NEW_WITH_ARGS:
r = execute(n[0], x);
c = n.children;
r = execute(c[0], x);
f = getValue(r);
if (n.type === NEW) {
a = {};
definitions.defineProperty(a, "length", 0, false, false, true);
} else {
a = execute(n[1], x);
a = execute(c[1], x);
}
if (isPrimitive(f) || typeof f.__construct__ !== "function") {
throw new TypeError(r + " is not a constructor",
n[0].filename, n[0].lineno);
throw new TypeError(r + " is not a constructor", c[0].filename, c[0].lineno);
}
v = f.__construct__(a, x);
break;
case ARRAY_INIT:
v = [];
for (i = 0, j = n.length; i < j; i++) {
if (n[i])
v[i] = getValue(execute(n[i], x));
c = n.children;
for (i = 0, j = c.length; i < j; i++) {
if (c[i])
v[i] = getValue(execute(c[i], x));
}
v.length = j;
break;
case OBJECT_INIT:
v = {};
for (i = 0, j = n.length; i < j; i++) {
t = n[i];
c = n.children;
for (i = 0, j = c.length; i < j; i++) {
t = c[i];
if (t.type === PROPERTY_INIT) {
v[t[0].value] = getValue(execute(t[1], x));
let c2 = t.children;
v[c2[0].value] = getValue(execute(c2[1], x));
} else {
f = newFunction(t, x);
u = (t.type === GETTER) ? '__defineGetter__'
@ -834,6 +868,9 @@ Narcissus.interpreter = (function() {
break;
case IDENTIFIER:
if (typeof n.resolve !== "function")
throw n;
// Identifiers with forward pointers that weren't intervened can't be
// lvalues, so we safely get the cached value directly.
var resolved = n.resolve();
@ -859,7 +896,7 @@ Narcissus.interpreter = (function() {
break;
case GROUP:
v = execute(n[0], x);
v = execute(n.children[0], x);
break;
default:
@ -1132,6 +1169,22 @@ Narcissus.interpreter = (function() {
print(e.toString());
} catch (e) {
print("internal Narcissus error");
if (typeof e === "object" && e.stack) {
let st = String(e.stack).split(/\n/);
// beautify stack trace:
// - eliminate blank lines
// - sanitize confusing trace lines for getters and js -e expressions
// - simplify source location reporting
// - indent
for (let i = 0; i < st.length; i++) {
let line = st[i].trim();
if (line) {
line = line.replace(/^(\(\))?@/, "<unknown>@");
line = line.replace(/@(.*\/|\\)?([^\/\\]+:[0-9]+)/, " at $2");
print(" in " + line);
}
}
}
throw e;
}
}

Просмотреть файл

@ -657,15 +657,15 @@ Narcissus.parser = (function() {
},
setCondition: function(n, e) {
n[0] = e;
n.children[0] = e;
},
setThenPart: function(n, n2) {
n[1] = n2;
n.children[1] = n2;
},
setElsePart: function(n, n2) {
n[2] = n2;
n.children[2] = n2;
},
finish: function(n) {
@ -906,11 +906,12 @@ Narcissus.parser = (function() {
// Nodes use a tokenizer for debugging (getSource, filename getter).
this.tokenizer = t;
this.children = [];
for (var i = 2; i < arguments.length; i++)
this.push(arguments[i]);
}
var Np = Node.prototype = new Array;
var Np = Node.prototype = {};
Np.constructor = Node;
Np.toSource = Object.prototype.toSource;
@ -923,7 +924,7 @@ Narcissus.parser = (function() {
if (this.end < kid.end)
this.end = kid.end;
}
return Array.prototype.push.call(this, kid);
return this.children.push(kid);
}
Node.indentLevel = 0;
@ -959,6 +960,11 @@ Narcissus.parser = (function() {
return this.tokenizer.filename;
});
definitions.defineGetter(Np, "length",
function() {
throw new Error("Node.prototype.length is gone; use n.children.length instead");
});
definitions.defineProperty(String.prototype, "repeat",
function(n) {
var s = "", t = this + s;
@ -1027,7 +1033,7 @@ Narcissus.parser = (function() {
* Parses a Statement.
*/
function Statement(t, x) {
var i, label, n, n2, ss, tt = t.get(true);
var i, label, n, n2, c, ss, tt = t.get(true);
var builder = x.builder, b, b2, b3;
// Cases for statements ending in a right curly return early, avoiding the
@ -1141,17 +1147,19 @@ Narcissus.parser = (function() {
b.rebuildForIn(n);
b.setObject(n, Expression(t, x));
if (n2.type === VAR || n2.type === LET) {
c = n2.children;
// Destructuring turns one decl into multiples, so either
// there must be only one destructuring or only one
// decl.
if (n2.length !== 1 && n2.destructurings.length !== 1) {
if (c.length !== 1 && n2.destructurings.length !== 1) {
throw new SyntaxError("Invalid for..in left-hand side",
t.filename, n2.lineno);
}
if (n2.destructurings.length > 0) {
b.setIterator(n, n2.destructurings[0], n2, forBlock);
} else {
b.setIterator(n, n2[0], n2, forBlock);
b.setIterator(n, c[0], n2, forBlock);
}
} else {
if (n2.type === ARRAY_INIT || n2.type === OBJECT_INIT) {
@ -1181,8 +1189,9 @@ Narcissus.parser = (function() {
if (forBlock) {
builder.BLOCK.finish(forBlock);
x.stmtStack.pop();
for (var i = 0, j = forBlock.length; i < j; i++) {
n.body.unshift(forBlock[i]);
c = forBlock.children;
for (var i = 0, j = c.length; i < j; i++) {
n.body.unshift(c[i]);
}
}
return n;
@ -1726,13 +1735,14 @@ Narcissus.parser = (function() {
return;
var lhss = {};
var nn, n2, idx, sub;
for (var i = 0, j = n.length; i < j; i++) {
if (!(nn = n[i]))
var nn, n2, idx, sub, cc, c = n.children;
for (var i = 0, j = c.length; i < j; i++) {
if (!(nn = c[i]))
continue;
if (nn.type === PROPERTY_INIT) {
sub = nn[1];
idx = nn[0].value;
cc = nn.children;
sub = cc[1];
idx = cc[0].value;
} else if (n.type === OBJECT_INIT) {
// Do we have destructuring shorthand {foo, bar}?
sub = nn;
@ -1891,7 +1901,7 @@ Narcissus.parser = (function() {
b.addOperand(n2, n);
n = n2;
do {
n2 = n[n.length-1];
n2 = n.children[n.children.length-1];
if (n2.type === YIELD && !n2.parenthesized)
throw t.newSyntaxError("Yield expression must be parenthesized");
b.addOperand(n, AssignExpression(t, x));
@ -2233,7 +2243,7 @@ Narcissus.parser = (function() {
throw t.newSyntaxError("Yield " + err);
if (t.match(FOR)) {
n2 = GeneratorExpression(t, x, n2);
if (n.length > 1 || t.peek(true) === COMMA)
if (n.children.length > 1 || t.peek(true) === COMMA)
throw t.newSyntaxError("Generator " + err);
}
b.addOperand(n, n2);
@ -2274,9 +2284,9 @@ Narcissus.parser = (function() {
// If we matched exactly one element and got a FOR, we have an
// array comprehension.
if (n.length === 1 && t.match(FOR)) {
if (n.children.length === 1 && t.match(FOR)) {
n2 = bArrayComp.build(t);
bArrayComp.setExpression(n2, n[0]);
bArrayComp.setExpression(n2, n.children[0]);
bArrayComp.setTail(n2, comprehensionTail(t, x));
n = n2;
}
@ -2379,9 +2389,6 @@ Narcissus.parser = (function() {
parse: parse,
Node: Node,
DefaultBuilder: DefaultBuilder,
get SSABuilder() {
throw new Error("SSA builder not yet supported");
},
bindSubBuilders: bindSubBuilders,
DECLARED_FORM: DECLARED_FORM,
EXPRESSED_FORM: EXPRESSED_FORM,

Просмотреть файл

@ -41,7 +41,7 @@
* SSA builder and optimizations.
*/
(function() {
Narcissus.parser.SSABuilder = (function() {
const parser = Narcissus.parser;
const definitions = Narcissus.definitions;
@ -717,7 +717,7 @@
if (allDashes) {
return null;
}
rhs.reverse();
rhs.children.reverse();
e = new Node(ft, ASSIGN);
e.push(lhs);
@ -732,20 +732,21 @@
continue;
}
rhs = e2[1];
rhs = e2.children[1];
// Optimize away phis that are only one branch, but we still need
// to propagate them!
if (branches == 1) {
rhs = rhs[0];
rhs = rhs.children[0];
} else {
// Push a phi use for each operand so the phis can be filled
// in during exec.
for (var i = 0, j = rhs.length; i < j; i++) {
if (rhs[i].type == INTERVENED) {
var rhsc = rhs.children;
for (var i = 0, j = rhsc.length; i < j; i++) {
if (rhsc[i].type == INTERVENED) {
rhs.intervened = true;
}
rhs[i].pushPhiUse(rhs);
rhsc[i].pushPhiUse(rhs);
}
e.push(e2);
}
@ -753,7 +754,7 @@
propagate(x, rhs);
}
return e.length > 0 ? e : null;
return e.children.length > 0 ? e : null;
}
SSAJoin.prototype = {
@ -904,9 +905,10 @@
uu = u[i];
// Phi nodes might have stale branches.
if (uu.type == PHI) {
for (var k = 0, l = uu.length; k < l; k++) {
if (uu[k] === old.def) {
uu[k] = rhs;
var uuc = uu.children;
for (var k = 0, l = uuc.length; k < l; k++) {
if (uuc[k] === old.def) {
uuc[k] = rhs;
rhs.pushPhiUse(uu);
}
}
@ -1279,7 +1281,7 @@
// do.
var bComma = this.COMMA;
e2.push(n.setup[0]);
e2.push(n.setup.children[0]);
n.setup = e2;
var comma = bComma.build(t);
@ -1318,7 +1320,7 @@
this.join = breakJoin.parent;
// Add update to the top if we were a for-in
if (n.type == FOR_IN) {
n.body.unshift(n.update);
n.body.children.unshift(n.update);
n.update = null;
n.type = FOR;
}
@ -1973,7 +1975,7 @@
ASSIGN: {
addOperand: function(n, n2) {
if (n.length == 0) {
if (n.children.length === 0) {
this.binds.inRHS++;
}
@ -1981,15 +1983,16 @@
},
finish: function(n) {
if (n.length == 0) {
if (n.children.length === 0) {
return;
}
var join = this.join;
var binds = this.binds;
var fb = binds.nearestFunction;
var lhs = n[0];
var init = n[1];
var nc = n.children;
var lhs = nc[0];
var init = nc[1];
var upvars = init.upvars || new Upvars;
if (--binds.inRHS > 0) {
@ -2001,7 +2004,7 @@
var t = n.tokenizer;
// Rebuild as COMMA.
n.type = COMMA;
n.length = 0;
n.children = [];
desugarDestructuringAssign(this, n, lhs, init);
return;
}
@ -2053,12 +2056,11 @@
// Transform op= into a normal assignment only if the
// lhs is an identifier we _know_ to be from a var.
var nt = n.tokenizer;
var lhs = n[0];
var n2 = mkRawIdentifier(nt, name, null, true);
this.PRIMARY.finish(n2);
var o = n.assignOp;
n.assignOp = undefined;
n.length = 0;
n.children = [];
n.push(lhs);
n.push(new Node(nt, o, n2, init));
n2.setForward(c.def);
@ -2066,17 +2068,17 @@
}
// Clear the forward pointer and upvars on lefthand side.
if (n[0].forward) {
n[0].forward = null;
n[0].upvars = null;
if (lhs.forward) {
lhs.forward = null;
lhs.upvars = null;
}
// Set local to help decomp to do value numbering.
n[0].local = c.type;
lhs.local = c.type;
// Get the rightmost expression in case of compound
// assignment.
while (init.type == ASSIGN)
init = init[1];
init = init.children[1];
if (join) {
// If the name is not a local let, we need a phi.
@ -2124,21 +2126,21 @@
},
setCondition: function(n, e) {
n[0] = e;
n.children[0] = e;
n.rhsUnionUpvars(e);
this.join = new SSAJoin(this.join, this.binds, false);
},
setThenPart: function(n, n2) {
var join = this.join;
n[1] = n2;
n.children[1] = n2;
n.rhsUnionUpvars(n2);
join.finishBranch();
join.restore(this.binds);
},
setElsePart: function(n, n2) {
n[2] = n2;
n.children[2] = n2;
n.rhsUnionUpvars(n2);
},
@ -2158,7 +2160,7 @@
},
addOperand: function(n, n2) {
if (n.length == 0) {
if (n.children.length == 0) {
// Short circuiting means the right hand expression needs
// to be parsed in a new context.
var join = this.join = new SSAJoin(this.join, this.binds, false);
@ -2186,7 +2188,7 @@
},
addOperand: function(n, n2) {
if (n.length == 0) {
if (n.children.length == 0) {
// Short circuiting means the right hand expression needs
// to be parsed in a new context.
var join = this.join = new SSAJoin(this.join, this.binds, false);
@ -2213,7 +2215,9 @@
var join = this.join;
var binds = this.binds;
if (!(n[0].type == IDENTIFIER && binds.hasCurrent(n[0].value)))
var nc = n.children;
var lhs = nc[0];
if (!(lhs.type == IDENTIFIER && binds.hasCurrent(lhs.value)))
return;
//
@ -2230,7 +2234,7 @@
// effect, so we do not duplicate side effects in an unsafe
// fashion.
//
var name = n[0].value;
var name = lhs.value;
var c = binds.current(name);
// Don't transform vars inside of withs
if (binds.isWith && c.type == VAR)
@ -2255,7 +2259,7 @@
if (n.postfix) {
n.parenthesized = true;
n.type = COMMA;
n.length = 0;
n.children = [];
n.push(mkAssignSimple(this, t, ptmp,
mkIdentifier(this, t, name)));
}
@ -2270,9 +2274,11 @@
n.push(mkIdentifier(this, t, ptmp));
} else {
n.type = ASSIGN;
n.length = 0;
n.push(assign[0]);
n.push(assign[1]);
n.children = [];
var assignc = assign.children;
n.push(assignc[0]);
n.push(assignc[1]);
}
}
},
@ -2296,12 +2302,13 @@
var join = this.join;
var binds = this.binds;
var fb = binds.nearestFunction;
var nc = n.children;
if (--binds.inRHS > 0) {
if (unionOnRight) {
n.upvars = n[1].upvars;
n.upvars = nc[1].upvars;
} else {
n.upvars = n[0].upvars;
n.upvars = nc[0].upvars;
}
}
@ -2357,8 +2364,9 @@
// local ones, so blast away context.
//
var inners = this.binds.inners;
var base = baseOfCall(n[0]);
var target = targetOfCall(n[0], IDENTIFIER);
var call = nc[0];
var base = baseOfCall(call);
var target = targetOfCall(call, IDENTIFIER);
if (target == "eval") {
escapeEval(join, binds);
@ -2454,7 +2462,7 @@
var unionOnRight = n.type == CALL || n.type == NEW_WITH_ARGS ||
n.type == INDEX;
if (unionOnRight) {
escapeVars(join, binds, n[1].upvars || new Upvars);
escapeVars(join, binds, nc[1].upvars || new Upvars);
}
}
},
@ -2581,7 +2589,7 @@
},
finish: function(n) {
n.rhsUnionUpvars(n[1]);
n.rhsUnionUpvars(n.children[1]);
}
},
@ -2837,9 +2845,9 @@
function baseOfCall(n) {
switch (n.type) {
case DOT:
return baseOfCall(n[0]);
return baseOfCall(n.children[0]);
case INDEX:
return baseOfCall(n[0]);
return baseOfCall(n.children[0]);
default:
return n;
}
@ -2850,9 +2858,9 @@
case ident:
return n.value;
case DOT:
return targetOfCall(n[1], IDENTIFIER);
return targetOfCall(n.children[1], IDENTIFIER);
case INDEX:
return targetOfCall(n[1], STRING);
return targetOfCall(n.children[1], STRING);
default:
return null;
}
@ -2948,9 +2956,9 @@
builder.genDestructuringSym(),
e, false);
builder.binds.block.push(decl);
decl[0].setForward(e);
go(n.destructuredNames, decl[0]);
var declc = decl.children[0];
declc[0].setForward(e);
go(n.destructuredNames, declc[0]);
}
function desugarDestructuringInit(builder, n, e) {
@ -2984,8 +2992,9 @@
var dtmp = builder.genDestructuringSym();
var decl = mkDecl(builder, "LET", t, dtmp, e, false);
block.push(decl);
decl[0].setForward(e);
go(ddecls, decl[0]);
var declc = decl.children[0];
declc[0].setForward(e);
go(ddecls, declc[0]);
} else {
// This only happens when we have destructuring for a catch var,
// in which case that catch var already has let-scoping, so we
@ -3139,6 +3148,6 @@
this.phiUses.push(p);
};
parser.SSABuilder = SSABuilder;
return SSABuilder;
}());

Просмотреть файл

@ -16,6 +16,7 @@ js_cmd = os.path.abspath(os.path.join(THIS_DIR, "js"))
narc_jsdefs = os.path.join(NARC_JS_DIR, "jsdefs.js")
narc_jslex = os.path.join(NARC_JS_DIR, "jslex.js")
narc_jsparse = os.path.join(NARC_JS_DIR, "jsparse.js")
narc_jsssa = os.path.join(NARC_JS_DIR, "jsssa.js")
narc_jsexec = os.path.join(NARC_JS_DIR, "jsexec.js")
def handler(signum, frame):
@ -62,5 +63,5 @@ if __name__ == '__main__':
if options.js_interactive:
cmd += 'Narcissus.interpreter.repl();'
Popen([js_cmd, '-f', narc_jsdefs, '-f', narc_jslex, '-f', narc_jsparse, '-f', narc_jsexec, '-e', cmd]).wait()
Popen([js_cmd, '-f', narc_jsdefs, '-f', narc_jslex, '-f', narc_jsparse, '-f', narc_jsssa, '-f', narc_jsexec, '-e', cmd]).wait()

Просмотреть файл

@ -259,6 +259,7 @@ e4x/extensions/regress-410192.js
e4x/extensions/regress-450871-01.js
e4x/extensions/regress-450871-02.js
e4x/extensions/regress-462734-01.js
e4x/extensions/extensibility.js
ecma/Array/15.4.4.3-1.js
ecma/Boolean/15.6.4.1.js
ecma/Boolean/15.6.4.2-4-n.js
@ -606,10 +607,13 @@ ecma_5/Object/15.2.3.6-redefinition-2-of-4.js
ecma_5/Object/15.2.3.6-redefinition-3-of-4.js
ecma_5/Object/15.2.3.6-redefinition-4-of-4.js
ecma_5/Object/15.2.3.7-01.js
ecma_5/Object/extensibility-01.js
ecma_5/Object/vacuous-accessor-unqualified-name.js
ecma_5/RegExp/15.10.7.5-01.js
ecma_5/Types/8.12.5-01.js
ecma_5/extensions/8.12.5-01.js
ecma_5/extensions/string-literal-getter-setter-decompilation.js
ecma_5/extensions/15.4.4.11.js
ecma_5/misc/enumerate-undefined.js
ecma_5/misc/global-numeric-properties.js
ecma_5/strict/10.4.2.js
@ -629,6 +633,21 @@ ecma_5/strict/8.7.2.js
ecma_5/strict/B.1.1.js
ecma_5/strict/B.1.2.js
ecma_5/strict/regress-532254.js
ecma_5/strict/8.12.5.js
ecma_5/strict/8.12.7.js
ecma_5/strict/10.6.js
ecma_5/strict/15.3.5.1.js
ecma_5/strict/15.3.5.2.js
ecma_5/strict/15.4.4.9.js
ecma_5/strict/15.4.4.6.js
ecma_5/strict/15.4.4.8.js
ecma_5/strict/15.4.4.12.js
ecma_5/strict/15.4.5.1.js
ecma_5/strict/15.4.4.13.js
ecma_5/strict/15.5.5.1.js
ecma_5/strict/15.5.5.2.js
ecma_5/strict/15.10.7.js
ecma_5/strict/function-name-arity.js
js1_2/regexp/RegExp_multiline.js
js1_2/regexp/RegExp_multiline_as_array.js
js1_2/regexp/alphanumeric.js
@ -1335,6 +1354,9 @@ js1_8_5/extensions/destructure-accessor.js
js1_8_5/extensions/reflect-parse.js
js1_8_5/extensions/scripted-proxies.js
js1_8_5/extensions/typedarray.js
js1_8_5/extensions/clone-object.js
js1_8_5/extensions/clone-errors.js
js1_8_5/extensions/clone-typed-array.js
js1_8_5/regress/regress-500528.js
js1_8_5/regress/regress-533876.js
js1_8_5/regress/regress-541255-0.js
@ -1354,6 +1376,10 @@ js1_8_5/regress/regress-577648-1.js
js1_8_5/regress/regress-577648-2.js
js1_8_5/regress/regress-584355.js
js1_8_5/regress/regress-588339.js
js1_8_5/regress/regress-592217.js
js1_8_5/regress/regress-596805-2.js
js1_8_5/regress/regress-597870.js
js1_8_5/regress/regress-597945-1.js
narcissus/../ecma/Date/15.9.5.10-2.js
narcissus/../ecma/Date/15.9.5.11-2.js
narcissus/../ecma/Date/15.9.5.12-2.js