aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jsifier.js42
-rw-r--r--src/parseTools.js6
2 files changed, 42 insertions, 6 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 2da90219..38cdac35 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -717,10 +717,45 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
if (!phiSets || !phiSets[label]) return '';
var labelSets = phiSets[label];
if (labelSets.length == 1) {
- return 'var ' + labelSets[0].ident + ' = ' + labelSets[0].valueJS + ';';
+ return labelSets[0].ident + ' = ' + labelSets[0].valueJS + ';';
}
- // TODO: optimize number of copies
// TODO: eliminate unneeded sets (to undefined etc.)
+ var deps = {}; // for each ident we will set, which others it depends on
+ var valueJSes = {};
+ labelSets.forEach(function(labelSet) {
+ deps[labelSet.ident] = {};
+ valueJSes[labelSet.ident] = labelSet.valueJS;
+ });
+ labelSets.forEach(function(labelSet) {
+ walkInterdata(labelSet.value, function mark(item) {
+ if (item.intertype == 'value' && item.ident in deps) {
+ deps[labelSet.ident][item.ident] = true;
+ }
+ });
+ });
+ var pre = '', post = '', idents;
+ mainLoop: while ((idents = keys(deps)).length > 0) {
+ function remove(ident) {
+ for (var i = 0; i < idents.length; i++) {
+ delete deps[idents[i]][ident];
+ }
+ delete deps[ident];
+ }
+ for (var i = 0; i < idents.length; i++) {
+ if (keys(deps[idents[i]]).length == 0) {
+ pre = idents[i] + ' = ' + valueJSes[idents[i]] + ';' + pre;
+ remove(idents[i]);
+ continue mainLoop;
+ }
+ }
+ // If we got here, we have circular dependencies, and must break at least one.
+ pre = 'var ' + idents[0] + '$phi = ' + valueJSes[idents[i]] + ';' + pre;
+ post += idents[0] + ' = ' + idents[0] + '$phi;';
+ remove(idents[0]);
+ }
+ return pre + post;
+
+ /* // Safe, unoptimized copying
var ret = '';
for (var i = 0; i < labelSets.length-1; i++) {
ret += 'var ' + labelSets[i].ident + '$phi = ' + labelSets[i].valueJS + ';';
@@ -729,7 +764,8 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
for (var i = 0; i < labelSets.length-1; i++) {
ret += labelSets[i].ident + ' = ' + labelSets[i].ident + '$phi;';
}
- return '/* phi */' + ret;
+ return ret;
+ */
}
makeFuncLineActor('branch', function(item) {
diff --git a/src/parseTools.js b/src/parseTools.js
index e3734e0e..07855c70 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1692,9 +1692,9 @@ function processMathop(item) { with(item) {
// TODO: Use this in analyzer, possibly also in jsifier
function walkInterdata(item, pre, post, obj) {
if (!item || !item.intertype) return false;
- if (pre(item, obj)) return true;
+ if (pre && pre(item, obj)) return true;
var originalObj = obj;
- if (obj.replaceWith) obj = obj.replaceWith; // allow pre to replace the object we pass to all its children
+ if (obj && obj.replaceWith) obj = obj.replaceWith; // allow pre to replace the object we pass to all its children
if (item.value && walkInterdata(item.value, pre, post, obj)) return true;
var i;
for (i = 1; i <= 4; i++) {
@@ -1712,7 +1712,7 @@ function walkInterdata(item, pre, post, obj) {
if (walkInterdata(box, pre, post, obj)) return true;
}
}
- return post(item, originalObj, obj);
+ return post && post(item, originalObj, obj);
}
function parseBlockAddress(segment) {