diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-06-03 19:25:21 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-06-03 19:25:21 -0700 |
commit | acaee4231b16bfb0fd5fc2bb0afd8dec7a665c84 (patch) | |
tree | 9a2a7a2fa22b59abbceebe50dec76499975948f4 | |
parent | cafdc3cca8493da19187880d99a32f021f706ce6 (diff) |
refactor call and invoke into a single method, so invoke supports all possible inputs
-rw-r--r-- | src/intertyper.js | 120 | ||||
-rw-r--r-- | tests/cases/invokebitcast.ll | 41 |
2 files changed, 94 insertions, 67 deletions
diff --git a/src/intertyper.js b/src/intertyper.js index 0058eec2..44fbeafb 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -552,81 +552,67 @@ function intertyper(data, parseFunctions, baseLineNum) { this.forwardItem(item, 'Reintegrator'); } }); - // 'call' + // 'call', 'invoke' + function makeCall(item, type) { + item.intertype = type; + if (['tail'].indexOf(item.tokens[0].text) != -1) { + item.tokens.splice(0, 1); + } + assertEq(item.tokens[0].text, type); + while (item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) { + item.tokens.splice(1, 1); + } + item.type = item.tokens[1].text; + Types.needAnalysis[item.type] = 0; + item.functionType = ''; + while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1 && !(item.tokens[2].text in PARSABLE_LLVM_FUNCTIONS)) { + // We cannot compile assembly. If you hit this, perhaps tell the compiler not + // to generate arch-specific code? |-U__i386__ -U__x86_64__| might help, it undefines + // the standard archs. + assert(item.tokens[2].text != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); + + item.functionType += item.tokens[2].text; + item.tokens.splice(2, 1); + } + var tokensLeft = item.tokens.slice(2); + item.ident = eatLLVMIdent(tokensLeft); + // We cannot compile assembly, see above. + assert(item.ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); + if (item.ident.substr(-2) == '()') { + // See comment in isStructType() + item.ident = item.ident.substr(0, item.ident.length-2); + // Also, we remove some spaces which might occur. + while (item.ident[item.ident.length-1] == ' ') { + item.ident = item.ident.substr(0, item.ident.length-1); + } + item.params = []; + } else { + item.params = parseParamTokens(tokensLeft[0].item.tokens); + } + item.ident = toNiceIdent(item.ident); + if (type === 'invoke') { + cleanOutTokens(['alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'], item.tokens, 4); + item.toLabel = toNiceIdent(item.tokens[6].text); + item.unwindLabel = toNiceIdent(item.tokens[9].text); + } + if (item.indent == 2) { + // standalone call - not in assign + item.standalone = true; + return [item]; + } + this.forwardItem(item, 'Reintegrator'); + return null; + } substrate.addActor('Call', { processItem: function(item) { - item.intertype = 'call'; - if (['tail'].indexOf(item.tokens[0].text) != -1) { - item.tokens.splice(0, 1); - } - assertEq(item.tokens[0].text, 'call'); - while (item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) { - item.tokens.splice(1, 1); - } - item.type = item.tokens[1].text; - Types.needAnalysis[item.type] = 0; - item.functionType = ''; - while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1 && !(item.tokens[2].text in PARSABLE_LLVM_FUNCTIONS)) { - // We cannot compile assembly. If you hit this, perhaps tell the compiler not - // to generate arch-specific code? |-U__i386__ -U__x86_64__| might help, it undefines - // the standard archs. - assert(item.tokens[2].text != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); - - item.functionType += item.tokens[2].text; - item.tokens.splice(2, 1); - } - var tokensLeft = item.tokens.slice(2); - item.ident = eatLLVMIdent(tokensLeft); - // We cannot compile assembly, see above. - assert(item.ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); - if (item.ident.substr(-2) == '()') { - // See comment in isStructType() - item.ident = item.ident.substr(0, item.ident.length-2); - // Also, we remove some spaces which might occur. - while (item.ident[item.ident.length-1] == ' ') { - item.ident = item.ident.substr(0, item.ident.length-1); - } - item.params = []; - } else { - item.params = parseParamTokens(tokensLeft[0].item.tokens); - } - item.ident = toNiceIdent(item.ident); - if (item.indent == 2) { - // standalone call - not in assign - item.standalone = true; - return [item]; - } - this.forwardItem(item, 'Reintegrator'); - return null; + return makeCall.call(this, item, 'call'); } }); - // 'invoke' substrate.addActor('Invoke', { processItem: function(item) { - item.intertype = 'invoke'; - item.functionType = ''; - cleanOutTokens(keys(LLVM.CALLING_CONVENTIONS), item.tokens, 1); - while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1) { - item.functionType += item.tokens[2].text; - item.tokens.splice(2, 1); - } - cleanOutTokens(['alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'], item.tokens, 4); - item.type = item.tokens[1].text; - Types.needAnalysis[item.type] = 0; - item.ident = toNiceIdent(item.tokens[2].text); - item.params = parseParamTokens(item.tokens[3].item.tokens); - item.toLabel = toNiceIdent(item.tokens[6].text); - item.unwindLabel = toNiceIdent(item.tokens[9].text); - if (item.indent == 2) { - // standalone call - not in assign - item.standalone = true; - return [item]; - } - this.forwardItem(item, 'Reintegrator'); - return null; + return makeCall.call(this, item, 'invoke'); } }); - // 'alloca' substrate.addActor('Alloca', { processItem: function(item) { diff --git a/tests/cases/invokebitcast.ll b/tests/cases/invokebitcast.ll new file mode 100644 index 00000000..ffb5803f --- /dev/null +++ b/tests/cases/invokebitcast.ll @@ -0,0 +1,41 @@ +; ModuleID = '/dev/shm/tmp/src.cpp.o' +; Just test for compilation here +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" + +%struct.CPU_Regs = type { [8 x %union.GenReg32] } +%union.GenReg32 = type { [1 x i32] } + +@cpu_regs = unnamed_addr global %struct.CPU_Regs zeroinitializer, align 32 ; [#uses=2] +@.str = private unnamed_addr constant [14 x i8] c"hello, world!\00", align 1 ; [#uses=1] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %1 = load i32* bitcast (i32* getelementptr inbounds (%struct.CPU_Regs* @cpu_regs, i32 0, i32 0, i32 1, i32 0, i32 0) to i32*), align 2 ; [#uses=1] + store i16 %1, i16* bitcast (%struct.CPU_Regs* @cpu_regs to i16*), align 2 + %2 = call i32 @puts(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0] + store i32 0, i32* %0, align 4 + %3 = load i32* %0, align 4 ; [#uses=1] + store i32 %3, i32* %retval, align 4 + br label %return + + invoke void bitcast (void (i32*, i32)* @_Z8toStringj to void (i64*, i32)*)(%struct.CPU_Regs* noalias @cpu_regs, i32 %99) + to label %invcont33 unwind label %lpad106 + +invcont33: + ret i32 %retval1 + +lpad106: + ret i32 %retval1 + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +; [#uses=1] +declare i32 @puts(i8*) |