From da9dc30c20f7d89e098413cf9379082f7c8f5338 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Thu, 16 Aug 2018 10:43:41 +0300 Subject: [PATCH] move dynamic_call to builder no change of test, great also remove some duplicate code that was hanging around in method_compiler --- lib/mom/instruction/dynamic_call.rb | 21 ++++--- lib/risc/block_compiler.rb | 12 ---- lib/risc/callable_compiler.rb | 17 +++++- lib/risc/method_compiler.rb | 88 ----------------------------- 4 files changed, 27 insertions(+), 111 deletions(-) diff --git a/lib/mom/instruction/dynamic_call.rb b/lib/mom/instruction/dynamic_call.rb index e15131ad..0b5ddadf 100644 --- a/lib/mom/instruction/dynamic_call.rb +++ b/lib/mom/instruction/dynamic_call.rb @@ -31,16 +31,19 @@ module Mom # Instead we need a DynamicJump instruction that explicitly takes a register as # a target (not a label) def to_risc(compiler) - compiler.add_constant( @cache_entry ) - entry = compiler.use_reg( :CacheEntry ) + entry = @cache_entry + compiler.add_constant( entry ) return_label = Risc.label(self, "continue_#{object_id}") - save_return = SlotLoad.new([:message,:next_message,:return_address],[return_label],self) - moves = save_return.to_risc(compiler) - moves << Risc.slot_to_reg(self, Risc.message_reg , :next_message , Risc.message_reg) - moves << Risc.load_constant( self , @cache_entry , entry ) - moves << Risc.slot_to_reg( self , entry ,:cached_method , entry) - moves << Risc::DynamicJump.new(self, entry ) - moves << return_label + compiler.build("DynamicCall") do + return_address! << return_label + next_message! << message[:next_message] + next_message[:return_address] << return_address + message << message[:next_message] + cache_entry! << entry + cache_entry << cache_entry[:cached_method] + add_code Risc::DynamicJump.new("DynamicCall", cache_entry ) + add_code return_label + end end end diff --git a/lib/risc/block_compiler.rb b/lib/risc/block_compiler.rb index b480d15d..73eef675 100644 --- a/lib/risc/block_compiler.rb +++ b/lib/risc/block_compiler.rb @@ -48,18 +48,6 @@ module Risc slot_def << name end - # return the frame type, ie the blocks frame type - def frame_type - @callable.frame_type - end - # return the frame type, ie the blocks arguments type - def arg_type - @callable.arguments_type - end - # return the frame type, ie the blocks self_type - def receiver_type - @callable.self_type - end end end diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index a1ac0782..b7041ee4 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -100,6 +100,19 @@ module Risc return new_type end + # return the frame type, ie the blocks frame type + def frame_type + @callable.frame_type + end + # return the frame type, ie the blocks arguments type + def arg_type + @callable.arguments_type + end + # return the frame type, ie the blocks self_type + def receiver_type + @callable.self_type + end + def copy( reg , source ) copied = use_reg reg.type add_code Register.transfer( source , reg , copied ) @@ -121,8 +134,8 @@ module Risc end # Build with builder (see there), adding the created instructions - def build(&block) - builder.build(&block) + def build(source , &block) + code_builder(source).build(&block) end # return a new code builder that uses this compiler diff --git a/lib/risc/method_compiler.rb b/lib/risc/method_compiler.rb index 81bcc8f0..4a986759 100644 --- a/lib/risc/method_compiler.rb +++ b/lib/risc/method_compiler.rb @@ -82,93 +82,5 @@ module Risc ret end - - # return the frame type, ie the method frame type - def frame_type - @callable.frame_type - end - # return the frame type, ie the method arguments type - def arg_type - @callable.arguments_type - end - # return the frame type, ie the method self_type - def receiver_type - @callable.self_type - end - - # convert the given mom instruction to_risc and then add it (see add_code) - # continue down the instruction chain unti depleted - # (adding moves the insertion point so the whole mom chain is added as a risc chain) - def add_mom( instruction ) - while( instruction ) - raise "whats this a #{instruction}" unless instruction.is_a?(Mom::Instruction) - #puts "adding mom #{instruction.to_s}:#{instruction.next.to_s}" - risc = instruction.to_risc( self ) - add_code(risc) - reset_regs - #puts "adding risc #{risc.to_s}:#{risc.next.to_s}" - instruction = instruction.next - end - end - - # add a risc instruction after the current (insertion point) - # the added instruction will become the new insertion point - def add_code( instruction ) - raise "Not an instruction:#{instruction.to_s}" unless instruction.is_a?(Risc::Instruction) - raise instruction.to_s if( instruction.class.name.split("::").first == "Arm") - new_current = instruction.last #after insertion this point is lost - @current.insert(instruction) #insert after current - @current = new_current - self - end - - # require a (temporary) register. code must give this back with release_reg - def use_reg( type , extra = {} ) - raise "Not type #{type.inspect}" unless type.is_a?(Symbol) or type.is_a?(Parfait::Type) - if @regs.empty? - reg = Risc.tmp_reg(type , extra) - else - reg = @regs.last.next_reg_use(type , extra) - end - @regs << reg - return reg - end - - def copy( reg , source ) - copied = use_reg reg.type - add_code Register.transfer( source , reg , copied ) - copied - end - - # releasing a register (accuired by use_reg) makes it available for use again - # thus avoiding possibly using too many registers - def release_reg( reg ) - last = @regs.pop - raise "released register in wrong order, expect #{last} but was #{reg}" if reg != last - end - - # reset the registers to be used. Start at r4 for next usage. - # Every statement starts with this, meaning each statement may use all registers, but none - # get saved. Statements have affect on objects. - def reset_regs - @regs.clear - end - - # Build with builder (see there), adding the created instructions - def build(source , &block) - code_builder(source).build(&block) - end - - # return a new code builder that uses this compiler - # CodeBuilder returns code after building - def code_builder( source) - CodeBuilder.new(self , source) - end - - # return a CompilerBuilder - # CompilerBuilder adds the generated code to the compiler - def compiler_builder( source) - CompilerBuilder.new(self , source) - end end end