rltk 2.2.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +12 -12
- data/README.md +458 -285
- data/Rakefile +99 -92
- data/lib/rltk/ast.rb +221 -126
- data/lib/rltk/cfg.rb +218 -239
- data/lib/rltk/cg/basic_block.rb +1 -1
- data/lib/rltk/cg/bindings.rb +9 -26
- data/lib/rltk/cg/builder.rb +40 -8
- data/lib/rltk/cg/context.rb +1 -1
- data/lib/rltk/cg/contractor.rb +51 -0
- data/lib/rltk/cg/execution_engine.rb +45 -8
- data/lib/rltk/cg/function.rb +12 -2
- data/lib/rltk/cg/generated_bindings.rb +2541 -575
- data/lib/rltk/cg/generic_value.rb +2 -2
- data/lib/rltk/cg/instruction.rb +104 -83
- data/lib/rltk/cg/llvm.rb +44 -3
- data/lib/rltk/cg/memory_buffer.rb +22 -5
- data/lib/rltk/cg/module.rb +85 -36
- data/lib/rltk/cg/old_generated_bindings.rb +6152 -0
- data/lib/rltk/cg/pass_manager.rb +87 -43
- data/lib/rltk/cg/support.rb +2 -4
- data/lib/rltk/cg/target.rb +158 -28
- data/lib/rltk/cg/triple.rb +8 -8
- data/lib/rltk/cg/type.rb +69 -25
- data/lib/rltk/cg/value.rb +107 -66
- data/lib/rltk/cg.rb +16 -17
- data/lib/rltk/lexer.rb +21 -11
- data/lib/rltk/lexers/calculator.rb +1 -1
- data/lib/rltk/lexers/ebnf.rb +8 -7
- data/lib/rltk/parser.rb +300 -247
- data/lib/rltk/parsers/infix_calc.rb +1 -1
- data/lib/rltk/parsers/postfix_calc.rb +2 -2
- data/lib/rltk/parsers/prefix_calc.rb +2 -2
- data/lib/rltk/token.rb +1 -2
- data/lib/rltk/version.rb +3 -3
- data/lib/rltk.rb +6 -6
- data/test/cg/tc_basic_block.rb +83 -0
- data/test/cg/tc_control_flow.rb +191 -0
- data/test/cg/tc_function.rb +54 -0
- data/test/cg/tc_generic_value.rb +33 -0
- data/test/cg/tc_instruction.rb +256 -0
- data/test/cg/tc_llvm.rb +25 -0
- data/test/cg/tc_math.rb +88 -0
- data/test/cg/tc_module.rb +89 -0
- data/test/cg/tc_transforms.rb +68 -0
- data/test/cg/tc_type.rb +69 -0
- data/test/cg/tc_value.rb +151 -0
- data/test/cg/ts_cg.rb +23 -0
- data/test/tc_ast.rb +105 -8
- data/test/tc_cfg.rb +63 -48
- data/test/tc_lexer.rb +84 -96
- data/test/tc_parser.rb +224 -52
- data/test/tc_token.rb +6 -6
- data/test/ts_rltk.rb +12 -15
- metadata +149 -75
- data/lib/rltk/cg/generated_extended_bindings.rb +0 -287
- data/lib/rltk/util/abstract_class.rb +0 -25
- data/lib/rltk/util/monkeys.rb +0 -129
data/lib/rltk/cg/pass_manager.rb
CHANGED
@@ -14,7 +14,7 @@ require 'rltk/cg/bindings'
|
|
14
14
|
# Classes and Modules #
|
15
15
|
#######################
|
16
16
|
|
17
|
-
module RLTK::CG
|
17
|
+
module RLTK::CG
|
18
18
|
|
19
19
|
# A PassManager is responsible for scheduling and running optimization
|
20
20
|
# passes on modules.
|
@@ -27,48 +27,53 @@ module RLTK::CG # :nodoc:
|
|
27
27
|
# A list of passes that are available to be added to the pass
|
28
28
|
# manager via the {PassManager#add} method.
|
29
29
|
PASSES = {
|
30
|
-
:ADCE
|
31
|
-
:AlwaysInline
|
32
|
-
:ArgPromote
|
33
|
-
:BasicAliasAnalysis
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
30
|
+
:ADCE => :aggressive_dce,
|
31
|
+
:AlwaysInline => :always_inliner,
|
32
|
+
:ArgPromote => :argument_promotion,
|
33
|
+
:BasicAliasAnalysis => :basic_alias_analysis,
|
34
|
+
:BBVectorize => :bb_vectorize,
|
35
|
+
:CFGSimplify => :cfg_simplification,
|
36
|
+
:ConstMerge => :constant_merge,
|
37
|
+
:ConstProp => :constant_propagation,
|
38
|
+
:CorValProp => :correlated_value_propagation,
|
39
|
+
:DAE => :dead_arg_elimination,
|
40
|
+
:DSE => :dead_store_elimination,
|
41
|
+
:DemoteMemToReg => :demote_memory_to_register,
|
42
|
+
:EarlyCSE => :early_cse,
|
43
|
+
:FunctionAttrs => :function_attrs,
|
44
|
+
:FunctionInline => :function_inlining,
|
45
|
+
:GDCE => :global_dce,
|
46
|
+
:GlobalOpt => :global_optimizer,
|
47
|
+
:GVN => :gvn,
|
48
|
+
:Internalize => :internalize,
|
49
|
+
:IndVarSimplify => :ind_var_simplify,
|
50
|
+
:InstCombine => :instruction_combining,
|
51
|
+
:IPConstProp => :ip_constant_propagation,
|
52
|
+
:IPSCCP => :ipsccp,
|
53
|
+
:JumpThreading => :jump_threading,
|
54
|
+
:LICM => :licm,
|
55
|
+
:LoopDeletion => :loop_deletion,
|
56
|
+
:LoopIdiom => :loop_idiom,
|
57
|
+
:LoopReroll => :loop_reroll,
|
58
|
+
:LoopRotate => :loop_rotate,
|
59
|
+
:LoopUnroll => :loop_unroll,
|
60
|
+
:LoopUnswitch => :loop_unswitch,
|
61
|
+
:LoopVectorize => :loop_vectorize,
|
62
|
+
:LEI => :lower_expect_intrinsics,
|
63
|
+
:MemCopyOpt => :mem_cpy_opt,
|
64
|
+
:PILC => :partially_inline_lib_calls,
|
65
|
+
:PromoteMemToReg => :promote_memory_to_register,
|
66
|
+
:PruneEH => :prune_eh,
|
67
|
+
:Reassociate => :reassociate,
|
68
|
+
:SCCP => :sccp,
|
69
|
+
:ScalarRepl => :scalar_repl_aggregates,
|
70
|
+
:SimplifyLibCalls => :simplify_lib_calls,
|
71
|
+
:SLPVectorize => :slp_vectorize,
|
72
|
+
:StripDeadProtos => :strip_dead_prototypes,
|
73
|
+
:StripSymbols => :strip_symbols,
|
74
|
+
:TailCallElim => :tail_call_elimination,
|
75
|
+
:TBAA => :type_based_alias_analysis,
|
76
|
+
:Verifier => :verifier
|
72
77
|
}
|
73
78
|
|
74
79
|
# Create a new pass manager. You should never have to do this as
|
@@ -205,4 +210,43 @@ module RLTK::CG # :nodoc:
|
|
205
210
|
Bindings.finalize_function_pass_manager(@ptr).to_bool
|
206
211
|
end
|
207
212
|
end
|
213
|
+
|
214
|
+
PASS_GROUPS = [
|
215
|
+
:analysis,
|
216
|
+
:core,
|
217
|
+
:inst_combine,
|
218
|
+
:instrumentation,
|
219
|
+
:ipa,
|
220
|
+
:ipo,
|
221
|
+
:objc_arc_opts,
|
222
|
+
:scalar_opts,
|
223
|
+
:target,
|
224
|
+
:transform_utils,
|
225
|
+
:vectorization
|
226
|
+
]
|
227
|
+
|
228
|
+
class PassRegistry
|
229
|
+
include BindingClass
|
230
|
+
|
231
|
+
def self.global
|
232
|
+
PassRegistry.allocate.tap { |pr| pr.ptr = Bindings.get_global_pass_registry }
|
233
|
+
end
|
234
|
+
|
235
|
+
def initialize
|
236
|
+
@ptr = Bindings::OpaquePassRegistry.new
|
237
|
+
end
|
238
|
+
|
239
|
+
def init(pass_group = :all)
|
240
|
+
if pass_group == :all
|
241
|
+
PASS_GROUPS.each { |pg| Bindings.send("initialize_#{pg}", @ptr) }
|
242
|
+
|
243
|
+
elsif PASS_GROUPS.include?(pass_group)
|
244
|
+
Bindings.send("initialize_#{pass_group}", @ptr)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def init(pass_group)
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
208
252
|
end
|
data/lib/rltk/cg/support.rb
CHANGED
@@ -14,16 +14,14 @@ require 'rltk/cg/bindings'
|
|
14
14
|
# Classes and Modules #
|
15
15
|
#######################
|
16
16
|
|
17
|
-
module RLTK::CG
|
17
|
+
module RLTK::CG
|
18
18
|
|
19
19
|
# Support functionality for LLVM code generation.
|
20
20
|
module Support
|
21
21
|
# Load a shared library into memory and make its exported symbols
|
22
22
|
# available to execution engines.
|
23
23
|
#
|
24
|
-
# @
|
25
|
-
#
|
26
|
-
# @param [String] lib Path to the shared library to load.
|
24
|
+
# @param [String] lib Path to the shared library to load
|
27
25
|
def self.load_library(lib)
|
28
26
|
Bindings.load_library_permanently(lib).to_bool
|
29
27
|
end
|
data/lib/rltk/cg/target.rb
CHANGED
@@ -15,20 +15,35 @@ require 'rltk/cg/triple'
|
|
15
15
|
# Classes and Modules #
|
16
16
|
#######################
|
17
17
|
|
18
|
-
module RLTK::CG
|
18
|
+
module RLTK::CG
|
19
19
|
|
20
20
|
# Class binding for the LLVM Triple class.
|
21
21
|
class Target
|
22
22
|
include BindingClass
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
#################
|
25
|
+
# Class Methods #
|
26
|
+
#################
|
27
|
+
|
28
|
+
# @return [Target] First target in the target list
|
29
|
+
def self.first
|
30
|
+
@first ||= self.new(Bindings.get_first_target)
|
31
|
+
end
|
26
32
|
|
27
33
|
# @return [Target] Target object for the host architecture.
|
28
34
|
def self.host
|
29
35
|
@host ||= self.new(Triple.host)
|
30
36
|
end
|
31
37
|
|
38
|
+
# @return [Target] Next target in the target list
|
39
|
+
def self.next_target(target)
|
40
|
+
self.new(Bindings.get_next_target(target))
|
41
|
+
end
|
42
|
+
|
43
|
+
####################
|
44
|
+
# Instance Methods #
|
45
|
+
####################
|
46
|
+
|
32
47
|
# Create an object representing a particular code generation target.
|
33
48
|
# You can create a target either from a string or a Triple.
|
34
49
|
#
|
@@ -36,10 +51,57 @@ module RLTK::CG # :nodoc:
|
|
36
51
|
def initialize(overloaded)
|
37
52
|
@ptr, @triple =
|
38
53
|
case overloaded
|
39
|
-
when String
|
40
|
-
|
54
|
+
when String
|
55
|
+
[Bindings.get_target_from_name(overloaded), Triple.new(overloaded)]
|
56
|
+
|
57
|
+
when RLTK::CG::Triple
|
58
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
59
|
+
error = FFI::MemoryPointer.new(:pointer)
|
60
|
+
status = Bindings.get_target_from_triple(overloaded.to_s, ptr, error)
|
61
|
+
|
62
|
+
if status.zero?
|
63
|
+
[ptr, overloaded]
|
64
|
+
|
65
|
+
else
|
66
|
+
errorp = error.read_pointer
|
67
|
+
message = errorp.null? ? 'Unknown' : errorp.read_string
|
68
|
+
|
69
|
+
error.autorelease = false
|
70
|
+
|
71
|
+
Bindings.dispose_message(error)
|
72
|
+
|
73
|
+
raise "Error creating target: #{message}"
|
74
|
+
end
|
75
|
+
|
76
|
+
when RLTK::CG::Bindings::Triple
|
77
|
+
[overloaded, nil]
|
41
78
|
end
|
42
79
|
end
|
80
|
+
|
81
|
+
# @return [Boolean] Whether or not the target has an ASM backend
|
82
|
+
def asm_backend?
|
83
|
+
Bindings.target_has_asm_backend(@ptr).to_bool
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [Boolean] Whether or not the target has a JIT
|
87
|
+
def jit?
|
88
|
+
Bindings.target_has_jit(@ptr).to_bool
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Boolean] Whether or not the target has a TargetMachine
|
92
|
+
def target_machine?
|
93
|
+
Bindings.target_has_target_machine(@ptr).to_bool
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [String] Description of the target
|
97
|
+
def describe
|
98
|
+
Bindings.get_target_description(@ptr)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [Triple] Triple object for this target
|
102
|
+
def triple
|
103
|
+
@triple ||= Triple.new(Bindings.get_target_name(@ptr))
|
104
|
+
end
|
43
105
|
end
|
44
106
|
|
45
107
|
# This class represents data about a specific architecture. Currently it
|
@@ -51,6 +113,16 @@ module RLTK::CG # :nodoc:
|
|
51
113
|
def initialize(ptr)
|
52
114
|
@ptr = ptr
|
53
115
|
end
|
116
|
+
|
117
|
+
# Gets the pointer size for this target machine and address space
|
118
|
+
# combination.
|
119
|
+
#
|
120
|
+
# @param [Integer] as Address space
|
121
|
+
#
|
122
|
+
# @return [Integer] Size of pointer
|
123
|
+
def pointer_size(as)
|
124
|
+
Bindings.pointer_size_for_as(@ptr, as)
|
125
|
+
end
|
54
126
|
end
|
55
127
|
|
56
128
|
# This class represents a specific architecture that wil be targeted by
|
@@ -58,18 +130,8 @@ module RLTK::CG # :nodoc:
|
|
58
130
|
class TargetMachine
|
59
131
|
include BindingClass
|
60
132
|
|
61
|
-
#
|
62
|
-
|
63
|
-
#
|
64
|
-
# @param [Array<String>] features Strings representing features of a target machine.
|
65
|
-
#
|
66
|
-
# @return [String] A single string representing all of the given features.
|
67
|
-
def self.build_feature_string(features)
|
68
|
-
strings_ptr = FFI::MemoryPointer.new(:pointer, features.length)
|
69
|
-
strings_ptr.write_array_of_pointer(features.map { |str| FFI::MemoryPointer.from_string(str) })
|
70
|
-
|
71
|
-
Bindings.build_features_string(strings_ptr, features.length)
|
72
|
-
end
|
133
|
+
# The Proc object called by the garbage collector to free resources used by LLVM.
|
134
|
+
CLASS_FINALIZER = Proc.new { |id| Bindings.dispose_target_machine(ptr) if ptr = ObjectSpace._id2ref(id).ptr }
|
73
135
|
|
74
136
|
# @return [TargetMachine] TargetMachine representation of the host machine.
|
75
137
|
def self.host
|
@@ -81,20 +143,88 @@ module RLTK::CG # :nodoc:
|
|
81
143
|
# @see Bindings._enum_reloc_model_
|
82
144
|
# @see Bindings._enum_code_model_
|
83
145
|
#
|
84
|
-
# @param [Target]
|
85
|
-
# @param [String]
|
86
|
-
# @param [Array<String>, String]
|
87
|
-
# @param [Symbol]
|
88
|
-
# @param [Symbol]
|
89
|
-
|
90
|
-
|
91
|
-
reloc_model = :default_rmodel if reloc_model == :default
|
92
|
-
code_model = :default_cmodel if code_model == :default
|
93
|
-
|
146
|
+
# @param [Target] target Target description
|
147
|
+
# @param [String] mcpu Specific CPU type to target
|
148
|
+
# @param [Array<String>, String] features Features present for this target machine
|
149
|
+
# @param [Symbol from _enum_code_gen_opt_level_] opt_level Optimization level
|
150
|
+
# @param [Symbol from _enum_reloc_mode_] reloc_mode Code relocation model
|
151
|
+
# @param [Symbol from _enum_code_model_] code_model Code generation model
|
152
|
+
def initialize(target, mcpu = '', features = '', opt_level = :none, reloc_mode = :default, code_model = :default)
|
94
153
|
# Convert the features parameter if necessary.
|
95
154
|
features = TargetMachine.build_feature_string(features) if features.is_a?(Array)
|
96
155
|
|
97
|
-
@ptr = Bindings.create_target_machine(target, target.triple.to_s, mcpu, features,
|
156
|
+
@ptr = Bindings.create_target_machine(target, target.triple.to_s, mcpu, features, opt_level, reloc_mode, code_model)
|
157
|
+
|
158
|
+
# Define a finalizer to free the memory used by LLVM for
|
159
|
+
# this target machine.
|
160
|
+
ObjectSpace.define_finalizer(self, CLASS_FINALIZER)
|
161
|
+
end
|
162
|
+
|
163
|
+
# @return [String] Name of the target machine's CPU
|
164
|
+
def cpu
|
165
|
+
Bindings.get_target_machine_cpu(@ptr)
|
166
|
+
end
|
167
|
+
|
168
|
+
# @return [TargetData]
|
169
|
+
def data
|
170
|
+
TargetData.new(Bindings.get_target_machine_data(@pt))
|
171
|
+
end
|
172
|
+
|
173
|
+
# Emit assembly or object code for the given module to the file
|
174
|
+
# specified.
|
175
|
+
#
|
176
|
+
# @param [Module] mod Module to emit code for
|
177
|
+
# @param [String] file_name File to emit code to
|
178
|
+
# @param [:assembly, :object] emit_type Type of code to emit
|
179
|
+
#
|
180
|
+
# @return [void]
|
181
|
+
#
|
182
|
+
# @raise LLVM error message if unable to emite code for module
|
183
|
+
def emit_module(mod, file_name, emit_type)
|
184
|
+
error = FFI::MemoryPointer.new(:pointer)
|
185
|
+
status = Bindings.target_machine_emit_to_file(@ptr, mod, file_name, emit_type, error)
|
186
|
+
|
187
|
+
if not status.zero?
|
188
|
+
errorp = error.read_pointer
|
189
|
+
message = errorp.null? ? 'Unknown' : errorp.read_string
|
190
|
+
|
191
|
+
error.autorelease = false
|
192
|
+
|
193
|
+
Bindings.dispose_message(error)
|
194
|
+
|
195
|
+
raise "Error emiting code for module: #{message}"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# @return [String] Feature string for this target machine
|
200
|
+
def feature_string
|
201
|
+
Bindings.get_target_machine_feature_string(@ptr)
|
202
|
+
end
|
203
|
+
|
204
|
+
# @return [Target]
|
205
|
+
def target
|
206
|
+
Target.new(Bindings.get_target_machine_target(@ptr))
|
207
|
+
end
|
208
|
+
|
209
|
+
# @return [Triple]
|
210
|
+
def triple
|
211
|
+
Triple.new(Bindings.get_target_machine_triple(@ptr))
|
212
|
+
end
|
213
|
+
|
214
|
+
# Set verbose ASM property.
|
215
|
+
#
|
216
|
+
# @param [Boolean] bool Verbose ASM or not
|
217
|
+
#
|
218
|
+
# @return [void]
|
219
|
+
def verbose_asm=(bool)
|
220
|
+
@verbose_asm = bool
|
221
|
+
|
222
|
+
Bindings.set_target_machine_asm_verbosity(@ptr, bool.to_i)
|
223
|
+
end
|
224
|
+
|
225
|
+
# @return [Boolean] If this target machine should print verbose ASM
|
226
|
+
def verbose_asm?
|
227
|
+
@verbose_asm ||= false
|
98
228
|
end
|
99
229
|
end
|
100
230
|
end
|
data/lib/rltk/cg/triple.rb
CHANGED
@@ -14,7 +14,7 @@ require 'rltk/cg/bindings'
|
|
14
14
|
# Classes and Modules #
|
15
15
|
#######################
|
16
16
|
|
17
|
-
module RLTK::CG
|
17
|
+
module RLTK::CG
|
18
18
|
|
19
19
|
# Class binding for the LLVM Triple class.
|
20
20
|
class Triple
|
@@ -26,12 +26,12 @@ module RLTK::CG # :nodoc:
|
|
26
26
|
|
27
27
|
# @return [Triple] Object representing the host architecture, vendor, OS, and environment.
|
28
28
|
def self.host
|
29
|
-
@host ||=
|
29
|
+
@host ||= Triple.new(host_string)
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# @return [String] String representation of the host architecture, vendor, OS, and environment.
|
33
33
|
def self.host_string
|
34
|
-
@host_string ||= Bindings.
|
34
|
+
@host_string ||= Bindings.get_default_target_triple
|
35
35
|
end
|
36
36
|
|
37
37
|
####################
|
@@ -43,16 +43,16 @@ module RLTK::CG # :nodoc:
|
|
43
43
|
#
|
44
44
|
# @param [FFI::Pointer, String] overloaded
|
45
45
|
def initialize(overloaded)
|
46
|
-
@ptr =
|
46
|
+
@ptr, @str =
|
47
47
|
case overloaded
|
48
|
-
when FFI::Pointer
|
49
|
-
when String
|
48
|
+
when FFI::Pointer then [overloaded, nil]
|
49
|
+
when String then [Bindings.triple_create(overloaded), overloaded]
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
# @return [String] String representation of this triple.
|
54
54
|
def to_s
|
55
|
-
Bindings.get_triple_string(@ptr)
|
55
|
+
@str ||= Bindings.get_triple_string(@ptr)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
data/lib/rltk/cg/type.rb
CHANGED
@@ -10,8 +10,10 @@
|
|
10
10
|
# Standard Library
|
11
11
|
require 'singleton'
|
12
12
|
|
13
|
+
# Gems
|
14
|
+
require 'filigree/abstract_class'
|
15
|
+
|
13
16
|
# Ruby Language Toolkit
|
14
|
-
require 'rltk/util/abstract_class'
|
15
17
|
require 'rltk/cg/bindings'
|
16
18
|
require 'rltk/cg/context'
|
17
19
|
|
@@ -19,7 +21,7 @@ require 'rltk/cg/context'
|
|
19
21
|
# Classes and Modules #
|
20
22
|
#######################
|
21
23
|
|
22
|
-
module RLTK::CG
|
24
|
+
module RLTK::CG
|
23
25
|
|
24
26
|
# The Type class and its sub-classes are used to describe the size and
|
25
27
|
# structure of various data objects inside LLVM and how different
|
@@ -29,7 +31,7 @@ module RLTK::CG # :nodoc:
|
|
29
31
|
# @abstract Root of the type class hierarchy.
|
30
32
|
class Type
|
31
33
|
include BindingClass
|
32
|
-
include AbstractClass
|
34
|
+
include Filigree::AbstractClass
|
33
35
|
|
34
36
|
# Instantiate a Type object from a pointer. This function is used
|
35
37
|
# internally, and as a library user you should never have to call it.
|
@@ -40,6 +42,7 @@ module RLTK::CG # :nodoc:
|
|
40
42
|
def self.from_ptr(ptr)
|
41
43
|
case Bindings.get_type_kind(ptr)
|
42
44
|
when :array then ArrayType.new(ptr)
|
45
|
+
when :half then HalfType.new
|
43
46
|
when :double then DoubleType.new
|
44
47
|
when :float then FloatType.new
|
45
48
|
when :function then FunctionType.new(ptr)
|
@@ -73,7 +76,7 @@ module RLTK::CG # :nodoc:
|
|
73
76
|
|
74
77
|
# @return [NativeInt] Alignment of the type.
|
75
78
|
def allignment
|
76
|
-
|
79
|
+
NativeInt.new(Bindings.align_of(@ptr))
|
77
80
|
end
|
78
81
|
|
79
82
|
# @return [Context] Context in which this type was created.
|
@@ -81,6 +84,13 @@ module RLTK::CG # :nodoc:
|
|
81
84
|
Context.new(Bindings.get_type_context(@ptr))
|
82
85
|
end
|
83
86
|
|
87
|
+
# Dump a string representation of the type to stdout.
|
88
|
+
#
|
89
|
+
# @return [void]
|
90
|
+
def dump
|
91
|
+
Bindings.dump_type(@ptr)
|
92
|
+
end
|
93
|
+
|
84
94
|
# @return [Fixnum] Hashed value of the pointer representing this type.
|
85
95
|
def hash
|
86
96
|
@ptr.address.hash
|
@@ -97,13 +107,18 @@ module RLTK::CG # :nodoc:
|
|
97
107
|
def size
|
98
108
|
Int64.new(Bindings.size_of(@ptr))
|
99
109
|
end
|
110
|
+
|
111
|
+
# @return [String] LLVM IR representation of the type
|
112
|
+
def to_s
|
113
|
+
Bindings.print_type_to_string(@ptr)
|
114
|
+
end
|
100
115
|
end
|
101
116
|
|
102
117
|
# All types that are used to represent numbers inherit from this class.
|
103
118
|
#
|
104
119
|
# @abstract
|
105
120
|
class NumberType < Type
|
106
|
-
include AbstractClass
|
121
|
+
include Filigree::AbstractClass
|
107
122
|
|
108
123
|
# @return [Value] The corresponding Value sub-class that is used to represent values of this type.
|
109
124
|
def self.value_class
|
@@ -126,7 +141,7 @@ module RLTK::CG # :nodoc:
|
|
126
141
|
#
|
127
142
|
# @abstract
|
128
143
|
class BasicIntType < NumberType
|
129
|
-
include AbstractClass
|
144
|
+
include Filigree::AbstractClass
|
130
145
|
|
131
146
|
# @return [Integer] Number of bits used to represent an integer type.
|
132
147
|
def width
|
@@ -165,7 +180,7 @@ module RLTK::CG # :nodoc:
|
|
165
180
|
#
|
166
181
|
# @abstract
|
167
182
|
class SimpleIntType < BasicIntType
|
168
|
-
include AbstractClass
|
183
|
+
include Filigree::AbstractClass
|
169
184
|
include Singleton
|
170
185
|
end
|
171
186
|
|
@@ -173,7 +188,7 @@ module RLTK::CG # :nodoc:
|
|
173
188
|
#
|
174
189
|
# @abstract
|
175
190
|
class RealType < NumberType
|
176
|
-
include AbstractClass
|
191
|
+
include Filigree::AbstractClass
|
177
192
|
include Singleton
|
178
193
|
end
|
179
194
|
|
@@ -181,48 +196,77 @@ module RLTK::CG # :nodoc:
|
|
181
196
|
#
|
182
197
|
# @abstract
|
183
198
|
class SimpleType < Type
|
184
|
-
include AbstractClass
|
199
|
+
include Filigree::AbstractClass
|
185
200
|
include Singleton
|
186
201
|
end
|
187
202
|
|
188
203
|
# 1 bit integer type. Often used to represent Boolean values.
|
189
|
-
class Int1Type
|
204
|
+
class Int1Type < SimpleIntType; end
|
190
205
|
# 8 bit (1 byte) integer type.
|
191
|
-
class Int8Type
|
206
|
+
class Int8Type < SimpleIntType; end
|
192
207
|
# 16 bit (2 byte) integer type.
|
193
|
-
class Int16Type
|
208
|
+
class Int16Type < SimpleIntType; end
|
194
209
|
# 32 bit (4 byte) integer type.
|
195
|
-
class Int32Type
|
210
|
+
class Int32Type < SimpleIntType; end
|
196
211
|
# 64 bit (8 byte) integer type.
|
197
|
-
class Int64Type
|
212
|
+
class Int64Type < SimpleIntType; end
|
213
|
+
|
214
|
+
# Integer the same size as a native pointer.
|
215
|
+
class IntPtr < SimpleIntType
|
216
|
+
# Create an integer that is the same size as a pointer on the target
|
217
|
+
# machine. Additionally, an address space and a context may be
|
218
|
+
# provided.
|
219
|
+
#
|
220
|
+
# @param [TargetData] target_data Data on compilation target
|
221
|
+
# @param [Integer] addr_space Target address space
|
222
|
+
# @param [Context] context Context in which to get the type
|
223
|
+
def initialize(target_data, addr_space = nil, context = nil)
|
224
|
+
call = 'int_type'
|
225
|
+
args = [target_data]
|
226
|
+
|
227
|
+
if addr_space
|
228
|
+
call += '_for_as'
|
229
|
+
args << addr_space
|
230
|
+
end
|
231
|
+
|
232
|
+
if context
|
233
|
+
call += '_in_context'
|
234
|
+
args << context
|
235
|
+
end
|
236
|
+
|
237
|
+
Bindings.send(call.to_s, *args)
|
238
|
+
end
|
239
|
+
end
|
198
240
|
|
199
241
|
# The native integer type on the current (not the target) platform.
|
200
242
|
NativeIntType = RLTK::CG.const_get("Int#{FFI.type_size(:int) * 8}Type")
|
201
243
|
|
244
|
+
# A 16-bit floating point number type.
|
245
|
+
class HalfType < RealType; end
|
202
246
|
# A double precision floating point number type.
|
203
|
-
class DoubleType
|
247
|
+
class DoubleType < RealType; end
|
204
248
|
# A single precision floating point number type.
|
205
|
-
class FloatType
|
249
|
+
class FloatType < RealType; end
|
206
250
|
# A 128 bit (16 byte) floating point number type.
|
207
|
-
class FP128Type
|
251
|
+
class FP128Type < RealType; end
|
208
252
|
# A 128 bit (16 byte) floating point number type for the PPC architecture.
|
209
|
-
class PPCFP128Type
|
253
|
+
class PPCFP128Type < RealType; end
|
210
254
|
# A 80 bit (10 byte) floating point number type for the x86 architecture.
|
211
|
-
class X86FP80Type
|
255
|
+
class X86FP80Type < RealType; end
|
212
256
|
|
213
257
|
# A type for x86 MMX instructions.
|
214
|
-
class X86MMXType
|
258
|
+
class X86MMXType < SimpleType; end
|
215
259
|
|
216
260
|
# A type used in representing void pointers and functions that return no values.
|
217
|
-
class VoidType
|
261
|
+
class VoidType < SimpleType; end
|
218
262
|
# A type used to represent labels in LLVM IR.
|
219
|
-
class LabelType
|
263
|
+
class LabelType < SimpleType; end
|
220
264
|
|
221
265
|
# The common ancestor for array, pointer, and struct types.
|
222
266
|
#
|
223
267
|
# @abstract
|
224
268
|
class AggregateType < Type
|
225
|
-
include AbstractClass
|
269
|
+
include Filigree::AbstractClass
|
226
270
|
end
|
227
271
|
|
228
272
|
# {ArrayType} and {PointerType} inherit from this class so they can share
|
@@ -230,7 +274,7 @@ module RLTK::CG # :nodoc:
|
|
230
274
|
#
|
231
275
|
# @abstract
|
232
276
|
class SimpleAggregateType < AggregateType
|
233
|
-
include AbstractClass
|
277
|
+
include Filigree::AbstractClass
|
234
278
|
|
235
279
|
# Used to initialize {ArrayType ArrayTypes} and {PointerType PointerTypes}.
|
236
280
|
#
|
@@ -376,7 +420,7 @@ module RLTK::CG # :nodoc:
|
|
376
420
|
if name
|
377
421
|
@name = check_type(name, String, 'name')
|
378
422
|
|
379
|
-
|
423
|
+
Bindings.struct_create_named(Context.global, @name).tap do |ptr|
|
380
424
|
Bindings.struct_set_body(ptr, el_types_ptr, @element_types.length, packed.to_i) unless @element_types.empty?
|
381
425
|
end
|
382
426
|
|