purego_llvm.go raw
1 //go:build purego
2
3 package llvm
4
5 import (
6 "fmt"
7 "os"
8 "unsafe"
9
10 "github.com/ebitengine/purego"
11 )
12
13 type (
14 Context struct{ C uintptr }
15 Module struct{ C uintptr }
16 Type struct{ C uintptr }
17 Value struct{ C uintptr }
18 BasicBlock struct{ C uintptr }
19 Builder struct{ C uintptr }
20 Metadata struct{ C uintptr }
21 Attribute struct{ C uintptr }
22 Comdat struct{ C uintptr }
23 MemoryBuffer struct{ C uintptr }
24 PassManager struct{ C uintptr }
25 Use struct{ C uintptr }
26 )
27
28 var Version string
29
30 type DebugLoc struct {
31 Line, Col uint
32 Scope Metadata
33 InlinedAt Metadata
34 }
35
36 func (c Context) IsNil() bool { return c.C == 0 }
37 func (m Module) IsNil() bool { return m.C == 0 }
38 func (t Type) IsNil() bool { return t.C == 0 }
39 func (v Value) IsNil() bool { return v.C == 0 }
40 func (b BasicBlock) IsNil() bool { return b.C == 0 }
41 func (b Builder) IsNil() bool { return b.C == 0 }
42 func (m Metadata) IsNil() bool { return m.C == 0 }
43 func (a Attribute) IsNil() bool { return a.C == 0 }
44 func (c Comdat) IsNil() bool { return c.C == 0 }
45 func (m MemoryBuffer) IsNil() bool { return m.C == 0 }
46 func (p PassManager) IsNil() bool { return p.C == 0 }
47 func (u Use) IsNil() bool { return u.C == 0 }
48
49 type TypeKind int
50
51 const (
52 VoidTypeKind TypeKind = 0
53 HalfTypeKind TypeKind = 1
54 FloatTypeKind TypeKind = 2
55 DoubleTypeKind TypeKind = 3
56 X86_FP80TypeKind TypeKind = 4
57 FP128TypeKind TypeKind = 5
58 PPC_FP128TypeKind TypeKind = 6
59 LabelTypeKind TypeKind = 7
60 IntegerTypeKind TypeKind = 8
61 FunctionTypeKind TypeKind = 9
62 StructTypeKind TypeKind = 10
63 ArrayTypeKind TypeKind = 11
64 PointerTypeKind TypeKind = 12
65 VectorTypeKind TypeKind = 13
66 MetadataTypeKind TypeKind = 14
67 TokenTypeKind TypeKind = 16
68 )
69
70 type Opcode int
71
72 const (
73 Ret Opcode = 1
74 Br Opcode = 2
75 Switch Opcode = 3
76 IndirectBr Opcode = 4
77 Invoke Opcode = 5
78 Unreachable Opcode = 7
79 Add Opcode = 8
80 FAdd Opcode = 9
81 Sub Opcode = 10
82 FSub Opcode = 11
83 Mul Opcode = 12
84 FMul Opcode = 13
85 UDiv Opcode = 14
86 SDiv Opcode = 15
87 FDiv Opcode = 16
88 URem Opcode = 17
89 SRem Opcode = 18
90 FRem Opcode = 19
91 Shl Opcode = 20
92 LShr Opcode = 21
93 AShr Opcode = 22
94 And Opcode = 23
95 Or Opcode = 24
96 Xor Opcode = 25
97 Alloca Opcode = 26
98 Load Opcode = 27
99 Store Opcode = 28
100 GEP Opcode = 29
101 GetElementPtr Opcode = 29
102 Trunc Opcode = 30
103 ZExt Opcode = 31
104 SExt Opcode = 32
105 FPToUI Opcode = 33
106 FPToSI Opcode = 34
107 UIToFP Opcode = 35
108 SIToFP Opcode = 36
109 FPTrunc Opcode = 37
110 FPExt Opcode = 38
111 PtrToInt Opcode = 39
112 IntToPtr Opcode = 40
113 BitCast Opcode = 41
114 ICmp Opcode = 42
115 FCmp Opcode = 43
116 PHI Opcode = 44
117 Call Opcode = 45
118 Select Opcode = 46
119 VAArg Opcode = 49
120 ExtractElement Opcode = 50
121 InsertElement Opcode = 51
122 ShuffleVector Opcode = 52
123 ExtractValue Opcode = 53
124 InsertValue Opcode = 54
125 Resume Opcode = 58
126 LandingPad Opcode = 59
127 CleanupRet Opcode = 61
128 CatchRet Opcode = 62
129 CatchPad Opcode = 63
130 CleanupPad Opcode = 64
131 CatchSwitch Opcode = 65
132 )
133
134 type Linkage int
135
136 const (
137 ExternalLinkage Linkage = 0
138 AvailableExternallyLinkage Linkage = 1
139 LinkOnceAnyLinkage Linkage = 2
140 LinkOnceODRLinkage Linkage = 3
141 WeakAnyLinkage Linkage = 5
142 WeakODRLinkage Linkage = 6
143 AppendingLinkage Linkage = 7
144 InternalLinkage Linkage = 8
145 PrivateLinkage Linkage = 9
146 ExternalWeakLinkage Linkage = 12
147 CommonLinkage Linkage = 14
148 )
149
150 type Visibility int
151
152 const (
153 DefaultVisibility Visibility = 0
154 HiddenVisibility Visibility = 1
155 ProtectedVisibility Visibility = 2
156 )
157
158 type CallConv int
159
160 const (
161 CCallConv CallConv = 0
162 FastCallConv CallConv = 8
163 ColdCallConv CallConv = 9
164 X86StdcallCallConv CallConv = 64
165 X86FastcallCallConv CallConv = 65
166 )
167
168 type IntPredicate int
169
170 const (
171 IntEQ IntPredicate = 32
172 IntNE IntPredicate = 33
173 IntUGT IntPredicate = 34
174 IntUGE IntPredicate = 35
175 IntULT IntPredicate = 36
176 IntULE IntPredicate = 37
177 IntSGT IntPredicate = 38
178 IntSGE IntPredicate = 39
179 IntSLT IntPredicate = 40
180 IntSLE IntPredicate = 41
181 )
182
183 type FloatPredicate int
184
185 const (
186 FloatPredicateFalse FloatPredicate = 0
187 FloatOEQ FloatPredicate = 1
188 FloatOGT FloatPredicate = 2
189 FloatOGE FloatPredicate = 3
190 FloatOLT FloatPredicate = 4
191 FloatOLE FloatPredicate = 5
192 FloatONE FloatPredicate = 6
193 FloatORD FloatPredicate = 7
194 FloatUNO FloatPredicate = 8
195 FloatUEQ FloatPredicate = 9
196 FloatUGT FloatPredicate = 10
197 FloatUGE FloatPredicate = 11
198 FloatULT FloatPredicate = 12
199 FloatULE FloatPredicate = 13
200 FloatUNE FloatPredicate = 14
201 FloatPredicateTrue FloatPredicate = 15
202 )
203
204 type AtomicRMWBinOp int
205
206 const (
207 AtomicRMWBinOpXchg AtomicRMWBinOp = 0
208 AtomicRMWBinOpAdd AtomicRMWBinOp = 1
209 AtomicRMWBinOpSub AtomicRMWBinOp = 2
210 AtomicRMWBinOpAnd AtomicRMWBinOp = 3
211 AtomicRMWBinOpNand AtomicRMWBinOp = 4
212 AtomicRMWBinOpOr AtomicRMWBinOp = 5
213 AtomicRMWBinOpXor AtomicRMWBinOp = 6
214 AtomicRMWBinOpMax AtomicRMWBinOp = 7
215 AtomicRMWBinOpMin AtomicRMWBinOp = 8
216 AtomicRMWBinOpUMax AtomicRMWBinOp = 9
217 AtomicRMWBinOpUMin AtomicRMWBinOp = 10
218 )
219
220 type AtomicOrdering int
221
222 const (
223 AtomicOrderingNotAtomic AtomicOrdering = 0
224 AtomicOrderingUnordered AtomicOrdering = 1
225 AtomicOrderingMonotonic AtomicOrdering = 2
226 AtomicOrderingAcquire AtomicOrdering = 4
227 AtomicOrderingRelease AtomicOrdering = 5
228 AtomicOrderingAcquireRelease AtomicOrdering = 6
229 AtomicOrderingSequentiallyConsistent AtomicOrdering = 7
230 )
231
232 type ComdatSelectionKind int
233
234 const (
235 AnyComdatSelectionKind ComdatSelectionKind = 0
236 ExactMatchComdatSelectionKind ComdatSelectionKind = 1
237 LargestComdatSelectionKind ComdatSelectionKind = 2
238 NoDeduplicateComdatSelectionKind ComdatSelectionKind = 3
239 SameSizeComdatSelectionKind ComdatSelectionKind = 4
240 )
241
242 type LandingPadClause int
243
244 const (
245 LandingPadCatch LandingPadClause = 0
246 LandingPadFilter LandingPadClause = 1
247 )
248
249 type InlineAsmDialect int
250
251 const (
252 InlineAsmDialectATT InlineAsmDialect = 0
253 InlineAsmDialectIntel InlineAsmDialect = 1
254 )
255
256 var (
257 libLLVM uintptr
258 libGlue uintptr
259 initDone bool
260 initErr error
261 )
262
263 func Init(llvmPath, gluePath string) error {
264 if initDone {
265 return initErr
266 }
267 initDone = true
268 var err error
269 libLLVM, err = purego.Dlopen(llvmPath, purego.RTLD_NOW|purego.RTLD_GLOBAL)
270 if err != nil {
271 initErr = fmt.Errorf("dlopen %s: %w", llvmPath, err)
272 return initErr
273 }
274 if gluePath != "" {
275 libGlue, err = purego.Dlopen(gluePath, purego.RTLD_NOW|purego.RTLD_GLOBAL)
276 if err != nil {
277 initErr = fmt.Errorf("dlopen %s: %w", gluePath, err)
278 return initErr
279 }
280 }
281 registerAll()
282 return nil
283 }
284
285 func mustSym(lib uintptr, name string) uintptr {
286 sym, err := purego.Dlsym(lib, name)
287 if err != nil {
288 fmt.Fprintf(os.Stderr, "llvmpure: missing symbol %s: %v\n", name, err)
289 os.Exit(1)
290 }
291 return sym
292 }
293
294 func trySym(lib uintptr, name string) uintptr {
295 sym, _ := purego.Dlsym(lib, name)
296 return sym
297 }
298
299 func goString(ptr uintptr) string {
300 if ptr == 0 {
301 return ""
302 }
303 p := (*byte)(unsafe.Pointer(ptr))
304 n := 0
305 for {
306 if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(n))) == 0 {
307 break
308 }
309 n++
310 }
311 return string((*[1 << 30]byte)(unsafe.Pointer(p))[:n:n])
312 }
313
314 func cString(s string) uintptr {
315 b := append([]byte(s), 0)
316 return uintptr(unsafe.Pointer(&b[0]))
317 }
318
319 func boolToInt(b bool) uintptr {
320 if b {
321 return 1
322 }
323 return 0
324 }
325
326 func typeRefPtr(types []Type) uintptr {
327 if len(types) == 0 {
328 return 0
329 }
330 return uintptr(unsafe.Pointer(&types[0]))
331 }
332
333 func valueRefPtr(values []Value) uintptr {
334 if len(values) == 0 {
335 return 0
336 }
337 return uintptr(unsafe.Pointer(&values[0]))
338 }
339
340 func metadataRefPtr(mds []Metadata) uintptr {
341 if len(mds) == 0 {
342 return 0
343 }
344 return uintptr(unsafe.Pointer(&mds[0]))
345 }
346