rltk 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -32,6 +32,52 @@ module RLTK::CG::Bindings
32
32
  # @scope class
33
33
  attach_function :target_version, :LLVMTargetVersion, [], :string
34
34
 
35
+ # (Not documented)
36
+ #
37
+ # @method initialize_all_asm_parsers()
38
+ # @return [nil]
39
+ # @scope class
40
+ attach_function :initialize_all_asm_parsers, :LLVMInitializeAllAsmParsers, [], :void
41
+
42
+ # (Not documented)
43
+ #
44
+ # @method initialize_all_asm_printers()
45
+ # @return [nil]
46
+ # @scope class
47
+ attach_function :initialize_all_asm_printers, :LLVMInitializeAllAsmPrinters, [], :void
48
+
49
+ # (Not documented)
50
+ #
51
+ # @method initialize_native_target_asm_parser()
52
+ # @return [nil]
53
+ # @scope class
54
+ attach_function :initialize_native_target_asm_parser, :LLVMInitializeNativeTargetAsmParser, [], :void
55
+
56
+ # (Not documented)
57
+ #
58
+ # @method initialize_native_target_asm_printer()
59
+ # @return [nil]
60
+ # @scope class
61
+ attach_function :initialize_native_target_asm_printer, :LLVMInitializeNativeTargetAsmPrinter, [], :void
62
+
63
+ # (Not documented)
64
+ #
65
+ # @method load_module_from_ir_file(file_name, context)
66
+ # @param [String] file_name
67
+ # @param [FFI::Pointer(ContextRef)] context
68
+ # @return [FFI::Pointer(ModuleRef)]
69
+ # @scope class
70
+ attach_function :load_module_from_ir_file, :LLVMLoadModuleFromIRFile, [:string, :pointer], :pointer
71
+
72
+ # (Not documented)
73
+ #
74
+ # @method print_module(mod, fd)
75
+ # @param [FFI::Pointer(ModuleRef)] mod
76
+ # @param [Integer] fd
77
+ # @return [nil]
78
+ # @scope class
79
+ attach_function :print_module, :LLVMPrintModule, [:pointer, :int], :void
80
+
35
81
  # (Not documented)
36
82
  #
37
83
  # @method load_library_permanently(filename)
@@ -40,4 +86,202 @@ module RLTK::CG::Bindings
40
86
  # @scope class
41
87
  attach_function :load_library_permanently, :LLVMLoadLibraryPermanently, [:string], :int
42
88
 
