Once I store a method in a V8::Context, all subsequent instances of that method stored in any context under any name behave like the initial one (i.e. as if the original instance had been stored again).
I tried to isolate/demonstrate the problem with the following:
require 'V8'
class TestClass
def test_method
self.inspect
end
end
(1..2).each do |cxt_i|
cxt = V8::Context.new
[:test_method, :test_method2].each_with_index do |method_name, method_i|
method = TestClass.new.method(:test_method)
cxt[method_name.to_s] = method
script = method_name.to_s+'()'
puts "Context #{cxt_i}, method #{method_i+1} result is #{method.call}, V8 returns #{cxt.eval(script)}"
end
end
Which produces the following output:
Context 1, method 1 result is #<TestClass:0x007fce2419cdb0>, V8 returns #<TestClass:0x007fce2419cdb0>
Context 1, method 2 result is #<TestClass:0x007fce2419b780>, V8 returns #<TestClass:0x007fce2419cdb0>
Context 2, method 1 result is #<TestClass:0x007fce2419abc8>, V8 returns #<TestClass:0x007fce2419cdb0>
Context 2, method 2 result is #<TestClass:0x007fce24199a98>, V8 returns #<TestClass:0x007fce2419cdb0>
It's a weak reference issue. By inserting a GC.start
inside the inner loop, we force the weak references in the V8 context to be garbage collected. Slows it down immensely though.
require 'v8'
class TestClass
def test_method
self.inspect
end
end
(1..2).each do |cxt_i|
cxt = V8::Context.new
[:test_method, :test_method2].each_with_index do |method_name, method_i|
method = TestClass.new.method(:test_method)
cxt[method_name.to_s] = method
script = method_name.to_s+'()'
puts "Context #{cxt_i}, method #{method_i+1} result is #{method.call}, V8 returns #{cxt.eval(script)}"
GC.start # <<<<=========
end
end
Output:
Context 1, method 1 result is #<TestClass:0x007f8f13a26cd8>, V8 returns #<TestClass:0x007f8f13a26cd8>
Context 1, method 2 result is #<TestClass:0x007f8f135cca48>, V8 returns #<TestClass:0x007f8f135cca48>
Context 2, method 1 result is #<TestClass:0x007f8f135ceac8>, V8 returns #<TestClass:0x007f8f135ceac8>
Context 2, method 2 result is #<TestClass:0x007f8f135cdbf0>, V8 returns #<TestClass:0x007f8f135cdbf0>
ruby -v is ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-linux]
, libv8 is 3.11.8.17 x86_64-linux