Skip to content

Commit acaee42

Browse files
committed
refactor call and invoke into a single method, so invoke supports all possible inputs
1 parent cafdc3c commit acaee42

File tree

2 files changed

+94
-67
lines changed

2 files changed

+94
-67
lines changed

src/intertyper.js

Lines changed: 53 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -552,81 +552,67 @@ function intertyper(data, parseFunctions, baseLineNum) {
552552
this.forwardItem(item, 'Reintegrator');
553553
}
554554
});
555-
// 'call'
555+
// 'call', 'invoke'
556+
function makeCall(item, type) {
557+
item.intertype = type;
558+
if (['tail'].indexOf(item.tokens[0].text) != -1) {
559+
item.tokens.splice(0, 1);
560+
}
561+
assertEq(item.tokens[0].text, type);
562+
while (item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) {
563+
item.tokens.splice(1, 1);
564+
}
565+
item.type = item.tokens[1].text;
566+
Types.needAnalysis[item.type] = 0;
567+
item.functionType = '';
568+
while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1 && !(item.tokens[2].text in PARSABLE_LLVM_FUNCTIONS)) {
569+
// We cannot compile assembly. If you hit this, perhaps tell the compiler not
570+
// to generate arch-specific code? |-U__i386__ -U__x86_64__| might help, it undefines
571+
// the standard archs.
572+
assert(item.tokens[2].text != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
573+
574+
item.functionType += item.tokens[2].text;
575+
item.tokens.splice(2, 1);
576+
}
577+
var tokensLeft = item.tokens.slice(2);
578+
item.ident = eatLLVMIdent(tokensLeft);
579+
// We cannot compile assembly, see above.
580+
assert(item.ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
581+
if (item.ident.substr(-2) == '()') {
582+
// See comment in isStructType()
583+
item.ident = item.ident.substr(0, item.ident.length-2);
584+
// Also, we remove some spaces which might occur.
585+
while (item.ident[item.ident.length-1] == ' ') {
586+
item.ident = item.ident.substr(0, item.ident.length-1);
587+
}
588+
item.params = [];
589+
} else {
590+
item.params = parseParamTokens(tokensLeft[0].item.tokens);
591+
}
592+
item.ident = toNiceIdent(item.ident);
593+
if (type === 'invoke') {
594+
cleanOutTokens(['alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'], item.tokens, 4);
595+
item.toLabel = toNiceIdent(item.tokens[6].text);
596+
item.unwindLabel = toNiceIdent(item.tokens[9].text);
597+
}
598+
if (item.indent == 2) {
599+
// standalone call - not in assign
600+
item.standalone = true;
601+
return [item];
602+
}
603+
this.forwardItem(item, 'Reintegrator');
604+
return null;
605+
}
556606
substrate.addActor('Call', {
557607
processItem: function(item) {
558-
item.intertype = 'call';
559-
if (['tail'].indexOf(item.tokens[0].text) != -1) {
560-
item.tokens.splice(0, 1);
561-
}
562-
assertEq(item.tokens[0].text, 'call');
563-
while (item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) {
564-
item.tokens.splice(1, 1);
565-
}
566-
item.type = item.tokens[1].text;
567-
Types.needAnalysis[item.type] = 0;
568-
item.functionType = '';
569-
while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1 && !(item.tokens[2].text in PARSABLE_LLVM_FUNCTIONS)) {
570-
// We cannot compile assembly. If you hit this, perhaps tell the compiler not
571-
// to generate arch-specific code? |-U__i386__ -U__x86_64__| might help, it undefines
572-
// the standard archs.
573-
assert(item.tokens[2].text != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
574-
575-
item.functionType += item.tokens[2].text;
576-
item.tokens.splice(2, 1);
577-
}
578-
var tokensLeft = item.tokens.slice(2);
579-
item.ident = eatLLVMIdent(tokensLeft);
580-
// We cannot compile assembly, see above.
581-
assert(item.ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!');
582-
if (item.ident.substr(-2) == '()') {
583-
// See comment in isStructType()
584-
item.ident = item.ident.substr(0, item.ident.length-2);
585-
// Also, we remove some spaces which might occur.
586-
while (item.ident[item.ident.length-1] == ' ') {
587-
item.ident = item.ident.substr(0, item.ident.length-1);
588-
}
589-
item.params = [];
590-
} else {
591-
item.params = parseParamTokens(tokensLeft[0].item.tokens);
592-
}
593-
item.ident = toNiceIdent(item.ident);
594-
if (item.indent == 2) {
595-
// standalone call - not in assign
596-
item.standalone = true;
597-
return [item];
598-
}
599-
this.forwardItem(item, 'Reintegrator');
600-
return null;
608+
return makeCall.call(this, item, 'call');
601609
}
602610
});
603-
// 'invoke'
604611
substrate.addActor('Invoke', {
605612
processItem: function(item) {
606-
item.intertype = 'invoke';
607-
item.functionType = '';
608-
cleanOutTokens(keys(LLVM.CALLING_CONVENTIONS), item.tokens, 1);
609-
while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1) {
610-
item.functionType += item.tokens[2].text;
611-
item.tokens.splice(2, 1);
612-
}
613-
cleanOutTokens(['alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'], item.tokens, 4);
614-
item.type = item.tokens[1].text;
615-
Types.needAnalysis[item.type] = 0;
616-
item.ident = toNiceIdent(item.tokens[2].text);
617-
item.params = parseParamTokens(item.tokens[3].item.tokens);
618-
item.toLabel = toNiceIdent(item.tokens[6].text);
619-
item.unwindLabel = toNiceIdent(item.tokens[9].text);
620-
if (item.indent == 2) {
621-
// standalone call - not in assign
622-
item.standalone = true;
623-
return [item];
624-
}
625-
this.forwardItem(item, 'Reintegrator');
626-
return null;
613+
return makeCall.call(this, item, 'invoke');
627614
}
628615
});
629-
630616
// 'alloca'
631617
substrate.addActor('Alloca', {
632618
processItem: function(item) {

tests/cases/invokebitcast.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; ModuleID = '/dev/shm/tmp/src.cpp.o'
2+
; Just test for compilation here
3+
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"
4+
target triple = "i386-pc-linux-gnu"
5+
6+
%struct.CPU_Regs = type { [8 x %union.GenReg32] }
7+
%union.GenReg32 = type { [1 x i32] }
8+
9+
@cpu_regs = unnamed_addr global %struct.CPU_Regs zeroinitializer, align 32 ; [#uses=2]
10+
@.str = private unnamed_addr constant [14 x i8] c"hello, world!\00", align 1 ; [#uses=1]
11+
12+
; [#uses=0]
13+
define i32 @main() {
14+
entry:
15+
%retval = alloca i32 ; [#uses=2]
16+
%0 = alloca i32 ; [#uses=2]
17+
%"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
18+
%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]
19+
store i16 %1, i16* bitcast (%struct.CPU_Regs* @cpu_regs to i16*), align 2
20+
%2 = call i32 @puts(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
21+
store i32 0, i32* %0, align 4
22+
%3 = load i32* %0, align 4 ; [#uses=1]
23+
store i32 %3, i32* %retval, align 4
24+
br label %return
25+
26+
invoke void bitcast (void (i32*, i32)* @_Z8toStringj to void (i64*, i32)*)(%struct.CPU_Regs* noalias @cpu_regs, i32 %99)
27+
to label %invcont33 unwind label %lpad106
28+
29+
invcont33:
30+
ret i32 %retval1
31+
32+
lpad106:
33+
ret i32 %retval1
34+
35+
return: ; preds = %entry
36+
%retval1 = load i32* %retval ; [#uses=1]
37+
ret i32 %retval1
38+
}
39+
40+
; [#uses=1]
41+
declare i32 @puts(i8*)

0 commit comments

Comments
 (0)