1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4
5 #include <Eina_Js.hh>
6
7 namespace efl { namespace eina { namespace js {
8
9 namespace {
10
eina_value_set(compatibility_callback_info_type args)11 compatibility_return_type eina_value_set(compatibility_callback_info_type args)
12 {
13 if (args.Length() != 1)
14 return compatibility_return();
15
16 void *ptr = js::compatibility_get_pointer_internal_field(args.Holder(), 0);
17 v8::Isolate *isolate = args.GetIsolate();
18 try {
19 *static_cast<value*>(ptr) = value_cast<value>(args[0]);
20 } catch(const std::bad_cast &e) {
21 v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
22 je->Set(compatibility_new<v8::String>(isolate, "code"),
23 compatibility_new<v8::String>(isolate, "std::bad_cast"));
24 return compatibility_throw(isolate, je);
25 } catch(const ::efl::eina::system_error &e) {
26 v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
27 je->Set(compatibility_new<v8::String>(isolate, "code"),
28 compatibility_new<v8::String>(isolate, "std::error_code"));
29 je->Set(compatibility_new<v8::String>(isolate, "category"),
30 compatibility_new<v8::String>(isolate, e.code().category().name()));
31 je->Set(compatibility_new<v8::String>(isolate, "value"),
32 compatibility_new<v8::Integer>(isolate, e.code().value()));
33 return compatibility_throw(isolate, je);
34 }
35 return compatibility_return();
36 }
37
eina_value_get(compatibility_callback_info_type args)38 compatibility_return_type eina_value_get(compatibility_callback_info_type args)
39 {
40 void *ptr = compatibility_get_pointer_internal_field(args.Holder(), 0);
41 auto &value = *static_cast<eina::value*>(ptr);
42 return compatibility_return
43 (value_cast<v8::Local<v8::Value>>(value, args.GetIsolate()), args);
44 }
45
eina_value_constructor(compatibility_callback_info_type args)46 compatibility_return_type eina_value_constructor(compatibility_callback_info_type args)
47 {
48 if (args.Length() != 1)
49 return compatibility_return();
50
51 v8::Isolate* isolate = args.GetIsolate();
52
53 try {
54 std::unique_ptr<value>
55 ptr(new value(value_cast<value>(args[0])));
56 compatibility_set_pointer_internal_field(args.This(), 0, ptr.get());
57 auto v = ptr.get();
58 if (v)
59 efl::eina::js::make_weak(isolate, args.This(), [v]{ delete v; });
60 ptr.release();
61 } catch(const std::bad_cast &e) {
62 v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
63 je->Set(compatibility_new<v8::String>(isolate, "code"),
64 compatibility_new<v8::String>(isolate, "std::bad_cast"));
65 return compatibility_throw(isolate,je);
66 } catch(const ::efl::eina::system_error &e) {
67 v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
68 je->Set(compatibility_new<v8::String>(isolate, "code"),
69 compatibility_new<v8::String>(isolate, "std::error_code"));
70 je->Set(compatibility_new<v8::String>(isolate, "category"),
71 compatibility_new<v8::String>(isolate, e.code().category().name()));
72 je->Set(compatibility_new<v8::String>(isolate, "value"),
73 compatibility_new<v8::Integer>(isolate, e.code().value()));
74 return compatibility_throw(isolate, je);
75 }
76 // makeweak
77 // {
78 // typedef global_ref<v8::Object> persistent_t;
79 // typedef v8::WeakCallbackData<v8::Object, persistent_t> cb_type;
80
81 // auto on_gc = [](const cb_type &data) {
82 // typedef ::efl::eina::value value_type;
83 // typedef value_type *ptr_type;
84
85 // auto o = data.GetValue();
86 // delete static_cast<ptr_type>
87 // (compatibility_get_pointer_internal_field(o, 0));
88 // compatibility_set_pointer_internal_field<void*>(o, 0, nullptr);
89
90 // delete data.GetParameter();
91 // };
92
93 // auto persistent = new persistent_t(isolate, args.This());
94 // persistent->SetWeak<v8::Object>(persistent, on_gc);
95 // }
96 }
97
98 }
99
100 EAPI
register_value(v8::Isolate * isolate,v8::Handle<v8::Object> global,v8::Handle<v8::String> name)101 void register_value(v8::Isolate *isolate, v8::Handle<v8::Object> global,
102 v8::Handle<v8::String> name)
103 {
104 using v8::Isolate;
105 using v8::Local;
106 using v8::Value;
107 using v8::Integer;
108 using v8::String;
109 using v8::Object;
110 using v8::FunctionTemplate;
111 using v8::FunctionCallbackInfo;
112
113 v8::Local<v8::FunctionTemplate> constructor = compatibility_new<v8::FunctionTemplate>(isolate, &eina_value_constructor);
114
115 v8::Local<v8::ObjectTemplate> instance = constructor->InstanceTemplate();
116 instance->SetInternalFieldCount(1);
117
118 auto prototype = constructor->PrototypeTemplate();
119
120 prototype->Set(compatibility_new<v8::String>(isolate, "set")
121 , compatibility_new<FunctionTemplate>(isolate, &eina_value_set));
122 prototype->Set(compatibility_new<v8::String>(isolate, "get")
123 , compatibility_new<FunctionTemplate>(isolate, &eina_value_get));
124
125 global->Set(name, constructor->GetFunction());
126 }
127
128 } } } // namespace efl { namespace js {
129
130 EAPI
eina_value_register(v8::Handle<v8::Object> global,v8::Isolate * isolate)131 void eina_value_register(v8::Handle<v8::Object> global, v8::Isolate* isolate)
132 {
133 efl::eina::js::register_value(isolate, global
134 , efl::eina::js::compatibility_new<v8::String>(isolate, "value"));
135 }
136