rltk3 3.0.2

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.
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