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.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/LICENSE +27 -0
- data/README.md +852 -0
- data/Rakefile +197 -0
- data/lib/rltk/ast.rb +573 -0
- data/lib/rltk/cfg.rb +683 -0
- data/lib/rltk/cg/basic_block.rb +157 -0
- data/lib/rltk/cg/bindings.rb +151 -0
- data/lib/rltk/cg/builder.rb +1127 -0
- data/lib/rltk/cg/context.rb +48 -0
- data/lib/rltk/cg/contractor.rb +51 -0
- data/lib/rltk/cg/execution_engine.rb +194 -0
- data/lib/rltk/cg/function.rb +237 -0
- data/lib/rltk/cg/generated_bindings.rb +8118 -0
- data/lib/rltk/cg/generic_value.rb +95 -0
- data/lib/rltk/cg/instruction.rb +519 -0
- data/lib/rltk/cg/llvm.rb +150 -0
- data/lib/rltk/cg/memory_buffer.rb +75 -0
- data/lib/rltk/cg/module.rb +451 -0
- data/lib/rltk/cg/pass_manager.rb +252 -0
- data/lib/rltk/cg/support.rb +29 -0
- data/lib/rltk/cg/target.rb +230 -0
- data/lib/rltk/cg/triple.rb +58 -0
- data/lib/rltk/cg/type.rb +554 -0
- data/lib/rltk/cg/value.rb +1272 -0
- data/lib/rltk/cg.rb +32 -0
- data/lib/rltk/lexer.rb +372 -0
- data/lib/rltk/lexers/calculator.rb +44 -0
- data/lib/rltk/lexers/ebnf.rb +38 -0
- data/lib/rltk/parser.rb +1702 -0
- data/lib/rltk/parsers/infix_calc.rb +43 -0
- data/lib/rltk/parsers/postfix_calc.rb +34 -0
- data/lib/rltk/parsers/prefix_calc.rb +34 -0
- data/lib/rltk/token.rb +90 -0
- data/lib/rltk/version.rb +11 -0
- data/lib/rltk.rb +16 -0
- 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 +332 -0
- data/test/tc_cfg.rb +164 -0
- data/test/tc_lexer.rb +216 -0
- data/test/tc_parser.rb +711 -0
- data/test/tc_token.rb +34 -0
- data/test/ts_rltk.rb +47 -0
- metadata +317 -0
@@ -0,0 +1,252 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/03/15
|
4
|
+
# Description: This file defines the PassManager class.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/cg/bindings'
|
12
|
+
|
13
|
+
#######################
|
14
|
+
# Classes and Modules #
|
15
|
+
#######################
|
16
|
+
|
17
|
+
module RLTK::CG
|
18
|
+
|
19
|
+
# A PassManager is responsible for scheduling and running optimization
|
20
|
+
# passes on modules.
|
21
|
+
class PassManager
|
22
|
+
include BindingClass
|
23
|
+
|
24
|
+
# The Proc object called by the garbage collector to free resources used by LLVM.
|
25
|
+
CLASS_FINALIZER = Proc.new { |id| Bindings.dispose_pass_manager(ptr) if ptr = ObjectSpace._id2ref(id).ptr }
|
26
|
+
|
27
|
+
# A list of passes that are available to be added to the pass
|
28
|
+
# manager via the {PassManager#add} method.
|
29
|
+
PASSES = {
|
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
|
77
|
+
}
|
78
|
+
|
79
|
+
# Create a new pass manager. You should never have to do this as
|
80
|
+
# {Module Modules} should create PassManagers for you whenever they
|
81
|
+
# are requested.
|
82
|
+
#
|
83
|
+
# @see Module#pass_manager
|
84
|
+
#
|
85
|
+
# @param [Module] mod Module this pass manager belongs to.
|
86
|
+
def initialize(mod)
|
87
|
+
# LLVM Initialization
|
88
|
+
@ptr = Bindings.create_pass_manager
|
89
|
+
@mod = mod
|
90
|
+
|
91
|
+
# Set the target data if the module is associated with a execution engine.
|
92
|
+
self.target_data = mod.engine.target_data if mod.engine
|
93
|
+
|
94
|
+
# RLTK Initialization
|
95
|
+
@enabled = Array.new
|
96
|
+
|
97
|
+
# Define a finalizer to free the memory used by LLVM for this
|
98
|
+
# pass manager.
|
99
|
+
ObjectSpace.define_finalizer(self, CLASS_FINALIZER)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Add a pass or passes to this pass manager. Passes may either be
|
103
|
+
# specified via the keys for the PASSES hash or any string that will
|
104
|
+
# be turned into a string (via the {Bindings.get_bname} method)
|
105
|
+
# appearing as a value of the PASSES hash.
|
106
|
+
#
|
107
|
+
# @see PASSES
|
108
|
+
#
|
109
|
+
# @param [Array<Symbol>] names Passes to add to the pass manager.
|
110
|
+
#
|
111
|
+
# @return [PassManager] self
|
112
|
+
def add(*names)
|
113
|
+
names.each do |name|
|
114
|
+
name = name.to_sym
|
115
|
+
|
116
|
+
if PASSES.has_key?(name)
|
117
|
+
next if @enabled.include?(name)
|
118
|
+
|
119
|
+
Bindings.send("add_#{PASSES[name]}_pass", @ptr)
|
120
|
+
|
121
|
+
@enabled << name
|
122
|
+
|
123
|
+
elsif PASSES.has_value?(bname = Bindings.get_bname(name))
|
124
|
+
next if @enabled.include?(PASSES.key(bname))
|
125
|
+
|
126
|
+
Bindings.send("add_#{bname}_pass", @ptr)
|
127
|
+
|
128
|
+
@enabled << PASSES.key(bname)
|
129
|
+
|
130
|
+
else
|
131
|
+
raise "Unknown pass: #{name}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
self
|
136
|
+
end
|
137
|
+
alias :<< :add
|
138
|
+
|
139
|
+
# @return [Array<Symbol>] List of passes that have been enabled.
|
140
|
+
def enabled
|
141
|
+
@enabled.clone
|
142
|
+
end
|
143
|
+
|
144
|
+
# @return [Boolean] Weather the pass has been enabled or not.
|
145
|
+
def enabled?(name)
|
146
|
+
@enabled.include?(name) or @enabled.include?(PASSES.key(Bindings.get_bname(name)))
|
147
|
+
end
|
148
|
+
|
149
|
+
# Run the enabled passes on the execution engine's module.
|
150
|
+
#
|
151
|
+
# @return [void]
|
152
|
+
def run
|
153
|
+
Bindings.run_pass_manager(@ptr, @mod).to_bool
|
154
|
+
end
|
155
|
+
|
156
|
+
# Set the target data for this pass manager.
|
157
|
+
#
|
158
|
+
# @param [TargetData] data
|
159
|
+
#
|
160
|
+
# @return [void]
|
161
|
+
def target_data=(data)
|
162
|
+
Bindings.add_target_data(check_type(data, TargetData, 'data'), @ptr)
|
163
|
+
end
|
164
|
+
|
165
|
+
protected
|
166
|
+
# Empty method used by {FunctionPassManager} to clean up resources.
|
167
|
+
def finalize
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# A FunctionPassManager is responsible for scheduling and running optimization
|
172
|
+
# passes on individual functions inside the context of a module.
|
173
|
+
class FunctionPassManager < PassManager
|
174
|
+
# Create a new function pass manager. You should never have to do
|
175
|
+
# this as {Module Modules} should create FunctionPassManagers for you
|
176
|
+
# whenever they are requested.
|
177
|
+
#
|
178
|
+
# @see Module#function_pass_manager
|
179
|
+
#
|
180
|
+
# @param [Module] mod Module this pass manager belongs to.
|
181
|
+
def initialize(mod)
|
182
|
+
# LLVM Initialization
|
183
|
+
@ptr = Bindings.create_function_pass_manager_for_module(mod)
|
184
|
+
|
185
|
+
# Set the target data if the module is associated with a execution engine.
|
186
|
+
self.target_data = mod.engine.target_data if mod.engine
|
187
|
+
|
188
|
+
Bindings.initialize_function_pass_manager(@ptr)
|
189
|
+
|
190
|
+
# RLTK Initialization
|
191
|
+
@enabled = Array.new
|
192
|
+
end
|
193
|
+
|
194
|
+
# Run the enabled passes on the given function inside the execution
|
195
|
+
# engine's module.
|
196
|
+
#
|
197
|
+
# @param [Function] fun Function to optimize.
|
198
|
+
#
|
199
|
+
# @return [void]
|
200
|
+
def run(fun)
|
201
|
+
Bindings.run_function_pass_manager(@ptr, fun).to_bool
|
202
|
+
end
|
203
|
+
|
204
|
+
protected
|
205
|
+
# Called by {#dispose} to finalize any operations of the function
|
206
|
+
# pass manager.
|
207
|
+
#
|
208
|
+
# @return [void]
|
209
|
+
def finalize
|
210
|
+
Bindings.finalize_function_pass_manager(@ptr).to_bool
|
211
|
+
end
|
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
|
252
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/03/15
|
4
|
+
# Description: This file defines the Support module.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/cg/bindings'
|
12
|
+
|
13
|
+
#######################
|
14
|
+
# Classes and Modules #
|
15
|
+
#######################
|
16
|
+
|
17
|
+
module RLTK::CG
|
18
|
+
|
19
|
+
# Support functionality for LLVM code generation.
|
20
|
+
module Support
|
21
|
+
# Load a shared library into memory and make its exported symbols
|
22
|
+
# available to execution engines.
|
23
|
+
#
|
24
|
+
# @param [String] lib Path to the shared library to load
|
25
|
+
def self.load_library(lib)
|
26
|
+
Bindings.load_library_permanently(lib).to_bool
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/06/13
|
4
|
+
# Description: This file defines the Target class.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/cg/bindings'
|
12
|
+
require 'rltk/cg/triple'
|
13
|
+
|
14
|
+
#######################
|
15
|
+
# Classes and Modules #
|
16
|
+
#######################
|
17
|
+
|
18
|
+
module RLTK::CG
|
19
|
+
|
20
|
+
# Class binding for the LLVM Triple class.
|
21
|
+
class Target
|
22
|
+
include BindingClass
|
23
|
+
|
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
|
32
|
+
|
33
|
+
# @return [Target] Target object for the host architecture.
|
34
|
+
def self.host
|
35
|
+
@host ||= self.new(Triple.host)
|
36
|
+
end
|
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
|
+
|
47
|
+
# Create an object representing a particular code generation target.
|
48
|
+
# You can create a target either from a string or a Triple.
|
49
|
+
#
|
50
|
+
# @param [Triple, String] overloaded Object describing the target.
|
51
|
+
def initialize(overloaded)
|
52
|
+
@ptr, @triple =
|
53
|
+
case overloaded
|
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]
|
78
|
+
end
|
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
|
105
|
+
end
|
106
|
+
|
107
|
+
# This class represents data about a specific architecture. Currently it
|
108
|
+
# is for internal use only and should not be instantiated by users.
|
109
|
+
class TargetData
|
110
|
+
include BindingClass
|
111
|
+
|
112
|
+
# @param [FFI::Pointer] ptr
|
113
|
+
def initialize(ptr)
|
114
|
+
@ptr = ptr
|
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
|
126
|
+
end
|
127
|
+
|
128
|
+
# This class represents a specific architecture that wil be targeted by
|
129
|
+
# LLVM's compilation process.
|
130
|
+
class TargetMachine
|
131
|
+
include BindingClass
|
132
|
+
|
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 }
|
135
|
+
|
136
|
+
# @return [TargetMachine] TargetMachine representation of the host machine.
|
137
|
+
def self.host
|
138
|
+
@host ||= self.new(Target.host)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Create a new object describing a target machine.
|
142
|
+
#
|
143
|
+
# @see Bindings._enum_reloc_model_
|
144
|
+
# @see Bindings._enum_code_model_
|
145
|
+
#
|
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)
|
153
|
+
# Convert the features parameter if necessary.
|
154
|
+
features = TargetMachine.build_feature_string(features) if features.is_a?(Array)
|
155
|
+
|
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
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/06/13
|
4
|
+
# Description: This file defines the Triple class.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/cg/bindings'
|
12
|
+
|
13
|
+
#######################
|
14
|
+
# Classes and Modules #
|
15
|
+
#######################
|
16
|
+
|
17
|
+
module RLTK::CG
|
18
|
+
|
19
|
+
# Class binding for the LLVM Triple class.
|
20
|
+
class Triple
|
21
|
+
include BindingClass
|
22
|
+
|
23
|
+
#################
|
24
|
+
# Class Methods #
|
25
|
+
#################
|
26
|
+
|
27
|
+
# @return [Triple] Object representing the host architecture, vendor, OS, and environment.
|
28
|
+
def self.host
|
29
|
+
@host ||= Triple.new(host_string)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [String] String representation of the host architecture, vendor, OS, and environment.
|
33
|
+
def self.host_string
|
34
|
+
@host_string ||= Bindings.get_default_target_triple
|
35
|
+
end
|
36
|
+
|
37
|
+
####################
|
38
|
+
# Instance Methods #
|
39
|
+
####################
|
40
|
+
|
41
|
+
# Create a new triple describing the host architecture, vendor, OS,
|
42
|
+
# and (optionally) environment.
|
43
|
+
#
|
44
|
+
# @param [FFI::Pointer, String] overloaded
|
45
|
+
def initialize(overloaded)
|
46
|
+
@ptr, @str =
|
47
|
+
case overloaded
|
48
|
+
when FFI::Pointer then [overloaded, nil]
|
49
|
+
when String then [Bindings.triple_create(overloaded), overloaded]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [String] String representation of this triple.
|
54
|
+
def to_s
|
55
|
+
@str ||= Bindings.get_triple_string(@ptr)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|