forked from ballerina-platform/nballerina
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFunction.bal
153 lines (132 loc) · 5.44 KB
/
Function.bal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import ballerina/jballerina.java;
// LLVM C-API don't differentiate between function declarations and definitions
public type FunctionDefn Function;
public type FunctionDecl Function;
function linkageToInt(Linkage linkage) returns int {
match linkage {
"external" => {
return 0;
}
"internal" => {
return 8;
}
}
panic error(string `${<string>linkage} not implemented`);
}
public distinct class Function {
final handle LLVMValueRef;
final FunctionType fnType;
final Context context;
final PointerType ty;
final handle LLVMTypeRef;
function init(handle llvmFunction, FunctionType fnType, Context context, handle llvmType) {
self.LLVMValueRef = llvmFunction;
jLLVMSetFunctionCallConv(llvmFunction, 0);
self.fnType = fnType;
self.context = context;
self.ty = pointerType(fnType);
self.LLVMTypeRef = llvmType;
}
public function getParam(int index) returns Value {
Type paramTy = self.fnType.paramTypes[index];
return new (jLLVMGetParam(self.LLVMValueRef, index), paramTy);
}
public function appendBasicBlock(string? label = ()) returns BasicBlock {
string bbLabel = label ?: "";
BasicBlock bb = new (jLLVMAppendBasicBlockInContext(self.context.LLVMContext, self.LLVMValueRef, java:fromString(bbLabel)));
return bb;
}
public function setLinkage(Linkage linkage) {
int linkageVal = linkageToInt(linkage);
jLLVMSetLinkage(self.LLVMValueRef, linkageVal);
}
public function addEnumAttribute(EnumAttribute attribute) {
int index;
string attributeContent;
match attribute {
["return", var attr] => {
index = 0;
attributeContent = attr;
}
["param", var i, var attr] => {
index = i + 1;
attributeContent = attr;
}
var attr => {
index = -1;
attributeContent = <FunctionEnumAttribute>attr;
}
}
handle attributeName = java:fromString(attributeContent);
int attrKind = jLLVMGetEnumAttributeKindForName(attributeName, attributeContent.length());
handle attr = jLLVMCreateEnumAttribute(self.context.LLVMContext, attrKind, 0);
jLLVMAddAttributeAtIndex(self.LLVMValueRef, index, attr);
}
public function setGC(string? name) {
if name is string {
jLLVMSetGC(self.LLVMValueRef, java:fromString(name));
}
else {
jLLVMSetGC(self.LLVMValueRef, java:fromString(""));
}
}
public function setSubprogram(Metadata metadata) {
jLLVMSetSubprogram(self.LLVMValueRef, metadata.llvmMetadata);
}
}
public distinct class BasicBlock {
handle LLVMBasicBlockRef;
function init(handle bbRef) {
self.LLVMBasicBlockRef = bbRef;
}
}
function jLLVMFunctionType(handle returnType, handle paramTypes, int paramCount, int isVarArg) returns handle = @java:Method {
name: "LLVMFunctionType",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMTypeRef", "org.bytedeco.javacpp.PointerPointer", "int", "int"]
} external;
function jLLVMSetFunctionCallConv(handle fn, int callConvention) = @java:Method {
name: "LLVMSetFunctionCallConv",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMValueRef", "int"]
} external;
function jLLVMGetParam(handle fn, int index) returns handle = @java:Method {
name: "LLVMGetParam",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMValueRef", "int"]
} external;
function jLLVMAppendBasicBlockInContext(handle context, handle fn, handle label) returns handle = @java:Method {
name: "LLVMAppendBasicBlockInContext",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMContextRef", "org.bytedeco.llvm.LLVM.LLVMValueRef", "java.lang.String"]
} external;
function jLLVMSetLinkage(handle global, int linkage) = @java:Method {
name: "LLVMSetLinkage",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMValueRef", "int"]
} external;
function jLLVMGetEnumAttributeKindForName(handle name, int length) returns int = @java:Method {
name: "LLVMGetEnumAttributeKindForName",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["java.lang.String", "long"]
} external;
function jLLVMCreateEnumAttribute(handle context, int kind, int val) returns handle = @java:Method {
name: "LLVMCreateEnumAttribute",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMContextRef", "int", "long"]
} external;
function jLLVMAddAttributeAtIndex(handle fn, int idx, handle attribute) = @java:Method {
name: "LLVMAddAttributeAtIndex",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMValueRef", "int", "org.bytedeco.llvm.LLVM.LLVMAttributeRef"]
} external;
function jLLVMSetGC(handle fn, handle name) = @java:Method {
name: "LLVMSetGC",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMValueRef", "java.lang.String"]
} external;
function jLLVMSetSubprogram(handle fn, handle sp) = @java:Method {
name: "LLVMSetSubprogram",
'class: "org.bytedeco.llvm.global.LLVM",
paramTypes: ["org.bytedeco.llvm.LLVM.LLVMValueRef", "org.bytedeco.llvm.LLVM.LLVMMetadataRef"]
} external;