Added header for compatibilization to v8 versions

This commit is contained in:
Felipe Magno de Almeida 2014-12-11 19:56:17 -02:00
parent ae3da5f067
commit 173db82492
5 changed files with 277 additions and 73 deletions

View File

@ -11,6 +11,7 @@ bindings/eo_js/eo_js_get_value_from_c.hh \
bindings/eo_js/eo_js_get_value.hh \
bindings/eo_js/eo_js_event.hh \
bindings/eo_js/eo_js_construct_from_eo.hh \
bindings/eo_js/eo_js_compatibility.hh \
bindings/eo_js/Eo_Js.hh
### Unit tests

View File

@ -1,6 +1,7 @@
#ifndef EFL_EO_JS_HH
#define EFL_EO_JS_HH
#include <eo_js_compatibility.hh>
#include <eo_js_direction.hh>
#include <eo_js_constructor.hh>
#include <eo_js_call_function.hh>

View File

@ -19,24 +19,14 @@
namespace efl { namespace eo { namespace js {
#if 0
inline void call_function(v8::FunctionCallbackInfo<v8::Value> const& args)
{
void* data = v8::External::Cast(*args.Data())->Value();
std::function<void(v8::FunctionCallbackInfo<v8::Value>const&)>*
f = static_cast<std::function<void(v8::FunctionCallbackInfo<v8::Value>const&)>*>(data);
(*f)(args);
}
#else
inline v8::Handle<v8::Value> call_function(v8::Arguments const& args)
inline compatibility_return_type call_function(compatibility_callback_info_type args)
{
std::cerr << "call_function" << std::endl;
void* data = v8::External::Cast(*args.Data())->Value();
std::function<v8::Handle<v8::Value>(v8::Arguments const&)>*
f = static_cast<std::function<v8::Handle<v8::Value>(v8::Arguments const&)>*>(data);
std::function<compatibility_return_type(compatibility_callback_info_type)>*
f = static_cast<std::function<compatibility_return_type(compatibility_callback_info_type)>*>(data);
return (*f)(args);
}
#endif
template <typename In, typename Out, typename Ownership, typename F>
struct method_caller
@ -167,7 +157,7 @@ struct method_caller
template <typename U, std::size_t I, typename Outs>
static
typename std::tuple_element<I, parameters_t>::type
get_value(v8::Arguments const& args, Outs& /*outs*/, v8::Isolate* isolate
get_value(compatibility_callback_info_type args, Outs& /*outs*/, v8::Isolate* isolate
, std::false_type)
{
std::cout << "is NOT out" << std::endl;
@ -182,7 +172,7 @@ struct method_caller
typename std::tuple_element
<eina::_mpl::tuple_find<std::integral_constant<std::size_t, I>, Out>::value
, Outs>::type>::type
get_value(v8::Arguments const&, Outs& outs, v8::Isolate*
get_value(compatibility_callback_info_type, Outs& outs, v8::Isolate*
, std::true_type)
{
std::cout << "is out" << std::endl;
@ -258,7 +248,7 @@ struct method_caller
// }
template <std::size_t... I>
void aux(v8::Arguments const& args, eina::index_sequence<I...>
void aux(compatibility_callback_info_type args, eina::index_sequence<I...>
, std::true_type) const
{
typename eina::_mpl::tuple_transform<Out, out_transform<parameters_t> >::type outs {};
@ -269,7 +259,7 @@ struct method_caller
}
template <std::size_t... I>
void aux(v8::Arguments const& args, eina::index_sequence<I...>
void aux(compatibility_callback_info_type args, eina::index_sequence<I...>
, std::false_type) const
{
typename eina::_mpl::tuple_transform<Out, out_transform<parameters_t> >::type outs {};
@ -291,31 +281,7 @@ struct method_caller
};
};
#if 0
void operator()(v8::FunctionCallbackInfo<v8::Value> const& args)
{
int input_parameters = std::tuple_size<In>::value;
if(input_parameters <= args.Length())
{
v8::Local<v8::Object> self = args.This();
v8::Local<v8::Value> external = self->GetInternalField(0);
Eo* eo = static_cast<Eo*>(v8::External::Cast(*external)->Value());
try
{
eo_do(eo, aux(args, eina::make_index_sequence<std::tuple_size<parameters_t>::value>()
, std::is_same<void, typename eina::_mpl::function_return<F>::type>()));
}
catch(std::logic_error const&) {}
}
else
{
args.GetIsolate()->ThrowException
(v8::Exception::TypeError
(v8::String::NewFromUtf8(args.GetIsolate(), "Expected more arguments for this call")));
}
}
#else
v8::Handle<v8::Value> operator()(v8::Arguments const& args)
compatibility_return_type operator()(compatibility_callback_info_type args)
{
std::cerr << "call function operator()(args)" << std::endl;
int input_parameters = std::tuple_size<In>::value;
@ -333,39 +299,24 @@ struct method_caller
}
else
{
#if 0
args.GetIsolate()->
#else
v8::
#endif
ThrowException
return compatibility_throw
(v8::Exception::TypeError
(v8::String::New/*FromUtf8*/(/*args.GetIsolate(),*/ "Expected more arguments for this call")));
(compatibility_new<v8::String>(nullptr, "Expected more arguments for this call")));
}
return v8::Handle<v8::Value>();
return compatibility_return();
}
#endif
F function;
};
#if 0
template <typename In, typename Out, typename Ownership, typename F>
v8::Handle<v8::Value> call_function_data(v8::Isolate* isolate, F f)
{
return v8::External::New
(isolate, new std::function<void(v8::FunctionCallbackInfo<v8::Value> const&)>
return compatibility_new<v8::External>
(isolate, new std::function<compatibility_return_type(compatibility_callback_info_type const&)>
(method_caller<In, Out, Ownership, F>{f}));
}
#else
template <typename In, typename Out, typename Ownership, typename F>
v8::Handle<v8::Value> call_function_data(v8::Isolate* /*isolate*/, F f)
{
return v8::External::New
(new std::function<v8::Handle<v8::Value>(v8::Arguments const&)>
(method_caller<In, Out, Ownership, F>{f}));
}
#endif
} } }
#endif

View File

@ -0,0 +1,255 @@
#ifndef EFL_EO_JS_COMPATIBILITY_HH
#define EFL_EO_JS_COMPATIBILITY_HH
#include <type_traits>
#if 0
#include <v8.h>
#else
#include <node/v8.h>
#endif
namespace v8 {
template <typename T>
struct FunctionCallbackInfo;
}
namespace efl { namespace eo { namespace js {
template <typename T = v8::External, typename Enable = void>
struct _libv8_isolate_test;
template <typename T>
struct _libv8_isolate_test
<T, typename std::enable_if
<std::is_same<decltype( & T::New)
, v8::Local<T> (*)(v8::Isolate*, void*)>::value>::type>
: std::true_type
{
};
template <typename T>
struct _libv8_isolate_test
<T, typename std::enable_if
<std::is_same<decltype( & T::New)
, v8::Local<T> (*)(void*)>::value>::type>
: std::false_type
{
};
template <typename T = v8::FunctionTemplate, typename Enable = void>
struct _libv8_callback_info_test;
typedef v8::Handle<v8::Value>(*_libv8_invocation_callback)(v8::Arguments const&);
template <typename T>
struct _libv8_callback_info_test
<T, typename std::enable_if
<!std::is_same<decltype( & T::SetCallHandler)
, void (T::*)(_libv8_invocation_callback, v8::Handle<v8::Value>)>::value>::type>
: std::true_type
{
};
template <typename T>
struct _libv8_callback_info_test
<T, typename std::enable_if
<std::is_same<decltype( & T::SetCallHandler)
, void (T::*)(_libv8_invocation_callback, v8::Handle<v8::Value>)>::value>::type>
: std::false_type
{
};
static constexpr bool const v8_uses_isolate = _libv8_isolate_test<>::value;
static constexpr bool const v8_uses_callback_info = _libv8_callback_info_test<>::value;
using compatibility_return_type = std::conditional<v8_uses_callback_info, void, v8::Handle<v8::Value> >::type;
using compatibility_callback_info_type
= std::conditional<v8_uses_callback_info, v8::FunctionCallbackInfo<v8::Value> const&, v8::Arguments const&>
::type;
static_assert(!v8_uses_callback_info, "");
static_assert(!v8_uses_isolate, "");
template <typename T>
struct compatibility_type_tag {};
template <typename T = std::integral_constant<bool, v8_uses_isolate> >
struct compatibility_string;
template <>
struct compatibility_string<std::true_type> : v8::String {};
template <>
struct compatibility_string<std::false_type> : v8::String
{
static v8::Local<v8::String> NewFromUtf8(v8::Isolate*, const char* data)
{
return v8::String::New(data);
}
};
template <typename...Args>
auto compatibility_new_impl(v8::Isolate* isolate, std::true_type, compatibility_type_tag<v8::String>
, Args...args) ->
decltype(compatibility_string<>::NewFromUtf8(isolate, args...))
{
return compatibility_string<>::NewFromUtf8(isolate, args...);
}
template <typename...Args>
auto compatibility_new_impl(nullptr_t, std::true_type, compatibility_type_tag<v8::String>
, Args...args) ->
decltype(compatibility_string<>::NewFromUtf8(v8::Isolate::GetCurrent(), args...))
{
return compatibility_string<>::NewFromUtf8(v8::Isolate::GetCurrent(), args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(v8::Isolate* isolate, std::true_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(isolate, args...))
{
return T::New(isolate, args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(v8::Isolate*, std::false_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(args...))
{
return T::New(args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(std::nullptr_t, std::true_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(v8::Isolate::GetCurrent(), args...))
{
return T::New(v8::Isolate::GetCurrent(), args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(std::nullptr_t, std::false_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(args...))
{
return T::New(args...);
}
template <typename T, typename...Args>
auto compatibility_new(v8::Isolate* isolate, Args...args) ->
decltype(js::compatibility_new_impl<T>
(isolate, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...))
{
return js::compatibility_new_impl(isolate, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...);
}
template <typename T, typename...Args>
auto compatibility_new(nullptr_t, Args...args) ->
decltype(js::compatibility_new_impl<T>(nullptr, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...))
{
return js::compatibility_new_impl<T>(nullptr, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...);
}
template <typename T>
inline void compatibility_return_impl(T object, compatibility_callback_info_type, std::true_type)
{
// should set to info.ReturnValue(object);
}
template <typename T>
inline v8::Handle<v8::Value>
compatibility_return_impl(T object, compatibility_callback_info_type, std::false_type)
{
return object;
}
template <typename T>
compatibility_return_type
compatibility_return(T object, compatibility_callback_info_type args)
{
return compatibility_return_impl(object, args, std::integral_constant<bool, v8_uses_callback_info>());
}
inline void compatibility_return_nil_impl(std::true_type) {}
inline v8::Handle<v8::Value>
compatibility_return_nil_impl(std::false_type)
{
return v8::Handle<v8::Value>();
}
inline
compatibility_return_type
compatibility_return()
{
return compatibility_return_nil_impl(std::integral_constant<bool, v8_uses_callback_info>());
}
template <typename T = std::integral_constant<bool, v8_uses_isolate> >
struct _v8_isolate_throw_exception;
template <>
struct _v8_isolate_throw_exception<std::true_type> : v8::Isolate
{
};
template <>
struct _v8_isolate_throw_exception<std::false_type> : v8::Isolate
{
static v8::Handle<v8::Value> ThrowException(v8::Handle<v8::Value> v)
{
return v8::ThrowException(v);
}
};
inline void
compatibility_throw_impl(v8::Isolate* isolate, v8::Local<v8::Value> exception, std::true_type)
{
static_cast<_v8_isolate_throw_exception<>*>(isolate)->ThrowException(exception);
}
inline v8::Handle<v8::Value>
compatibility_throw_impl(v8::Isolate*, v8::Local<v8::Value> exception, std::false_type)
{
return v8::ThrowException(exception);
}
inline std::conditional<v8_uses_isolate, void, v8::Handle<v8::Value> >::type
compatibility_throw(v8::Isolate* isolate, v8::Local<v8::Value> exception)
{
return compatibility_throw_impl(isolate, exception, std::integral_constant<bool, v8_uses_isolate>());
}
inline void
compatibility_throw_impl(v8::Local<v8::Value> exception, std::true_type)
{
static_cast<_v8_isolate_throw_exception<>*>(v8::Isolate::GetCurrent())->ThrowException(exception);
}
inline v8::Handle<v8::Value>
compatibility_throw_impl(v8::Local<v8::Value> exception, std::false_type)
{
return v8::ThrowException(exception);
}
inline std::conditional<v8_uses_isolate, void, v8::Handle<v8::Value> >::type
compatibility_throw(v8::Local<v8::Value> exception)
{
return compatibility_throw_impl(exception, std::integral_constant<bool, v8_uses_isolate>());
}
} } }
#endif

View File

@ -35,8 +35,7 @@ inline Eina_Bool event_callback(void* data, Eo* obj, Eo_Event_Description const*
, void* /*event_info*/)
{
event_callback_information* event = static_cast<event_callback_information*>(data);
v8::Handle<v8::Value> a[] = {v8::External::New(/*isolate,*/ obj)};
// v8::Local<v8::Function> f = (*event->event_info->constructor)->GetFunction();
v8::Handle<v8::Value> a[] = {compatibility_new<v8::External>(nullptr, obj)};
v8::Local<v8::Object> self = (*event->event_info->constructor)->NewInstance(1, a);
v8::Handle<v8::Value> call_args[] = {self};
@ -45,10 +44,7 @@ inline Eina_Bool event_callback(void* data, Eo* obj, Eo_Event_Description const*
return EO_CALLBACK_CONTINUE;
}
#if 0
#else
inline v8::Handle<v8::Value> event_call(v8::Arguments const& args)
inline compatibility_return_type event_call(compatibility_callback_info_type args)
{
if(args.Length() >= 1)
{
@ -65,8 +61,9 @@ inline v8::Handle<v8::Value> event_call(v8::Arguments const& args)
Eo* eo = static_cast<Eo*>(v8::External::Cast(*external)->Value());
event_callback_information* i = new event_callback_information
{event, v8::Persistent<v8::Function>::New(v8::Handle<v8::Function>
(v8::Function::Cast(*arg1->ToObject())))};
{event, compatibility_new<v8::Persistent<v8::Function> >
(args.GetIsolate()
, v8::Handle<v8::Function>(v8::Function::Cast(*arg1->ToObject())))};
eo_do(eo, eo_event_callback_priority_add
(event->event, EO_CALLBACK_PRIORITY_DEFAULT, &event_callback, i));
@ -75,9 +72,8 @@ inline v8::Handle<v8::Value> event_call(v8::Arguments const& args)
else
{
}
return v8::Handle<v8::Value>();
return compatibility_return();
}
#endif
} } }