1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00
therubyracer/ext/v8/external.h
2015-07-07 20:32:55 -05:00

48 lines
1.5 KiB
C++

// -*- mode: c++ -*-
#ifndef EXTERNAL_H
#define EXTERNAL_H
namespace rr {
class External : public Ref<v8::External> {
public:
static void Init();
static VALUE New(VALUE self, VALUE isolate, VALUE object);
static VALUE Value(VALUE self);
inline External(VALUE value) : Ref<v8::External>(value) {}
inline External(v8::Isolate* isolate, v8::Handle<v8::External> handle) :
Ref<v8::External>(isolate, handle) {}
inline External(v8::Isolate* isolate, v8::Handle<v8::Value> value) :
External(isolate, v8::Handle<v8::External>::Cast<v8::Value>(value)) {}
struct Container {
Container(VALUE v) : object(v) {}
v8::Global<v8::External>* global;
VALUE object;
};
/**
* Implements a v8::WeakCallbackInfo<Container>::Callback with all
* of its idiosyncracies. It happens in two passes. In the first
* pass, you are required to only reset the weak reference. In the
* second pass, you can actually do your cleanup. In this case, we
* schedule the referenced Ruby object to be released in the next
* Ruby gc pass.
*/
static void release(const v8::WeakCallbackInfo<Container>& info) {
Container* container(info.GetParameter());
if (info.IsFirstPass()) {
container->global->Reset();
info.SetSecondPassCallback(&release);
} else {
Isolate isolate(info.GetIsolate());
isolate.scheduleReleaseObject(container->object);
delete container;
}
}
};
}
#endif /* EXTERNAL_H */