Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,24 @@ void rejectWithException(

} // namespace

const JavaTurboModule::MethodInfo& JavaTurboModule::getMethodInfo(
jmethodID methodID,
const std::string& methodSignature) {
std::lock_guard<std::mutex> lock(methodInfosMutex_);
auto entry = methodInfos_.find(methodID);
if (entry == methodInfos_.end()) {
entry = methodInfos_
.emplace(
methodID,
MethodInfo{
getMethodArgTypesFromSignature(methodSignature),
methodSignature.substr(
methodSignature.find_last_of(')') + 1)})
.first;
}
return entry->second;
}

jsi::Value JavaTurboModule::invokeJavaMethod(
jsi::Runtime& runtime,
TurboModuleMethodValueKind valueKind,
Expand Down Expand Up @@ -689,14 +707,13 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
return returnValue;
}

std::vector<std::string> methodArgTypes =
getMethodArgTypesFromSignature(methodSignature);
const MethodInfo& methodInfo = getMethodInfo(methodID, methodSignature);

JNIArgs jniArgs = convertJSIArgsToJNIArgs(
env,
runtime,
methodNameStr,
methodArgTypes,
methodInfo.argTypes,
args,
argCount,
jsInvoker_,
Expand All @@ -712,8 +729,7 @@ jsi::Value JavaTurboModule::invokeJavaMethod(

switch (valueKind) {
case BooleanKind: {
std::string returnType =
methodSignature.substr(methodSignature.find_last_of(')') + 1);
const std::string& returnType = methodInfo.returnType;
if (returnType == "Ljava/lang/Boolean;") {
auto returnObject =
env->CallObjectMethodA(instance, methodID, jargs.data());
Expand Down Expand Up @@ -749,8 +765,7 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
}
}
case NumberKind: {
std::string returnType =
methodSignature.substr(methodSignature.find_last_of(')') + 1);
const std::string& returnType = methodInfo.returnType;
if (returnType == "Ljava/lang/Double;" ||
returnType == "Ljava/lang/Float;" ||
returnType == "Ljava/lang/Integer;") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@

#include <react/cxxstableapi/UmbrellaGuard.h>

#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>

#include <React/Bridging.h>
#include <React/CallInvoker.h>
Expand Down Expand Up @@ -61,6 +64,15 @@ class JSI_EXPORT JavaTurboModule : public TurboModule {
// instance_ can be of type JTurboModule, or JNativeModule
jni::global_ref<jobject> instance_;
std::shared_ptr<NativeMethodCallInvoker> nativeMethodCallInvoker_;

// A method's JNI signature, parsed on its first call since it doesn't change.
struct MethodInfo {
std::vector<std::string> argTypes;
std::string returnType;
};
std::unordered_map<jmethodID, MethodInfo> methodInfos_;
std::mutex methodInfosMutex_;
const MethodInfo &getMethodInfo(jmethodID methodID, const std::string &methodSignature);
Comment on lines +68 to +75

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a follow-up PR, let's actually store jmethodID here too, and index based on method name. I previously added it as a mutable method signature to act as a similar "cache", but it's actually simpler to have a single cache in the TurboModule instance.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javache, thank you for the comment! I'll create a follow-up PR. 👍

};

} // namespace facebook::react
Loading