rubyjs / therubyracer

Embed the V8 Javascript Interpreter into Ruby
1.66k stars 193 forks source link

Different instances of same method not converted properly? #260

Closed palfvin closed 11 months ago

palfvin commented 11 years ago

I posted this on stackoverflow a few days ago, but haven't gotten any responses, so with apologies if I'm misunderstanding something, I'm posted it here as a potential issue.

It seems that when different instances of the same method are put into a V8::Context, all instances beyond the first are treated as identical to the first, at least as far as I've been able to determine. Here's some sample code, including the workaround I'm using of wrapping such methods in a lambda.


require 'v8'

class C

  attr_reader :foo

  def initialize(foo)
    @foo = foo
  end

end

m1 = C.new('bar1').method(:foo)
m2 = C.new('bar2').method(:foo)

cxt = V8::Context.new
cxt['m1'] = m1
cxt['m2'] = m2
cxt['m2l'] = lambda {m2.call}

puts "#{m1.call}, #{cxt.eval('m1()')}"
# => bar1, bar1

print "#{m2.call}, #{cxt.eval('m2()')}, #{cxt.eval('m2l()')}"
# => bar2, bar1 (!!), bar2

I've tried studying the code, but while I'm beginning to grock the Ruby, the C++ is beyond me at this point and I'm wondering if the explanation resides there.

Finally, this behavior persists across different contexts as well. That is, subsequent instances of the same method, even if stored in a different context, behave as the first.

Update: See http://stackoverflow.com/questions/16847402/method-closure-not-seeming-to-work-in-therubyracer?noredirect=1#comment24781543_16847402 for some additional information. Apparently, earlier versions of Ruby and libv8 gave different, if still not expected, results.

phluid61 commented 11 years ago

Appears to be related to weak references. Something in @v8_idmap is not updating (or possibly the key in said map is being persisted incorrectly.) It was more apparent in the code example given in the stackoverflow question, by inspecting the Context at each iteration.

cowboyd commented 11 years ago

This is a duplicate of #176. Recommended fix is upgrade to 2.0

palfvin commented 11 years ago

Umm, as reported as a comment on the StackOverflow question above, the problem was reproduced by someone else with Ruby 2.0.0 and libv8-3.11.8.17. Was that the 2.0 you were referring to?

cowboyd commented 11 years ago

Oops, I misread the issue. I was under the impression from mu too short that upgrading to 2.0 fixed the problem.

palfvin commented 11 years ago

Note also that the GC workaround reported by Matty K was tested on 2.0 as well.