Bug 573569: One-pass SSA builder for Narcissus. (r=gal)

This commit is contained in:
Shu-yu Guo 2010-09-23 13:19:05 -07:00
parent d66fd134da
commit f0f46d8ec8
4 changed files with 3207 additions and 10 deletions

View File

@ -112,6 +112,9 @@ Narcissus.definitions = (function() {
// Terminals.
"IDENTIFIER", "NUMBER", "STRING", "REGEXP",
// SSA fiction.
"PHI", "INTERVENED",
// Keywords.
"break",
"case", "catch", "const", "continue",

View File

@ -1,5 +1,5 @@
/* -*- Mode: JS; tab-width: 4; indent-tabs-mode: nil; -*-
* vim: set sw=4 ts=8 et tw=78:
* vim: set sw=4 ts=4 et tw=78:
/* ***** BEGIN LICENSE BLOCK *****
*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -140,7 +140,7 @@ Narcissus.interpreter = (function() {
return s;
},
//Don't want to proxy RegExp or some features won't work
// Don't want to proxy RegExp or some features won't work
RegExp: RegExp,
// Extensions to ECMA.
@ -307,6 +307,22 @@ Narcissus.interpreter = (function() {
: new TypeError(message);
}
function valuatePhis(n, v) {
var ps = n.phiUses;
if (!ps)
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
// thus we should break.
if (ps[i].v === v)
break;
ps[i].v = v;
valuatePhis(ps[i], v);
}
}
function execute(n, x) {
var a, f, i, j, r, s, t, u, v;
@ -818,11 +834,22 @@ Narcissus.interpreter = (function() {
break;
case IDENTIFIER:
for (s = x.scope; s; s = s.parent) {
if (n.value in s.object)
break;
// Identifiers with forward pointers that weren't intervened can't be
// lvalues, so we safely get the cached value directly.
var resolved = n.resolve();
if (n.forward && !resolved.intervened &&
!(resolved.type == FUNCTION &&
resolved.functionForm == parser.DECLARED_FORM)) {
v = resolved.v;
break;
} else {
for (s = x.scope; s; s = s.parent) {
if (n.value in s.object)
break;
}
v = new Reference(s && s.object, n.value, n);
}
v = new Reference(s && s.object, n.value, n);
break;
case NUMBER:
@ -839,6 +866,11 @@ Narcissus.interpreter = (function() {
throw "PANIC: unknown operation " + n.type + ": " + uneval(n);
}
if (n.backwards) {
n.v = v;
}
valuatePhis(n, v);
return v;
}
@ -864,6 +896,21 @@ Narcissus.interpreter = (function() {
definitions.defineProperty(proto, "constructor", this, false, false, true);
}
function getPropertyDescriptor(obj, name) {
while (obj) {
if (({}).hasOwnProperty.call(obj, name))
return Object.getOwnPropertyDescriptor(obj, name);
obj = Object.getPrototypeOf(obj);
}
}
function getOwnProperties(obj) {
var map = {};
for (var name in Object.getOwnPropertyNames(obj))
map[name] = Object.getOwnPropertyDescriptor(obj, name);
return map;
}
// Returns a new function wrapped with a Proxy.
function newFunction(n, x) {
var fobj = new FunctionObject(n, x.scope);
@ -1098,4 +1145,3 @@ Narcissus.interpreter = (function() {
};
}());

View File

@ -94,8 +94,10 @@ Narcissus.lexer = (function() {
},
mustMatch: function (tt) {
if (!this.match(tt))
throw this.newSyntaxError("Missing " + tokens[tt].toLowerCase());
if (!this.match(tt)) {
throw this.newSyntaxError("Missing " +
definitions.tokens[tt].toLowerCase());
}
return this.token;
},
@ -466,4 +468,3 @@ Narcissus.lexer = (function() {
return { Tokenizer: Tokenizer };
}());

3147
js/narcissus/jsssa.js Normal file

File diff suppressed because it is too large Load Diff