remove WeakRef from the equation

It turns out that the Ruby stdlib WeakRef class is
completely broken. 

http://bugs.ruby-lang.org/issues/4168

While it is fixed in trunk, it is not useable, so
as a temporary measure, use the `ref` gem as a 
dependency. It appears to be both faster and more
correct.
This commit is contained in:
Charles Lowell 2012-06-20 04:35:40 -05:00
parent 7f967d0c5e
commit 1a93c34b07
5 changed files with 20 additions and 50 deletions

View File

@ -1,5 +1,6 @@
require "v8/version"
require 'ref'
require 'v8/init'
require 'v8/util/weakcell'
require 'v8/error'

View File

@ -1,57 +1,30 @@
require 'ref'
class V8::Conversion
module Identity
def to_ruby(v8_object)
v8_idmap[v8_object] || super
if v8_object.class <= V8::C::Object
v8_idmap[v8_object.GetIdentityHash()] || super(v8_object)
else
super(v8_object)
end
end
def to_v8(ruby_object)
rb_idmap[ruby_object] || super
rb_idmap[ruby_object.object_id] || super(ruby_object)
end
def equate(ruby_object, v8_object)
v8_idmap.equate(v8_object, ruby_object)
rb_idmap.equate(ruby_object, v8_object)
v8_idmap[v8_object.GetIdentityHash()] = ruby_object
rb_idmap[ruby_object.object_id] = v8_object
end
def v8_idmap
@v8_idmap ||= V8IDMap.new
@v8_idmap ||= Ref::WeakValueMap.new
end
def rb_idmap
@ruby_idmap ||= RubyIDMap.new
end
class IDMap
def initialize
@map = {}
end
def [](object)
weakref = @map[to_key(object)]
weakref.__getobj__ if weakref
rescue WeakRef::RefError
nil #peer was garbage collected, so no current mapping.
end
def equate(key_object, value_object)
@map[to_key(key_object)] = WeakRef.new(value_object)
end
end
class RubyIDMap < IDMap
def to_key(object)
object.object_id
end
end
class V8IDMap < IDMap
def to_key(object)
object.GetIdentityHash()
end
def [](v8_object)
super if v8_object.is_a?(V8::C::Object)
end
@ruby_idmap ||= Ref::WeakValueMap.new
end
end
end

View File

@ -9,18 +9,15 @@ class V8::Conversion
class MethodCache
def initialize
@map = {}
@map = Ref::WeakValueMap.new
end
def [](method)
weakref = @map[method.to_s]
weakref.__getobj__ if weakref
rescue WeakRef::RefError
nil #template was garbage collected, so no mapping
@map[method.to_s]
end
def []=(method, template)
@map[method.to_s] = WeakRef.new(template)
@map[method.to_s] = template
end
end

View File

@ -1,4 +1,3 @@
require 'weakref'
module V8
module Util
module Weakcell
@ -11,19 +10,17 @@ module V8
class Storage
def access(&block)
if @ref
@ref.__getobj__
@ref.object || populate(block)
else
populate(block)
end
rescue WeakRef::RefError
populate(block)
end
private
def populate(block)
occupant = block.call()
@ref = WeakRef.new(occupant)
@ref = Ref::WeakReference.new(occupant)
return occupant
end
end

View File

@ -15,4 +15,6 @@ Gem::Specification.new do |gem|
gem.extensions = ["ext/v8/extconf.rb"]
gem.require_paths = ["lib", "ext"]
gem.version = V8::VERSION
gem.add_dependency 'ref'
end