mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
Remove old ext files and spec & link to the new V8
The functionality will be added (that is, if I don't get bored) one thing at a time with the spec. If you want to test, point the libv8 gem (in Gemfile) to its trunk branch & my changes at stormbreakerbg/libv8 @ trunk. What works currently is getting V8 to initialize, say its version and create a new Isolate.
This commit is contained in:
parent
654b808ac5
commit
2fca33f9d0
49 changed files with 338 additions and 3454 deletions
|
|
@ -1,181 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
VALUE Accessor::Info::Class;
|
||||
|
||||
void Accessor::Init() {
|
||||
ClassBuilder("AccessorInfo").
|
||||
defineMethod("This", &Info::This).
|
||||
defineMethod("Holder", &Info::Holder).
|
||||
defineMethod("Data", &Info::Data).
|
||||
store(&Info::Class);
|
||||
}
|
||||
|
||||
Accessor::Accessor(VALUE getter, VALUE setter, VALUE data_) : get(getter), set(setter), query(Qnil), deleter(Qnil), enumerator(Qnil), data(data_) {}
|
||||
|
||||
Accessor::Accessor(VALUE get, VALUE set, VALUE query, VALUE deleter, VALUE enumerator, VALUE data) {
|
||||
this->get = get;
|
||||
this->set = set;
|
||||
this->query = query;
|
||||
this->deleter = deleter;
|
||||
this->enumerator = enumerator;
|
||||
this->data = data;
|
||||
}
|
||||
|
||||
Accessor::Accessor(v8::Handle<v8::Value> value) {
|
||||
v8::Local<v8::Object> wrapper = value->ToObject();
|
||||
this->get = unwrap(wrapper, 0);
|
||||
this->set = unwrap(wrapper, 1);
|
||||
this->query = unwrap(wrapper, 2);
|
||||
this->deleter = unwrap(wrapper, 3);
|
||||
this->enumerator = unwrap(wrapper, 4);
|
||||
v8::Handle<v8::Value> data = wrapper->Get(5);
|
||||
if (!data.IsEmpty() && !data->IsNull() && !data->IsUndefined()) {
|
||||
this->data = Value(data);
|
||||
}
|
||||
}
|
||||
|
||||
Accessor::operator v8::Handle<v8::Value>() {
|
||||
v8::Local<v8::Object> wrapper = v8::Object::New();
|
||||
wrap(wrapper, 0, this->get);
|
||||
wrap(wrapper, 1, this->set);
|
||||
wrap(wrapper, 2, this->query);
|
||||
wrap(wrapper, 3, this->deleter);
|
||||
wrap(wrapper, 4, this->enumerator);
|
||||
if (RTEST(this->data)) {
|
||||
wrapper->Set(5, Value(this->data));
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
void Accessor::wrap(v8::Handle<v8::Object> wrapper, int index, VALUE value) {
|
||||
if (RTEST(value)) {
|
||||
wrapper->Set(index, External::wrap(value));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE Accessor::unwrap(v8::Handle<v8::Object> wrapper, int index) {
|
||||
v8::Handle<v8::Value> value = wrapper->Get(index);
|
||||
if (value.IsEmpty() || !value->IsExternal()) {
|
||||
return Qnil;
|
||||
} else {
|
||||
v8::Handle<v8::External> external(v8::External::Cast(*value));
|
||||
return External::unwrap(external);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VALUE Accessor::Info::This(VALUE self) {
|
||||
return Object(Info(self)->This());
|
||||
}
|
||||
|
||||
VALUE Accessor::Info::Holder(VALUE self) {
|
||||
return Object(Info(self)->Holder());
|
||||
}
|
||||
|
||||
VALUE Accessor::Info::Data(VALUE self) {
|
||||
return Accessor(Info(self)->Data()).data;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::AccessorGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).get(property);
|
||||
}
|
||||
|
||||
void Accessor::AccessorSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
||||
Info(info).set(property, value);
|
||||
}
|
||||
v8::Handle<v8::Value> Accessor::NamedPropertyGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).get(property);
|
||||
}
|
||||
v8::Handle<v8::Value> Accessor::NamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
||||
return Info(info).set(property, value);
|
||||
}
|
||||
v8::Handle<v8::Integer> Accessor::NamedPropertyQuery(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).query(property);
|
||||
}
|
||||
v8::Handle<v8::Boolean> Accessor::NamedPropertyDeleter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).remove(property);
|
||||
}
|
||||
v8::Handle<v8::Array> Accessor::NamedPropertyEnumerator(const v8::AccessorInfo& info) {
|
||||
return Info(info).enumerateNames();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) {
|
||||
return Info(info).get(index);
|
||||
}
|
||||
v8::Handle<v8::Value> Accessor::IndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
||||
return Info(info).set(index, value);
|
||||
}
|
||||
v8::Handle<v8::Integer> Accessor::IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info) {
|
||||
return Info(info).query(index);
|
||||
}
|
||||
v8::Handle<v8::Boolean> Accessor::IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info) {
|
||||
return Info(info).remove(index);
|
||||
}
|
||||
v8::Handle<v8::Array> Accessor::IndexedPropertyEnumerator(const v8::AccessorInfo& info) {
|
||||
return Info(info).enumerateIndices();
|
||||
}
|
||||
|
||||
Accessor::Info::Info(const v8::AccessorInfo& info) {
|
||||
this->info = &info;
|
||||
}
|
||||
|
||||
Accessor::Info::Info(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::AccessorInfo, info);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::Info::get(v8::Local<v8::String> property) {
|
||||
Accessor accessor(info->Data());
|
||||
return Value(rb_funcall(accessor.get, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::Info::set(v8::Local<v8::String> property, v8::Local<v8::Value> value) {
|
||||
Accessor accessor(info->Data());
|
||||
return Value(rb_funcall(accessor.set, rb_intern("call"), 3, (VALUE)String(property), (VALUE)Value(value), (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Integer> Accessor::Info::query(v8::Local<v8::String> property) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Integer::New(NUM2INT(rb_funcall(accessor.query, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Boolean> Accessor::Info::remove(v8::Local<v8::String> property) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Array> Accessor::Info::enumerateNames() {
|
||||
Accessor accessor(info->Data());
|
||||
return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::Info::get(uint32_t index) {
|
||||
Accessor accessor(info->Data());
|
||||
return Value(rb_funcall(accessor.get, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::Info::set(uint32_t index, v8::Local<v8::Value> value) {
|
||||
Accessor accessor(info->Data());
|
||||
return Value(rb_funcall(accessor.set, rb_intern("call"), 3, UINT2NUM(index), (VALUE)Value(value), (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Integer> Accessor::Info::query(uint32_t index) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Integer::New(NUM2INT(rb_funcall(accessor.query, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Boolean> Accessor::Info::remove(uint32_t index) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Array> Accessor::Info::enumerateIndices() {
|
||||
Accessor accessor(info->Data());
|
||||
return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
|
||||
}
|
||||
|
||||
Accessor::Info::operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, 0, (void*)this->info);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Array::Init() {
|
||||
ClassBuilder("Array", Object::Class).
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("Length", &Length).
|
||||
defineMethod("CloneElementAt", &CloneElementAt).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE Array::New(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE length; rb_scan_args(argc, argv, "01", &length);
|
||||
return Array(v8::Array::New(RTEST(length) ? NUM2INT(length) : 0));
|
||||
}
|
||||
|
||||
VALUE Array::Length(VALUE self) {
|
||||
return UInt32(Array(self)->Length());
|
||||
}
|
||||
|
||||
VALUE Array::CloneElementAt(VALUE self, VALUE index) {
|
||||
return Object(Array(self)->CloneElementAt(UInt32(index)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
VALUE Backref::Storage;
|
||||
ID Backref::_new;
|
||||
ID Backref::object;
|
||||
|
||||
void Backref::Init() {
|
||||
Storage = rb_eval_string("V8::Weak::Ref");
|
||||
rb_gc_register_address(&Storage);
|
||||
_new = rb_intern("new");
|
||||
object = rb_intern("object");
|
||||
}
|
||||
|
||||
Backref::Backref(VALUE initial) {
|
||||
set(initial);
|
||||
rb_gc_register_address(&storage);
|
||||
}
|
||||
|
||||
Backref::~Backref() {
|
||||
rb_gc_unregister_address(&storage);
|
||||
}
|
||||
|
||||
VALUE Backref::set(VALUE data) {
|
||||
this->storage = rb_funcall(Storage, _new, 1, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
VALUE Backref::get() {
|
||||
return rb_funcall(storage, object, 0);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Backref::toExternal() {
|
||||
v8::Local<v8::Value> wrapper = v8::External::New(this);
|
||||
v8::Persistent<v8::Value>::New(wrapper).MakeWeak(this, &release);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
void Backref::release(v8::Persistent<v8::Value> handle, void* data) {
|
||||
handle.Dispose();
|
||||
Backref* backref = (Backref*)data;
|
||||
delete backref;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
#include "rr.h"
|
||||
#include "class_builder.h"
|
||||
|
||||
namespace rr {
|
||||
VALUE defineClass(const char *name, VALUE superclass = rb_cObject) {
|
||||
|
||||
VALUE ClassBuilder::defineClass(const char *name, VALUE superclass) {
|
||||
VALUE V8 = rb_define_module("V8");
|
||||
VALUE V8_C = rb_define_module_under(V8, "C");
|
||||
VALUE klass = rb_define_class_under(V8_C, name, superclass);
|
||||
|
|
@ -9,44 +11,46 @@ namespace rr {
|
|||
return klass;
|
||||
}
|
||||
|
||||
VALUE defineModule(const char *name) {
|
||||
VALUE ClassBuilder::defineModule(const char *name) {
|
||||
VALUE V8 = rb_define_module("V8");
|
||||
VALUE V8_C = rb_define_module_under(V8, "C");
|
||||
return rb_define_module_under(V8_C, name);
|
||||
}
|
||||
|
||||
VALUE not_implemented(const char* message) {
|
||||
Void(rb_raise(rb_eStandardError, "not yet implemented %s", message));
|
||||
}
|
||||
|
||||
ClassBuilder::ClassBuilder(const char* name, VALUE superclass) {
|
||||
this->value = defineClass(name, superclass);
|
||||
this->value = ClassBuilder::defineClass(name, superclass);
|
||||
}
|
||||
|
||||
ClassBuilder::ClassBuilder(const char* name, const char* supername) {
|
||||
VALUE superclass = defineClass(supername);
|
||||
this->value = defineClass(name, superclass);
|
||||
VALUE superclass = ClassBuilder::defineClass(supername);
|
||||
this->value = ClassBuilder::defineClass(name, superclass);
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineConst(const char* name, VALUE value) {
|
||||
rb_define_const(this->value, name, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE)) {
|
||||
rb_define_method(this->value, name, (VALUE (*)(...))impl, -1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE)) {
|
||||
rb_define_method(this->value, name, (VALUE (*)(...))impl, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE)) {
|
||||
rb_define_method(this->value, name, (VALUE (*)(...))impl, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE)) {
|
||||
rb_define_method(this->value, name, (VALUE (*)(...))impl, 2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE)) {
|
||||
rb_define_method(this->value, name, (VALUE (*)(...))impl, 3);
|
||||
return *this;
|
||||
|
|
@ -55,29 +59,36 @@ namespace rr {
|
|||
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, -1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE)) {
|
||||
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE)) {
|
||||
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE)) {
|
||||
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE)) {
|
||||
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 3);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::defineEnumConst(const char* name, int value) {
|
||||
rb_define_const(this->value, name, INT2FIX(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClassBuilder& ClassBuilder::store(VALUE* storage) {
|
||||
rb_gc_register_address(storage);
|
||||
*storage = this->value;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
40
ext/v8/class_builder.h
Normal file
40
ext/v8/class_builder.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef RR_CLASS_BUILDER
|
||||
#define RR_CLASS_BUILDER
|
||||
|
||||
namespace rr {
|
||||
|
||||
class ClassBuilder {
|
||||
public:
|
||||
static VALUE defineClass(const char *name, VALUE superclass = rb_cObject);
|
||||
static VALUE defineModule(const char *name);
|
||||
|
||||
ClassBuilder() {};
|
||||
ClassBuilder(const char* name, VALUE superclass = rb_cObject);
|
||||
ClassBuilder(const char* name, const char* supername);
|
||||
|
||||
ClassBuilder& defineConst(const char* name, VALUE value);
|
||||
|
||||
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;}
|
||||
protected:
|
||||
VALUE value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
VALUE Constants::_Undefined;
|
||||
VALUE Constants::_Null;
|
||||
VALUE Constants::_True;
|
||||
VALUE Constants::_False;
|
||||
void Constants::Init() {
|
||||
ModuleBuilder("V8::C").
|
||||
defineSingletonMethod("Undefined", &Undefined).
|
||||
defineSingletonMethod("Null", &Null).
|
||||
defineSingletonMethod("True", &True).
|
||||
defineSingletonMethod("False", &False);
|
||||
|
||||
_Undefined = _Null = _True = _False = Qnil;
|
||||
rb_gc_register_address(&_Undefined);
|
||||
rb_gc_register_address(&_Null);
|
||||
rb_gc_register_address(&_True);
|
||||
rb_gc_register_address(&_False);
|
||||
}
|
||||
|
||||
VALUE Constants::Undefined(VALUE self) {
|
||||
return cached<Primitive, v8::Primitive>(&_Undefined, v8::Undefined());
|
||||
}
|
||||
VALUE Constants::Null(VALUE self) {
|
||||
return cached<Primitive, v8::Primitive>(&_Null, v8::Null());
|
||||
}
|
||||
VALUE Constants::True(VALUE self) {
|
||||
return cached<Bool, v8::Boolean>(&_True, v8::True());
|
||||
}
|
||||
VALUE Constants::False(VALUE self) {
|
||||
return cached<Bool, v8::Boolean>(&_False, v8::False());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void ResourceConstraints::Init() {
|
||||
ClassBuilder("ResourceConstraints").
|
||||
defineSingletonMethod("new", &initialize).
|
||||
defineMethod("max_young_space_size", &max_young_space_size).
|
||||
defineMethod("set_max_young_space_size", &set_max_young_space_size).
|
||||
defineMethod("max_old_space_size", &max_old_space_size).
|
||||
defineMethod("set_max_old_space_size", &set_max_old_space_size).
|
||||
defineMethod("max_executable_size", &set_max_executable_size).
|
||||
defineMethod("set_max_executable_size", &set_max_executable_size).
|
||||
store(&Class);
|
||||
ModuleBuilder("V8::C").
|
||||
defineSingletonMethod("SetResourceConstraints", &SetResourceConstraints);
|
||||
}
|
||||
|
||||
VALUE ResourceConstraints::SetResourceConstraints(VALUE self, VALUE constraints) {
|
||||
Void(v8::SetResourceConstraints(ResourceConstraints(constraints)));
|
||||
}
|
||||
|
||||
VALUE ResourceConstraints::initialize(VALUE self) {
|
||||
return ResourceConstraints(new v8::ResourceConstraints());
|
||||
}
|
||||
VALUE ResourceConstraints::max_young_space_size(VALUE self) {
|
||||
return INT2FIX(ResourceConstraints(self)->max_young_space_size());
|
||||
}
|
||||
VALUE ResourceConstraints::set_max_young_space_size(VALUE self, VALUE value) {
|
||||
Void(ResourceConstraints(self)->set_max_young_space_size(NUM2INT(value)));
|
||||
}
|
||||
VALUE ResourceConstraints::max_old_space_size(VALUE self) {
|
||||
return INT2FIX(ResourceConstraints(self)->max_old_space_size());
|
||||
}
|
||||
VALUE ResourceConstraints::set_max_old_space_size(VALUE self, VALUE value) {
|
||||
Void(ResourceConstraints(self)->set_max_old_space_size(NUM2INT(value)));
|
||||
}
|
||||
VALUE ResourceConstraints::max_executable_size(VALUE self) {
|
||||
return INT2FIX(ResourceConstraints(self)->max_executable_size());
|
||||
}
|
||||
VALUE ResourceConstraints::set_max_executable_size(VALUE self, VALUE value) {
|
||||
Void(ResourceConstraints(self)->set_max_executable_size(NUM2INT(value)));
|
||||
}
|
||||
|
||||
// What do these even mean?
|
||||
// uint32_t* stack_limit() const { return stack_limit_; }
|
||||
// // Sets an address beyond which the VM's stack may not grow.
|
||||
// void set_stack_limit(uint32_t* value) { stack_limit_ = value; }
|
||||
|
||||
template <> void Pointer<v8::ResourceConstraints>::unwrap(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::ResourceConstraints, pointer);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Context::Init() {
|
||||
ClassBuilder("Context").
|
||||
defineSingletonMethod("New", &New).
|
||||
defineSingletonMethod("GetCurrent", &GetCurrent).
|
||||
defineSingletonMethod("GetEntered", &GetEntered).
|
||||
defineSingletonMethod("GetCalling", &GetCalling).
|
||||
defineSingletonMethod("InContext", &InContext).
|
||||
defineMethod("Dispose", &Dispose).
|
||||
defineMethod("Global", &Global).
|
||||
defineMethod("DetachGlobal", &Global).
|
||||
defineMethod("ReattachGlobal", &ReattachGlobal).
|
||||
defineMethod("SetSecurityToken", &SetSecurityToken).
|
||||
defineMethod("UseDefaultSecurityToken", &UseDefaultSecurityToken).
|
||||
defineMethod("GetSecurityToken", &GetSecurityToken).
|
||||
defineMethod("HasOutOfMemoryException", &HasOutOfMemoryException).
|
||||
defineMethod("SetEmbedderData", &SetEmbedderData).
|
||||
defineMethod("GetEmbedderData", &GetEmbedderData).
|
||||
defineMethod("AllowCodeGenerationFromStrings", &AllowCodeGenerationFromStrings).
|
||||
defineMethod("IsCodeGenerationFromStringsAllowed", &IsCodeGenerationFromStringsAllowed).
|
||||
defineMethod("Enter", &Enter).
|
||||
defineMethod("Exit", &Exit).
|
||||
store(&Class);
|
||||
ClassBuilder("ExtensionConfiguration").
|
||||
defineSingletonMethod("new", &ExtensionConfiguration::initialize).
|
||||
store(&ExtensionConfiguration::Class);
|
||||
}
|
||||
|
||||
VALUE Context::Dispose(VALUE self) {
|
||||
Void(Context(self).dispose())
|
||||
}
|
||||
|
||||
VALUE Context::Global(VALUE self) {
|
||||
return Object(Context(self)->Global());
|
||||
}
|
||||
|
||||
VALUE Context::DetachGlobal(VALUE self) {
|
||||
Void(Context(self)->DetachGlobal());
|
||||
}
|
||||
|
||||
VALUE Context::ReattachGlobal(VALUE self, VALUE global) {
|
||||
Void(Context(self)->ReattachGlobal(Object(global)));
|
||||
}
|
||||
|
||||
VALUE Context::GetEntered(VALUE self) {
|
||||
return Context(v8::Context::GetEntered());
|
||||
}
|
||||
|
||||
VALUE Context::GetCurrent(VALUE self) {
|
||||
return Context(v8::Context::GetCurrent());
|
||||
}
|
||||
|
||||
VALUE Context::GetCalling(VALUE self) {
|
||||
return Context(v8::Context::GetCalling());
|
||||
}
|
||||
|
||||
VALUE Context::SetSecurityToken(VALUE self, VALUE token) {
|
||||
Void(Context(self)->SetSecurityToken(Value(token)));
|
||||
}
|
||||
|
||||
VALUE Context::UseDefaultSecurityToken(VALUE self) {
|
||||
Void(Context(self)->UseDefaultSecurityToken());
|
||||
}
|
||||
|
||||
VALUE Context::GetSecurityToken(VALUE self) {
|
||||
return Value(Context(self)->GetSecurityToken());
|
||||
}
|
||||
|
||||
VALUE Context::HasOutOfMemoryException(VALUE self) {
|
||||
return Bool(Context(self)->HasOutOfMemoryException());
|
||||
}
|
||||
|
||||
VALUE Context::InContext(VALUE self) {
|
||||
return Bool(v8::Context::InContext());
|
||||
}
|
||||
|
||||
VALUE Context::SetEmbedderData(VALUE self, VALUE index, VALUE data) {
|
||||
Void(Context(self)->SetEmbedderData(NUM2INT(index), Value(data)));
|
||||
}
|
||||
|
||||
VALUE Context::GetEmbedderData(VALUE self, VALUE index) {
|
||||
Void(Context(self)->GetEmbedderData(NUM2INT(index)));
|
||||
}
|
||||
|
||||
VALUE Context::AllowCodeGenerationFromStrings(VALUE self, VALUE allow) {
|
||||
Void(Context(self)->AllowCodeGenerationFromStrings(RTEST(allow)));
|
||||
}
|
||||
|
||||
VALUE Context::IsCodeGenerationFromStringsAllowed(VALUE self) {
|
||||
return Bool(Context(self)->IsCodeGenerationFromStringsAllowed());
|
||||
}
|
||||
|
||||
VALUE ExtensionConfiguration::initialize(VALUE self, VALUE names) {
|
||||
int length = RARRAY_LENINT(names);
|
||||
const char* array[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = RSTRING_PTR(rb_ary_entry(names, i));
|
||||
}
|
||||
return ExtensionConfiguration(new v8::ExtensionConfiguration(length, array));
|
||||
}
|
||||
|
||||
VALUE Context::New(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE extension_configuration; VALUE global_template; VALUE global_object;
|
||||
rb_scan_args(argc, argv, "03", &extension_configuration, &global_template, &global_object);
|
||||
v8::Persistent<v8::Context> context(v8::Context::New(
|
||||
ExtensionConfiguration(extension_configuration),
|
||||
*ObjectTemplate(global_template),
|
||||
*Object(global_object)
|
||||
));
|
||||
Context reference(context);
|
||||
context.Dispose();
|
||||
return reference;
|
||||
}
|
||||
|
||||
VALUE Context::Enter(VALUE self) {
|
||||
Void(Context(self)->Enter());
|
||||
}
|
||||
|
||||
VALUE Context::Exit(VALUE self) {
|
||||
Void(Context(self)->Exit());
|
||||
}
|
||||
|
||||
template <> void Pointer<v8::ExtensionConfiguration>::unwrap(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::ExtensionConfiguration, pointer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Date::Init() {
|
||||
ClassBuilder("Date", Value::Class).
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("NumberValue", &NumberValue).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE Date::New(VALUE self, VALUE time) {
|
||||
return Value(v8::Date::New(NUM2DBL(time)));
|
||||
}
|
||||
VALUE Date::NumberValue(VALUE self) {
|
||||
return rb_float_new(Date(self)->NumberValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Exception::Init() {
|
||||
ModuleBuilder("V8::C").
|
||||
defineSingletonMethod("ThrowException", &ThrowException);
|
||||
ClassBuilder("Exception").
|
||||
defineSingletonMethod("RangeError", &RangeError).
|
||||
defineSingletonMethod("ReferenceError", &ReferenceError).
|
||||
defineSingletonMethod("SyntaxError", &SyntaxError).
|
||||
defineSingletonMethod("TypeError", &TypeError).
|
||||
defineSingletonMethod("Error", &Error);
|
||||
}
|
||||
|
||||
VALUE Exception::ThrowException(VALUE self, VALUE exception) {
|
||||
return Value(v8::ThrowException(Value(exception)));
|
||||
}
|
||||
|
||||
VALUE Exception::RangeError(VALUE self, VALUE message) {
|
||||
return Value(v8::Exception::RangeError(String(message)));
|
||||
}
|
||||
|
||||
VALUE Exception::ReferenceError(VALUE self, VALUE message) {
|
||||
return Value(v8::Exception::ReferenceError(String(message)));
|
||||
}
|
||||
|
||||
VALUE Exception::SyntaxError(VALUE self, VALUE message) {
|
||||
return Value(v8::Exception::SyntaxError(String(message)));
|
||||
}
|
||||
|
||||
VALUE Exception::TypeError(VALUE self, VALUE message) {
|
||||
return Value(v8::Exception::TypeError(String(message)));
|
||||
}
|
||||
|
||||
VALUE Exception::Error(VALUE self, VALUE message) {
|
||||
return Value(v8::Exception::Error(String(message)));
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ if enable_config('debug')
|
|||
$CFLAGS += " -O0 -ggdb3"
|
||||
end
|
||||
|
||||
LIBV8_COMPATIBILITY = '~> 3.16.14'
|
||||
LIBV8_COMPATIBILITY = '~> 3.31.0'
|
||||
|
||||
begin
|
||||
require 'rubygems'
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void External::Init() {
|
||||
ClassBuilder("External", "Value").
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("Value", &Value).
|
||||
store(&Class);
|
||||
}
|
||||
VALUE External::New(VALUE self, VALUE data) {
|
||||
return External(wrap(data));
|
||||
}
|
||||
|
||||
v8::Handle<v8::External> External::wrap(VALUE data) {
|
||||
Data* holder = new Data(data);
|
||||
v8::Local<v8::External> ext = v8::External::New(holder);
|
||||
v8::Persistent<v8::External>::New(ext).MakeWeak(holder, &release);
|
||||
return ext;
|
||||
}
|
||||
|
||||
VALUE External::unwrap(v8::Handle<v8::External> external) {
|
||||
Data* data = (Data*)(external->Value());
|
||||
return data->value;
|
||||
}
|
||||
|
||||
VALUE External::Value(VALUE self) {
|
||||
return unwrap(External(self));
|
||||
}
|
||||
|
||||
void External::release(v8::Persistent<v8::Value> handle, void* parameter) {
|
||||
handle.Dispose();
|
||||
Data* data = (Data*)parameter;
|
||||
delete data;
|
||||
}
|
||||
External::Data::Data(VALUE data) {
|
||||
this->value = data;
|
||||
rb_gc_register_address(&value);
|
||||
}
|
||||
External::Data::~Data() {
|
||||
rb_gc_unregister_address(&value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Function::Init() {
|
||||
ClassBuilder("Function", Object::Class).
|
||||
defineMethod("NewInstance", &NewInstance).
|
||||
defineMethod("Call", &Call).
|
||||
defineMethod("SetName", &SetName).
|
||||
defineMethod("GetName", &GetName).
|
||||
defineMethod("GetInferredName", &GetInferredName).
|
||||
defineMethod("GetScriptLineNumber", &GetScriptLineNumber).
|
||||
defineMethod("GetScriptColumnNumber", &GetScriptColumnNumber).
|
||||
defineMethod("GetScriptId", &GetScriptId).
|
||||
defineMethod("GetScriptOrigin", &GetScriptOrigin).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE Function::NewInstance(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE args;
|
||||
rb_scan_args(argc,argv,"01", &args);
|
||||
if (RTEST(args)) {
|
||||
return Object(Function(self)->NewInstance(RARRAY_LENINT(args), Value::array<Value>(args)));
|
||||
} else {
|
||||
return Object(Function(self)->NewInstance());
|
||||
}
|
||||
}
|
||||
VALUE Function::Call(VALUE self, VALUE receiver, VALUE argv) {
|
||||
return Value(Function(self)->Call(Object(receiver), RARRAY_LENINT(argv), Value::array<Value>(argv)));
|
||||
}
|
||||
|
||||
VALUE Function::SetName(VALUE self, VALUE name) {
|
||||
Void(Function(self)->SetName(String(name)));
|
||||
}
|
||||
|
||||
VALUE Function::GetName(VALUE self) {
|
||||
return Value(Function(self)->GetName());
|
||||
}
|
||||
|
||||
VALUE Function::GetInferredName(VALUE self) {
|
||||
return Value(Function(self)->GetInferredName());
|
||||
}
|
||||
|
||||
VALUE Function::GetScriptLineNumber(VALUE self) {
|
||||
return INT2FIX(Function(self)->GetScriptLineNumber());
|
||||
}
|
||||
|
||||
VALUE Function::GetScriptColumnNumber(VALUE self) {
|
||||
return INT2FIX(Function(self)->GetScriptColumnNumber());
|
||||
}
|
||||
|
||||
VALUE Function::GetScriptId(VALUE self) {
|
||||
return Value(Function(self)->GetScriptId());
|
||||
}
|
||||
|
||||
VALUE Function::GetScriptOrigin(VALUE self) {
|
||||
return not_implemented("GetScriptOrigin");
|
||||
}
|
||||
}
|
||||
43
ext/v8/gc.cc
43
ext/v8/gc.cc
|
|
@ -1,43 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
GC::Queue* queue;
|
||||
|
||||
GC::Queue::Queue() : first(0), divider(0), last(0){
|
||||
first = new GC::Queue::Node(NULL);
|
||||
divider = first;
|
||||
last = first;
|
||||
}
|
||||
|
||||
void GC::Queue::Enqueue(void* reference) {
|
||||
last->next = new Node(reference);
|
||||
last = last->next;
|
||||
while (first != divider) {
|
||||
Node* tmp = first;
|
||||
first = first->next;
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void* GC::Queue::Dequeue() {
|
||||
void* result = NULL;
|
||||
if (divider != last) {
|
||||
result = divider->next->value;
|
||||
divider = divider->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void GC::Finalize(void* phantom) {
|
||||
queue->Enqueue(phantom);
|
||||
}
|
||||
void GC::Drain(v8::GCType type, v8::GCCallbackFlags flags) {
|
||||
for(Phantom phantom = queue->Dequeue(); phantom.NotNull(); phantom = queue->Dequeue()) {
|
||||
phantom.destroy();
|
||||
}
|
||||
}
|
||||
void GC::Init() {
|
||||
queue = new GC::Queue();
|
||||
v8::V8::AddGCPrologueCallback(GC::Drain);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,33 +2,35 @@
|
|||
|
||||
namespace rr {
|
||||
|
||||
void Handles::Init() {
|
||||
VALUE v8 = rb_define_module("V8");
|
||||
VALUE c = rb_define_module_under(v8, "C");
|
||||
rb_define_singleton_method(c, "HandleScope", (VALUE (*)(...))&HandleScope, -1);
|
||||
}
|
||||
|
||||
VALUE Handles::HandleScope(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
void Handles::Init() {
|
||||
VALUE v8 = rb_define_module("V8");
|
||||
VALUE c = rb_define_module_under(v8, "C");
|
||||
rb_define_singleton_method(c, "HandleScope", (VALUE (*)(...))&HandleScope, -1);
|
||||
}
|
||||
int state = 0;
|
||||
VALUE code;
|
||||
rb_scan_args(argc,argv,"00&", &code);
|
||||
VALUE result = SetupAndCall(&state, code);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
|
||||
VALUE Handles::HandleScope(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE isolate, block;
|
||||
rb_scan_args(argc, argv, "10&", &isolate, &block);
|
||||
|
||||
int state = 0;
|
||||
VALUE result = SetupAndCall(Isolate(isolate), &state, block);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE Handles::SetupAndCall(int* state, VALUE code) {
|
||||
v8::HandleScope scope;
|
||||
return rb_protect(&DoCall, code, state);
|
||||
}
|
||||
VALUE Handles::SetupAndCall(Isolate isolate, int* state, VALUE block) {
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
return rb_protect(&DoCall, block, state);
|
||||
}
|
||||
|
||||
VALUE Handles::DoCall(VALUE code) {
|
||||
return rb_funcall(code, rb_intern("call"), 0);
|
||||
}
|
||||
VALUE Handles::DoCall(VALUE block) {
|
||||
return rb_funcall(block, rb_intern("call"), 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
ext/v8/handles.h
Normal file
17
ext/v8/handles.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef RR_HANDLES
|
||||
#define RR_HANDLES
|
||||
|
||||
namespace rr {
|
||||
|
||||
class Handles {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE HandleScope(int argc, VALUE* argv, VALUE self);
|
||||
private:
|
||||
static VALUE SetupAndCall(Isolate isolate, int* state, VALUE code);
|
||||
static VALUE DoCall(VALUE code);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void HeapStatistics::Init() {
|
||||
ClassBuilder("HeapStatistics").
|
||||
defineSingletonMethod("new", &initialize).
|
||||
defineMethod("total_heap_size", &total_heap_size).
|
||||
defineMethod("total_heap_size_executable", &total_heap_size_executable).
|
||||
defineMethod("total_physical_size", &total_physical_size).
|
||||
defineMethod("used_heap_size", &used_heap_size).
|
||||
defineMethod("heap_size_limit", &heap_size_limit).
|
||||
store(&Class);
|
||||
}
|
||||
VALUE HeapStatistics::initialize(VALUE self) {
|
||||
return HeapStatistics(new v8::HeapStatistics());
|
||||
}
|
||||
VALUE HeapStatistics::total_heap_size(VALUE self) {
|
||||
return SIZET2NUM(HeapStatistics(self)->total_heap_size());
|
||||
}
|
||||
VALUE HeapStatistics::total_heap_size_executable(VALUE self) {
|
||||
return SIZET2NUM(HeapStatistics(self)->total_heap_size_executable());
|
||||
}
|
||||
VALUE HeapStatistics::total_physical_size(VALUE self) {
|
||||
return SIZET2NUM(HeapStatistics(self)->total_physical_size());
|
||||
}
|
||||
VALUE HeapStatistics::used_heap_size(VALUE self) {
|
||||
return SIZET2NUM(HeapStatistics(self)->used_heap_size());
|
||||
}
|
||||
VALUE HeapStatistics::heap_size_limit(VALUE self) {
|
||||
return SIZET2NUM(HeapStatistics(self)->heap_size_limit());
|
||||
}
|
||||
template <> void Pointer<v8::HeapStatistics>::unwrap(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::HeapStatistics, pointer);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,32 +8,33 @@ using namespace rr;
|
|||
|
||||
extern "C" {
|
||||
void Init_init() {
|
||||
v8::Locker lock();
|
||||
GC::Init();
|
||||
V8::Init();
|
||||
Handles::Init();
|
||||
Accessor::Init();
|
||||
Context::Init();
|
||||
Invocation::Init();
|
||||
Signature::Init();
|
||||
Value::Init();
|
||||
Primitive::Init();
|
||||
String::Init();
|
||||
Object::Init();
|
||||
Array::Init();
|
||||
Function::Init();
|
||||
Date::Init();
|
||||
Constants::Init();
|
||||
External::Init();
|
||||
Script::Init();
|
||||
Template::Init();
|
||||
Stack::Init();
|
||||
Message::Init();
|
||||
TryCatch::Init();
|
||||
Exception::Init();
|
||||
Locker::Init();
|
||||
ResourceConstraints::Init();
|
||||
HeapStatistics::Init();
|
||||
Backref::Init();
|
||||
Isolate::Init();
|
||||
// v8::Locker lock();
|
||||
// GC::Init();
|
||||
// Handles::Init();
|
||||
// Accessor::Init();
|
||||
// Context::Init();
|
||||
// Invocation::Init();
|
||||
// Signature::Init();
|
||||
// Value::Init();
|
||||
// Primitive::Init();
|
||||
// String::Init();
|
||||
// Object::Init();
|
||||
// Array::Init();
|
||||
// Function::Init();
|
||||
// Date::Init();
|
||||
// Constants::Init();
|
||||
// External::Init();
|
||||
// Script::Init();
|
||||
// Template::Init();
|
||||
// Stack::Init();
|
||||
// Message::Init();
|
||||
// TryCatch::Init();
|
||||
// Exception::Init();
|
||||
// Locker::Init();
|
||||
// ResourceConstraints::Init();
|
||||
// HeapStatistics::Init();
|
||||
// Backref::Init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
VALUE Invocation::Arguments::Class;
|
||||
|
||||
void Invocation::Init() {
|
||||
Arguments::Init();
|
||||
}
|
||||
|
||||
void Invocation::Arguments::Init() {
|
||||
ClassBuilder("Arguments").
|
||||
defineMethod("Length", &Length).
|
||||
defineMethod("[]", &Get).
|
||||
defineMethod("Callee", &Callee).
|
||||
defineMethod("This", &This).
|
||||
defineMethod("Holder", &Holder).
|
||||
defineMethod("IsConstructCall", &IsConstructCall).
|
||||
defineMethod("Data", &Data).
|
||||
store(&Invocation::Arguments::Class);
|
||||
}
|
||||
|
||||
Invocation::Invocation(VALUE code, VALUE data) {
|
||||
this->code = code;
|
||||
this->data = data;
|
||||
}
|
||||
Invocation::Invocation(v8::Handle<v8::Value> value) {
|
||||
v8::Local<v8::Object> wrapper = value->ToObject();
|
||||
this->code = External::unwrap((v8::Handle<v8::External>)v8::External::Cast(*wrapper->Get(0)));
|
||||
this->data = Value(wrapper->Get(1));
|
||||
}
|
||||
Invocation::operator v8::InvocationCallback() {
|
||||
return &Callback;
|
||||
}
|
||||
Invocation::operator v8::Handle<v8::Value>() {
|
||||
v8::Local<v8::Object> wrapper = v8::Object::New();
|
||||
wrapper->Set(0, External::wrap(this->code));
|
||||
wrapper->Set(1, Value(this->data));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Invocation::Callback(const v8::Arguments& args) {
|
||||
return Arguments(args).Call();
|
||||
}
|
||||
|
||||
Invocation::Arguments::Arguments(const v8::Arguments& args) {
|
||||
this->args = &args;
|
||||
}
|
||||
|
||||
Invocation::Arguments::Arguments(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::Arguments, args);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Invocation::Arguments::Call() {
|
||||
Invocation invocation(args->Data());
|
||||
return Value(rb_funcall(invocation.code, rb_intern("call"), 1, Data_Wrap_Struct(Class, 0, 0, (void*)this->args)));
|
||||
}
|
||||
|
||||
VALUE Invocation::Arguments::Length(VALUE self) {
|
||||
return INT2FIX(Arguments(self)->Length());
|
||||
}
|
||||
|
||||
VALUE Invocation::Arguments::Get(VALUE self, VALUE index) {
|
||||
return Value((*Arguments(self))[NUM2INT(index)]);
|
||||
}
|
||||
|
||||
VALUE Invocation::Arguments::Callee(VALUE self) {
|
||||
return Function(Arguments(self)->Callee());
|
||||
}
|
||||
|
||||
VALUE Invocation::Arguments::This(VALUE self) {
|
||||
return Object(Arguments(self)->This());
|
||||
}
|
||||
|
||||
VALUE Invocation::Arguments::Holder(VALUE self) {
|
||||
return Object(Arguments(self)->Holder());
|
||||
}
|
||||
|
||||
VALUE Invocation::Arguments::IsConstructCall(VALUE self) {
|
||||
return Bool(Arguments(self)->IsConstructCall());
|
||||
}
|
||||
|
||||
VALUE Invocation::Arguments::Data(VALUE self) {
|
||||
return Invocation(Arguments(self)->Data()).data;
|
||||
}
|
||||
}
|
||||
20
ext/v8/isolate.cc
Normal file
20
ext/v8/isolate.cc
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Isolate::Init() {
|
||||
ClassBuilder("Isolate").
|
||||
defineSingletonMethod("New", &New).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE Isolate::New(VALUE self) {
|
||||
return Isolate(v8::Isolate::New());
|
||||
}
|
||||
|
||||
template <>
|
||||
void Pointer<v8::Isolate>::unwrap(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::Isolate, pointer);
|
||||
}
|
||||
|
||||
}
|
||||
31
ext/v8/isolate.h
Normal file
31
ext/v8/isolate.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef RR_ISOLATE
|
||||
#define RR_ISOLATE
|
||||
|
||||
namespace rr {
|
||||
|
||||
class Isolate : public Pointer<v8::Isolate> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(VALUE self);
|
||||
|
||||
inline Isolate(v8::Isolate* isolate) : Pointer<v8::Isolate>(isolate) {}
|
||||
inline Isolate(VALUE value) : Pointer<v8::Isolate>(value) {}
|
||||
|
||||
inline operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, &release, pointer);
|
||||
}
|
||||
|
||||
static void release(v8::Isolate* isolate) {
|
||||
// The isolates must be released with Dispose.
|
||||
// Using the delete operator is not allowed.
|
||||
|
||||
// TODO: Do we want to dispose of the isolate when the object itself
|
||||
// is garbage-collected?
|
||||
// Can the isolate be used without it having a reference in ruby world?
|
||||
isolate->Dispose();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Locker::Init() {
|
||||
ClassBuilder("Locker").
|
||||
defineSingletonMethod("StartPreemption", &StartPreemption).
|
||||
defineSingletonMethod("StopPreemption", &StopPreemption).
|
||||
defineSingletonMethod("IsLocked", &IsLocked).
|
||||
defineSingletonMethod("IsActive", &IsActive);
|
||||
VALUE v8 = rb_define_module("V8");
|
||||
VALUE c = rb_define_module_under(v8, "C");
|
||||
rb_define_singleton_method(c, "Locker", (VALUE (*)(...))&doLock, -1);
|
||||
rb_define_singleton_method(c, "Unlocker",(VALUE (*)(...))&doUnlock, -1);
|
||||
}
|
||||
|
||||
VALUE Locker::StartPreemption(VALUE self, VALUE every_n_ms) {
|
||||
Void(v8::Locker::StartPreemption(NUM2INT(every_n_ms)));
|
||||
}
|
||||
|
||||
VALUE Locker::StopPreemption(VALUE self) {
|
||||
Void(v8::Locker::StopPreemption());
|
||||
}
|
||||
|
||||
VALUE Locker::IsLocked(VALUE self) {
|
||||
return Bool(v8::Locker::IsLocked(v8::Isolate::GetCurrent()));
|
||||
}
|
||||
|
||||
VALUE Locker::IsActive(VALUE self) {
|
||||
return Bool(v8::Locker::IsActive());
|
||||
}
|
||||
|
||||
VALUE Locker::doLock(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
int state = 0;
|
||||
VALUE code;
|
||||
rb_scan_args(argc,argv,"00&", &code);
|
||||
VALUE result = setupLockAndCall(&state, code);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE Locker::setupLockAndCall(int* state, VALUE code) {
|
||||
v8::Locker locker;
|
||||
return rb_protect(&doLockCall, code, state);
|
||||
}
|
||||
|
||||
VALUE Locker::doLockCall(VALUE code) {
|
||||
return rb_funcall(code, rb_intern("call"), 0);
|
||||
}
|
||||
|
||||
VALUE Locker::doUnlock(int argc, VALUE* argv, VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
int state = 0;
|
||||
VALUE code;
|
||||
rb_scan_args(argc,argv,"00&", &code);
|
||||
VALUE result = setupUnlockAndCall(&state, code);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE Locker::setupUnlockAndCall(int* state, VALUE code) {
|
||||
v8::Unlocker unlocker;
|
||||
return rb_protect(&doUnlockCall, code, state);
|
||||
}
|
||||
|
||||
VALUE Locker::doUnlockCall(VALUE code) {
|
||||
return rb_funcall(code, rb_intern("call"), 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Message::Init() {
|
||||
ClassBuilder("Message").
|
||||
defineMethod("Get", &Get).
|
||||
defineMethod("GetSourceLine", &GetSourceLine).
|
||||
defineMethod("GetScriptResourceName", &GetScriptResourceName).
|
||||
defineMethod("GetScriptData", &GetScriptData).
|
||||
defineMethod("GetStackTrace", &GetStackTrace).
|
||||
defineMethod("GetLineNumber", &GetLineNumber).
|
||||
defineMethod("GetStartPosition", &GetStartPosition).
|
||||
defineMethod("GetEndPosition", &GetEndPosition).
|
||||
defineMethod("GetStartColumn", &GetEndColumn).
|
||||
defineSingletonMethod("kNoLineNumberInfo", &kNoLineNumberInfo).
|
||||
defineSingletonMethod("kNoColumnInfo", &kNoColumnInfo).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE Message::Get(VALUE self) {
|
||||
return String(Message(self)->Get());
|
||||
}
|
||||
VALUE Message::GetSourceLine(VALUE self) {
|
||||
return String(Message(self)->GetSourceLine());
|
||||
}
|
||||
VALUE Message::GetScriptResourceName(VALUE self) {
|
||||
return Value(Message(self)->GetScriptResourceName());
|
||||
}
|
||||
VALUE Message::GetScriptData(VALUE self) {
|
||||
return Value(Message(self)->GetScriptData());
|
||||
}
|
||||
VALUE Message::GetStackTrace(VALUE self) {
|
||||
return Stack::Trace(Message(self)->GetStackTrace());
|
||||
}
|
||||
VALUE Message::GetLineNumber(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetLineNumber());
|
||||
}
|
||||
VALUE Message::GetStartPosition(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetStartPosition());
|
||||
}
|
||||
VALUE Message::GetEndPosition(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetEndPosition());
|
||||
}
|
||||
VALUE Message::GetStartColumn(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetStartColumn());
|
||||
}
|
||||
VALUE Message::GetEndColumn(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetEndColumn());
|
||||
}
|
||||
}
|
||||
335
ext/v8/object.cc
335
ext/v8/object.cc
|
|
@ -1,335 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Object::Init() {
|
||||
ClassBuilder("Object", Value::Class).
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("Set", &Set).
|
||||
defineMethod("ForceSet", &ForceSet).
|
||||
defineMethod("Get", &Get).
|
||||
defineMethod("GetPropertyAttributes", &GetPropertyAttributes).
|
||||
defineMethod("Has", &Has).
|
||||
defineMethod("Delete", &Delete).
|
||||
defineMethod("ForceDelete", &ForceDelete).
|
||||
defineMethod("SetAccessor", &SetAccessor).
|
||||
defineMethod("GetPropertyNames", &GetPropertyNames).
|
||||
defineMethod("GetOwnPropertyNames", &GetOwnPropertyNames).
|
||||
defineMethod("GetPrototype", &GetPrototype).
|
||||
defineMethod("SetPrototype", &SetPrototype).
|
||||
defineMethod("FindInstanceInPrototypeChain", &FindInstanceInPrototypeChain).
|
||||
defineMethod("ObjectProtoToString", &ObjectProtoToString).
|
||||
defineMethod("GetConstructorName", &GetConstructorName).
|
||||
defineMethod("InternalFieldCount", &InternalFieldCount).
|
||||
defineMethod("GetInternalField", &GetInternalField).
|
||||
defineMethod("SetInternalField", &SetInternalField).
|
||||
defineMethod("HasOwnProperty", &HasOwnProperty).
|
||||
defineMethod("HasRealNamedProperty", &HasRealNamedProperty).
|
||||
defineMethod("HasRealIndexedProperty", &HasRealIndexedProperty).
|
||||
defineMethod("HasRealNamedCallbackProperty", &HasRealNamedCallbackProperty).
|
||||
defineMethod("GetRealNamedPropertyInPrototypeChain", &GetRealNamedPropertyInPrototypeChain).
|
||||
defineMethod("GetRealNamedProperty", &GetRealNamedProperty).
|
||||
defineMethod("HasNamedLookupInterceptor", &HasNamedLookupInterceptor).
|
||||
defineMethod("HasIndexedLookupInterceptor", &HasIndexedLookupInterceptor).
|
||||
defineMethod("TurnOnAccessCheck", &TurnOnAccessCheck).
|
||||
defineMethod("GetIdentityHash", &GetIdentityHash).
|
||||
defineMethod("SetHiddenValue", &SetHiddenValue).
|
||||
defineMethod("GetHiddenValue", &GetHiddenValue).
|
||||
defineMethod("DeleteHiddenValue", &DeleteHiddenValue).
|
||||
defineMethod("IsDirty", &IsDirty).
|
||||
defineMethod("Clone", &Clone).
|
||||
defineMethod("CreationContext", &CreationContext).
|
||||
defineMethod("SetIndexedPropertiesToPixelData", &SetIndexedPropertiesToPixelData).
|
||||
defineMethod("GetIndexedPropertiesPixelData", &GetIndexedPropertiesPixelData).
|
||||
defineMethod("HasIndexedPropertiesToPixelData", &HasIndexedPropertiesInPixelData).
|
||||
defineMethod("GetIndexedPropertiesPixelDataLength", &GetIndexedPropertiesPixelDataLength).
|
||||
defineMethod("SetIndexedPropertiesToExternalArrayData", &SetIndexedPropertiesToExternalArrayData).
|
||||
defineMethod("HasIndexedPropertiesInExternalArrayData", &HasIndexedPropertiesInExternalArrayData).
|
||||
defineMethod("GetIndexedPropertiesExternalArrayData", &GetIndexedPropertiesExternalArrayData).
|
||||
defineMethod("GetIndexedPropertiesExternalArrayDataType", &GetIndexedPropertiesExternalArrayDataType).
|
||||
defineMethod("GetIndexedPropertiesExternalArrayDataLength", &GetIndexedPropertiesExternalArrayDataLength).
|
||||
defineMethod("IsCallable", &IsCallable).
|
||||
defineMethod("CallAsFunction", &CallAsFunction).
|
||||
defineMethod("CallAsConstructor", &CallAsConstructor).
|
||||
store(&Class);
|
||||
ClassBuilder("PropertyAttribute").
|
||||
defineEnumConst("None", v8::None).
|
||||
defineEnumConst("ReadOnly", v8::ReadOnly).
|
||||
defineEnumConst("DontEnum", v8::DontEnum).
|
||||
defineEnumConst("DontDelete", v8::DontDelete);
|
||||
ClassBuilder("AccessControl").
|
||||
defineEnumConst("DEFAULT", v8::DEFAULT).
|
||||
defineEnumConst("ALL_CAN_READ", v8::ALL_CAN_READ).
|
||||
defineEnumConst("ALL_CAN_WRITE", v8::ALL_CAN_WRITE).
|
||||
defineEnumConst("PROHIBITS_OVERWRITING", v8::PROHIBITS_OVERWRITING);
|
||||
}
|
||||
|
||||
|
||||
VALUE Object::New(VALUE self) {
|
||||
return Object(v8::Object::New());
|
||||
}
|
||||
|
||||
//TODO: Allow setting of property attributes
|
||||
VALUE Object::Set(VALUE self, VALUE key, VALUE value) {
|
||||
if (rb_obj_is_kind_of(key, rb_cNumeric)) {
|
||||
return Bool(Object(self)->Set(UInt32(key), Value(value)));
|
||||
} else {
|
||||
return Bool(Object(self)->Set(*Value(key), Value(value)));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE Object::ForceSet(VALUE self, VALUE key, VALUE value) {
|
||||
return Bool(Object(self)->ForceSet(Value(key), Value(value)));
|
||||
}
|
||||
|
||||
VALUE Object::Get(VALUE self, VALUE key) {
|
||||
if (rb_obj_is_kind_of(key, rb_cNumeric)) {
|
||||
return Value(Object(self)->Get(UInt32(key)));
|
||||
} else {
|
||||
return Value(Object(self)->Get(*Value(key)));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE Object::GetPropertyAttributes(VALUE self, VALUE key) {
|
||||
return PropertyAttribute(Object(self)->GetPropertyAttributes(Value(key)));
|
||||
}
|
||||
|
||||
VALUE Object::Has(VALUE self, VALUE key) {
|
||||
Object obj(self);
|
||||
if (rb_obj_is_kind_of(key, rb_cNumeric)) {
|
||||
return Bool(obj->Has(UInt32(key)));
|
||||
} else {
|
||||
return Bool(obj->Has(*String(key)));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE Object::Delete(VALUE self, VALUE key) {
|
||||
Object obj(self);
|
||||
if (rb_obj_is_kind_of(key, rb_cNumeric)) {
|
||||
return Bool(obj->Delete(UInt32(key)));
|
||||
} else {
|
||||
return Bool(obj->Delete(*String(key)));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE Object::ForceDelete(VALUE self, VALUE key) {
|
||||
return Bool(Object(self)->ForceDelete(Value(key)));
|
||||
}
|
||||
|
||||
|
||||
VALUE Object::SetAccessor(int argc, VALUE* argv, VALUE self) {
|
||||
VALUE name; VALUE get; VALUE set; VALUE data; VALUE settings; VALUE attribs;
|
||||
rb_scan_args(argc, argv, "24", &name, &get, &set, &data, &settings, &attribs);
|
||||
Accessor access(get, set, data);
|
||||
return Bool(Object(self)->SetAccessor(
|
||||
String(name),
|
||||
access.accessorGetter(),
|
||||
access.accessorSetter(),
|
||||
access,
|
||||
AccessControl(settings),
|
||||
PropertyAttribute(attribs))
|
||||
);
|
||||
}
|
||||
|
||||
Object::operator VALUE() {
|
||||
if (handle.IsEmpty()) {
|
||||
return Qnil;
|
||||
}
|
||||
Backref* backref;
|
||||
v8::Local<v8::String> key(v8::String::NewSymbol("rr::Backref"));
|
||||
v8::Local<v8::Value> external = handle->GetHiddenValue(key);
|
||||
VALUE value;
|
||||
if (external.IsEmpty()) {
|
||||
value = downcast();
|
||||
backref = new Backref(value);
|
||||
handle->SetHiddenValue(key, backref->toExternal());
|
||||
} else {
|
||||
v8::Local<v8::External> wrapper = v8::External::Cast(*external);
|
||||
backref = (Backref*)wrapper->Value();
|
||||
value = backref->get();
|
||||
if (!RTEST(value)) {
|
||||
value = downcast();
|
||||
backref->set(value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
VALUE Object::downcast() {
|
||||
if (handle->IsFunction()) {
|
||||
return Function((v8::Handle<v8::Function>) v8::Function::Cast(*handle));
|
||||
}
|
||||
if (handle->IsArray()) {
|
||||
return Array((v8::Handle<v8::Array>)v8::Array::Cast(*handle));
|
||||
}
|
||||
if (handle->IsDate()) {
|
||||
// return Date(handle);
|
||||
}
|
||||
if (handle->IsBooleanObject()) {
|
||||
// return BooleanObject(handle);
|
||||
}
|
||||
if (handle->IsNumberObject()) {
|
||||
// return NumberObject(handle);
|
||||
}
|
||||
if (handle->IsStringObject()) {
|
||||
// return StringObject(handle);
|
||||
}
|
||||
if (handle->IsRegExp()) {
|
||||
// return RegExp(handle);
|
||||
}
|
||||
return Ref<v8::Object>::operator VALUE();
|
||||
}
|
||||
|
||||
VALUE Object::GetPropertyNames(VALUE self) {
|
||||
return Array(Object(self)->GetPropertyNames());
|
||||
}
|
||||
|
||||
VALUE Object::GetOwnPropertyNames(VALUE self) {
|
||||
return Array(Object(self)->GetOwnPropertyNames());
|
||||
}
|
||||
|
||||
VALUE Object::GetPrototype(VALUE self) {
|
||||
return Value(Object(self)->GetPrototype());
|
||||
}
|
||||
|
||||
VALUE Object::SetPrototype(VALUE self, VALUE prototype) {
|
||||
return Bool(Object(self)->SetPrototype(Value(prototype)));
|
||||
}
|
||||
|
||||
VALUE Object::FindInstanceInPrototypeChain(VALUE self, VALUE impl) {
|
||||
return Object(Object(self)->FindInstanceInPrototypeChain(FunctionTemplate(impl)));
|
||||
}
|
||||
|
||||
VALUE Object::ObjectProtoToString(VALUE self) {
|
||||
return String(Object(self)->ObjectProtoToString());
|
||||
}
|
||||
|
||||
VALUE Object::GetConstructorName(VALUE self) {
|
||||
return String(Object(self)->GetConstructorName());
|
||||
}
|
||||
|
||||
VALUE Object::InternalFieldCount(VALUE self) {
|
||||
return INT2FIX(Object(self)->InternalFieldCount());
|
||||
}
|
||||
|
||||
VALUE Object::GetInternalField(VALUE self, VALUE idx) {
|
||||
return Value(Object(self)->GetInternalField(NUM2INT(idx)));
|
||||
}
|
||||
|
||||
VALUE Object::SetInternalField(VALUE self, VALUE idx, VALUE value) {
|
||||
Void(Object(self)->SetInternalField(NUM2INT(idx), Value(value)));
|
||||
}
|
||||
|
||||
VALUE Object::HasOwnProperty(VALUE self, VALUE key) {
|
||||
return Bool(Object(self)->HasOwnProperty(String(key)));
|
||||
}
|
||||
|
||||
VALUE Object::HasRealNamedProperty(VALUE self, VALUE key) {
|
||||
return Bool(Object(self)->HasRealNamedProperty(String(key)));
|
||||
}
|
||||
|
||||
VALUE Object::HasRealIndexedProperty(VALUE self, VALUE idx) {
|
||||
return Bool(Object(self)->HasRealIndexedProperty(UInt32(idx)));
|
||||
}
|
||||
|
||||
VALUE Object::HasRealNamedCallbackProperty(VALUE self, VALUE key) {
|
||||
return Bool(Object(self)->HasRealNamedCallbackProperty(String(key)));
|
||||
}
|
||||
|
||||
VALUE Object::GetRealNamedPropertyInPrototypeChain(VALUE self, VALUE key) {
|
||||
return Value(Object(self)->GetRealNamedPropertyInPrototypeChain(String(key)));
|
||||
}
|
||||
|
||||
VALUE Object::GetRealNamedProperty(VALUE self, VALUE key) {
|
||||
return Value(Object(self)->GetRealNamedProperty(String(key)));
|
||||
}
|
||||
|
||||
VALUE Object::HasNamedLookupInterceptor(VALUE self) {
|
||||
return Bool(Object(self)->HasNamedLookupInterceptor());
|
||||
}
|
||||
|
||||
VALUE Object::HasIndexedLookupInterceptor(VALUE self) {
|
||||
return Bool(Object(self)->HasIndexedLookupInterceptor());
|
||||
}
|
||||
|
||||
VALUE Object::TurnOnAccessCheck(VALUE self) {
|
||||
Void(Object(self)->TurnOnAccessCheck());
|
||||
}
|
||||
|
||||
VALUE Object::GetIdentityHash(VALUE self) {
|
||||
return INT2FIX(Object(self)->GetIdentityHash());
|
||||
}
|
||||
|
||||
VALUE Object::SetHiddenValue(VALUE self, VALUE key, VALUE value) {
|
||||
return Bool(Object(self)->SetHiddenValue(String(key), Value(value)));
|
||||
}
|
||||
|
||||
VALUE Object::GetHiddenValue(VALUE self, VALUE key) {
|
||||
return Value(Object(self)->GetHiddenValue(String(key)));
|
||||
}
|
||||
|
||||
VALUE Object::DeleteHiddenValue(VALUE self, VALUE key) {
|
||||
return Bool(Object(self)->DeleteHiddenValue(String(key)));
|
||||
}
|
||||
|
||||
VALUE Object::IsDirty(VALUE self) {
|
||||
return Bool(Object(self)->IsDirty());
|
||||
}
|
||||
|
||||
VALUE Object::Clone(VALUE self) {
|
||||
return Object(Object(self)->Clone());
|
||||
}
|
||||
|
||||
VALUE Object::CreationContext(VALUE self) {
|
||||
return Context(Object(self)->CreationContext());
|
||||
}
|
||||
|
||||
VALUE Object::SetIndexedPropertiesToPixelData(VALUE self, VALUE data, VALUE length) {
|
||||
return not_implemented("SetIndexedPropertiesToPixelData");
|
||||
}
|
||||
|
||||
VALUE Object::GetIndexedPropertiesPixelData(VALUE self) {
|
||||
return not_implemented("GetIndexedPropertiesPixelData");
|
||||
}
|
||||
|
||||
VALUE Object::HasIndexedPropertiesInPixelData(VALUE self) {
|
||||
return Bool(Object(self)->HasIndexedPropertiesInPixelData());
|
||||
}
|
||||
|
||||
VALUE Object::GetIndexedPropertiesPixelDataLength(VALUE self) {
|
||||
return INT2FIX(Object(self)->GetIndexedPropertiesPixelDataLength());
|
||||
}
|
||||
|
||||
VALUE Object::SetIndexedPropertiesToExternalArrayData(VALUE self) {
|
||||
return not_implemented("SetIndexedPropertiesToExternalArrayData");
|
||||
}
|
||||
|
||||
VALUE Object::HasIndexedPropertiesInExternalArrayData(VALUE self) {
|
||||
return Bool(Object(self)->HasIndexedPropertiesInExternalArrayData());
|
||||
}
|
||||
|
||||
VALUE Object::GetIndexedPropertiesExternalArrayData(VALUE self) {
|
||||
return not_implemented("GetIndexedPropertiesExternalArrayData");
|
||||
}
|
||||
|
||||
VALUE Object::GetIndexedPropertiesExternalArrayDataType(VALUE self) {
|
||||
return not_implemented("GetIndexedPropertiesExternalArrayDataType");
|
||||
}
|
||||
|
||||
VALUE Object::GetIndexedPropertiesExternalArrayDataLength(VALUE self) {
|
||||
return INT2FIX(Object(self)->GetIndexedPropertiesExternalArrayDataLength());
|
||||
}
|
||||
|
||||
VALUE Object::IsCallable(VALUE self) {
|
||||
return Bool(Object(self)->IsCallable());
|
||||
}
|
||||
|
||||
VALUE Object::CallAsFunction(VALUE self, VALUE recv, VALUE argv) {
|
||||
return Value(Object(self)->CallAsFunction(Object(recv), RARRAY_LENINT(argv), Value::array<Value>(argv)));
|
||||
}
|
||||
|
||||
VALUE Object::CallAsConstructor(VALUE self, VALUE argv) {
|
||||
return Value(Object(self)->CallAsConstructor(RARRAY_LENINT(argv), Value::array<Value>(argv)));
|
||||
}
|
||||
|
||||
}
|
||||
71
ext/v8/pointer.h
Normal file
71
ext/v8/pointer.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef RR_POINTER
|
||||
#define RR_POINTER
|
||||
|
||||
namespace rr {
|
||||
|
||||
/**
|
||||
* A pointer to V8 object managed by Ruby
|
||||
*
|
||||
* You deal with V8 objects as either pointers or handles.
|
||||
* While handles are managed by the V8 garbage collector, pointers
|
||||
* must be explicitly created and destroyed by your code.
|
||||
*
|
||||
* The pointer class provides a handly way to wrap V8 pointers
|
||||
* into Ruby objects so that they will be deleted when the
|
||||
* Ruby object is garbage collected. Automatic type coercion is
|
||||
* used to make wrapping and unwrapping painless.
|
||||
*
|
||||
* To create Ruby VALUE:
|
||||
*
|
||||
* Pointer<v8::ScriptOrigin> ptr(new v8::ScriptOrigin());
|
||||
* VALUE value = ptr; //automatically wraps in Data_Wrap_Struct
|
||||
*
|
||||
* Conversely, the pointer can be unwrapped from a struct
|
||||
* created in this way and the underlying methods can be
|
||||
* invoked:
|
||||
*
|
||||
* VALUE value = ...;
|
||||
* Pointer<v8::ScriptOrigin> ptr(value);
|
||||
* ptr->CallMethod();
|
||||
*/
|
||||
template <class T>
|
||||
class Pointer {
|
||||
public:
|
||||
inline Pointer(T* t) : pointer(t) {};
|
||||
inline Pointer(VALUE v) {
|
||||
if (RTEST(v)) {
|
||||
this->unwrap(v);
|
||||
} else {
|
||||
this->pointer = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
inline operator T*() {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
inline T* operator ->() {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
inline operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, &release, pointer);
|
||||
}
|
||||
|
||||
void unwrap(VALUE value);
|
||||
|
||||
static void release(T* pointer) {
|
||||
delete pointer;
|
||||
}
|
||||
|
||||
static VALUE Class;
|
||||
|
||||
protected:
|
||||
T* pointer;
|
||||
};
|
||||
|
||||
template <class T> VALUE Pointer<T>::Class;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Primitive::Init() {
|
||||
ClassBuilder("Primitive", Value::Class).
|
||||
store(&Class);
|
||||
}
|
||||
}
|
||||
931
ext/v8/rr.h
931
ext/v8/rr.h
|
|
@ -1,934 +1,21 @@
|
|||
#ifndef THE_RUBY_RACER
|
||||
#define THE_RUBY_RACER
|
||||
|
||||
#include <v8.h>
|
||||
#include <include/v8.h>
|
||||
#include <include/libplatform/libplatform.h>
|
||||
|
||||
#include <ruby.h>
|
||||
#include <vector>
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
#include "ruby/encoding.h"
|
||||
#endif
|
||||
|
||||
#if !defined(RARRAY_LENINT)
|
||||
# define RARRAY_LENINT(v) (int)RARRAY_LEN(v)
|
||||
#endif /* ! defined(RARRAY_LENINT) */
|
||||
#include "class_builder.h"
|
||||
#include "pointer.h"
|
||||
|
||||
#if !defined(SIZET2NUM)
|
||||
# if SIZEOF_SIZE_T == SIZEOF_LONG
|
||||
# define SIZET2NUM(n) ULONG2NUM(n)
|
||||
# else
|
||||
# define SIZET2NUM(n) ULL2NUM(n)
|
||||
# endif
|
||||
#endif /* ! defined(SIZET2NUM) */
|
||||
|
||||
#if !defined(NUM2SIZET)
|
||||
# if SIZEOF_SIZE_T == SIZEOF_LONG
|
||||
# define NUM2SIZET(n) ((size_t)NUM2ULONG(n))
|
||||
# else
|
||||
# define NUM2SIZET(n) ((size_t)NUM2ULL(n))
|
||||
# endif
|
||||
#endif /* ! defined(NUM2SIZET) */
|
||||
|
||||
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) {}
|
||||
Bool(v8::Handle<v8::Boolean> b) : Equiv(b->Value() ? Qtrue : Qfalse) {}
|
||||
inline operator bool() {return RTEST(value);}
|
||||
};
|
||||
|
||||
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 T> class Enum : public Equiv {
|
||||
public:
|
||||
Enum<T>(VALUE value, T defaultValue = 0) : Equiv(value) {
|
||||
this->defaultValue = defaultValue;
|
||||
}
|
||||
inline operator T() {
|
||||
return (T)(RTEST(value) ? NUM2INT(value) : defaultValue);
|
||||
}
|
||||
private:
|
||||
T defaultValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pointer to V8 object managed by Ruby
|
||||
*
|
||||
* You deal with V8 objects as either pointers or handles.
|
||||
* While handles are managed by the V8 garbage collector, pointers
|
||||
* must be explicitly created and destroyed by your code.
|
||||
*
|
||||
* The pointer class provides a handly way to wrap V8 pointers
|
||||
* into Ruby objects so that they will be deleted when the
|
||||
* Ruby object is garbage collected. Automatic type coercion is
|
||||
* used to make wrapping and unwrapping painless.
|
||||
*
|
||||
* To create Ruby VALUE:
|
||||
*
|
||||
* Pointer<v8::ScriptOrigin> ptr(new v8::ScriptOrigin());
|
||||
* VALUE value = ptr; //automatically wraps in Data_Wrap_Struct
|
||||
*
|
||||
* Conversely, the pointer can be unwrapped from a struct
|
||||
* created in this way and the underlying methods can be
|
||||
* invoked:
|
||||
*
|
||||
* VALUE value = ...;
|
||||
* Pointer<v8::ScriptOrigin> ptr(value);
|
||||
* ptr->CallMethod();
|
||||
*/
|
||||
|
||||
template <class T> class Pointer {
|
||||
public:
|
||||
inline Pointer(T* t) : pointer(t) {};
|
||||
inline Pointer(VALUE v) {
|
||||
if (RTEST(v)) {
|
||||
this->unwrap(v);
|
||||
} else {
|
||||
this->pointer = NULL;
|
||||
}
|
||||
};
|
||||
inline operator T*() {return pointer;}
|
||||
inline T* operator ->() {return pointer;}
|
||||
inline operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, &release, pointer);
|
||||
}
|
||||
void unwrap(VALUE value);
|
||||
static void release(T* pointer) {
|
||||
delete pointer;
|
||||
}
|
||||
static VALUE Class;
|
||||
protected:
|
||||
T* pointer;
|
||||
};
|
||||
template <class T> VALUE Pointer<T>::Class;
|
||||
|
||||
/**
|
||||
* A Reference to a V8 managed object
|
||||
*
|
||||
* Uses type coercion to quickly convert from a v8 handle
|
||||
* to a ruby object and back again. Suppose we have a v8 handle
|
||||
* that we want to return to Ruby. We can put it into a Ref:
|
||||
*
|
||||
* v8::Handle<v8::Object> object = v8::Object::New();
|
||||
* VALUE val = Ref<v8::Object>(object);
|
||||
*
|
||||
* this will create a `v8::Persistent` handle for the object
|
||||
* so that it will not be garbage collected by v8. It then
|
||||
* stuffs this new persistent handle into a Data_Wrap_Struct
|
||||
* which can then be passed to Ruby code. When this struct
|
||||
* is garbage collected by Ruby, it enqueues the corresponding
|
||||
* v8 handle to be released during v8 gc.
|
||||
*
|
||||
* By the same token, you can use Refs to unwrap a Data_Wrap_Struct
|
||||
* which has been generated in this fashion and call through to
|
||||
* the underlying v8 methods. Suppose we are passed a VALUE `val`
|
||||
* wrapping a v8::Object:
|
||||
*
|
||||
* Ref<v8::Object> object(val);
|
||||
* object->Get(v8::String::New("foo"));
|
||||
*
|
||||
*/
|
||||
template <class T> class Ref {
|
||||
public:
|
||||
Ref(VALUE value) {
|
||||
this->value = value;
|
||||
}
|
||||
Ref(v8::Handle<T> handle, const char* label = "v8::Handle<void>") {
|
||||
this->handle = handle;
|
||||
}
|
||||
virtual ~Ref() {}
|
||||
/*
|
||||
* Coerce a Ref into a Ruby VALUE
|
||||
*/
|
||||
virtual operator VALUE() const {
|
||||
return handle.IsEmpty() ? Qnil : Data_Wrap_Struct(Class, 0, &Holder::enqueue, new Holder(handle));
|
||||
}
|
||||
/*
|
||||
* Coerce a Ref into a v8::Handle.
|
||||
*/
|
||||
virtual operator v8::Handle<T>() const {
|
||||
if (RTEST(this->value)) {
|
||||
Holder* holder = NULL;
|
||||
Data_Get_Struct(this->value, class Holder, holder);
|
||||
return holder->handle;
|
||||
} else {
|
||||
return v8::Handle<T>();
|
||||
}
|
||||
}
|
||||
void dispose() {
|
||||
Holder* holder = NULL;
|
||||
Data_Get_Struct(this->value, class Holder, holder);
|
||||
holder->dispose();
|
||||
}
|
||||
|
||||
/*
|
||||
* Pointer de-reference operators, this lets you use a ref to
|
||||
* call through to underlying v8 methods. e.g
|
||||
*
|
||||
* Ref<v8::Object>(value)->ToString();
|
||||
*/
|
||||
inline v8::Handle<T> operator->() const { return *this;}
|
||||
inline v8::Handle<T> operator*() const {return *this;}
|
||||
|
||||
template <class C> class array {
|
||||
public:
|
||||
inline array(VALUE ary) : argv(ary), vector(RARRAY_LENINT(argv)) {}
|
||||
inline operator v8::Handle<T>*() {
|
||||
for (uint32_t i = 0; i < vector.size(); i++) {
|
||||
vector[i] = C(rb_ary_entry(argv, i));
|
||||
}
|
||||
return &vector[0];
|
||||
}
|
||||
private:
|
||||
VALUE argv;
|
||||
std::vector< v8::Handle<T> > vector;
|
||||
};
|
||||
|
||||
class Holder {
|
||||
friend class Ref;
|
||||
public:
|
||||
Holder(v8::Handle<T> handle) {
|
||||
this->disposed_p = false;
|
||||
this->handle = v8::Persistent<T>::New(handle);
|
||||
}
|
||||
virtual ~Holder() {
|
||||
this->dispose();
|
||||
}
|
||||
void dispose() {
|
||||
if (!this->disposed_p) {
|
||||
handle.Dispose();
|
||||
this->disposed_p = true;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
v8::Persistent<T> handle;
|
||||
bool disposed_p;
|
||||
|
||||
static void enqueue(Holder* holder) {
|
||||
GC::Finalize(holder);
|
||||
}
|
||||
};
|
||||
|
||||
VALUE value;
|
||||
v8::Handle<T> handle;
|
||||
static VALUE Class;
|
||||
};
|
||||
template <class T> VALUE Ref<T>::Class;
|
||||
|
||||
class Backref {
|
||||
public:
|
||||
static void Init();
|
||||
Backref(VALUE value);
|
||||
virtual ~Backref();
|
||||
VALUE get();
|
||||
VALUE set(VALUE value);
|
||||
v8::Handle<v8::Value> toExternal();
|
||||
static void release(v8::Persistent<v8::Value> handle, void* data);
|
||||
private:
|
||||
VALUE storage;
|
||||
static VALUE Storage;
|
||||
static ID _new;
|
||||
static ID object;
|
||||
};
|
||||
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<void>::Holder*)reference) {}
|
||||
inline bool NotNull() {
|
||||
return this->holder != NULL;
|
||||
}
|
||||
inline void destroy() {
|
||||
delete holder;
|
||||
}
|
||||
Ref<void>::Holder* holder;
|
||||
};
|
||||
|
||||
class ExtensionConfiguration : public Pointer<v8::ExtensionConfiguration> {
|
||||
public:
|
||||
static VALUE initialize(VALUE self, VALUE names);
|
||||
inline ExtensionConfiguration(v8::ExtensionConfiguration* config) : Pointer<v8::ExtensionConfiguration>(config) {}
|
||||
inline ExtensionConfiguration(VALUE value) : Pointer<v8::ExtensionConfiguration>(value) {}
|
||||
};
|
||||
|
||||
class Context : public Ref<v8::Context> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE Dispose(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 SetEmbedderData(VALUE self, VALUE index, VALUE data);
|
||||
static VALUE GetEmbedderData(VALUE self, VALUE index);
|
||||
static VALUE AllowCodeGenerationFromStrings(VALUE self, VALUE allow);
|
||||
static VALUE IsCodeGenerationFromStringsAllowed(VALUE self);
|
||||
|
||||
inline Context(VALUE value) : Ref<v8::Context>(value) {}
|
||||
inline Context(v8::Handle<v8::Context> cxt) : Ref<v8::Context>(cxt) {}
|
||||
};
|
||||
|
||||
class External: public Ref<v8::External> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(VALUE self, VALUE data);
|
||||
static VALUE Value(VALUE self);
|
||||
|
||||
inline External(VALUE value) : Ref<v8::External>(value) {}
|
||||
inline External(v8::Handle<v8::External> ext) : Ref<v8::External>(ext) {}
|
||||
static v8::Handle<v8::External> wrap(VALUE data);
|
||||
static VALUE unwrap(v8::Handle<v8::External> external);
|
||||
private:
|
||||
static void release(v8::Persistent<v8::Value> object, void* parameter);
|
||||
struct Data {
|
||||
Data(VALUE data);
|
||||
~Data();
|
||||
VALUE value;
|
||||
};
|
||||
};
|
||||
|
||||
class ScriptOrigin : public Pointer<v8::ScriptOrigin> {
|
||||
public:
|
||||
inline ScriptOrigin(v8::ScriptOrigin* o) : Pointer<v8::ScriptOrigin>(o) {};
|
||||
inline ScriptOrigin(VALUE value) : Pointer<v8::ScriptOrigin>(value) {}
|
||||
|
||||
static VALUE initialize(int argc, VALUE argv[], VALUE self);
|
||||
};
|
||||
|
||||
class ScriptData : public Pointer<v8::ScriptData> {
|
||||
public:
|
||||
inline ScriptData(v8::ScriptData* d) : Pointer<v8::ScriptData>(d) {};
|
||||
inline ScriptData(VALUE value) : Pointer<v8::ScriptData>(value) {}
|
||||
|
||||
static VALUE PreCompile(VALUE self, VALUE input, VALUE length);
|
||||
static VALUE New(VALUE self, VALUE data, VALUE length);
|
||||
static VALUE Length(VALUE self);
|
||||
static VALUE Data(VALUE self);
|
||||
static VALUE HasError(VALUE self);
|
||||
};
|
||||
|
||||
class Script : public Ref<v8::Script> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE Run(VALUE self);
|
||||
static VALUE RunWithTimeout(VALUE self, VALUE timeout);
|
||||
|
||||
inline Script(VALUE value) : Ref<v8::Script>(value) {}
|
||||
inline Script(v8::Handle<v8::Script> script) : Ref<v8::Script>(script) {}
|
||||
};
|
||||
|
||||
class Value : public Ref<v8::Value> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE IsUndefined(VALUE self);
|
||||
static VALUE IsNull(VALUE self);
|
||||
static VALUE IsTrue(VALUE self);
|
||||
static VALUE IsFalse(VALUE self);
|
||||
static VALUE IsString(VALUE self);
|
||||
static VALUE IsFunction(VALUE self);
|
||||
static VALUE IsArray(VALUE self);
|
||||
static VALUE IsObject(VALUE self);
|
||||
static VALUE IsBoolean(VALUE self);
|
||||
static VALUE IsNumber(VALUE self);
|
||||
static VALUE IsExternal(VALUE self);
|
||||
static VALUE IsInt32(VALUE self);
|
||||
static VALUE IsUint32(VALUE self);
|
||||
static VALUE IsDate(VALUE self);
|
||||
static VALUE IsBooleanObject(VALUE self);
|
||||
static VALUE IsNumberObject(VALUE self);
|
||||
static VALUE IsStringObject(VALUE self);
|
||||
static VALUE IsNativeError(VALUE self);
|
||||
static VALUE IsRegExp(VALUE self);
|
||||
// VALUE ToBoolean(VALUE self);
|
||||
// VALUE ToNumber(VALUE self);
|
||||
static VALUE ToString(VALUE self);
|
||||
static VALUE ToDetailString(VALUE self);
|
||||
static VALUE ToObject(VALUE self);
|
||||
// static VALUE ToInteger(VALUE self);
|
||||
// static VALUE ToUint32(VALUE self);
|
||||
// static VALUE ToInt32(VALUE self);
|
||||
// static VALUE ToArrayIndex(VALUE self);
|
||||
static VALUE BooleanValue(VALUE self);
|
||||
static VALUE NumberValue(VALUE self);
|
||||
static VALUE IntegerValue(VALUE self);
|
||||
static VALUE Uint32Value(VALUE self);
|
||||
static VALUE Int32Value(VALUE self);
|
||||
|
||||
static VALUE Equals(VALUE self, VALUE other);
|
||||
static VALUE StrictEquals(VALUE self, VALUE other);
|
||||
inline Value(VALUE value) : Ref<v8::Value>(value) {}
|
||||
inline Value(v8::Handle<v8::Value> value) : Ref<v8::Value>(value) {}
|
||||
virtual operator VALUE();
|
||||
virtual operator v8::Handle<v8::Value>() const;
|
||||
static VALUE Empty;
|
||||
};
|
||||
|
||||
class Primitive: public Ref<v8::Primitive> {
|
||||
public:
|
||||
static void Init();
|
||||
inline Primitive(VALUE value) : Ref<v8::Primitive>(value) {}
|
||||
inline Primitive(v8::Handle<v8::Primitive> primitive) : Ref<v8::Primitive>(primitive) {}
|
||||
};
|
||||
|
||||
class String: public Ref<v8::String> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(VALUE self, VALUE value);
|
||||
static VALUE NewSymbol(VALUE self, VALUE string);
|
||||
static VALUE Utf8Value(VALUE self);
|
||||
static VALUE Concat(VALUE self, VALUE left, VALUE right);
|
||||
|
||||
inline String(VALUE value) : Ref<v8::String>(value) {}
|
||||
inline String(v8::Handle<v8::String> string) : Ref<v8::String>(string) {}
|
||||
virtual operator v8::Handle<v8::String>() const;
|
||||
};
|
||||
|
||||
class PropertyAttribute: public Enum<v8::PropertyAttribute> {
|
||||
public:
|
||||
inline PropertyAttribute(VALUE value) : Enum<v8::PropertyAttribute>(value, v8::None) {}
|
||||
};
|
||||
class AccessControl: public Enum<v8::AccessControl> {
|
||||
public:
|
||||
inline AccessControl(VALUE value) : Enum<v8::AccessControl>(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<v8::Value> 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<v8::Value>();
|
||||
|
||||
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<v8::Value> get(v8::Local<v8::String> property);
|
||||
v8::Handle<v8::Value> set(v8::Local<v8::String> property, v8::Local<v8::Value> value);
|
||||
v8::Handle<v8::Integer> query(v8::Local<v8::String> property);
|
||||
v8::Handle<v8::Boolean> remove(v8::Local<v8::String> property);
|
||||
v8::Handle<v8::Array> enumerateNames();
|
||||
v8::Handle<v8::Value> get(uint32_t index);
|
||||
v8::Handle<v8::Value> set(uint32_t index, v8::Local<v8::Value> value);
|
||||
v8::Handle<v8::Integer> query(uint32_t index);
|
||||
v8::Handle<v8::Boolean> remove(uint32_t index);
|
||||
v8::Handle<v8::Array> enumerateIndices();
|
||||
|
||||
static VALUE Class;
|
||||
private:
|
||||
const v8::AccessorInfo* info;
|
||||
};
|
||||
friend class Info;
|
||||
private:
|
||||
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);
|
||||
|
||||
static v8::Handle<v8::Value> NamedPropertyGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Value> NamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Integer> NamedPropertyQuery(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Boolean> NamedPropertyDeleter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Array> NamedPropertyEnumerator(const v8::AccessorInfo& info);
|
||||
|
||||
static v8::Handle<v8::Value> IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Value> IndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Integer> IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Boolean> IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Array> IndexedPropertyEnumerator(const v8::AccessorInfo& info);
|
||||
|
||||
void wrap(v8::Handle<v8::Object> wrapper, int index, VALUE value);
|
||||
VALUE unwrap(v8::Handle<v8::Object> 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<v8::Value> wrapper);
|
||||
operator v8::InvocationCallback();
|
||||
operator v8::Handle<v8::Value>();
|
||||
static v8::Handle<v8::Value> 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<v8::Value> 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<v8::Object> {
|
||||
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 argv);
|
||||
static VALUE CallAsConstructor(VALUE self, VALUE argv);
|
||||
|
||||
inline Object(VALUE value) : Ref<v8::Object>(value) {}
|
||||
inline Object(v8::Handle<v8::Object> object) : Ref<v8::Object>(object) {}
|
||||
virtual operator VALUE();
|
||||
|
||||
protected:
|
||||
VALUE downcast();
|
||||
};
|
||||
|
||||
class Array : public Ref<v8::Array> {
|
||||
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<v8::Array> array) : Ref<v8::Array>(array) {}
|
||||
inline Array(VALUE value) : Ref<v8::Array>(value) {}
|
||||
};
|
||||
|
||||
class Function : public Ref<v8::Function> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE NewInstance(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE Call(VALUE self, VALUE receiver, 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<v8::Function>(value) {}
|
||||
inline Function(v8::Handle<v8::Function> function) : Ref<v8::Function>(function) {}
|
||||
};
|
||||
|
||||
class Date : public Ref<v8::Date> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(VALUE self, VALUE time);
|
||||
static VALUE NumberValue(VALUE self);
|
||||
|
||||
inline Date(VALUE value) : Ref<v8::Date>(value) {}
|
||||
inline Date(v8::Handle<v8::Date> date) : Ref<v8::Date>(date) {}
|
||||
};
|
||||
|
||||
class Signature : public Ref<v8::Signature> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(int argc, VALUE argv[], VALUE self);
|
||||
|
||||
inline Signature(v8::Handle<v8::Signature> sig) : Ref<v8::Signature>(sig) {}
|
||||
inline Signature(VALUE value) : Ref<v8::Signature>(value) {}
|
||||
};
|
||||
|
||||
class Template : public Ref<v8::Template> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE Set(int argc, VALUE argv[], VALUE self);
|
||||
inline Template(v8::Handle<v8::Template> t) : Ref<v8::Template>(t) {}
|
||||
inline Template(VALUE value) : Ref<v8::Template>(value) {}
|
||||
};
|
||||
|
||||
class ObjectTemplate : public Ref<v8::ObjectTemplate> {
|
||||
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<v8::ObjectTemplate>(value) {}
|
||||
inline ObjectTemplate(v8::Handle<v8::ObjectTemplate> t) : Ref<v8::ObjectTemplate>(t) {}
|
||||
};
|
||||
|
||||
class FunctionTemplate : public Ref<v8::FunctionTemplate> {
|
||||
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<v8::FunctionTemplate>(value) {}
|
||||
inline FunctionTemplate(v8::Handle<v8::FunctionTemplate> t) : Ref<v8::FunctionTemplate>(t) {}
|
||||
};
|
||||
|
||||
class Message : public Ref<v8::Message> {
|
||||
public:
|
||||
static void Init();
|
||||
inline Message(v8::Handle<v8::Message> message) : Ref<v8::Message>(message) {}
|
||||
inline Message(VALUE value) : Ref<v8::Message>(value) {}
|
||||
|
||||
static VALUE Get(VALUE self);
|
||||
static VALUE GetSourceLine(VALUE self);
|
||||
static VALUE GetScriptResourceName(VALUE self);
|
||||
static VALUE GetScriptData(VALUE self);
|
||||
static VALUE GetStackTrace(VALUE self);
|
||||
static VALUE GetLineNumber(VALUE self);
|
||||
static VALUE GetStartPosition(VALUE self);
|
||||
static VALUE GetEndPosition(VALUE self);
|
||||
static VALUE GetStartColumn(VALUE self);
|
||||
static VALUE GetEndColumn(VALUE self);
|
||||
static inline VALUE kNoLineNumberInfo(VALUE self) {return INT2FIX(v8::Message::kNoLineNumberInfo);}
|
||||
static inline VALUE kNoColumnInfo(VALUE self) {return INT2FIX(v8::Message::kNoColumnInfo);}
|
||||
};
|
||||
|
||||
class Stack {
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
class Trace : public Ref<v8::StackTrace> {
|
||||
public:
|
||||
class StackTraceOptions : public Enum<v8::StackTrace::StackTraceOptions> {
|
||||
public:
|
||||
inline StackTraceOptions(VALUE value) : Enum<v8::StackTrace::StackTraceOptions>(value, v8::StackTrace::kOverview) {}
|
||||
};
|
||||
public:
|
||||
inline Trace(v8::Handle<v8::StackTrace> trace) : Ref<v8::StackTrace>(trace) {}
|
||||
inline Trace(VALUE value) : Ref<v8::StackTrace>(value) {}
|
||||
static inline VALUE kLineNumber(VALUE self) {return INT2FIX(v8::StackTrace::kLineNumber);}
|
||||
static inline VALUE kColumnOffset(VALUE self) {return INT2FIX(v8::StackTrace::kColumnOffset);}
|
||||
static inline VALUE kScriptName(VALUE self) {return INT2FIX(v8::StackTrace::kScriptName);}
|
||||
static inline VALUE kFunctionName(VALUE self) {return INT2FIX(v8::StackTrace::kFunctionName);}
|
||||
static inline VALUE kIsEval(VALUE self) {return INT2FIX(v8::StackTrace::kIsEval);}
|
||||
static inline VALUE kIsConstructor(VALUE self) {return INT2FIX(v8::StackTrace::kIsConstructor);}
|
||||
static inline VALUE kScriptNameOrSourceURL(VALUE self) {return INT2FIX(v8::StackTrace::kScriptNameOrSourceURL);}
|
||||
static inline VALUE kOverview(VALUE self) {return INT2FIX(v8::StackTrace::kOverview);}
|
||||
static inline VALUE kDetailed(VALUE self) {return INT2FIX(v8::StackTrace::kDetailed);}
|
||||
|
||||
static VALUE GetFrame(VALUE self, VALUE index);
|
||||
static VALUE GetFrameCount(VALUE self);
|
||||
static VALUE AsArray(VALUE self);
|
||||
static VALUE CurrentStackTrace(int argc, VALUE argv[], VALUE self);
|
||||
};
|
||||
class Frame : public Ref<v8::StackFrame> {
|
||||
public:
|
||||
inline Frame(v8::Handle<v8::StackFrame> frame) : Ref<v8::StackFrame>(frame) {}
|
||||
inline Frame(VALUE value) : Ref<v8::StackFrame>(value) {}
|
||||
static VALUE GetLineNumber(VALUE self);
|
||||
static VALUE GetColumn(VALUE self);
|
||||
static VALUE GetScriptName(VALUE self);
|
||||
static VALUE GetScriptNameOrSourceURL(VALUE self);
|
||||
static VALUE GetFunctionName(VALUE self);
|
||||
static VALUE IsEval(VALUE self);
|
||||
static VALUE IsConstructor(VALUE self);
|
||||
};
|
||||
};
|
||||
|
||||
class TryCatch {
|
||||
public:
|
||||
static void Init();
|
||||
TryCatch(v8::TryCatch*);
|
||||
TryCatch(VALUE value);
|
||||
operator VALUE();
|
||||
inline v8::TryCatch* operator->() {return this->impl;}
|
||||
static VALUE HasCaught(VALUE self);
|
||||
static VALUE CanContinue(VALUE self);
|
||||
static VALUE ReThrow(VALUE self);
|
||||
static VALUE Exception(VALUE self);
|
||||
static VALUE StackTrace(VALUE self);
|
||||
static VALUE Message(VALUE self);
|
||||
static VALUE Reset(VALUE self);
|
||||
static VALUE SetVerbose(VALUE self, VALUE value);
|
||||
static VALUE SetCaptureMessage(VALUE self, VALUE value);
|
||||
private:
|
||||
static VALUE doTryCatch(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE setupAndCall(int* state, VALUE code);
|
||||
static VALUE doCall(VALUE code);
|
||||
static VALUE Class;
|
||||
v8::TryCatch* impl;
|
||||
};
|
||||
|
||||
class Locker {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE StartPreemption(VALUE self, VALUE every_n_ms);
|
||||
static VALUE StopPreemption(VALUE self);
|
||||
static VALUE IsLocked(VALUE self);
|
||||
static VALUE IsActive(VALUE self);
|
||||
static VALUE doLock(int argc, VALUE* argv, VALUE self);
|
||||
static VALUE setupLockAndCall(int* state, VALUE code);
|
||||
static VALUE doLockCall(VALUE code);
|
||||
static VALUE doUnlock(int argc, VALUE* argv, VALUE self);
|
||||
static VALUE setupUnlockAndCall(int* state, VALUE code);
|
||||
static VALUE doUnlockCall(VALUE code);
|
||||
};
|
||||
|
||||
class HeapStatistics : public Pointer<v8::HeapStatistics> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE initialize(VALUE self);
|
||||
static VALUE total_heap_size(VALUE self);
|
||||
static VALUE total_heap_size_executable(VALUE self);
|
||||
static VALUE total_physical_size(VALUE self);
|
||||
static VALUE used_heap_size(VALUE self);
|
||||
static VALUE heap_size_limit(VALUE self);
|
||||
|
||||
inline HeapStatistics(v8::HeapStatistics* stats) : Pointer<v8::HeapStatistics>(stats) {}
|
||||
inline HeapStatistics(VALUE value) : Pointer<v8::HeapStatistics>(value) {}
|
||||
};
|
||||
|
||||
class ResourceConstraints : Pointer<v8::ResourceConstraints> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE initialize(VALUE self);
|
||||
static VALUE max_young_space_size(VALUE self);
|
||||
static VALUE set_max_young_space_size(VALUE self, VALUE value);
|
||||
static VALUE max_old_space_size(VALUE self);
|
||||
static VALUE set_max_old_space_size(VALUE self, VALUE value);
|
||||
static VALUE max_executable_size(VALUE self);
|
||||
static VALUE set_max_executable_size(VALUE self, VALUE value);
|
||||
|
||||
static VALUE SetResourceConstraints(VALUE self, VALUE constraints);
|
||||
|
||||
inline ResourceConstraints(v8::ResourceConstraints* o) : Pointer<v8::ResourceConstraints>(o) {};
|
||||
inline ResourceConstraints(VALUE value) : Pointer<v8::ResourceConstraints>(value) {}
|
||||
};
|
||||
|
||||
class Exception {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE ThrowException(VALUE self, VALUE exception);
|
||||
static VALUE RangeError(VALUE self, VALUE message);
|
||||
static VALUE ReferenceError(VALUE self, VALUE message);
|
||||
static VALUE SyntaxError(VALUE self, VALUE message);
|
||||
static VALUE TypeError(VALUE self, VALUE message);
|
||||
static VALUE Error(VALUE self, VALUE message);
|
||||
};
|
||||
|
||||
class Constants {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE Undefined(VALUE self);
|
||||
static VALUE Null(VALUE self);
|
||||
static VALUE True(VALUE self);
|
||||
static VALUE False(VALUE self);
|
||||
|
||||
private:
|
||||
template <class R, class V> static VALUE cached(VALUE* storage, v8::Handle<V> value) {
|
||||
if (!RTEST(*storage)) {
|
||||
*storage = R(value);
|
||||
}
|
||||
return *storage;
|
||||
}
|
||||
static VALUE _Undefined;
|
||||
static VALUE _Null;
|
||||
static VALUE _True;
|
||||
static VALUE _False;
|
||||
};
|
||||
|
||||
class V8 {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE IdleNotification(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE SetFlagsFromString(VALUE self, VALUE string);
|
||||
static VALUE SetFlagsFromCommandLine(VALUE self, VALUE args, VALUE remove_flags);
|
||||
static VALUE AdjustAmountOfExternalAllocatedMemory(VALUE self, VALUE change_in_bytes);
|
||||
static VALUE PauseProfiler(VALUE self);
|
||||
static VALUE ResumeProfiler(VALUE self);
|
||||
static VALUE IsProfilerPaused(VALUE self);
|
||||
static VALUE GetCurrentThreadId(VALUE self);
|
||||
static VALUE TerminateExecution(VALUE self, VALUE thread_id);
|
||||
static VALUE IsExecutionTerminating(VALUE self);
|
||||
static VALUE Dispose(VALUE self);
|
||||
static VALUE LowMemoryNotification(VALUE self);
|
||||
static VALUE ContextDisposedNotification(VALUE self);
|
||||
|
||||
static VALUE SetCaptureStackTraceForUncaughtExceptions(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE GetHeapStatistics(VALUE self, VALUE statistics_ptr);
|
||||
static VALUE GetVersion(VALUE self);
|
||||
};
|
||||
|
||||
class ClassBuilder {
|
||||
public:
|
||||
ClassBuilder() {};
|
||||
ClassBuilder(const char* name, VALUE superclass = rb_cObject);
|
||||
ClassBuilder(const char* name, const char* supername);
|
||||
ClassBuilder& defineConst(const char* name, VALUE value);
|
||||
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;}
|
||||
protected:
|
||||
VALUE value;
|
||||
};
|
||||
|
||||
class ModuleBuilder : public ClassBuilder {
|
||||
public:
|
||||
inline ModuleBuilder(const char* name) {
|
||||
this->value = rb_eval_string(name);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#include "v8.h"
|
||||
#include "isolate.h"
|
||||
#include "handles.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
115
ext/v8/script.cc
115
ext/v8/script.cc
|
|
@ -1,115 +0,0 @@
|
|||
#include "rr.h"
|
||||
#include "pthread.h"
|
||||
#include "unistd.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Script::Init() {
|
||||
ClassBuilder("Script").
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("Run", &Run).
|
||||
defineMethod("RunWithTimeout", &RunWithTimeout).
|
||||
store(&Class);
|
||||
ClassBuilder("ScriptOrigin").
|
||||
defineSingletonMethod("new", &ScriptOrigin::initialize).
|
||||
store(&ScriptOrigin::Class);
|
||||
ClassBuilder("ScriptData").
|
||||
defineSingletonMethod("PreCompile", &ScriptData::PreCompile).
|
||||
defineSingletonMethod("New", &ScriptData::New).
|
||||
defineMethod("Length", &ScriptData::Length).
|
||||
defineMethod("Data", &ScriptData::Data).
|
||||
defineMethod("HasError", &ScriptData::HasError).
|
||||
store(&ScriptData::Class);
|
||||
}
|
||||
|
||||
VALUE ScriptOrigin::initialize(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE name; VALUE line_offset; VALUE column_offset;
|
||||
rb_scan_args(argc, argv, "12", &name, &line_offset, &column_offset);
|
||||
v8::Handle<v8::Integer> loff = v8::Integer::New(RTEST(line_offset) ? NUM2INT(line_offset) : 0);
|
||||
v8::Handle<v8::Integer> coff = v8::Integer::New(RTEST(column_offset) ? NUM2INT(column_offset) : 0);
|
||||
return ScriptOrigin(new v8::ScriptOrigin(*String(name), loff, coff));
|
||||
}
|
||||
|
||||
VALUE ScriptData::PreCompile(VALUE self, VALUE input, VALUE length) {
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
if (!rb_equal(rb_enc_from_encoding(rb_utf8_encoding()), rb_obj_encoding(input))) {
|
||||
rb_warn("ScriptData::Precompile only accepts UTF-8 encoded source, not: %s", RSTRING_PTR(rb_inspect(rb_obj_encoding(input))));
|
||||
}
|
||||
#endif
|
||||
return ScriptData(v8::ScriptData::PreCompile(RSTRING_PTR(input), NUM2INT(length)));
|
||||
}
|
||||
VALUE ScriptData::New(VALUE self, VALUE data, VALUE length) {
|
||||
return ScriptData(v8::ScriptData::New(RSTRING_PTR(data), NUM2INT(length)));
|
||||
}
|
||||
VALUE ScriptData::Length(VALUE self) {
|
||||
return ScriptData(self)->Length();
|
||||
}
|
||||
VALUE ScriptData::Data(VALUE self) {
|
||||
ScriptData data(self);
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
return rb_enc_str_new(data->Data(), data->Length(), rb_enc_find("BINARY"));
|
||||
#else
|
||||
return rb_str_new(data->Data(), data->Length());
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE ScriptData::HasError(VALUE self) {
|
||||
return ScriptData(self)->HasError();
|
||||
}
|
||||
|
||||
VALUE Script::New(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE source; VALUE origin; VALUE pre_data; VALUE script_data;
|
||||
rb_scan_args(argc, argv, "13", &source, &origin, &pre_data, &script_data);
|
||||
if (argc == 2) {
|
||||
VALUE filename = origin;
|
||||
return Script(v8::Script::New(String(source), Value(filename)));
|
||||
} else {
|
||||
return Script(v8::Script::New(String(source), ScriptOrigin(origin), ScriptData(pre_data), String(script_data)));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE Script::Run(VALUE self) {
|
||||
return Value(Script(self)->Run());
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
v8::Isolate *isolate;
|
||||
long timeout;
|
||||
} timeout_data;
|
||||
|
||||
void* breaker(void *d) {
|
||||
timeout_data* data = (timeout_data*)d;
|
||||
usleep(data->timeout*1000);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
v8::V8::TerminateExecution(data->isolate);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VALUE Script::RunWithTimeout(VALUE self, VALUE timeout) {
|
||||
pthread_t breaker_thread;
|
||||
timeout_data data;
|
||||
VALUE rval;
|
||||
void *res;
|
||||
|
||||
data.isolate = v8::Isolate::GetCurrent();
|
||||
data.timeout = NUM2LONG(timeout);
|
||||
|
||||
pthread_create(&breaker_thread, NULL, breaker, &data);
|
||||
|
||||
rval = Value(Script(self)->Run());
|
||||
|
||||
pthread_cancel(breaker_thread);
|
||||
pthread_join(breaker_thread, &res);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
template <> void Pointer<v8::ScriptData>::unwrap(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::ScriptData, pointer);
|
||||
}
|
||||
|
||||
template <> void Pointer<v8::ScriptOrigin>::unwrap(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::ScriptOrigin, pointer);
|
||||
}
|
||||
|
||||
} //namespace rr
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Signature::Init() {
|
||||
ClassBuilder("Signature").
|
||||
defineMethod("New", &New).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE Signature::New(int argc, VALUE args[], VALUE self) {
|
||||
VALUE receiver; VALUE argv;
|
||||
rb_scan_args(argc, args, "02", &receiver, &argv);
|
||||
FunctionTemplate recv(receiver);
|
||||
int length = RARRAY_LENINT(argv);
|
||||
FunctionTemplate::array<FunctionTemplate> types(argv);
|
||||
return Signature(v8::Signature::New(recv, length, types));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Stack::Init() {
|
||||
ClassBuilder("StackTrace").
|
||||
defineSingletonMethod("kLineNumber", &Trace::kLineNumber).
|
||||
defineSingletonMethod("kColumnOffset", &Trace::kColumnOffset).
|
||||
defineSingletonMethod("kScriptName", &Trace::kScriptName).
|
||||
defineSingletonMethod("kFunctionName", &Trace::kFunctionName).
|
||||
defineSingletonMethod("kIsEval", &Trace::kIsEval).
|
||||
defineSingletonMethod("kIsConstructor", &Trace::kIsConstructor).
|
||||
defineSingletonMethod("kScriptNameOrSourceURL", &Trace::kScriptNameOrSourceURL).
|
||||
defineSingletonMethod("kOverview", &Trace::kOverview).
|
||||
defineSingletonMethod("kDetailed", &Trace::kDetailed).
|
||||
defineSingletonMethod("CurrentStackTrace", &Trace::CurrentStackTrace).
|
||||
defineMethod("GetFrame", &Trace::GetFrame).
|
||||
defineMethod("GetFrameCount", &Trace::GetFrameCount).
|
||||
defineMethod("AsArray", &Trace::AsArray).
|
||||
store(&Trace::Class);
|
||||
ClassBuilder("StackFrame").
|
||||
defineMethod("GetLineNumber", &Frame::GetLineNumber).
|
||||
defineMethod("GetColumn", &Frame::GetColumn).
|
||||
defineMethod("GetScriptName", &Frame::GetScriptName).
|
||||
defineMethod("GetScriptNameOrSourceURL", &Frame::GetScriptNameOrSourceURL).
|
||||
defineMethod("GetFunctionName", &Frame::GetFunctionName).
|
||||
defineMethod("IsEval", &Frame::IsEval).
|
||||
defineMethod("IsConstructor", &Frame::IsConstructor).
|
||||
store(&Frame::Class);
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::GetFrame(VALUE self, VALUE index) {
|
||||
return Frame(Trace(self)->GetFrame(NUM2UINT(index)));
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::GetFrameCount(VALUE self) {
|
||||
return INT2FIX(Trace(self)->GetFrameCount());
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::AsArray(VALUE self) {
|
||||
return Array(Trace(self)->AsArray());
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::CurrentStackTrace(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE frame_limit; VALUE options;
|
||||
rb_scan_args(argc, argv, "11", &frame_limit, &options);
|
||||
return Trace(v8::StackTrace::CurrentStackTrace(NUM2INT(frame_limit), StackTraceOptions(options)));
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetLineNumber(VALUE self) {
|
||||
return INT2FIX(Frame(self)->GetLineNumber());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetColumn(VALUE self) {
|
||||
return INT2FIX(Frame(self)->GetColumn());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetScriptName(VALUE self) {
|
||||
return String(Frame(self)->GetScriptName());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetScriptNameOrSourceURL(VALUE self) {
|
||||
return String(Frame(self)->GetScriptNameOrSourceURL());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetFunctionName(VALUE self) {
|
||||
return String(Frame(self)->GetFunctionName());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::IsEval(VALUE self) {
|
||||
return Bool(Frame(self)->IsEval());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::IsConstructor(VALUE self) {
|
||||
return Bool(Frame(self)->IsConstructor());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void String::Init() {
|
||||
ClassBuilder("String", Primitive::Class).
|
||||
defineSingletonMethod("New", &New).
|
||||
defineSingletonMethod("NewSymbol", &NewSymbol).
|
||||
defineSingletonMethod("Concat", &Concat).
|
||||
defineMethod("Utf8Value", &Utf8Value).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE String::New(VALUE StringClass, VALUE string) {
|
||||
return String(v8::String::New(RSTRING_PTR(string), (int)RSTRING_LEN(string)));
|
||||
}
|
||||
|
||||
VALUE String::NewSymbol(VALUE self, VALUE string) {
|
||||
return String(v8::String::NewSymbol(RSTRING_PTR(string), (int)RSTRING_LEN(string)));
|
||||
}
|
||||
|
||||
VALUE String::Utf8Value(VALUE self) {
|
||||
String str(self);
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
return rb_enc_str_new(*v8::String::Utf8Value(*str), str->Utf8Length(), rb_enc_find("utf-8"));
|
||||
#else
|
||||
return rb_str_new(*v8::String::Utf8Value(*str), str->Utf8Length());
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE String::Concat(VALUE self, VALUE left, VALUE right) {
|
||||
return String(v8::String::Concat(String(left), String(right)));
|
||||
}
|
||||
|
||||
String::operator v8::Handle<v8::String>() const {
|
||||
switch (TYPE(value)) {
|
||||
case T_STRING:
|
||||
return v8::String::New(RSTRING_PTR(value), (int)RSTRING_LEN(value));
|
||||
case T_DATA:
|
||||
return Ref<v8::String>::operator v8::Handle<v8::String>();
|
||||
default:
|
||||
VALUE string = rb_funcall(value, rb_intern("to_s"), 0);
|
||||
return v8::String::New(RSTRING_PTR(string), (int)RSTRING_LEN(string));
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace rr
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Template::Init() {
|
||||
ClassBuilder("Template").
|
||||
defineMethod("Set", &Set);
|
||||
ObjectTemplate::Init();
|
||||
FunctionTemplate::Init();
|
||||
}
|
||||
|
||||
VALUE Template::Set(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE name; VALUE value; VALUE attributes;
|
||||
rb_scan_args(argc, argv, "21", &name, &value, &attributes);
|
||||
Void(Template(self)->Set(*String(name), *Value(value), PropertyAttribute(attributes)));
|
||||
}
|
||||
|
||||
void ObjectTemplate::Init() {
|
||||
ClassBuilder("ObjectTemplate", "Template").
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("NewInstance", &NewInstance).
|
||||
defineMethod("SetAccessor", &SetAccessor).
|
||||
defineMethod("SetNamedPropertyHandler", &SetNamedPropertyHandler).
|
||||
defineMethod("SetIndexedPropertyHandler", &SetIndexedPropertyHandler).
|
||||
defineMethod("SetCallAsFunctionHandler", &SetCallAsFunctionHandler).
|
||||
defineMethod("MarkAsUndetectable", &MarkAsUndetectable).
|
||||
defineMethod("SetAccessCheckCallbacks", &SetAccessCheckCallbacks).
|
||||
defineMethod("InternalFieldCount", &InternalFieldCount).
|
||||
defineMethod("SetInternalFieldCount", &SetInternalFieldCount).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::New(VALUE self) {
|
||||
return ObjectTemplate(v8::ObjectTemplate::New());
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::NewInstance(VALUE self) {
|
||||
return Object(ObjectTemplate(self)->NewInstance());
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetAccessor(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE name; VALUE get; VALUE set; VALUE data; VALUE settings; VALUE attribs;
|
||||
rb_scan_args(argc, argv, "24", &name, &get, &set, &data, &settings, &attribs);
|
||||
Accessor accessor(get, set, data);
|
||||
ObjectTemplate(self)->SetAccessor(
|
||||
String(name),
|
||||
accessor.accessorGetter(),
|
||||
accessor.accessorSetter(),
|
||||
accessor,
|
||||
AccessControl(settings),
|
||||
PropertyAttribute(attribs)
|
||||
);
|
||||
Void();
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetNamedPropertyHandler(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE get; VALUE set; VALUE query; VALUE deleter; VALUE enumerator; VALUE data;
|
||||
rb_scan_args(argc, argv, "15", &get, &set, &query, &deleter, &enumerator, &data);
|
||||
Accessor accessor(get,set,query,deleter,enumerator,data);
|
||||
ObjectTemplate(self)->SetNamedPropertyHandler(
|
||||
accessor.namedPropertyGetter(),
|
||||
accessor.namedPropertySetter(),
|
||||
accessor.namedPropertyQuery(),
|
||||
accessor.namedPropertyDeleter(),
|
||||
accessor.namedPropertyEnumerator(),
|
||||
accessor
|
||||
);
|
||||
Void();
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetIndexedPropertyHandler(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE get; VALUE set; VALUE query; VALUE deleter; VALUE enumerator; VALUE data;
|
||||
rb_scan_args(argc, argv, "15", &get, &set, &query, &deleter, &enumerator, &data);
|
||||
Accessor accessor(get,set,query,deleter,enumerator,data);
|
||||
ObjectTemplate(self)->SetIndexedPropertyHandler(
|
||||
accessor.indexedPropertyGetter(),
|
||||
accessor.indexedPropertySetter(),
|
||||
accessor.indexedPropertyQuery(),
|
||||
accessor.indexedPropertyDeleter(),
|
||||
accessor.indexedPropertyEnumerator(),
|
||||
accessor
|
||||
);
|
||||
Void();
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetCallAsFunctionHandler(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE callback; VALUE data;
|
||||
rb_scan_args(argc, argv, "11", &callback, &data);
|
||||
Invocation invocation(callback, data);
|
||||
Void(ObjectTemplate(self)->SetCallAsFunctionHandler(invocation, invocation));
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::MarkAsUndetectable(VALUE self) {
|
||||
Void(ObjectTemplate(self)->MarkAsUndetectable());
|
||||
}
|
||||
|
||||
|
||||
VALUE ObjectTemplate::SetAccessCheckCallbacks(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE named_handler; VALUE indexed_handler; VALUE data; VALUE turned_on_by_default;
|
||||
rb_scan_args(argc, argv, "22", &named_handler, &indexed_handler, &data, &turned_on_by_default);
|
||||
return not_implemented("ObjectTemplate::SetAccessCheckCallbacks");
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::InternalFieldCount(VALUE self) {
|
||||
return INT2FIX(ObjectTemplate(self)->InternalFieldCount());
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetInternalFieldCount(VALUE self, VALUE count) {
|
||||
Void(ObjectTemplate(self)->SetInternalFieldCount(NUM2INT(count)));
|
||||
}
|
||||
|
||||
void FunctionTemplate::Init() {
|
||||
ClassBuilder("FunctionTemplate", "Template").
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("GetFunction", &GetFunction).
|
||||
defineMethod("SetCallHandler", &SetCallHandler).
|
||||
defineMethod("InstanceTemplate", &InstanceTemplate).
|
||||
defineMethod("Inherit", &Inherit).
|
||||
defineMethod("PrototypeTemplate", &PrototypeTemplate).
|
||||
defineMethod("SetClassName", &SetClassName).
|
||||
defineMethod("SetHiddenPrototype", &SetHiddenPrototype).
|
||||
defineMethod("ReadOnlyPrototype", &ReadOnlyPrototype).
|
||||
defineMethod("HasInstance", &HasInstance).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::New(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE code; VALUE data; VALUE signature;
|
||||
rb_scan_args(argc, argv, "03", &code, &data, &signature);
|
||||
if (RTEST(code)) {
|
||||
Invocation invocation(code, data);
|
||||
return FunctionTemplate(v8::FunctionTemplate::New(invocation, invocation, Signature(signature)));
|
||||
} else {
|
||||
return FunctionTemplate(v8::FunctionTemplate::New());
|
||||
}
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::GetFunction(VALUE self) {
|
||||
return Function(FunctionTemplate(self)->GetFunction());
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::SetCallHandler(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE code; VALUE data;
|
||||
rb_scan_args(argc, argv, "11", &code, &data);
|
||||
Invocation invocation(code, data);
|
||||
Void(FunctionTemplate(self)->SetCallHandler(invocation, invocation));
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::InstanceTemplate(VALUE self) {
|
||||
return ObjectTemplate(FunctionTemplate(self)->InstanceTemplate());
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::Inherit(VALUE self, VALUE parent) {
|
||||
Void(FunctionTemplate(self)->Inherit(FunctionTemplate(parent)));
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::PrototypeTemplate(VALUE self) {
|
||||
return ObjectTemplate(FunctionTemplate(self)->PrototypeTemplate());
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::SetClassName(VALUE self, VALUE name) {
|
||||
Void(FunctionTemplate(self)->SetClassName(String(name)));
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::SetHiddenPrototype(VALUE self, VALUE value) {
|
||||
Void(FunctionTemplate(self)->SetHiddenPrototype(Bool(value)));
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::ReadOnlyPrototype(VALUE self) {
|
||||
Void(FunctionTemplate(self)->ReadOnlyPrototype());
|
||||
}
|
||||
|
||||
VALUE FunctionTemplate::HasInstance(VALUE self, VALUE object) {
|
||||
return Bool(FunctionTemplate(self)->HasInstance(Value(object)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
VALUE TryCatch::Class;
|
||||
|
||||
void TryCatch::Init() {
|
||||
ClassBuilder("TryCatch").
|
||||
defineMethod("HasCaught", &HasCaught).
|
||||
defineMethod("CanContinue", &CanContinue).
|
||||
defineMethod("ReThrow", &ReThrow).
|
||||
defineMethod("Exception", &Exception).
|
||||
defineMethod("StackTrace", &StackTrace).
|
||||
defineMethod("Message", &Message).
|
||||
defineMethod("Reset", &Reset).
|
||||
defineMethod("SetVerbose", &SetVerbose).
|
||||
defineMethod("SetCaptureMessage", &SetCaptureMessage).
|
||||
store(&Class);
|
||||
VALUE v8 = rb_define_module("V8");
|
||||
VALUE c = rb_define_module_under(v8, "C");
|
||||
rb_define_singleton_method(c, "TryCatch", (VALUE (*)(...))&doTryCatch, -1);
|
||||
}
|
||||
|
||||
TryCatch::TryCatch(v8::TryCatch* impl) {
|
||||
this->impl = impl;
|
||||
}
|
||||
TryCatch::TryCatch(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::TryCatch, impl);
|
||||
}
|
||||
|
||||
TryCatch::operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, 0, impl);
|
||||
}
|
||||
|
||||
VALUE TryCatch::HasCaught(VALUE self) {
|
||||
return Bool(TryCatch(self)->HasCaught());
|
||||
}
|
||||
VALUE TryCatch::CanContinue(VALUE self) {
|
||||
return Bool(TryCatch(self)->CanContinue());
|
||||
}
|
||||
VALUE TryCatch::ReThrow(VALUE self) {
|
||||
return Value(TryCatch(self)->ReThrow());
|
||||
}
|
||||
VALUE TryCatch::Exception(VALUE self) {
|
||||
return Value(TryCatch(self)->Exception());
|
||||
}
|
||||
VALUE TryCatch::StackTrace(VALUE self) {
|
||||
return Value(TryCatch(self)->StackTrace());
|
||||
}
|
||||
VALUE TryCatch::Message(VALUE self) {
|
||||
return rr::Message(TryCatch(self)->Message());
|
||||
}
|
||||
VALUE TryCatch::Reset(VALUE self) {
|
||||
Void(TryCatch(self)->Reset());
|
||||
}
|
||||
VALUE TryCatch::SetVerbose(VALUE self, VALUE value) {
|
||||
Void(TryCatch(self)->SetVerbose(Bool(value)));
|
||||
}
|
||||
VALUE TryCatch::SetCaptureMessage(VALUE self, VALUE value) {
|
||||
Void(TryCatch(self)->SetCaptureMessage(Bool(value)));
|
||||
}
|
||||
|
||||
VALUE TryCatch::doTryCatch(int argc, VALUE argv[], VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
int state = 0;
|
||||
VALUE code;
|
||||
rb_scan_args(argc,argv,"00&", &code);
|
||||
VALUE result = setupAndCall(&state, code);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE TryCatch::setupAndCall(int* state, VALUE code) {
|
||||
v8::TryCatch trycatch;
|
||||
rb_iv_set(code, "_v8_trycatch", TryCatch(&trycatch));
|
||||
VALUE result = rb_protect(&doCall, code, state);
|
||||
rb_iv_set(code, "_v8_trycatch", Qnil);
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE TryCatch::doCall(VALUE code) {
|
||||
return rb_funcall(code, rb_intern("call"), 1, rb_iv_get(code, "_v8_trycatch"));
|
||||
}
|
||||
}
|
||||
120
ext/v8/v8.cc
120
ext/v8/v8.cc
|
|
@ -2,86 +2,48 @@
|
|||
|
||||
namespace rr {
|
||||
|
||||
void V8::Init() {
|
||||
ClassBuilder("V8").
|
||||
defineSingletonMethod("IdleNotification", &IdleNotification).
|
||||
defineSingletonMethod("SetFlagsFromString", &SetFlagsFromString).
|
||||
defineSingletonMethod("SetFlagsFromCommandLine", &SetFlagsFromCommandLine).
|
||||
defineSingletonMethod("PauseProfiler", &PauseProfiler).
|
||||
defineSingletonMethod("ResumeProfiler", &ResumeProfiler).
|
||||
defineSingletonMethod("IsProfilerPaused", &IsProfilerPaused).
|
||||
defineSingletonMethod("GetCurrentThreadId", &GetCurrentThreadId).
|
||||
defineSingletonMethod("TerminateExecution", &TerminateExecution).
|
||||
defineSingletonMethod("IsExecutionTerminating", &IsExecutionTerminating).
|
||||
defineSingletonMethod("Dispose", &Dispose).
|
||||
defineSingletonMethod("LowMemoryNotification", &LowMemoryNotification).
|
||||
defineSingletonMethod("AdjustAmountOfExternalAllocatedMemory", &AdjustAmountOfExternalAllocatedMemory).
|
||||
defineSingletonMethod("ContextDisposedNotification", &ContextDisposedNotification).
|
||||
defineSingletonMethod("SetCaptureStackTraceForUncaughtExceptions", &SetCaptureStackTraceForUncaughtExceptions).
|
||||
defineSingletonMethod("GetHeapStatistics", &GetHeapStatistics).
|
||||
defineSingletonMethod("GetVersion", &GetVersion);
|
||||
}
|
||||
v8::Platform* V8::v8_platform = NULL;
|
||||
|
||||
VALUE V8::IdleNotification(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE hint;
|
||||
rb_scan_args(argc, argv, "01", &hint);
|
||||
if (RTEST(hint)) {
|
||||
return Bool(v8::V8::IdleNotification(NUM2INT(hint)));
|
||||
} else {
|
||||
return Bool(v8::V8::IdleNotification());
|
||||
void V8::Init() {
|
||||
// Initialize V8.
|
||||
v8::V8::InitializeICU();
|
||||
v8_platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(v8_platform);
|
||||
v8::V8::Initialize();
|
||||
|
||||
ClassBuilder("V8").
|
||||
// defineSingletonMethod("IdleNotification", &IdleNotification).
|
||||
// defineSingletonMethod("SetFlagsFromString", &SetFlagsFromString).
|
||||
// defineSingletonMethod("SetFlagsFromCommandLine", &SetFlagsFromCommandLine).
|
||||
// defineSingletonMethod("PauseProfiler", &PauseProfiler).
|
||||
// defineSingletonMethod("ResumeProfiler", &ResumeProfiler).
|
||||
// defineSingletonMethod("IsProfilerPaused", &IsProfilerPaused).
|
||||
// defineSingletonMethod("GetCurrentThreadId", &GetCurrentThreadId).
|
||||
// defineSingletonMethod("TerminateExecution", &TerminateExecution).
|
||||
// defineSingletonMethod("IsExecutionTerminating", &IsExecutionTerminating).
|
||||
defineSingletonMethod("Dispose", &Dispose).
|
||||
// defineSingletonMethod("LowMemoryNotification", &LowMemoryNotification).
|
||||
// defineSingletonMethod("AdjustAmountOfExternalAllocatedMemory", &AdjustAmountOfExternalAllocatedMemory).
|
||||
// defineSingletonMethod("ContextDisposedNotification", &ContextDisposedNotification).
|
||||
// defineSingletonMethod("SetCaptureStackTraceForUncaughtExceptions", &SetCaptureStackTraceForUncaughtExceptions).
|
||||
// defineSingletonMethod("GetHeapStatistics", &GetHeapStatistics).
|
||||
defineSingletonMethod("GetVersion", &GetVersion);
|
||||
}
|
||||
}
|
||||
VALUE V8::SetFlagsFromString(VALUE self, VALUE string) {
|
||||
Void(v8::V8::SetFlagsFromString(RSTRING_PTR(string), (int)RSTRING_LEN(string)));
|
||||
}
|
||||
VALUE V8::SetFlagsFromCommandLine(VALUE self, VALUE args, VALUE remove_flags) {
|
||||
int argc = RARRAY_LENINT(args);
|
||||
char* argv[argc];
|
||||
for(int i = 0; i < argc; i++) {
|
||||
argv[i] = RSTRING_PTR(rb_ary_entry(args, i));
|
||||
|
||||
VALUE V8::Dispose(VALUE self) {
|
||||
v8::V8::Dispose();
|
||||
v8::V8::ShutdownPlatform();
|
||||
|
||||
if (v8_platform) {
|
||||
delete v8_platform;
|
||||
v8_platform = NULL;
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
Void(v8::V8::SetFlagsFromCommandLine(&argc, argv, Bool(remove_flags)));
|
||||
|
||||
VALUE V8::GetVersion(VALUE self) {
|
||||
return rb_str_new2(v8::V8::GetVersion());
|
||||
}
|
||||
|
||||
}
|
||||
VALUE V8::AdjustAmountOfExternalAllocatedMemory(VALUE self, VALUE change_in_bytes) {
|
||||
return SIZET2NUM(v8::V8::AdjustAmountOfExternalAllocatedMemory(NUM2SIZET(change_in_bytes)));
|
||||
}
|
||||
VALUE V8::PauseProfiler(VALUE self) {
|
||||
Void(v8::V8::PauseProfiler());
|
||||
}
|
||||
VALUE V8::ResumeProfiler(VALUE self) {
|
||||
Void(v8::V8::ResumeProfiler());
|
||||
}
|
||||
VALUE V8::IsProfilerPaused(VALUE self) {
|
||||
return Bool(v8::V8::IsProfilerPaused());
|
||||
}
|
||||
VALUE V8::GetCurrentThreadId(VALUE self) {
|
||||
return INT2FIX(v8::V8::GetCurrentThreadId());
|
||||
}
|
||||
VALUE V8::TerminateExecution(VALUE self, VALUE thread_id) {
|
||||
Void(v8::V8::TerminateExecution(NUM2INT(thread_id)));
|
||||
}
|
||||
VALUE V8::IsExecutionTerminating(VALUE self) {
|
||||
return Bool(v8::V8::IsExecutionTerminating());
|
||||
}
|
||||
VALUE V8::Dispose(VALUE self) {
|
||||
Void(v8::V8::Dispose());
|
||||
}
|
||||
VALUE V8::LowMemoryNotification(VALUE self) {
|
||||
Void(v8::V8::LowMemoryNotification());
|
||||
}
|
||||
VALUE V8::ContextDisposedNotification(VALUE self) {
|
||||
return INT2FIX(v8::V8::ContextDisposedNotification());
|
||||
}
|
||||
VALUE V8::SetCaptureStackTraceForUncaughtExceptions(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE should_capture; VALUE frame_limit; VALUE options;
|
||||
rb_scan_args(argc, argv, "12", &should_capture, &frame_limit, &options);
|
||||
int limit = RTEST(frame_limit) ? NUM2INT(frame_limit) : 10;
|
||||
Void(v8::V8::SetCaptureStackTraceForUncaughtExceptions(Bool(should_capture), limit, Stack::Trace::StackTraceOptions(options)));
|
||||
}
|
||||
VALUE V8::GetHeapStatistics(VALUE self, VALUE statistics_ptr) {
|
||||
Void(v8::V8::GetHeapStatistics(HeapStatistics(statistics_ptr)));
|
||||
}
|
||||
VALUE V8::GetVersion(VALUE self) {
|
||||
return rb_str_new2(v8::V8::GetVersion());
|
||||
}
|
||||
}
|
||||
25
ext/v8/v8.h
Normal file
25
ext/v8/v8.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
namespace rr {
|
||||
class V8 {
|
||||
public:
|
||||
static v8::Platform* v8_platform;
|
||||
|
||||
static void Init();
|
||||
// static VALUE IdleNotification(int argc, VALUE argv[], VALUE self);
|
||||
// static VALUE SetFlagsFromString(VALUE self, VALUE string);
|
||||
// static VALUE SetFlagsFromCommandLine(VALUE self, VALUE args, VALUE remove_flags);
|
||||
// static VALUE AdjustAmountOfExternalAllocatedMemory(VALUE self, VALUE change_in_bytes);
|
||||
// static VALUE PauseProfiler(VALUE self);
|
||||
// static VALUE ResumeProfiler(VALUE self);
|
||||
// static VALUE IsProfilerPaused(VALUE self);
|
||||
// static VALUE GetCurrentThreadId(VALUE self);
|
||||
// static VALUE TerminateExecution(VALUE self, VALUE thread_id);
|
||||
// static VALUE IsExecutionTerminating(VALUE self);
|
||||
static VALUE Dispose(VALUE self);
|
||||
// static VALUE LowMemoryNotification(VALUE self);
|
||||
// static VALUE ContextDisposedNotification(VALUE self);
|
||||
|
||||
// static VALUE SetCaptureStackTraceForUncaughtExceptions(int argc, VALUE argv[], VALUE self);
|
||||
// static VALUE GetHeapStatistics(VALUE self, VALUE statistics_ptr);
|
||||
static VALUE GetVersion(VALUE self);
|
||||
};
|
||||
}
|
||||
239
ext/v8/value.cc
239
ext/v8/value.cc
|
|
@ -1,239 +0,0 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
VALUE Value::Empty;
|
||||
|
||||
void Value::Init() {
|
||||
Empty = rb_eval_string("Object.new");
|
||||
ClassBuilder("Value").
|
||||
defineConst("Empty", Empty).
|
||||
defineMethod("IsUndefined", &IsUndefined).
|
||||
defineMethod("IsNull", &IsNull).
|
||||
defineMethod("IsTrue", &IsTrue).
|
||||
defineMethod("IsFalse", &IsFalse).
|
||||
defineMethod("IsString", &IsString).
|
||||
defineMethod("IsFunction", &IsFunction).
|
||||
defineMethod("IsArray", &IsArray).
|
||||
defineMethod("IsObject", &IsObject).
|
||||
defineMethod("IsBoolean", &IsBoolean).
|
||||
defineMethod("IsNumber", &IsNumber).
|
||||
defineMethod("IsExternal", &IsExternal).
|
||||
defineMethod("IsInt32", &IsInt32).
|
||||
defineMethod("IsUint32", &IsUint32).
|
||||
defineMethod("IsDate", &IsDate).
|
||||
defineMethod("IsBooleanObject", &IsBooleanObject).
|
||||
defineMethod("IsNumberObject", &IsNumberObject).
|
||||
defineMethod("IsStringObject", &IsStringObject).
|
||||
defineMethod("IsNativeError", &IsNativeError).
|
||||
defineMethod("IsRegExp", &IsRegExp).
|
||||
defineMethod("ToString", &ToString).
|
||||
defineMethod("ToDetailString", &ToDetailString).
|
||||
defineMethod("ToObject", &ToObject).
|
||||
defineMethod("BooleanValue", &BooleanValue).
|
||||
defineMethod("NumberValue", &NumberValue).
|
||||
defineMethod("IntegerValue", &IntegerValue).
|
||||
defineMethod("Uint32Value", &Uint32Value).
|
||||
defineMethod("IntegerValue", &IntegerValue).
|
||||
defineMethod("Equals", &Equals).
|
||||
defineMethod("StrictEquals", &StrictEquals)
|
||||
.store(&Class);
|
||||
rb_gc_register_address(&Empty);
|
||||
}
|
||||
|
||||
VALUE Value::IsUndefined(VALUE self) {
|
||||
return Bool(Value(self)->IsUndefined());
|
||||
}
|
||||
VALUE Value::IsNull(VALUE self) {
|
||||
return Bool(Value(self)->IsNull());
|
||||
}
|
||||
VALUE Value::IsTrue(VALUE self) {
|
||||
return Bool(Value(self)->IsTrue());
|
||||
}
|
||||
VALUE Value::IsFalse(VALUE self) {
|
||||
return Bool(Value(self)->IsFalse());
|
||||
}
|
||||
VALUE Value::IsString(VALUE self) {
|
||||
return Bool(Value(self)->IsString());
|
||||
}
|
||||
VALUE Value::IsFunction(VALUE self) {
|
||||
return Bool(Value(self)->IsFunction());
|
||||
}
|
||||
VALUE Value::IsArray(VALUE self) {
|
||||
return Bool(Value(self)->IsArray());
|
||||
}
|
||||
VALUE Value::IsObject(VALUE self) {
|
||||
return Bool(Value(self)->IsObject());
|
||||
}
|
||||
VALUE Value::IsBoolean(VALUE self) {
|
||||
return Bool(Value(self)->IsBoolean());
|
||||
}
|
||||
VALUE Value::IsNumber(VALUE self) {
|
||||
return Bool(Value(self)->IsNumber());
|
||||
}
|
||||
VALUE Value::IsExternal(VALUE self) {
|
||||
return Bool(Value(self)->IsExternal());
|
||||
}
|
||||
VALUE Value::IsInt32(VALUE self) {
|
||||
return Bool(Value(self)->IsInt32());
|
||||
}
|
||||
VALUE Value::IsUint32(VALUE self) {
|
||||
return Bool(Value(self)->IsUint32());
|
||||
}
|
||||
VALUE Value::IsDate(VALUE self) {
|
||||
return Bool(Value(self)->IsDate());
|
||||
}
|
||||
VALUE Value::IsBooleanObject(VALUE self) {
|
||||
return Bool(Value(self)->IsBooleanObject());
|
||||
}
|
||||
VALUE Value::IsNumberObject(VALUE self) {
|
||||
return Bool(Value(self)->IsNumberObject());
|
||||
}
|
||||
VALUE Value::IsStringObject(VALUE self) {
|
||||
return Bool(Value(self)->IsStringObject());
|
||||
}
|
||||
VALUE Value::IsNativeError(VALUE self) {
|
||||
return Bool(Value(self)->IsNativeError());
|
||||
}
|
||||
VALUE Value::IsRegExp(VALUE self) {
|
||||
return Bool(Value(self)->IsRegExp());
|
||||
}
|
||||
|
||||
// VALUE Value::ToBoolean(VALUE self) {
|
||||
// return Boolean(Value(self)->ToBoolean());
|
||||
// }
|
||||
|
||||
// VALUE Value::ToNumber(VALUE self) {
|
||||
// return Number(Value(self)->ToNumber());
|
||||
// }
|
||||
VALUE Value::ToString(VALUE self) {
|
||||
return String(Value(self)->ToString());
|
||||
}
|
||||
|
||||
VALUE Value::ToDetailString(VALUE self) {
|
||||
return String(Value(self)->ToDetailString());
|
||||
}
|
||||
|
||||
VALUE Value::ToObject(VALUE self) {
|
||||
return Object(Value(self)->ToObject());
|
||||
}
|
||||
|
||||
// VALUE Value::ToInteger(VALUE self) {
|
||||
// return Integer(Value(self)->ToInteger());
|
||||
// }
|
||||
|
||||
// VALUE Value::ToUint32(VALUE self) {
|
||||
// return Uint32(Value(self)->ToUint32());
|
||||
// }
|
||||
|
||||
// VALUE Value::ToInt32(VALUE self) {
|
||||
// return Int32(Value(self)->ToInt32());
|
||||
// }
|
||||
|
||||
|
||||
// VALUE Value::ToArrayIndex(VALUE self) {
|
||||
// return Uint32(Value(self)->ToArrayIndex());
|
||||
// }
|
||||
|
||||
VALUE Value::BooleanValue(VALUE self) {
|
||||
return Bool(Value(self)->BooleanValue());
|
||||
}
|
||||
VALUE Value::NumberValue(VALUE self) {
|
||||
return rb_float_new(Value(self)->NumberValue());
|
||||
}
|
||||
VALUE Value::IntegerValue(VALUE self) {
|
||||
return INT2NUM(Value(self)->IntegerValue());
|
||||
}
|
||||
VALUE Value::Uint32Value(VALUE self) {
|
||||
return UINT2NUM(Value(self)->Uint32Value());
|
||||
}
|
||||
VALUE Value::Int32Value(VALUE self) {
|
||||
return INT2FIX(Value(self)->Int32Value());
|
||||
}
|
||||
|
||||
VALUE Value::Equals(VALUE self, VALUE other) {
|
||||
return Bool(Value(self)->Equals(Value(other)));
|
||||
}
|
||||
|
||||
VALUE Value::StrictEquals(VALUE self, VALUE other) {
|
||||
return Bool(Value(self)->StrictEquals(Value(other)));
|
||||
}
|
||||
|
||||
Value::operator VALUE() {
|
||||
if (handle.IsEmpty() || handle->IsUndefined() || handle->IsNull()) {
|
||||
return Qnil;
|
||||
}
|
||||
if (handle->IsTrue()) {
|
||||
return Qtrue;
|
||||
}
|
||||
if (handle->IsFalse()) {
|
||||
return Qfalse;
|
||||
}
|
||||
if (handle->IsExternal()) {
|
||||
return External((v8::Handle<v8::External>)v8::External::Cast(*handle));
|
||||
}
|
||||
if (handle->IsUint32()) {
|
||||
return UInt32(handle->Uint32Value());
|
||||
}
|
||||
if (handle->IsInt32()) {
|
||||
return INT2FIX(handle->Int32Value());
|
||||
}
|
||||
if (handle->IsBoolean()) {
|
||||
return handle->BooleanValue() ? Qtrue : Qfalse;
|
||||
}
|
||||
if (handle->IsNumber()) {
|
||||
return rb_float_new(handle->NumberValue());
|
||||
}
|
||||
if (handle->IsString()) {
|
||||
return String(handle->ToString());
|
||||
}
|
||||
if (handle->IsDate()) {
|
||||
return Date((v8::Handle<v8::Date>)v8::Date::Cast(*handle));
|
||||
}
|
||||
if (handle->IsObject()) {
|
||||
return Object(handle->ToObject());
|
||||
}
|
||||
return Ref<v8::Value>::operator VALUE();
|
||||
}
|
||||
|
||||
Value::operator v8::Handle<v8::Value>() const {
|
||||
if (rb_equal(value,Empty)) {
|
||||
return v8::Handle<v8::Value>();
|
||||
}
|
||||
switch (TYPE(value)) {
|
||||
case T_FIXNUM:
|
||||
return v8::Integer::New(NUM2INT(value));
|
||||
case T_FLOAT:
|
||||
return v8::Number::New(NUM2DBL(value));
|
||||
case T_STRING:
|
||||
return v8::String::New(RSTRING_PTR(value), (int)RSTRING_LEN(value));
|
||||
case T_NIL:
|
||||
return v8::Null();
|
||||
case T_TRUE:
|
||||
return v8::True();
|
||||
case T_FALSE:
|
||||
return v8::False();
|
||||
case T_DATA:
|
||||
return Ref<v8::Value>::operator v8::Handle<v8::Value>();
|
||||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
case T_ICLASS:
|
||||
case T_MODULE:
|
||||
case T_REGEXP:
|
||||
case T_MATCH:
|
||||
case T_ARRAY:
|
||||
case T_HASH:
|
||||
case T_STRUCT:
|
||||
case T_BIGNUM:
|
||||
case T_FILE:
|
||||
case T_SYMBOL:
|
||||
case T_UNDEF:
|
||||
case T_NODE:
|
||||
default:
|
||||
rb_warn("unknown conversion to V8 for: %s", RSTRING_PTR(rb_inspect(value)));
|
||||
return v8::String::New("Undefined Conversion");
|
||||
}
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Array do
|
||||
requires_v8_context
|
||||
|
||||
it "can store and retrieve a value" do
|
||||
o = V8::C::Object::New()
|
||||
a = V8::C::Array::New()
|
||||
a.Length().should eql 0
|
||||
a.Set(0, o)
|
||||
a.Length().should eql 1
|
||||
a.Get(0).Equals(o).should be_true
|
||||
end
|
||||
|
||||
it "can be initialized with a length" do
|
||||
a = V8::C::Array::New(5)
|
||||
a.Length().should eql 5
|
||||
end
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C do
|
||||
requires_v8_context
|
||||
|
||||
it "has constant methods for Undefined, Null, True and False" do
|
||||
[:Undefined, :Null, :True, :False].each do |name|
|
||||
constant = V8::C.send(name)
|
||||
constant.should_not be_nil
|
||||
V8::C.send(name).should be constant
|
||||
end
|
||||
end
|
||||
|
||||
it "has a value for the Empty handle" do
|
||||
V8::C::Value::Empty.should_not be_nil
|
||||
V8::C::Value::Empty.should be V8::C::Value::Empty
|
||||
end
|
||||
|
||||
it "can access the V8 version" do
|
||||
V8::C::V8::GetVersion().should match /^3\.16/
|
||||
end
|
||||
end
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Exception do
|
||||
requires_v8_context
|
||||
|
||||
it "can be thrown from Ruby" do
|
||||
t = V8::C::FunctionTemplate::New(method(:explode))
|
||||
@cxt.Global().Set("explode", t.GetFunction())
|
||||
script = V8::C::Script::New(<<-JS, '<eval>')
|
||||
(function() {
|
||||
try {
|
||||
explode()
|
||||
} catch (e) {
|
||||
return e.message
|
||||
}
|
||||
})()
|
||||
JS
|
||||
result = script.Run()
|
||||
result.should_not be_nil
|
||||
result.should be_kind_of(V8::C::String)
|
||||
result.Utf8Value().should eql 'did not pay syntax'
|
||||
end
|
||||
|
||||
def explode(arguments)
|
||||
error = V8::C::Exception::SyntaxError('did not pay syntax')
|
||||
V8::C::ThrowException(error)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::External do
|
||||
requires_v8_context
|
||||
|
||||
it "can store and retrieve a value" do
|
||||
o = Object.new
|
||||
external = V8::C::External::New(o)
|
||||
external.Value().should be(o)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Function do
|
||||
requires_v8_context
|
||||
|
||||
it "can be called" do
|
||||
fn = run '(function() {return "foo"})'
|
||||
fn.Call(@cxt.Global(), []).Utf8Value().should eql "foo"
|
||||
end
|
||||
|
||||
it "can be called with arguments and context" do
|
||||
fn = run '(function(one, two, three) {this.one = one; this.two = two; this.three = three})'
|
||||
one = V8::C::Object::New()
|
||||
two = V8::C::Object::New()
|
||||
fn.Call(@cxt.Global(), [one, two, 3])
|
||||
@cxt.Global().Get("one").should eql one
|
||||
@cxt.Global().Get("two").should eql two
|
||||
@cxt.Global().Get("three").should eql 3
|
||||
end
|
||||
|
||||
it "can be called as a constructor" do
|
||||
fn = run '(function() {this.foo = "foo"})'
|
||||
fn.NewInstance().Get(V8::C::String::New('foo')).Utf8Value().should eql "foo"
|
||||
end
|
||||
|
||||
it "can be called as a constructor with arguments" do
|
||||
fn = run '(function(foo) {this.foo = foo})'
|
||||
object = fn.NewInstance([V8::C::String::New("bar")])
|
||||
object.Get(V8::C::String::New('foo')).Utf8Value().should eql "bar"
|
||||
end
|
||||
|
||||
it "doesn't kill the world if invoking it throws a javascript exception" do
|
||||
V8::C::TryCatch() do
|
||||
fn = run '(function() { throw new Error("boom!")})'
|
||||
fn.Call(@cxt.Global(), [])
|
||||
fn.NewInstance([])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def run(source)
|
||||
source = V8::C::String::New(source.to_s)
|
||||
filename = V8::C::String::New("<eval>")
|
||||
script = V8::C::Script::New(source, filename)
|
||||
result = script.Run()
|
||||
result.kind_of?(V8::C::String) ? result.Utf8Value() : result
|
||||
end
|
||||
end
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "setting up handles scopes" do
|
||||
around(:each) do |example|
|
||||
V8::C::Locker() do
|
||||
cxt = V8::C::Context::New()
|
||||
begin
|
||||
cxt.Enter()
|
||||
example.run
|
||||
ensure
|
||||
cxt.Exit()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "can allocate handle scopes" do
|
||||
V8::C::HandleScope() do
|
||||
V8::C::Object::New()
|
||||
end.class.should eql V8::C::Object
|
||||
end
|
||||
|
||||
it "isn't the end of the world if a ruby exception is raised inside a HandleScope" do
|
||||
begin
|
||||
V8::C::HandleScope() do
|
||||
raise "boom!"
|
||||
end
|
||||
rescue StandardError => e
|
||||
e.message.should eql "boom!"
|
||||
end
|
||||
end
|
||||
end
|
||||
7
spec/c/isolate_spec.rb
Normal file
7
spec/c/isolate_spec.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
require 'v8/init'
|
||||
|
||||
describe V8::C::Isolate do
|
||||
it "can create a new isolate" do
|
||||
expect(V8::C::Isolate.New).to be
|
||||
end
|
||||
end
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Locker do
|
||||
it "can lock and unlock the VM" do
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
V8::C::Locker() do
|
||||
V8::C::Locker::IsLocked().should be_true
|
||||
V8::C::Unlocker() do
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
end
|
||||
end
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
end
|
||||
|
||||
it "properly unlocks if an exception is thrown inside a lock block" do
|
||||
begin
|
||||
V8::C::Locker() do
|
||||
raise "boom!"
|
||||
end
|
||||
rescue
|
||||
V8::C::Locker::IsLocked().should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "properly re-locks if an exception is thrown inside an un-lock block" do
|
||||
V8::C::Locker() do
|
||||
begin
|
||||
V8::C::Unlocker() do
|
||||
raise "boom!"
|
||||
end
|
||||
rescue
|
||||
V8::C::Locker::IsLocked().should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Object do
|
||||
requires_v8_context
|
||||
|
||||
it "can store and retrieve a value" do
|
||||
o = V8::C::Object::New()
|
||||
key = V8::C::String::New("foo")
|
||||
value = V8::C::String::New("bar")
|
||||
o.Set(key, value)
|
||||
o.Get(key).Utf8Value().should eql "bar"
|
||||
end
|
||||
|
||||
it "can retrieve all property names" do
|
||||
o = V8::C::Object::New()
|
||||
o.Set(V8::C::String::New("foo"), V8::C::String::New("bar"))
|
||||
o.Set(V8::C::String::New("baz"), V8::C::String::New("bang"))
|
||||
names = o.GetPropertyNames()
|
||||
names.Length().should eql 2
|
||||
names.Get(0).Utf8Value().should eql "foo"
|
||||
names.Get(1).Utf8Value().should eql "baz"
|
||||
end
|
||||
it "can set an accessor from ruby" do
|
||||
o = V8::C::Object::New()
|
||||
property = V8::C::String::New("statement")
|
||||
callback_data = V8::C::String::New("I am Legend")
|
||||
left = V8::C::String::New("Yo! ")
|
||||
getter = proc do |name, info|
|
||||
info.This().StrictEquals(o).should be_true
|
||||
info.Holder().StrictEquals(o).should be_true
|
||||
V8::C::String::Concat(left, info.Data())
|
||||
end
|
||||
setter = proc do |name, value, info|
|
||||
left = value
|
||||
end
|
||||
o.SetAccessor(property, getter, setter, callback_data)
|
||||
o.Get(property).Utf8Value().should eql "Yo! I am Legend"
|
||||
o.Set(property, V8::C::String::New("Bro! "))
|
||||
o.Get(property).Utf8Value().should eql "Bro! I am Legend"
|
||||
end
|
||||
it "always returns the same ruby object for the same V8 object" do
|
||||
one = V8::C::Object::New()
|
||||
two = V8::C::Object::New()
|
||||
one.Set("two", two)
|
||||
one.Get("two").should be two
|
||||
end
|
||||
end
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# encoding: UTF-8
|
||||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Script do
|
||||
requires_v8_context
|
||||
|
||||
it "can run a script and return a polymorphic result" do
|
||||
source = V8::C::String::New("(new Array())")
|
||||
filename = V8::C::String::New("<eval>")
|
||||
script = V8::C::Script::New(source, filename)
|
||||
result = script.Run()
|
||||
result.should be_kind_of V8::C::Array
|
||||
end
|
||||
|
||||
it "can accept precompiled script data" do
|
||||
source = "7 * 6"
|
||||
name = V8::C::String::New("<spec>")
|
||||
origin = V8::C::ScriptOrigin.new(name)
|
||||
data = V8::C::ScriptData::PreCompile(source, source.length)
|
||||
data.HasError().should be_false
|
||||
script = V8::C::Script::New(V8::C::String::New(source), origin, data)
|
||||
script.Run().should eql 42
|
||||
end
|
||||
|
||||
it "can detect errors in the script data" do
|
||||
source = "^ = ;"
|
||||
data = V8::C::ScriptData::PreCompile(source, source.length)
|
||||
data.HasError().should be_true
|
||||
end
|
||||
end
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::String do
|
||||
requires_v8_context
|
||||
|
||||
it "can hold Unicode values outside the Basic Multilingual Plane" do
|
||||
string = V8::C::String::New("\u{100000}")
|
||||
string.Utf8Value().should eql "\u{100000}"
|
||||
end
|
||||
|
||||
it "can naturally translate ruby strings into v8 strings" do
|
||||
V8::C::String::Concat(V8::C::String::New("Hello "), "World").Utf8Value().should eql "Hello World"
|
||||
end
|
||||
|
||||
it "can naturally translate ruby objects into v8 strings" do
|
||||
V8::C::String::Concat(V8::C::String::New("forty two is "), 42).Utf8Value().should eql "forty two is 42"
|
||||
end
|
||||
end
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Template do
|
||||
requires_v8_context
|
||||
|
||||
describe V8::C::FunctionTemplate do
|
||||
it "can be created with no arguments" do
|
||||
t = V8::C::FunctionTemplate::New()
|
||||
t.GetFunction().Call(@cxt.Global(),[]).StrictEquals(@cxt.Global()).should be_true
|
||||
end
|
||||
|
||||
it "can be created with a callback" do
|
||||
receiver = V8::C::Object::New()
|
||||
f = nil
|
||||
callback = lambda do |arguments|
|
||||
arguments.Length().should be(2)
|
||||
arguments[0].Utf8Value().should eql 'one'
|
||||
arguments[1].Utf8Value().should eql 'two'
|
||||
arguments.Callee().StrictEquals(f).should be_true
|
||||
arguments.This().StrictEquals(receiver).should be_true
|
||||
arguments.Holder().StrictEquals(receiver).should be_true
|
||||
arguments.IsConstructCall().should be_false
|
||||
arguments.Data().Value().should be(42)
|
||||
V8::C::String::New("result")
|
||||
end
|
||||
t = V8::C::FunctionTemplate::New(callback, V8::C::External::New(42))
|
||||
f = t.GetFunction()
|
||||
f.Call(receiver, [V8::C::String::New('one'), V8::C::String::New('two')]).Utf8Value().should eql "result"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::External do
|
||||
requires_v8_context
|
||||
|
||||
it "can catch javascript exceptions" do
|
||||
V8::C::V8::SetCaptureStackTraceForUncaughtExceptions(true, 99, V8::C::StackTrace::kDetailed)
|
||||
V8::C::TryCatch() do |trycatch|
|
||||
source = V8::C::String::New(<<-JS)
|
||||
function one() {
|
||||
two()
|
||||
}
|
||||
function two() {
|
||||
three()
|
||||
}
|
||||
function three() {
|
||||
boom()
|
||||
}
|
||||
function boom() {
|
||||
throw new Error('boom!')
|
||||
}
|
||||
eval('one()')
|
||||
JS
|
||||
filename = V8::C::String::New("<eval>")
|
||||
script = V8::C::Script::New(source, filename)
|
||||
result = script.Run()
|
||||
trycatch.HasCaught().should be_true
|
||||
trycatch.CanContinue().should be_true
|
||||
exception = trycatch.Exception()
|
||||
exception.should_not be_nil
|
||||
exception.IsNativeError().should be_true
|
||||
trycatch.StackTrace().Utf8Value().should match /boom.*three.*two.*one/m
|
||||
message = trycatch.Message();
|
||||
message.should_not be_nil
|
||||
message.Get().Utf8Value().should eql "Uncaught Error: boom!"
|
||||
message.GetSourceLine().Utf8Value().should eql " throw new Error('boom!')"
|
||||
message.GetScriptResourceName().Utf8Value().should eql "<eval>"
|
||||
message.GetLineNumber().should eql 11
|
||||
stack = message.GetStackTrace()
|
||||
stack.should_not be_nil
|
||||
stack.GetFrameCount().should eql 6
|
||||
frame = stack.GetFrame(0)
|
||||
frame.GetLineNumber().should eql 11
|
||||
frame.GetColumn().should eql 15
|
||||
frame.GetScriptName().Utf8Value().should eql "<eval>"
|
||||
frame.GetScriptNameOrSourceURL().Utf8Value().should eql "<eval>"
|
||||
frame.IsEval().should be_false
|
||||
stack.GetFrame(4).IsEval().should be_true
|
||||
frame.IsConstructor().should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue