rltk 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,510 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/03/18
4
+ # Description: This file defines the various LLVM Types.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Standard Library
11
+ require 'singleton'
12
+
13
+ # Ruby Language Toolkit
14
+ require 'rltk/util/abstract_class'
15
+ require 'rltk/cg/bindings'
16
+ require 'rltk/cg/context'
17
+
18
+ #######################
19
+ # Classes and Modules #
20
+ #######################
21
+
22
+ module RLTK::CG # :nodoc:
23
+
24
+ # The Type class and its sub-classes are used to describe the size and
25
+ # structure of various data objects inside LLVM and how different
26
+ # operations interact with them. When instantiating objects of the
27
+ # {Value} class you will often need to pass in some type information.
28
+ #
29
+ # @abstract Root of the type class hierarchy.
30
+ class Type
31
+ include BindingClass
32
+ include AbstractClass
33
+
34
+ # Instantiate a Type object from a pointer. This function is used
35
+ # internally, and as a library user you should never have to call it.
36
+ #
37
+ # @param [FFI::Pointer] ptr
38
+ #
39
+ # @return [Type] A object of type Type or one of its sub-classes.
40
+ def self.from_ptr(ptr)
41
+ case Bindings.get_type_kind(ptr)
42
+ when :array then ArrayType.new(ptr)
43
+ when :double then DoubleType.new
44
+ when :float then FloatType.new
45
+ when :function then FunctionType.new(ptr)
46
+ when :fp128 then FP128Type.new
47
+ when :integer then IntType.new
48
+ when :label then LabelType.new
49
+ when :metadata then raise "Can't generate a Type object for objects of type Metadata."
50
+ when :pointer then PointerType.new(ptr)
51
+ when :ppc_fp128 then PPCFP128Type.new
52
+ when :struct then StructType.new(ptr)
53
+ when :vector then VectorType.new(ptr)
54
+ when :void then VoidType.new
55
+ when :x86_fp80 then X86FP80Type.new
56
+ when :x86_mmx then X86MMXType.new
57
+ end
58
+ end
59
+
60
+ # The default constructor for Type objects.
61
+ #
62
+ # @param [Context, nil] context An optional context in which to create the type.
63
+ def initialize(context = nil)
64
+ bname = Bindings.get_bname(self.class.short_name)
65
+
66
+ @ptr =
67
+ if context
68
+ Bindings.send((bname.to_s + '_in_context').to_sym, check_type(context, Context, 'context'))
69
+ else
70
+ Bindings.send(bname)
71
+ end
72
+ end
73
+
74
+ # @return [NativeInt] Alignment of the type.
75
+ def allignment
76
+ Int64.new(Bindings.align_of(@ptr))
77
+ end
78
+
79
+ # @return [Context] Context in which this type was created.
80
+ def context
81
+ Context.new(Bindings.get_type_context(@ptr))
82
+ end
83
+
84
+ # @return [Fixnum] Hashed value of the pointer representing this type.
85
+ def hash
86
+ @ptr.address.hash
87
+ end
88
+
89
+ # @see Bindings._enum_type_kind_
90
+ #
91
+ # @return [Symbol] The *kind* of this type.
92
+ def kind
93
+ Bindings.get_type_kind(@ptr)
94
+ end
95
+
96
+ # @return [NativeInt] Size of objects of this type.
97
+ def size
98
+ Int64.new(Bindings.size_of(@ptr))
99
+ end
100
+ end
101
+
102
+ # All types that are used to represent numbers inherit from this class.
103
+ #
104
+ # @abstract
105
+ class NumberType < Type
106
+ include AbstractClass
107
+
108
+ # @return [Value] The corresponding Value sub-class that is used to represent values of this type.
109
+ def self.value_class
110
+ begin
111
+ @value_class ||=
112
+ RLTK::CG.const_get(self.name.match(/::(.+)Type$/).captures.last.to_sym)
113
+
114
+ rescue
115
+ raise "#{self.name} has no value class."
116
+ end
117
+ end
118
+
119
+ # @return [Value] The corresponding Value sub-class that is used to represent values of this type.
120
+ def value_class
121
+ self.class.value_class
122
+ end
123
+ end
124
+
125
+ # All types that represent integers of a given width inherit from this class.
126
+ #
127
+ # @abstract
128
+ class BasicIntType < NumberType
129
+ include AbstractClass
130
+
131
+ # @return [Integer] Number of bits used to represent an integer type.
132
+ def width
133
+ @width ||= Bindings.get_int_type_width(@ptr)
134
+ end
135
+ end
136
+
137
+ # An integer of an arbitrary width.
138
+ class IntType < BasicIntType
139
+ # @param [Integer] width Width of new integer type.
140
+ # @param [Context] context Context in which to create the type.
141
+ #
142
+ # @raise [RuntimeError] Raises an error when width is <= 0.
143
+ def initialize(width, context = nil)
144
+ if width > 0
145
+ @ptr =
146
+ if context
147
+ Bindings.get_int_type_in_context(width, check_type(context, Context, 'context'))
148
+ else
149
+ Bidnings.get_int_type(width)
150
+ end
151
+ else
152
+ raise 'The width parameter must be greater then 0.'
153
+ end
154
+ end
155
+
156
+ # Overrides {NumberType#value_class}.
157
+ #
158
+ # @raise [RuntimeError] This function has no meaning in this class.
159
+ def value_class
160
+ raise 'The RLKT::CG::IntType class has no value class.'
161
+ end
162
+ end
163
+
164
+ # A class inherited by singleton integer type classes.
165
+ #
166
+ # @abstract
167
+ class SimpleIntType < BasicIntType
168
+ include AbstractClass
169
+ include Singleton
170
+ end
171
+
172
+ # A class inherited by all types representing floats.
173
+ #
174
+ # @abstract
175
+ class RealType < NumberType
176
+ include AbstractClass
177
+ include Singleton
178
+ end
179
+
180
+ # A class inherited by non-number singleton type classes.
181
+ #
182
+ # @abstract
183
+ class SimpleType < Type
184
+ include AbstractClass
185
+ include Singleton
186
+ end
187
+
188
+ # 1 bit integer type. Often used to represent Boolean values.
189
+ class Int1Type < SimpleIntType; end
190
+ # 8 bit (1 byte) integer type.
191
+ class Int8Type < SimpleIntType; end
192
+ # 16 bit (2 byte) integer type.
193
+ class Int16Type < SimpleIntType; end
194
+ # 32 bit (4 byte) integer type.
195
+ class Int32Type < SimpleIntType; end
196
+ # 64 bit (8 byte) integer type.
197
+ class Int64Type < SimpleIntType; end
198
+
199
+ # The native integer type on the current (not the target) platform.
200
+ NativeIntType = RLTK::CG.const_get("Int#{FFI.type_size(:int) * 8}Type")
201
+
202
+ # A double precision floating point number type.
203
+ class DoubleType < RealType; end
204
+ # A single precision floating point number type.
205
+ class FloatType < RealType; end
206
+ # A 128 bit (16 byte) floating point number type.
207
+ class FP128Type < RealType; end
208
+ # A 128 bit (16 byte) floating point number type for the PPC architecture.
209
+ class PPCFP128Type < RealType; end
210
+ # A 80 bit (10 byte) floating point number type for the x86 architecture.
211
+ class X86FP80Type < RealType; end
212
+
213
+ # A type for x86 MMX instructions.
214
+ class X86MMXType < SimpleType; end
215
+
216
+ # A type used in representing void pointers and functions that return no values.
217
+ class VoidType < SimpleType; end
218
+ # A type used to represent labels in LLVM IR.
219
+ class LabelType < SimpleType; end
220
+
221
+ # The common ancestor for array, pointer, and struct types.
222
+ #
223
+ # @abstract
224
+ class AggregateType < Type
225
+ include AbstractClass
226
+ end
227
+
228
+ # {ArrayType} and {PointerType} inherit from this class so they can share
229
+ # a constructor.
230
+ #
231
+ # @abstract
232
+ class SimpleAggregateType < AggregateType
233
+ include AbstractClass
234
+
235
+ # Used to initialize {ArrayType ArrayTypes} and {PointerType PointerTypes}.
236
+ #
237
+ # @param [FFI::Pointer, Type] overloaded Pointer to an existing aggregate type or a Type object that
238
+ # describes the objects that will be stored in an aggregate type.
239
+ def initialize(overloaded, size_or_address_space = 0)
240
+ @ptr =
241
+ case overloaded
242
+ when FFI::Pointer
243
+ overloaded
244
+ else
245
+ @element_type = check_cg_type(overloaded, Type, 'overloaded')
246
+ bname = Bindings.get_bname(self.class.short_name)
247
+
248
+ Bindings.send(bname, @element_type, size_or_address_space)
249
+ end
250
+ end
251
+
252
+ # @return [Type] Type of objects stored inside this aggregate.
253
+ def element_type
254
+ @element_type ||= Type.from_ptr(Bindings.get_element_type(@ptr))
255
+ end
256
+ end
257
+
258
+ # A Type describing an array that holds objects of a single given type.
259
+ class ArrayType < SimpleAggregateType
260
+ # @return [Integer] Number of elements in this array type.
261
+ def size
262
+ @length ||= Bindings.get_array_length(@ptr)
263
+ end
264
+ alias :length :size
265
+ end
266
+
267
+ # A Type describing a pointer to another type.
268
+ class PointerType < SimpleAggregateType
269
+ # @return [Integer] Address space of this pointer.
270
+ def address_space
271
+ @address_space ||= Bindings.get_pointer_address_space(@ptr)
272
+ end
273
+ end
274
+
275
+ # A type used to represent vector operations (SIMD). This is NOT an
276
+ # aggregate type.
277
+ class VectorType < Type
278
+ # Create a new vector type from a pointer or a type.
279
+ #
280
+ # @param [FFI::Pointer, Type] overloaded Pointer to existing vector type or Type of object stored in the vector.
281
+ # @param [Integer] size Number of objects in this vector type.
282
+ def initialize(overloaded, size = 0)
283
+ @ptr =
284
+ case overloaded
285
+ when FFI::Pointer
286
+ overloaded
287
+ else
288
+ @element_type = check_cg_type(overloaded, Type, 'overloaded')
289
+ bname = Bindings.get_bname(self.class.short_name)
290
+
291
+ Bindings.send(bname, @element_type, size)
292
+ end
293
+ end
294
+
295
+ # @return [Type] Type of object stored inside this vector.
296
+ def element_type
297
+ @element_type ||= Type.from_ptr(Bindings.get_element_type(@ptr))
298
+ end
299
+
300
+ # @return [Integer] Number of objects in this vector type.
301
+ def size
302
+ Bindings.get_vector_size(@ptr)
303
+ end
304
+ alias :length :size
305
+ end
306
+
307
+ # A type representing the return an argument types for a function.
308
+ class FunctionType < Type
309
+ # @return [Array<Type>] Types of this function type's arguments.
310
+ attr_reader :arg_types
311
+
312
+ # Create a new function type from a pointer or description of the
313
+ # return type and argument types.
314
+ #
315
+ # @param [FFI::Pointer, Type] overloaded Pointer to existing function type or the return type.
316
+ # @param [Array<Type>] arg_types Types of the function's arguments.
317
+ # @param [Boolean] varargs Weather or not this function has varargs.
318
+ def initialize(overloaded, arg_types = nil, varargs = false)
319
+ @ptr =
320
+ case overloaded
321
+ when FFI::Pointer
322
+ overloaded
323
+ else
324
+ @return_type = check_cg_type(overloaded, Type, 'return_type')
325
+ @arg_types = check_cg_array_type(arg_types, Type, 'arg_types').freeze
326
+
327
+ arg_types_ptr = FFI::MemoryPointer.new(:pointer, @arg_types.length)
328
+ arg_types_ptr.write_array_of_pointer(@arg_types)
329
+
330
+ Bindings.function_type(@return_type, arg_types_ptr, @arg_types.length, varargs.to_i)
331
+ end
332
+ end
333
+
334
+ # @return [Array<Type>] Types of this function type's arguments.
335
+ def argument_types
336
+ @arg_types ||=
337
+ begin
338
+ num_elements = Bindings.count_param_types(@ptr)
339
+
340
+ ret_ptr = FFI::MemoryPointer.new(:pointer)
341
+ Bindings.get_param_types(@ptr, ret_ptr)
342
+
343
+ types_ptr = ret_ptr.get_pointer(0)
344
+
345
+ types_ptr.get_array_of_pointer(0, num_elements).map { |ptr| Type.from_ptr(ptr) }
346
+ end
347
+ end
348
+ alias :arg_types :argument_types
349
+
350
+ # @return [Type] The return type of this function type.
351
+ def return_type
352
+ @return_type ||= Type.from_ptr(Bindings.get_return_type(@ptr))
353
+ end
354
+ end
355
+
356
+ # A type for representing an arbitrary collection of types.
357
+ class StructType < AggregateType
358
+ # Create a new struct type.
359
+ #
360
+ # @param [FFI::Pointer, Array<Type>] overloaded Pointer to an existing struct type or an array of types in the struct.
361
+ # @param [String, nil] name Name of the new struct type in LLVM IR.
362
+ # @param [Boolean] packed Are the types packed already, or should they be re-arranged to save space?
363
+ # @param [Context, nil] context Context in which to create this new type.
364
+ def initialize(overloaded, name = nil, packed = false, context = nil)
365
+ @ptr =
366
+ case overloaded
367
+ when FFI::Pointer
368
+ overloaded
369
+ else
370
+ # Check the types of the elements of the overloaded parameter.
371
+ @element_types = check_cg_array_type(overloaded, Type, 'overloaded')
372
+
373
+ el_types_ptr = FFI::MemoryPointer.new(:pointer, @element_types.length)
374
+ el_types_ptr.write_array_of_pointer(@element_types)
375
+
376
+ if name
377
+ @name = check_type(name, String, 'name')
378
+
379
+ returning Bindings.struct_create_named(Context.global, @name) do |ptr|
380
+ Bindings.struct_set_body(ptr, el_types_ptr, @element_types.length, packed.to_i) unless @element_types.empty?
381
+ end
382
+
383
+ elsif context
384
+ check_type(context, Context, 'context')
385
+
386
+ Bindings.struct_type_in_context(context, el_types_ptr, @element_types.length, is_packed.to_i)
387
+
388
+ else
389
+ Bindings.struct_type(el_types_ptr, @element_types.length, packed.to_i)
390
+ end
391
+ end
392
+ end
393
+
394
+ # @return [Array<Type>] Array of the types in this struct type.
395
+ def element_types
396
+ @element_types ||=
397
+ begin
398
+ num_elements = Bindings.count_struct_element_types(@ptr)
399
+
400
+ ret_ptr = FFI::MemoryPointer.new(:pointer)
401
+ Bindings.get_struct_element_types(@ptr, ret_ptr)
402
+
403
+ types_ptr = ret_ptr.get_pointer(0)
404
+
405
+ types_ptr.get_array_of_pointer(0, num_elements).map { |ptr| Type.from_ptr(ptr) }
406
+ end
407
+ end
408
+
409
+ # Set the types in the body of this struct type.
410
+ #
411
+ # @param [Array<Type>] el_types Array of types in the struct.
412
+ # @param [Boolean] packed Are the types packed already, or should they be re-arranged to save space?
413
+ #
414
+ # @return [void]
415
+ def element_types=(el_types, packed = false)
416
+ @element_types = check_cg_array_type(el_types, Type, 'el_types')
417
+
418
+ el_types_ptr = FFI::MemoryPointer.new(:pointer, @element_types.length)
419
+ el_types_ptr.write_array_of_pointer(@element_types)
420
+
421
+ Bindings.struct_set_body(@ptr, el_types_ptr, @element_types.length, packed.to_i)
422
+ end
423
+
424
+ # @return [String] Name of the struct type in LLVM IR.
425
+ def name
426
+ @name ||= Bindings.get_struct_name(@ptr)
427
+ end
428
+ end
429
+ end
430
+
431
+ ####################
432
+ # Helper Functions #
433
+ ####################
434
+
435
+ # This helper function checks to make sure that an object is a sub-class of
436
+ # {RLTK::CG::Type Type} or an instance of a sub-class of Type. If a class is
437
+ # passed in the *o* parameter it is expected to be a singleton class and will
438
+ # be instantiated via the *instance* method.
439
+ #
440
+ # @param [Type, Class] o Object to type check for code generation type.
441
+ # @param [Type] type Class the object should be an instance (or sub-class) of.
442
+ # @param [String] blame Variable name to blame for failed type checks.
443
+ # @param [Boolean] strict Strict or non-strict checking. Uses `instance_of?` and `is_a?` respectively.
444
+ #
445
+ # @raise [RuntimeError] An error is raise if a class is passed in parameter *o*
446
+ # that hasn't included the Singleton class, if the class passed in parameter
447
+ # *type* isn't a sub-class of {RLTK::CG::Type Type}, or if the type check
448
+ # fails.
449
+ #
450
+ # @return [Type] The object *o* or an instance of the class passed in parameter *o*.
451
+ def check_cg_type(o, type = RLTK::CG::Type, blame = 'type', strict = false)
452
+ if o.is_a?(Class)
453
+ type_ok = if strict then o == type else o.subclass_of?(type) end
454
+
455
+ if type_ok
456
+ if o.includes_module?(Singleton)
457
+ o.instance
458
+ else
459
+ raise "The #{o.name} class (passed as parameter #{blame}) must be instantiated directly."
460
+ end
461
+ else
462
+ raise "The #{o.name} class (passed as parameter #{blame} does not inherit from the #{type.name} class."
463
+ end
464
+ else
465
+ check_type(o, type, blame, strict)
466
+ end
467
+ end
468
+
469
+ # This helper function checks to make sure that an array of objects are all
470
+ # sub-classses of {RLTK::CG::Type Type} or instances of a sub-class of Type.
471
+ # If a class is present in the *array* parameter it is expected to be a
472
+ # singleton class and will be instantiated via the *instance* method.
473
+ #
474
+ # @param [Array<Type, Class>] array Array of objects to type check for code generation type.
475
+ # @param [Type] type Class the objects should be an instance (or sub-class) of.
476
+ # @param [String] blame Variable name to blame for failed type checks.
477
+ # @param [Boolean] strict Strict or non-strict checking. Uses `instance_of?` and `is_a?` respectively.
478
+ #
479
+ # @raise [RuntimeError] An error is raise if a class is passed in *array* that
480
+ # hasn't included the Singleton class, if the class passed in parameter
481
+ # *type* isn't a sub-class of {RLTK::CG::Type Type}, or if the type check
482
+ # fails.
483
+ #
484
+ # @return [Array<Type>] An array containing the objects in *array* with any singleton classes replaced by their instances.
485
+ def check_cg_array_type(array, type = RLTK::CG::Type, blame = 'el_types', strict = false)
486
+ array.map do |o|
487
+ if o.is_a?(Class)
488
+ type_ok = if strict then o == type else o.subclass_of?(type) end
489
+
490
+ if type_ok
491
+ if o.includes_module?(Singleton)
492
+ o.instance
493
+ else
494
+ raise "The #{o.name} class (passed in parameter #{blame}) must be instantiated directly."
495
+ end
496
+ else
497
+ raise "The #{o.name} class (passed in parameter #{blame}) does not inherit from the #{type.name} class."
498
+ end
499
+
500
+ else
501
+ type_ok = if strict then o.instance_of(type) else o.is_a?(type) end
502
+
503
+ if type_ok
504
+ o
505
+ else
506
+ raise "Parameter #{blame} must contain instances of the #{type.name} class."
507
+ end
508
+ end
509
+ end
510
+ end