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

only use 'ref' gem for MRI

This commit is contained in:
Charles Lowell 2012-08-11 12:26:14 -05:00
parent 8a5652fb02
commit 8ec7ba11e7
7 changed files with 76 additions and 36 deletions

View file

@ -7,7 +7,7 @@ namespace rr {
ID Backref::object;
void Backref::Init() {
Storage = rb_eval_string("Ref::WeakReference");
Storage = rb_eval_string("V8::Weak::Ref");
rb_gc_register_address(&Storage);
_new = rb_intern("new");
object = rb_intern("object");

View file

@ -1,8 +1,7 @@
require "v8/version"
require 'ref'
require 'v8/weak'
require 'v8/init'
require 'v8/util/weakcell'
require 'v8/error'
require 'v8/conversion/fundamental'
require 'v8/conversion/indentity'

View file

@ -1,6 +1,6 @@
class V8::Conversion
module Code
include V8::Util::Weakcell
include V8::Weak::Cell
def to_v8
fn = to_template.GetFunction()

View file

@ -21,11 +21,11 @@ class V8::Conversion
end
def v8_idmap
@v8_idmap ||= Ref::WeakValueMap.new
@v8_idmap ||= V8::Weak::WeakValueMap.new
end
def rb_idmap
@ruby_idmap ||= Ref::WeakValueMap.new
@ruby_idmap ||= V8::Weak::WeakValueMap.new
end
end
end

View file

@ -9,7 +9,7 @@ class V8::Conversion
class MethodCache
def initialize
@map = Ref::WeakValueMap.new
@map = V8::Weak::WeakValueMap.new
end
def [](method)

View file

@ -1,29 +0,0 @@
module V8
module Util
module Weakcell
def weakcell(name, &block)
unless storage = instance_variable_get("@#{name}")
storage = instance_variable_set("@#{name}", Storage.new)
end
storage.access(&block)
end
class Storage
def access(&block)
if @ref
@ref.object || populate(block)
else
populate(block)
end
end
private
def populate(block)
occupant = block.call()
@ref = Ref::WeakReference.new(occupant)
return occupant
end
end
end
end
end

70
lib/v8/weak.rb Normal file
View file

@ -0,0 +1,70 @@
module V8
module Weak
# weak refs are broken on MRI 1.9 and merely slow on 1.8
# so we mitigate this by using the 'ref' gem. However, this
# only mitigates the problem. Under heavy load, you will still
# get different or terminated objects being returned. bad stuff
#
# for other platforms we just use the stdlib 'weakref'
# implementation
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby'
require 'ref'
Ref = ::Ref::WeakReference
WeakValueMap = ::Ref::WeakValueMap
else
require 'weakref'
class Ref
def initialize(object)
@ref = ::WeakRef.new(object)
end
def object
@ref.__getobj__
rescue ::WeakRef::RefError
nil
end
end
class WeakValueMap
def initialize
@values = {}
end
def [](key)
if ref = @values[key]
ref.object
end
end
def []=(key, value)
@values[key] = V8::Weak::Ref.new(value)
end
end
end
module Cell
def weakcell(name, &block)
unless storage = instance_variable_get("@#{name}")
storage = instance_variable_set("@#{name}", Storage.new)
end
storage.access(&block)
end
class Storage
def access(&block)
if @ref
@ref.object || populate(block)
else
populate(block)
end
end
private
def populate(block)
occupant = block.call()
@ref = V8::Weak::Ref.new(occupant)
return occupant
end
end
end
end
end