fixing assembly
position code changed and linking too passes not working
This commit is contained in:
parent
95ac024421
commit
2ccbea04b9
@ -5,15 +5,14 @@ module Arm
|
|||||||
def initialize to , from , options = {}
|
def initialize to , from , options = {}
|
||||||
super(options)
|
super(options)
|
||||||
@to = to
|
@to = to
|
||||||
raise "old code, fix this to use LoadConstant" if from.is_a? Virtual::ObjectConstant
|
@from = from #from.is_a?(Fixnum) ? Virtual::IntegerConstant.new(from) : from
|
||||||
@from = from.is_a?(Fixnum) ? Virtual::IntegerConstant.new(from) : from
|
|
||||||
raise "move must have from set #{inspect}" unless from
|
raise "move must have from set #{inspect}" unless from
|
||||||
@attributes[:update_status] = 0 if @attributes[:update_status] == nil
|
@attributes[:update_status] = 0 if @attributes[:update_status] == nil
|
||||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||||
@attributes[:opcode] = attributes[:opcode]
|
@attributes[:opcode] = attributes[:opcode]
|
||||||
@operand = 0
|
@operand = 0
|
||||||
|
|
||||||
@immediate = 0
|
@immediate = 0
|
||||||
@rn = :r0 # register zero = zero bit pattern
|
@rn = :r0 # register zero = zero bit pattern
|
||||||
@from = Virtual::IntegerConstant.new( @from ) if( @from.is_a? Fixnum )
|
@from = Virtual::IntegerConstant.new( @from ) if( @from.is_a? Fixnum )
|
||||||
@extra = nil
|
@extra = nil
|
||||||
@ -22,11 +21,11 @@ module Arm
|
|||||||
|
|
||||||
# arm intructions are pretty sensible, and always 4 bytes (thumb not supported)
|
# arm intructions are pretty sensible, and always 4 bytes (thumb not supported)
|
||||||
# but not all constants fit into the part of the instruction that is left after the instruction code,
|
# but not all constants fit into the part of the instruction that is left after the instruction code,
|
||||||
# so large moves have to be split into two instructions.
|
# so large moves have to be split into two instructions.
|
||||||
# we handle this "transparently", just this instruction looks longer
|
# we handle this "transparently", just this instruction looks longer
|
||||||
# alas, full transparency is not achieved as we only know when to use 2 instruction once we know where the
|
# alas, full transparency is not achieved as we only know when to use 2 instruction once we know where the
|
||||||
# other object is, and that position is only set after code positions have been determined (in link) and so
|
# other object is, and that position is only set after code positions have been determined (in link) and so
|
||||||
# see below in assemble
|
# see below in assemble
|
||||||
def mem_length
|
def mem_length
|
||||||
@extra ? 8 : 4
|
@extra ? 8 : 4
|
||||||
end
|
end
|
||||||
@ -60,15 +59,15 @@ module Arm
|
|||||||
#armv7 operand = (right.integer & 0xFFF)
|
#armv7 operand = (right.integer & 0xFFF)
|
||||||
#armv7 immediate = 1
|
#armv7 immediate = 1
|
||||||
#armv7 rn = (right.integer >> 12)
|
#armv7 rn = (right.integer >> 12)
|
||||||
# a little STRANGE, that the armv7 movw (move a 2 byte word) is an old test opcode, but there it is
|
# a little STRANGE, that the armv7 movw (move a 2 byte word) is an old test opcode, but there it is
|
||||||
#armv7 @attributes[:opcode] = :tst
|
#armv7 @attributes[:opcode] = :tst
|
||||||
raise "No negatives implemented #{right} " if right.integer < 0
|
raise "No negatives implemented #{right} " if right.integer < 0
|
||||||
# and so it continues: when we notice that the const doesn't fit, first time we raise an
|
# and so it continues: when we notice that the const doesn't fit, first time we raise an
|
||||||
# error,but set the extra flag, to say the instruction is now 8 bytes
|
# error,but set the extra flag, to say the instruction is now 8 bytes
|
||||||
# then on subsequent assemblies we can assemble
|
# then on subsequent assemblies we can assemble
|
||||||
unless @extra
|
unless @extra
|
||||||
@extra = 1
|
@extra = 1
|
||||||
raise ::Register::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}")
|
raise ::Register::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}")
|
||||||
end
|
end
|
||||||
# now we can do the actual breaking of instruction, by splitting the operand
|
# now we can do the actual breaking of instruction, by splitting the operand
|
||||||
first = Virtual::IntegerConstant.new(right.integer & 0xFFFFFF00)
|
first = Virtual::IntegerConstant.new(right.integer & 0xFFFFFF00)
|
||||||
@ -80,7 +79,7 @@ module Arm
|
|||||||
# is to check that the first part is doabe with u8_with_rr AND leaves a u8 remainder
|
# is to check that the first part is doabe with u8_with_rr AND leaves a u8 remainder
|
||||||
end
|
end
|
||||||
elsif (right.is_a?(Symbol) or right.is_a?(::Register::RegisterReference))
|
elsif (right.is_a?(Symbol) or right.is_a?(::Register::RegisterReference))
|
||||||
operand = reg_code(right)
|
operand = reg_code(right)
|
||||||
immediate = 0 # ie not immediate is register
|
immediate = 0 # ie not immediate is register
|
||||||
else
|
else
|
||||||
raise "invalid operand argument #{right.class} , #{self.class}"
|
raise "invalid operand argument #{right.class} , #{self.class}"
|
||||||
@ -89,17 +88,17 @@ module Arm
|
|||||||
instuction_class = 0b00 # OPC_DATA_PROCESSING
|
instuction_class = 0b00 # OPC_DATA_PROCESSING
|
||||||
val = shift(operand , 0)
|
val = shift(operand , 0)
|
||||||
val |= shift(op , 0) # any barrel action, is already shifted
|
val |= shift(op , 0) # any barrel action, is already shifted
|
||||||
val |= shift(reg_code(@to) , 12)
|
val |= shift(reg_code(@to) , 12)
|
||||||
val |= shift(reg_code(rn) , 12+4)
|
val |= shift(reg_code(rn) , 12+4)
|
||||||
val |= shift(@attributes[:update_status] , 12+4+4)#20
|
val |= shift(@attributes[:update_status] , 12+4+4)#20
|
||||||
val |= shift(op_bit_code , 12+4+4 +1)
|
val |= shift(op_bit_code , 12+4+4 +1)
|
||||||
val |= shift(immediate , 12+4+4 +1+4)
|
val |= shift(immediate , 12+4+4 +1+4)
|
||||||
val |= shift(instuction_class , 12+4+4 +1+4+1)
|
val |= shift(instuction_class , 12+4+4 +1+4+1)
|
||||||
val |= shift(cond_bit_code , 12+4+4 +1+4+1+2)
|
val |= shift(cond_bit_code , 12+4+4 +1+4+1+2)
|
||||||
io.write_uint32 val
|
io.write_uint32 val
|
||||||
# by now we have the extra add so assemble that
|
# by now we have the extra add so assemble that
|
||||||
if(@extra)
|
if(@extra)
|
||||||
@extra.assemble(io)
|
@extra.assemble(io)
|
||||||
#puts "Assemble extra at #{val.to_s(16)}"
|
#puts "Assemble extra at #{val.to_s(16)}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -115,4 +114,4 @@ module Arm
|
|||||||
[@to.register]
|
[@to.register]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -34,10 +34,6 @@ module Parfait
|
|||||||
@object_layout.push name
|
@object_layout.push name
|
||||||
end
|
end
|
||||||
|
|
||||||
def mem_length
|
|
||||||
padded_words(3)
|
|
||||||
end
|
|
||||||
|
|
||||||
# ruby 2.1 list (just for reference, keep at bottom)
|
# ruby 2.1 list (just for reference, keep at bottom)
|
||||||
#:allocate, :new, :superclass
|
#:allocate, :new, :superclass
|
||||||
end
|
end
|
||||||
|
@ -33,7 +33,7 @@ module Parfait
|
|||||||
raise "not a method #{method.class} #{method.inspect}" unless method.is_a? Method
|
raise "not a method #{method.class} #{method.inspect}" unless method.is_a? Method
|
||||||
raise "syserr #{method.name.class}" unless method.name.is_a? Word
|
raise "syserr #{method.name.class}" unless method.name.is_a? Word
|
||||||
@instance_methods << method
|
@instance_methods << method
|
||||||
puts "#{self.name} add #{method.name}"
|
#puts "#{self.name} add #{method.name}"
|
||||||
method
|
method
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -71,6 +71,10 @@ module Parfait
|
|||||||
get_layout().index_of(name)
|
get_layout().index_of(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mem_length
|
||||||
|
padded_words( get_layout().get_length() + 2 )
|
||||||
|
end
|
||||||
|
|
||||||
# Object
|
# Object
|
||||||
# :nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint,
|
# :nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint,
|
||||||
# :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods,
|
# :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods,
|
||||||
|
@ -74,10 +74,6 @@ module Parfait
|
|||||||
raise "uups " if name.is_a? String
|
raise "uups " if name.is_a? String
|
||||||
@classes[name] = c
|
@classes[name] = c
|
||||||
end
|
end
|
||||||
|
|
||||||
def mem_length
|
|
||||||
padded_words( 5 )
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
# ObjectSpace
|
# ObjectSpace
|
||||||
# :each_object, :garbage_collect, :define_finalizer, :undefine_finalizer, :_id2ref, :count_objects
|
# :each_object, :garbage_collect, :define_finalizer, :undefine_finalizer, :_id2ref, :count_objects
|
||||||
|
@ -22,14 +22,13 @@ module Register
|
|||||||
@space.set_position(0)
|
@space.set_position(0)
|
||||||
at = @space.mem_length # first jump instruction
|
at = @space.mem_length # first jump instruction
|
||||||
# then all functions
|
# then all functions
|
||||||
@objects.each_value do | objekt|
|
@space.objects.each do | objekt|
|
||||||
next unless objekt.is_a? Virtual::CompiledMethod
|
next unless objekt.is_a? Parfait::Method
|
||||||
objekt.set_position(at)
|
objekt.info.set_position(at)
|
||||||
at += objekt.mem_length
|
at += objekt.info.mem_length
|
||||||
end
|
end
|
||||||
#and then all data object
|
#and then all data object
|
||||||
@objects.each_value do | objekt|
|
@objects.each do | objekt|
|
||||||
next if objekt.is_a? Virtual::CompiledMethod
|
|
||||||
objekt.set_position at
|
objekt.set_position at
|
||||||
at += objekt.mem_length
|
at += objekt.mem_length
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
require "parfait"
|
||||||
require "virtual/machine"
|
require "virtual/machine"
|
||||||
|
|
||||||
require "virtual/compiler"
|
require "virtual/compiler"
|
||||||
@ -5,7 +6,6 @@ require "virtual/instruction"
|
|||||||
require "virtual/compiled_method_info"
|
require "virtual/compiled_method_info"
|
||||||
require "virtual/slots/slot"
|
require "virtual/slots/slot"
|
||||||
require "virtual/type"
|
require "virtual/type"
|
||||||
require "virtual/constants"
|
|
||||||
# the passes _are_ order dependant
|
# the passes _are_ order dependant
|
||||||
require "virtual/passes/send_implementation"
|
require "virtual/passes/send_implementation"
|
||||||
require "virtual/passes/get_implementation"
|
require "virtual/passes/get_implementation"
|
||||||
|
@ -7,7 +7,7 @@ module Virtual
|
|||||||
|
|
||||||
# Blocks form a graph, which is managed by the method
|
# Blocks form a graph, which is managed by the method
|
||||||
|
|
||||||
class Block < Virtual::Object
|
class Block
|
||||||
|
|
||||||
def initialize(name , method )
|
def initialize(name , method )
|
||||||
super()
|
super()
|
||||||
|
@ -140,9 +140,15 @@ module Virtual
|
|||||||
l = @blocks.inject(0) { |c , block| c += block.mem_length }
|
l = @blocks.inject(0) { |c , block| c += block.mem_length }
|
||||||
padded(l)
|
padded(l)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def padded len
|
||||||
|
a = 32 * (1 + (len + 7)/32 )
|
||||||
|
#puts "#{a} for #{len}"
|
||||||
|
a
|
||||||
|
end
|
||||||
|
|
||||||
# position of the function is the position of the entry block, is where we call
|
# position of the function is the position of the entry block, is where we call
|
||||||
def set_position at
|
def set_position at
|
||||||
super
|
|
||||||
at += 8 #for the 2 header words
|
at += 8 #for the 2 header words
|
||||||
@blocks.each do |block|
|
@blocks.each do |block|
|
||||||
block.set_position at
|
block.set_position at
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
require_relative "positioned"
|
require_relative "positioned"
|
||||||
|
|
||||||
module Virtual
|
module Virtual
|
||||||
@ -12,30 +11,6 @@ module Virtual
|
|||||||
|
|
||||||
class Instruction
|
class Instruction
|
||||||
include Positioned
|
include Positioned
|
||||||
|
|
||||||
# simple thought: don't recurse for Blocks, just check their names
|
|
||||||
def == other
|
|
||||||
return false unless other.class == self.class
|
|
||||||
Sof::Util.attributes(self).each do |a|
|
|
||||||
begin
|
|
||||||
left = send(a)
|
|
||||||
rescue NoMethodError
|
|
||||||
next # not using instance variables that are not defined as attr_readers for equality
|
|
||||||
end
|
|
||||||
begin
|
|
||||||
right = other.send(a)
|
|
||||||
rescue NoMethodError
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return false unless left.class == right.class
|
|
||||||
if( left.is_a? Block)
|
|
||||||
return false unless left.name == right.name
|
|
||||||
else
|
|
||||||
return false unless left == right
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -42,7 +42,9 @@ module Virtual
|
|||||||
|
|
||||||
def run_passes
|
def run_passes
|
||||||
#TODO puts "INIT #{@init}"
|
#TODO puts "INIT #{@init}"
|
||||||
|
|
||||||
@passes.each do |pass_class|
|
@passes.each do |pass_class|
|
||||||
|
puts "run pass #{pass_class}"
|
||||||
blocks = []#[@init] #TODO + @main.blocks
|
blocks = []#[@init] #TODO + @main.blocks
|
||||||
@space.classes.values.each do |c|
|
@space.classes.values.each do |c|
|
||||||
c.instance_methods.each do |f|
|
c.instance_methods.each do |f|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
module FakeMem
|
module FakeMem
|
||||||
def initialize
|
def initialize
|
||||||
@memory = [0,nil]
|
@memory = [0,nil]
|
||||||
|
@position = nil
|
||||||
|
@length = -1
|
||||||
if Parfait::Space.object_space and Parfait::Space.object_space.objects
|
if Parfait::Space.object_space and Parfait::Space.object_space.objects
|
||||||
Parfait::Space.object_space.add_object self
|
Parfait::Space.object_space.add_object self
|
||||||
else
|
else
|
||||||
@ -21,6 +23,30 @@ module FakeMem
|
|||||||
raise "Class not found #{vm_name}" unless clazz
|
raise "Class not found #{vm_name}" unless clazz
|
||||||
self.set_layout clazz.object_layout
|
self.set_layout clazz.object_layout
|
||||||
end
|
end
|
||||||
|
def position
|
||||||
|
raise "position accessed but not set at #{length} for #{self.inspect[0...500]}" if @position == nil
|
||||||
|
@position
|
||||||
|
end
|
||||||
|
def set_position pos
|
||||||
|
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
|
||||||
|
# in measures (of 32)
|
||||||
|
if @position != nil and ((@position - pos).abs > 32)
|
||||||
|
raise "position set again #{pos}!=#{@position} for #{self}"
|
||||||
|
end
|
||||||
|
@position = pos
|
||||||
|
end
|
||||||
|
# objects only come in lengths of multiple of 8 words
|
||||||
|
# but there is a constant overhead of 2 words, one for type, one for layout
|
||||||
|
# and as we would have to subtract 1 to make it work without overhead, we now have to add 7
|
||||||
|
def padded len
|
||||||
|
a = 32 * (1 + (len + 7)/32 )
|
||||||
|
#puts "#{a} for #{len}"
|
||||||
|
a
|
||||||
|
end
|
||||||
|
|
||||||
|
def padded_words words
|
||||||
|
padded(words*4) # 4 == word length, a constant waiting for a home
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Parfait
|
module Parfait
|
||||||
@ -29,6 +55,7 @@ module Parfait
|
|||||||
# These are the same functions that Builtin implements at run-time
|
# These are the same functions that Builtin implements at run-time
|
||||||
class Object
|
class Object
|
||||||
include FakeMem
|
include FakeMem
|
||||||
|
|
||||||
# these internal functions are _really_ internal
|
# these internal functions are _really_ internal
|
||||||
# they respresent the smallest code needed to build larger functionality
|
# they respresent the smallest code needed to build larger functionality
|
||||||
# but should _never_ be used outside parfait. in fact that should be impossible
|
# but should _never_ be used outside parfait. in fact that should be impossible
|
||||||
@ -67,6 +94,9 @@ module Parfait
|
|||||||
|
|
||||||
end
|
end
|
||||||
class List
|
class List
|
||||||
|
def mem_length
|
||||||
|
Virtual::Object.new.padded_words(length())
|
||||||
|
end
|
||||||
def to_sof_node(writer , level , ref )
|
def to_sof_node(writer , level , ref )
|
||||||
Sof.array_to_sof_node(self , writer , level , ref )
|
Sof.array_to_sof_node(self , writer , level , ref )
|
||||||
end
|
end
|
||||||
@ -91,6 +121,10 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
class Word
|
class Word
|
||||||
|
def mem_length
|
||||||
|
Virtual::Object.new.padded(1 + length())
|
||||||
|
end
|
||||||
|
|
||||||
def == other
|
def == other
|
||||||
return false unless other.is_a?(String) or other.is_a?(Word)
|
return false unless other.is_a?(String) or other.is_a?(Word)
|
||||||
as_string = self.to_s
|
as_string = self.to_s
|
||||||
@ -112,6 +146,7 @@ module Parfait
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
module Virtual
|
module Virtual
|
||||||
# Functions to generate parfait objects
|
# Functions to generate parfait objects
|
||||||
def self.new_word( string )
|
def self.new_word( string )
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
require_relative "type"
|
require_relative "type"
|
||||||
require "parfait"
|
|
||||||
|
|
||||||
module Positioned
|
module Positioned
|
||||||
def position
|
def position
|
||||||
@ -14,124 +13,16 @@ module Positioned
|
|||||||
end
|
end
|
||||||
@position = pos
|
@position = pos
|
||||||
end
|
end
|
||||||
end
|
# objects only come in lengths of multiple of 8 words
|
||||||
|
# but there is a constant overhead of 2 words, one for type, one for layout
|
||||||
|
# and as we would have to subtract 1 to make it work without overhead, we now have to add 7
|
||||||
|
def padded len
|
||||||
|
a = 32 * (1 + (len + 7)/32 )
|
||||||
|
#puts "#{a} for #{len}"
|
||||||
|
a
|
||||||
|
end
|
||||||
|
|
||||||
module Virtual
|
def padded_words words
|
||||||
# our machine is made up of objects, some of which are code, some data
|
padded(words*4) # 4 == word length, a constant waiting for a home
|
||||||
#
|
|
||||||
# during compilation objects are module Virtual objects, but during execution they are not scoped
|
|
||||||
#
|
|
||||||
# So compiling/linking/assembly turns ::virtual objects into binary that represents ruby objects at runtime
|
|
||||||
# The equivalence is listed below (i'll try and work on clearer correspondence later)
|
|
||||||
# ::Virtual Runtime / parfait
|
|
||||||
# Object Object
|
|
||||||
# BootClass Class
|
|
||||||
# MetaClass self/Object
|
|
||||||
# Space ObjectSpace
|
|
||||||
# CompiledMethod Function
|
|
||||||
# (ruby)Array Array
|
|
||||||
# String String
|
|
||||||
class Object
|
|
||||||
include Positioned
|
|
||||||
def initialize
|
|
||||||
@position = nil
|
|
||||||
@length = -1
|
|
||||||
end
|
|
||||||
attr_accessor :length , :layout
|
|
||||||
def inspect
|
|
||||||
Sof::Writer.write(self)
|
|
||||||
end
|
|
||||||
def to_s
|
|
||||||
inspect[0..300]
|
|
||||||
end
|
|
||||||
def mem_length
|
|
||||||
raise "abstract #{self.class}"
|
|
||||||
end
|
|
||||||
@@EMPTY = { :names => [] , :types => []}
|
|
||||||
def old_layout
|
|
||||||
raise "Find me #{self}"
|
|
||||||
self.class.layout
|
|
||||||
end
|
|
||||||
def self.layout
|
|
||||||
@@EMPTY
|
|
||||||
end
|
|
||||||
# class variables to have _identical_ objects passed back (stops recursion)
|
|
||||||
@@ARRAY = { :names => [] , :types => []}
|
|
||||||
# @@HASH = { :names => [:keys,:values] , :types => [Virtual::Reference,Virtual::Reference]}
|
|
||||||
# @@CLAZZ = { :names => [:name , :super_class_name , :instance_methods] , :types => [Virtual::Reference,Virtual::Reference,Virtual::Reference]}
|
|
||||||
# @@SPACE = { :names => [:classes,:objects] , :types => [Virtual::Reference,Virtual::Reference]}
|
|
||||||
|
|
||||||
def old_layout_for(object)
|
|
||||||
case object
|
|
||||||
when Array , Symbol , String , Virtual::CompiledMethod , Virtual::Block , Parfait::Word
|
|
||||||
@@ARRAY
|
|
||||||
when Hash
|
|
||||||
@@HASH.merge :keys => object.keys , :values => object.values
|
|
||||||
when Virtual::BootClass
|
|
||||||
@@CLAZZ
|
|
||||||
when Virtual::Space
|
|
||||||
@@SPACE
|
|
||||||
else
|
|
||||||
raise "linker encounters unknown class #{object.class}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# objects only come in lengths of multiple of 8 words
|
|
||||||
# but there is a constant overhead of 2 words, one for type, one for layout
|
|
||||||
# and as we would have to subtract 1 to make it work without overhead, we now have to add 7
|
|
||||||
def padded len
|
|
||||||
a = 32 * (1 + (len + 7)/32 )
|
|
||||||
#puts "#{a} for #{len}"
|
|
||||||
a
|
|
||||||
end
|
|
||||||
|
|
||||||
def padded_words words
|
|
||||||
padded(words*4) # 4 == word length, a constant waiting for a home
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::Parfait::Message.class_eval do
|
|
||||||
include Positioned
|
|
||||||
def old_layout
|
|
||||||
Virtual::Object.layout
|
|
||||||
end
|
|
||||||
def mem_length
|
|
||||||
Virtual::Object.new.padded_words(2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::Parfait::Frame.class_eval do
|
|
||||||
include Positioned
|
|
||||||
def old_layout
|
|
||||||
Virtual::Object.layout
|
|
||||||
end
|
|
||||||
def mem_length
|
|
||||||
Virtual::Object.new.padded_words(2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Parfait::Dictionary.class_eval do
|
|
||||||
include Positioned
|
|
||||||
HASH = { :names => [:keys,:values] , :types => [Virtual::Reference,Virtual::Reference]}
|
|
||||||
def old_layout
|
|
||||||
HASH
|
|
||||||
end
|
|
||||||
def mem_length
|
|
||||||
Virtual::Object.new.padded_words(2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::Parfait::List.class_eval do
|
|
||||||
include Positioned
|
|
||||||
def old_layout
|
|
||||||
Virtual::Object.layout
|
|
||||||
end
|
|
||||||
def mem_length
|
|
||||||
Virtual::Object.new.padded_words(length())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::Parfait::Word.class_eval do
|
|
||||||
include Positioned
|
|
||||||
def old_layout
|
|
||||||
Virtual::Object.layout
|
|
||||||
end
|
|
||||||
def mem_length
|
|
||||||
Virtual::Object.new.padded(1 + length())
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -30,9 +30,9 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
|
|||||||
|
|
||||||
require 'salama'
|
require 'salama'
|
||||||
|
|
||||||
Virtual::Object.class_eval do
|
class Ignored
|
||||||
def == other
|
def == other
|
||||||
return false unless other.class == self.class
|
return false unless other.class == self.class
|
||||||
Sof::Util.attributes(self).each do |a|
|
Sof::Util.attributes(self).each do |a|
|
||||||
begin
|
begin
|
||||||
left = send(a)
|
left = send(a)
|
||||||
@ -44,7 +44,7 @@ Virtual::Object.class_eval do
|
|||||||
rescue NoMethodError
|
rescue NoMethodError
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return false unless left.class == right.class
|
return false unless left.class == right.class
|
||||||
return false unless left == right
|
return false unless left == right
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
|
@ -28,3 +28,29 @@ module VirtualHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class UnusedSofEquality
|
||||||
|
# simple thought: don't recurse for Blocks, just check their names
|
||||||
|
def == other
|
||||||
|
return false unless other.class == self.class
|
||||||
|
Sof::Util.attributes(self).each do |a|
|
||||||
|
begin
|
||||||
|
left = send(a)
|
||||||
|
rescue NoMethodError
|
||||||
|
next # not using instance variables that are not defined as attr_readers for equality
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
right = other.send(a)
|
||||||
|
rescue NoMethodError
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return false unless left.class == right.class
|
||||||
|
if( left.is_a? Block)
|
||||||
|
return false unless left.name == right.name
|
||||||
|
else
|
||||||
|
return false unless left == right
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user