diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-07-01 07:51:10 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-07-01 07:51:10 -0700 |
commit | 1c1d291964d025845228e5e8b985aec066bf79d2 (patch) | |
tree | c187be177043d0cec12d8f730d8b98ea6da56d1b | |
parent | 7d8e65edda5d330787c35a3d9f9aef3ba660d2c2 (diff) |
handle complex expressions in br. fixes issue 39
-rw-r--r-- | src/intertyper.js | 7 | ||||
-rw-r--r-- | src/jsifier.js | 7 | ||||
-rw-r--r-- | src/parseTools.js | 12 | ||||
-rw-r--r-- | tests/issue_39.ll | 37 | ||||
-rw-r--r-- | tests/runner.py | 4 |
5 files changed, 56 insertions, 11 deletions
diff --git a/src/intertyper.js b/src/intertyper.js index 715b6fa4..972b5de6 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -715,11 +715,12 @@ function intertyper(data, parseFunctions, baseLineNum) { lineNum: item.lineNum }]; } else { + var commaIndex = findTokenText(item, ','); return [{ intertype: 'branch', - ident: toNiceIdent(item.tokens[2].text), - labelTrue: toNiceIdent(item.tokens[5].text), - labelFalse: toNiceIdent(item.tokens[8].text), + condition: parseLLVMSegment(item.tokens.slice(1, commaIndex)), + labelTrue: toNiceIdent(item.tokens[commaIndex+2].text), + labelFalse: toNiceIdent(item.tokens[commaIndex+5].text), lineNum: item.lineNum }]; } diff --git a/src/jsifier.js b/src/jsifier.js index 7784c1ab..1b83b991 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -606,14 +606,15 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { makeFuncLineActor('branch', function(item) { if (item.stolen) return ';'; // We will appear where we were stolen to - if (!item.ident) { + if (!item.condition) { return makeBranch(item.label, item.currLabelId); } else { + var condition = finalizeLLVMParameter(item.condition); var labelTrue = makeBranch(item.labelTrue, item.currLabelId); var labelFalse = makeBranch(item.labelFalse, item.currLabelId); if (labelTrue == ';' && labelFalse == ';') return ';'; - var head = 'if (' + item.ident + ') { '; - var head2 = 'if (!(' + item.ident + ')) { '; + var head = 'if (' + condition + ') { '; + var head2 = 'if (!(' + condition + ')) { '; var else_ = ' } else { '; var tail = ' }'; if (labelTrue == ';') { diff --git a/src/parseTools.js b/src/parseTools.js index debfb6da..8c8389fb 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -953,7 +953,7 @@ function finalizeLLVMFunctionCall(item) { }; for (var i = 1; i <= 4; i++) { if (item.params[i-1]) { - temp['param' + i] = finalizeLLVMParameter(item.params[i-1]); + temp['param' + i] = item.params[i-1]; } } return processMathop(temp); @@ -1106,8 +1106,10 @@ function isSignedOp(op, variant) { } function processMathop(item) { with(item) { + var paramTypes = ['', '', '', '']; for (var i = 1; i <= 4; i++) { if (item['param'+i]) { + paramTypes[i-1] = item['param'+i].type || type; item['ident'+i] = finalizeLLVMParameter(item['param'+i]); if (!isNumber(item['ident'+i])) { item['ident'+i] = '(' + item['ident'+i] + ')'; // we may have nested expressions. So enforce the order of operations we want @@ -1117,11 +1119,11 @@ function processMathop(item) { with(item) { } } if (isUnsignedOp(op, variant)) { - ident1 = makeSignOp(ident1, type, 'un'); - ident2 = makeSignOp(ident2, type, 'un'); + ident1 = makeSignOp(ident1, paramTypes[0], 'un'); + ident2 = makeSignOp(ident2, paramTypes[1], 'un'); } else if (isSignedOp(op, variant)) { - ident1 = makeSignOp(ident1, type, 're'); - ident2 = makeSignOp(ident2, type, 're'); + ident1 = makeSignOp(ident1, paramTypes[0], 're'); + ident2 = makeSignOp(ident2, paramTypes[1], 're'); } var bits = null; if (item.type[0] === 'i') { diff --git a/tests/issue_39.ll b/tests/issue_39.ll new file mode 100644 index 00000000..96460693 --- /dev/null +++ b/tests/issue_39.ll @@ -0,0 +1,37 @@ +; ModuleID = '/dev/shm/tmp/src.cpp.o' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-f128:128:128-n8:16:32" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [6 x i8] c"*yes*\00", align 1 ; [#uses=1] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %x = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 5, i32* %x, align 4 + %1 = load i32* %x, align 4 ; [#uses=1] + br i1 icmp sgt (i32 %1, i32 3), label %bb, label %bb1 + +bb: ; preds = %entry + %3 = call i32 @puts(i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)) ; [#uses=0] + br label %bb1 + +bb1: ; preds = %bb, %entry + store i32 0, i32* %0, align 4 + %4 = load i32* %0, align 4 ; [#uses=1] + store i32 %4, i32* %retval, align 4 + br label %return + +return: ; preds = %bb1 + %retval2 = load i32* %retval ; [#uses=1] + ret i32 %retval2 +} + +; [#uses=1] +declare i32 @puts(i8*) + +; br i1 icmp ne (%16* bitcast (%11* @PyFloat_Type to %16*), %16* @PyBaseObject_Type), label %bb6, label %bb14 + diff --git a/tests/runner.py b/tests/runner.py index fdf15d44..60b97b63 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -642,6 +642,10 @@ if 'benchmark' not in sys.argv: ''' self.do_test(src, '*yes*') + # Test for issue 39 + if not LLVM_OPTS: + self.do_ll_test(path_from_root('tests', 'issue_39.ll'), '*yes*') + def test_if_else(self): src = ''' #include <stdio.h> |