1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

don't use rb_block_call() since it is not in rbx

This commit is contained in:
Charles Lowell 2012-06-20 04:53:47 -05:00
parent 1a93c34b07
commit eb87ceb340
3 changed files with 37 additions and 23 deletions

View file

@ -4,27 +4,42 @@ namespace rr {
VALUE Backref::Storage; VALUE Backref::Storage;
ID Backref::_new; ID Backref::_new;
ID Backref::access; ID Backref::object;
void Backref::Init() { void Backref::Init() {
Storage = rb_eval_string("require 'v8/util/weakcell'; V8::Util::Weakcell::Storage"); Storage = rb_eval_string("Ref::WeakReference");
rb_gc_register_address(&Storage); rb_gc_register_address(&Storage);
_new = rb_intern("new"); _new = rb_intern("new");
access = rb_intern("access"); object = rb_intern("object");
} }
Backref::Backref() { Backref::Backref(VALUE initial) {
this->storage = rb_funcall(Storage, _new, 0); allocate(initial);
this->storage = rb_funcall(Storage, _new, 1, initial);
rb_gc_register_address(&storage); rb_gc_register_address(&storage);
} }
Backref::~Backref() { Backref::~Backref() {
deallocate();
}
void Backref::allocate(VALUE data) {
this->storage = rb_funcall(Storage, _new, 1, data);
rb_gc_register_address(&storage);
}
void Backref::deallocate() {
rb_gc_unregister_address(&storage); rb_gc_unregister_address(&storage);
} }
VALUE Backref::get(VALUE (*populate)(ANYARGS), VALUE data) { VALUE Backref::get() {
VALUE args[0]; return rb_funcall(storage, object, 0);
return rb_block_call(storage, access, 0, args, populate, data); }
VALUE Backref::set(VALUE data) {
deallocate();
allocate(data);
return data;
} }
v8::Handle<v8::Value> Backref::toExternal() { v8::Handle<v8::Value> Backref::toExternal() {

View file

@ -135,29 +135,25 @@ Object::operator VALUE() {
if (handle.IsEmpty()) { if (handle.IsEmpty()) {
return Qnil; return Qnil;
} }
VALUE value;
Backref* backref; Backref* backref;
v8::Local<v8::String> key(v8::String::NewSymbol("rr::Backref")); v8::Local<v8::String> key(v8::String::NewSymbol("rr::Backref"));
v8::Local<v8::Value> external = handle->GetHiddenValue(key); v8::Local<v8::Value> external = handle->GetHiddenValue(key);
VALUE value;
if (external.IsEmpty()) { if (external.IsEmpty()) {
backref = new Backref(); value = downcast();
backref = new Backref(value);
handle->SetHiddenValue(key, backref->toExternal()); handle->SetHiddenValue(key, backref->toExternal());
} else { } else {
backref = (Backref*)v8::External::Unwrap(external); backref = (Backref*)v8::External::Unwrap(external);
value = backref->get();
if (!RTEST(value)) {
value = downcast();
backref->set(value);
}
} }
return backref->get((VALUE (*)(...))&toVALUE, Data_Wrap_Struct(rb_cObject, 0, 0, this));
return value; return value;
} }
VALUE Object::toVALUE(VALUE yield, VALUE wrapper) {
if (!RTEST(wrapper)) {
fprintf(stderr, "WTF?");
}
Object* object(NULL);
Data_Get_Struct(wrapper, class Object, object);
return object->downcast();
}
VALUE Object::downcast() { VALUE Object::downcast() {
if (handle->IsFunction()) { if (handle->IsFunction()) {
return Function((v8::Handle<v8::Function>) v8::Function::Cast(*handle)); return Function((v8::Handle<v8::Function>) v8::Function::Cast(*handle));

View file

@ -206,16 +206,19 @@ template <class T> VALUE Ref<T>::Class;
class Backref { class Backref {
public: public:
static void Init(); static void Init();
Backref(); Backref(VALUE value);
virtual ~Backref(); virtual ~Backref();
VALUE get(VALUE (*populate)(ANYARGS), VALUE data); VALUE get();
VALUE set(VALUE value);
v8::Handle<v8::Value> toExternal(); v8::Handle<v8::Value> toExternal();
static void release(v8::Persistent<v8::Value> handle, void* data); static void release(v8::Persistent<v8::Value> handle, void* data);
private: private:
void allocate(VALUE data);
void deallocate();
VALUE storage; VALUE storage;
static VALUE Storage; static VALUE Storage;
static ID _new; static ID _new;
static ID access; static ID object;
}; };
class Handles { class Handles {
public: public: