rltk3 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +1 -0
  3. data/LICENSE +27 -0
  4. data/README.md +852 -0
  5. data/Rakefile +197 -0
  6. data/lib/rltk/ast.rb +573 -0
  7. data/lib/rltk/cfg.rb +683 -0
  8. data/lib/rltk/cg/basic_block.rb +157 -0
  9. data/lib/rltk/cg/bindings.rb +151 -0
  10. data/lib/rltk/cg/builder.rb +1127 -0
  11. data/lib/rltk/cg/context.rb +48 -0
  12. data/lib/rltk/cg/contractor.rb +51 -0
  13. data/lib/rltk/cg/execution_engine.rb +194 -0
  14. data/lib/rltk/cg/function.rb +237 -0
  15. data/lib/rltk/cg/generated_bindings.rb +8118 -0
  16. data/lib/rltk/cg/generic_value.rb +95 -0
  17. data/lib/rltk/cg/instruction.rb +519 -0
  18. data/lib/rltk/cg/llvm.rb +150 -0
  19. data/lib/rltk/cg/memory_buffer.rb +75 -0
  20. data/lib/rltk/cg/module.rb +451 -0
  21. data/lib/rltk/cg/pass_manager.rb +252 -0
  22. data/lib/rltk/cg/support.rb +29 -0
  23. data/lib/rltk/cg/target.rb +230 -0
  24. data/lib/rltk/cg/triple.rb +58 -0
  25. data/lib/rltk/cg/type.rb +554 -0
  26. data/lib/rltk/cg/value.rb +1272 -0
  27. data/lib/rltk/cg.rb +32 -0
  28. data/lib/rltk/lexer.rb +372 -0
  29. data/lib/rltk/lexers/calculator.rb +44 -0
  30. data/lib/rltk/lexers/ebnf.rb +38 -0
  31. data/lib/rltk/parser.rb +1702 -0
  32. data/lib/rltk/parsers/infix_calc.rb +43 -0
  33. data/lib/rltk/parsers/postfix_calc.rb +34 -0
  34. data/lib/rltk/parsers/prefix_calc.rb +34 -0
  35. data/lib/rltk/token.rb +90 -0
  36. data/lib/rltk/version.rb +11 -0
  37. data/lib/rltk.rb +16 -0
  38. data/test/cg/tc_basic_block.rb +83 -0
  39. data/test/cg/tc_control_flow.rb +191 -0
  40. data/test/cg/tc_function.rb +54 -0
  41. data/test/cg/tc_generic_value.rb +33 -0
  42. data/test/cg/tc_instruction.rb +256 -0
  43. data/test/cg/tc_llvm.rb +25 -0
  44. data/test/cg/tc_math.rb +88 -0
  45. data/test/cg/tc_module.rb +89 -0
  46. data/test/cg/tc_transforms.rb +68 -0
  47. data/test/cg/tc_type.rb +69 -0
  48. data/test/cg/tc_value.rb +151 -0
  49. data/test/cg/ts_cg.rb +23 -0
  50. data/test/tc_ast.rb +332 -0
  51. data/test/tc_cfg.rb +164 -0
  52. data/test/tc_lexer.rb +216 -0
  53. data/test/tc_parser.rb +711 -0
  54. data/test/tc_token.rb +34 -0
  55. data/test/ts_rltk.rb +47 -0
  56. metadata +317 -0