89
+ # (Not documented)
90
+ #
91
+ # @method print_value(val, fd)
92
+ # @param [FFI::Pointer(ValueRef)] val
93
+ # @param [Integer] fd
94
+ # @return [nil]
95
+ # @scope class
96
+ attach_function :print_value, :LLVMPrintValue, [:pointer, :int], :void
97
+
98
+ # (Not documented)
99
+ #
100
+ # <em>This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:code_model).</em>
101
+ #
102
+ # === Options:
103
+ # :default_cmodel ::
104
+ #
105
+ # :kernel ::
106
+ #
107
+ # :small ::
108
+ #
109
+ # :medium ::
110
+ #
111
+ # :large ::
112
+ #
113
+ #
114
+ # @method _enum_code_model_
115
+ # @return [Symbol]
116
+ # @scope class
117
+ enum :code_model, [
118
+ :default_cmodel, 0,
119
+ :kernel, 1,
120
+ :small, 2,
121
+ :medium, 3,
122
+ :large, 4
123
+ ]
124
+
125
+ # (Not documented)
126
+ #
127
+ # <em>This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:reloc_model).</em>
128
+ #
129
+ # === Options:
130
+ # :default_rmodel ::
131
+ #
132
+ # :static ::
133
+ #
134
+ # :pic ::
135
+ #
136
+ # :dynamic_no_pic ::
137
+ #
138
+ #
139
+ # @method _enum_reloc_model_
140
+ # @return [Symbol]
141
+ # @scope class
142
+ enum :reloc_model, [
143
+ :default_rmodel, 0,
144
+ :static, 1,
145
+ :pic, 2,
146
+ :dynamic_no_pic, 3
147
+ ]
148
+
149
+ # (Not documented)
150
+ #
151
+ # <em>This entry is only for documentation and no real method. The FFI::Enum can be accessed via #enum_type(:compile_type).</em>
152
+ #
153
+ # === Options:
154
+ # :asm ::
155
+ #
156
+ # :object ::
157
+ #
158
+ #
159
+ # @method _enum_compile_type_
160
+ # @return [Symbol]
161
+ # @scope class
162
+ enum :compile_type, [
163
+ :asm, 0,
164
+ :object, 1
165
+ ]
166
+
167
+ # (Not documented)
168
+ class OpaqueTarget < FFI::Struct
169
+ layout :dummy, :char
170
+ end
171
+
172
+ # (Not documented)
173
+ class OpaqueTargetMachine < FFI::Struct
174
+ layout :dummy, :char
175
+ end
176
+
177
+ # (Not documented)
178
+ class OpaqueTriple < FFI::Struct
179
+ layout :dummy, :char
180
+ end
181
+
182
+ # // Utility
183
+ #
184
+ # @method build_features_string(attrs, num_attrs)
185
+ # @param [FFI::Pointer(**CharS)] attrs
186
+ # @param [Integer] num_attrs
187
+ # @return [String]
188
+ # @scope class
189
+ attach_function :build_features_string, :LLVMBuildFeaturesString, [:pointer, :int], :string
190
+
191
+ # (Not documented)
192
+ #
193
+ # @method compile_module_to_file(mod, machine, pm, file_name, ctype, opt_level, no_verify)
194
+ # @param [FFI::Pointer(ModuleRef)] mod
195
+ # @param [OpaqueTargetMachine] machine
196
+ # @param [FFI::Pointer(PassManagerRef)] pm
197
+ # @param [String] file_name
198
+ # @param [Symbol from _enum_compile_type_] ctype
199
+ # @param [Integer] opt_level
200
+ # @param [Integer] no_verify
201
+ # @return [nil]
202
+ # @scope class
203
+ attach_function :compile_module_to_file, :LLVMCompileModuleToFile, [:pointer, OpaqueTargetMachine, :pointer, :string, :compile_type, :uint, :uint], :void
204
+
205
+ # (Not documented)
206
+ #
207
+ # @method ecb_initialize_all_targets()
208
+ # @return [nil]
209
+ # @scope class
210
+ attach_function :ecb_initialize_all_targets, :LLVMECBInitializeAllTargets, [], :void
211
+
212
+ # (Not documented)
213
+ #
214
+ # @method ecb_initialize_native_target()
215
+ # @return [nil]
216
+ # @scope class
217
+ attach_function :ecb_initialize_native_target, :LLVMECBInitializeNativeTarget, [], :void
218
+
219
+ # // Target
220
+ #
221
+ # @method get_target_from_name(name)
222
+ # @param [String] name
223
+ # @return [OpaqueTarget]
224
+ # @scope class
225
+ attach_function :get_target_from_name, :LLVMGetTargetFromName, [:string], OpaqueTarget
226
+
227
+ # (Not documented)
228
+ #
229
+ # @method get_target_from_triple(triple)
230
+ # @param [OpaqueTriple] triple
231
+ # @return [OpaqueTarget]
232
+ # @scope class
233
+ attach_function :get_target_from_triple, :LLVMGetTargetFromTriple, [OpaqueTriple], OpaqueTarget
234
+
235
+ # // Target Machine
236
+ #
237
+ # @method create_target_machine(target, triple, mcpu, features, rmodel, cmodel)
238
+ # @param [OpaqueTarget] target
239
+ # @param [String] triple
240
+ # @param [String] mcpu
241
+ # @param [String] features
242
+ # @param [Symbol from _enum_reloc_model_] rmodel
243
+ # @param [Symbol from _enum_code_model_] cmodel
244
+ # @return [OpaqueTargetMachine]
245
+ # @scope class
246
+ attach_function :create_target_machine, :LLVMCreateTargetMachine, [OpaqueTarget, :string, :string, :string, :reloc_model, :code_model], OpaqueTargetMachine
247
+
248
+ # (Not documented)
249
+ #
250
+ # @method set_target_machine_asm_verbosity(machine, boolean)
251
+ # @param [OpaqueTargetMachine] machine
252
+ # @param [Integer] boolean
253
+ # @return [nil]
254
+ # @scope class
255
+ attach_function :set_target_machine_asm_verbosity, :LLVMSetTargetMachineASMVerbosity, [OpaqueTargetMachine, :int], :void
256
+
257
+ # // Triple
258
+ #
259
+ # @method get_host_triple()
260
+ # @return [OpaqueTriple]
261
+ # @scope class
262
+ attach_function :get_host_triple, :LLVMGetHostTriple, [], OpaqueTriple
263
+
264
+ # (Not documented)
265
+ #
266
+ # @method get_host_triple_string()
267
+ # @return [String]
268
+ # @scope class
269
+ attach_function :get_host_triple_string, :LLVMGetHostTripleString, [], :string
270
+
271
+ # (Not documented)
272
+ #
273
+ # @method get_triple_string(triple)
274
+ # @param [OpaqueTriple] triple
275
+ # @return [String]
276
+ # @scope class
277
+ attach_function :get_triple_string, :LLVMGetTripleString, [OpaqueTriple], :string
278
+
279
+ # (Not documented)
280
+ #
281
+ # @method triple_create(string)
282
+ # @param [String] string
283
+ # @return [OpaqueTriple]
284
+ # @scope class
285
+ attach_function :triple_create, :LLVMTripleCreate, [:string], OpaqueTriple
286
+
43
287
  end
data/lib/rltk/cg/llvm.rb CHANGED
@@ -19,27 +19,85 @@ module RLTK::CG # :nodoc:
19
19
 
20
20
  # This module contains global operations on the LLVM compiler infrastructure.
21
21
  module LLVM
22
- # Initialize LLVM to generate code for a given architecture.
22
+ # Initialize LLVM to generate code for a given architecture. You may
23
+ # also specify :all to initialize all targets or :native to
24
+ # initialize the host target.
23
25
  #
24
26
  # @see Bindings::ARCHS
25
27
  #
26
28
  # @param [Symbol] arch Architecture to initialize LLVM for.
27
29
  #
28
- # @raise [RuntimeError] An error is raised if an unsupported architecture is specified.
30
+ # @raise [ArgumentError] An error is raised if an unsupported architecture is specified.
29
31
  #
30
- # @return [true]
32
+ # @return [void]
31
33
  def self.init(arch)
32
- if Bindings::ARCHS.include?(arch) or Bindings::ARCHS.map { |sym| sym.to_s.downcase.to_sym }.include?(arch)
34
+ if arch == :all
35
+ Bindings.ecb_initialize_all_targets
36
+
37
+ elsif arch == :native
38
+ Bindings.ecb_initialize_native_target
39
+
40
+ elsif Bindings::ARCHS.include?(arch) or Bindings::ARCHS.map { |sym| sym.to_s.downcase.to_sym }.include?(arch)
33
41
  arch = Bindings.get_bname(arch)
34
42
 
35
43
  Bindings.send("initialize_#{arch}_target".to_sym)
36
44
  Bindings.send("initialize_#{arch}_target_info".to_sym)
37
45
  Bindings.send("initialize_#{arch}_target_mc".to_sym)
38
46
 
39
- true
47
+ else
48
+ raise ArgumentError, "Unsupported architecture specified: #{arch}."
49
+ end
50
+ end
51
+
52
+ # Initialize a given ASM parser inside LLVM. You may also specify
53
+ # :all to initialize all ASM parsers.
54
+ #
55
+ # @see Bindings::ASM_PARSERS
56
+ #
57
+ # @param [Symbol] asm Assembly language type to initialize parser for.
58
+ #
59
+ # @raise [ArgumentError] An error is raised if an unsupported assembler parser is specified.
60
+ #
61
+ # @return [void]
62
+ def self.init_asm_parser(asm)
63
+ if asm == :all
64
+ Bindings.initialize_all_asm_parsers
65
+
66
+ elsif Bindings::ASM_PARSERS.include?(asm) or Bindings::ASM_PARSERS.map { |sym| sym.to_s.downcase.to_sym }.include?(asm)
67
+ asm = Bindings.get_bname(asm)
68
+
69
+ Bindings.send("initialize_#{asm}_asm_parser".to_sym)
70
+
71
+ else
72
+ raise ArgumentError, "Unsupported assembler type specified: #{asm}"
73
+ end
74
+ end
75
+
76
+ # Initialize a given ASM printer inside LLVM. You may also specify
77
+ # :all to initialize all ASM printers or :native to initialize the
78
+ # printer for the host machine's assembly language.
79
+ #
80
+ # @see Bindings::ASM_PRINTERS
81
+ #
82
+ # @param [Symbol] asm Assembly language type to initialize printer for.
83
+ #
84
+ # @raise [ArgumentError] An error is raised if an unsupported assembler printer is specified.
85
+ #
86
+ # @return [void]
87
+ def self.init_asm_printer(asm)
88
+ if asm == :all
89
+ Bindings.initialize_all_asm_printers
90
+
91
+ elsif asm == :native
92
+ Bindings.initialize_native_asm_printer
93
+
94
+ elsif Bindings::ASM_PRINTERS.include?(asm) or Bindings::ASM_PRINTERS.map { |sym| sym.to_s.downcase.to_sym }.include?(asm)
95
+ asm = Bindings.get_bname(asm)
96
+
97
+ Bindings.send("initialize_#{asm}_asm_printer".to_sym)
40
98
 
