diff options
-rw-r--r-- | src/analyzer.js | 7 | ||||
-rw-r--r-- | src/jsifier.js | 11 | ||||
-rw-r--r-- | tests/cases/legalizer_ta2.ll | 22 | ||||
-rw-r--r-- | tests/cases/legalizer_ta2.txt | 1 |
4 files changed, 39 insertions, 2 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index a1c009f2..9aa84650 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -290,7 +290,7 @@ function analyzer(data, sidePass) { continue; } // call, return: Return value is in an unlegalized array literal. Not fully optimal. - case 'call': case 'invoke': { + case 'call': { bits = getBits(value.type); var elements = getLegalVars(item.assignTo, bits); var toAdd = [value]; @@ -318,6 +318,11 @@ function analyzer(data, sidePass) { i++; continue; } + case 'invoke': { + // We can't add lines after this, since invoke already modifies control flow. So we handle this in invoke + i++; + continue; + } case 'value': { bits = getBits(value.type); var elements = getLegalVars(item.assignTo, bits); diff --git a/src/jsifier.js b/src/jsifier.js index 56e49788..b93cdf9a 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -969,7 +969,16 @@ function JSify(data, functionsOnly, givenFunctions) { + 'if (typeof e != "number") throw e; ' + 'if (ABORT) throw e; __THREW__ = true; ' + (EXCEPTION_DEBUG ? 'print("Exception: " + e + ", currently at: " + (new Error().stack)); ' : '') - + 'return null } })(); if (!__THREW__) { ' + getPhiSetsForLabel(phiSets, item.toLabel) + makeBranch(item.toLabel, item.currLabelId) + + 'return null } })();'; + if (item.assignTo) { + ret = 'var ' + item.assignTo + ' = ' + ret; + if (isIllegalType(item.type)) { + assert(item.type == 'i64', 'Can only handle i64 invoke among illegal invokes'); + ret += 'var ' + item.assignTo + '$0 = ' + item.assignTo + '[0], ' + item.assignTo + '$1 = ' + item.assignTo + '[1];'; + } + item.assignTo = null; + } + ret += 'if (!__THREW__) { ' + getPhiSetsForLabel(phiSets, item.toLabel) + makeBranch(item.toLabel, item.currLabelId) + ' } else { ' + getPhiSetsForLabel(phiSets, item.unwindLabel) + makeBranch(item.unwindLabel, item.currLabelId) + ' }'; return ret; }); diff --git a/tests/cases/legalizer_ta2.ll b/tests/cases/legalizer_ta2.ll index fbb5dc5d..ae6e9b0c 100644 --- a/tests/cases/legalizer_ta2.ll +++ b/tests/cases/legalizer_ta2.ll @@ -4,6 +4,10 @@ target triple = "i386-pc-linux-gnu" @globaliz = global [300 x i8] zeroinitializer +define i64 @retter() { + ret i64 7017280452245743464 +} + define i32 @main() { entry: %buffer = alloca i8, i32 1000, align 4 @@ -146,6 +150,16 @@ a30: a40: call i32 (i8*)* @puts(i8* %buffer) +; invoke return value + + %inv64 = invoke i64 @retter() + to label %a100 unwind label %a111 + +a100: + store i104 0, i104* bitcast ([300 x i8]* @globaliz to i104*), align 4 ; wipe it out + store i64 %inv64, i64* bitcast ([300 x i8]* @globaliz to i64*), align 4 + call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*)) + ; select %chosen = select i1 %if, i104 %loaded, i104 -1 @@ -158,9 +172,17 @@ a40: %s64 = select i1 %if, i64 %s64a, i64 -1 store i64 %s64, i64* bitcast ([300 x i8]* @globaliz to i64*), align 4 call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*)) + br label %done + +a111: + %aaaa79 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + br label %done +done: ret i32 1 } declare i32 @puts(i8*) +declare i32 @__gxx_personality_v0(...) diff --git a/tests/cases/legalizer_ta2.txt b/tests/cases/legalizer_ta2.txt index c57b20f5..0075107d 100644 --- a/tests/cases/legalizer_ta2.txt +++ b/tests/cases/legalizer_ta2.txt @@ -18,5 +18,6 @@ hello, wor hello, worl 9 hello, war`d +hgfedcba hello, world hello, w |