1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

store references to the weak callbacks in function adapters, so they don't get garbage collected.

This commit is contained in:
Charles Lowell 2011-05-02 15:40:07 -05:00
parent 1b398b175a
commit f0ddef4412

View file

@ -10,15 +10,16 @@ module V8
@constructors = {}
@methods = {}
@procs = {}
@releases = {}
end
def to_constructor(ruby_class)
class_id = ruby_class.object_id
if constructor = @constructors[class_id]
return constructor
else
constructor = @constructors[class_id] = ConstructorAdapter.new(self, class_id)
ObjectSpace.define_finalizer(ruby_class, bind(@constructors, :delete, class_id))
ObjectSpace.define_finalizer(ruby_class, release(@constructors, class_id))
return constructor
end
end
@ -31,16 +32,16 @@ module V8
else
function = @methods[code.to_s] = FunctionAdapter.new(@portal, code)
#TODO: test this weak behavior
function.template.MakeWeak(0, bind(@methods, :delete, code.to_s))
function.template.MakeWeak(0, release(@methods, code.to_s))
return function
end
else
if fn = @procs[code]
return fn
else
function = FunctionAdapter.new(@portal, code)
function = @procs[code] = FunctionAdapter.new(@portal, code)
#TODO: test this weak behavior
function.template.MakeWeak(0, bind(@procs, :delete, code))
function.template.MakeWeak(0, release(@procs, code))
return function
end
end
@ -50,8 +51,22 @@ module V8
@portal.proxies
end
def bind(object, method, *args)
lambda {object.send(:method, *args)}
def release(refs, id)
release = Release.new(@releases, refs, id)
@releases[release] = true
return release
end
class Release
def initialize(releases, refs, id)
@releases, @refs, @id = releases, refs, id
end
def call(*args)
@refs.delete(@id)
@releases.delete(self)
end
end
end
end