41
99
  else
42
- raise "Unsupported architecture specified: #{arch}"
100
+ raise ArgumentError, "Unsupported assembler type specified: #{asm}"
43
101
  end
44
102
  end
45
103
 
@@ -22,11 +22,15 @@ module RLTK::CG # :nodoc:
22
22
  class Module
23
23
  include BindingClass
24
24
 
25
+ # @!attribute [rw] engine
26
+ # @return [ExecutionEngine, nil] Execution engine associated with this module.
27
+ attr_accessor :engine
28
+
25
29
  # Load a module from LLVM bitcode.
26
30
  #
27
31
  # @see MemoryBuffer#initialize
28
32
  #
29
- # @param [MemoryBuffer, FFI::Pointer, String, nil] overloaded Where to read the bytecode from.
33
+ # @param [MemoryBuffer, FFI::Pointer, String, nil] overloaded Where to read the bitecode from.
30
34
  #
31
35
  # @return [Module]
32
36
  def self.read_bitcode(overloaded)
@@ -44,6 +48,15 @@ module RLTK::CG # :nodoc:
44
48
  end
45
49
  end
46
50
 
51
+ # Load a Module form an LLVM IR file.
52
+ #
53
+ # @param [String] file_name Name of file containing LLVM IR module.
54
+ #
55
+ # @return [Module]
56
+ def self.read_ir_file(file_name, context = Context.global)
57
+ self.new(Bindings.load_module_from_ir_file(file_name, context))
58
+ end
59
+
47
60
  # Create a new LLVM module.
48
61
  #
49
62
  # @param [FFI::Pointer, String] overloaded Pointer to existing module or name of new module.
@@ -66,6 +79,19 @@ module RLTK::CG # :nodoc:
66
79
  self.instance_exec(&block) if block
67
80
  end
68
81
 
82
+ # Compile this module to an assembly or object file.
83
+ #
84
+ # @param [String] file_name Name of output file.
85
+ # @param [:asm, :object] mode Generate assembly or object file?
86
+ # @param [TargetMachine] machine Machine type to target.
87
+ # @param [0, 1, 2, 3] opt_level Optimization level to use during compilation.
88
+ # @param [Boolean] verify Verify the module before compilation or not.
89
+ #
90
+ # @return [void]
91
+ def compile(file_name, mode = :object, machine = TargetMachine.host, opt_level = 2, verify = true)
92
+ Bindings.compile_module_to_file(@ptr, machine, self.pm, file_name, mode, opt_level, (!verify).to_i)
93
+ end
94
+
69
95
  # @return [Context] Context in which this module exists.
70
96
  def context
71
97
  Context.new(Bindings.get_module_context(@ptr))
@@ -82,13 +108,49 @@ module RLTK::CG # :nodoc:
82
108
  end
83
109
  end
84
110
 
85
- # Print the IR of this module to standard out.
111
+ # Print the LLVM IR representation of this value to standard error.
112
+ # This function is the debugging version of the more general purpose
113
+ # {#print} method.
114
+ #
115
+ # @see #print
86
116
  #
87
117
  # @return [void]
88
118
  def dump
89
119
  Bindings.dump_module(@ptr)
90
120
  end
91
121
 
