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:
parent
1a93c34b07
commit
eb87ceb340
3 changed files with 37 additions and 23 deletions
|
@ -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() {
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue