diff options
author | Felipe Magno de Almeida <felipe@expertisesolutions.com.br> | 2015-01-13 20:23:42 -0200 |
---|---|---|
committer | Felipe Magno de Almeida <felipe@expertisesolutions.com.br> | 2015-01-13 20:23:42 -0200 |
commit | 5f77d8639a6d8d68c0fb332e758bbcc0936964bb (patch) | |
tree | 8fb40a46c031e8ec3cdcb39911377148e2c60317 | |
parent | d59ec443365af7f296c9fdcc93f5f7c33f65c320 (diff) | |
download | efl-5f77d8639a6d8d68c0fb332e758bbcc0936964bb.tar.gz |
eina-js: Fixes to iterator and value tests compatibilizataion
-rw-r--r-- | src/bindings/eina_js/eina_js_iterator.hh | 91 | ||||
-rw-r--r-- | src/bindings/eina_js/eina_js_value.cc | 258 | ||||
-rw-r--r-- | src/tests/eina_js/eina_js_suite.cc | 21 | ||||
-rwxr-xr-x | src/tests/eina_js/eina_js_suite.js | 76 |
4 files changed, 267 insertions, 179 deletions
diff --git a/src/bindings/eina_js/eina_js_iterator.hh b/src/bindings/eina_js/eina_js_iterator.hh index cd19729c4e..f9dc2a8171 100644 --- a/src/bindings/eina_js/eina_js_iterator.hh +++ b/src/bindings/eina_js/eina_js_iterator.hh @@ -23,52 +23,51 @@ namespace efl { namespace eina { namespace js { template<class T> v8::Local<v8::Object> export_iterator(::efl::eina::iterator<T> *i, v8::Isolate *isolate) - ; -// { -// using v8::Local; -// using v8::Value; -// using v8::Object; -// using v8::String; -// using v8::FunctionCallbackInfo; -// using v8::FunctionTemplate; -// using v8::ObjectTemplate; - -// typedef ::efl::eina::iterator<T> value_type; -// typedef value_type *ptr_type; -// typedef void (*deleter_t)(void*); - -// auto obj_tpl = ObjectTemplate::New(isolate); -// obj_tpl->SetInternalFieldCount(2); - -// auto ret = obj_tpl->NewInstance(); - -// auto next = [](const FunctionCallbackInfo<Value> &info) { -// if (info.Length() != 0) -// return; - -// void *ptr = info.This()->GetAlignedPointerFromInternalField(0); -// auto &value = *static_cast<ptr_type>(ptr); -// Local<Object> o = v8::Object::New(info.GetIsolate()); -// o->Set(String::NewFromUtf8(info.GetIsolate(), "value"), -// value_cast<Local<Value>>(*value, info.GetIsolate())); -// info.GetReturnValue().Set(o); -// ++value; -// }; - -// ret->Set(String::NewFromUtf8(isolate, "next"), -// FunctionTemplate::New(isolate, next)->GetFunction()); - -// { -// deleter_t deleter = [](void *i) { -// delete static_cast<ptr_type>(i); -// }; -// ret->SetAlignedPointerInInternalField(0, i); -// ret->SetAlignedPointerInInternalField(1, -// reinterpret_cast<void*>(deleter)); -// } - -// return ret; -// } +{ + using v8::Local; + using v8::Value; + using v8::Object; + using v8::String; + using v8::FunctionCallbackInfo; + using v8::FunctionTemplate; + using v8::ObjectTemplate; + + typedef ::efl::eina::iterator<T> value_type; + typedef value_type *ptr_type; + typedef void (*deleter_t)(void*); + + auto obj_tpl = ObjectTemplate::New(isolate); + obj_tpl->SetInternalFieldCount(2); + + auto ret = obj_tpl->NewInstance(); + + auto next = [](const FunctionCallbackInfo<Value> &info) { + if (info.Length() != 0) + return; + + void *ptr = info.This()->GetAlignedPointerFromInternalField(0); + auto &value = *static_cast<ptr_type>(ptr); + Local<Object> o = v8::Object::New(info.GetIsolate()); + o->Set(String::NewFromUtf8(info.GetIsolate(), "value"), + value_cast<Local<Value>>(*value, info.GetIsolate())); + info.GetReturnValue().Set(o); + ++value; + }; + + ret->Set(String::NewFromUtf8(isolate, "next"), + FunctionTemplate::New(isolate, next)->GetFunction()); + + { + deleter_t deleter = [](void *i) { + delete static_cast<ptr_type>(i); + }; + ret->SetAlignedPointerInInternalField(0, i); + ret->SetAlignedPointerInInternalField(1, + reinterpret_cast<void*>(deleter)); + } + + return ret; +} /* Extracts and returns a copy from the internal iterator object from the JS object. */ diff --git a/src/bindings/eina_js/eina_js_value.cc b/src/bindings/eina_js/eina_js_value.cc index 2877d8a3ce..04c91258e4 100644 --- a/src/bindings/eina_js/eina_js_value.cc +++ b/src/bindings/eina_js/eina_js_value.cc @@ -1,132 +1,136 @@ -// #ifdef HAVE_CONFIG_H -// #include <config.h> -// #endif - -// #include <eina_js_value.hh> -// #include <eina_js_compatibility.hh> - -// namespace efl { namespace eina { namespace js { - -// namespace { - -// compatibility_return_type eina_value_set(compatibility_callback_info_type args) -// { -// if (args.Length() != 1) -// return compatibility_return(); - -// void *ptr = args.Holder()->GetAlignedPointerFromInternalField(0); -// v8::Isolate *isolate = args.GetIsolate(); -// try { -// *static_cast<ptr_type>(ptr) = value_cast<value_type>(info[0]); -// } catch(const std::bad_cast &e) { -// Local<Object> je = Object::New(isolate); -// je->Set(String::NewFromUtf8(isolate, "code"), -// String::NewFromUtf8(isolate, "std::bad_cast")); -// isolate->ThrowException(je); -// } catch(const ::efl::eina::system_error &e) { -// Local<Object> je = Object::New(isolate); -// je->Set(String::NewFromUtf8(isolate, "code"), -// String::NewFromUtf8(isolate, "std::error_code")); -// je->Set(String::NewFromUtf8(isolate, "category"), -// String::NewFromUtf8(isolate, e.code().category().name())); -// je->Set(String::NewFromUtf8(isolate, "value"), -// Integer::New(isolate, e.code().value())); -// isolate->ThrowException(je); -// } -// } - -// compatibility_return_type eina_value_get(compatibility_callback_info_type args) -// { -// void *ptr = info.Holder()->GetAlignedPointerFromInternalField(0); -// auto &value = *static_cast<ptr_type>(ptr); -// info.GetReturnValue().Set(value_cast<Local<Value>> -// (value, info.GetIsolate())); -// } - -// compatibility_return_type eina_value_constructor(compatibility_callback_info_type args) -// { -// if (info.Length() != 1) -// return; - -// try { -// std::unique_ptr<value_type> -// ptr(new value_type(value_cast<value_type>(info[0]))); -// ret->SetAlignedPointerInInternalField(0, ptr.get()); -// ptr.release(); -// } catch(const std::bad_cast &e) { -// Local<Object> je = Object::New(isolate); -// je->Set(String::NewFromUtf8(isolate, "code"), -// String::NewFromUtf8(isolate, "std::bad_cast")); -// isolate->ThrowException(je); -// } catch(const ::efl::eina::system_error &e) { -// Local<Object> je = Object::New(isolate); -// je->Set(String::NewFromUtf8(isolate, "code"), -// String::NewFromUtf8(isolate, "std::error_code")); -// je->Set(String::NewFromUtf8(isolate, "category"), -// String::NewFromUtf8(isolate, e.code().category().name())); -// je->Set(String::NewFromUtf8(isolate, "value"), -// Integer::New(isolate, e.code().value())); -// isolate->ThrowException(je); -// } -// } - -// } +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <eina_js_value.hh> +#include <eina_js_compatibility.hh> + +namespace efl { namespace eina { namespace js { + +namespace { + +compatibility_return_type eina_value_set(compatibility_callback_info_type args) +{ + if (args.Length() != 1) + return compatibility_return(); + + void *ptr = js::compatibility_get_pointer_internal_field(args.Holder(), 0); + v8::Isolate *isolate = args.GetIsolate(); + try { + *static_cast<value*>(ptr) = value_cast<value>(args[0]); + } catch(const std::bad_cast &e) { + v8::Local<v8::Object> je = v8::Object::New(isolate); + je->Set(v8::String::NewFromUtf8(isolate, "code"), + v8::String::NewFromUtf8(isolate, "std::bad_cast")); + isolate->ThrowException(je); + } catch(const ::efl::eina::system_error &e) { + v8::Local<v8::Object> je = v8::Object::New(isolate); + je->Set(v8::String::NewFromUtf8(isolate, "code"), + v8::String::NewFromUtf8(isolate, "std::error_code")); + je->Set(v8::String::NewFromUtf8(isolate, "category"), + v8::String::NewFromUtf8(isolate, e.code().category().name())); + je->Set(v8::String::NewFromUtf8(isolate, "value"), + v8::Integer::New(isolate, e.code().value())); + isolate->ThrowException(je); + } + return compatibility_return(); +} + +compatibility_return_type eina_value_get(compatibility_callback_info_type args) +{ + void *ptr = args.Holder()->GetAlignedPointerFromInternalField(0); + auto &value = *static_cast<eina::value*>(ptr); + args.GetReturnValue().Set(value_cast<v8::Local<v8::Value>> + (value, args.GetIsolate())); +} + +compatibility_return_type eina_value_constructor(compatibility_callback_info_type args) +{ + if (args.Length() != 1) + return; + + v8::Isolate* isolate = args.GetIsolate(); + + try { + std::unique_ptr<value> + ptr(new value(value_cast<value>(args[0]))); + args.This()->SetAlignedPointerInInternalField(0, ptr.get()); + ptr.release(); + } catch(const std::bad_cast &e) { + v8::Local<v8::Object> je = v8::Object::New(isolate); + je->Set(v8::String::NewFromUtf8(isolate, "code"), + v8::String::NewFromUtf8(isolate, "std::bad_cast")); + isolate->ThrowException(je); + } catch(const ::efl::eina::system_error &e) { + v8::Local<v8::Object> je = v8::Object::New(isolate); + je->Set(v8::String::NewFromUtf8(isolate, "code"), + v8::String::NewFromUtf8(isolate, "std::error_code")); + je->Set(v8::String::NewFromUtf8(isolate, "category"), + v8::String::NewFromUtf8(isolate, e.code().category().name())); + je->Set(v8::String::NewFromUtf8(isolate, "value"), + v8::Integer::New(isolate, e.code().value())); + isolate->ThrowException(je); + } +} + +} -// EAPI -// void register_make_value(v8::Isolate *isolate, v8::Handle<v8::Object> global, -// v8::Handle<v8::String> name) -// { -// using v8::Isolate; -// using v8::Local; -// using v8::Value; -// using v8::Integer; -// using v8::String; -// using v8::Object; -// using v8::FunctionTemplate; -// using v8::FunctionCallbackInfo; - -// typedef ::efl::eina::value value_type; -// typedef value_type *ptr_type; - -// v8::FunctionTemplate constructor -// = compatibility_new<FunctionTemplate>(isolate, &eina_value_constructor); +EAPI +void register_make_value(v8::Isolate *isolate, v8::Handle<v8::Object> global, + v8::Handle<v8::String> name) +{ + using v8::Isolate; + using v8::Local; + using v8::Value; + using v8::Integer; + using v8::String; + using v8::Object; + using v8::FunctionTemplate; + using v8::FunctionCallbackInfo; + + typedef ::efl::eina::value value_type; + typedef value_type *ptr_type; + + static compatibility_persistent<v8::FunctionTemplate> constructor + {isolate, compatibility_new<v8::FunctionTemplate>(isolate, &eina_value_constructor)}; -// auto instance = constructor->InstanceTemplate(); -// instance_template->SetInternalFieldCount(1); + static compatibility_persistent<v8::ObjectTemplate> + instance = {isolate, constructor.handle()->InstanceTemplate()}; + instance.handle()->SetInternalFieldCount(1); -// auto prototype = constructor->PrototypeTemplate(); + auto prototype = constructor.handle()->PrototypeTemplate(); -// prototype->Set(compatibility_new<v8::String>(isolate, "set") -// , compatibility_new<FunctionTemplate>(isolate, &eina_value_set)); -// prototype->Set(compatibility_new<v8::String>(isolate, "get") -// , compatibility_new<FunctionTemplate>(isolate, &eina_value_get)); + prototype->Set(compatibility_new<v8::String>(isolate, "set") + , compatibility_new<FunctionTemplate>(isolate, &eina_value_set)); + prototype->Set(compatibility_new<v8::String>(isolate, "get") + , compatibility_new<FunctionTemplate>(isolate, &eina_value_get)); -// global->Set(name, constructor->GetFunction()); -// } - -// EAPI -// void register_destroy_value(v8::Isolate *isolate, v8::Handle<v8::Object> global, -// v8::Handle<v8::String> name) -// { -// using v8::Local; -// using v8::Value; -// using v8::FunctionTemplate; -// using v8::FunctionCallbackInfo; - -// typedef ::efl::eina::value value_type; -// typedef value_type *ptr_type; - -// auto dtor = [](const FunctionCallbackInfo<Value> &info) { -// if (info.Length() != 1) -// return; - -// auto o = info[0]->ToObject(); -// delete static_cast<ptr_type>(o->GetAlignedPointerFromInternalField(0)); -// o->SetAlignedPointerInInternalField(0, nullptr); -// assert(o->GetAlignedPointerFromInternalField(0) == nullptr); -// }; - -// global->Set(name, FunctionTemplate::New(isolate, dtor)->GetFunction()); -// } - -// } } } // namespace efl { namespace js { + global->Set(name, constructor.handle()->GetFunction()); +} + +EAPI +void register_destroy_value(v8::Isolate *isolate, v8::Handle<v8::Object> global, + v8::Handle<v8::String> name) +{ + using v8::Local; + using v8::Value; + using v8::FunctionTemplate; + using v8::FunctionCallbackInfo; + + typedef ::efl::eina::value value_type; + typedef value_type *ptr_type; + + auto dtor = [](const FunctionCallbackInfo<Value> &info) { + if (info.Length() != 1) + return; + + auto o = info[0]->ToObject(); + delete static_cast<ptr_type>(o->GetAlignedPointerFromInternalField(0)); + o->SetAlignedPointerInInternalField(0, nullptr); + assert(o->GetAlignedPointerFromInternalField(0) == nullptr); + }; + + global->Set(name, FunctionTemplate::New(isolate, dtor)->GetFunction()); +} + +} } } // namespace efl { namespace js { diff --git a/src/tests/eina_js/eina_js_suite.cc b/src/tests/eina_js/eina_js_suite.cc index a83fd97440..d8ffd81663 100644 --- a/src/tests/eina_js/eina_js_suite.cc +++ b/src/tests/eina_js/eina_js_suite.cc @@ -15,6 +15,7 @@ #include <eina_js_accessor.hh> #include <eina_js_list.hh> +#include <eina_js_iterator.hh> #include <eina_js_error.hh> const char* ToCString(const v8::String::Utf8Value& value) { @@ -140,21 +141,29 @@ void test_setup(v8::Handle<v8::Object> exports) std::cerr << __LINE__ << std::endl; // accessor - Eina_Array* array = eina_array_new(2); + Eina_Array* array = eina_array_new(3); eina_array_push(array, new int(42)); eina_array_push(array, new int(24)); + eina_array_push(array, new int(0)); static efl::eina::accessor<int> acc(eina_array_accessor_new(array)); std::cerr << __LINE__ << std::endl; - // efl::eina::js::register_destroy_accessor - // (isolate, exports - // , efl::eina::js::compatibility_new<v8::String>(isolate, "destroy_accessor")); - std::cerr << __LINE__ << std::endl; - v8::Local<v8::Object> wrapped_acc = efl::eina::js::export_accessor( acc, isolate); exports->Set(efl::eina::js::compatibility_new<v8::String>(isolate, "acc"), wrapped_acc); + static efl::eina::iterator<int> it(eina_array_iterator_new(array)); + + v8::Local<v8::Object> wrapped_it = efl::eina::js::export_iterator(&it, isolate); + + exports->Set(efl::eina::js::compatibility_new<v8::String>(isolate, "it"), wrapped_it); + + std::cerr << __LINE__ << std::endl; + + efl::eina::js::register_make_value + (isolate, exports + , efl::eina::js::compatibility_new<v8::String>(isolate, "make_value")); + std::cerr << __LINE__ << std::endl; } diff --git a/src/tests/eina_js/eina_js_suite.js b/src/tests/eina_js/eina_js_suite.js index cb57b1a197..a66d58b4f9 100755 --- a/src/tests/eina_js/eina_js_suite.js +++ b/src/tests/eina_js/eina_js_suite.js @@ -86,6 +86,82 @@ assert(captured === true, 'error #4'); assert(suite.acc.get(0) === 42, 'accessor #1'); assert(suite.acc.get(1) === 24, 'accessor #2'); +// iterator tests + +assert(suite.it.next().value === 42, 'iterator #1'); +assert(suite.it.next().value === 24, 'iterator #2'); + +// value tests + +console.log("x"); + +var my_value = new suite.make_value(1); +console.log("x"); +var wrapped = my_value.get(); +console.log("x"); +assert(typeof(wrapped) === 'number', 'value #1'); +console.log("x"); +assert(wrapped === 1, 'value #2'); +console.log("x"); + +my_value.set(2); +console.log("x"); +assert(wrapped === 1, 'value #3'); +console.log("x"); +wrapped = my_value.get(); +console.log("x"); +assert(typeof(wrapped) === 'number', 'value #4'); +console.log("x"); +assert(wrapped === 2, 'value #5'); +console.log("x"); + +my_value.set(true); +console.log("x"); +assert(wrapped === 2, 'value #6'); +console.log("x"); +wrapped = my_value.get(); +console.log("x"); +// boolean is represented as integer in the efl::eina::value layer +console.log("x"); +assert(typeof(wrapped) === 'number', 'value #7'); +console.log("x"); +assert(wrapped === 1, 'value #8'); +console.log("x"); + +console.log("x"); +var captured = false; +console.log("x"); +try { +console.log("x"); + my_value.set({type: 'complex object'}); +console.log("x"); +} catch(e) { +console.log("x"); + assert(e.code === 'std::bad_cast', 'value #9'); +console.log("x"); + captured = true; +console.log("x"); +} +console.log("x"); +assert(captured === true, 'value #10'); +console.log("x"); + +console.log("x"); +captured = false; +console.log("x"); +try { +console.log("x"); + my_value = make_value({type: 'complex object'}); +console.log("x"); +} catch(e) { + console.log("e.code ", e.code, ' ', typeof e); + assert(e.code === 'std::bad_cast', 'value #11'); +console.log("x"); + captured = true; +console.log("x"); +} +assert(captured === true, 'value #12'); + // finished tests console.log ("Test execution with success"); |