@@ -0,0 +1,1272 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/03/15
4
+ # Description: This file defines LLVM Value classes.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Gems
11
+ require 'filigree/abstract_class'
12
+
13
+ # Ruby Language Toolkit
14
+ require 'rltk/cg/bindings'
15
+ require 'rltk/cg/type'
16
+
17
+ #######################
18
+ # Classes and Modules #
19
+ #######################
20
+
21
+ module RLTK::CG
22
+
23
+ # This class represents LLVM IR "data", including integer and float
24
+ # literals, functions, and constant arrays, structs, and vectors.
25
+ class Value
26
+ include BindingClass
27
+
28
+ # Instantiate a Value object from a pointer. This should never be
29
+ # done by library users, and is only used internally.
30
+ #
31
+ # @param [FFI::Pointer] ptr Pointer to an LLVM value.
32
+ def initialize(ptr)
33
+ @ptr = check_type(ptr, FFI::Pointer, 'ptr')
34
+ end
35
+
36
+ # Compare one Value to another.
37
+ #
38
+ # @param [Value] other Another value object.
39
+ #
40
+ # @return [Boolean]
41
+ def ==(other)
42
+ other.is_a?(Value) and @ptr == other.ptr
43
+ end
44
+
45
+ # @return [AttrCollection] Proxy object for inspecing a value's attributes.
46
+ def attributes
47
+ @attributes ||= AttrCollection.new(@ptr)
48
+ end
49
+ alias :attrs :attributes
50
+
51
+ # Bitcast a value to a given type.
52
+ #
53
+ # @param [Type] type Type to cast to.
54
+ #
55
+ # @return [ConstantExpr]
56
+ def bitcast(type)
57
+ ConstantExpr.new(Bindings.const_bit_cast(@ptr, check_cg_type(type)))
58
+ end
59
+
60
+ # @return [Boolean] If this value is a constant.
61
+ def constant?
62
+ Bindings.is_constant(@ptr).to_bool
63
+ end
64
+
65
+ # Print the LLVM IR representation of this value to standard error.
66
+ # This function is the debugging version of the more general purpose
67
+ # {#print} method.
68
+ #
69
+ # @see #print
70
+ #
71
+ # @return [void]
72
+ def dump
73
+ Bindings.dump_value(@ptr)
74
+ end
75
+
76
+ # @return [Fixnum] Hashed value of the pointer representing this value.
77
+ def hash
78
+ @ptr.address.hash
79
+ end
80
+
81
+ # @return [String] Name of this value in LLVM IR.
82
+ def name
83
+ Bindings.get_value_name(@ptr)
84
+ end
85
+
86
+ # Set the name of this value in LLVM IR.
87
+ #
88
+ # @param [String] str Name of the value in LLVM IR.
89
+ #
90
+ # @return [String] *str*
91
+ def name=(str)
92
+ str.tap { Bindings.set_value_name(@ptr, check_type(str, String)) }
93
+ end
94
+
95
+ # @return [Boolean] If the value is null or not.
96
+ def null?
97
+ Bindings.is_null(@ptr).to_bool
98
+ end
99
+
100
+ # @return [String] LLVM IR representation of this value
101
+ def print
102
+ Bindings.print_value_to_string(@ptr)
103
+ end
104
+
105
+ # Truncate a value to a given type.
106
+ #
107
+ # @param [Type] type Type to truncate to.
108
+ #
109
+ # @return [ConstantExpr]
110
+ def trunc(type)
111
+ ConstantExpr.new(Bindings.const_trunc(check_cg_type(type)))
112
+ end
113
+
114
+ # Truncate or bitcast a value to the given type as is appropriate.
115
+ #
116
+ # @param [Type] type Type to cast or truncate to.
117
+ #
118
+ # @return [ConstantExpr]
119
+ def trunc_or_bitcast(type)
120
+ ConstantExpr.new(Bindings.const_trunc_or_bit_cast(check_cg_type(type)))
121
+ end
122
+
123
+ # @return [Type] Type of this value.
124
+ def type
125
+ @type ||= Type.from_ptr(Bindings.type_of(@ptr))
126
+ end
127
+
128
+ # @return [Boolean] If the value is undefined or not.
129
+ def undefined?
130
+ Bindings.is_undef(@ptr).to_bool
131
+ end
132
+
133
+ # Zero extend the value to the length of *type*.
134
+ #
135
+ # @param [Type] type Type to extend the value to.
136
+ #
137
+ # @return [ConstantExpr]
138
+ def zextend(type)
139
+ ConstantExpr.new(Bindings.const_z_ext(check_cg_type(type)))
140
+ end
141
+
142
+ # Zero extend or bitcast the value to the given type as is appropriate.
143
+ #
144
+ # @param [Type] type Type to cast or extend to.
145
+ #
146
+ # @return [ConstantExpr]
147
+ def zextend_or_bitcast(type)
148
+ ConstantExpr.new(Bindings.const_z_ext_or_bit_cast(check_cg_type(type)))
149
+ end
150
+
151
+ # This class is used to access a {Value Value's} attributes.
152
+ class AttrCollection
153
+ @@add_method = :add_attribute
154
+ @@del_method = :remove_attribute
155
+
156
+ # @param [Value] value Value for which this is a proxy.
157
+ def initialize(value)
158
+ @attributes = Array.new
159
+ @value = value
160
+ end
161
+
162
+ # Add the given attribute to a value.
163
+ #
164
+ # @see Bindings._enum_attribute_
165
+ #
166
+ # @param [Symbol] attribute Attribute to add.
167
+ #
168
+ # @return [void]
169
+ def add(attribute)
170
+ if not @attributes.include?(attribute)
171
+ @attributes << attribute
172
+ Bindings.send(@@add_method, @value, attribute)
173
+ end
174
+ end
175
+ alias :'<<' :add
176
+
177
+ # Test to see if an attribute has been set on a value.
178
+ #
179
+ # @see Bindings._enum_attribute_
180
+ #
181
+ # @param [Symbol] attribute Attribute to check.
182
+ #
183
+ # @return [Boolean]
184
+ def include?(attribute)
185
+ @attributes.include?(attribute)
186
+ end
187
+
188
+ # Remove the given attribute from a value.
189
+ #
190
+ # @see Bindings._enum_attribute_
191
+ #
192
+ # @param [Symbol] attribute Attribute to remove.
193
+ #
194
+ # @return [void]
195
+ def remove(attribute)
196
+ if @attributes.include?(attribute)
197
+ @attributes.delete(attribute)
198
+ Bindings.send(@@del_method, @value, attribute)
199
+ end
200
+ end
201
+ alias :'>>' :remove
202
+
203
+ # @return [String] Textual representation of the enabled attributes.
204
+ def to_s
205
+ @attributes.to_s
206
+ end
207
+ end
208
+ end
209
+
210
+ # An empty class definition for completeness and future use.
211
+ class Argument < Value; end
212
+
213
+ # A base class for a wide variety of classes.
214
+ #
215
+ # @abstract
216
+ class User < Value
217
+ include Filigree::AbstractClass
218
+
219
+ # @return [OperandCollection] Proxy object for accessing a value's operands.
220
+ def operands
221
+ @operands ||= OperandCollection.new(self)
222
+ end
223
+
224
+ # This class is used to access a {User User's} operands.
225
+ class OperandCollection
226
+ include Enumerable
227
+
228
+ # @param [User] user User object for which this is a proxy.
229
+ def initialize(user)
230
+ @user = user
231
+ end
232
+
233
+ # Access the operand at the given index.
234
+ #
235
+ # @param [Integer] index
236
+ #
237
+ # @return [Value, nil] Value object representing the operand at *index* if one exists.
238
+ def [](index)
239
+ if (ptr = Bindings.get_operand(@user, index)).null? then nil else Value.new(ptr) end
240
+ end
241
+
242
+ # Set the operand at the given index.
243
+ #
244
+ # @param [Integer] index Index of operand to set.
245
+ # @param [Value] value Value to set as operand.
246
+ #
247
+ # @return [void]
248
+ def []=(index, value)
249
+ Bindings.set_operand(@user, index, check_type(value, Value, 'value'))
250
+ end
251
+
252
+ # An iterator for each operand inside this collection.
253
+ #
254
+ # @yieldparam val [Value]
255
+ #
256
+ # @return [Enumerator] Returns an Enumerator if no block is given.
257
+ def each
258
+ return to_enum(:each) unless block_given?
259
+
260
+ self.size.times { |i| yield self[i] }
261
+
262
+ self
263
+ end
264
+
265
+ # @return [Integer] Number of operands.
266
+ def size
267
+ Bindings.get_num_operands(@user)
268
+ end
269
+ end
270
+ end
271
+
272
+ # All classes representing constant values inherit from this class.
273
+ #
274
+ # @abstract
275
+ class Constant < User
276
+ include Filigree::AbstractClass
277
+
278
+ # Create a new constant from a pointer or a type. As a library user
279
+ # you should never pass a pointer in here as that is only used
280
+ # internally.
281
+ #
282
+ # @param [FFI::Pointer, Type] overloaded Pointer to existing constant or a Type.
283
+ def initialize(overloaded)
284
+ @ptr =
285
+ case overloaded
286
+ when FFI::Pointer
287
+ overloaded
288
+
289
+ when Type
290
+ Bindings.send(@@initializer, @type = overloaded)
291
+ else
292
+ raise 'New must be passed either a Type or a FFI::Pointer.'
293
+ end
294
+ end
295
+
296
+ # Cast a constant to a given address space
297
+ #
298
+ # @param [Type] type Type to cast to
299
+ #
300
+ # @return [ConstantExpr]
301
+ def addr_space_cast(type)
302
+ ConstantExpr.new(Bindings.const_addr_space_cast(@ptr, check_cg_type(type)))
303
+ end
304
+
305
+ # Bitcast a constant to a given type.
306
+ #
307
+ # @param [Type] type Type to cast to
308
+ #
309
+ # @return [ConstantExpr]
310
+ def bitcast_to(type)
311
+ ConstantExpr.new(Bindings.const_bit_cast(@ptr, check_cg_type(type)))
312
+ end
313
+
314
+ # Get a pointer to an element of a constant value.
315
+ #
316
+ # @param [Array<Value>] indices A Ruby array of Value objects representing indicies into the constant value.
317
+ #
318
+ # @return [ConstantExpr] LLVM Value object representing a pointer to a LLVM Value object.
319
+ def get_element_ptr(*indices)
320
+ indicies_ptr = FFI::MemoryPointer.new(:pointer, indices.length)
321
+ indices_ptr.write_array_of_pointer(indices)
322
+
323
+ ConstantExpr.new(Bindings.const_gep(@ptr, indices_ptr, indices.length))
324
+ end
325
+ alias :gep :get_element_ptr
326
+
327
+ # Get a pointer to an element of a constant value, ensuring that the
328
+ # pointer is within the bounds of the value.
329
+ #
330
+ # @param [Array<Value>] indices A Ruby array of Value objects representing indicies into the constant value.
331
+ #
332
+ # @return [ConstantExpr] LLVM Value object representing a pointer to a LLVM Value object.
333
+ def get_element_ptr_in_bounds(*indices)
334
+ indices_ptr = FFI::MemoryPointer.new(:pointer, indices.length)
335
+ indices_ptr.write_array_of_pointer(indices)
336
+
337
+ ConstantExpr.new(Bindings.const_in_bounds_gep(@ptr, indices_ptr, indices.length))
338
+ end
339
+ alias :inbounds_gep :get_element_ptr_in_bounds
340
+ end
341
+
342
+ # This class represents a wide range of values returned by various
343
+ # operations.
344
+ class ConstantExpr < Constant
345
+ # Constant expressions can only be instantiated from a pointer, and
346
+ # should never be instantiated by library users.
347
+ #
348
+ # @param [FFI::Pointer] ptr
349
+ def initialize(ptr)
350
+ @ptr = check_type(ptr, FFI::Pointer, 'ptr')
351
+ end
352
+ end
353
+
354
+ # A constant null value.
355
+ class ConstantNull < Constant
356
+ @@initializer = :const_null
357
+ end
358
+
359
+ # A constant null pointer value.
360
+ class ConstantNullPtr < Constant
361
+ @@initializer = :const_pointer_null
362
+ end
363
+
364
+ # A constant undefined value.
365
+ class ConstantUndef < Constant
366
+ @@initializer = :get_undef
367
+ end
368
+
369
+ # All constant aggregate values inherit from this class.
370
+ #
371
+ # @abstract
372
+ class ConstantAggregate < Constant
373
+ include Filigree::AbstractClass
374
+
375
+ # Extract values from a constant aggregate value.
376
+ #
377
+ # @param [Array<Value>] indices Array of values representing indices into the aggregate.
378
+ #
379
+ # @return [ConstantExpr] Extracted values.
380
+ def extract(*indices)
381
+ indices_ptr = FFI::MemoryPointer.new(:uint, indices.length)
382
+ indices_ptr.write_array_of_uint(indices)
383
+
384
+ ConstantExpr.new(Bindings.const_extract_value(@ptr, indices_ptr, indices.length))
385
+ end
386
+
387
+ # Insert values into a constant aggregate value.
388
+ #
389
+ # @param [Value] value Value to insert.
390
+ # @param [Array<Value>] indices Array of values representing indices into the aggregate.
391
+ #
392
+ # @return [ConstantExpr] New aggregate representation with inserted values.
393
+ def insert(value, indices)
394
+ indices_ptr = FFI::MemoryPointer.new(:uint, indices.length)
395
+ indices_ptr.write_array_of_uint(indices)
396
+
397
+ ConstantExpr.new(Bindings.const_insert_value(@ptr, value, indices_ptr, inicies.length))
398
+ end
399
+ end
400
+
401
+ # A constant array value.
402
+ class ConstantArray < ConstantAggregate
403
+ # Create a new constant array value.
404
+ #
405
+ # @example Using array of values:
406
+ # ConstantArray.new(Int32Type, [Int32.new(0), Int32.new(1)])
407
+ #
408
+ # @example Using size:
409
+ # ConstantArray.new(Int32Type, 2) { |i| Int32.new(i) }
410
+ #
411
+ # @yieldparam index [Integer] Index of the value in the array.
412
+ #
413
+ # @param [Type] element_type Type of values in this aggregate.
414
+ # @param [Array<Value>, Integer] size_or_values Number of values or array of values.
415
+ # @param [Proc] block Block evaluated if size is specified.
416
+ def initialize(element_type, size_or_values, &block)
417
+ vals_ptr = make_ptr_to_elements(size_or_values, &block)
418
+ element_type = check_cg_type(element_type, Type, 'element_type')
419
+ @ptr = Bindings.const_array(element_type, vals_ptr, vals_ptr.size / vals_ptr.type_size)
420
+ end
421
+
422
+ def size
423
+ self.type.size
424
+ end
425
+ alias :length :size
426
+ end
427
+
428
+ # A sub-class of {ConstantArray} specifically for holding strings.
429
+ class ConstantString < ConstantArray
430
+ # Create a new constant string value.
431
+ #
432
+ # @param [String] string Sting to turn into a value.
433
+ # @param [Boolean] null_terminate To null terminate the string or not.
434
+ # @param [Context, nil] context Context in which to create the value.
435
+ def initialize(string, null_terminate = true, context = nil)
436
+ @type = ArrayType.new(Int8Type)
437
+
438
+ @ptr =
439
+ if context
440
+ Bindings.const_string_in_context(check_type(context, Context, 'context'), string, string.length, null_terminate.to_i)
441
+ else
442
+ Bindings.const_string(string, string.length, null_terminate.to_i)
443
+ end
444
+ end
445
+ end
446
+
447
+ # A constant struct value.
448
+ class ConstantStruct < ConstantAggregate
449
+ # Create a new constant struct value.
450
+ #
451
+ # @example Using array of values:
452
+ # ConstantStruct.new([Int32.new(0), Int64.new(1), Int32.new(2), Int64.new(3)])
453
+ #
454
+ # @example Using size:
455
+ # ConstantStruct.new(4) { |i| if i % 2 == 0 then Int32.new(i) else Int64.new(i) end }
456
+ #
457
+ # @yieldparam index [Integer] Index of the value in the struct.
458
+ #
459
+ # @param [Array<Value>, Integer] size_or_values Number of values or array of values.
460
+ # @param [Boolean] packed Are the types packed already, or should they be re-arranged to save space?
461
+ # @param [Context, nil] context Context in which to create the value.
462
+ # @param [Proc] block Block evaluated if size is specified.
463
+ def initialize(size_or_values, packed = false, context = nil, &block)
464
+ vals_ptr = make_ptr_to_elements(size_or_values, &block)
465
+
466
+ @ptr =
467
+ if context
468
+ Bindings.const_struct_in_context(check_type(context, Context, 'context'),
469
+ vals_ptr, vals_ptr.size / vals_ptr.type_size, packed.to_i)
470
+ else
471
+ Bindings.const_struct(vals_ptr, vals_ptr.size / vals_ptr.type_size, packed.to_i)
472
+ end
473
+ end
474
+ end
475
+
476
+ # A constant vector value used for SIMD instructions.
477
+ class ConstantVector < Constant
478
+ # Create a new constant vector value.
479
+ #
480
+ # @example Using array of values:
481
+ # ConstantVector.new([Int32.new(0), Int32.new(1)])
482
+ #
483
+ # @example Using size:
484
+ # ConstantVector.new(2) { |i| Int32.new(i) }
485
+ #
486
+ # @yieldparam index [Integer] Index of the value in the vector.
487
+ #
488
+ # @param [FFI::Pointer, Array<Value>, Integer] size_or_values Number of values or array of values.
489
+ # @param [Proc] block Block evaluated if size is specified.
490
+ def initialize(size_or_values, &block)
491
+ @ptr =
492
+ if size_or_values.is_a?(FFI::Pointer)
493
+ size_or_values
494
+ else
495
+ vals_ptr = make_ptr_to_elements(size_or_values, &block)
496
+
497
+ Bindings.const_vector(vals_ptr, vals_ptr.size / vals_ptr.type_size)
498
+ end
499
+ end
500
+
501
+ # @param [Integer] index Index of desired element.
502
+ #
503
+ # @return [ConstantExpr] Extracted element.
504
+ def extract_element(index)
505
+ ConstantExpr.new(Bindings.const_extract_element(@ptr, index))
506
+ end
507
+
508
+ # @param [Value] element Value to insert into the vector.
509
+ # @param [Integer] index Index to insert the value at.
510
+ #
511
+ # @return [ConstantExpr] New vector representation with inserted value.
512
+ def insert_element(element, index)
513
+ ConstantExpr.new(Bindings.const_insert_element(@ptr, element, index))
514
+ end
515
+
516
+ # @param [ConstantVector] other Other vector to shuffle with this one.
517
+ # @param [ConstantVector] mask Mask to use when shuffling.
518
+ #
519
+ # @return [ConstantVector] New vector formed by shuffling the two vectors together using the mask.
520
+ def shuffle(other, mask)
521
+ ConstantVector.new(Bindings.const_shuffle_vector(@ptr, other, mask))
522
+ end
523
+
524
+ def size
525
+ self.type.size
526
+ end
527
+ alias :length :size
528
+ end
529
+
530
+ # All number constants inherit from this class.
531
+ #
532
+ # @abstract
533
+ class ConstantNumber < Constant
534
+ include Filigree::AbstractClass
535
+
536
+ # @return [Type] The corresponding Type sub-class that is used to represent the type of this value.
537
+ def self.type
538
+ @type ||= RLTK::CG.const_get(self.short_name + 'Type').instance
539
+ end
540
+
541
+ # @return [Type] The corresponding Type sub-class that is used to represent the type of this value.
542
+ def type
543
+ self.class.type
544
+ end
545
+ end
546
+
547
+ # All integer constants inherit from this class.
548
+ #
549
+ # @abstract
550
+ class ConstantInteger < ConstantNumber
551
+ include Filigree::AbstractClass
552
+
553
+ # @return [Boolean] If the integer is signed or not.
554
+ attr_reader :signed
555
+
556
+ # The constructor for ConstantInteger's various sub-classes. This
557
+ # constructor is a bit complicated due to having two overloaded
558
+ # parameters, but once you see the valid combinations it is a bit
559
+ # simpler.
560
+ #
561
+ # @example Constant (signed) integer from Ruby Integer:
562
+ # Int32.new(128)
563
+ #
564
+ # @example Constant (signed) base 8 integer from Ruby String:
565
+ # Int32.new('72', 8)
566
+ #
567
+ # @example Constant integer of all 1s:
568
+ # Int32.new
569
+ #
570
+ # @param [FFI::Pointer, Integer, String, nil] overloaded0 Pointer to a ConstantInteger, value, or string representing value.
571
+ # @param [Boolean, Integer] overloaded1 Signed or unsigned (when overloaded0 is Integer) or base used to
572
+ # decode string value.
573
+ # @param [Integer] size Optional length of string to use.
574
+ def initialize(overloaded0 = nil, overloaded1 = nil, size = nil)
575
+ @ptr =
576
+ case overloaded0
577
+ when FFI::Pointer
578
+ overloaded0
579
+
580
+ when Integer
581
+ @signed = overloaded1 or true
582
+
583
+ Bindings.const_int(self.type, overloaded0, @signed.to_i)
584
+
585
+ when String
586
+ base = overloaded1 or 10
587
+
588
+ if size
589
+ Bindings.const_int_of_string_and_size(self.type, overloaded0, size, base)
590
+ else
591
+ Bindings.const_int_of_string(self.type, overloaded0, base)
592
+ end
593
+ else
594
+ @signed = true
595
+
596
+ Bindings.const_all_ones(self.type)
597
+ end
598
+ end
599
+
600
+ ########
601
+ # Math #
602
+ ########
603
+
604
+ # Addition
605
+
606
+ # Add this value with another value.
607
+ #
608
+ # @param [ConstantInteger] rhs
609
+ #
610
+ # @return [ConstantInteger] Instance of the same class.
611
+ def +(rhs)
612
+ self.class.new(Bindings.const_add(@ptr, rhs))
613
+ end
614
+
615
+ # Add this value with another value. Performs no signed wrap
616
+ # addition.
617
+ #
618
+ # @param [ConstantInteger] rhs
619
+ #
620
+ # @return [ConstantInteger] Instance of the same class.
621
+ def nsw_add(rhs)
622
+ self.class.new(Bindings.const_nsw_add(@ptr, rhs))
623
+ end
624
+
625
+ # Add this value with another value. Performs no unsigned wrap
626
+ # addition.
627
+ #
628
+ # @param [ConstantInteger] rhs
629
+ #
630
+ # @return [ConstantInteger] Instance of the same class.
631
+ def nuw_add(rhs)
632
+ self.class.new(Bindings.const_nuw_add(@ptr, rhs))
633
+ end
634
+
635
+ # Subtraction
636
+
637
+ # Subtract a value from this value.
638
+ #
639
+ # @param [ConstantInteger] rhs
640
+ #
641
+ # @return [ConstantInteger] Instance of the same class.
642
+ def -(rhs)
643
+ self.class.new(Bindings.const_sub(@ptr, rhs))
644
+ end
645
+
646
+ # Subtract a value from this value. Performs no signed wrap
647
+ # subtraction.
648
+ #
649
+ # @param [ConstantInteger] rhs
650
+ #
651
+ # @return [ConstantInteger] Instance of the same class.
652
+ def nsw_sub(rhs)
653
+ self.class.new(Bindings.const_nsw_sub(@ptr, rhs))
654
+ end
655
+
656
+ # Subtract a value from this value. Performs no unsigned wrap
657
+ # subtraction.
658
+ #
659
+ # @param [ConstantInteger] rhs
660
+ #
661
+ # @return [ConstantInteger] Instance of the same class.
662
+ def nuw_sub(rhs)
663
+ self.class.new(Bindings.const_nuw_sub(@ptr, rhs))
664
+ end
665
+
666
+ # Multiplication
667
+
668
+ # Multiply this value with another value.
669
+ #
670
+ # @param [ConstantInteger] rhs
671
+ #
672
+ # @return [ConstantInteger] Instance of the same class.
673
+ def *(rhs)
674
+ self.class.new(Bindings.const_mul(@ptr, rhs))
675
+ end
676
+
677
+ # Multiply this value with another value. Perform no signed wrap
678
+ # multiplication.
679
+ #
680
+ # @param [ConstantInteger] rhs
681
+ #
682
+ # @return [ConstantInteger] Instance of the same class.
683
+ def nsw_mul(rhs)
684
+ self.class.new(Bindings.const_nsw_mul(@ptr, rhs))
685
+ end
686
+
687
+ # Multiply this value with another value. Perform no unsigned wrap
688
+ # multiplication.
689
+ #
690
+ # @param [ConstantInteger] rhs
691
+ #
692
+ # @return [ConstantInteger] Instance of the same class.
693
+ def nuw_mul(rhs)
694
+ self.class.new(Bindings.const_nuw_mul(@ptr, rhs))
695
+ end
696
+
697
+ # Division
698
+
699
+ # Divide this value by another value. Uses signed division.
700
+ #
701
+ # @param [ConstantInteger] rhs
702
+ #
703
+ # @return [ConstantInteger] Instance of the same class.
704
+ def /(rhs)
705
+ self.class.new(Bindings.const_s_div(@ptr, rhs))
706
+ end
707
+
708
+ # Divide this value by another value. Uses exact signed division.
709
+ #
710
+ # @param [ConstantInteger] rhs
711
+ #
712
+ # @return [ConstantInteger] Instance of the same class.
713
+ def extact_sdiv(rhs)
714
+ self.class.new(Bindings.const_extact_s_div(@ptr, rhs))
715
+ end
716
+
717
+ # Divide this value by another value. Uses unsigned division.
718
+ #
719
+ # @param [ConstantInteger] rhs
720
+ #
721
+ # @return [ConstantInteger] Instance of the same class.
722
+ def udiv(rhs)
723
+ self.class.new(Bindings.const_u_div(@ptr, rhs))
724
+ end
725
+
726
+ # Remainder
727
+
728
+ # Modulo this value by another value. Uses signed modulo.
729
+ #
730
+ # @param [ConstantInteger] rhs
731
+ #
732
+ # @return [ConstantInteger] Instance of the same class.
733
+ def %(rhs)
734
+ self.class.new(Bindings.const_s_rem(@ptr, rhs))
735
+ end
736
+
737
+ # Modulo this value by another value. Uses unsigned modulo.
738
+ #
739
+ # @param [ConstantInteger] rhs
740
+ #
741
+ # @return [ConstantInteger] Instance of the same class.
742
+ def urem(rhs)
743
+ self.class.new(Bindings.const_u_rem(@ptr, rhs))
744
+ end
745
+
746
+ # Negation
747
+
748
+ # Negate this value.
749
+ #
750
+ # @return [ConstantInteger] Instance of the same class
751
+ def -@
752
+ self.class.new(Bindings.const_neg(@ptr))
753
+ end
754
+
755
+ # Negate this value. Uses no signed wrap negation.
756
+ #
757
+ # @return [ConstantInteger] Instance of the same class
758
+ def nsw_neg
759
+ self.class.new(Bindings.const_nsw_neg(@ptr))
760
+ end
761
+
762
+ # Negate this value. Uses no unsigned wrap negation.
763
+ #
764
+ # @return [ConstantInteger] Instance of the same class
765
+ def nuw_neg
766
+ self.class.new(Bindings.const_nuw_neg(@ptr))
767
+ end
768
+
769
+ ######################
770
+ # Bitwise Operations #
771
+ ######################
772
+
773
+ # A wrapper method around the {#shift_left} and {#shift_right}
774
+ # methods.
775
+ #
776
+ # @param [:left, :right] dir The direction to shift.
777
+ # @param [Integer] bits Number of bits to shift.
778
+ # @param [:arithmetic, :logical] mode Shift mode for right shifts.
779
+ #
780
+ # @return [ConstantInteger] Instance of the same class.
781
+ def shift(dir, bits, mode = :arithmetic)
782
+ case dir
783
+ when :left then shift_left(bits)
784
+ when :right then shift_right(bits, mode)
785
+ end
786
+ end
787
+
788
+ # Shift the value left a specific number of bits.
789
+ #
790
+ # @param [Integer] bits Number of bits to shift.
791
+ #
792
+ # @return [ConstantInteger] Instance of the same class.
793
+ def shift_left(bits)
794
+ self.class.new(Bindings.const_shl(@ptr, bits))
795
+ end
796
+ alias :shl :shift_left
797
+ alias :<< :shift_left
798
+
799
+ # Shift the value right a specific number of bits.
800
+ #
801
+ # @param [Integer] bits Number of bits to shift.
802
+ # @param [:arithmetic, :logical] mode Shift mode.
803
+ #
804
+ # @return [ConstantInteger] Instance of the same class.
805
+ def shift_right(bits, mode = :arithmetic)
806
+ case mode
807
+ when :arithmetic then ashr(bits)
808
+ when :logical then lshr(bits)
809
+ end
810
+ end
811
+
812
+ # Arithmetic right shift.
813
+ #
814
+ # @param [Integer] bits Number of bits to shift.
815
+ #
816
+ # @return [ConstantInteger] Instance of the same class.
817
+ def ashr(bits)
818
+ self.class.new(Bindings.const_a_shr(@ptr, bits))
819
+ end
820
+ alias :>> :ashr
821
+
822
+ # Logical right shift.
823
+ #
824
+ # @param [Integer] bits Number of bits to shift.
825
+ #
826
+ # @return [ConstantInteger] Instance of the same class.
827
+ def lshr(bits)
828
+ self.class.new(Bindings.const_l_shr(@ptr, bits))
829
+ end
830
+
831
+ # Bitwise AND this value with another.
832
+ #
833
+ # @param [ConstantInteger] rhs
834
+ #
835
+ # @return [ConstantInteger] Instance of the same class.
836
+ def and(rhs)
837
+ self.class.new(Bindings.const_and(@ptr, rhs))
838
+ end
839
+
840
+ # Bitwise OR this value with another.
841
+ #
842
+ # @param [ConstantInteger] rhs
843
+ #
844
+ # @return [ConstantInteger] Instance of the same class.
845
+ def or(rhs)
846
+ self.class.new(Bindings.const_or(@ptr, rhs))
847
+ end
848
+
849
+ # Bitwise XOR this value with another.
850
+ #
851
+ # @param [ConstantInteger] rhs
852
+ #
853
+ # @return [ConstantInteger] Instance of the same class.
854
+ def xor(rhs)
855
+ self.class.new(Bindings.const_xor(@ptr, rhs))
856
+ end
857
+
858
+ # Bitwise NOT this value.
859
+ #
860
+ # @return [ConstantInteger] Instance of the same class.
861
+ def not
862
+ self.class.new(Bindings.const_not(@ptr))
863
+ end
864
+
865
+ #################
866
+ # Miscellaneous #
867
+ #################
868
+
869
+ # Cast this constant integer to another number type.
870
+ #
871
+ # @param [NumberType] type Desired type to cast to.
872
+ # @param [Boolean] signed Is the value signed or not.
873
+ #
874
+ # @return [ConstantNumber] This value as as the given type.
875
+ def cast(type, signed = true)
876
+ type.value_class.new(Bindings.const_int_cast(@ptr, check_cg_type(type, NumberType), signed.to_i))
877
+ end
878
+
879
+ # Compare this value to another value.
880
+ #
881
+ # @see Bindings._enum_int_predicate_
882
+ #
883
+ # @param [Symbol] pred An integer predicate.
884
+ # @param [ConstantInteger] rhs Value to compare to.
885
+ #
886
+ # @return [Int1] Value used to represent a Boolean value.
887
+ def cmp(pred, rhs)
888
+ Int1.new(Bindings.const_i_cmp(pred, @ptr, rhs))
889
+ end
890
+
891
+ # Convert this integer to a float.
892
+ #
893
+ # @param [RealType] type Type of float to convert to.
894
+ #
895
+ # @return [ConstantReal] This value as a floating point value of the given type.
896
+ def to_f(type)
897
+ type.value_class.new(Bindings.send(@signed ? :const_si_to_fp : :const_ui_to_fp, @ptr, check_cg_type(type, FloatingPointType)))
898
+ end
899
+
900
+ # Get the value of this constant as a signed or unsigned long long.
901
+ #
902
+ # @param [:sign, :zero] extension Extension method.
903
+ #
904
+ # @return [Integer]
905
+ def value(extension = :sign)
906
+ case extension
907
+ when :sign then Bindings.const_int_get_s_ext_value(@ptr)
908
+ when :zero then Bindings.const_int_get_z_ext_value(@ptr)
909
+ end
910
+ end
911
+ end
912
+
913
+ # 1 bit integer value. Often used to represent Boolean values.
914
+ class Int1 < ConstantInteger; end
915
+ # 8 bit (1 byte) integer value.
916
+ class Int8 < ConstantInteger; end
917
+ # 16 bit (2 byte) integer value.
918
+ class Int16 < ConstantInteger; end
919
+ # 32 bit (4 byte) integer value.
920
+ class Int32 < ConstantInteger; end
921
+ # 64 bit (8 byte) integer value.
922
+ class Int64 < ConstantInteger; end
923
+
924
+ # The native integer value class on the current (not the target) platform.
925
+ NativeInt = RLTK::CG.const_get("Int#{FFI.type_size(:int) * 8}")
926
+
927
+ # A constant Int 1 representing the Boolean value TRUE.
928
+ TRUE = Int1.new(-1)
929
+ # A constant Int 1 representing the Boolean value FALSE.
930
+ FALSE = Int1.new( 0)
931
+
932
+ # All real constants inherit from this class.
933
+ #
934
+ # @abstract
935
+ class ConstantReal < ConstantNumber
936
+ include Filigree::AbstractClass
937
+
938
+ # Create a constant real number using a Ruby value or a string.
939
+ #
940
+ # @param [::Float, String] num_or_string Ruby value or string representation of a float.
941
+ # @param [Integer, nil] size Optional length of string to use.
942
+ def initialize(num_or_string, size = nil)
943
+ @ptr =
944
+ if num_or_string.is_a?(::Float)
945
+ Bindings.const_real(self.type, num_or_string)
946
+
947
+ elsif size
948
+ Bindings.const_real_of_string_and_size(self.type, num_or_string, size)
949
+
950
+ else
951
+ Bindings.const_real_of_string(self.type, num_or_string)
952
+ end
953
+ end
954
+
955
+ # Negate this value.
956
+ #
957
+ # @return [ConstantReal] Instance of the same class
958
+ def -@
959
+ self.class.new(Bindings.const_f_neg(@ptr))
960
+ end
961
+
962
+ # Add this value with another value.
963
+ #
964
+ # @param [ConstantReal] rhs
965
+ #
966
+ # @return [ConstantReal] Instance of the same class.
967
+ def +(rhs)
968
+ self.class.new(Bindings.const_f_add(@ptr, rhs))
969
+ end
970
+
971
+ # Subtract a value from this value.
972
+ #
973
+ # @param [ConstantReal] rhs
974
+ #
975
+ # @return [ConstantReal] Instance of the same class.
976
+ def -(rhs)
977
+ self.class.new(Bindings.const_f_sub(@ptr, rhs))
978
+ end
979
+
980
+ # Multiply this value with another value.
981
+ #
982
+ # @param [ConstantReal] rhs
983
+ #
984
+ # @return [ConstantReal] Instance of the same class.
985
+ def *(rhs)
986
+ self.class.new(Bindings.const_f_mul(@ptr, rhs))
987
+ end
988
+
989
+ # Divide this value by another value.
990
+ #
991
+ # @param [ConstantReal] rhs
992
+ #
993
+ # @return [ConstantReal] Instance of the same class.
994
+ def /(rhs)
995
+ self.class.new(Bindings.const_f_div(@ptr, rhs))
996
+ end
997
+
998
+ # Modulo this value by another value.
999
+ #
1000
+ # @param [ConstantReal] rhs
1001
+ #
1002
+ # @return [ConstantReal] Instance of the same class.
1003
+ def %(rhs)
1004
+ self.class.new(Bindings.const_f_remm(@ptr, rhs))
1005
+ end
1006
+
1007
+ # Compare this value to another value.
1008
+ #
1009
+ # @see Bindings._enum_real_predicate_
1010
+ #
1011
+ # @param [Symbol] pred An real predicate.
1012
+ # @param [ConstantReal] rhs Value to compare to.
1013
+ #
1014
+ # @return [Int1] Value used to represent a Boolean value.
1015
+ def cmp(pred, rhs)
1016
+ Int1.new(Bindings.const_f_cmp(pred, @ptr, rhs))
1017
+ end
1018
+
1019
+ # Cast this constant real to another number type.
1020
+ #
1021
+ # @param [NumberType] type Desired type to cast to.
1022
+ #
1023
+ # @return [ConstantNumber] Constant number of given type.
1024
+ def cast(type)
1025
+ type.value_class.new(Bindings.const_fp_cast(@ptr, check_cg_type(type, NumberType)))
1026
+ end
1027
+
1028
+ # Convert this real number into an integer.
1029
+ #
1030
+ # @param [BasicIntType] type Type to convert to.
1031
+ # @param [Boolean] signed Should the result be a signed integer or not.
1032
+ #
1033
+ # @return [
1034
+ def to_i(type = NativeIntType, signed = true)
1035
+ type.value_class.new(Bindings.send(signed ? :const_fp_to_si : :const_fp_to_ui, @ptr, check_cg_type(type, BasicIntType)))
1036
+ end
1037
+
1038
+ # Extend a constant real number to a larger size.
1039
+ #
1040
+ # @param [RealType] type Type to extend to.
1041
+ #
1042
+ # @return [ConstantReal] This value as a real of the given type.
1043
+ def extend(type)
1044
+ type.value_class.new(Bindings.const_fp_ext(@ptr, check_cg_type(type, RealType)))
1045
+ end
1046
+
1047
+ # Truncate a constant real number to a smaller size.
1048
+ #
1049
+ # @param [RealType] type Type to truncate to.
1050
+ #
1051
+ # @return [ConstantReal] This value as a real of the given type.
1052
+ def truncate(type)
1053
+ type.value_class.new(Bindings.const_fp_trunc(@ptr, check_cg_type(type, RealType)))
1054
+ end
1055
+ end
1056
+
1057
+ # A 16-bit floating point number value.
1058
+ class Half < ConstantReal; end
1059
+ # A double precision floating point number value.
1060
+ class Double < ConstantReal; end
1061
+ # A single precision floating point number value.
1062
+ class Float < ConstantReal; end
1063
+ # A 128 bit (16 byte) floating point number value.
1064
+ class FP128 < ConstantReal; end
1065
+ # A 128 bit (16 byte) floating point number value for the PPC architecture.
1066
+ class PPCFP128 < ConstantReal; end
1067
+ # A 80 bit (10 byte) floating point number value for the x86 architecture.
1068
+ class X86FP80 < ConstantReal; end
1069
+
1070
+ # This class represents global constants, variables, and functions.
1071
+ class GlobalValue < Constant
1072
+ # Global values can only be instantiated using a pointer, and as such
1073
+ # should not be created directly by library users.
1074
+ #
1075
+ # @param [FFI::Pointer] ptr
1076
+ def initialize(ptr)
1077
+ @ptr = check_type(ptr, FFI::Pointer, 'ptr')
1078
+ end
1079
+
1080
+ # Get the byte alignment of this value.
1081
+ #
1082
+ # @return [Integer]
1083
+ def alignment
1084
+ Bindings.get_alignment(@ptr)
1085
+ end
1086
+
1087
+ # Set the byte alignment of this value.
1088
+ #
1089
+ # @param [Integer] bytes
1090
+ #
1091
+ # @return [void]
1092
+ def alignment=(bytes)
1093
+ Bindings.set_alignment(@ptr, bytes)
1094
+ end
1095
+
1096
+ # Check if this value is a declaration.
1097
+ #
1098
+ # @return [Boolean]
1099
+ def declaration?
1100
+ Bindings.is_declaration(@ptr).to_bool
1101
+ end
1102
+
1103
+ # Sets the externally initialized property of a global value.
1104
+ #
1105
+ # @param [Boolean] bool If the value is externally initialized
1106
+ #
1107
+ # @return [void]
1108
+ def externally_initialized=(bool)
1109
+ Bindings.set_externally_initialized(@ptr, bool.to_i)
1110
+ end
1111
+
1112
+ # Check if this global is initialized externally.
1113
+ #
1114
+ # @return [Boolean]
1115
+ def externally_initialized?
1116
+ Bindings.externally_initialized(@ptr).to_bool
1117
+ end
1118
+
1119
+ # Check if this value is a global constant.
1120
+ #
1121
+ # @return [Boolean]
1122
+ def global_constant?
1123
+ Bindings.is_global_constant(@ptr).to_bool
1124
+ end
1125
+
1126
+ # Set this value as a global constant or not.
1127
+ #
1128
+ # @param [Boolean] flag
1129
+ #
1130
+ # @return [void]
1131
+ def global_constant=(flag)
1132
+ Bindings.set_global_constant(@ptr, flag.to_i)
1133
+ end
1134
+
1135
+ # Get this value's initializer.
1136
+ #
1137
+ # @return [Value]
1138
+ def initializer
1139
+ Value.new(Bindings.get_initializer(@ptr))
1140
+ end
1141
+
1142
+ # Set this value's initializer.
1143
+ #
1144
+ # @param [Value] val
1145
+ #
1146
+ # @return [void]
1147
+ def initializer=(val)
1148
+ Bindings.set_initializer(@ptr, check_type(val, Value, 'val'))
1149
+ end
1150
+
1151
+ # Get this value's linkage type.
1152
+ #
1153
+ # @see Bindings._enum_linkage_
1154
+ #
1155
+ # @return [Symbol]
1156
+ def linkage
1157
+ Bindings.get_linkage(@ptr)
1158
+ end
1159
+
1160
+ # Set this value's linkage type.
1161
+ #
1162
+ # @see Bindings._enum_linkage_
1163
+ #
1164
+ # @param [Symbol] linkage
1165
+ #
1166
+ # @return [void]
1167
+ def linkage=(linkage)
1168
+ Bindings.set_linkage(@ptr, linkage)
1169
+ end
1170
+
1171
+ # Get this value's section string.
1172
+ #
1173
+ # @return [String]
1174
+ def section
1175
+ Bindings.get_section(@ptr)
1176
+ end
1177
+
1178
+ # Set this value's section string.
1179
+ #
1180
+ # @param [String] section
1181
+ #
1182
+ # @return [void]
1183
+ def section=(section)
1184
+ Bindings.set_section(@ptr, section)
1185
+ end
1186
+
1187
+ # Returns the thread local model used by a global value.
1188
+ #
1189
+ # @return [Symbol from _enum_thread_local_mode_]
1190
+ def thread_local_mode
1191
+ Bindings.get_thread_local_mode(@ptr)
1192
+ end
1193
+
1194
+
1195
+ # Set the global value's thread local mode.
1196
+ #
1197
+ # @param [Symbol from _enum_thread_local_mode_] mode
1198
+ #
1199
+ # @return [void]
1200
+ def thread_local_mode=(mode)
1201
+ Bindings.set_thread_local_mode(@ptr, mode)
1202
+ end
1203
+
1204
+ # Get this value's visibility.
1205
+ #
1206
+ # @see Bindings._enum_visibility_
1207
+ #
1208
+ # @return [String]
1209
+ def visibility
1210
+ Bindings.get_visibility(@ptr)
1211
+ end
1212
+
1213
+ # Set this value's visibility.
1214
+ #
1215
+ # @see Bindings._enum_visibility_
1216
+ #
1217
+ # @param [Symbol] vis
1218
+ #
1219
+ # @return [void]
1220
+ def visibility=(vis)
1221
+ Bindings.set_visibility(@ptr, vis)
1222
+ end
1223
+ end
1224
+
1225
+ # This class represents global aliases.
1226
+ class GlobalAlias < GlobalValue
1227
+ end
1228
+
1229
+ # This class represents global variables.
1230
+ class GlobalVariable < GlobalValue
1231
+ # Check to see if this global variable is thread local.
1232
+ #
1233
+ # @return [Boolean]
1234
+ def thread_local?
1235
+ Bindings.is_thread_local(@ptr).to_bool
1236
+ end
1237
+
1238
+ # Set this global variable as thread local or not.
1239
+ #
1240
+ # @param [Boolean] local
1241
+ #
1242
+ # @return [void]
1243
+ def thread_local=(local)
1244
+ Bindings.set_thread_local(@ptr, local.to_i)
1245
+ end
1246
+ end
1247
+ end
1248
+
1249
+ ####################
1250
+ # Helper Functions #
1251
+ ####################
1252
+
1253
+ # A helper function for creating constant array, vector, and struct types.
1254
+ # This method should never be used by library users.
1255
+ #
1256
+ # @param [Array<RLTK::CG::Value>, Integer] size_or_values Number of values or array of values.
1257
+ # @param [Proc] block Block evaluated if size is specified.
1258
+ #
1259
+ # @return [FFI::MemoryPointer] An array of pointers to LLVM Values.
1260
+ def make_ptr_to_elements(size_or_values, &block)
1261
+ values =
1262
+ case size_or_values
1263
+ when Integer
1264
+ raise ArgumentError, 'Block not given.' if not block_given?
1265
+
1266
+ ::Array.new(size_or_values, &block)
1267
+ else
1268
+ size_or_values
1269
+ end
1270
+
1271
+ FFI::MemoryPointer.new(:pointer, values.size).write_array_of_pointer(values)
1272
+ end