#ifndef THE_RUBY_RACER #define THE_RUBY_RACER #include #include #include namespace rr { #define Void(expr) expr; return Qnil; VALUE not_implemented(const char* message); class Equiv { public: Equiv(VALUE val) : value(val) {} inline operator VALUE() {return value;} protected: VALUE value; }; class Bool : public Equiv { public: Bool(VALUE val) : Equiv(val) {} Bool(bool b) : Equiv(b ? Qtrue : Qfalse) {} inline operator bool() {return RTEST(value);} }; class Int : public Equiv { public: Int(VALUE val) : Equiv(val) {} Int(int i) : Equiv(INT2FIX(i)) {} inline operator int() {return RTEST(value) ? NUM2INT(value) : 0;} inline int toInt() {return (int)*this;} }; class UInt32 : public Equiv { public: UInt32(VALUE val) : Equiv(val) {} UInt32(uint32_t ui) : Equiv(UINT2NUM(ui)) {} inline operator uint32_t() {return RTEST(value) ? NUM2UINT(value) : 0;} }; 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 V8 Enum */ template class Enum { public: Enum(VALUE value, T defaultValue = 0) { this->value = value; this->defaultValue = defaultValue; } inline operator T() { return (T)(RTEST(value) ? NUM2INT(value) : defaultValue); } private: VALUE value; T defaultValue; }; /** * A Reference to a V8 managed object */ template class Ref { public: Ref(VALUE value) { this->value = value; } Ref(v8::Handle handle) { this->handle = handle; } virtual operator VALUE() const { return (new Holder(handle, Class))->value; } virtual operator v8::Handle() const { if (RTEST(this->value)) { Holder* holder = NULL; Data_Get_Struct(this->value, class Holder, holder); return holder->handle; } else { return v8::Handle(); } } inline v8::Handle operator->() const { return *this;} inline v8::Handle GetHandle() const { return *this;} inline v8::Handle operator*() const {return *this;} static v8::Handle * array(VALUE argv, std::vector< v8::Handle >& v) { for (uint32_t i = 0; i < v.size(); i++) { v[i] = Ref(rb_ary_entry(argv, i)); } return &v[0]; } 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); } }; VALUE value; v8::Handle handle; static VALUE Class; }; template VALUE Ref::Class; class Handles { public: static void Init(); static VALUE HandleScope(int argc, VALUE* argv, VALUE self); private: static VALUE SetupAndCall(int* state, VALUE code); static VALUE DoCall(VALUE code); }; class Phantom { public: inline Phantom(void* reference) : holder((Ref::Holder*)reference) {} inline bool NotNull() { return this->holder != NULL; } inline void destroy() { delete holder; } Ref::Holder* holder; }; class Context : public Ref { public: static void Init(); static VALUE New(VALUE self); static VALUE Enter(VALUE self); static VALUE Exit(VALUE self); static VALUE Global(VALUE self); static VALUE DetachGlobal(VALUE self); static VALUE ReattachGlobal(VALUE self, VALUE global); static VALUE GetEntered(VALUE self); static VALUE GetCurrent(VALUE self); static VALUE GetCalling(VALUE self); static VALUE SetSecurityToken(VALUE self, VALUE token); static VALUE UseDefaultSecurityToken(VALUE self); static VALUE GetSecurityToken(VALUE self); static VALUE HasOutOfMemoryException(VALUE self); static VALUE InContext(VALUE self); static VALUE SetData(VALUE self, VALUE data); static VALUE GetData(VALUE self); static VALUE AllowCodeGenerationFromStrings(VALUE self, VALUE allow); static VALUE IsCodeGenerationFromStringsAllowed(VALUE self); inline Context(VALUE value) : Ref(value) {} inline Context(v8::Handle cxt) : Ref(cxt) {} }; class External: public Ref { public: static void Init(); static VALUE New(VALUE self, VALUE data); static VALUE Value(VALUE self); inline External(VALUE value) : Ref(value) {} inline External(v8::Handle ext) : Ref(ext) {} static v8::Handle wrap(VALUE data); static VALUE unwrap(v8::Handle external); private: static void release(v8::Persistent object, void* parameter); struct Data { Data(VALUE data); ~Data(); VALUE value; }; }; class Script : public Ref { public: static void Init(); static VALUE New(VALUE klass, VALUE source, VALUE filename); static VALUE Run(VALUE self); inline Script(VALUE value) : Ref(value) {} inline Script(v8::Handle script) : Ref(script) {} }; class Value : public Ref { public: static void Init(); static VALUE Equals(VALUE self, VALUE other); static VALUE StrictEquals(VALUE self, VALUE other); inline Value(VALUE value) : Ref(value) {} inline Value(v8::Handle value) : Ref(value) {} virtual operator VALUE(); }; class String: public Ref { public: static void Init(); static VALUE New(VALUE self, VALUE value); static VALUE Utf8Value(VALUE self); static VALUE Concat(VALUE self, VALUE left, VALUE right); inline String(VALUE value) : Ref(value) {} inline String(v8::Handle string) : Ref(string) {} }; class PropertyAttribute: public Enum { public: inline PropertyAttribute(VALUE value) : Enum(value, v8::None) {} }; class AccessControl: public Enum { public: inline AccessControl(VALUE value) : Enum(value, v8::DEFAULT) {} }; class Accessor { public: static void Init(); Accessor(VALUE get, VALUE set, VALUE data); Accessor(VALUE get, VALUE set, VALUE query, VALUE deleter, VALUE enumerator, VALUE data); Accessor(v8::Handle value); inline v8::AccessorGetter accessorGetter() {return &AccessorGetter;} inline v8::AccessorSetter accessorSetter() {return RTEST(set) ? &AccessorSetter : 0;} inline v8::NamedPropertyGetter namedPropertyGetter() {return &NamedPropertyGetter;} inline v8::NamedPropertySetter namedPropertySetter() {return RTEST(set) ? &NamedPropertySetter : 0;} inline v8::NamedPropertyQuery namedPropertyQuery() {return RTEST(query) ? &NamedPropertyQuery : 0;} inline v8::NamedPropertyDeleter namedPropertyDeleter() {return RTEST(deleter) ? &NamedPropertyDeleter : 0;} inline v8::NamedPropertyEnumerator namedPropertyEnumerator() {return RTEST(enumerator) ? &NamedPropertyEnumerator : 0;} inline v8::IndexedPropertyGetter indexedPropertyGetter() {return &IndexedPropertyGetter;} inline v8::IndexedPropertySetter indexedPropertySetter() {return RTEST(set) ? &IndexedPropertySetter : 0;} inline v8::IndexedPropertyQuery indexedPropertyQuery() {return RTEST(query) ? &IndexedPropertyQuery : 0;} inline v8::IndexedPropertyDeleter indexedPropertyDeleter() {return RTEST(deleter) ? &IndexedPropertyDeleter : 0;} inline v8::IndexedPropertyEnumerator indexedPropertyEnumerator() {return RTEST(enumerator) ? &IndexedPropertyEnumerator : 0;} operator v8::Handle(); class Info { public: Info(const v8::AccessorInfo& info); Info(VALUE value); static VALUE This(VALUE self); static VALUE Holder(VALUE self); static VALUE Data(VALUE self); operator VALUE(); inline const v8::AccessorInfo* operator->() {return this->info;} v8::Handle get(v8::Local property); v8::Handle set(v8::Local property, v8::Local value); v8::Handle query(v8::Local property); v8::Handle remove(v8::Local property); v8::Handle enumerateNames(); v8::Handle get(uint32_t index); v8::Handle set(uint32_t index, v8::Local value); v8::Handle query(uint32_t index); v8::Handle remove(uint32_t index); v8::Handle enumerateIndices(); static VALUE Class; private: const v8::AccessorInfo* info; }; friend class Info; private: static v8::Handle AccessorGetter(v8::Local property, const v8::AccessorInfo& info); static void AccessorSetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info); static v8::Handle NamedPropertyGetter(v8::Local property, const v8::AccessorInfo& info); static v8::Handle NamedPropertySetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info); static v8::Handle NamedPropertyQuery(v8::Local property, const v8::AccessorInfo& info); static v8::Handle NamedPropertyDeleter(v8::Local property, const v8::AccessorInfo& info); static v8::Handle NamedPropertyEnumerator(const v8::AccessorInfo& info); static v8::Handle IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info); static v8::Handle IndexedPropertySetter(uint32_t index, v8::Local value, const v8::AccessorInfo& info); static v8::Handle IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info); static v8::Handle IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info); static v8::Handle IndexedPropertyEnumerator(const v8::AccessorInfo& info); void wrap(v8::Handle wrapper, int index, VALUE value); VALUE unwrap(v8::Handle wrapper, int index); VALUE get; VALUE set; VALUE query; VALUE deleter; VALUE enumerator; VALUE data; }; class Invocation { public: static void Init(); Invocation(VALUE code, VALUE data); Invocation(v8::Handle wrapper); operator v8::InvocationCallback(); operator v8::Handle(); static v8::Handle Callback(const v8::Arguments& args); class Arguments { public: static void Init(); Arguments(const v8::Arguments& args); Arguments(VALUE value); inline const v8::Arguments* operator->() {return this->args;} inline const v8::Arguments operator*() {return *this->args;} v8::Handle Call(); static VALUE Length(VALUE self); static VALUE Get(VALUE self, VALUE index); static VALUE Callee(VALUE self); static VALUE This(VALUE self); static VALUE Holder(VALUE self); static VALUE IsConstructCall(VALUE self); static VALUE Data(VALUE self); private: const v8::Arguments* args; static VALUE Class; }; private: VALUE code; VALUE data; friend class Arguments; }; class Object : public Ref { public: static void Init(); static VALUE New(VALUE self); static VALUE Set(VALUE self, VALUE key, VALUE value); static VALUE ForceSet(VALUE self, VALUE key, VALUE value); static VALUE Get(VALUE self, VALUE key); static VALUE GetPropertyAttributes(VALUE self, VALUE key); static VALUE Has(VALUE self, VALUE key); static VALUE Delete(VALUE self, VALUE key); static VALUE ForceDelete(VALUE self, VALUE key); static VALUE SetAccessor(int argc, VALUE* argv, VALUE self); static VALUE GetPropertyNames(VALUE self); static VALUE GetOwnPropertyNames(VALUE self); static VALUE GetPrototype(VALUE self); static VALUE SetPrototype(VALUE self, VALUE prototype); static VALUE FindInstanceInPrototypeChain(VALUE self, VALUE impl); static VALUE ObjectProtoToString(VALUE self); static VALUE GetConstructorName(VALUE self); static VALUE InternalFieldCount(VALUE self); static VALUE GetInternalField(VALUE self, VALUE idx); static VALUE SetInternalField(VALUE self, VALUE idx, VALUE value); static VALUE HasOwnProperty(VALUE self, VALUE key); static VALUE HasRealNamedProperty(VALUE self, VALUE key); static VALUE HasRealIndexedProperty(VALUE self, VALUE idx); static VALUE HasRealNamedCallbackProperty(VALUE self, VALUE key); static VALUE GetRealNamedPropertyInPrototypeChain(VALUE self, VALUE key); static VALUE GetRealNamedProperty(VALUE self, VALUE key); static VALUE HasNamedLookupInterceptor(VALUE self); static VALUE HasIndexedLookupInterceptor(VALUE self); static VALUE TurnOnAccessCheck(VALUE self); static VALUE GetIdentityHash(VALUE self); static VALUE SetHiddenValue(VALUE self, VALUE key, VALUE value); static VALUE GetHiddenValue(VALUE self, VALUE key); static VALUE DeleteHiddenValue(VALUE self, VALUE key); static VALUE IsDirty(VALUE self); static VALUE Clone(VALUE self); static VALUE CreationContext(VALUE self); static VALUE SetIndexedPropertiesToPixelData(VALUE self, VALUE data, VALUE length); static VALUE GetIndexedPropertiesPixelData(VALUE self); static VALUE HasIndexedPropertiesInPixelData(VALUE self); static VALUE GetIndexedPropertiesPixelDataLength(VALUE self); static VALUE SetIndexedPropertiesToExternalArrayData(VALUE self); static VALUE HasIndexedPropertiesInExternalArrayData(VALUE self); static VALUE GetIndexedPropertiesExternalArrayData(VALUE self); static VALUE GetIndexedPropertiesExternalArrayDataType(VALUE self); static VALUE GetIndexedPropertiesExternalArrayDataLength(VALUE self); static VALUE IsCallable(VALUE self); static VALUE CallAsFunction(VALUE self, VALUE recv, VALUE argc, VALUE argv); static VALUE CallAsConstructor(VALUE self, VALUE argc, VALUE argv); inline Object(VALUE value) : Ref(value) {} inline Object(v8::Handle object) : Ref(object) {} virtual operator VALUE(); }; class Array : public Ref { public: static void Init(); static VALUE New(int argc, VALUE argv[], VALUE self); static VALUE Length(VALUE self); static VALUE CloneElementAt(VALUE self, VALUE index); inline Array(v8::Handle array) : Ref(array) {} inline Array(VALUE value) : Ref(value) {} }; class Function : public Ref { public: static void Init(); static VALUE NewInstance(int i, VALUE v[], VALUE self); static VALUE Call(VALUE self, VALUE receiver, VALUE argc, VALUE argv); static VALUE SetName(VALUE self, VALUE name); static VALUE GetName(VALUE self); static VALUE GetInferredName(VALUE self); static VALUE GetScriptLineNumber(VALUE self); static VALUE GetScriptColumnNumber(VALUE self); static VALUE GetScriptId(VALUE self); static VALUE GetScriptOrigin(VALUE self); inline Function(VALUE value) : Ref(value) {} inline Function(v8::Handle function) : Ref(function) {} }; class Signature : public Ref { public: static void Init(); static VALUE New(int argc, VALUE argv[], VALUE self); inline Signature(v8::Handle sig) : Ref(sig) {} inline Signature(VALUE value) : Ref(value) {} }; class Template { public: static void Init(); }; class ObjectTemplate : public Ref { public: static void Init(); static VALUE New(VALUE self); static VALUE NewInstance(VALUE self); static VALUE SetAccessor(int argc, VALUE argv[], VALUE self); static VALUE SetNamedPropertyHandler(int argc, VALUE argv[], VALUE self); static VALUE SetIndexedPropertyHandler(int argc, VALUE argv[], VALUE self); static VALUE SetCallAsFunctionHandler(int argc, VALUE argv[], VALUE self); static VALUE MarkAsUndetectable(VALUE self); static VALUE SetAccessCheckCallbacks(int argc, VALUE argv[], VALUE self); static VALUE InternalFieldCount(VALUE self); static VALUE SetInternalFieldCount(VALUE self, VALUE count); inline ObjectTemplate(VALUE value) : Ref(value) {} inline ObjectTemplate(v8::Handle t) : Ref(t) {} }; class FunctionTemplate : public Ref { public: static void Init(); static VALUE New(int argc, VALUE argv[], VALUE self); static VALUE GetFunction(VALUE self); static VALUE SetCallHandler(int argc, VALUE argv[], VALUE self); static VALUE InstanceTemplate(VALUE self); static VALUE Inherit(VALUE self, VALUE parent); static VALUE PrototypeTemplate(VALUE self); static VALUE SetClassName(VALUE self, VALUE name); static VALUE SetHiddenPrototype(VALUE self, VALUE value); static VALUE ReadOnlyPrototype(VALUE self); static VALUE HasInstance(VALUE self, VALUE object); inline FunctionTemplate(VALUE value) : Ref(value) {} inline FunctionTemplate(v8::Handle t) : Ref(t) {} }; class V8 { public: static void Init(); static VALUE IdleNotification(VALUE self); }; class ClassBuilder { public: ClassBuilder(const char* name, VALUE superclass = rb_cObject); ClassBuilder(const char* name, const char* supername); ClassBuilder& defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE)); 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& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE)); ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(int, 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)); ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE)); ClassBuilder& defineEnumConst(const char* name, int value); ClassBuilder& store(VALUE* storage); inline operator VALUE() {return this->value;} private: VALUE value; }; } #endif