rename typed_method to callable_method

seems to make the essence clearer
also extracted base class
This commit is contained in:
Torsten Ruger
2018-07-07 09:11:09 +03:00
parent acd5cd8f30
commit 9005513368
28 changed files with 146 additions and 142 deletions

View File

@ -2,7 +2,7 @@
# we resolve the method at runtime, and then cache it. Aaron has shown that over 99%
# of call sites are type stable, so one cache entry at the moment
#
# A cache entry stores the type of the object and the TypedMethod that is to be called
# A cache entry stores the type of the object and the CallableMethod that is to be called
# This is used in DynamicCall, see there
#
module Parfait

View File

@ -8,11 +8,12 @@ module Parfait
# - frame_type: A type object describing the local variables that the method has
# - binary: The binary (jumpable) code that instructions get assembled into
# - blocks: linked list of blocks inside this method/block
# - next: next block/method at same level
#
class Callable < Object
attr_reader :self_type , :arguments_type , :frame_type , :binary , :blocks
attr_reader :self_type , :arguments_type , :frame_type , :binary
attr_reader :blocks, :next
def initialize( self_type , arguments_type , frame_type)
super()
raise "No class #{self}" unless self_type
@ -53,5 +54,10 @@ module Parfait
bin = bin.next
end
end
def set_next( method )
@next = method
end
end
end

View File

@ -0,0 +1,40 @@
# 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
class CallableMethod < Callable
attr_reader :name
def initialize( self_type , name , arguments_type , frame_type)
@name = name
super(self_type , arguments_type , frame_type)
end
def ==(other)
return false unless other.is_a?(CallableMethod)
return false if @name != other.name
super
end
def rxf_reference_name
"Method: " + @name.to_s
end
def inspect
"#{@self_type.object_class.name}:#{name}(#{arguments_type.inspect})"
end
def each_method( &block )
block.call( self )
@next.each_method( &block ) if @next
end
end
end

View File

@ -12,7 +12,7 @@
# An Object carries the data for the instance variables it has.
# The Type lists the names of the instance variables
# The Class keeps a list of instance methods, these have a name and (vool) code
# Each type in turn has a list of TypedMethods that hold binary code
# Each type in turn has a list of CallableMethods that hold binary code
module Parfait
class Class < Object

View File

@ -87,12 +87,12 @@ module Parfait
found.init(arguments , frame)
return found
else
add_method TypedMethod.new( self , method_name , arguments , frame )
add_method CallableMethod.new( self , method_name , arguments , frame )
end
end
def add_method( method )
raise "not a method #{method.class} #{method.inspect}" unless method.is_a? TypedMethod
raise "not a method #{method.class} #{method.inspect}" unless method.is_a? CallableMethod
raise "syserr #{method.name.class}" unless method.name.is_a? Symbol
if self.is_a?(Class) and (method.self_type != self)
raise "Adding to wrong class, should be #{method.for_class}"
@ -109,16 +109,16 @@ module Parfait
def remove_method( method_name )
raise "No such method #{method_name} in #{self.name}" unless @methods
if( @methods.name == method_name)
@methods = @methods.next_method
@methods = @methods.next
return true
end
method = @methods
while(method && method.next_method)
if( method.next_method.name == method_name)
method.set_next( method.next_method.next_method )
while(method && method.next)
if( method.next.name == method_name)
method.set_next( method.next.next )
return true
else
method = method.next_method
method = method.next
end
end
raise "No such method #{method_name} in #{self.name}"
@ -144,6 +144,7 @@ module Parfait
return method if method
sup = object_class.super_class
return nil unless sup
return nil if object_class.name == :Object
sup.instance_type.resolve_method(fname)
end

View File

@ -1,53 +0,0 @@
require_relative "callable"
# A TypedMethod is static object that primarily holds the executable code.
# It is called typed, because all arguments and variables it uses are "typed",
# that is to say the names are known and form a type (not that the types of the
# variables are known). The object's type is known too, which means all instances
# variable names are known (not their respective type).
# It's relation to the method a ruby programmer knows (called VoolMethod) is many to one,
# meaning one VoolMethod (untyped) has many TypedMethod implementations.
# The VoolMethod only holds vool code, no binary.
# The Typed method has the following instance variables
# - name : This is the same as the ruby method name it implements
# - binary: The binary (jumpable) code that the instructions get assembled into
# - arguments_type: A type object describing the arguments (name+types) to be passed
# - frame_type: A type object describing the local variables that the method has
# - self_type: The Type the Method is for
module Parfait
class TypedMethod < Callable
attr_reader :name , :next_method
def initialize( self_type , name , arguments_type , frame_type)
@name = name
super(self_type , arguments_type , frame_type)
end
def ==(other)
return false unless other.is_a?(TypedMethod)
return false if @name != other.name
super
end
def rxf_reference_name
"Method: " + @name.to_s
end
def inspect
"#{@self_type.object_class.name}:#{name}(#{arguments_type.inspect})"
end
def each_method( &block )
block.call( self )
next_method.each_method( &block ) if next_method
end
def set_next( method )
@next_method = method
end
end
end

View File

@ -5,7 +5,7 @@ module Parfait
# Type objects are already created for args and locals, but the main attribute
# is the source, which is a Vool::Statement
#
# Classes store VoolMethods, while Types store TypedMethod
# Classes store VoolMethods, while Types store CallableMethod
# A Type referes to a Class , but a Class (interface) is implemented by many types
# as it changes during the course of it's life. Types do not change. Objects have
# type, and so only indirectly a class.
@ -23,14 +23,14 @@ module Parfait
raise "Empty bod" if(source.is_a?(Vool::Statements) and source.empty?)
end
def create_typed_method( type )
def create_callable_method( type )
raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type
type.create_method( @name , @args_type , @frame_type)
end
def compiler_for(self_type)
typed_method = create_typed_method(self_type)
compiler = Risc::MethodCompiler.new( typed_method )
callable_method = create_callable_method(self_type)
compiler = Risc::MethodCompiler.new( callable_method )
head = source.to_mom( compiler )
compiler.add_mom(head)
compiler