2012-01-31 16:52:08 -05:00
|
|
|
#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-04 00:22:36 -04:00
|
|
|
VALUE Convert(bool);
|
|
|
|
VALUE Convert(v8::Handle<v8::Value> handle);
|
2012-05-02 19:15:11 -04:00
|
|
|
|
2012-05-03 03:24:15 -04:00
|
|
|
class GC {
|
2012-05-02 19:15:11 -04:00
|
|
|
public:
|
2012-05-03 05:00:04 -04:00
|
|
|
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);
|
2012-05-02 19:15:11 -04:00
|
|
|
static void Init();
|
|
|
|
};
|
|
|
|
|
2012-05-08 12:45:06 -04:00
|
|
|
/**
|
|
|
|
* A V8 Enum
|
|
|
|
*/
|
|
|
|
|
|
|
|
template <class T> class Enum {
|
|
|
|
public:
|
|
|
|
Enum<T>(VALUE value) {
|
|
|
|
this->value = value;
|
|
|
|
}
|
|
|
|
inline operator T() {
|
2012-05-09 14:12:44 -04:00
|
|
|
return (T)(RTEST(value) ? NUM2INT(value) : 0);
|
2012-05-08 12:45:06 -04:00
|
|
|
}
|
|
|
|
private:
|
|
|
|
VALUE value;
|
|
|
|
};
|
|
|
|
|
2012-05-02 19:15:11 -04:00
|
|
|
/**
|
|
|
|
* A Reference to a V8 managed object
|
|
|
|
*/
|
|
|
|
template <class T> class Ref {
|
|
|
|
public:
|
2012-05-15 14:41:19 -04:00
|
|
|
Ref(VALUE wrapper) {
|
2012-05-02 19:15:11 -04:00
|
|
|
Holder* holder = NULL;
|
|
|
|
Data_Get_Struct(wrapper, class Holder, holder) ;
|
|
|
|
this->holder = holder;
|
|
|
|
}
|
2012-05-15 14:41:19 -04:00
|
|
|
Ref(v8::Handle<T> handle) {
|
2012-05-15 13:23:06 -04:00
|
|
|
this->holder = new Holder(handle, Class);
|
|
|
|
}
|
2012-05-02 19:15:11 -04:00
|
|
|
virtual operator VALUE() {
|
|
|
|
return holder->value;
|
|
|
|
}
|
|
|
|
virtual operator v8::Handle<T>() {
|
|
|
|
return holder->handle;
|
|
|
|
}
|
|
|
|
inline v8::Handle<T> operator->() const { return holder->handle; }
|
2012-05-03 14:01:10 -04:00
|
|
|
v8::Handle<T> GetHandle() {return holder->handle;}
|
2012-05-03 03:24:15 -04:00
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
virtual ~Holder() {
|
|
|
|
handle.Dispose();
|
|
|
|
}
|
|
|
|
protected:
|
|
|
|
VALUE value;
|
|
|
|
v8::Persistent<T> handle;
|
|
|
|
|
|
|
|
static void enqueue(Holder* holder) {
|
|
|
|
holder->value = Qnil;
|
2012-05-03 05:00:04 -04:00
|
|
|
GC::Finalize(holder);
|
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;
|
2012-05-15 12:46:14 -04:00
|
|
|
static VALUE Class;
|
2012-05-02 19:15:11 -04:00
|
|
|
};
|
2012-05-15 12:46:14 -04:00
|
|
|
template <class T> VALUE Ref<T>::Class;
|
2012-05-02 19:15:11 -04:00
|
|
|
|
2012-05-08 16:11:50 -04:00
|
|
|
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);
|
|
|
|
};
|
|
|
|
|
2012-05-03 03:24:15 -04:00
|
|
|
class Phantom : public Ref<void> {
|
|
|
|
public:
|
2012-05-03 05:00:04 -04:00
|
|
|
inline Phantom(void* reference) : Ref<void>((Ref<void>::Holder*)reference) {}
|
|
|
|
inline bool NotNull() {
|
|
|
|
return this->holder != NULL;
|
|
|
|
}
|
2012-05-03 03:24:15 -04:00
|
|
|
inline void destroy() {
|
|
|
|
delete holder;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-05-02 19:15:11 -04:00
|
|
|
class Context : public Ref<v8::Context> {
|
|
|
|
public:
|
|
|
|
static void Init();
|
2012-05-03 18:21:25 -04:00
|
|
|
static VALUE New(VALUE self);
|
|
|
|
static VALUE Enter(VALUE self);
|
|
|
|
static VALUE Exit(VALUE self);
|
2012-05-08 17:04:47 -04:00
|
|
|
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);
|
2012-05-03 18:21:25 -04:00
|
|
|
|
|
|
|
inline Context(VALUE value) : Ref<v8::Context>(value) {}
|
2012-05-15 13:23:06 -04:00
|
|
|
inline Context(v8::Handle<v8::Context> cxt) : Ref<v8::Context>(cxt) {}
|
2012-05-02 19:15:11 -04:00
|
|
|
};
|
|
|
|
|
2012-05-08 16:11:50 -04:00
|
|
|
class External: public Ref<v8::External> {
|
|
|
|
public:
|
|
|
|
static void Init();
|
|
|
|
static VALUE New(VALUE self, VALUE data);
|
|
|
|
static VALUE Value(VALUE self);
|
2012-05-09 14:12:44 -04:00
|
|
|
|
2012-05-15 13:23:06 -04:00
|
|
|
inline External(VALUE value) : Ref<v8::External>(value) {}
|
|
|
|
inline External(v8::Handle<v8::External> ext) : Ref<v8::External>(ext) {}
|
2012-05-09 14:12:44 -04:00
|
|
|
static v8::Handle<v8::External> wrap(VALUE data);
|
|
|
|
static VALUE unwrap(v8::Handle<v8::External> external);
|
2012-05-08 16:11:50 -04:00
|
|
|
private:
|
|
|
|
static void release(v8::Persistent<v8::Value> object, void* parameter);
|
|
|
|
struct Data {
|
|
|
|
Data(VALUE data);
|
|
|
|
~Data();
|
|
|
|
VALUE value;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2012-05-02 19:15:11 -04:00
|
|
|
class Script : public Ref<v8::Script> {
|
|
|
|
public:
|
|
|
|
static void Init();
|
2012-05-03 18:21:25 -04:00
|
|
|
static VALUE New(VALUE klass, VALUE source, VALUE filename);
|
|
|
|
static VALUE Run(VALUE self);
|
|
|
|
|
|
|
|
inline Script(VALUE value) : Ref<v8::Script>(value) {}
|
2012-05-15 13:23:06 -04:00
|
|
|
inline Script(v8::Handle<v8::Script> script) : Ref<v8::Script>(script) {}
|
2012-05-02 19:15:11 -04:00
|
|
|
};
|
2012-05-01 14:53:01 -04:00
|
|
|
|
2012-05-03 23:35:50 -04:00
|
|
|
class Value : public Ref<v8::Value> {
|
|
|
|
public:
|
|
|
|
static void Init();
|
2012-05-04 00:22:36 -04:00
|
|
|
static VALUE Equals(VALUE self, VALUE other);
|
|
|
|
static VALUE StrictEquals(VALUE self, VALUE other);
|
2012-05-03 23:35:50 -04:00
|
|
|
inline Value(VALUE value) : Ref<v8::Value>(value) {}
|
|
|
|
};
|
|
|
|
|
2012-05-03 03:24:15 -04:00
|
|
|
class String: public Ref<v8::String> {
|
|
|
|
public:
|
2012-05-03 18:21:25 -04:00
|
|
|
static void Init();
|
|
|
|
static VALUE New(VALUE self, VALUE value);
|
|
|
|
static VALUE Utf8Value(VALUE self);
|
2012-05-09 14:12:44 -04:00
|
|
|
static VALUE Concat(VALUE self, VALUE left, VALUE right);
|
2012-05-03 18:21:25 -04:00
|
|
|
|
2012-05-03 18:48:49 -04:00
|
|
|
inline String(VALUE value) : Ref<v8::String>(value) {}
|
2012-05-15 13:23:06 -04:00
|
|
|
inline String(v8::Handle<v8::String> string) : Ref<v8::String>(string) {}
|
2012-05-03 03:24:15 -04:00
|
|
|
};
|
|
|
|
|
2012-05-09 14:12:44 -04:00
|
|
|
class PropertyAttribute: public Enum<v8::PropertyAttribute> {
|
|
|
|
public:
|
|
|
|
inline PropertyAttribute(VALUE value) : Enum<v8::PropertyAttribute>(value) {}
|
|
|
|
};
|
|
|
|
class AccessControl: public Enum<v8::AccessControl> {
|
|
|
|
public:
|
|
|
|
inline AccessControl(VALUE value) : Enum<v8::AccessControl>(value) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Accessor {
|
|
|
|
public:
|
|
|
|
static void Init();
|
|
|
|
Accessor(const v8::AccessorInfo& info);
|
|
|
|
~Accessor();
|
|
|
|
static VALUE This(VALUE self);
|
|
|
|
static VALUE Holder(VALUE self);
|
|
|
|
static VALUE Data(VALUE self);
|
|
|
|
operator VALUE();
|
|
|
|
v8::Handle<v8::Value> get(v8::Local<v8::String> property);
|
|
|
|
v8::Handle<v8::Value> set(v8::Local<v8::String> property, v8::Local<v8::Value> value);
|
|
|
|
static v8::Handle<v8::Value> AccessorGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
|
|
|
static void AccessorSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
|
|
|
|
|
|
|
|
class Info {
|
|
|
|
public:
|
|
|
|
Info(VALUE getter, VALUE setter, VALUE data);
|
|
|
|
Info(v8::Local<v8::Value> value);
|
|
|
|
operator v8::Handle<v8::Value>();
|
|
|
|
void mark();
|
|
|
|
v8::AccessorGetter Getter();
|
|
|
|
v8::AccessorSetter Setter();
|
|
|
|
VALUE getter;
|
|
|
|
VALUE setter;
|
|
|
|
VALUE data;
|
|
|
|
private:
|
|
|
|
void wrap(v8::Handle<v8::Object> wrapper, uint32_t index, VALUE value);
|
|
|
|
VALUE unwrap(v8::Handle<v8::Object> wrapper, uint32_t index);
|
|
|
|
};
|
|
|
|
private:
|
|
|
|
VALUE thisObject;
|
|
|
|
VALUE holder;
|
|
|
|
VALUE value;
|
|
|
|
Info* info;
|
|
|
|
static void mark(Accessor* accessor);
|
|
|
|
static void sweep(Accessor* accessor);
|
|
|
|
static Accessor* accessor(VALUE self);
|
|
|
|
static VALUE Class;
|
|
|
|
};
|
2012-05-08 12:45:06 -04:00
|
|
|
|
2012-05-04 01:23:41 -04:00
|
|
|
class Object : public Ref<v8::Object> {
|
|
|
|
public:
|
|
|
|
static void Init();
|
|
|
|
static VALUE New(VALUE self);
|
2012-05-08 12:45:06 -04:00
|
|
|
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);
|
2012-05-08 13:08:58 -04:00
|
|
|
static VALUE SetAccessor(int argc, VALUE* argv, VALUE self);
|
2012-05-04 01:23:41 -04:00
|
|
|
|
|
|
|
inline Object(VALUE value) : Ref<v8::Object>(value) {}
|
2012-05-15 13:23:06 -04:00
|
|
|
inline Object(v8::Handle<v8::Object> object) : Ref<v8::Object>(object) {}
|
2012-05-04 01:23:41 -04:00
|
|
|
};
|
|
|
|
|
2012-05-03 13:56:41 -04:00
|
|
|
class V8 {
|
|
|
|
public:
|
|
|
|
static void Init();
|
2012-05-03 18:21:25 -04:00
|
|
|
static VALUE IdleNotification(VALUE self);
|
2012-05-03 13:56:41 -04:00
|
|
|
};
|
2012-05-03 03:24:15 -04:00
|
|
|
|
2012-05-03 17:34:51 -04:00
|
|
|
class ClassBuilder {
|
|
|
|
public:
|
|
|
|
ClassBuilder(const char* name, VALUE superclass = rb_cObject);
|
2012-05-04 01:04:01 -04:00
|
|
|
ClassBuilder(const char* name, const char* supername);
|
2012-05-08 13:08:58 -04:00
|
|
|
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE));
|
2012-05-03 17:34:51 -04:00
|
|
|
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE));
|
|
|
|
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE));
|
2012-05-03 17:47:23 -04:00
|
|
|
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE));
|
2012-05-08 13:08:58 -04:00
|
|
|
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE));
|
2012-05-03 17:34:51 -04:00
|
|
|
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE));
|
|
|
|
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE));
|
2012-05-03 17:47:23 -04:00
|
|
|
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE));
|
2012-05-08 12:45:06 -04:00
|
|
|
ClassBuilder& defineEnumConst(const char* name, int value);
|
2012-05-08 17:04:47 -04:00
|
|
|
ClassBuilder& store(VALUE* storage);
|
2012-05-03 17:34:51 -04:00
|
|
|
inline operator VALUE() {return this->value;}
|
|
|
|
private:
|
|
|
|
VALUE value;
|
|
|
|
};
|
|
|
|
|
2012-01-31 16:52:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|