2017-01-19 08:02:29 +01:00
|
|
|
module Risc
|
2015-05-31 10:07:49 +02:00
|
|
|
|
2019-07-28 15:42:40 +02:00
|
|
|
# collect anything that is in the space and reachable (linker constants)
|
2018-06-15 20:54:21 +02:00
|
|
|
#
|
|
|
|
# The place we collect in is the position map in Position class
|
2015-10-18 18:27:02 +02:00
|
|
|
module Collector
|
2019-07-28 15:42:40 +02:00
|
|
|
# Collect all object that need to be added to the binary
|
|
|
|
# This means the object_space and aby constants the linker has
|
|
|
|
# we call keep on each object, see there for details
|
|
|
|
# return all positions
|
2018-07-01 13:11:29 +02:00
|
|
|
def self.collect_space(linker)
|
2019-07-28 15:42:40 +02:00
|
|
|
keep Parfait.object_space
|
2018-08-29 20:05:54 +02:00
|
|
|
linker.constants.each do |obj|
|
2019-07-28 15:42:40 +02:00
|
|
|
keep(obj)
|
2018-08-29 20:05:54 +02:00
|
|
|
end
|
2018-06-15 20:54:21 +02:00
|
|
|
Position.positions
|
2015-05-31 10:07:49 +02:00
|
|
|
end
|
|
|
|
|
2019-07-28 15:42:40 +02:00
|
|
|
# keep "collects" the object for "keeping". Such objects get written to binary
|
|
|
|
# keeping used to be done by adding to a hash, but now the object is
|
|
|
|
# given a position, and the Position class has a hash of all positions
|
|
|
|
# (the same hash has all objects, off course)
|
|
|
|
def self.keep( object)
|
|
|
|
collection = []
|
|
|
|
mark_1k( object , 0 , collection)
|
|
|
|
collection.each do |obj|
|
|
|
|
keep(obj)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# marking object that make up the binary.
|
|
|
|
# "Only" up to 1k stack depth, collect object that make up the "border"
|
|
|
|
#
|
|
|
|
# Collection is an empty arry that is passed on. Objects below 1k get added
|
|
|
|
# So basically it "should" be a return, but then we would keep creating and adding
|
|
|
|
# arrays, most of which would be empty
|
|
|
|
def self.mark_1k(object , depth , collection)
|
2015-05-31 12:02:29 +02:00
|
|
|
return if object.nil?
|
2019-07-28 15:42:40 +02:00
|
|
|
if depth > 1000
|
|
|
|
collection << object
|
|
|
|
return
|
|
|
|
end
|
|
|
|
return unless position!( object )
|
2016-02-25 20:50:10 +01:00
|
|
|
return unless object.respond_to? :has_type?
|
|
|
|
type = object.get_type
|
2019-07-28 15:42:40 +02:00
|
|
|
mark_1k(type , depth + 1 , collection)
|
2015-10-26 11:23:52 +01:00
|
|
|
return if object.is_a? Symbol
|
2016-12-29 17:45:32 +01:00
|
|
|
type.names.each do |name|
|
2019-07-28 15:42:40 +02:00
|
|
|
mark_1k(name , depth + 1, collection)
|
2015-07-21 18:41:30 +02:00
|
|
|
inst = object.get_instance_variable name
|
2019-07-28 15:42:40 +02:00
|
|
|
mark_1k(inst , depth + 1, collection)
|
2015-05-31 10:07:49 +02:00
|
|
|
end
|
2016-12-30 20:00:18 +01:00
|
|
|
if object.is_a? Parfait::List
|
2015-05-31 10:07:49 +02:00
|
|
|
object.each do |item|
|
2019-07-28 15:42:40 +02:00
|
|
|
mark_1k(item , depth + 1, collection)
|
2015-05-31 10:07:49 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2016-12-31 13:54:15 +01:00
|
|
|
|
2019-07-28 15:42:40 +02:00
|
|
|
# Give the object a position. Position class keeps a list of all positions
|
|
|
|
# and associated objects. The actual position is determined later, here a
|
|
|
|
# Position object is assigned.
|
|
|
|
#
|
|
|
|
# All Objects that end up in the binary must have a Position.
|
|
|
|
#
|
|
|
|
# return if the position was assigned (true) or had been assigned already (false)
|
|
|
|
def self.position!( objekt )
|
2018-06-15 20:54:21 +02:00
|
|
|
return false if Position.set?(objekt)
|
2019-02-07 17:24:35 +01:00
|
|
|
return true if objekt.is_a? ::Integer
|
2019-09-30 16:09:13 +02:00
|
|
|
return true if objekt.is_a? ::NilClass
|
|
|
|
return true if objekt.is_a? ::TrueClass
|
|
|
|
return true if objekt.is_a? ::FalseClass
|
2018-03-27 18:06:16 +02:00
|
|
|
return true if objekt.is_a?( Risc::Label)
|
2019-07-28 15:42:40 +02:00
|
|
|
#puts "ADD #{objekt.class.name}"
|
2018-03-27 18:06:16 +02:00
|
|
|
unless objekt.is_a?( Parfait::Object) or objekt.is_a?( Symbol)
|
2018-03-22 16:38:13 +01:00
|
|
|
raise "adding non parfait #{objekt.class}:#{objekt}"
|
2016-12-31 13:54:15 +01:00
|
|
|
end
|
2018-07-07 08:11:09 +02:00
|
|
|
#raise "Method #{objekt.name}" if objekt.is_a? Parfait::CallableMethod
|
2018-06-15 20:54:21 +02:00
|
|
|
Position.get_or_create(objekt)
|
2016-12-31 13:54:15 +01:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2015-05-31 10:07:49 +02:00
|
|
|
end
|
|
|
|
end
|