diff --git a/ext/v8/accessor.cc b/ext/v8/accessor.cc deleted file mode 100644 index 31bef24..0000000 --- a/ext/v8/accessor.cc +++ /dev/null @@ -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 value) { - v8::Local 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 data = wrapper->Get(5); - if (!data.IsEmpty() && !data->IsNull() && !data->IsUndefined()) { - this->data = Value(data); - } - } - - Accessor::operator v8::Handle() { - v8::Local 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 wrapper, int index, VALUE value) { - if (RTEST(value)) { - wrapper->Set(index, External::wrap(value)); - } - } - - VALUE Accessor::unwrap(v8::Handle wrapper, int index) { - v8::Handle value = wrapper->Get(index); - if (value.IsEmpty() || !value->IsExternal()) { - return Qnil; - } else { - v8::Handle 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 Accessor::AccessorGetter(v8::Local property, const v8::AccessorInfo& info) { - return Info(info).get(property); - } - - void Accessor::AccessorSetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - Info(info).set(property, value); - } - v8::Handle Accessor::NamedPropertyGetter(v8::Local property, const v8::AccessorInfo& info) { - return Info(info).get(property); - } - v8::Handle Accessor::NamedPropertySetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - return Info(info).set(property, value); - } - v8::Handle Accessor::NamedPropertyQuery(v8::Local property, const v8::AccessorInfo& info) { - return Info(info).query(property); - } - v8::Handle Accessor::NamedPropertyDeleter(v8::Local property, const v8::AccessorInfo& info) { - return Info(info).remove(property); - } - v8::Handle Accessor::NamedPropertyEnumerator(const v8::AccessorInfo& info) { - return Info(info).enumerateNames(); - } - - v8::Handle Accessor::IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) { - return Info(info).get(index); - } - v8::Handle Accessor::IndexedPropertySetter(uint32_t index, v8::Local value, const v8::AccessorInfo& info) { - return Info(info).set(index, value); - } - v8::Handle Accessor::IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info) { - return Info(info).query(index); - } - v8::Handle Accessor::IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info) { - return Info(info).remove(index); - } - v8::Handle 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 Accessor::Info::get(v8::Local property) { - Accessor accessor(info->Data()); - return Value(rb_funcall(accessor.get, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)); - } - - v8::Handle Accessor::Info::set(v8::Local property, v8::Local 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 Accessor::Info::query(v8::Local 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 Accessor::Info::remove(v8::Local 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 Accessor::Info::enumerateNames() { - Accessor accessor(info->Data()); - return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this)); - } - - v8::Handle 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 Accessor::Info::set(uint32_t index, v8::Local value) { - Accessor accessor(info->Data()); - return Value(rb_funcall(accessor.set, rb_intern("call"), 3, UINT2NUM(index), (VALUE)Value(value), (VALUE)*this)); - } - - v8::Handle 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 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 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); - } -} \ No newline at end of file diff --git a/ext/v8/array.cc b/ext/v8/array.cc deleted file mode 100644 index 9f9bfc1..0000000 --- a/ext/v8/array.cc +++ /dev/null @@ -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))); -} - -} \ No newline at end of file diff --git a/ext/v8/backref.cc b/ext/v8/backref.cc deleted file mode 100644 index 25421b3..0000000 --- a/ext/v8/backref.cc +++ /dev/null @@ -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 Backref::toExternal() { - v8::Local wrapper = v8::External::New(this); - v8::Persistent::New(wrapper).MakeWeak(this, &release); - return wrapper; - } - - void Backref::release(v8::Persistent handle, void* data) { - handle.Dispose(); - Backref* backref = (Backref*)data; - delete backref; - } -} diff --git a/ext/v8/rr.cc b/ext/v8/class_builder.cc similarity index 88% rename from ext/v8/rr.cc rename to ext/v8/class_builder.cc index 2896d1a..047f19a 100644 --- a/ext/v8/rr.cc +++ b/ext/v8/class_builder.cc @@ -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; } -} \ No newline at end of file + +} diff --git a/ext/v8/class_builder.h b/ext/v8/class_builder.h new file mode 100644 index 0000000..163b88f --- /dev/null +++ b/ext/v8/class_builder.h @@ -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 diff --git a/ext/v8/constants.cc b/ext/v8/constants.cc deleted file mode 100644 index 65ca1b0..0000000 --- a/ext/v8/constants.cc +++ /dev/null @@ -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(&_Undefined, v8::Undefined()); - } - VALUE Constants::Null(VALUE self) { - return cached(&_Null, v8::Null()); - } - VALUE Constants::True(VALUE self) { - return cached(&_True, v8::True()); - } - VALUE Constants::False(VALUE self) { - return cached(&_False, v8::False()); - } -} \ No newline at end of file diff --git a/ext/v8/constraints.cc b/ext/v8/constraints.cc deleted file mode 100644 index 5ba5e86..0000000 --- a/ext/v8/constraints.cc +++ /dev/null @@ -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::unwrap(VALUE value) { - Data_Get_Struct(value, class v8::ResourceConstraints, pointer); - } -} \ No newline at end of file diff --git a/ext/v8/context.cc b/ext/v8/context.cc deleted file mode 100644 index f5849f5..0000000 --- a/ext/v8/context.cc +++ /dev/null @@ -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 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::unwrap(VALUE value) { - Data_Get_Struct(value, class v8::ExtensionConfiguration, pointer); -} - -} diff --git a/ext/v8/date.cc b/ext/v8/date.cc deleted file mode 100644 index 1c51b1b..0000000 --- a/ext/v8/date.cc +++ /dev/null @@ -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()); - } -} \ No newline at end of file diff --git a/ext/v8/exception.cc b/ext/v8/exception.cc deleted file mode 100644 index 8fb23de..0000000 --- a/ext/v8/exception.cc +++ /dev/null @@ -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))); - } -} \ No newline at end of file diff --git a/ext/v8/extconf.rb b/ext/v8/extconf.rb index 1bc885b..bcbe4cf 100644 --- a/ext/v8/extconf.rb +++ b/ext/v8/extconf.rb @@ -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' diff --git a/ext/v8/external.cc b/ext/v8/external.cc deleted file mode 100644 index c4f6701..0000000 --- a/ext/v8/external.cc +++ /dev/null @@ -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 External::wrap(VALUE data) { - Data* holder = new Data(data); - v8::Local ext = v8::External::New(holder); - v8::Persistent::New(ext).MakeWeak(holder, &release); - return ext; -} - -VALUE External::unwrap(v8::Handle external) { - Data* data = (Data*)(external->Value()); - return data->value; -} - -VALUE External::Value(VALUE self) { - return unwrap(External(self)); -} - -void External::release(v8::Persistent 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); -} -} \ No newline at end of file diff --git a/ext/v8/function.cc b/ext/v8/function.cc deleted file mode 100644 index c4380c2..0000000 --- a/ext/v8/function.cc +++ /dev/null @@ -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(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(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"); - } -} \ No newline at end of file diff --git a/ext/v8/gc.cc b/ext/v8/gc.cc deleted file mode 100644 index 9412e9b..0000000 --- a/ext/v8/gc.cc +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/ext/v8/handles.cc b/ext/v8/handles.cc index d51c909..f1c37fa 100644 --- a/ext/v8/handles.cc +++ b/ext/v8/handles.cc @@ -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); + } -} \ No newline at end of file +} diff --git a/ext/v8/handles.h b/ext/v8/handles.h new file mode 100644 index 0000000..3d57ebf --- /dev/null +++ b/ext/v8/handles.h @@ -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 diff --git a/ext/v8/heap.cc b/ext/v8/heap.cc deleted file mode 100644 index cf930b6..0000000 --- a/ext/v8/heap.cc +++ /dev/null @@ -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::unwrap(VALUE value) { - Data_Get_Struct(value, class v8::HeapStatistics, pointer); - } -} diff --git a/ext/v8/init.cc b/ext/v8/init.cc index 94d6f01..e09c605 100644 --- a/ext/v8/init.cc +++ b/ext/v8/init.cc @@ -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(); } -} \ No newline at end of file +} diff --git a/ext/v8/invocation.cc b/ext/v8/invocation.cc deleted file mode 100644 index 497e530..0000000 --- a/ext/v8/invocation.cc +++ /dev/null @@ -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 value) { - v8::Local wrapper = value->ToObject(); - this->code = External::unwrap((v8::Handle)v8::External::Cast(*wrapper->Get(0))); - this->data = Value(wrapper->Get(1)); - } - Invocation::operator v8::InvocationCallback() { - return &Callback; - } - Invocation::operator v8::Handle() { - v8::Local wrapper = v8::Object::New(); - wrapper->Set(0, External::wrap(this->code)); - wrapper->Set(1, Value(this->data)); - return wrapper; - } - - v8::Handle 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 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; - } -} \ No newline at end of file diff --git a/ext/v8/isolate.cc b/ext/v8/isolate.cc new file mode 100644 index 0000000..18e6ff9 --- /dev/null +++ b/ext/v8/isolate.cc @@ -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::unwrap(VALUE value) { + Data_Get_Struct(value, class v8::Isolate, pointer); + } + +} diff --git a/ext/v8/isolate.h b/ext/v8/isolate.h new file mode 100644 index 0000000..d956cee --- /dev/null +++ b/ext/v8/isolate.h @@ -0,0 +1,31 @@ +#ifndef RR_ISOLATE +#define RR_ISOLATE + +namespace rr { + + class Isolate : public Pointer { + public: + static void Init(); + static VALUE New(VALUE self); + + inline Isolate(v8::Isolate* isolate) : Pointer(isolate) {} + inline Isolate(VALUE value) : Pointer(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 diff --git a/ext/v8/locker.cc b/ext/v8/locker.cc deleted file mode 100644 index b9fbe78..0000000 --- a/ext/v8/locker.cc +++ /dev/null @@ -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); - } -} diff --git a/ext/v8/message.cc b/ext/v8/message.cc deleted file mode 100644 index 0d732ed..0000000 --- a/ext/v8/message.cc +++ /dev/null @@ -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()); - } -} \ No newline at end of file diff --git a/ext/v8/object.cc b/ext/v8/object.cc deleted file mode 100644 index e63ee3b..0000000 --- a/ext/v8/object.cc +++ /dev/null @@ -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 key(v8::String::NewSymbol("rr::Backref")); - v8::Local external = handle->GetHiddenValue(key); - VALUE value; - if (external.IsEmpty()) { - value = downcast(); - backref = new Backref(value); - handle->SetHiddenValue(key, backref->toExternal()); - } else { - v8::Local 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::Cast(*handle)); - } - if (handle->IsArray()) { - return Array((v8::Handle)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::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(argv))); -} - -VALUE Object::CallAsConstructor(VALUE self, VALUE argv) { - return Value(Object(self)->CallAsConstructor(RARRAY_LENINT(argv), Value::array(argv))); -} - -} diff --git a/ext/v8/pointer.h b/ext/v8/pointer.h new file mode 100644 index 0000000..a2c3884 --- /dev/null +++ b/ext/v8/pointer.h @@ -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 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 ptr(value); + * ptr->CallMethod(); + */ + template + 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 VALUE Pointer::Class; + +} + +#endif diff --git a/ext/v8/primitive.cc b/ext/v8/primitive.cc deleted file mode 100644 index 6ea1186..0000000 --- a/ext/v8/primitive.cc +++ /dev/null @@ -1,8 +0,0 @@ -#include "rr.h" - -namespace rr { - void Primitive::Init() { - ClassBuilder("Primitive", Value::Class). - store(&Class); - } -} \ No newline at end of file diff --git a/ext/v8/rr.h b/ext/v8/rr.h index 6c76bc0..401cf47 100644 --- a/ext/v8/rr.h +++ b/ext/v8/rr.h @@ -1,934 +1,21 @@ #ifndef THE_RUBY_RACER #define THE_RUBY_RACER -#include +#include +#include + #include #include #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 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 Enum : public Equiv { -public: - Enum(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 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 ptr(value); -* ptr->CallMethod(); -*/ - -template 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 VALUE Pointer::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 object = v8::Object::New(); -* VALUE val = Ref(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 object(val); -* object->Get(v8::String::New("foo")); -* -*/ -template class Ref { -public: - Ref(VALUE value) { - this->value = value; - } - Ref(v8::Handle handle, const char* label = "v8::Handle") { - 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() const { - if (RTEST(this->value)) { - Holder* holder = NULL; - Data_Get_Struct(this->value, class Holder, holder); - return holder->handle; - } else { - return v8::Handle(); - } - } - 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(value)->ToString(); - */ - inline v8::Handle operator->() const { return *this;} - inline v8::Handle operator*() const {return *this;} - - template class array { - public: - inline array(VALUE ary) : argv(ary), vector(RARRAY_LENINT(argv)) {} - inline operator v8::Handle*() { - 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 > vector; - }; - - class Holder { - friend class Ref; - public: - Holder(v8::Handle handle) { - this->disposed_p = false; - this->handle = v8::Persistent::New(handle); - } - virtual ~Holder() { - this->dispose(); - } - void dispose() { - if (!this->disposed_p) { - handle.Dispose(); - this->disposed_p = true; - } - } - protected: - v8::Persistent handle; - bool disposed_p; - - static void enqueue(Holder* holder) { - GC::Finalize(holder); - } - }; - - VALUE value; - v8::Handle handle; - static VALUE Class; -}; -template VALUE Ref::Class; - -class Backref { -public: - static void Init(); - Backref(VALUE value); - virtual ~Backref(); - VALUE get(); - VALUE set(VALUE value); - v8::Handle toExternal(); - static void release(v8::Persistent 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::Holder*)reference) {} - inline bool NotNull() { - return this->holder != NULL; - } - inline void destroy() { - delete holder; - } - Ref::Holder* holder; -}; - -class ExtensionConfiguration : public Pointer { -public: - static VALUE initialize(VALUE self, VALUE names); - inline ExtensionConfiguration(v8::ExtensionConfiguration* config) : Pointer(config) {} - inline ExtensionConfiguration(VALUE value) : Pointer(value) {} -}; - -class Context : public Ref { -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(value) {} - inline Context(v8::Handle cxt) : Ref(cxt) {} -}; - -class External: public Ref { -public: - static void Init(); - static VALUE New(VALUE self, VALUE data); - static VALUE Value(VALUE self); - - inline External(VALUE value) : Ref(value) {} - inline External(v8::Handle ext) : Ref(ext) {} - static v8::Handle wrap(VALUE data); - static VALUE unwrap(v8::Handle external); -private: - static void release(v8::Persistent object, void* parameter); - struct Data { - Data(VALUE data); - ~Data(); - VALUE value; - }; -}; - -class ScriptOrigin : public Pointer { -public: - inline ScriptOrigin(v8::ScriptOrigin* o) : Pointer(o) {}; - inline ScriptOrigin(VALUE value) : Pointer(value) {} - - static VALUE initialize(int argc, VALUE argv[], VALUE self); -}; - -class ScriptData : public Pointer { -public: - inline ScriptData(v8::ScriptData* d) : Pointer(d) {}; - inline ScriptData(VALUE value) : Pointer(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 { -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(value) {} - inline Script(v8::Handle script) : Ref(script) {} -}; - -class Value : public Ref { -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(value) {} - inline Value(v8::Handle value) : Ref(value) {} - virtual operator VALUE(); - virtual operator v8::Handle() const; - static VALUE Empty; -}; - -class Primitive: public Ref { -public: - static void Init(); - inline Primitive(VALUE value) : Ref(value) {} - inline Primitive(v8::Handle primitive) : Ref(primitive) {} -}; - -class String: public Ref { -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(value) {} - inline String(v8::Handle string) : Ref(string) {} - virtual operator v8::Handle() const; -}; - -class PropertyAttribute: public Enum { -public: - inline PropertyAttribute(VALUE value) : Enum(value, v8::None) {} -}; -class AccessControl: public Enum { -public: - inline AccessControl(VALUE value) : Enum(value, v8::DEFAULT) {} -}; - -class Accessor { -public: - static void Init(); - Accessor(VALUE get, VALUE set, VALUE data); - Accessor(VALUE get, VALUE set, VALUE query, VALUE deleter, VALUE enumerator, VALUE data); - Accessor(v8::Handle value); - - inline v8::AccessorGetter accessorGetter() {return &AccessorGetter;} - inline v8::AccessorSetter accessorSetter() {return RTEST(set) ? &AccessorSetter : 0;} - - inline v8::NamedPropertyGetter namedPropertyGetter() {return &NamedPropertyGetter;} - inline v8::NamedPropertySetter namedPropertySetter() {return RTEST(set) ? &NamedPropertySetter : 0;} - inline v8::NamedPropertyQuery namedPropertyQuery() {return RTEST(query) ? &NamedPropertyQuery : 0;} - inline v8::NamedPropertyDeleter namedPropertyDeleter() {return RTEST(deleter) ? &NamedPropertyDeleter : 0;} - inline v8::NamedPropertyEnumerator namedPropertyEnumerator() {return RTEST(enumerator) ? &NamedPropertyEnumerator : 0;} - - inline v8::IndexedPropertyGetter indexedPropertyGetter() {return &IndexedPropertyGetter;} - inline v8::IndexedPropertySetter indexedPropertySetter() {return RTEST(set) ? &IndexedPropertySetter : 0;} - inline v8::IndexedPropertyQuery indexedPropertyQuery() {return RTEST(query) ? &IndexedPropertyQuery : 0;} - inline v8::IndexedPropertyDeleter indexedPropertyDeleter() {return RTEST(deleter) ? &IndexedPropertyDeleter : 0;} - inline v8::IndexedPropertyEnumerator indexedPropertyEnumerator() {return RTEST(enumerator) ? &IndexedPropertyEnumerator : 0;} - - operator v8::Handle(); - - class Info { - public: - Info(const v8::AccessorInfo& info); - Info(VALUE value); - static VALUE This(VALUE self); - static VALUE Holder(VALUE self); - static VALUE Data(VALUE self); - operator VALUE(); - inline const v8::AccessorInfo* operator->() {return this->info;} - v8::Handle get(v8::Local property); - v8::Handle set(v8::Local property, v8::Local value); - v8::Handle query(v8::Local property); - v8::Handle remove(v8::Local property); - v8::Handle enumerateNames(); - v8::Handle get(uint32_t index); - v8::Handle set(uint32_t index, v8::Local value); - v8::Handle query(uint32_t index); - v8::Handle remove(uint32_t index); - v8::Handle enumerateIndices(); - - static VALUE Class; - private: - const v8::AccessorInfo* info; - }; - friend class Info; -private: - static v8::Handle AccessorGetter(v8::Local property, const v8::AccessorInfo& info); - static void AccessorSetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info); - - static v8::Handle NamedPropertyGetter(v8::Local property, const v8::AccessorInfo& info); - static v8::Handle NamedPropertySetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info); - static v8::Handle NamedPropertyQuery(v8::Local property, const v8::AccessorInfo& info); - static v8::Handle NamedPropertyDeleter(v8::Local property, const v8::AccessorInfo& info); - static v8::Handle NamedPropertyEnumerator(const v8::AccessorInfo& info); - - static v8::Handle IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info); - static v8::Handle IndexedPropertySetter(uint32_t index, v8::Local value, const v8::AccessorInfo& info); - static v8::Handle IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info); - static v8::Handle IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info); - static v8::Handle IndexedPropertyEnumerator(const v8::AccessorInfo& info); - - void wrap(v8::Handle wrapper, int index, VALUE value); - VALUE unwrap(v8::Handle wrapper, int index); - VALUE get; - VALUE set; - VALUE query; - VALUE deleter; - VALUE enumerator; - VALUE data; -}; - -class Invocation { -public: - static void Init(); - Invocation(VALUE code, VALUE data); - Invocation(v8::Handle wrapper); - operator v8::InvocationCallback(); - operator v8::Handle(); - static v8::Handle Callback(const v8::Arguments& args); - - class Arguments { - public: - static void Init(); - Arguments(const v8::Arguments& args); - Arguments(VALUE value); - inline const v8::Arguments* operator->() {return this->args;} - inline const v8::Arguments operator*() {return *this->args;} - v8::Handle Call(); - - static VALUE Length(VALUE self); - static VALUE Get(VALUE self, VALUE index); - static VALUE Callee(VALUE self); - static VALUE This(VALUE self); - static VALUE Holder(VALUE self); - static VALUE IsConstructCall(VALUE self); - static VALUE Data(VALUE self); - private: - const v8::Arguments* args; - static VALUE Class; - }; -private: - VALUE code; - VALUE data; - friend class Arguments; -}; - -class Object : public Ref { -public: - static void Init(); - static VALUE New(VALUE self); - static VALUE Set(VALUE self, VALUE key, VALUE value); - static VALUE ForceSet(VALUE self, VALUE key, VALUE value); - static VALUE Get(VALUE self, VALUE key); - static VALUE GetPropertyAttributes(VALUE self, VALUE key); - static VALUE Has(VALUE self, VALUE key); - static VALUE Delete(VALUE self, VALUE key); - static VALUE ForceDelete(VALUE self, VALUE key); - static VALUE SetAccessor(int argc, VALUE* argv, VALUE self); - static VALUE GetPropertyNames(VALUE self); - static VALUE GetOwnPropertyNames(VALUE self); - static VALUE GetPrototype(VALUE self); - static VALUE SetPrototype(VALUE self, VALUE prototype); - static VALUE FindInstanceInPrototypeChain(VALUE self, VALUE impl); - static VALUE ObjectProtoToString(VALUE self); - static VALUE GetConstructorName(VALUE self); - static VALUE InternalFieldCount(VALUE self); - static VALUE GetInternalField(VALUE self, VALUE idx); - static VALUE SetInternalField(VALUE self, VALUE idx, VALUE value); - static VALUE HasOwnProperty(VALUE self, VALUE key); - static VALUE HasRealNamedProperty(VALUE self, VALUE key); - static VALUE HasRealIndexedProperty(VALUE self, VALUE idx); - static VALUE HasRealNamedCallbackProperty(VALUE self, VALUE key); - static VALUE GetRealNamedPropertyInPrototypeChain(VALUE self, VALUE key); - static VALUE GetRealNamedProperty(VALUE self, VALUE key); - static VALUE HasNamedLookupInterceptor(VALUE self); - static VALUE HasIndexedLookupInterceptor(VALUE self); - static VALUE TurnOnAccessCheck(VALUE self); - static VALUE GetIdentityHash(VALUE self); - static VALUE SetHiddenValue(VALUE self, VALUE key, VALUE value); - static VALUE GetHiddenValue(VALUE self, VALUE key); - static VALUE DeleteHiddenValue(VALUE self, VALUE key); - static VALUE IsDirty(VALUE self); - static VALUE Clone(VALUE self); - static VALUE CreationContext(VALUE self); - static VALUE SetIndexedPropertiesToPixelData(VALUE self, VALUE data, VALUE length); - static VALUE GetIndexedPropertiesPixelData(VALUE self); - static VALUE HasIndexedPropertiesInPixelData(VALUE self); - static VALUE GetIndexedPropertiesPixelDataLength(VALUE self); - static VALUE SetIndexedPropertiesToExternalArrayData(VALUE self); - static VALUE HasIndexedPropertiesInExternalArrayData(VALUE self); - static VALUE GetIndexedPropertiesExternalArrayData(VALUE self); - static VALUE GetIndexedPropertiesExternalArrayDataType(VALUE self); - static VALUE GetIndexedPropertiesExternalArrayDataLength(VALUE self); - static VALUE IsCallable(VALUE self); - static VALUE CallAsFunction(VALUE self, VALUE recv, VALUE argv); - static VALUE CallAsConstructor(VALUE self, VALUE argv); - - inline Object(VALUE value) : Ref(value) {} - inline Object(v8::Handle object) : Ref(object) {} - virtual operator VALUE(); - -protected: - VALUE downcast(); -}; - -class Array : public Ref { -public: - static void Init(); - static VALUE New(int argc, VALUE argv[], VALUE self); - static VALUE Length(VALUE self); - static VALUE CloneElementAt(VALUE self, VALUE index); - - inline Array(v8::Handle array) : Ref(array) {} - inline Array(VALUE value) : Ref(value) {} -}; - -class Function : public Ref { -public: - static void Init(); - static VALUE NewInstance(int 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(value) {} - inline Function(v8::Handle function) : Ref(function) {} -}; - -class Date : public Ref { -public: - static void Init(); - static VALUE New(VALUE self, VALUE time); - static VALUE NumberValue(VALUE self); - - inline Date(VALUE value) : Ref(value) {} - inline Date(v8::Handle date) : Ref(date) {} -}; - -class Signature : public Ref { -public: - static void Init(); - static VALUE New(int argc, VALUE argv[], VALUE self); - - inline Signature(v8::Handle sig) : Ref(sig) {} - inline Signature(VALUE value) : Ref(value) {} -}; - -class Template : public Ref { -public: - static void Init(); - static VALUE Set(int argc, VALUE argv[], VALUE self); - inline Template(v8::Handle t) : Ref(t) {} - inline Template(VALUE value) : Ref(value) {} -}; - -class ObjectTemplate : public Ref { -public: - static void Init(); - static VALUE New(VALUE self); - static VALUE NewInstance(VALUE self); - static VALUE SetAccessor(int argc, VALUE argv[], VALUE self); - static VALUE SetNamedPropertyHandler(int argc, VALUE argv[], VALUE self); - static VALUE SetIndexedPropertyHandler(int argc, VALUE argv[], VALUE self); - static VALUE SetCallAsFunctionHandler(int argc, VALUE argv[], VALUE self); - static VALUE MarkAsUndetectable(VALUE self); - static VALUE SetAccessCheckCallbacks(int argc, VALUE argv[], VALUE self); - static VALUE InternalFieldCount(VALUE self); - static VALUE SetInternalFieldCount(VALUE self, VALUE count); - - inline ObjectTemplate(VALUE value) : Ref(value) {} - inline ObjectTemplate(v8::Handle t) : Ref(t) {} -}; - -class FunctionTemplate : public Ref { -public: - static void Init(); - static VALUE New(int argc, VALUE argv[], VALUE self); - static VALUE GetFunction(VALUE self); - static VALUE SetCallHandler(int argc, VALUE argv[], VALUE self); - static VALUE InstanceTemplate(VALUE self); - static VALUE Inherit(VALUE self, VALUE parent); - static VALUE PrototypeTemplate(VALUE self); - static VALUE SetClassName(VALUE self, VALUE name); - static VALUE SetHiddenPrototype(VALUE self, VALUE value); - static VALUE ReadOnlyPrototype(VALUE self); - static VALUE HasInstance(VALUE self, VALUE object); - - inline FunctionTemplate(VALUE value) : Ref(value) {} - inline FunctionTemplate(v8::Handle t) : Ref(t) {} -}; - -class Message : public Ref { -public: - static void Init(); - inline Message(v8::Handle message) : Ref(message) {} - inline Message(VALUE value) : Ref(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 { - public: - class StackTraceOptions : public Enum { - public: - inline StackTraceOptions(VALUE value) : Enum(value, v8::StackTrace::kOverview) {} - }; - public: - inline Trace(v8::Handle trace) : Ref(trace) {} - inline Trace(VALUE value) : Ref(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 { - public: - inline Frame(v8::Handle frame) : Ref(frame) {} - inline Frame(VALUE value) : Ref(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 { -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(stats) {} - inline HeapStatistics(VALUE value) : Pointer(value) {} -}; - -class ResourceConstraints : Pointer { -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(o) {}; - inline ResourceConstraints(VALUE value) : Pointer(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 static VALUE cached(VALUE* storage, v8::Handle 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 + diff --git a/ext/v8/script.cc b/ext/v8/script.cc deleted file mode 100644 index f93823c..0000000 --- a/ext/v8/script.cc +++ /dev/null @@ -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 loff = v8::Integer::New(RTEST(line_offset) ? NUM2INT(line_offset) : 0); - v8::Handle 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::unwrap(VALUE value) { - Data_Get_Struct(value, class v8::ScriptData, pointer); -} - -template <> void Pointer::unwrap(VALUE value) { - Data_Get_Struct(value, class v8::ScriptOrigin, pointer); -} - -} //namespace rr diff --git a/ext/v8/signature.cc b/ext/v8/signature.cc deleted file mode 100644 index d227d27..0000000 --- a/ext/v8/signature.cc +++ /dev/null @@ -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 types(argv); - return Signature(v8::Signature::New(recv, length, types)); - } -} \ No newline at end of file diff --git a/ext/v8/stack.cc b/ext/v8/stack.cc deleted file mode 100644 index 1f09558..0000000 --- a/ext/v8/stack.cc +++ /dev/null @@ -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()); - } -} \ No newline at end of file diff --git a/ext/v8/string.cc b/ext/v8/string.cc deleted file mode 100644 index a75ead4..0000000 --- a/ext/v8/string.cc +++ /dev/null @@ -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() const { - switch (TYPE(value)) { - case T_STRING: - return v8::String::New(RSTRING_PTR(value), (int)RSTRING_LEN(value)); - case T_DATA: - return Ref::operator v8::Handle(); - default: - VALUE string = rb_funcall(value, rb_intern("to_s"), 0); - return v8::String::New(RSTRING_PTR(string), (int)RSTRING_LEN(string)); - } -} - -} //namespace rr \ No newline at end of file diff --git a/ext/v8/template.cc b/ext/v8/template.cc deleted file mode 100644 index e82642d..0000000 --- a/ext/v8/template.cc +++ /dev/null @@ -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))); - } -} \ No newline at end of file diff --git a/ext/v8/trycatch.cc b/ext/v8/trycatch.cc deleted file mode 100644 index 1f09298..0000000 --- a/ext/v8/trycatch.cc +++ /dev/null @@ -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")); - } -} \ No newline at end of file diff --git a/ext/v8/v8.cc b/ext/v8/v8.cc index 6357ca6..4bdc60d 100644 --- a/ext/v8/v8.cc +++ b/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()); -} -} \ No newline at end of file diff --git a/ext/v8/v8.h b/ext/v8/v8.h new file mode 100644 index 0000000..a8f5ca5 --- /dev/null +++ b/ext/v8/v8.h @@ -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); + }; +} diff --git a/ext/v8/value.cc b/ext/v8/value.cc deleted file mode 100644 index af2a955..0000000 --- a/ext/v8/value.cc +++ /dev/null @@ -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::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::Cast(*handle)); - } - if (handle->IsObject()) { - return Object(handle->ToObject()); - } - return Ref::operator VALUE(); -} - -Value::operator v8::Handle() const { - if (rb_equal(value,Empty)) { - return v8::Handle(); - } - 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::operator v8::Handle(); - 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(); -} -} \ No newline at end of file diff --git a/spec/c/array_spec.rb b/spec/c/array_spec.rb deleted file mode 100644 index aab6976..0000000 --- a/spec/c/array_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/constants_spec.rb b/spec/c/constants_spec.rb deleted file mode 100644 index 46837bf..0000000 --- a/spec/c/constants_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/exception_spec.rb b/spec/c/exception_spec.rb deleted file mode 100644 index 1851237..0000000 --- a/spec/c/exception_spec.rb +++ /dev/null @@ -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, '') - (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 diff --git a/spec/c/external_spec.rb b/spec/c/external_spec.rb deleted file mode 100644 index 2553028..0000000 --- a/spec/c/external_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/function_spec.rb b/spec/c/function_spec.rb deleted file mode 100644 index 17835bc..0000000 --- a/spec/c/function_spec.rb +++ /dev/null @@ -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("") - script = V8::C::Script::New(source, filename) - result = script.Run() - result.kind_of?(V8::C::String) ? result.Utf8Value() : result - end -end diff --git a/spec/c/handles_spec.rb b/spec/c/handles_spec.rb deleted file mode 100644 index 4882403..0000000 --- a/spec/c/handles_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/isolate_spec.rb b/spec/c/isolate_spec.rb new file mode 100644 index 0000000..1ec1aea --- /dev/null +++ b/spec/c/isolate_spec.rb @@ -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 diff --git a/spec/c/locker_spec.rb b/spec/c/locker_spec.rb deleted file mode 100644 index 3f7e163..0000000 --- a/spec/c/locker_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/object_spec.rb b/spec/c/object_spec.rb deleted file mode 100644 index 5864989..0000000 --- a/spec/c/object_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/script_spec.rb b/spec/c/script_spec.rb deleted file mode 100644 index db1a8b7..0000000 --- a/spec/c/script_spec.rb +++ /dev/null @@ -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("") - 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("") - 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 diff --git a/spec/c/string_spec.rb b/spec/c/string_spec.rb deleted file mode 100644 index 75184e4..0000000 --- a/spec/c/string_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/template_spec.rb b/spec/c/template_spec.rb deleted file mode 100644 index f1da9b3..0000000 --- a/spec/c/template_spec.rb +++ /dev/null @@ -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 diff --git a/spec/c/trycatch_spec.rb b/spec/c/trycatch_spec.rb deleted file mode 100644 index d9ec06e..0000000 --- a/spec/c/trycatch_spec.rb +++ /dev/null @@ -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("") - 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 "" - 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 "" - frame.GetScriptNameOrSourceURL().Utf8Value().should eql "" - frame.IsEval().should be_false - stack.GetFrame(4).IsEval().should be_true - frame.IsConstructor().should be_false - end - end -end