// Copyright © 2021-present 650 Industries, Inc. (aka Expo) #include "JavaScriptFunction.h" #include "types/JNIToJSIConverter.h" #include "types/AnyType.h" namespace expo { void JavaScriptFunction::registerNatives() { registerHybrid({ makeNativeMethod("invoke", JavaScriptFunction::invoke), }); } JavaScriptFunction::JavaScriptFunction( std::weak_ptr runtime, std::shared_ptr jsFunction ) : runtimeHolder(std::move(runtime)), jsFunction(std::move(jsFunction)) { runtimeHolder.ensureRuntimeIsValid(); } JavaScriptFunction::JavaScriptFunction( WeakRuntimeHolder runtime, std::shared_ptr jsFunction ) : runtimeHolder(std::move(runtime)), jsFunction(std::move(jsFunction)) { runtimeHolder.ensureRuntimeIsValid(); } std::shared_ptr JavaScriptFunction::get() { return jsFunction; } jobject JavaScriptFunction::invoke( jni::alias_ref> args, jni::alias_ref expectedReturnType ) { auto &rt = runtimeHolder.getJSRuntime(); auto moduleRegistry = runtimeHolder.getModuleRegistry(); JNIEnv *env = jni::Environment::current(); size_t size = args->size(); std::vector convertedArgs; convertedArgs.reserve(size); for (size_t i = 0; i < size; i++) { jni::local_ref arg = args->getElement(i); convertedArgs.push_back(convert(moduleRegistry, env, rt, std::move(arg))); } // TODO(@lukmccall): add better error handling jsi::Value result = jsFunction->call(rt, (const jsi::Value *) convertedArgs.data(), size); auto converter = AnyType(jni::make_local(expectedReturnType)).converter; auto convertedResult = converter->convert(rt, env, moduleRegistry, result); return convertedResult; } } // namespace expo