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

114 lines
2.6 KiB
C
Raw Normal View History

#ifndef THE_RUBY_RACER
#define THE_RUBY_RACER
#include <v8.h>
#include <ruby.h>
namespace rr {
2012-05-01 14:53:01 -04:00
2012-05-02 19:15:11 -04:00
class Value {
public:
Value(v8::Handle<v8::Value> handle);
Value(VALUE value);
virtual operator VALUE();
virtual operator v8::Handle<v8::Value>();
2012-05-02 19:15:11 -04:00
static void Init();
protected:
v8::Handle<v8::Value> value;
VALUE object;
};
class GC {
2012-05-02 19:15:11 -04:00
public:
static void Push(VALUE phantom);
static void Pop(v8::GCType type, v8::GCCallbackFlags flags);
2012-05-02 19:15:11 -04:00
static void Init();
};
/**
* A Reference to a V8 managed object
*/
template <class T> class Ref {
public:
Ref<T>(VALUE wrapper) {
Holder* holder = NULL;
Data_Get_Struct(wrapper, class Holder, holder) ;
this->holder = holder;
}
virtual operator VALUE() {
return holder->value;
}
virtual operator v8::Handle<T>() {
return holder->handle;
}
static Ref<T> create(v8::Handle<T> handle, VALUE klass) {
return Ref<T>(new Holder(handle, klass));
}
inline v8::Handle<T> operator->() const { return holder->handle; }
2012-05-02 19:15:11 -04:00
class Holder {
friend class Ref;
2012-05-01 14:53:01 -04:00
public:
2012-05-02 19:15:11 -04:00
Holder(v8::Handle<T> handle, VALUE klass) {
this->handle = v8::Persistent<T>::New(handle);
this->value = Data_Wrap_Struct(klass, 0, &Holder::enqueue, this);
this->phantom = Data_Wrap_Struct(rb_cObject, 0, 0, this);
rb_gc_register_address(&phantom);
2012-05-02 19:15:11 -04:00
}
virtual ~Holder() {
handle.Dispose();
rb_gc_unregister_address(&phantom);
2012-05-02 19:15:11 -04:00
}
protected:
VALUE value;
VALUE phantom;
2012-05-02 19:15:11 -04:00
v8::Persistent<T> handle;
static void enqueue(Holder* holder) {
holder->value = Qnil;
GC::Push(holder->phantom);
2012-05-02 19:15:11 -04:00
}
};
Ref(Holder* holder) {
this->holder = holder;
2012-05-01 14:53:01 -04:00
};
2012-05-02 19:15:11 -04:00
Holder* holder;
};
class Phantom : public Ref<void> {
public:
inline Phantom(VALUE value) : Ref<void>(value) {}
inline void destroy() {
delete holder;
}
};
2012-05-02 19:15:11 -04:00
class Context : public Ref<v8::Context> {
public:
inline Context(VALUE value) : Ref<v8::Context>(value) {}
2012-05-02 19:15:11 -04:00
static void Init();
};
class Script : public Ref<v8::Script> {
public:
inline Script(VALUE value) : Ref<v8::Script>(value) {}
2012-05-02 19:15:11 -04:00
static void Init();
};
2012-05-01 14:53:01 -04:00
class String: public Ref<v8::String> {
public:
inline String(VALUE value) : Ref<v8::String>(value) {}
static VALUE ToRuby(v8::Handle<v8::String> value);
static void Init();
};
2012-05-02 19:15:11 -04:00
VALUE defineClass(const char *name, VALUE superclass = rb_cObject);
VALUE defineModule(const char *name);
}
2012-05-01 14:53:01 -04:00
#define RR_DEFINE_METHOD(klass, name, impl, argc) rb_define_method(klass, name, (VALUE(*)(...))impl, argc)
#define RR_DEFINE_SINGLETON_METHOD(object, name, impl, argc) rb_define_singleton_method(object, name, (VALUE(*)(...))impl, argc)
#endif