mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
create a context with a Ruby object as its scope
This commit is contained in:
parent
a39114a6bd
commit
d8579acf28
4 changed files with 59 additions and 8 deletions
|
@ -19,4 +19,5 @@ require 'v8/access/indices'
|
||||||
require 'v8/access'
|
require 'v8/access'
|
||||||
require 'v8/context'
|
require 'v8/context'
|
||||||
require 'v8/object'
|
require 'v8/object'
|
||||||
require 'v8/array'
|
require 'v8/array'
|
||||||
|
require 'v8/util/weakcell'
|
|
@ -2,10 +2,24 @@ module V8
|
||||||
class Context
|
class Context
|
||||||
attr_reader :native, :conversion, :access
|
attr_reader :native, :conversion, :access
|
||||||
|
|
||||||
def initialize
|
def initialize(options = {})
|
||||||
@native = V8::C::Context::New()
|
|
||||||
@conversion = Conversion.new
|
@conversion = Conversion.new
|
||||||
@access = Access.new
|
@access = Access.new
|
||||||
|
if global = options[:with]
|
||||||
|
V8::C::Locker() do
|
||||||
|
V8::C::HandleScope() do
|
||||||
|
tmp = V8::C::Context::New()
|
||||||
|
tmp.Enter()
|
||||||
|
global_template = global.to_v8_template
|
||||||
|
tmp.Exit()
|
||||||
|
@native = V8::C::Context::New(nil, global_template)
|
||||||
|
enter { link global, @native.Global() }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@native = V8::C::Context::New()
|
||||||
|
end
|
||||||
|
yield self if block_given?
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_ruby(v8_object)
|
def to_ruby(v8_object)
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
class V8::Conversion
|
class V8::Conversion
|
||||||
module Object
|
module Object
|
||||||
def to_v8
|
def to_v8
|
||||||
template = V8::C::ObjectTemplate::New()
|
object = to_v8_template.NewInstance()
|
||||||
template.SetNamedPropertyHandler(Get, Set, nil, nil, nil, V8::C::External::New(self))
|
V8::Context.link self, object
|
||||||
instance = template.NewInstance()
|
return object
|
||||||
V8::Context.link self, instance
|
end
|
||||||
return instance
|
|
||||||
|
def to_v8_template
|
||||||
|
V8::C::ObjectTemplate::New().tap do |template|
|
||||||
|
template.SetNamedPropertyHandler(Get, Set, nil, nil, nil, V8::C::External::New(self))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_ruby
|
def to_ruby
|
||||||
|
|
32
lib/v8/util/weakcell.rb
Normal file
32
lib/v8/util/weakcell.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require 'weakref'
|
||||||
|
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.__getobj__
|
||||||
|
else
|
||||||
|
populate(block)
|
||||||
|
end
|
||||||
|
rescue RefError
|
||||||
|
populate(block)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def populate(block)
|
||||||
|
occupant = block.call()
|
||||||
|
@ref = WeakRef.new(occupant)
|
||||||
|
return occupant
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue