aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js18
-rw-r--r--src/intertyper.js5
-rw-r--r--src/jsifier.js42
3 files changed, 38 insertions, 27 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 2ee43d6c..c8529dd5 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -282,13 +282,25 @@ function analyzer(data) {
substrate.addZyme('LabelAnalyzer', {
processItem: function(item) {
item.functions.forEach(function(func) {
+ func.labelsDict = {};
+ func.labels.forEach(function(label) {
+ func.labelsDict[label.ident] = label;
+ });
func.hasPhi = false;
func.remarkableLabels = [];
func.labels.forEach(function(label) {
label.lines.forEach(function(line) {
if (line.value && line.value.intertype == 'phi') {
for (var i = 0; i < line.value.params.length; i++) {
- func.remarkableLabels.push(line.value.params[i].label);
+ var remarkableLabelId = line.value.params[i].label;
+ func.remarkableLabels.push(remarkableLabelId);
+ var remarkableLabel = func.labelsDict[remarkableLabelId];
+ var lastLine = remarkableLabel.lines.slice(-1)[0];
+ if (lastLine.value) {
+ lastLine.value.currLabelId = remarkableLabelId;
+ } else {
+ lastLine.currLabelId = remarkableLabelId;
+ }
}
func.hasPhi = true;
}
@@ -698,10 +710,6 @@ function analyzer(data) {
// TODO: each of these can be run in parallel
item.functions.forEach(function(func) {
dprint('relooping', "// relooping function: " + func.ident);
- func.labelsDict = {};
- func.labels.forEach(function(label) {
- func.labelsDict[label.ident] = label;
- });
func.block = makeBlock(func.labels, [toNiceIdent(func.labels[0].ident)], func.labelsDict);
});
diff --git a/src/intertyper.js b/src/intertyper.js
index be2045f2..b20f9391 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -523,9 +523,10 @@ function intertyper(data) {
item.type = item.tokens[1].text;
var last = getTokenIndexByText(item.tokens, ';');
item.params = splitTokenList(item.tokens.slice(2, last)).map(function(segment) {
+ var subSegments = splitTokenList(segment[0].item.tokens);
return {
- label: toNiceIdent(segment[0].item.tokens[2].text),
- value: toNiceIdent(segment[0].item.tokens[0].text),
+ label: toNiceIdent(subSegments[1][0].text),
+ value: parseLLVMSegment(subSegments[0]),
};
});
this.forwardItem(item, 'Reintegrator');
diff --git a/src/jsifier.js b/src/jsifier.js
index 82330a16..ec9672b3 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -278,10 +278,10 @@ function JSify(data) {
func.JS += ' var __label__;\n';
}
if (hasVarArgs) {
- func.JS += ' __numArgs__ = ' + params.length + ';\n';
+ func.JS += ' var __numArgs__ = ' + params.length + ';\n';
}
if (func.hasPhi) {
- func.JS += ' __lastLabel__ = null;\n';
+ func.JS += ' var __lastLabel__ = null;\n';
}
var usedLabels = {}; // We can get a loop and inside it a multiple, which will try to use the same
@@ -302,9 +302,6 @@ function JSify(data) {
ret += indent + 'if (Date.now() - START_TIME >= ' + (EXECUTION_TIMEOUT*1000) + ') throw "Timed out!" + (new Error().stack);\n';
}
// for special labels we care about (for phi), mark that we visited them
- if (func.remarkableLabels.indexOf(label.ident) >= 0) {
- ret += indent + '__lastLabel__ = ' + getLabelId(label.ident) + ';\n';
- }
return ret + label.lines.map(function(line) { return line.JS + (line.comment ? ' // ' + line.comment : '') })
.join('\n')
.split('\n') // some lines include line breaks
@@ -344,7 +341,7 @@ function JSify(data) {
var intendedTrueLabel = stolen.labelTrue;
assert(block.entryLabels.length <= 2);
[stolen.labelTrue, stolen.labelFalse].forEach(function(entry) {
- var branch = makeBranch(entry);
+ var branch = makeBranch(entry, stolen.currLabelId);
entryLabel = block.entryLabels.filter(function(possible) { return possible.ident === getActualLabelId(entry) })[0];
if (branch.length < 5 && !entryLabel) return;
//ret += indent + multipleIdent + (first ? '' : 'else ') +
@@ -501,35 +498,39 @@ function JSify(data) {
return LABEL_IDs[label] = LABEL_ID_COUNTER ++;
}
- function makeBranch(label) {
+ function makeBranch(label, lastLabel) {
+ var pre = '';
+ if (lastLabel) {
+ pre = '__lastLabel__ = ' + getLabelId(lastLabel) + '; ';
+ }
if (label[0] == 'B') {
var parts = label.split('|');
var trueLabel = parts[1];
var oldLabel = parts[2];
var labelSetting = '__label__ = ' + getLabelId(oldLabel) + '; /* ' + cleanLabel(oldLabel) + ' */ '; // TODO: optimize away
if (label[1] == 'R') {
- return labelSetting + 'break ' + trueLabel + ';';
+ return pre + labelSetting + 'break ' + trueLabel + ';';
} else if (label[1] == 'C') { // CONT
- return labelSetting + 'continue ' + trueLabel + ';';
+ return pre + labelSetting + 'continue ' + trueLabel + ';';
} else if (label[1] == 'N') { // NOPP
- return ';'; // Returning no text might confuse this parser
+ return pre + ';'; // Returning no text might confuse this parser
} else if (label[1] == 'J') { // JSET
- return labelSetting;
+ return pre + labelSetting;
} else {
throw 'Invalid B-op in branch: ' + trueLabel + ',' + oldLabel;
}
} else {
- return '__label__ = ' + getLabelId(label) + '; /* ' + cleanLabel(label) + ' */ break;';
+ return pre + '__label__ = ' + getLabelId(label) + '; /* ' + cleanLabel(label) + ' */ break;';
}
}
makeFuncLineZyme('branch', function(item) {
if (item.stolen) return ';'; // We will appear where we were stolen to
if (!item.ident) {
- return makeBranch(item.label);
+ return makeBranch(item.label, item.currLabelId);
} else {
- var labelTrue = makeBranch(item.labelTrue);
- var labelFalse = makeBranch(item.labelFalse);
+ var labelTrue = makeBranch(item.labelTrue, item.currLabelId);
+ var labelFalse = makeBranch(item.labelFalse, item.currLabelId);
if (labelTrue == ';' && labelFalse == ';') return ';';
var head = 'if (' + item.ident + ') { ';
var head2 = 'if (!(' + item.ident + ')) { ';
@@ -554,11 +555,11 @@ function JSify(data) {
first = false;
}
ret += 'if (' + item.ident + ' == ' + switchLabel.value + ') {\n';
- ret += ' ' + makeBranch(switchLabel.label) + '\n';
+ ret += ' ' + makeBranch(switchLabel.label, item.currLabelId) + '\n';
ret += '}\n';
});
ret += 'else {\n';
- ret += makeBranch(item.defaultLabel) + '\n';
+ ret += makeBranch(item.defaultLabel, item.currLabelId) + '\n';
ret += '}\n';
if (item.value) {
ret += ' ' + toNiceIdent(item.value);
@@ -582,7 +583,8 @@ function JSify(data) {
+ '__THREW__ = false } catch(e) { '
+ '__THREW__ = true; '
+ (EXCEPTION_DEBUG ? 'print("Exception: " + e + " : " + (new Error().stack)); ' : '')
- + '} })(); if (!__THREW__) { ' + makeBranch(item.toLabel) + ' } else { ' + makeBranch(item.unwindLabel) + ' }';
+ + '} })(); if (!__THREW__) { ' + makeBranch(item.toLabel, item.currLabelId)
+ + ' } else { ' + makeBranch(item.unwindLabel, item.currLabelId) + ' }';
return ret;
});
makeFuncLineZyme('load', function(item) {
@@ -613,9 +615,9 @@ function JSify(data) {
var params = item.params;
function makeOne(i) {
if (i === params.length-1) {
- return params[i].value;
+ return finalizeLLVMParameter(params[i].value);
}
- return '__lastLabel__ == ' + getLabelId(params[i].label) + ' ? ' + params[i].value + ' : (' + makeOne(i+1) + ')';
+ return '__lastLabel__ == ' + getLabelId(params[i].label) + ' ? ' + finalizeLLVMParameter(params[i].value) + ' : (' + makeOne(i+1) + ')';
}
return makeOne(0);
});