aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analyzer.js52
-rw-r--r--src/jsifier.js22
2 files changed, 51 insertions, 23 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 1195c68b..6cfb2b6d 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -621,19 +621,15 @@ function analyzer(data) {
// we need __lastLabel__.
func.needsLastLabel = false;
func.labels.forEach(function(label) {
- var phis = [];
+ var phis = [], phi;
label.lines.forEach(function(line) {
- if (line.value && line.value.intertype == 'phi') {
- for (var i = 0; i < line.value.params.length; i++) {
- var remarkableLabelId = line.value.params[i].label;
- var remarkableLabel = func.labelsDict[remarkableLabelId];
- assert(remarkableLabel);
- var lastLine = remarkableLabel.lines.slice(-1)[0];
- if (lastLine.intertype === 'assign') {
- lastLine.value.currLabelId = remarkableLabelId;
- } else {
- lastLine.currLabelId = remarkableLabelId;
- }
+ if ((phi = line.value) && phi.intertype == 'phi') {
+ for (var i = 0; i < phi.params.length; i++) {
+ var sourceLabelId = phi.params[i].label;
+ var sourceLabel = func.labelsDict[sourceLabelId];
+ var lastLine = sourceLabel.lines.slice(-1)[0];
+ assert(lastLine.intertype == 'branch', 'Only branches can lead to labels with phis');
+ lastLine.currLabelId = sourceLabelId;
}
phis.push(line);
func.needsLastLabel = true;
@@ -661,8 +657,36 @@ function analyzer(data) {
}
}
});
- } else { // MICRO_OPTS
- assert(0, 'TODO');
+ } else {
+ // MICRO_OPTS == 1: Properly implement phis, by pushing them back into the branch
+ // that leads to here. We will only have the |var| definition in this location.
+
+ // First, push phis back
+ func.labels.forEach(function(label) {
+ label.lines.forEach(function(line) {
+ var phi;
+ if ((phi = line.value) && phi.intertype == 'phi') {
+ for (var i = 0; i < phi.params.length; i++) {
+ var param = phi.params[i];
+ var sourceLabelId = param.label;
+ var sourceLabel = func.labelsDict[sourceLabelId];
+ var lastLine = sourceLabel.lines.slice(-1)[0];
+ assert(lastLine.intertype == 'branch', 'Only branches can lead to labels with phis');
+ if (!lastLine.phi) {
+ // We store the phi assignments in the branch's params (which are otherwise unused)
+ lastLine.phi = true;
+ assert(!lastLine.params);
+ lastLine.params = [];
+ };
+ lastLine.params.push({
+ intertype: 'phiassign',
+ ident: line.ident,
+ value: param.value
+ });
+ }
+ }
+ });
+ });
}
});
this.forwardItem(item, 'StackAnalyzer');
diff --git a/src/jsifier.js b/src/jsifier.js
index 604e8b8c..d158a9b9 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -671,7 +671,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
function makeBranch(label, lastLabel, labelIsVariable) {
var pre = '';
- if (lastLabel) {
+ if (!MICRO_OPTS && lastLabel) {
pre = '__lastLabel__ = ' + getLabelId(lastLabel) + '; ';
}
if (label[0] == 'B') {
@@ -819,16 +819,20 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
});
makeFuncLineActor('phi', function(item) {
var params = item.params;
- function makeOne(i) {
- if (i === params.length-1) {
- return finalizeLLVMParameter(params[i].value);
+ if (!MICRO_OPTS) {
+ function makeOne(i) {
+ if (i === params.length-1) {
+ return finalizeLLVMParameter(params[i].value);
+ }
+ return '__lastLabel__ == ' + getLabelId(params[i].label) + ' ? ' +
+ finalizeLLVMParameter(params[i].value) + ' : (' + makeOne(i+1) + ')';
}
- return '__lastLabel__ == ' + getLabelId(params[i].label) + ' ? ' +
- finalizeLLVMParameter(params[i].value) + ' : (' + makeOne(i+1) + ')';
+ var ret = makeOne(0);
+ if (item.postSet) ret += item.postSet;
+ return ret;
+ } else { // MICRO_OPTS == 1
+ assert(0, 'TODO');
}
- var ret = makeOne(0);
- if (item.postSet) ret += item.postSet;
- return ret;
});
makeFuncLineActor('mathop', processMathop);