rubyjs / therubyracer

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

Allow registering Ruby callbacks for V8 objects. #387

Open cowboyd opened 9 years ago

cowboyd commented 9 years ago

This allows Ruby code to listen directly for when V8 object is garbage collected. This is done with the SetWeak method which can be invoked on any handle. This handle is now weak, and the object that it references can be garbage collected by V8 even if the Ruby object is still in scope. E.g.

  v8_object.SetWeak(method_that_generates_callable)

Later, once v8_object has been gc'd, the finalizer will be enqueued into an internal data structure that can be accessed via the isolate's __EachV8Finalizer

  isolate.__EachV8Finalizer__ do |finalizer|
    finalizer.call()
  end

This also adds the ability to capture a new, persistent reference to an existing handle via the V8::C::Handle::New() method. For example, suppose we have the following:

object = V8::C::Object::New(isolate)

The object variable represents a persistent reference to this V8 object, and it cannot be garbage collected by V8 as long as this Ruby object is reachable. But we can add another reference:

second = V8::C::Handle::New(object)
second.class #=> V8::C::Object

Notice that even though we are using the handle api, the type of the returned object is the same as the original reference.

This V8 object cannot be garbage collected until both of the Ruby objects are either no longer reachable, or are set to be weak.