From 1218198afad531ee19533e2c23ec5da7d9226b9a Mon Sep 17 00:00:00 2001 From: Sam Saffron Date: Thu, 12 May 2016 09:38:47 +1000 Subject: [PATCH] - Add support for objects - Correct warnings on mac --- .../mini_racer_extension.cc | 27 ++++++++++++++++--- test/mini_racer_test.rb | 6 +++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ext/mini_racer_extension/mini_racer_extension.cc b/ext/mini_racer_extension/mini_racer_extension.cc index 83085d9..bf8e905 100644 --- a/ext/mini_racer_extension/mini_racer_extension.cc +++ b/ext/mini_racer_extension/mini_racer_extension.cc @@ -151,7 +151,7 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Handle &value) { if (value->IsArray()) { VALUE rb_array = rb_ary_new(); Local arr = Local::Cast(value); - for(int i=0; iLength(); i++) { + for(uint32_t i=0; i < arr->Length(); i++) { Local element = arr->Get(i); VALUE rb_elem = convert_v8_to_ruby(isolate, element); rb_ary_push(rb_array, rb_elem); @@ -159,6 +159,24 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Handle &value) { return rb_array; } + if (value->IsObject()) { + VALUE rb_hash = rb_hash_new(); + Local context = Context::New(isolate); + Local object = value->ToObject(); + MaybeLocal maybe_props = object->GetOwnPropertyNames(context); + if (!maybe_props.IsEmpty()) { + Local props = maybe_props.ToLocalChecked(); + for(uint32_t i=0; i < props->Length(); i++) { + Local key = props->Get(i); + VALUE rb_key = convert_v8_to_ruby(isolate, key); + Local value = object->Get(key); + VALUE rb_value = convert_v8_to_ruby(isolate, value); + rb_hash_aset(rb_hash, rb_key, rb_value); + } + } + return rb_hash; + } + Local rstr = value->ToString(); return rb_enc_str_new(*v8::String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8")); } @@ -273,7 +291,8 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) { rb_raise(rb_eJavaScriptError, "Unknown JavaScript Error during execution"); } } else { - rb_raise(CLASS_OF(ruby_exception), RSTRING_PTR(rb_funcall(ruby_exception, rb_intern("to_s"), 0))); + VALUE rb_str = rb_funcall(ruby_exception, rb_intern("to_s"), 0); + rb_raise(CLASS_OF(ruby_exception), RSTRING_PTR(rb_str)); } } @@ -356,8 +375,8 @@ gvl_ruby_callback(void* data) { callback_data.args = ruby_args; callback_data.failed = false; - result = rb_rescue(protected_callback, (VALUE)(&callback_data), - rescue_callback, (VALUE)(&callback_data)); + result = rb_rescue((VALUE(*)(...))&protected_callback, (VALUE)(&callback_data), + (VALUE(*)(...))&rescue_callback, (VALUE)(&callback_data)); if(callback_data.failed) { VALUE parent = rb_iv_get(self, "@parent"); diff --git a/test/mini_racer_test.rb b/test/mini_racer_test.rb index e8f44bc..41bbc58 100644 --- a/test/mini_racer_test.rb +++ b/test/mini_racer_test.rb @@ -22,6 +22,12 @@ class MiniRacerTest < Minitest::Test assert_equal [1,"two"], context.eval('[1,"two"]') end + def test_object + context = MiniRacer::Context.new + # remember JavaScript is quirky {"1" : 1} magically turns to {1: 1} cause magic + assert_equal({1 => 2, "two" => "two"}, context.eval('a={"1" : 2, "two" : "two"}')) + end + def test_it_returns_runtime_error context = MiniRacer::Context.new exp = nil