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:
parent
8a5652fb02
commit
8ec7ba11e7
7 changed files with 76 additions and 36 deletions
|
@ -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");
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class V8::Conversion
|
||||
module Code
|
||||
include V8::Util::Weakcell
|
||||
include V8::Weak::Cell
|
||||
|
||||
def to_v8
|
||||
fn = to_template.GetFunction()
|
||||
|
|
|
@ -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
|
|
@ -9,7 +9,7 @@ class V8::Conversion
|
|||
|
||||
class MethodCache
|
||||
def initialize
|
||||
@map = Ref::WeakValueMap.new
|
||||
@map = V8::Weak::WeakValueMap.new
|
||||
end
|
||||
|
||||
def [](method)
|
||||
|
|
|
@ -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
70
lib/v8/weak.rb
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue