From 5346077a726fd719fa0b85cb250eff93a0059fe1 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Thu, 2 Aug 2018 17:36:39 +0300 Subject: [PATCH] use the return jump to jump to the return sequence thus every method only has one exit should make multi return messages smaller especially when we have escape analisis (maybe will help with inlining too) --- lib/parfait/callable_method.rb | 19 ++++++++++--------- lib/risc/callable_compiler.rb | 18 ++++++++++++++++-- lib/vool/return_statement.rb | 2 +- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/parfait/callable_method.rb b/lib/parfait/callable_method.rb index 343a277c..00d4cc1f 100644 --- a/lib/parfait/callable_method.rb +++ b/lib/parfait/callable_method.rb @@ -1,14 +1,15 @@ -# A CallableMethod is static object that primarily holds the executable code. -# It is callable through it's binary code -# Additionally to the base class it has a name -# -# It's relation to the method a ruby programmer knows (called VoolMethod) is many to one, -# meaning one VoolMethod (untyped) has many CallableMethod implementations. -# The VoolMethod only holds vool code, no binary. - - module Parfait + # A CallableMethod is static object that primarily holds the executable code. + # It is callable through it's binary code + # + # It's relation to the method a ruby programmer knows (called VoolMethod) is many to one, + # meaning one VoolMethod (untyped) has many CallableMethod implementations. + # The VoolMethod only holds vool code, no binary. + # + # CallableMethods are bound to a known type (self_type) and have known argument + # and local variables. All variable resolution inside the method is exact (static), + # only method resolution may be dynamic class CallableMethod < Callable def ==(other) diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index e079eef9..a1ac0782 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -13,14 +13,28 @@ module Risc def initialize( callable ) @callable = callable @regs = [] - @risc_instructions = Risc.label(source_name, source_name) - @risc_instructions << Risc.label( source_name, "unreachable") + init_instructions @current = @risc_instructions @constants = [] @block_compilers = [] end attr_reader :risc_instructions , :constants , :block_compilers , :callable + def init_instructions + @risc_instructions = Risc.label(source_name, source_name) + @risc_instructions.append Risc.label( source_name, "return_label") + @risc_instructions.append Mom::ReturnSequence.new.to_risc(self) + @risc_instructions.append Risc.label( source_name, "unreachable") + reset_regs + end + + def return_label + @risc_instructions.each do |ins| + next unless ins.is_a?(Label) + return ins if ins.name == "return_label" + end + 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) diff --git a/lib/vool/return_statement.rb b/lib/vool/return_statement.rb index 86736e16..35c3d879 100644 --- a/lib/vool/return_statement.rb +++ b/lib/vool/return_statement.rb @@ -18,7 +18,7 @@ module Vool def to_mom( compiler ) ret = Mom::SlotLoad.new( [:message , :return_value] , @return_value.slot_definition(compiler) ) - ret << Mom::ReturnSequence.new + ret << Mom::ReturnJump.new end def to_s(depth = 0)