aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-08-31 17:53:41 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-08-31 17:53:41 -0700
commit7565b00cce206bb7fd8899ba121e412996d0d8e2 (patch)
tree3389e5916e24b65edb8e6dd1b293f4f8240e6282
parent1e7f45eb40bf8597ae7b1263e9e546737979851c (diff)
initial work to support resume, landingpad and insertvalue
-rw-r--r--src/analyzer.js3
-rw-r--r--src/intertyper.js43
-rw-r--r--src/jsifier.js16
-rw-r--r--src/preamble.js1
-rw-r--r--src/settings.js2
5 files changed, 60 insertions, 5 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 8e8f8ac7..4e49c7a4 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -46,6 +46,7 @@ function analyzer(data) {
// Functions & labels
item.functions = [];
var currLabelFinished; // Sometimes LLVM puts a branch in the middle of a label. We need to ignore all lines after that.
+ item.items.sort(function(a, b) { return a.lineNum - b.lineNum });
for (var i = 0; i < item.items.length; i++) {
var subItem = item.items[i];
if (subItem.intertype == 'function') {
@@ -80,7 +81,7 @@ function analyzer(data) {
print('// WARNING: content after a branch in a label, line: ' + subItem.lineNum);
}
} else {
- print("ERROR: what is this? " + JSON.stringify(subItem));
+ throw "ERROR: what is this? " + JSON.stringify(subItem);
}
}
delete item.items;
diff --git a/src/intertyper.js b/src/intertyper.js
index 56443d20..248aad36 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -51,8 +51,10 @@ function intertyper(data, parseFunctions, baseLineNum) {
currFunctionLineNum = i + 1;
}
if (!inFunction || parseFunctions) {
- if (inContinual || new RegExp(/^\ +to.*/g).test(line)) {
- // to after invoke
+ if (inContinual || new RegExp(/^\ +to.*/g).test(line)
+ || new RegExp(/^\ +catch .*/g).test(line)
+ || new RegExp(/^\ +cleanup .*/g).test(line)) {
+ // to after invoke or landingpad second line
ret.slice(-1)[0].lineText += line;
if (new RegExp(/^\ +\]/g).test(line)) { // end of llvm switch
inContinual = false;
@@ -142,7 +144,7 @@ function intertyper(data, parseFunctions, baseLineNum) {
lastToken.text += ' ' + text;
} else if (lastToken && text[text.length-1] == '}') {
var openBrace = tokens.length-1;
- while (tokens[openBrace].text != '{') openBrace --;
+ while (tokens[openBrace].text.substr(-1) != '{') openBrace --;
token = combineTokens(tokens.slice(openBrace+1));
tokens.splice(openBrace, tokens.length-openBrace+1);
tokens.push(token);
@@ -268,6 +270,8 @@ function intertyper(data, parseFunctions, baseLineNum) {
return 'Unreachable';
if (tokensLength >= 3 && token0Text == 'indirectbr')
return 'IndirectBr';
+ if (tokensLength >= 2 && token0Text == 'resume')
+ return 'Resume';
} else if (item.indent === -1) {
if (tokensLength >= 3 &&
(token0Text == 'load' || token1Text == 'load'))
@@ -283,8 +287,12 @@ function intertyper(data, parseFunctions, baseLineNum) {
return 'Alloca';
if (tokensLength >= 3 && token0Text == 'extractvalue')
return 'ExtractValue';
+ if (tokensLength >= 3 && token0Text == 'insertvalue')
+ return 'InsertValue';
if (tokensLength >= 3 && token0Text == 'phi')
return 'Phi';
+ if (tokensLength >= 3 && token0Text == 'landingpad')
+ return 'Landingpad';
} else if (item.indent === 0) {
if ((tokensLength >= 1 && token0Text.substr(-1) == ':') || // LLVM 2.7 format, or llvm-gcc in 2.8
(tokensLength >= 3 && token1Text == '<label>'))
@@ -540,6 +548,20 @@ function intertyper(data, parseFunctions, baseLineNum) {
this.forwardItem(item, 'Reintegrator');
}
});
+ // 'insertvalue'
+ substrate.addActor('InsertValue', {
+ processItem: function(item) {
+ var last = getTokenIndexByText(item.tokens, ';');
+ item.intertype = 'insertvalue';
+ item.type = item.tokens[1].text; // Of the origin aggregate, as well as the result
+ Types.needAnalysis[item.type] = 0;
+ item.ident = toNiceIdent(item.tokens[2].text);
+ var segments = splitTokenList(item.tokens.slice(4, last));
+ item.value = parseLLVMSegment(segments[0]);
+ item.indexes = segments.slice(1);
+ this.forwardItem(item, 'Reintegrator');
+ }
+ });
// 'bitcast'
substrate.addActor('Bitcast', {
processItem: function(item) {
@@ -632,6 +654,15 @@ function intertyper(data, parseFunctions, baseLineNum) {
return makeCall.call(this, item, 'invoke');
}
});
+ // 'landingpad' - just a stub implementation
+ substrate.addActor('Landingpad', {
+ processItem: function(item) {
+ item.intertype = 'landingpad';
+ item.type = item.tokens[1].text;
+ Types.needAnalysis[item.type] = 0;
+ this.forwardItem(item, 'Reintegrator');
+ }
+ });
// 'alloca'
var allocaPossibleVars = ['allocatedNum'];
substrate.addActor('Alloca', {
@@ -757,6 +788,12 @@ function intertyper(data, parseFunctions, baseLineNum) {
}];
}
});
+ // 'resume' - partial implementation
+ substrate.addActor('Resume', {
+ processItem: function(item) {
+ return [{ intertype: 'resume' }];
+ }
+ });
// 'switch'
substrate.addActor('Switch', {
processItem: function(item) {
diff --git a/src/jsifier.js b/src/jsifier.js
index 330597bf..82642f6b 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -701,6 +701,9 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
}
return ret + ';';
});
+ makeFuncLineActor('resume', function(item) {
+ return (EXCEPTION_DEBUG ? 'print("Resuming exception");' : '') + 'throw [0,0];';
+ });
makeFuncLineActor('invoke', function(item) {
// Wrapping in a function lets us easily return values if we are
// in an assignment
@@ -716,6 +719,10 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
+ ' } else { ' + makeBranch(item.unwindLabel, item.currLabelId) + ' }';
return ret;
});
+ makeFuncLineActor('landingpad', function(item) {
+ // Just a stub
+ return '{ f0: 0, f1: 0 }';
+ });
makeFuncLineActor('load', function(item) {
var value = finalizeLLVMParameter(item.pointer);
var impl = item.ident ? getVarImpl(item.funcData, item.ident) : VAR_EMULATED;
@@ -732,6 +739,15 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
// and we emulate them using simple JS objects { f1: , f2: , } etc., for speed
return item.ident + '.f' + item.indexes[0][0].text;
});
+ makeFuncLineActor('insertvalue', function(item) {
+ assert(item.indexes.length == 1); // TODO: see extractvalue
+ var ret, ident;
+ if (item.ident === 'undef') {
+ ident = 'tempValue';
+ ret += ident + ' = ' + makeEmptyStruct(item.type) + ', ';
+ }
+ return item.ident + '.f' + item.indexes[0][0].text + ' = ' + finalizeLLVMParameter(item.value) + ', ' + item.ident;
+ });
makeFuncLineActor('indirectbr', function(item) {
return makeBranch(finalizeLLVMParameter(item.pointer), item.currLabelId, true);
});
diff --git a/src/preamble.js b/src/preamble.js
index 8ab9bce8..dccf2c31 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -288,6 +288,7 @@ var __ATEXIT__ = [];
var ABORT = false;
var undef = 0;
+var tempValue;
function abort(text) {
print(text + ':\n' + (new Error).stack);
diff --git a/src/settings.js b/src/settings.js
index ab532e67..31acfc1a 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -140,7 +140,7 @@ FAKE_X86_FP80 = 0; // Replaces x86_fp80 with double. This loses precision. It is
// (which is nonportable anyhow).
// Compiler debugging options
-DEBUG_TAGS_SHOWING = [];
+DEBUG_TAGS_SHOWING = ['framework', 'frameworkLines'];
// Some useful items:
// framework
// frameworkLines