diff --git a/ext/v8/array.cc b/ext/v8/array.cc new file mode 100644 index 0000000..1e3c7fd --- /dev/null +++ b/ext/v8/array.cc @@ -0,0 +1,40 @@ +#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 rb_isolate, length; + rb_scan_args(argc, argv, "11", &rb_isolate, &length); + + Isolate isolate(rb_isolate); + Locker lock(isolate); + + return Array(isolate, v8::Array::New(isolate, RTEST(length) ? NUM2INT(length) : 0)); + } + + VALUE Array::Length(VALUE self) { + Array array(self); + Locker lock(array.getIsolate()); + + return UInt32(array->Length()); + } + + VALUE Array::CloneElementAt(VALUE self, VALUE index) { + Array array(self); + Locker lock(array.getIsolate()); + + return Object(array.getIsolate(), array->CloneElementAt(UInt32(index))); + } + +} diff --git a/ext/v8/array.h b/ext/v8/array.h new file mode 100644 index 0000000..da150a9 --- /dev/null +++ b/ext/v8/array.h @@ -0,0 +1,20 @@ +#ifndef RR_ARRAY +#define RR_ARRAY + +namespace rr { + + 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::Isolate* isolate, v8::Handle array) : Ref(isolate, array) {} + inline Array(VALUE value) : Ref(value) {} + }; + +} + +#endif diff --git a/ext/v8/init.cc b/ext/v8/init.cc index af60e34..4ac6e99 100644 --- a/ext/v8/init.cc +++ b/ext/v8/init.cc @@ -19,11 +19,11 @@ extern "C" { String::Init(); Function::Init(); Script::Init(); + Array::Init(); // Accessor::Init(); // Invocation::Init(); // Signature::Init(); - // Array::Init(); // Date::Init(); // Constants::Init(); // External::Init(); diff --git a/ext/v8/ref.h b/ext/v8/ref.h index d708b17..6beb7a5 100644 --- a/ext/v8/ref.h +++ b/ext/v8/ref.h @@ -65,11 +65,11 @@ namespace rr { /* * Coerce a Ref into a v8::Local. */ - virtual operator v8::Handle() const { + inline operator v8::Handle() const { return handle; } - v8::Isolate* getIsolate() const { + inline v8::Isolate* getIsolate() const { return isolate; } diff --git a/ext/v8/rr.h b/ext/v8/rr.h index edc478e..2e7c6fa 100644 --- a/ext/v8/rr.h +++ b/ext/v8/rr.h @@ -35,6 +35,7 @@ inline VALUE not_implemented(const char* message) { #include "backref.h" #include "object.h" +#include "array.h" #include "primitive.h" // This one is named v8_string to avoid name collisions with C's string.h #include "rr_string.h" diff --git a/ext/v8/value.cc b/ext/v8/value.cc index b4e4f3f..02b4119 100644 --- a/ext/v8/value.cc +++ b/ext/v8/value.cc @@ -37,8 +37,8 @@ namespace rr { // defineMethod("IntegerValue", &IntegerValue). // defineMethod("Uint32Value", &Uint32Value). // defineMethod("IntegerValue", &IntegerValue). - // defineMethod("Equals", &Equals). - // defineMethod("StrictEquals", &StrictEquals). + defineMethod("Equals", &Equals). + defineMethod("StrictEquals", &StrictEquals). defineMethod("ToRubyObject", &ToRubyObject). defineSingletonMethod("FromRubyObject", &FromRubyObject). diff --git a/spec/c/array_spec.rb b/spec/c/array_spec.rb new file mode 100644 index 0000000..66a15c1 --- /dev/null +++ b/spec/c/array_spec.rb @@ -0,0 +1,23 @@ +require 'c_spec_helper' + +describe V8::C::Array do + requires_v8_context + + it 'can store and retrieve a value' do + o = V8::C::Object::New(@isolate) + a = V8::C::Array::New(@isolate) + + expect(a.Length).to eq 0 + + a.Set(0, o) + expect(a.Length).to eq 1 + + expect(a.Get(0).Equals(o)).to eq true + end + + it 'can be initialized with a length' do + a = V8::C::Array::New(@isolate, 5) + + expect(a.Length).to eq 5 + end +end