122
+ # @return [FunctionPassManager] Function pass manager for this module.
123
+ def function_pass_manager
124
+ @function_pass_manager ||= FunctionPassManager.new(self)
125
+ end
126
+ alias :fpm :function_pass_manager
127
+
128
+ # @return [PassManager] Pass manager for this module.
129
+ def pass_manager
130
+ @pass_manager ||= PassManager.new(self)
131
+ end
132
+ alias :pm :pass_manager
133
+
134
+ # Print the LLVM IR representation of this module to a file. The
135
+ # file may be specified via a file name (which will be created or
136
+ # truncated) or an object that responds to #fileno.
137
+ #
138
+ # @LLVMECB
139
+ #
140
+ # @param [String, #fileno] io File name or object with a file descriptor to print to.
141
+ #
142
+ # @return [void]
143
+ def print(io = $stdout)
144
+ case io
145
+ when String
146
+ File.open(io, 'w') do |f|
147
+ Bindings.print_module(@ptr, f.fileno)
148
+ end
149
+ else
150
+ Bindings.print_module(@ptr, io.fileno)
151
+ end
152
+ end
153
+
92
154
  # @return [FunctionCollection] Proxy object for inspecting this module's functions.
93
155
  def functions
94
156
  @functions ||= FunctionCollection.new(self)
@@ -100,6 +162,22 @@ module RLTK::CG # :nodoc:
100
162
  @globals ||= GlobalCollection.new(self)
101
163
  end
102
164
 
165
+ # Set the module's target triple.
166
+ #
167
+ # @param [String] triple Triple value to set.
168
+ #
169
+ # @return [void]
170
+ def target=(triple)
171
+ Bindings.set_target(@ptr, triple)
172
+ end
173
+
174
+ # Get the module's target triple.
175
+ #
176
+ # @return [String]
177
+ def target
178
+ Bindings.get_target(@ptr)
179
+ end
180
+
103
181
  # Write the module as LLVM bitcode to a file.
104
182
  #
105
183
  # @param [#path, #fileno, Integer, String] overloaded Where to write the bitcode.
@@ -68,18 +68,20 @@ module RLTK::CG # :nodoc:
68
68
  :Verifier => :verifier
69
69
  }
70
70
 
71
- # Creat a new pass manager. You should never have to do this as
72
- # {ExecutionEngine ExecutionEngines} creates a PassManager whenever
73
- # one is requested.
71
+ # Create a new pass manager. You should never have to do this as
72
+ # {Module Modules} should create PassManagers for you whenever they
73
+ # are requested.
74
74
  #
75
- # @param [ExecutionEngine] engine ExecutionEngine this pass manager belongs to.
76
- # @param [Module] mod Module this pass manager belongs to.
77
- def initialize(engine, mod)
75
+ # @see Module#pass_manager
76
+ #
77
+ # @param [Module] mod Module this pass manager belongs to.
78
+ def initialize(mod)
78
79
  # LLVM Initialization
79
80
  @ptr = Bindings.create_pass_manager
80
81
  @mod = mod
81
82
 
82
- Bindings.add_target_data(Bindings.get_execution_engine_target_data(engine), @ptr)
83
+ # Set the target data if the module is associated with a execution engine.
84
+ self.target_data = mod.engine.target_data if mod.engine
83
85
 
84
86
  # RLTK Initialization
85
87
  @enabled = Array.new
@@ -152,6 +154,15 @@ module RLTK::CG # :nodoc:
152
154
  Bindings.run_pass_manager(@ptr, @mod).to_bool
153
155
  end
154
156
 
157
+ # Set the target data for this pass manager.
158
+ #
159
+ # @param [TargetData] data
160
+ #
161
+ # @return [void]
162
+ def target_data=(data)
163
+ Bindings.add_target_data(check_type(data, TargetData, 'data'), @ptr)
164
+ end
165
+
155
166
  protected
156
167
  # Empty method used by {FunctionPassManager} to clean up resources.
157
168
  def finalize
@@ -161,19 +172,21 @@ module RLTK::CG # :nodoc:
161
172
  # A FunctionPassManager is responsible for scheduling and running optimization
162
173
  # passes on individual functions inside the context of a module.
163
174
  class FunctionPassManager < PassManager
164
- # Creat a new function pass manager. You should never have to do
165
- # this as {ExecutionEngine ExecutionEngines} creates a
166
- # FunctionPassManager whenever one is requested.
175
+ # Create a new function pass manager. You should never have to do
176
+ # this as {Module Modules} should create FunctionPassManagers for you
177
+ # whenever they are requested.
178
+ #
179
+ # @see Module#function_pass_manager
167
180
  #
