diff --git a/Manifest.txt b/Manifest.txt index 98a6a08..216b705 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -10,6 +10,7 @@ ext/v8/convert_string.cpp ext/v8/convert_string.h ext/v8/convert_v8.cpp ext/v8/convert_v8.h +ext/v8/converters.cpp ext/v8/converters.h ext/v8/extconf.rb ext/v8/v8.cpp diff --git a/ext/v8/convert_ruby.h b/ext/v8/convert_ruby.h index 2131e37..0c66a07 100644 --- a/ext/v8/convert_ruby.h +++ b/ext/v8/convert_ruby.h @@ -2,9 +2,6 @@ #define __convert_ruby_h__ #include -#include -#include "v8_ref.h" -#include "v8_obj.h" #include /** @@ -44,16 +41,6 @@ template class RubyValueSource { return dest.pushBool(true); case T_FALSE: return dest.pushBool(false); - case T_DATA: -/* - VALUE clsProc = rb_eval_string("::Proc"); - VALUE clsMethod = rb_eval_string("::Method"); - VALUE smartMatch = rb_intern("==="); - if (RTEST(rb_funcall(clsProc, smartMatch, value)) || RTEST(rb_funcall(clsMethod, smartMatch, value))) { - - } -*/ - break; } return dest.pushUndefined(); } @@ -99,10 +86,6 @@ class RubyValueDest { VALUE pushUndefined() { return Qnil; } - - VALUE pushObject(v8::Handle& value) { - return V8_Ref_Create(V8_C_Object, value); - } }; diff --git a/ext/v8/convert_v8.h b/ext/v8/convert_v8.h index 88c7aaf..a13a238 100644 --- a/ext/v8/convert_v8.h +++ b/ext/v8/convert_v8.h @@ -15,57 +15,69 @@ template class V8HandleSource { V8HandleSource() {} ~V8HandleSource() {} - R operator() (v8::Handle& value) { + bool operator() (v8::Handle& value, R& result) { + + // a bit klunky, but alternative is to evaluate what type the + // object is twice, which is unappealing if (value.IsEmpty()) { - return dest.pushNull(); + result = dest.pushNull(); + return true; } if (value->IsUndefined()) { - return dest.pushNull(); + result = dest.pushNull(); + return true; } if(value->IsNull()) { - return dest.pushNull(); + result = dest.pushNull(); + return true; } if(value->IsTrue()) { - return dest.pushBool(true); + result = dest.pushBool(true); + return true; } if(value->IsFalse()) { - return dest.pushBool(false); + result = dest.pushBool(false); + return true; } if(value->IsString()) { v8::Local str = value->ToString(); - char buffer[1024]; - int strlen = str->Length(); - std::string output(strlen, 0); - for (int total = 0; total < strlen;) { - int written = str->WriteAscii(buffer, total, 1024); - output.replace(total, written, buffer); - total += written; - } - return dest.pushString(output); + result = convertString(str); + return true; } if(value->IsInt32()) { - return dest.pushInt(value->Int32Value()); + result = dest.pushInt(value->Int32Value()); + return true; } if(value->IsNumber()) { - return dest.pushDouble(value->NumberValue()); + result = dest.pushDouble(value->NumberValue()); + return true; } - if (value->IsObject()) { - v8::Local object(v8::Object::Cast(*value)); - return dest.pushObject(object); - } - - return dest.pushNull(); + result = dest.pushNull(); + return false; } + R convertString(v8::Local& str) { + char buffer[1024]; + int strlen = str->Length(); + std::string output(strlen, 0); + for (int total = 0; total < strlen;) { + int written = str->WriteAscii(buffer, total, 1024); + output.replace(total, written, buffer); + total += written; + } + return dest.pushString(output); + } + + }; /** @@ -103,10 +115,6 @@ public: v8::Local pushUndefined() { return v8::Local::New(v8::Undefined()); } - - // v8:Local pushFunction(Function) { - // - // } }; diff --git a/ext/v8/converters.cpp b/ext/v8/converters.cpp index ff311b3..e157445 100644 --- a/ext/v8/converters.cpp +++ b/ext/v8/converters.cpp @@ -1,4 +1,51 @@ #include "converters.h" -convert_v8_to_rb_t V82RB; -convert_rb_to_v8_t RB2V8; +#include "v8_ref.h" +#include "v8_obj.h" + +namespace { + std::string UNDEFINED_STR("undefined"); +} + +VALUE V82RB(v8::Handle& value) { + convert_v8_to_rb_t convert; + VALUE result; + if(convert(value, result)) { + return result; + } + + if (value->IsObject()) { + v8::Local object(v8::Object::Cast(*value)); + return V8_Ref_Create(V8_C_Object, value); + } + + return Qnil; +} + +v8::Local RB2V8(VALUE value) { + convert_rb_to_v8_t convert; + return convert(value); +} + +std::string RB2String(VALUE value) { + convert_rb_to_string_t convert; + return convert(value); +} + +std::string V82String(v8::Handle& value) { + convert_v8_to_string_t convert; + std::string result; + if(convert(value, result)) { + return result; + } + + if (value->IsObject()) { + v8::Local object(v8::Object::Cast(*value)); + v8::Local str = object->ToString(); + if(convert(value, result)) { + return result; + } + } + + return UNDEFINED_STR; +} \ No newline at end of file diff --git a/ext/v8/converters.h b/ext/v8/converters.h index 160a6df..c0f79cb 100644 --- a/ext/v8/converters.h +++ b/ext/v8/converters.h @@ -4,6 +4,7 @@ #include "convert_ruby.h" #include "convert_string.h" #include "convert_v8.h" +#include typedef RubyValueSource > convert_rb_to_v8_t; typedef V8HandleSource convert_v8_to_rb_t; @@ -11,7 +12,10 @@ typedef V8HandleSource convert_v8_to_rb_t; typedef RubyValueSource convert_rb_to_string_t; typedef V8HandleSource convert_v8_to_string_t; -extern convert_v8_to_rb_t V82RB; -extern convert_rb_to_v8_t RB2V8; +VALUE V82RB(v8::Handle& value); +v8::Local RB2V8(VALUE value); + +std::string RB2String(VALUE value); +std::string V82String(v8::Handle& value); #endif \ No newline at end of file diff --git a/ext/v8/v8_cxt.cpp b/ext/v8/v8_cxt.cpp index e9cdb8f..694743e 100644 --- a/ext/v8/v8_cxt.cpp +++ b/ext/v8/v8_cxt.cpp @@ -18,10 +18,9 @@ VALUE v8_Context_New(int argc, VALUE *argv, VALUE self) { VALUE v8_cxt_Global(VALUE self) { HandleScope handles; - convert_v8_to_rb_t v82rb; Local cxt = V8_Ref_Get(self); Local global = *cxt->Global(); - return v82rb(global); + return V82RB(global); } VALUE v8_cxt_open(VALUE self) { diff --git a/ext/v8/v8_obj.cpp b/ext/v8/v8_obj.cpp index 5f0c8fa..3cb0079 100644 --- a/ext/v8/v8_obj.cpp +++ b/ext/v8/v8_obj.cpp @@ -28,10 +28,10 @@ VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value) { VALUE valueClass = rb_class_of(value); if(valueClass == rb_cProc) { - printf("** This is a proc! We should do something different.\n"); + //printf("** This is a proc! We should do something different.\n"); } else if(valueClass == rb_cMethod) { - printf("** This is a method! We should do something different.\n"); + //printf("** This is a method! We should do something different.\n"); } obj->Set(RB2V8(keystr), RB2V8(value)); diff --git a/ext/v8/v8_script.cpp b/ext/v8/v8_script.cpp index 1d6a58f..1a89508 100644 --- a/ext/v8/v8_script.cpp +++ b/ext/v8/v8_script.cpp @@ -15,7 +15,6 @@ VALUE v8_script_new(VALUE self, VALUE source) { VALUE v8_script_Run(VALUE self) { HandleScope handles; Local