summaryrefslogtreecommitdiff
path: root/lib/supple/objects.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/supple/objects.lua')
-rw-r--r--lib/supple/objects.lua35
1 files changed, 33 insertions, 2 deletions
diff --git a/lib/supple/objects.lua b/lib/supple/objects.lua
index 5a5dfca..72eaf9a 100644
--- a/lib/supple/objects.lua
+++ b/lib/supple/objects.lua
@@ -12,6 +12,7 @@
local gc = collectgarbage
local capi = require 'supple.capi'
+local track = require 'supple.track'
local my_objects_by_obj = {}
local my_objects_by_tag = {}
@@ -24,6 +25,9 @@ local proc_call = nil
local type = capi.rawtype
local function clean_down(call_other_end)
+ track.enter("clean_down")
+ setmetatable(their_objects_by_tag, { __mode="v" })
+ setmetatable(their_objects_by_obj, { __mode="k" })
-- And force a full GC
gc "collect"
gc "collect"
@@ -35,6 +39,7 @@ local function clean_down(call_other_end)
-- And forget all our local objects
my_objects_by_obj = {}
my_objects_by_tag = {}
+ track.leave("clean_down")
end
local function set_name(newname)
@@ -76,14 +81,17 @@ local function give(obj, special_tag)
end
-- If the passed object is one of their objects then "unwrap" it by
-- returning their tag.
+ track.enter("give", tostring(obj), tostring(special_tag))
local tag = their_objects_by_obj[obj];
if tag then
+ track.leave("give", "theirs", tag)
return { tag = tag }
end
-- If it's one of our objects which has already been wrapped, return our
-- tag
local tag = my_objects_by_obj[obj]
if tag then
+ track.leave("give", "ours", tag)
return { tag = tag }
end
-- otherwise wrap it freshly for us and return that.
@@ -91,6 +99,7 @@ local function give(obj, special_tag)
local expn = capi.explain(obj, tag)
my_objects_by_obj[obj] = tag
my_objects_by_tag[tag] = obj
+ track.leave("give", "ours, new", tag)
return expn
end
@@ -103,18 +112,21 @@ local function receive(obj)
assert(type(obj) == "table")
assert(type(obj.tag) == "string")
local tag = obj.tag
+ track.enter("receive", tag)
-- First up, is it one of our objects?
local ret = my_objects_by_tag[tag]
if ret then
+ track.leave("receive", "ours", tostring(ret))
return ret
end
-- Now is it a known one of their objects?
ret = their_objects_by_tag[tag]
if ret then
+ track.leave("receive", "theirs", tostring(ret))
return ret
end
-- Okay, prepare a proxy?
- assert(type(obj.type) == "string")
+ assert(type(obj.type) == "string", "Type string expected, got " .. type(obj.type) .. " preparing proxy for " .. obj.tag)
local proxy, mt = capi.new_proxy(obj.type)
assert(capi.type(proxy) == obj.type)
their_objects_by_tag[tag] = proxy
@@ -133,18 +145,25 @@ local function receive(obj)
end
for _, name in ipairs(obj.methods or {}) do
local function meta_func(mobj, ...)
- return proc_call(tag, name, ...)
+ track.enter("meta_func", tostring(mobj), tag, name)
+ local ret = {proc_call(tag, name, ...)}
+ track.leave("meta_func", tostring(mobj), tag, name)
+ return unpack(ret)
end
mt[name] = meta_func
end
-- And return the proxy object
+ track.leave("receive", "theirs, new", tostring(proxy))
return proxy
end
local function forget_mine(tag)
+ track.enter("forget_mine", tag)
local obj = my_objects_by_tag[tag]
+ assert(obj, "Trying to forget nil object: " .. tag)
my_objects_by_tag[tag] = nil
my_objects_by_obj[obj] = nil
+ track.leave("forget_mine", tag)
end
local function find_tag(obj)
@@ -156,6 +175,17 @@ local function find_tag(obj)
end
end
+local function get_object_anchor()
+ local ret = {}
+ for obj in pairs(their_objects_by_obj) do
+ ret[obj] = true
+ end
+ for obj in pairs(my_objects_by_obj) do
+ ret[obj] = true
+ end
+ return ret
+end
+
return {
set_name = set_name,
get_name = get_name,
@@ -165,4 +195,5 @@ return {
clean_down = clean_down,
forget_mine = forget_mine,
find_tag = find_tag,
+ get_object_anchor = get_object_anchor,
}