/* * Tencent is pleased to support the open source community by making Puerts available. * Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. * Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may * be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE', * which is part of this source code package. */ #pragma once #pragma warning(push, 0) #include #pragma warning(pop) #include "DataTransfer.h" namespace PUERTS_NAMESPACE { template struct FastCallArgument { }; template struct FastCallArgument::value && !std::is_same::value && !std::is_enum::type>::value && !std::is_integral::type>::value && !std::is_floating_point::type>::value>::type> { using DeclType = v8::Local; static T Get(v8::Local v) { if (V8_LIKELY(v->IsObject())) { // return static_cast(v.As()->GetAlignedPointerFromInternalField(1)); return static_cast(DataTransfer::GetPointerFast(v.As())); } return nullptr; } }; template <> struct FastCallArgument { }; template struct FastCallArgument::value>::type> { using DeclType = int; static T Get(int i) { return static_cast(i); } }; template struct FastCallArgument::value || std::is_floating_point::value>::type> { using DeclType = typename std::decay::type; static T Get(typename std::decay::type i) { return i; } }; template <> struct FastCallArgument { using DeclType = bool; static bool Get(bool i) { return i; } }; namespace internal { namespace fastcallutil { template struct _Conjunction { // handle false trait or last trait using type = _First; }; template struct _Conjunction { // the first trait is true, try the next one using type = typename _Conjunction<_Next::value, _Next, _Rest...>::type; }; template struct Conjunction : std::true_type { }; // If _Traits is empty, true_type template struct Conjunction<_First, _Rest...> : _Conjunction<_First::value, _First, _Rest...>::type { // the first false trait in _Traits, or the last trait if none are false }; template using Void_t = void; } // namespace fastcallutil } // namespace internal template struct IsArgSupportedHelper : std::false_type { }; template struct IsArgSupportedHelper::Get)>> : std::true_type { }; template struct IsArgsSupportedHelper : std::false_type { }; template struct IsArgsSupportedHelper, typename std::enable_if...>::value>::type> : std::true_type { }; template struct IsReturnSupportedHelper : std::false_type { }; template struct IsReturnSupportedHelper::value && !std::is_pointer::value && !std::is_integral::value>::type> : std::true_type { }; template struct IsReturnSupportedHelper::value && sizeof(T) < 8>::type> : std::true_type { }; template <> struct IsReturnSupportedHelper : std::true_type { }; template struct V8FastCall { static const v8::CFunction* info() { return nullptr; } }; template struct V8FastCall::value && IsArgsSupportedHelper>::value && (sizeof...(Args) > 0)>::type> { static Ret Wrap(v8::Local receiver_obj, typename FastCallArgument::DeclType... args) { return func(FastCallArgument::Get(args)...); } static const v8::CFunction* info() { static v8::CFunction _info = v8::CFunction::Make(Wrap); return &_info; } }; template struct V8FastCall::value && IsArgsSupportedHelper>::value>::type> { static Ret Wrap(v8::Local receiver_obj, typename FastCallArgument::DeclType... args) { auto self = FastCallArgument::Get(receiver_obj); return (self->*func)(FastCallArgument::Get(args)...); } static const v8::CFunction* info() { static v8::CFunction _info = v8::CFunction::Make(Wrap); return &_info; } }; template struct V8FastCall::value && IsArgsSupportedHelper>::value>::type> { static Ret Wrap(v8::Local receiver_obj, typename FastCallArgument::DeclType... args) { auto self = FastCallArgument::Get(receiver_obj); return (self->*func)(FastCallArgument::Get(args)...); } static const v8::CFunction* info() { static v8::CFunction _info = v8::CFunction::Make(Wrap); return &_info; } }; } // namespace PUERTS_NAMESPACE