mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
extract v8 handle objects into a payload wrapper so that it can be detached separately
This commit is contained in:
parent
edc8eb7086
commit
56359f4bf3
2 changed files with 33 additions and 14 deletions
|
@ -8,14 +8,25 @@ using namespace v8;
|
||||||
* Creates a new Persistent storage cell for `handle`
|
* Creates a new Persistent storage cell for `handle`
|
||||||
* so that we can reference it from Ruby.
|
* so that we can reference it from Ruby.
|
||||||
*/
|
*/
|
||||||
v8_handle::v8_handle(Handle<void> handle) : handle(Persistent<void>::New(handle)) {
|
v8_handle::v8_handle(Handle<void> object) {
|
||||||
this->weakref_callback = Qnil;
|
this->weakref_callback = Qnil;
|
||||||
this->weakref_callback_parameters = Qnil;
|
this->weakref_callback_parameters = Qnil;
|
||||||
this->dead = false;
|
this->dead = false;
|
||||||
|
this->payload = new Payload(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
v8_handle::~v8_handle() {}
|
v8_handle::~v8_handle() {}
|
||||||
|
|
||||||
|
v8_handle::Payload::Payload(Handle<void> object) {
|
||||||
|
handle = Persistent<void>::New(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
v8_handle::Payload::~Payload() {}
|
||||||
|
void v8_handle::Payload::release() {
|
||||||
|
handle.Dispose();
|
||||||
|
handle.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/**
|
/**
|
||||||
* Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected
|
* Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected
|
||||||
|
@ -37,8 +48,8 @@ namespace {
|
||||||
* Deallocates this handle. This function is invoked on Zombie handles after they have
|
* Deallocates this handle. This function is invoked on Zombie handles after they have
|
||||||
* been released from V8 and finally
|
* been released from V8 and finally
|
||||||
*/
|
*/
|
||||||
void v8_handle_free(v8_handle* handle) {
|
void v8_handle_free(v8_handle::Payload* payload) {
|
||||||
delete handle;
|
delete payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,8 +60,8 @@ namespace {
|
||||||
*/
|
*/
|
||||||
void v8_handle_enqueue(v8_handle* handle) {
|
void v8_handle_enqueue(v8_handle* handle) {
|
||||||
handle->dead = true;
|
handle->dead = true;
|
||||||
VALUE zombie = Data_Wrap_Struct(rr_v8_handle_class(), 0, v8_handle_free, handle);
|
VALUE payload = Data_Wrap_Struct(rb_cObject, 0, v8_handle_free, handle->payload);
|
||||||
rb_ary_unshift(handle_queue, zombie);
|
rb_ary_unshift(handle_queue, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,10 +74,9 @@ namespace {
|
||||||
*/
|
*/
|
||||||
void v8_handle_dequeue(GCType type, GCCallbackFlags flags) {
|
void v8_handle_dequeue(GCType type, GCCallbackFlags flags) {
|
||||||
for (VALUE handle = rb_ary_pop(handle_queue); RTEST(handle); handle = rb_ary_pop(handle_queue)) {
|
for (VALUE handle = rb_ary_pop(handle_queue); RTEST(handle); handle = rb_ary_pop(handle_queue)) {
|
||||||
v8_handle* dead = NULL;
|
v8_handle::Payload* payload = NULL;
|
||||||
Data_Get_Struct(handle, struct v8_handle, dead);
|
Data_Get_Struct(handle, struct v8_handle::Payload, payload);
|
||||||
dead->handle.Dispose();
|
payload->release();
|
||||||
dead->handle.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +112,9 @@ namespace {
|
||||||
rb_funcall(callback, rb_intern("call"), 2, self, parameters);
|
rb_funcall(callback, rb_intern("call"), 2, self, parameters);
|
||||||
}
|
}
|
||||||
value.Dispose();
|
value.Dispose();
|
||||||
handle->handle.Dispose();
|
handle->payload->release();
|
||||||
handle->handle.Clear();
|
// handle->handle.Dispose();
|
||||||
|
// handle->handle.Clear();
|
||||||
handle->dead = true;
|
handle->dead = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,18 @@
|
||||||
* class for all of the low-level proxies that reference into V8
|
* class for all of the low-level proxies that reference into V8
|
||||||
*/
|
*/
|
||||||
struct v8_handle {
|
struct v8_handle {
|
||||||
|
|
||||||
|
struct Payload {
|
||||||
|
Payload(v8::Handle<void> object);
|
||||||
|
virtual ~Payload();
|
||||||
|
void release();
|
||||||
|
v8::Persistent<void> handle;
|
||||||
|
};
|
||||||
|
|
||||||
v8_handle(v8::Handle<void> object);
|
v8_handle(v8::Handle<void> object);
|
||||||
virtual ~v8_handle();
|
virtual ~v8_handle();
|
||||||
|
|
||||||
v8::Persistent<void> handle;
|
Payload* payload;
|
||||||
bool dead;
|
bool dead;
|
||||||
VALUE weakref_callback;
|
VALUE weakref_callback;
|
||||||
VALUE weakref_callback_parameters;
|
VALUE weakref_callback_parameters;
|
||||||
|
@ -23,7 +31,7 @@ void rr_init_handle();
|
||||||
v8_handle* rr_v8_handle_raw(VALUE value);
|
v8_handle* rr_v8_handle_raw(VALUE value);
|
||||||
|
|
||||||
template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) {
|
template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) {
|
||||||
return (v8::Persistent<T>&)(rr_v8_handle_raw(value)->handle);
|
return (v8::Persistent<T>&)(rr_v8_handle_raw(value)->payload->handle);
|
||||||
}
|
}
|
||||||
VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle);
|
VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle);
|
||||||
VALUE rr_v8_handle_class();
|
VALUE rr_v8_handle_class();
|
||||||
|
|
Loading…
Add table
Reference in a new issue