diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-08-31 17:53:41 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-08-31 17:53:41 -0700 |
commit | 7565b00cce206bb7fd8899ba121e412996d0d8e2 (patch) | |
tree | 3389e5916e24b65edb8e6dd1b293f4f8240e6282 | |
parent | 1e7f45eb40bf8597ae7b1263e9e546737979851c (diff) |
initial work to support resume, landingpad and insertvalue
-rw-r--r-- | src/analyzer.js | 3 | ||||
-rw-r--r-- | src/intertyper.js | 43 | ||||
-rw-r--r-- | src/jsifier.js | 16 | ||||
-rw-r--r-- | src/preamble.js | 1 | ||||
-rw-r--r-- | src/settings.js | 2 |
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 |