aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js4
-rw-r--r--src/jsifier.js47
-rw-r--r--src/modules.js1
3 files changed, 29 insertions, 23 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index c5d1d405..c8e31dea 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -628,7 +628,7 @@ function analyzer(data) {
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, line ' + [func.ident, label.ident]);
+ assert(lastLine.intertype in LLVM.BRANCHINGS, 'Only branches can lead to labels with phis, line ' + [func.ident, label.ident]);
lastLine.currLabelId = sourceLabelId;
}
phis.push(line);
@@ -671,7 +671,7 @@ function analyzer(data) {
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, line ' + [func.ident, label.ident]);
+ assert(lastLine.intertype in LLVM.BRANCHINGS, 'Only branches can lead to labels with phis, line ' + [func.ident, label.ident]);
if (!lastLine.phi) {
// We store the phi assignments in the branch's params (which are otherwise unused)
lastLine.phi = true;
diff --git a/src/jsifier.js b/src/jsifier.js
index 7a267e92..a4340623 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -701,30 +701,34 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
}
}
+ function calcPhiSets(item) {
+ if (!item.phi) return null;
+ var phiSets = {};
+ // TODO: Do not always rename them all
+ // TODO: eliminate unneeded sets (to undefined etc.)
+ item.params.forEach(function(param) {
+ if (!phiSets[param.targetLabel]) phiSets[param.targetLabel] = [];
+ phiSets[param.targetLabel].unshift('var ' + param.ident + '$phi = ' + finalizeLLVMParameter(param.value) + ';');
+ phiSets[param.targetLabel].push(param.ident + ' = ' + param.ident + '$phi;');
+ });
+ return phiSets;
+ }
+
+ function getPhiSetsForLabel(phiSets, label) {
+ label = getOldLabel(label);
+ if (!phiSets || !phiSets[label]) return '';
+ return sumStringy(phiSets[label]);
+ }
+
makeFuncLineActor('branch', function(item) {
- var phiSets = null;
- if (item.phi) {
- phiSets = {};
- // TODO: Do not always rename them all
- // TODO: eliminate unneeded sets (to undefined etc.)
- item.params.forEach(function(param) {
- if (!phiSets[param.targetLabel]) phiSets[param.targetLabel] = [];
- phiSets[param.targetLabel].unshift('var ' + param.ident + '$phi = ' + finalizeLLVMParameter(param.value) + ';');
- phiSets[param.targetLabel].push(param.ident + ' = ' + param.ident + '$phi;');
- });
- }
- function getPhiSets(label) {
- label = getOldLabel(label);
- if (!phiSets || !phiSets[label]) return '';
- return sumStringy(phiSets[label]);
- }
- if (item.stolen) return getPhiSets(item.label) || ';'; // We will appear where we were stolen to
+ var phiSets = calcPhiSets(item);
+ if (item.stolen) return getPhiSetsForLabel(phiSets, item.label) || ';'; // We will appear where we were stolen to
if (!item.value) {
- return getPhiSets(item.label) + makeBranch(item.label, item.currLabelId);
+ return getPhiSetsForLabel(phiSets, item.label) + makeBranch(item.label, item.currLabelId);
} else {
var condition = finalizeLLVMParameter(item.value);
- var labelTrue = getPhiSets(item.labelTrue) + makeBranch(item.labelTrue, item.currLabelId);
- var labelFalse = getPhiSets(item.labelFalse) + makeBranch(item.labelFalse, item.currLabelId);
+ var labelTrue = getPhiSetsForLabel(phiSets, item.labelTrue) + makeBranch(item.labelTrue, item.currLabelId);
+ var labelFalse = getPhiSetsForLabel(phiSets, item.labelFalse) + makeBranch(item.labelFalse, item.currLabelId);
if (labelTrue == ';' && labelFalse == ';') return ';';
var head = 'if (' + condition + ') { ';
var head2 = 'if (!(' + condition + ')) { ';
@@ -740,6 +744,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
}
});
makeFuncLineActor('switch', function(item) {
+ var phiSets = calcPhiSets(item);
var ret = '';
var first = true;
item.switchLabels.forEach(function(switchLabel) {
@@ -749,7 +754,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
first = false;
}
ret += 'if (' + item.ident + ' == ' + switchLabel.value + ') {\n';
- ret += ' ' + makeBranch(switchLabel.label, item.currLabelId || null) + '\n';
+ ret += ' ' + getPhiSetsForLabel(phiSets, switchLabel.label) + makeBranch(switchLabel.label, item.currLabelId || null) + '\n';
ret += '}\n';
});
if (item.switchLabels.length > 0) ret += 'else {\n';
diff --git a/src/modules.js b/src/modules.js
index 00f5266e..ba4a95bd 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -12,6 +12,7 @@ var LLVM = {
ACCESS_OPTIONS: set('volatile', 'atomic'),
INVOKE_MODIFIERS: set('alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'),
SHIFTS: set('ashr', 'lshr', 'shl'),
+ BRANCHINGS: set('branch', 'switch'),
EXTENDS: set('sext', 'zext'),
INTRINSICS_32: set('_llvm_memcpy_p0i8_p0i8_i64', '_llvm_memmove_p0i8_p0i8_i64', '_llvm_memset_p0i8_i64'), // intrinsics that need args converted to i32 in I64_MODE 1
};