introduce performVoidMethodInvocation (#39760)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39760

Changelog: [Internal]

void functions are kinda special right now for the following reasons:
- they can be executed async or sync right now
- they don't return any value

thus, it makes sense for us to separate the invocation logic out and clean up the logic for retrieving return values specifically.

Reviewed By: javache

Differential Revision: D49652998

fbshipit-source-id: 7dba03adb8154e73ed75f8c2864294215c748107
This commit is contained in:
Phillip Pan
2023-10-04 16:26:58 -07:00
committed by Facebook GitHub Bot
parent 45d74b4bd5
commit dd30d05e00
2 changed files with 56 additions and 2 deletions
@@ -142,6 +142,11 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule {
const char *methodName,
NSInvocation *inv,
NSMutableArray *retainedObjectsForInvocation);
void performVoidMethodInvocation(
jsi::Runtime &runtime,
const char *methodName,
NSInvocation *inv,
NSMutableArray *retainedObjectsForInvocation);
using PromiseInvocationBlock = void (^)(RCTPromiseResolveBlock resolveWrapper, RCTPromiseRejectBlock rejectWrapper);
jsi::Value createPromise(jsi::Runtime &runtime, std::string methodName, PromiseInvocationBlock invoke);
@@ -430,6 +430,55 @@ id ObjCTurboModule::performMethodInvocation(
}
}
void ObjCTurboModule::performVoidMethodInvocation(
jsi::Runtime &runtime,
const char *methodName,
NSInvocation *inv,
NSMutableArray *retainedObjectsForInvocation)
{
__weak id<RCTBridgeModule> weakModule = instance_;
const char *moduleName = name_.c_str();
std::string methodNameStr{methodName};
__block int32_t asyncCallCounter = 0;
void (^block)() = ^{
id<RCTBridgeModule> strongModule = weakModule;
if (!strongModule) {
return;
}
if (shouldVoidMethodsExecuteSync_) {
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
} else {
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
}
@try {
[inv invokeWithTarget:strongModule];
} @catch (NSException *exception) {
throw convertNSExceptionToJSError(runtime, exception);
} @finally {
[retainedObjectsForInvocation removeAllObjects];
}
if (shouldVoidMethodsExecuteSync_) {
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
} else {
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
}
return;
};
if (shouldVoidMethodsExecuteSync_) {
nativeMethodCallInvoker_->invokeSync(methodNameStr, [&]() -> void { block(); });
} else {
asyncCallCounter = getUniqueId();
TurboModulePerfLogger::asyncMethodCallDispatch(moduleName, methodName);
nativeMethodCallInvoker_->invokeAsync(methodNameStr, [block]() -> void { block(); });
}
}
jsi::Value ObjCTurboModule::convertReturnIdToJSIValue(
jsi::Runtime &runtime,
const char *methodName,
@@ -741,11 +790,11 @@ jsi::Value ObjCTurboModule::invokeObjCMethod(
break;
}
case VoidKind: {
id result = performMethodInvocation(runtime, isSyncInvocation, methodName, inv, retainedObjectsForInvocation);
performVoidMethodInvocation(runtime, methodName, inv, retainedObjectsForInvocation);
if (isSyncInvocation) {
TurboModulePerfLogger::syncMethodCallReturnConversionStart(moduleName, methodName);
}
returnValue = convertReturnIdToJSIValue(runtime, methodName, returnType, result);
returnValue = jsi::Value::undefined();
if (isSyncInvocation) {
TurboModulePerfLogger::syncMethodCallReturnConversionEnd(moduleName, methodName);
}