start on call implementation, getting separation issues

This commit is contained in:
Torsten Ruger 2014-08-23 23:37:33 +03:00
parent 594784c729
commit ad6be2676c
5 changed files with 31 additions and 12 deletions

View File

@ -31,6 +31,7 @@ module Boot
def run_passes def run_passes
@passes.each do |pass| @passes.each do |pass|
puts "Runnning pass #{pass}"
all = main.blocks all = main.blocks
@classes.each_value do |c| @classes.each_value do |c|
c.method_definitions.each {|f| all += f.blocks } c.method_definitions.each {|f| all += f.blocks }
@ -55,12 +56,6 @@ module Boot
raise "No such pass to add after: #{after}" unless index raise "No such pass to add after: #{after}" unless index
@passes.insert(index , pass) @passes.insert(index , pass)
end end
def add_pass_after( pass , after)
index = @passes.index(after)
raise "No such pass to add after: #{after}" unless index
@passes.insert(index , pass)
end
# boot the classes, ie create a minimal set of classes with a minimal set of functions # boot the classes, ie create a minimal set of classes with a minimal set of functions
# minimal means only that which can not be coded in ruby # minimal means only that which can not be coded in ruby
# MethodDefinitions are grabbed from respective modules by sending the method name. This should return the # MethodDefinitions are grabbed from respective modules by sending the method name. This should return the

View File

@ -0,0 +1,22 @@
module Register
# This implements call logic, which is simply like a c call (not send, that involves lookup and all sorts)
#
# The only target for a call is a MethodDefinition, so we just need to get the address for the code
# and call it.
#
# The only slight snag is that we would need to assemble before getting the address, but to assemble
# we'd have to have finished compiling. So we need a reference.
class CallImplementation
def run block
block.codes.dup.each do |code|
next unless code.is_a? Virtual::FunctionCall
to = RegisterReference.new(:r0)
tmp = RegisterReference.new(:r5)
move = RegisterMachine.instance.ldr( to , tmp , code.to.index )
block.replace(code , [move] )
end
end
end
Virtual::Object.space.add_pass_after CallImplementation , SetImplementation
end

View File

@ -1,7 +1,8 @@
module Register module Register
# This implements the send logic # This implements instance variable get (not the opposite of Set, such a thing does not exists, their slots)
# Send is so complicated that we actually code it in ruby and stick it in
# That off course opens up an endless loop possibility that we stop by reducing to Class and Module methods # Ivar get needs to acces the layout, find the index of the name, and shuffle the data to return register
# In short it's so complicated we implement it in ruby and stick the implementation here
class GetImplementation class GetImplementation
def run block def run block
block.codes.dup.each do |code| block.codes.dup.each do |code|

View File

@ -148,4 +148,5 @@ require_relative "instruction"
require_relative "register_reference" require_relative "register_reference"
require_relative "get_implementation" require_relative "get_implementation"
require_relative "set_implementation" require_relative "set_implementation"
require_relative "call_implementation"
require "arm/arm_machine" require "arm/arm_machine"

View File

@ -1,7 +1,7 @@
module Register module Register
# This implements the send logic # This implements setting of the various slot variables the vm defines.
# Send is so complicated that we actually code it in ruby and stick it in # Basic mem moves, but have to shuffle the type nibbles
# That off course opens up an endless loop possibility that we stop by reducing to Class and Module methods
class SetImplementation class SetImplementation
def run block def run block
block.codes.dup.each do |code| block.codes.dup.each do |code|