#ifndef THE_RUBY_RACER #define THE_RUBY_RACER #include #include namespace rr { class Value { public: Value(v8::Handle handle); Value(VALUE value); virtual operator VALUE(); virtual operator v8::Handle(); static void Init(); protected: v8::Handle value; VALUE object; }; class GC { public: static void Push(VALUE phantom); static void Pop(v8::GCType type, v8::GCCallbackFlags flags); static void Init(); }; /** * A Reference to a V8 managed object */ template class Ref { public: Ref(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() { return holder->handle; } static Ref create(v8::Handle handle, VALUE klass) { return Ref(new Holder(handle, klass)); } inline v8::Handle operator->() const { return holder->handle; } class Holder { friend class Ref; public: Holder(v8::Handle handle, VALUE klass) { this->handle = v8::Persistent::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); } virtual ~Holder() { handle.Dispose(); rb_gc_unregister_address(&phantom); } protected: VALUE value; VALUE phantom; v8::Persistent handle; static void enqueue(Holder* holder) { holder->value = Qnil; GC::Push(holder->phantom); } }; Ref(Holder* holder) { this->holder = holder; }; Holder* holder; }; class Phantom : public Ref { public: inline Phantom(VALUE value) : Ref(value) {} inline void destroy() { delete holder; } }; class Context : public Ref { public: inline Context(VALUE value) : Ref(value) {} static void Init(); }; class Script : public Ref { public: inline Script(VALUE value) : Ref(value) {} static void Init(); }; class String: public Ref { public: inline String(VALUE value) : Ref(value) {} static VALUE ToRuby(v8::Handle value); static void Init(); }; VALUE defineClass(const char *name, VALUE superclass = rb_cObject); VALUE defineModule(const char *name); } #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