#ifdef HAVE_CONFIG_H #include #endif #include 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(ptr) = value_cast(args[0]); } catch(const std::bad_cast &e) { v8::Local je = compatibility_new(isolate); je->Set(compatibility_new(isolate, "code"), compatibility_new(isolate, "std::bad_cast")); return compatibility_throw(isolate, je); } catch(const ::efl::eina::system_error &e) { v8::Local je = compatibility_new(isolate); je->Set(compatibility_new(isolate, "code"), compatibility_new(isolate, "std::error_code")); je->Set(compatibility_new(isolate, "category"), compatibility_new(isolate, e.code().category().name())); je->Set(compatibility_new(isolate, "value"), compatibility_new(isolate, e.code().value())); return compatibility_throw(isolate, je); } return compatibility_return(); } compatibility_return_type eina_value_get(compatibility_callback_info_type args) { void *ptr = compatibility_get_pointer_internal_field(args.Holder(), 0); auto &value = *static_cast(ptr); return compatibility_return (value_cast>(value, args.GetIsolate()), args); } compatibility_return_type eina_value_constructor(compatibility_callback_info_type args) { if (args.Length() != 1) return compatibility_return(); v8::Isolate* isolate = args.GetIsolate(); try { std::unique_ptr ptr(new value(value_cast(args[0]))); compatibility_set_pointer_internal_field(args.This(), 0, ptr.get()); auto v = ptr.get(); if (v) efl::eina::js::make_weak(isolate, args.This(), [v]{ delete v; }); ptr.release(); } catch(const std::bad_cast &e) { v8::Local je = compatibility_new(isolate); je->Set(compatibility_new(isolate, "code"), compatibility_new(isolate, "std::bad_cast")); return compatibility_throw(isolate,je); } catch(const ::efl::eina::system_error &e) { v8::Local je = compatibility_new(isolate); je->Set(compatibility_new(isolate, "code"), compatibility_new(isolate, "std::error_code")); je->Set(compatibility_new(isolate, "category"), compatibility_new(isolate, e.code().category().name())); je->Set(compatibility_new(isolate, "value"), compatibility_new(isolate, e.code().value())); return compatibility_throw(isolate, je); } // makeweak // { // typedef global_ref persistent_t; // typedef v8::WeakCallbackData cb_type; // auto on_gc = [](const cb_type &data) { // typedef ::efl::eina::value value_type; // typedef value_type *ptr_type; // auto o = data.GetValue(); // delete static_cast // (compatibility_get_pointer_internal_field(o, 0)); // compatibility_set_pointer_internal_field(o, 0, nullptr); // delete data.GetParameter(); // }; // auto persistent = new persistent_t(isolate, args.This()); // persistent->SetWeak(persistent, on_gc); // } } } EAPI void register_value(v8::Isolate *isolate, v8::Handle global, v8::Handle 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; v8::Local constructor = compatibility_new(isolate, &eina_value_constructor); v8::Local instance = constructor->InstanceTemplate(); instance->SetInternalFieldCount(1); auto prototype = constructor->PrototypeTemplate(); prototype->Set(compatibility_new(isolate, "set") , compatibility_new(isolate, &eina_value_set)); prototype->Set(compatibility_new(isolate, "get") , compatibility_new(isolate, &eina_value_get)); global->Set(name, constructor->GetFunction()); } } } } // namespace efl { namespace js { EAPI void eina_value_register(v8::Handle global, v8::Isolate* isolate) { efl::eina::js::register_value(isolate, global , efl::eina::js::compatibility_new(isolate, "value")); }