getting a _start and _exit, just missing the actual code
This commit is contained in:
@ -34,7 +34,11 @@ module Vm
|
||||
end
|
||||
|
||||
def add_code(kode)
|
||||
@codes << kode
|
||||
if( kode.is_a? Array )
|
||||
kode.each { |code| @codes << code }
|
||||
else
|
||||
@codes << kode
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -13,7 +13,7 @@ module Vm
|
||||
|
||||
# set the position to zero, will have to reset later
|
||||
def initialize
|
||||
@address = 0
|
||||
@position = 0
|
||||
end
|
||||
|
||||
# the position in the stream. Think of it as an address if you want. The difference is small.
|
||||
@ -21,19 +21,19 @@ module Vm
|
||||
# in other words, during assembly the position _must_ be resolved into a pc relative address
|
||||
# and not used as is
|
||||
def position
|
||||
throw "Not set" unless @address
|
||||
@address
|
||||
throw "Not set" unless @position
|
||||
@position
|
||||
end
|
||||
|
||||
# The containing class (assembler/function) call this to tell the instruction/data where it is in the
|
||||
# stream. During assembly the position is then used to calculate pc relative addresses.
|
||||
def link_at address , context
|
||||
@address = address
|
||||
@position = address
|
||||
end
|
||||
|
||||
# length for this code in bytes
|
||||
def length
|
||||
raise "Not implemented #{self}"
|
||||
raise "Not implemented #{inspect}"
|
||||
end
|
||||
|
||||
# so currently the interface passes the io (usually string_io) in for the code to assemble itself.
|
||||
|
@ -24,16 +24,28 @@ module Vm
|
||||
@args.length
|
||||
end
|
||||
|
||||
def link_at address , context
|
||||
# function = context.program.get_function(name)
|
||||
# unless function
|
||||
# function = Vm::Kernel.send(name)
|
||||
# context.program.get_or_create_function( name , function , arity )
|
||||
# end
|
||||
|
||||
@entry.link_at address , context
|
||||
address += @entry.length
|
||||
super(address , context)
|
||||
address += @entry.length
|
||||
@exit.link_at(address,context)
|
||||
end
|
||||
|
||||
def length
|
||||
@entry.length + @exit.length + super
|
||||
end
|
||||
|
||||
def compiled context
|
||||
function = context.program.get_function(name)
|
||||
unless function
|
||||
function = Vm::Kernel.send(name)
|
||||
context.program.get_or_create_function( name , function , arity )
|
||||
end
|
||||
def assemble io
|
||||
@entry.assemble io
|
||||
super(io)
|
||||
@exit.assemble(io)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -5,7 +5,7 @@ module Vm
|
||||
Machine.instance.main_entry
|
||||
end
|
||||
def self.exit
|
||||
# Machine.exit swi 0
|
||||
# Machine.exit mov r7 , 0 + swi 0
|
||||
Machine.instance.main_exit
|
||||
end
|
||||
def self.puts string
|
||||
|
30
lib/vm/string_literal.rb
Normal file
30
lib/vm/string_literal.rb
Normal file
@ -0,0 +1,30 @@
|
||||
require "vm/code"
|
||||
|
||||
module Vm
|
||||
# The name really says it all.
|
||||
# The only interesting thing is storage.
|
||||
# Currently string are stored "inline" , ie in the code segment.
|
||||
# Mainly because that works an i aint no elf expert.
|
||||
|
||||
class StringLiteral < Vm::Code
|
||||
|
||||
# currently aligned to 4 (ie padded with 0) and off course 0 at the end
|
||||
def initialize(str)
|
||||
length = str.length
|
||||
# rounding up to the next 4 (always adding one for zero pad)
|
||||
pad = ((length / 4 ) + 1 ) * 4 - length
|
||||
raise "#{pad} #{self}" unless pad >= 1
|
||||
@string = str + "\x00" * pad
|
||||
end
|
||||
|
||||
# the strings length plus padding
|
||||
def length
|
||||
@string.length
|
||||
end
|
||||
|
||||
# just writing the string
|
||||
def assemble(io)
|
||||
io << @string
|
||||
end
|
||||
end
|
||||
end
|
@ -77,3 +77,4 @@ module Vm
|
||||
end
|
||||
|
||||
end
|
||||
require_relative "string_literal"
|
Reference in New Issue
Block a user