rltk 1.2.0 → 2.0.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.
@@ -0,0 +1,43 @@
1
+ # Generated by ffi_gen. Please do not change this file by hand.
2
+
3
+ require 'ffi'
4
+
5
+ module RLTK::CG::Bindings
6
+ extend FFI::Library
7
+ ffi_lib 'LLVM-ECB-3.0'
8
+
9
+ def self.attach_function(name, *_)
10
+ begin; super; rescue FFI::NotFoundError => e
11
+ (class << self; self; end).class_eval { define_method(name) { |*_| raise e } }
12
+ end
13
+ end
14
+
15
+ ECB_VERSION = 0
16
+
17
+ TARGET_VERSION_MAJOR = 3
18
+
19
+ TARGET_VERSION_MINOR = 0
20
+
21
+ # (Not documented)
22
+ #
23
+ # @method ecb_version()
24
+ # @return [String]
25
+ # @scope class
26
+ attach_function :ecb_version, :LLVMECBVersion, [], :string
27
+
28
+ # (Not documented)
29
+ #
30
+ # @method target_version()
31
+ # @return [String]
32
+ # @scope class
33
+ attach_function :target_version, :LLVMTargetVersion, [], :string
34
+
35
+ # (Not documented)
36
+ #
37
+ # @method load_library_permanently(filename)
38
+ # @param [String] filename
39
+ # @return [Integer]
40
+ # @scope class
41
+ attach_function :load_library_permanently, :LLVMLoadLibraryPermanently, [:string], :int
42
+
43
+ end
@@ -0,0 +1,98 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/04/18
4
+ # Description: This file defines the GenericValue class.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Ruby Language Toolkit
11
+ require 'rltk/cg/bindings'
12
+ require 'rltk/cg/type'
13
+
14
+ #######################
15
+ # Classes and Modules #
16
+ #######################
17
+
18
+ module RLTK::CG # :nodoc:
19
+
20
+ # GenericValue objects are used to pass parameters into
21
+ # {ExecutionEngine ExecutionEngines} as well as retreive an evaluated
22
+ # function's result. They may contain values of several different types:
23
+ #
24
+ # * Integer
25
+ # * Float
26
+ # * Boolean
27
+ class GenericValue
28
+ include BindingClass
29
+
30
+ # @return [Type] LLVM type of this GenericValue.
31
+ attr_reader :type
32
+
33
+ # Creates a new GenericValue from a given Ruby value.
34
+ #
35
+ # @param [FFI::Pointer, Integer, ::Float, Boolean] ruby_val
36
+ # @param [Type] type Type of Integer or Float to create.
37
+ # @param [Boolean] signed Signed or unsigned Integer.
38
+ def initialize(ruby_val, type = nil, signed = true)
39
+ @ptr, @type =
40
+ case ruby_val
41
+ when FFI::Pointer
42
+ [ruby_val, nil]
43
+
44
+ when ::Integer
45
+ type = if type then check_cg_type(type, IntType) else NativeIntType.instance end
46
+
47
+ [Bindings.create_generic_value_of_int(type, ruby_val, signed.to_i), type]
48
+
49
+ when ::Float
50
+ type = if type then check_cg_type(type, RealType) else FloatType.instance end
51
+
52
+ [Bindings.create_generic_value_of_float(type, ruby_val), type]
53
+
54
+ when TrueClass
55
+ [Bindings.create_generic_value_of_int(Int1Type, 1, 0), Int1Type]
56
+
57
+ when FalseClass
58
+ [Bindings.create_generic_value_of_int(Int1Type, 0, 0), Int1Type]
59
+ end
60
+ end
61
+
62
+ # Frees the resources used by LLVM for this value.
63
+ #
64
+ # @return [void]
65
+ def dispose
66
+ if @ptr
67
+ Bindings.dispose_generic_value(@ptr)
68
+ @ptr = nil
69
+ end
70
+ end
71
+
72
+ # @param [Boolean] signed Treat the GenericValue as a signed integer.
73
+ #
74
+ # @return [Integer]
75
+ def to_i(signed = true)
76
+ val = Bindings.generic_value_to_int(@ptr, signed.to_i)
77
+
78
+ if signed and val >= 2**63 then val - 2**64 else val end
79
+ end
80
+
81
+ # @param [FloatType] type Type of the real value stored in this GenericValue.
82
+ #
83
+ # @return [Float]
84
+ def to_f(type = RLTK::CG::FloatType)
85
+ Bindings.generic_value_to_float(@type || check_cg_type(type, RLTK::CG::NumberType), @ptr)
86
+ end
87
+
88
+ # @return [Boolean]
89
+ def to_b
90
+ self.to_i(false).to_bool
91
+ end
92
+
93
+ # @return [FFI::Pointer] GenericValue as a pointer.
94
+ def to_ptr_value
95
+ Bindings.generic_value_to_pointer(@ptr)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,498 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/04/09
4
+ # Description: This file defines LLVM Instruction classes.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Ruby Language Toolkit
11
+ require 'rltk/cg/bindings'
12
+ require 'rltk/cg/value'
13
+
14
+ #######################
15
+ # Classes and Modules #
16
+ #######################
17
+
18
+ module RLTK::CG # :nodoc:
19
+
20
+ # This class represents LLVM IR instructions.
21
+ class Instruction < User
22
+
23
+ # Many of the C functions for interacting with instructions treat
24
+ # all instructions as Instruction objects. However, some Instruction
25
+ # sub-types can be tested for. This is a list of those sub-types and
26
+ # the names of their tests.
27
+ TESTABLE = [
28
+ :Alloca,
29
+ :BitCast,
30
+ :Call,
31
+ :ExtractElement,
32
+ :ExtractValue,
33
+ :FCmp,
34
+ [:FPExtend, :FPExt],
35
+ :FPToSI,
36
+ :FPToUI,
37
+ :FPTrunc,
38
+ :GetElementPtr,
39
+ [:IntCmp, :ICmp],
40
+ :InsertElement,
41
+ :InsertValue,
42
+ :IntToPtr,
43
+ :Invoke,
44
+ :Load,
45
+ :PtrToInt,
46
+ :Return,
47
+ [:SignExtend, :SExt],
48
+ :SIToFP,
49
+ :Select,
50
+ :ShuffleVector,
51
+ :Store,
52
+ :Switch,
53
+ [:Truncate, :Trunc],
54
+ :UIToFP,
55
+ :Unreachable
56
+ ]
57
+
58
+ # Instantiate an Instruction object from a given pointer. The type
59
+ # of the instruction is tested and the appropriate sub-type is picked
60
+ # if possible. If not, a generic Instruction object is returned.
61
+ #
62
+ # @param [FFI::Pointer] ptr Pointer to a C instruction object.
63
+ #
64
+ # @return [Instruction] An Instruction or one of its sub-types.
65
+ def self.from_ptr(ptr)
66
+ match = nil
67
+
68
+ TESTABLE.each do |el|
69
+ klass, test =
70
+ if el.is_a?(Symbol)
71
+ [RLTK::CG.const_get("#{el}Inst".to_sym), Bindings.get_bname("IsA#{el}Inst")]
72
+
73
+ else
74
+ [RLTK::CG.const_get("#{el.first}Inst".to_sym), Bindings.get_bname("IsA#{el.last}Inst")]
75
+ end
76
+
77
+ match = klass if Bindings.send(test, ptr)
78
+ end
79
+
80
+ if match then match else Intruction end.new(ptr)
81
+ end
82
+
83
+ # You should never instantiate Instruction object directly. Use the
84
+ # builder class to add new instructions.
85
+ #
86
+ # @param [FFI::Pointer] ptr Pointer to a C instruction object.
87
+ def initialize(ptr)
88
+ @ptr = check_type(ptr, FFI::Pointer, 'ptr')
89
+ end
90
+
91
+ # @return [Instruction, nil] Instruction that follows the current one in a {BasicBlock}.
92
+ def next
93
+ if (ptr = Bindings.get_next_instruction(@ptr)).null? then nil else Instruction.from_ptr(ptr) end
94
+ end
95
+
96
+ # @return [BasicBlock] BasicBlock that contains this Instruction.
97
+ def parent
98
+ if (ptr = Bindings.get_instruction_parent(@ptr)).null? then nil else BasicBlock.new(ptr) end
99
+ end
100
+
101
+ # @return [Instruction, nil] Instruction that precedes the current on in a {BasicBlock}.
102
+ def previous
103
+ if (ptr = Bindings.get_previous_instruction(@ptr)).null? then nil else Instruction.from_ptr(ptr) end
104
+ end
105
+
106
+ ##########################################
107
+ # Instruction Testing Method Definitions #
108
+ ##########################################
109
+
110
+ selector = Regexp.new(/LLVMIsA.*Inst/)
111
+ syms = Symbol.all_symbols.select { |sym| selector.match(sym.to_s) }
112
+
113
+ syms.each do |sym|
114
+ sym = (Bindings.get_bname(sym).to_s + '?').to_sym
115
+
116
+ define_method(sym) do
117
+ Bindings.send(sym, @ptr)
118
+ end
119
+ end
120
+ end
121
+
122
+ # An Instruction representing a function call.
123
+ #
124
+ # @LLVMInst call
125
+ class CallInst < Instruction
126
+ # Get the calling convention used for this call.
127
+ #
128
+ # @see Bindings._enum_call_conv_
129
+ #
130
+ # @return [Symbol]
131
+ def calling_convention
132
+ Bindings.enum_type(:call_conv)[Bindings.get_instruction_call_conv(@ptr)]
133
+ end
134
+
135
+ # Set the calling convention used for this call.
136
+ #
137
+ # @see Bindings._enum_call_conv_
138
+ #
139
+ # @param [Symbol] conv Calling convention to set.
140
+ def calling_convention=(conv)
141
+ Bindings.set_instruction_call_conv(@ptr, Bindings.enum_type(:call_conv)[conv])
142
+
143
+ conv
144
+ end
145
+ end
146
+
147
+ # An Instruction representing a Phi node.
148
+ #
149
+ # @see http://en.wikipedia.org/wiki/Static_single_assignment_form
150
+ # @LLVMInst phi
151
+ class PhiInst < Instruction
152
+ # @return [IncomingCollection] Proxy object for inspecting the incoming {BasicBlock}/{Value} pairs.
153
+ def incoming
154
+ @incoming_collection ||= IncomingCollection.new(self)
155
+ end
156
+
157
+ # This class is used to access a Phi node's incoming {BasicBlock}/{Value} pairs.
158
+ class IncomingCollection
159
+ include Enumerable
160
+
161
+ # @param [PhiInst] phi Phi instruction for which this is a proxy.
162
+ def initialize(phi)
163
+ @phi = phi
164
+ end
165
+
166
+ # Access the {BasicBlock}/{Value} pair at the given index.
167
+ #
168
+ # @param [Integer] index Index of the desired pair. May be negative.
169
+ #
170
+ # @return [Array(BasicBlock, Value)]
171
+ def [](index)
172
+ index += self.size if index < 0
173
+
174
+ if 0 <= index and index < self.size
175
+ [self.block(index), self.value(index)]
176
+ end
177
+ end
178
+
179
+ # Add incoming {BasicBlock}/{Value} pairs to a Phi node.
180
+ #
181
+ # @example Adding a single block/value pair:
182
+ # phi.incoming.add(bb, val)
183
+ #
184
+ # @example Adding several block/value pairs:
185
+ # phi.incoming.add({bb0 => val0, bb1 => val1})
186
+ #
187
+ # @param [BasicBlock, Hash{BasicBlock => Value}] overloaded
188
+ # @param [Value, nil] value
189
+ #
190
+ # @return [void]
191
+ def add(overloaded, value = nil)
192
+ blks, vals =
193
+ if overloaded.is_a?(BasicBlock) and check_type(value, Value, 'value')
194
+ [overloaded, value]
195
+ else
196
+ if RUBY_VERSION[0..2] == '1.9'
197
+ [overloaded.keys, overloaded.values]
198
+ else
199
+ [(keys = overloaded.keys), overloaded.values_at(*keys)]
200
+ end
201
+ end
202
+
203
+ vals_ptr = FFI::MemoryPointer.new(:pointer, vals.size)
204
+ vals_ptr.write_array_of_pointer(vals)
205
+
206
+ blks_ptr = FFI::MemoryPointer.new(:pointer, blks.size)
207
+ blks_ptr.write_array_of_pointer(blks)
208
+
209
+ returning(nil) { Bindings.add_incoming(@phi, vals_ptr, blks_ptr, vals.length) }
210
+ end
211
+ alias :<< :add
212
+
213
+ # @param [Integer] index Index of desired incoming {BasicBlock}.
214
+ #
215
+ # @return [BasicBlock] Incoming {BasicBlock}.
216
+ def block(index)
217
+ index += self.size if index < 0
218
+
219
+ if 0 <= index and index < self.size
220
+ BasicBlock.new(Bindings.get_incoming_block(@phi, index))
221
+ end
222
+ end
223
+
224
+ # An iterator for each incoming {BasicBlock}/{Value} pair.
225
+ #
226
+ # @yieldparam pair [Array(BasicBlock, Value)]
227
+ #
228
+ # @return [Enumerator] Returns an Enumerator if no block is given.
229
+ def each
230
+ return to_enum(:each) unless block_given?
231
+
232
+ self.size.times { |index| yield self[index] }
233
+
234
+ self
235
+ end
236
+
237
+ # @return [Integer] Number of incoming {BasicBlock}/{Value} pairs.
238
+ def size
239
+ Bindings.count_incoming(@phi)
240
+ end
241
+
242
+ # @param [Integer] index Index of desired incoming {Value}.
243
+ #
244
+ # @return [BasicBlock] Incoming {Value}.
245
+ def value(index)
246
+ index += self.size if index < 0
247
+
248
+ if 0 <= index and index < self.size
249
+ Value.new(Bindings.get_incoming_value(@phi, index))
250
+ end
251
+ end
252
+ end
253
+ end
254
+
255
+ # An Instruction representing a conditional jump with multiple cases.
256
+ #
257
+ # @LLVMInst switch
258
+ class SwitchInst < Instruction
259
+ # Add a case to this conditional jump.
260
+ #
261
+ # @param [Value] val Value for this case.
262
+ # @param [BasicBlock] block BasicBlock to jump to if this case is matched.
263
+ #
264
+ # @return [void]
265
+ def add_case(val, block)
266
+ Bindings.add_case(@ptr, val, block)
267
+ end
268
+ end
269
+
270
+ #############################
271
+ # Empty Instruction Classes #
272
+ #############################
273
+
274
+ # @LLVMInst add
275
+ class AddInst < Instruction; end
276
+
277
+ # @LLVMInst alloca
278
+ class AllocaInst < Instruction; end
279
+
280
+ # @LLVMInst and
281
+ class AndInst < Instruction; end
282
+
283
+ # @LLVMInst ashr
284
+ class ARightShiftInst < Instruction; end
285
+
286
+ # @LLVMInst alloca
287
+ class ArrayAllocaInst < Instruction; end
288
+
289
+ class ArrayMallocInst < Instruction; end
290
+
291
+ # @LLVMInst bitcast
292
+ class BitCastInst < Instruction; end
293
+
294
+ # @LLVMInst br
295
+ class BranchInst < Instruction; end
296
+
297
+ # @LLVMInst br
298
+ class CondBranchInst < Instruction; end
299
+
300
+ # @LLVMInst sdiv
301
+ class ExactSDivInst < Instruction; end
302
+
303
+ # @LLVMInst extractelement
304
+ class ExtractElementInst < Instruction; end
305
+
306
+ # @LLVMInst extractvalue
307
+ class ExtractValueInst < Instruction; end
308
+
309
+ # @LLVMInst fadd
310
+ class FAddInst < Instruction; end
311
+
312
+ # @LLVMInst fcmp
313
+ class FCmpInst < Instruction; end
314
+
315
+ # @LLVMInst fdiv
316
+ class FDivInst < Instruction; end
317
+
318
+ # @LLVMInst fmul
319
+ class FMulInst < Instruction; end
320
+
321
+ # @LLVMInst fsub
322
+ class FNegInst < Instruction; end
323
+
324
+ # @LLVMInst fptosi
325
+ class FPToSIInst < Instruction; end
326
+
327
+ # @LLVMInst fptoui
328
+ class FPToUIInst < Instruction; end
329
+
330
+ class FPCastInst < Instruction; end
331
+
332
+ # @LLVMInst fpext
333
+ class FPExtendInst < Instruction; end
334
+
335
+ # @LLVMInst fptrunc
336
+ class FPTruncInst < Instruction; end
337
+
338
+ class FreeInst < Instruction; end
339
+
340
+ # @LLVMInst frem
341
+ class FRemInst < Instruction; end
342
+
343
+ # @LLVMInst fsub
344
+ class FSubInst < Instruction; end
345
+
346
+ # @LLVMInst gep
347
+ # @see http://llvm.org/docs/GetElementPtr.html
348
+ class GetElementPtrInst < Instruction; end
349
+
350
+ class GlobalStringInst < Instruction; end
351
+ class GlobalStringPtrInst < Instruction; end
352
+
353
+ # @LLVMInst gep
354
+ # @see http://llvm.org/docs/GetElementPtr.html
355
+ class InBoundsGEPInst < Instruction; end
356
+
357
+ # @LLVMInst insertelement
358
+ class InsertElementInst < Instruction; end
359
+
360
+ # @LLVMInst insertvalue
361
+ class InsertValueInst < Instruction; end
362
+
363
+ # @LLVMInst inttoptr
364
+ class IntToPtrInst < Instruction; end
365
+
366
+ class IntCastInst < Instruction; end
367
+
368
+ # @LLVMInst icmp
369
+ class IntCmpInst < Instruction; end
370
+
371
+ # @LLVMInst invoke
372
+ class InvokeInst < Instruction; end
373
+
374
+ class IsNotNullInst < Instruction; end
375
+ class IsNullInstInst < Instruction; end
376
+
377
+ # @LLVMInst shl
378
+ class LeftShiftInst < Instruction; end
379
+
380
+ # @LLVMInst load
381
+ class LoadInst < Instruction; end
382
+
383
+ # @LLVMInst lshr
384
+ class LRightShiftInst < Instruction; end
385
+
386
+ class MallocInst < Instruction; end
387
+
388
+ # @LLVMInst mul
389
+ class MulInst < Instruction; end
390
+
391
+ # @LLVMInst sub
392
+ class NegInst < Instruction; end
393
+
394
+ class NotInst < Instruction; end
395
+
396
+ # @LLVMInst add
397
+ class NSWAddInst < Instruction; end
398
+
399
+ # @LLVMInst mul
400
+ class NSWMulInst < Instruction; end
401
+
402
+ # @LLVMInst sub
403
+ class NSWNegInst < Instruction; end
404
+
405
+ # @LLVMInst sub
406
+ class NSWSubInst < Instruction; end
407
+
408
+ # @LLVMInst add
409
+ class NUWAddInst < Instruction; end
410
+
411
+ # @LLVMInst mul
412
+ class NUWMulInst < Instruction; end
413
+
414
+ # @LLVMInst sub
415
+ class NUWNegInst < Instruction; end
416
+
417
+ # @LLVMInst sub
418
+ class NUWSubInst < Instruction; end
419
+
420
+ # @LLVMInst or
421
+ class OrInst < Instruction; end
422
+
423
+ # @LLVMInst ptrtoint
424
+ class PtrToIntInst < Instruction; end
425
+
426
+ class PtrCastInst < Instruction; end
427
+ class PtrDiffInst < Instruction; end
428
+
429
+ # @LLVMInst ret
430
+ class ReturnInst < Instruction; end
431
+
432
+ # @LLVMInst ret
433
+ class ReturnAggregateInst < Instruction; end
434
+
435
+ # @LLVMInst ret
436
+ class ReturnVoidInst < Instruction; end
437
+
438
+ # @LLVMInst sdiv
439
+ class SDivInst < Instruction; end
440
+
441
+ # @LLVMInst select
442
+ class SelectInst < Instruction; end
443
+
444
+ # @LLVMInst shufflevector
445
+ class ShuffleVectorInst < Instruction; end
446
+
447
+ # @LLVMInst sext
448
+ class SignExtendInst < Instruction; end
449
+
450
+ # @LLVMInst sext
451
+ # @LLVMInst bitcast
452
+ class SignExtendOrBitCastInst < Instruction; end
453
+
454
+ # @LLVMInst sitofp
455
+ class SIToFPInst < Instruction; end
456
+
457
+ # @LLVMInst srem
458
+ class SRemInst < Instruction; end
459
+
460
+ # @LLVMInst store
461
+ class StoreInst < Instruction; end
462
+
463
+ # @LLVMInst gep
464
+ # @see http://llvm.org/docs/GetElementPtr.html
465
+ class StructGEPInst < Instruction; end
466
+
467
+ # @LLVMInst sub
468
+ class SubInst < Instruction; end
469
+
470
+ # @LLVMInst trunc
471
+ class TruncateInst < Instruction; end
472
+
473
+ # @LLVMInst trunc
474
+ # @LLVMInst bitcast
475
+ class TruncateOrBitCastInst < Instruction; end
476
+
477
+ # @LLVMInst udiv
478
+ class UDivInst < Instruction; end
479
+
480
+ # @LLVMInst uitofp
481
+ class UIToFPInst < Instruction; end
482
+
483
+ # @LLVMInst unreachable
484
+ class UnreachableInst < Instruction; end
485
+
486
+ # @LLVMInst urem
487
+ class URemInst < Instruction; end
488
+
489
+ # @LLVMInst xor
490
+ class XOrInst < Instruction; end
491
+
492
+ # @LLVMInst zext
493
+ class ZeroExtendInst < Instruction; end
494
+
495
+ # @LLVMInst zext
496
+ # @LLVMInst bitcast
497
+ class ZeroExtendOrBitCastInst < Instruction; end
498
+ end
@@ -0,0 +1,51 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/03/15
4
+ # Description: This file defines the LLVM module.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Ruby Language Toolkit
11
+ require 'rltk/version'
12
+ require 'rltk/cg/bindings'
13
+
14
+ #######################
15
+ # Classes and Modules #
16
+ #######################
17
+
18
+ module RLTK::CG # :nodoc:
19
+
20
+ # This module contains global operations on the LLVM compiler infrastructure.
21
+ module LLVM
22
+ # Initialize LLVM to generate code for a given architecture.
23
+ #
24
+ # @see Bindings::ARCHS
25
+ #
26
+ # @param [Symbol] arch Architecture to initialize LLVM for.
27
+ #
28
+ # @raise [RuntimeError] An error is raised if an unsupported architecture is specified.
29
+ #
30
+ # @return [true]
31
+ def self.init(arch)
32
+ if Bindings::ARCHS.include?(arch) or Bindings::ARCHS.map { |sym| sym.to_s.downcase.to_sym }.include?(arch)
33
+ arch = Bindings.get_bname(arch)
34
+
35
+ Bindings.send("initialize_#{arch}_target".to_sym)
36
+ Bindings.send("initialize_#{arch}_target_info".to_sym)
37
+ Bindings.send("initialize_#{arch}_target_mc".to_sym)
38
+
39
+ true
40
+
41
+ else
42
+ raise "Unsupported architecture specified: #{arch}"
43
+ end
44
+ end
45
+
46
+ # @return [String] String representing the version of LLVM targeted by these bindings.
47
+ def self.version
48
+ RLTK::LLVM_TARGET_VERSION
49
+ end
50
+ end
51
+ end