168
- # @param [ExecutionEngine] engine ExecutionEngine this pass manager belongs to.
169
- # @param [Module] mod Module this pass manager belongs to.
170
- def initialize(engine, mod)
181
+ # @param [Module] mod Module this pass manager belongs to.
182
+ def initialize(mod)
171
183
  # LLVM Initialization
172
184
  @ptr = Bindings.create_function_pass_manager_for_module(mod)
173
185
 
174
- Bindings.add_target_data(Bindings.get_execution_engine_target_data(engine), @ptr)
186
+ # Set the target data if the module is associated with a execution engine.
187
+ self.target_data = mod.engine.target_data if mod.engine
175
188
 
176
- Bindings.initialize_function_pass_manager(@ptr).to_bool
189
+ Bindings.initialize_function_pass_manager(@ptr)
177
190
 
178
191
  # RLTK Initialization
179
192
  @enabled = Array.new
@@ -21,6 +21,8 @@ module RLTK::CG # :nodoc:
21
21
  # Load a shared library into memory and make its exported symbols
22
22
  # available to execution engines.
23
23
  #
24
+ # @LLVMECB
25
+ #
24
26
  # @param [String] lib Path to the shared library to load.
25
27
  def self.load_library(lib)
26
28
  Bindings.load_library_permanently(lib).to_bool
@@ -0,0 +1,100 @@
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 # :nodoc:
19
+
20
+ # Class binding for the LLVM Triple class.
21
+ class Target
22
+ include BindingClass
23
+
24
+ # @return [Triple] Triple object for this target.
25
+ attr_reader :triple
26
+
27
+ # @return [Target] Target object for the host architecture.
28
+ def self.host
29
+ @host ||= self.new(Triple.host)
30
+ end
31
+
32
+ # Create an object representing a particular code generation target.
33
+ # You can create a target either from a string or a Triple.
34
+ #
35
+ # @param [Triple, String] overloaded Object describing the target.
36
+ def initialize(overloaded)
37
+ @ptr, @triple =
38
+ case overloaded
39
+ when String then [Bindings.get_target_from_string(overloaded), Triple.new(overloaded)]
40
+ when Triple then [Bindings.get_target_from_triple(overloaded), overloaded]
41
+ end
42
+ end
43
+ end
44
+
45
+ # This class represents data about a specific architecture. Currently it
46
+ # is for internal use only and should not be instantiated by users.
47
+ class TargetData
48
+ include BindingClass
49
+
50
+ # @param [FFI::Pointer] ptr
51
+ def initialize(ptr)
52
+ @ptr = ptr
53
+ end
54
+ end
55
+
56
+ # This class represents a specific architecture that wil be targeted by
57
+ # LLVM's compilation process.
58
+ class TargetMachine
59
+ include BindingClass
60
+
61
+ # Convert an array of strings representing features of a target
62
+ # machine into a single string.
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
73
+
74
+ # @return [TargetMachine] TargetMachine representation of the host machine.
75
+ def self.host
76
+ @host ||= self.new(Target.host)
77
+ end
78
+
79
+ # Create a new object describing a target machine.
80
+ #
81
+ # @see Bindings._enum_reloc_model_
82
+ # @see Bindings._enum_code_model_
83
+ #
84
+ # @param [Target] target Target description.
85
+ # @param [String] mcpu Specific CPU type to target.
86
+ # @param [Array<String>, String] features Features present for this target machine.
87
+ # @param [Symbol] reloc_model Code relocation model.
88
+ # @param [Symbol] code_model Code generation model.
89
+ def initialize(target, mcpu = '', features = '', reloc_model = :default, code_model = :default)
90
+ # Just to make things easier on developers.
91
+ reloc_model = :default_rmodel if reloc_model == :default
92
+ code_model = :default_cmodel if code_model == :default
93
+
94
+ # Convert the features parameter if necessary.
95
+ features = TargetMachine.build_feature_string(features) if features.is_a?(Array)
96
+
97
+ @ptr = Bindings.create_target_machine(target, target.triple.to_s, mcpu, features, reloc_model, code_model)
98
+ end
99
+ end
100
+ end