24 #define V8_TOOLKIT_DEBUG false 43 v8::Isolate * isolate,
66 native_object(new
AnyPtr<T>(native_object)),
67 weak_callback_data(weak_callback_data),
68 original_pointer(native_object)
78 #define CONTEXT_SCOPED_RUN(local_context) \ 79 v8::Isolate * _v8toolkit_internal_isolate = (local_context)->GetIsolate(); \ 80 v8::Locker _v8toolkit_internal_locker(_v8toolkit_internal_isolate); \ 81 v8::Isolate::Scope _v8toolkit_internal_isolate_scope(_v8toolkit_internal_isolate); \ 82 v8::HandleScope _v8toolkit_internal_handle_scope(_v8toolkit_internal_isolate); \ 83 v8::Context::Scope _v8toolkit_internal_context_scope((local_context)); 85 #define GLOBAL_CONTEXT_SCOPED_RUN(isolate, global_context) \ 86 v8::Locker _v8toolkit_internal_locker(isolate); \ 87 v8::Isolate::Scope _v8toolkit_internal_isolate_scope(isolate); \ 88 v8::HandleScope _v8toolkit_internal_handle_scope(isolate); \ 90 v8::Local<v8::Context> _v8toolkit_internal_local_context = global_context.Get(isolate); \ 91 v8::Context::Scope _v8toolkit_internal_context_scope(_v8toolkit_internal_local_context); 93 #define ISOLATE_SCOPED_RUN(isolate) \ 94 v8::Locker _v8toolkit_internal_locker((isolate)); \ 95 v8::Isolate::Scope _v8toolkit_internal_isolate_scope((isolate)); \ 96 v8::HandleScope _v8toolkit_internal_handle_scope((isolate)); 98 #define DEBUG_SCOPED_RUN(isolate) \ 99 v8::Locker _v8toolkit_internal_locker((isolate)); \ 100 v8::Isolate::Scope _v8toolkit_internal_isolate_scope((isolate)); \ 101 v8::HandleScope _v8toolkit_internal_handle_scope((isolate)); \ 102 v8::Context::Scope _v8toolkit_internal_context_scope(v8::Debug::GetDebugContext((isolate))); 111 auto scoped_run(v8::Isolate * isolate, T callable) ->
typename std::result_of<T()>::type
113 v8::Locker locker(isolate);
114 v8::Isolate::Scope isolate_scope(isolate);
115 v8::HandleScope handle_scope(isolate);
117 if (isolate->InContext()) {
118 auto context = isolate->GetCurrentContext();
119 v8::Context::Scope context_scope(context);
134 auto scoped_run(v8::Isolate * isolate, T callable) ->
typename std::result_of<T(v8::Isolate*)>::type
136 v8::Locker locker(isolate);
137 v8::Isolate::Scope isolate_scope(isolate);
138 v8::HandleScope handle_scope(isolate);
140 return callable(isolate);
151 auto scoped_run(v8::Isolate * isolate, T callable) ->
typename std::result_of<T(v8::Isolate*, v8::Local<v8::Context>)>::type
153 v8::Locker locker(isolate);
154 v8::Isolate::Scope isolate_scope(isolate);
155 v8::HandleScope handle_scope(isolate);
157 if (isolate->InContext()) {
158 auto context = isolate->GetCurrentContext();
159 v8::Context::Scope context_scope(context);
160 return callable(isolate, context);
162 throw InvalidCallException(
"Isolate not currently in a context, but callable expects a context.");
178 v8::Locker locker(isolate);
179 v8::Isolate::Scope isolate_scope(isolate);
180 v8::HandleScope handle_scope(isolate);
181 v8::Context::Scope context_scope(context);
197 v8::Locker locker(isolate);
198 v8::Isolate::Scope isolate_scope(isolate);
199 v8::HandleScope handle_scope(isolate);
200 v8::Context::Scope context_scope(context);
202 return callable(isolate);
214 typename std::result_of<T(v8::Isolate*, v8::Local<v8::Context>)>::type
216 v8::Locker locker(isolate);
217 v8::Isolate::Scope isolate_scope(isolate);
218 v8::HandleScope handle_scope(isolate);
219 v8::Context::Scope context_scope(context);
221 return callable(isolate, context);
228 auto scoped_run(v8::Isolate * isolate,
const v8::Global<v8::Context> & context, T callable)
230 v8::Locker l(isolate);
231 v8::HandleScope hs(isolate);
232 auto local_context = context.Get(isolate);
233 return scoped_run(isolate, local_context, callable);
247 v8::Isolate * isolate;
248 v8::Global<v8::Value> value;
252 V8Exception(v8::Isolate * isolate, v8::Global<v8::Value>&& value) : isolate(isolate), value(
std::
move(value)) {
253 std::string str(*v8::String::Utf8Value(this->value.Get(isolate)));
254 value_for_what = str ==
"" ?
"unknown error" : str;
258 virtual const char *
what() const noexcept
override {
259 return value_for_what.c_str();
263 v8::Global<v8::Value>
get_value(){
return v8::Global<v8::Value>(isolate, value);}
284 auto stacktrace_maybe = tc.StackTrace(isolate->GetCurrentContext());
285 if (!stacktrace_maybe.IsEmpty()) {
286 stacktrace = *v8::String::Utf8Value(stacktrace_maybe.ToLocalChecked());
343 template<
class R,
class...
Args>
355 template <
class R,
class...
Args>
365 return v8::FunctionTemplate::New(isolate, [](
const v8::FunctionCallbackInfo<v8::Value>& info) {
366 auto isolate = info.GetIsolate();
371 CallCallable<decltype(data.callable)>()(data.callable, info, std::index_sequence_for<Args...>{});
373 }
catch (std::exception & e) {
375 isolate->ThrowException(v8::String::NewFromUtf8(isolate, e.what()));
385 }, v8::External::New(isolate, (
void*)data));
392 template<
class R,
class CLASS,
class...
Args>
400 template<
class R,
class...
Args>
419 template <
class R,
class...
Args>
430 template<
class R,
class...
Args>
441 decltype(
LTG<T>::go(&T::operator())) f(callable);
449 template<
class R,
class...
Args>
464 auto isolate = context->GetIsolate();
466 auto function = function_template->GetFunction();
467 (void)object->Set(context, v8::String::NewFromUtf8(isolate, name),
function);
495 template<
int position,
class Tuple>
501 template<
int position,
class Tuple>
505 constexpr
int array_position = position - 1;
507 super::operator()(isolate, params, tuple);
514 template<
class Tuple>
523 template<
class... OriginalTypes,
class... Ts>
529 auto isolate = context->GetIsolate();
531 auto parameter_count =
sizeof...(ts);
532 v8::TryCatch tc(isolate);
533 auto maybe_result =
function->Call(context, receiver, parameter_count, ¶meters[0]);
534 if(tc.HasCaught() || maybe_result.IsEmpty()) {
535 printf(
"Error running javascript function: '%s'\n", *v8::String::Utf8Value(tc.Exception()));
537 printf(
"Some of the types are const, make sure what you are using them for is available on the const type\n");
542 return maybe_result.ToLocalChecked();
549 template<
class TupleType = std::tuple<>>
553 const TupleType & tuple = {})
555 constexpr
int tuple_size = std::tuple_size<TupleType>::value;
556 std::array<v8::Local<v8::Value>, tuple_size> parameters;
557 auto isolate = context->GetIsolate();
560 v8::TryCatch tc(isolate);
563 auto maybe_result =
function->Call(context, receiver, tuple_size, parameters.data());
564 if(tc.HasCaught() || maybe_result.IsEmpty()) {
566 printf(
"Error running javascript function: '%s'\n", *v8::String::Utf8Value(tc.Exception()));
569 return maybe_result.ToLocalChecked();
575 template<
class TupleType = std::tuple<>>
579 const TupleType & tuple = {})
581 auto maybe_value = receiver->Get(context, v8::String::NewFromUtf8(context->GetIsolate(),function_name.c_str()));
582 if(maybe_value.IsEmpty()) {
586 auto value = maybe_value.ToLocalChecked();
587 if(!value->IsFunction()) {
598 const v8::PropertyCallbackInfo<v8::Value>& info)
600 auto isolate = info.GetIsolate();
601 T * variable = (T*)v8::External::Cast(*(info.Data()))->Value();
606 info.GetReturnValue().Set(
CastToJS<T>()(isolate, *variable));
612 template<class T, std::enable_if_t<std::is_const<T>::value,
int> = 0>
620 template<class T, std::enable_if_t<!std::is_const<T>::value,
int> = 0>
624 *(T*)v8::External::Cast(*(info.Data()))->Value() =
CastToNative<T>()(info.GetIsolate(), value);
643 object_template->SetAccessor(v8::String::NewFromUtf8(isolate, name),
646 v8::External::New(isolate, &variable));
650 template<
class T,
class... Rest>
654 std::unique_ptr<T, Rest...> & variable) {
655 object_template->SetAccessor(v8::String::NewFromUtf8(isolate, name),
658 v8::External::New(isolate, variable.get()));
670 object_template->SetAccessor(v8::String::NewFromUtf8(isolate, name),
673 v8::External::New(isolate, &variable));
682 auto isolate = context->GetIsolate();
683 object->SetAccessor(v8::String::NewFromUtf8(isolate, name),
686 v8::External::New(isolate, &variable));
696 auto isolate = context->GetIsolate();
697 object->SetAccessor(v8::String::NewFromUtf8(isolate, name), _variable_getter<T>, 0, v8::External::New(isolate, &variable));
724 std::vector<v8::Local<v8::Value>>
get_all_values(
const v8::FunctionCallbackInfo<v8::Value>& args,
int depth = 1);
775 template<
class R,
class T,
class...
Args>
776 struct Bind<R(T::*)(Args...)> {
780 object(object), method(method)
789 return (
object.*method)(std::forward<Args>(params)...);
794 template<
class R,
class T,
class...
Args>
795 struct Bind<R(T::*)(Args...) &> {
798 object(object), method(method){}
806 return (
object.*method)(std::forward<Args>(params)...);
815 template<
class R,
class T,
class...
Args>
816 struct Bind<R(T::*)(Args...) const> {
818 Bind(T
const &
object, R(T::*method)(
Args...)
const) :
819 object(object), method(method){}
825 return (
object.*method)(std::forward<Args>(params)...);
830 template<
class R,
class T,
class...
Args>
831 struct Bind<R(T::*)(Args...) const &> {
833 Bind(T
const &
object, R(T::*method)(
Args...)
const &) :
834 object(object), method(method){}
837 R(T::*method)(
Args...)
const &;
840 return (
object.*method)(std::forward<Args>(params)...);
854 template <
class CLASS,
class R,
class METHOD_CLASS,
class...
Args>
870 template <
class CLASS,
class R,
class METHOD_CLASS,
class...
Args>
884 template <
class CLASS,
class R,
class METHOD_CLASS,
class...
Args>
897 template <
class CLASS,
class R,
class METHOD_CLASS,
class...
Args>
909 inline virtual void*
Allocate(
size_t length)
override {
910 void* data = AllocateUninitialized(length);
911 return data == NULL ? data : memset(data, 0, length);
914 inline virtual void Free(
void* data,
size_t)
override { free(data); }
958 v8::Global<v8::Function>
function;
965 const time_t & time) :
967 context(
v8::Global<
v8::
Context>(isolate, context)),
968 function(
v8::Global<
v8::Function>(isolate, function)),
969 result(
v8::Global<
v8::
Value>(isolate, result)),
984 const std::vector<std::string> & paths,
985 bool track_modification_times =
false,
986 bool use_cache =
true,
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
bool Value(const T &value, M matcher)
const T & move(const T &t)