From 3eb5c526b190c370ac287d117ef2ac71d7c79567 Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Thu, 22 Oct 2009 23:27:41 -0500 Subject: [PATCH] access javascript objects from ruby --- ruby_data.h | 5 ++-- spec/therubyracer_spec.rb | 6 ++--- v8.cpp | 4 ++++ v8_data.h | 3 ++- v8_object.cpp | 49 +++++++++++++++++++++++++++++++++++++++ v8_object.h | 27 +++++++++++++++++++++ 6 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 v8_object.cpp create mode 100644 v8_object.h diff --git a/ruby_data.h b/ruby_data.h index f00239c..2d6e29f 100644 --- a/ruby_data.h +++ b/ruby_data.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -89,8 +90,8 @@ class RubyDest { return Qnil; } - VALUE pushObject(v8::Handle& value, const char* name = 0) { - return Qnil; + VALUE pushObject(v8::Handle& value, const char* name = 0) { + return Data_Wrap_Struct(rb_cV8_JSObject, v8_object_mark, v8_object_free, new v8_object(value)); } }; diff --git a/spec/therubyracer_spec.rb b/spec/therubyracer_spec.rb index ce44129..018523d 100644 --- a/spec/therubyracer_spec.rb +++ b/spec/therubyracer_spec.rb @@ -48,10 +48,10 @@ describe "The Ruby Racer" do object['foo'].should == 'bar' object['baz'].should == 'bang' end - end - + end + end - + def eval(str) @cxt.eval(str) end diff --git a/v8.cpp b/v8.cpp index bb3b02b..afe1748 100644 --- a/v8.cpp +++ b/v8.cpp @@ -38,6 +38,10 @@ extern "C" { rb_cV8 = rb_define_class_under(rb_mModule, "Context", rb_cObject); rb_define_alloc_func(rb_cV8, v8_allocate); rb_define_method(rb_cV8, "eval", (VALUE(*)(...)) eval, 1); + + rb_cV8_JSObject = rb_define_class_under(rb_mModule, "JSObject", rb_cObject); + rb_define_alloc_func(rb_cV8_JSObject, v8_object_allocate); + rb_define_method(rb_cV8_JSObject, "[]", (VALUE(*)(...)) v8_object_hash_access, 1); } } diff --git a/v8_data.h b/v8_data.h index 096331e..ffc7985 100644 --- a/v8_data.h +++ b/v8_data.h @@ -56,7 +56,8 @@ template class V8HandleSource { } if (value->IsObject()) { - return dest.pushObject(value, name); + v8::Local object(v8::Object::Cast(*value)); + return dest.pushObject(object, name); } return dest.pushNull(name); diff --git a/v8_object.cpp b/v8_object.cpp new file mode 100644 index 0000000..bc7ce65 --- /dev/null +++ b/v8_object.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include + +VALUE rb_cV8_JSObject; + +using namespace v8; + +v8_object::v8_object() : handle(Persistent(*Object::New())) { + dispose = false; +} +v8_object::v8_object(Handle& object) : handle(Persistent(*object)) { + dispose = true; +} +v8_object::~v8_object() { + if (dispose) { + handle.Dispose(); + } + +} + +VALUE v8_object_hash_access(VALUE self, VALUE key) { + v8_object* object = 0; + Data_Get_Struct(self, struct v8_object, object); + + RubyValueSource tostring; + const std::string cppkey(tostring.push(key)); + + HandleScope scope; + Handle result = object->handle->Get(String::New(cppkey.c_str())); + + V8HandleSource toValue; + return toValue.push(result); +} + +VALUE v8_object_allocate(VALUE clazz) { + v8_object *wrapper = new v8_object; + return Data_Wrap_Struct(clazz, v8_object_mark, v8_object_free, wrapper); +} + +void v8_object_mark(v8_object *o) { + +} +void v8_object_free(v8_object *o) { + delete o; +} + + diff --git a/v8_object.h b/v8_object.h new file mode 100644 index 0000000..baf9579 --- /dev/null +++ b/v8_object.h @@ -0,0 +1,27 @@ +#ifndef __RUBY_V8_OBJECT__ +#define __RUBY_V8_OBJECT__ + +#include +#include + +extern VALUE rb_cV8_JSObject; + +typedef struct v8_object { + v8_object(); + v8_object(v8::Handle& object); + ~v8_object(); + + v8::Persistent handle; + bool dispose; +} v8_object; + + +VALUE v8_object_hash_access(VALUE self, VALUE key); + +//memory management +VALUE v8_object_allocate(VALUE clazz); +void v8_object_mark(v8_object *object); +void v8_object_free(v8_object *object); + + +#endif \ No newline at end of file