diff --git a/ext/v8/v8_weakref.cpp b/ext/v8/v8_weakref.cpp index 919c84b..2ff949f 100644 --- a/ext/v8/v8_weakref.cpp +++ b/ext/v8/v8_weakref.cpp @@ -5,19 +5,33 @@ using namespace v8; v8_weakref::v8_weakref(VALUE object) { this->external = Persistent::New(External::New((void *)this)); - this->external.MakeWeak(this, v8_weakref_finalize); + this->external.MakeWeak(this, v8_weakref_dispose); this->set(object); } void v8_weakref::set(VALUE value) { this->object_id = rb_obj_id(value); + VALUE self = Data_Wrap_Struct(rb_cObject, 0, 0, this); + VALUE finalizer = rb_proc_new((VALUE (*)(...))v8_weakref_finalize, self); + rb_funcall(v8_weakref_objectspace(), rb_intern("define_finalizer"), 2, value, finalizer); } VALUE v8_weakref::get() { - return rb_rescue((VALUE (*)(...))v8_weakref_id2ref, this->object_id, (VALUE (*)(...))v8_weakref_nil, Qnil); + if (this->object_id) { + return rb_rescue((VALUE (*)(...))v8_weakref_id2ref, this->object_id, (VALUE (*)(...))v8_weakref_nil, Qnil); + } else { + return Qnil; + } } -void v8_weakref_finalize(Persistent value, void* weakref) { +VALUE v8_weakref_finalize(VALUE self, VALUE object_id) { + v8_weakref* weakref = 0; + Data_Get_Struct(self, struct v8_weakref, weakref); + weakref->object_id = Qnil; + return Qnil; +} + +void v8_weakref_dispose(Persistent value, void* weakref) { value.Dispose(); value.Clear(); delete (v8_weakref*)weakref; @@ -27,7 +41,11 @@ VALUE v8_weakref_nil(VALUE nil, VALUE exception) { return nil; } -VALUE v8_weakref_id2ref(VALUE id) { - return rb_funcall(rb_const_get(rb_cObject, rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, id); +VALUE v8_weakref_objectspace() { + return rb_const_get(rb_cObject, rb_intern("ObjectSpace")); +} + +VALUE v8_weakref_id2ref(VALUE id) { + return rb_funcall(v8_weakref_objectspace(), rb_intern("_id2ref"), 1, id); } diff --git a/ext/v8/v8_weakref.h b/ext/v8/v8_weakref.h index 21c1218..3aa3091 100644 --- a/ext/v8/v8_weakref.h +++ b/ext/v8/v8_weakref.h @@ -15,7 +15,9 @@ struct v8_weakref { v8::Persistent external; }; -void v8_weakref_finalize(v8::Persistent value, void* weakref); +void v8_weakref_dispose(v8::Persistent value, void* weakref); +VALUE v8_weakref_finalize(VALUE self, VALUE object_id); +VALUE v8_weakref_objectspace(); VALUE v8_weakref_nil(VALUE nil, VALUE exception); VALUE v8_weakref_id2ref(VALUE id);