rltk 2.2.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|