Module: Tem::Builders::Assembler::CodeBuilderBase

Defined in:
lib/tem/builders/assembler.rb

Overview

Module injected into the assembler’s code builder class.

Instance Method Summary collapse

Instance Method Details

#done_assembling(proxy) ⇒ Object

Called by assemble after its associated block returns.

This method is responsible for the final assembly steps (i.e. linking) and returning a processed result. The method’s result is returned by assemble.



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/tem/builders/assembler.rb', line 299

def done_assembling(proxy)
  # Process link directives.
  abi = proxy.class.const_get :Abi
  @link_directives.each do |directive|
    if label = directive[:label]
      raise "Label #{label} undefined" unless address = @labels[label]
    else
      address = directive[:address]
    end
    if directive[:relative]
      address -= directive[:offset] + directive[:relative]
    end
    address_bytes = abi.send :"signed_to_#{directive[:type]}", address
    @bytes[directive[:offset], address_bytes.length] = *address_bytes
  end
  
  # Wrap all the built data into a nice package and return it.
  { :bytes => @bytes, :link_directives => @link_directives,
    :labels => @labels, :line_info => @line_info }
end

#emit_bytes(emit_atom_name, emit_data) ⇒ Object

Emits code or data bytes, with associated link directives.



276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/tem/builders/assembler.rb', line 276

def emit_bytes(emit_atom_name, emit_data)
  (emit_data[:link_directives] || []).each do |directive|
    directive[:offset] += @bytes.length
    @link_directives << directive
  end
  
  emit_data[:emit] ||= []
  if emit_data[:emit].length > 0
    @line_info << [@bytes.length, emit_atom_name, Kernel.caller(2)]  
  end    
  @bytes += emit_data[:emit] || []    
end

#emit_label(label_name) ⇒ Object

Emits labels, which are symbolic names for addresses.



290
291
292
293
# File 'lib/tem/builders/assembler.rb', line 290

def emit_label(label_name)
  raise "label #{label_name} already defined" if @labels[label_name]
  @labels[label_name] = @bytes.length
end

#start_assemblingObject

Called by assemble before its associated block receives control.

This method is responsible for setting up the state needed by the emit_ methods.



268
269
270
271
272
273
# File 'lib/tem/builders/assembler.rb', line 268

def start_assembling
  @bytes = []
  @link_directives = []
  @line_info = []
  @labels = {}
end