ruby-llvm 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +28 -0
- data/lib/llvm.rb +15 -0
- data/lib/llvm/analysis.rb +46 -0
- data/lib/llvm/core.rb +520 -0
- data/lib/llvm/core/builder.rb +377 -0
- data/lib/llvm/core/context.rb +29 -0
- data/lib/llvm/core/module.rb +199 -0
- data/lib/llvm/core/pass_manager.rb +30 -0
- data/lib/llvm/core/type.rb +113 -0
- data/lib/llvm/core/value.rb +469 -0
- data/lib/llvm/execution_engine.rb +139 -0
- data/lib/llvm/target.rb +8 -0
- data/lib/llvm/transforms/scalar.rb +119 -0
- metadata +74 -0
@@ -0,0 +1,377 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Builder
|
3
|
+
class << self
|
4
|
+
private :new
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(ptr) # :nodoc:
|
8
|
+
@ptr = ptr
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_ptr # :nodoc:
|
12
|
+
@ptr
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.create
|
16
|
+
new(C.LLVMCreateBuilder())
|
17
|
+
end
|
18
|
+
|
19
|
+
def position_at_end(block)
|
20
|
+
C.LLVMPositionBuilderAtEnd(self, block)
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_insert_block
|
25
|
+
BasicBlock.from_ptr(C.LLVMGetInsertBlock(self))
|
26
|
+
end
|
27
|
+
|
28
|
+
# Terminators
|
29
|
+
|
30
|
+
def ret_void
|
31
|
+
Instruction.from_ptr(C.LLVMBuildRetVoid(self))
|
32
|
+
end
|
33
|
+
|
34
|
+
def ret(val)
|
35
|
+
Instruction.from_ptr(C.LLVMBuildRet(self, val))
|
36
|
+
end
|
37
|
+
|
38
|
+
def aggregate_ret(*vals)
|
39
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer) * vals.size) do |vals_ptr|
|
40
|
+
vals_ptr.write_array_of_pointer(vals)
|
41
|
+
Instruction.from_ptr(C.LLVMBuildAggregateRet(self, vals_ptr, vals.size))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def br(block)
|
46
|
+
Instruction.from_ptr(
|
47
|
+
C.LLVMBuildBr(self, block))
|
48
|
+
end
|
49
|
+
|
50
|
+
def cond(cond, iftrue, iffalse)
|
51
|
+
Instruction.from_ptr(
|
52
|
+
C.LLVMBuildCondBr(self, cond, iftrue, iffalse))
|
53
|
+
end
|
54
|
+
|
55
|
+
def switch(val, block, ncases)
|
56
|
+
SwitchInst.from_ptr(C.LLVMBuildSwitch(self, val, block, ncases))
|
57
|
+
end
|
58
|
+
|
59
|
+
def invoke(fun, args, _then, _catch, name = "")
|
60
|
+
Instruction.from_ptr(
|
61
|
+
C.LLVMBuildInvoke(self,
|
62
|
+
fun, args, args.size, _then, _catch, name))
|
63
|
+
end
|
64
|
+
|
65
|
+
def unwind
|
66
|
+
Instruction.from_ptr(C.LLVMBuildUnwind(self))
|
67
|
+
end
|
68
|
+
|
69
|
+
def unreachable
|
70
|
+
Instruction.from_ptr(C.LLVMBuildUnreachable(self))
|
71
|
+
end
|
72
|
+
|
73
|
+
# Arithmetic
|
74
|
+
|
75
|
+
def add(lhs, rhs, name = "")
|
76
|
+
Instruction.from_ptr(C.LLVMBuildAdd(self, lhs, rhs, name))
|
77
|
+
end
|
78
|
+
|
79
|
+
def nsw_add(lhs, rhs, name = "")
|
80
|
+
Instruction.from_ptr(C.LLVMBuildNSWAdd(self, lhs, rhs, name))
|
81
|
+
end
|
82
|
+
|
83
|
+
def fadd(lhs, rhs, name = "")
|
84
|
+
Instruction.from_ptr(C.LLVMBuildFAdd(self, lhs, rhs, name))
|
85
|
+
end
|
86
|
+
|
87
|
+
def sub(lhs, rhs, name = "")
|
88
|
+
Instruction.from_ptr(C.LLVMBuildSub(self, lhs, rhs, name))
|
89
|
+
end
|
90
|
+
|
91
|
+
def fsub(lhs, rhs, name = "")
|
92
|
+
Instruction.from_ptr(C.LLVMBuildFSub(self, lhs, rhs, name))
|
93
|
+
end
|
94
|
+
|
95
|
+
def mul(lhs, rhs, name = "")
|
96
|
+
Instruction.from_ptr(C.LLVMBuildMul(self, lhs, rhs, name))
|
97
|
+
end
|
98
|
+
|
99
|
+
def fmul(lhs, rhs, name = "")
|
100
|
+
Instruction.from_ptr(C.LLVMBuildFMul(self, lhs, rhs, name))
|
101
|
+
end
|
102
|
+
|
103
|
+
def udiv(lhs, rhs, name = "")
|
104
|
+
Instruction.from_ptr(C.LLVMBuildUDiv(self, lhs, rhs, name))
|
105
|
+
end
|
106
|
+
|
107
|
+
def sdiv(lhs, rhs, name = "")
|
108
|
+
Instruction.from_ptr(C.LLVMBuildSDiv(self, lhs, rhs, name))
|
109
|
+
end
|
110
|
+
|
111
|
+
def exact_sdiv(lhs, rhs, name = "")
|
112
|
+
Instruction.from_ptr(C.LLVMBuildExactSDiv(self, lhs, rhs, name))
|
113
|
+
end
|
114
|
+
|
115
|
+
def fdiv(lhs, rhs, name = "")
|
116
|
+
Instruction.from_ptr(C.LLVMBuildFDiv(self, lhs, rhs, name))
|
117
|
+
end
|
118
|
+
|
119
|
+
def urem(lhs, rhs, name = "")
|
120
|
+
Instruction.from_ptr(C.LLVMBuildURem(self, lhs, rhs, name))
|
121
|
+
end
|
122
|
+
|
123
|
+
def srem(lhs, rhs, name = "")
|
124
|
+
Instruction.from_ptr(C.LLVMBuildSRem(self, lhs, rhs, name))
|
125
|
+
end
|
126
|
+
|
127
|
+
def frem(lhs, rhs, name = "")
|
128
|
+
Instruction.from_ptr(C.LLVMBuildFRem(self, lhs, rhs, name))
|
129
|
+
end
|
130
|
+
|
131
|
+
def shl(lhs, rhs, name = "")
|
132
|
+
Instruction.from_ptr(C.LLVMBuildShl(self, lhs, rhs, name))
|
133
|
+
end
|
134
|
+
|
135
|
+
def lshr(lhs, rhs, name = "")
|
136
|
+
Instruction.from_ptr(C.LLVMBuildLShr(self, lhs, rhs, name))
|
137
|
+
end
|
138
|
+
|
139
|
+
def ashr(lhs, rhs, name = "")
|
140
|
+
Instruction.from_ptr(C.LLVMBuildAShr(self, lhs, rhs, name))
|
141
|
+
end
|
142
|
+
|
143
|
+
def and(lhs, rhs, name = "")
|
144
|
+
Instruction.from_ptr(C.LLVMBuildAnd(self, lhs, rhs, name))
|
145
|
+
end
|
146
|
+
|
147
|
+
def or(lhs, rhs, name = "")
|
148
|
+
Instruction.from_ptr(C.LLVMBuildOr(self, lhs, rhs, name))
|
149
|
+
end
|
150
|
+
|
151
|
+
def xor(lhs, rhs, name = "")
|
152
|
+
Instruction.from_ptr(C.LLVMBuildXor(self, lhs, rhs, name))
|
153
|
+
end
|
154
|
+
|
155
|
+
def neg(arg, name = "")
|
156
|
+
Instruction.from_ptr(C.LLVMBuildNeg(self, arg, name))
|
157
|
+
end
|
158
|
+
|
159
|
+
def not(arg, name = "")
|
160
|
+
Instruction.from_ptr(C.LLVMBuildNot(self, arg, name))
|
161
|
+
end
|
162
|
+
|
163
|
+
# Memory
|
164
|
+
|
165
|
+
def malloc(ty, name = "")
|
166
|
+
Instruction.from_ptr(C.LLVMBuildMalloc(self, LLVM::Type(ty), name))
|
167
|
+
end
|
168
|
+
|
169
|
+
def array_malloc(ty, val, name = "")
|
170
|
+
Instruction.from_ptr(C.LLVMBuildArrayMalloc(self, LLVM::Type(ty), val, name))
|
171
|
+
end
|
172
|
+
|
173
|
+
def alloca(ty, name = "")
|
174
|
+
Instruction.from_ptr(C.LLVMBuildAlloca(self, LLVM::Type(ty), name))
|
175
|
+
end
|
176
|
+
|
177
|
+
def array_alloca(ty, val, name = "")
|
178
|
+
Instruction.from_ptr(C.LLVMBuildArrayAlloca(self, LLVM::Type(ty), val, name))
|
179
|
+
end
|
180
|
+
|
181
|
+
def free(pointer)
|
182
|
+
Instruction.from_ptr(C.LLVMBuildFree(self, pointer))
|
183
|
+
end
|
184
|
+
|
185
|
+
def load(pointer, name = "")
|
186
|
+
Instruction.from_ptr(C.LLVMBuildLoad(self, pointer, name))
|
187
|
+
end
|
188
|
+
|
189
|
+
def store(val, pointer)
|
190
|
+
Instruction.from_ptr(C.LLVMBuildStore(self, val, pointer))
|
191
|
+
end
|
192
|
+
|
193
|
+
def gep(pointer, indices, name = "")
|
194
|
+
indices = Array(indices)
|
195
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer) * indices.size) do |indices_ptr|
|
196
|
+
indices_ptr.write_array_of_pointer(indices)
|
197
|
+
return Instruction.from_ptr(
|
198
|
+
C.LLVMBuildInBoundsGEP(self, pointer, indices_ptr, indices.size, name))
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def inbounds_gep(pointer, indices, name = "")
|
203
|
+
indices = Array(indices)
|
204
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer) * indices.size) do |indices_ptr|
|
205
|
+
indices_ptr.write_array_of_pointer(indices)
|
206
|
+
return Instruction.from_ptr(
|
207
|
+
C.LLVMBuildGEP(self, pointer, indices_ptr, indices.size, name))
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def struct_gep(pointer, idx, name = "")
|
212
|
+
Instruction.from_ptr(C.LLVMBuildStructGEP(self, pointer, idx, name))
|
213
|
+
end
|
214
|
+
|
215
|
+
def global_string(string, name = "")
|
216
|
+
Instruction.from_ptr(C.LLVMBuildGlobalString(self, string, name))
|
217
|
+
end
|
218
|
+
|
219
|
+
def global_string_pointer(string, name = "")
|
220
|
+
Instruction.from_ptr(C.LLVMBuildGlobalStringPointer(self, string, name))
|
221
|
+
end
|
222
|
+
|
223
|
+
# Casts
|
224
|
+
|
225
|
+
def trunc(val, ty, name = "")
|
226
|
+
Instruction.from_ptr(C.LLVMBuildTrunc(self, val, LLVM::Type(ty), name))
|
227
|
+
end
|
228
|
+
|
229
|
+
def zext(val, ty, name = "")
|
230
|
+
Instruction.from_ptr(C.LLVMBuildZExt(self, val, LLVM::Type(ty), name))
|
231
|
+
end
|
232
|
+
|
233
|
+
def sext(val, ty, name = "")
|
234
|
+
Instruction.from_ptr(C.LLVMBuildSExt(self, val, LLVM::Type(ty), name))
|
235
|
+
end
|
236
|
+
|
237
|
+
def fp2ui(val, ty, name = "")
|
238
|
+
Instruction.from_ptr(C.LLVMBuildFPToUI(self, val, LLVM::Type(ty), name))
|
239
|
+
end
|
240
|
+
|
241
|
+
def fp2si(val, ty, name = "")
|
242
|
+
Instruction.from_ptr(C.LLVMBuildFPToSI(self, val, LLVM::Type(ty), name))
|
243
|
+
end
|
244
|
+
|
245
|
+
def ui2fp(val, ty, name = "")
|
246
|
+
Instruction.from_ptr(C.LLVMBuildUIToFP(self, val, LLVM::Type(ty), name))
|
247
|
+
end
|
248
|
+
|
249
|
+
def si2fp(val, ty, name = "")
|
250
|
+
Instruction.from_ptr(C.LLVMBuildSIToFP(self, val, LLVM::Type(ty), name))
|
251
|
+
end
|
252
|
+
|
253
|
+
def fp_trunc(val, ty, name = "")
|
254
|
+
Instruction.from_ptr(C.LLVMBuildFPTrunc(self, val, LLVM::Type(ty), name))
|
255
|
+
end
|
256
|
+
|
257
|
+
def fp_ext(val, ty, name = "")
|
258
|
+
Instruction.from_ptr(C.LLVMBuildFPExt(self, val, LLVM::Type(ty), name))
|
259
|
+
end
|
260
|
+
|
261
|
+
def ptr2int(val, ty, name = "")
|
262
|
+
Instruction.from_ptr(C.LLVMBuildPtrToInt(self, val, LLVM::Type(ty), name))
|
263
|
+
end
|
264
|
+
|
265
|
+
def int2ptr(val, ty, name = "")
|
266
|
+
Instruction.from_ptr(C.LLVMBuildIntToPtr(self, val, LLVM::Type(ty), name))
|
267
|
+
end
|
268
|
+
|
269
|
+
def bit_cast(val, ty, name = "")
|
270
|
+
Instruction.from_ptr(C.LLVMBuildBitCast(self, val, LLVM::Type(ty), name))
|
271
|
+
end
|
272
|
+
|
273
|
+
def zext_or_bit_cast(val, ty, name = "")
|
274
|
+
Instruction.from_ptr(C.LLVMBuildZExtOrBitCast(self, val, LLVM::Type(ty), name))
|
275
|
+
end
|
276
|
+
|
277
|
+
def sext_or_bit_cast(val, ty, name = "")
|
278
|
+
Instruction.from_ptr(C.LLVMBuildSExtOrBitCast(self, val, LLVM::Type(ty), name))
|
279
|
+
end
|
280
|
+
|
281
|
+
def trunc_or_bit_cast(val, ty, name = "")
|
282
|
+
Instruction.from_ptr(C.LLVMBuildTruncOrBitCast(self, val, LLVM::Type(ty), name))
|
283
|
+
end
|
284
|
+
|
285
|
+
def pointer_cast(val, ty, name = "")
|
286
|
+
Instruction.from_ptr(C.LLVMBuildPointerCast(self, val, LLVM::Type(ty), name))
|
287
|
+
end
|
288
|
+
|
289
|
+
def int_cast(val, ty, name = "")
|
290
|
+
Instruction.from_ptr(C.LLVMBuildIntCast(self, val, LLVM::Type(ty), name))
|
291
|
+
end
|
292
|
+
|
293
|
+
def fp_cast(val, ty, name = "")
|
294
|
+
Instruction.from_ptr(C.LLVMBuildFPCast(self, val, LLVM::Type(ty), name))
|
295
|
+
end
|
296
|
+
|
297
|
+
# Comparisons
|
298
|
+
|
299
|
+
def icmp(pred, lhs, rhs, name = "")
|
300
|
+
Instruction.from_ptr(C.LLVMBuildICmp(self, pred, lhs, rhs, name))
|
301
|
+
end
|
302
|
+
|
303
|
+
def fcmp(pred, lhs, rhs, name = "")
|
304
|
+
Instruction.from_ptr(C.LLVMBuildFCmp(self, pred, lhs, rhs, name))
|
305
|
+
end
|
306
|
+
|
307
|
+
# Misc
|
308
|
+
|
309
|
+
def phi(ty, *incoming)
|
310
|
+
if incoming.last.kind_of? String
|
311
|
+
name = incomimg.pop
|
312
|
+
else
|
313
|
+
name = ""
|
314
|
+
end
|
315
|
+
|
316
|
+
phi = Phi.from_ptr(C.LLVMBuildPhi(self, LLVM::Type(ty), name))
|
317
|
+
phi.add_incoming(*incoming) unless incoming.empty?
|
318
|
+
phi
|
319
|
+
end
|
320
|
+
|
321
|
+
def call(fun, *args)
|
322
|
+
if args.last.kind_of? String
|
323
|
+
name = args.pop
|
324
|
+
else
|
325
|
+
name = ""
|
326
|
+
end
|
327
|
+
|
328
|
+
args_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * args.size)
|
329
|
+
args_ptr.write_array_of_pointer(args)
|
330
|
+
CallInst.from_ptr(C.LLVMBuildCall(self, fun, args_ptr, args.size, name))
|
331
|
+
end
|
332
|
+
|
333
|
+
def select(_if, _then, _else, name = "")
|
334
|
+
Instruction.from_ptr(C.LLVMBuildSelect(self, _if, _then, _else, name))
|
335
|
+
end
|
336
|
+
|
337
|
+
def va_arg(list, ty, name = "")
|
338
|
+
Instruction.from_ptr(C.LLVMBuildVAArg(self, list, LLVM::Type(ty), name))
|
339
|
+
end
|
340
|
+
|
341
|
+
def extract_element(vector, index, name = "")
|
342
|
+
Instruction.from_ptr(C.LLVMBuildExtractElement(self, vector, index, name))
|
343
|
+
end
|
344
|
+
|
345
|
+
def insert_element(vector, elem, index, name = "")
|
346
|
+
Instruction.from_ptr(C.LLVMBuildInsertElement(self, vector, elem, index, name))
|
347
|
+
end
|
348
|
+
|
349
|
+
def shuffle_vector(vec1, vec2, mask, name = "")
|
350
|
+
Instruction.from_ptr(C.LLVMBuildShuffleVector(self, vec1, vec2, mask, name))
|
351
|
+
end
|
352
|
+
|
353
|
+
def extract_value(aggregate, index, name = "")
|
354
|
+
Instruction.from_ptr(C.LLVMBuildExtractValue(self, aggregate, index, name))
|
355
|
+
end
|
356
|
+
|
357
|
+
def insert_value(aggregate, elem, index, name = "")
|
358
|
+
Instruction.from_ptr(C.LLVMBuildInsertValue(self, aggregate, elem, index, name))
|
359
|
+
end
|
360
|
+
|
361
|
+
def is_null(val, name = "")
|
362
|
+
Instruction.from_ptr(C.LLVMBuildIsNull(self, val, name))
|
363
|
+
end
|
364
|
+
|
365
|
+
def is_not_null(val, name = "")
|
366
|
+
Instruction.from_ptr(C.LLVMBuildIsNotNull(self, val, name))
|
367
|
+
end
|
368
|
+
|
369
|
+
def ptr_diff(lhs, rhs, name = "")
|
370
|
+
Instruction.from_ptr(C.LLVMBuildPtrDiff(lhs, rhs, name))
|
371
|
+
end
|
372
|
+
|
373
|
+
def dispose
|
374
|
+
C.LLVMDisposeBuilder(@ptr)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Context
|
3
|
+
class << self
|
4
|
+
private :new
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(ptr) # :nodoc:
|
8
|
+
@ptr = ptr
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_ptr # :nodoc:
|
12
|
+
@ptr
|
13
|
+
end
|
14
|
+
|
15
|
+
# Creates a new Context
|
16
|
+
def self.create
|
17
|
+
new(C.LLVMContextCreate())
|
18
|
+
end
|
19
|
+
|
20
|
+
# Obtains a reference to the global Context
|
21
|
+
def self.global
|
22
|
+
new(C.LLVMGetGlobalContext())
|
23
|
+
end
|
24
|
+
|
25
|
+
def dispose
|
26
|
+
C.LLVMContextDispose(@ptr)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Module
|
3
|
+
class << self
|
4
|
+
private :new
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.from_ptr(ptr)
|
8
|
+
ptr.null? ? nil : new(ptr)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(ptr) # :nodoc:
|
12
|
+
@ptr = ptr
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_ptr # :nodoc:
|
16
|
+
@ptr
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.create(name)
|
20
|
+
new(C.LLVMModuleCreateWithName(name))
|
21
|
+
end
|
22
|
+
|
23
|
+
def types
|
24
|
+
@types ||= TypeCollection.new(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
class TypeCollection
|
28
|
+
def initialize(mod)
|
29
|
+
@module = mod
|
30
|
+
end
|
31
|
+
|
32
|
+
def add(name, type)
|
33
|
+
C.LLVMAddTypeName(@module, name.to_s, type)
|
34
|
+
end
|
35
|
+
|
36
|
+
def named(name)
|
37
|
+
Type.from_ptr(C.LLVMGetTypeByName(@module, name))
|
38
|
+
end
|
39
|
+
|
40
|
+
def [](key)
|
41
|
+
case key
|
42
|
+
when String then named(key)
|
43
|
+
when Symbol then named(key.to_s)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def []=(key, type)
|
48
|
+
add(key, type)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def globals
|
53
|
+
@globals ||= GlobalCollection.new(self)
|
54
|
+
end
|
55
|
+
|
56
|
+
class GlobalCollection
|
57
|
+
include Enumerable
|
58
|
+
|
59
|
+
def initialize(mod)
|
60
|
+
@module = mod
|
61
|
+
end
|
62
|
+
|
63
|
+
def add(ty, name)
|
64
|
+
GlobalVariable.from_ptr(C.LLVMAddGlobal(@module, LLVM::Type(ty), name))
|
65
|
+
end
|
66
|
+
|
67
|
+
def named(name)
|
68
|
+
GlobalValue.from_ptr(C.LLVMGetNamedGlobal(@module, name))
|
69
|
+
end
|
70
|
+
|
71
|
+
def first
|
72
|
+
GlobalValue.from_ptr(C.LLVMGetFirstGlobal(@module))
|
73
|
+
end
|
74
|
+
|
75
|
+
def last
|
76
|
+
GlobalValue.from_ptr(C.LLVMGetLastGlobal(@module))
|
77
|
+
end
|
78
|
+
|
79
|
+
def next(global)
|
80
|
+
GlobalValue.from_ptr(C.LLVMGetNextGlobal(global))
|
81
|
+
end
|
82
|
+
|
83
|
+
def previous(global)
|
84
|
+
GlobalValue.from_ptr(C.LLVMGetPreviousGlobal(global))
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete(global)
|
88
|
+
C.LLVMDeleteGlobal(global)
|
89
|
+
end
|
90
|
+
|
91
|
+
def [](key)
|
92
|
+
case key
|
93
|
+
when String then named(key)
|
94
|
+
when Symbol then named(key.to_s)
|
95
|
+
when Integer then
|
96
|
+
i = 0
|
97
|
+
g = first
|
98
|
+
until i >= key || g.nil?
|
99
|
+
g = self.next(g)
|
100
|
+
i += 1
|
101
|
+
end
|
102
|
+
g
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def each
|
107
|
+
g = first
|
108
|
+
until g.nil?
|
109
|
+
yield g
|
110
|
+
g = self.next(g)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def functions
|
116
|
+
@functions ||= FunctionCollection.new(self)
|
117
|
+
end
|
118
|
+
|
119
|
+
class FunctionCollection
|
120
|
+
include Enumerable
|
121
|
+
|
122
|
+
def initialize(mod)
|
123
|
+
@module = mod
|
124
|
+
end
|
125
|
+
|
126
|
+
def add(name, *args)
|
127
|
+
if args.first.kind_of? Type
|
128
|
+
type = args.first
|
129
|
+
else
|
130
|
+
type = Type.function(*args)
|
131
|
+
end
|
132
|
+
function = Function.from_ptr(C.LLVMAddFunction(@module, name.to_s, type))
|
133
|
+
|
134
|
+
if block_given?
|
135
|
+
params = (0...function.params.size).map { |i| function.params[i] }
|
136
|
+
yield function, *params
|
137
|
+
end
|
138
|
+
|
139
|
+
function
|
140
|
+
end
|
141
|
+
|
142
|
+
def named(name)
|
143
|
+
Function.from_ptr(C.LLVMGetNamedFunction(@module, name))
|
144
|
+
end
|
145
|
+
|
146
|
+
def first
|
147
|
+
Function.from_ptr(C.LLVMGetFirstFunction(@module))
|
148
|
+
end
|
149
|
+
|
150
|
+
def last
|
151
|
+
Function.from_ptr(C.LLVMGetLastFunction(@module))
|
152
|
+
end
|
153
|
+
|
154
|
+
def next(function)
|
155
|
+
Function.from_ptr(C.LLVMGetNextFunction(function))
|
156
|
+
end
|
157
|
+
|
158
|
+
def previous(function)
|
159
|
+
Function.from_ptr(C.LLVMGetPreviousFunction(function))
|
160
|
+
end
|
161
|
+
|
162
|
+
def delete(function)
|
163
|
+
C.LLVMDeleteFunction(function)
|
164
|
+
end
|
165
|
+
|
166
|
+
def [](key)
|
167
|
+
case key
|
168
|
+
when String then named(key)
|
169
|
+
when Symbol then named(key.to_s)
|
170
|
+
when Integer
|
171
|
+
i = 0
|
172
|
+
f = first
|
173
|
+
until i >= key || f.nil?
|
174
|
+
f = self.next(f)
|
175
|
+
i += 1
|
176
|
+
end
|
177
|
+
f
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def each
|
182
|
+
f = first
|
183
|
+
until f.nil?
|
184
|
+
yield f
|
185
|
+
f = self.next(f)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Print the module's IR to stdout
|
191
|
+
def dump
|
192
|
+
C.LLVMDumpModule(self)
|
193
|
+
end
|
194
|
+
|
195
|
+
def dispose
|
196
|
+
C.LLVMDisposeModule(@ptr)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|