Class: V8::Portal::Proxies

Inherits:
Object show all
Defined in:
lib/v8/portal/proxies.rb

Defined Under Namespace

Classes: ClearJSProxy, ClearRubyProxy

Constant Summary collapse

DoubleProxyError =
Class.new(StandardError)

Instance Method Summary collapse

Constructor Details

#initializeProxies

Returns a new instance of Proxies.



5
6
7
8
9
10
11
12
# File 'lib/v8/portal/proxies.rb', line 5

def initialize
  @js_proxies_rb2js = {}
  @js_proxies_js2rb = {}
  @rb_proxies_rb2js = {}
  @rb_proxies_js2rb = {}
  @clear_js_proxy = ClearJSProxy.new(@js_proxies_rb2js, @js_proxies_js2rb)
  @clear_rb_proxy = ClearRubyProxy.new(@rb_proxies_rb2js, @rb_proxies_js2rb)
end

Instance Method Details

#empty?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/v8/portal/proxies.rb', line 101

def empty?
  js_empty? && rb_empty?
end

#js2rb(js) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/v8/portal/proxies.rb', line 14

def js2rb(js)
  if rb = js_proxy_2_rb_object(js)
    return rb
  elsif rb = js_object_2_rb_proxy(js)
    return rb
  else
    proxy = block_given? ? yield(js) : Object.new
    register_ruby_proxy proxy, :for => js if proxy && js && js.kind_of?(V8::C::Handle)
    return proxy
  end
end

#js_empty?Boolean

Returns:

  • (Boolean)


93
94
95
# File 'lib/v8/portal/proxies.rb', line 93

def js_empty?
  @js_proxies_rb2js.empty? && @js_proxies_js2rb.empty?
end

#js_object_2_rb_proxy(object) ⇒ Object

Looks up the Ruby proxy for an object that is natively JavaScript

Parameters:

  • object (V8::C::Handle)

    the JavaScript whose proxy we want

Returns:

  • (Object)

    the Ruby proxy for ‘object`



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/v8/portal/proxies.rb', line 73

def js_object_2_rb_proxy(object)
  if id = @rb_proxies_js2rb[object]
    ObjectSpace._id2ref id
  end
rescue RangeError => e
  # sometimes, the Ruby proxy has been garbage collected, but
  # the finalizer which runs has not been called. That's OK
  # we just clear out the entry, and return nil so that a new
  # proxy can be created.
  @clear_rb_proxy.call(id)
  return nil
end

#js_proxy_2_rb_object(proxy) ⇒ Object

Look up a natively Ruby object given its JavaScript proxy

Parameters:

  • proxy (V8::C::Handle)

    the JavaScript proxy

Returns:

  • (Object)

    the Ruby object represented by ‘proxy`



58
59
60
# File 'lib/v8/portal/proxies.rb', line 58

def js_proxy_2_rb_object(proxy)
  @js_proxies_js2rb[proxy]
end

#rb2js(rb) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/v8/portal/proxies.rb', line 26

def rb2js(rb)
  if js = rb_proxy_2_js_object(rb)
    return js
  elsif js = rb_object_2_js_proxy(rb)
    return js
  else
    proxy = block_given? ? yield(rb) : V8::C::Object::New()
    register_javascript_proxy proxy, :for => rb unless @js_proxies_rb2js[rb]
    return proxy
  end
end

#rb_empty?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/v8/portal/proxies.rb', line 97

def rb_empty?
  @rb_proxies_rb2js.empty? && @rb_proxies_js2rb.empty?
end

#rb_object_2_js_proxy(object) ⇒ V8::C::Handle

Lookup the JavaScript proxy for a natively Ruby object

Parameters:

  • object (Object)

    the Ruby object

Returns:

  • (V8::C::Handle)

    the JavaScript proxy representing ‘object`



51
52
53
# File 'lib/v8/portal/proxies.rb', line 51

def rb_object_2_js_proxy(object)
  @js_proxies_rb2js[object]
end

#rb_proxy_2_js_object(proxy) ⇒ V8::C::Handle

Looks up a native JavaScript object by its Ruby proxy

Parameters:

  • proxy (Object)

    the Ruby proxy

Returns:

  • (V8::C::Handle)

    the native JavaScript object



89
90
91
# File 'lib/v8/portal/proxies.rb', line 89

def rb_proxy_2_js_object(proxy)
  @rb_proxies_rb2js[proxy.object_id]
end

#register_javascript_proxy(proxy, options = {}) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'lib/v8/portal/proxies.rb', line 38

def register_javascript_proxy(proxy, options = {})
  target = options[:for] or fail ArgumentError, "must specify the object that you're proxying with the :for => param"
  fail ArgumentError, "javascript proxy must be a V8::C::Handle, not #{proxy.class}" unless proxy.kind_of?(V8::C::Handle)
  fail DoubleProxyError, "target already has a registered proxy" if @js_proxies_rb2js[target]

  @js_proxies_js2rb[proxy] = target
  @js_proxies_rb2js[target] = proxy
  proxy.MakeWeak(nil, @clear_js_proxy)
end

#register_ruby_proxy(proxy, options = {}) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/v8/portal/proxies.rb', line 62

def register_ruby_proxy(proxy, options = {})
  target = options[:for] or fail ArgumentError, "must specify the object that you're proxying with the :for => param"
  fail ArgumentError, "'#{proxy.inspect}' is not a Handle to an actual V8 object" unless target.kind_of?(V8::C::Handle)
  @rb_proxies_rb2js[proxy.object_id] = target
  @rb_proxies_js2rb[target] = proxy.object_id
  ObjectSpace.define_finalizer(proxy, @clear_rb_proxy)
end