#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: class Queue { public: Queue(); void Enqueue(void* phantom); void* Dequeue(); private: struct Node { Node(void* val ) : value(val), next(NULL) { } void* value; Node* next; }; Node* first; // for producer only Node* divider; Node* last; }; static void Finalize(void* phantom); static void Drain(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; } v8::Handle GetHandle() {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); } virtual ~Holder() { handle.Dispose(); } protected: VALUE value; v8::Persistent handle; static void enqueue(Holder* holder) { holder->value = Qnil; GC::Finalize(holder); } }; Ref(Holder* holder) { this->holder = holder; }; Holder* holder; }; class Phantom : public Ref { public: inline Phantom(void* reference) : Ref((Ref::Holder*)reference) {} inline bool NotNull() { return this->holder != NULL; } inline void destroy() { delete holder; } }; class Context : public Ref { public: static void Init(); static VALUE New(VALUE self); static VALUE Enter(VALUE self); static VALUE Exit(VALUE self); private: inline Context(VALUE value) : Ref(value) {} }; class Script : public Ref { public: static void Init(); static VALUE New(VALUE klass, VALUE source, VALUE filename); static VALUE Run(VALUE self); private: inline Script(VALUE value) : Ref(value) {} }; class String: public Ref { public: static void Init(); static VALUE New(VALUE self, VALUE value); static VALUE Utf8Value(VALUE self); inline String(VALUE value) : Ref(value) {} virtual operator v8::Handle(); static VALUE ToRuby(v8::Handle value); private: static VALUE Class; }; class V8 { public: static void Init(); static VALUE IdleNotification(VALUE self); }; class ClassBuilder { public: ClassBuilder(const char* name, VALUE superclass = rb_cObject); ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE)); ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE)); ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE)); ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE)); ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE)); ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE)); inline operator VALUE() {return this->value;} private: VALUE value; }; } #endif