5ddc96718b
simplification, new model is such that the upon start the method: has a message in r0, works on it and returns to the return address. Everything else is up to the caller
35 lines
1.3 KiB
Ruby
35 lines
1.3 KiB
Ruby
module Register
|
|
# name says it all really
|
|
# only arg is the method object we want to call
|
|
# assembly takes care of the rest (ie getting the address)
|
|
|
|
class FunctionCall < Instruction
|
|
def initialize source , method
|
|
super(source)
|
|
@method = method
|
|
end
|
|
attr_reader :method
|
|
|
|
def to_s
|
|
"FunctionCall: #{method.name}"
|
|
end
|
|
end
|
|
|
|
def self.issue_call compiler , callee
|
|
source = "_issue_call(#{callee.name})"
|
|
return_label = Label.new("_return_label" , "#{compiler.clazz.name}.#{compiler.method.name}" )
|
|
ret_tmp = compiler.use_reg(:Label)
|
|
compiler.add_code Register::LoadConstant.new(source, return_label , ret_tmp)
|
|
compiler.add_code Register.set_slot(source, ret_tmp , :new_message , :return_address)
|
|
# move the current new_message to message
|
|
compiler.add_code RegisterTransfer.new(source, Register.new_message_reg , Register.message_reg )
|
|
# do the register call
|
|
compiler.add_code FunctionCall.new( source , callee )
|
|
compiler.add_code return_label
|
|
# move the current message to new_message
|
|
compiler.add_code Register::RegisterTransfer.new(source, Register.message_reg , Register.new_message_reg )
|
|
# and restore the message from saved value in new_message
|
|
compiler.add_code Register.get_slot(source , :new_message , :caller , :message )
|
|
end
|
|
end
|