/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include namespace facebook::react::bridging { template < typename T, typename C, typename R, typename... Args, typename... JSArgs> T callFromJs( jsi::Runtime &rt, R (C::*method)(jsi::Runtime &, Args...), const std::shared_ptr &jsInvoker, C *instance, JSArgs &&...args) { static_assert( sizeof...(Args) == sizeof...(JSArgs), "Incorrect arguments length"); static_assert( (supportsFromJs && ...), "Incompatible arguments"); if constexpr (std::is_void_v) { (instance->*method)( rt, fromJs(rt, std::forward(args), jsInvoker)...); } else if constexpr (std::is_void_v) { static_assert( std::is_same_v, "Void functions may only return undefined"); (instance->*method)( rt, fromJs(rt, std::forward(args), jsInvoker)...); return jsi::Value(); } else if constexpr (is_jsi_v) { static_assert(supportsToJs, "Incompatible return type"); return toJs( rt, (instance->*method)( rt, fromJs(rt, std::forward(args), jsInvoker)...), jsInvoker); } else if constexpr (is_optional_v) { static_assert( is_optional_v ? supportsToJs : supportsToJs, "Incompatible return type"); auto result = toJs( rt, (instance->*method)( rt, fromJs(rt, std::forward(args), jsInvoker)...), jsInvoker); if constexpr (std::is_same_v) { if (result.isNull() || result.isUndefined()) { return std::nullopt; } } return convert(rt, std::move(result)); } else { static_assert(std::is_convertible_v, "Incompatible return type"); return (instance->*method)( rt, fromJs(rt, std::forward(args), jsInvoker)...); } } template constexpr size_t getParameterCount(R (*)(Args...)) { return sizeof...(Args); } template constexpr size_t getParameterCount(R (C::*)(Args...)) { return sizeof...(Args); } } // namespace facebook::react::bridging