diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 4 | ||||
-rw-r--r-- | src/jsifier.js | 47 | ||||
-rw-r--r-- | src/modules.js | 1 |
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 }; |