Use fbjni boxed values for Java turbomodule arg conversion

Summary:
Simplify argument and result conversion by using existing fbjni helpers (which will cache class and method ID lookups already)

Changelog: [internal]

Reviewed By: RSNara

Differential Revision: D36312751

fbshipit-source-id: 16713642b2c5fb4c2b6447c30652d91ddbd88224
This commit is contained in:
Pieter De Baets
2022-05-18 09:12:10 -07:00
committed by Facebook GitHub Bot
parent fced96bf52
commit d1541f169f
@@ -280,9 +280,6 @@ JNIArgs convertJSIArgsToJNIArgs(
return obj;
};
jclass booleanClass = nullptr;
jclass doubleClass = nullptr;
for (unsigned int argIndex = 0; argIndex < count; argIndex += 1) {
const std::string &type = methodArgTypes.at(argIndex);
@@ -294,7 +291,6 @@ JNIArgs convertJSIArgsToJNIArgs(
throw JavaTurboModuleArgumentConversionException(
"number", argIndex, methodName, arg, &rt);
}
jarg->d = arg->getNumber();
continue;
}
@@ -304,108 +300,64 @@ JNIArgs convertJSIArgsToJNIArgs(
throw JavaTurboModuleArgumentConversionException(
"boolean", argIndex, methodName, arg, &rt);
}
jarg->z = (jboolean)arg->getBool();
continue;
}
if (!(type == "Ljava/lang/Double;" || type == "Ljava/lang/Boolean;" ||
type == "Ljava/lang/String;" ||
type == "Lcom/facebook/react/bridge/ReadableArray;" ||
type == "Lcom/facebook/react/bridge/Callback;" ||
type == "Lcom/facebook/react/bridge/ReadableMap;")) {
throw JavaTurboModuleInvalidArgumentTypeException(
type, argIndex, methodName);
}
if (arg->isNull() || arg->isUndefined()) {
jarg->l = nullptr;
continue;
}
if (type == "Ljava/lang/Double;") {
} else if (type == "Ljava/lang/Double;") {
if (!arg->isNumber()) {
throw JavaTurboModuleArgumentConversionException(
"number", argIndex, methodName, arg, &rt);
}
if (doubleClass == nullptr) {
doubleClass = env->FindClass("java/lang/Double");
}
jmethodID doubleConstructor =
env->GetMethodID(doubleClass, "<init>", "(D)V");
jarg->l = makeGlobalIfNecessary(
env->NewObject(doubleClass, doubleConstructor, arg->getNumber()));
continue;
}
if (type == "Ljava/lang/Boolean;") {
jni::JDouble::valueOf(arg->getNumber()).release());
} else if (type == "Ljava/lang/Boolean;") {
if (!arg->isBool()) {
throw JavaTurboModuleArgumentConversionException(
"boolean", argIndex, methodName, arg, &rt);
}
if (booleanClass == nullptr) {
booleanClass = env->FindClass("java/lang/Boolean");
}
jmethodID booleanConstructor =
env->GetMethodID(booleanClass, "<init>", "(Z)V");
jarg->l = makeGlobalIfNecessary(
env->NewObject(booleanClass, booleanConstructor, arg->getBool()));
continue;
}
if (type == "Ljava/lang/String;") {
jni::JBoolean::valueOf(arg->getBool()).release());
} else if (type == "Ljava/lang/String;") {
if (!arg->isString()) {
throw JavaTurboModuleArgumentConversionException(
"string", argIndex, methodName, arg, &rt);
}
jarg->l = makeGlobalIfNecessary(
env->NewStringUTF(arg->getString(rt).utf8(rt).c_str()));
continue;
}
if (type == "Lcom/facebook/react/bridge/ReadableArray;") {
if (!(arg->isObject() && arg->getObject(rt).isArray(rt))) {
throw JavaTurboModuleArgumentConversionException(
"Array", argIndex, methodName, arg, &rt);
}
auto dynamicFromValue = jsi::dynamicFromValue(rt, *arg);
auto jParams =
ReadableNativeArray::newObjectCxxArgs(std::move(dynamicFromValue));
jarg->l = makeGlobalIfNecessary(jParams.release());
continue;
}
if (type == "Lcom/facebook/react/bridge/Callback;") {
} else if (type == "Lcom/facebook/react/bridge/Callback;") {
if (!(arg->isObject() && arg->getObject(rt).isFunction(rt))) {
throw JavaTurboModuleArgumentConversionException(
"Function", argIndex, methodName, arg, &rt);
}
jsi::Function fn = arg->getObject(rt).getFunction(rt);
jarg->l = makeGlobalIfNecessary(
createJavaCallbackFromJSIFunction(
retainJSCallback, std::move(fn), rt, jsInvoker)
.release());
continue;
}
if (type == "Lcom/facebook/react/bridge/ReadableMap;") {
} else if (type == "Lcom/facebook/react/bridge/ReadableArray;") {
if (!(arg->isObject() && arg->getObject(rt).isArray(rt))) {
throw JavaTurboModuleArgumentConversionException(
"Array", argIndex, methodName, arg, &rt);
}
auto dynamicFromValue = jsi::dynamicFromValue(rt, *arg);
auto jParams =
ReadableNativeArray::newObjectCxxArgs(std::move(dynamicFromValue));
jarg->l = makeGlobalIfNecessary(jParams.release());
} else if (type == "Lcom/facebook/react/bridge/ReadableMap;") {
if (!(arg->isObject())) {
throw JavaTurboModuleArgumentConversionException(
"Object", argIndex, methodName, arg, &rt);
}
auto dynamicFromValue = jsi::dynamicFromValue(rt, *arg);
auto jParams =
ReadableNativeMap::createWithContents(std::move(dynamicFromValue));
jarg->l = makeGlobalIfNecessary(jParams.release());
continue;
} else {
throw JavaTurboModuleInvalidArgumentTypeException(
type, argIndex, methodName);
}
}
@@ -556,81 +508,73 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
methodSignature.substr(methodSignature.find_last_of(')') + 1);
if (returnType == "Ljava/lang/Boolean;") {
auto returnObject =
(jobject)env->CallObjectMethodA(instance, methodID, jargs.data());
env->CallObjectMethodA(instance, methodID, jargs.data());
checkJNIErrorForMethodCall();
TMPL::syncMethodCallExecutionEnd(moduleName, methodName);
TMPL::syncMethodCallReturnConversionStart(moduleName, methodName);
jsi::Value returnValue = jsi::Value::null();
if (returnObject != nullptr) {
jclass booleanClass = env->FindClass("java/lang/Boolean");
jmethodID booleanValueMethod =
env->GetMethodID(booleanClass, "booleanValue", "()Z");
bool returnBoolean =
(bool)env->CallBooleanMethod(returnObject, booleanValueMethod);
checkJNIErrorForMethodCall();
returnValue = jsi::Value(returnBoolean);
auto returnValue = jsi::Value::null();
if (returnObject) {
auto booleanObj = jni::adopt_local(
static_cast<jni::JBoolean::javaobject>(returnObject));
returnValue = jsi::Value(static_cast<bool>(booleanObj->value()));
}
TMPL::syncMethodCallReturnConversionEnd(moduleName, methodName);
TMPL::syncMethodCallEnd(moduleName, methodName);
return returnValue;
} else {
bool returnBoolean =
(bool)env->CallBooleanMethodA(instance, methodID, jargs.data());
checkJNIErrorForMethodCall();
TMPL::syncMethodCallExecutionEnd(moduleName, methodName);
TMPL::syncMethodCallReturnConversionStart(moduleName, methodName);
jsi::Value returnValue = jsi::Value(returnBoolean);
TMPL::syncMethodCallReturnConversionEnd(moduleName, methodName);
TMPL::syncMethodCallEnd(moduleName, methodName);
return returnValue;
}
bool returnBoolean =
(bool)env->CallBooleanMethodA(instance, methodID, jargs.data());
checkJNIErrorForMethodCall();
TMPL::syncMethodCallExecutionEnd(moduleName, methodName);
TMPL::syncMethodCallReturnConversionStart(moduleName, methodName);
jsi::Value returnValue = jsi::Value(returnBoolean);
TMPL::syncMethodCallReturnConversionEnd(moduleName, methodName);
TMPL::syncMethodCallEnd(moduleName, methodName);
return returnValue;
}
case NumberKind: {
std::string returnType =
methodSignature.substr(methodSignature.find_last_of(')') + 1);
if (returnType == "Ljava/lang/Double;") {
auto returnObject =
(jobject)env->CallObjectMethodA(instance, methodID, jargs.data());
env->CallObjectMethodA(instance, methodID, jargs.data());
checkJNIErrorForMethodCall();
TMPL::syncMethodCallExecutionEnd(moduleName, methodName);
TMPL::syncMethodCallReturnConversionStart(moduleName, methodName);
jsi::Value returnValue = jsi::Value::null();
if (returnObject != nullptr) {
jclass doubleClass = env->FindClass("java/lang/Double");
jmethodID doubleValueMethod =
env->GetMethodID(doubleClass, "doubleValue", "()D");
double returnDouble =
(double)env->CallDoubleMethod(returnObject, doubleValueMethod);
checkJNIErrorForMethodCall();
returnValue = jsi::Value(returnDouble);
auto returnValue = jsi::Value::null();
if (returnObject) {
auto doubleObj = jni::adopt_local(
static_cast<jni::JDouble::javaobject>(returnObject));
returnValue = jsi::Value(doubleObj->value());
}
TMPL::syncMethodCallReturnConversionEnd(moduleName, methodName);
TMPL::syncMethodCallEnd(moduleName, methodName);
return returnValue;
} else {
double returnDouble =
(double)env->CallDoubleMethodA(instance, methodID, jargs.data());
checkJNIErrorForMethodCall();
TMPL::syncMethodCallExecutionEnd(moduleName, methodName);
TMPL::syncMethodCallReturnConversionStart(moduleName, methodName);
jsi::Value returnValue = jsi::Value(returnDouble);
TMPL::syncMethodCallReturnConversionEnd(moduleName, methodName);
TMPL::syncMethodCallEnd(moduleName, methodName);
return returnValue;
}
double returnDouble =
(double)env->CallDoubleMethodA(instance, methodID, jargs.data());
checkJNIErrorForMethodCall();
TMPL::syncMethodCallExecutionEnd(moduleName, methodName);
TMPL::syncMethodCallReturnConversionStart(moduleName, methodName);
jsi::Value returnValue = jsi::Value(returnDouble);
TMPL::syncMethodCallReturnConversionEnd(moduleName, methodName);
TMPL::syncMethodCallEnd(moduleName, methodName);
return returnValue;
}
case StringKind: {
auto returnString =
@@ -655,7 +599,7 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
}
case ObjectKind: {
auto returnObject =
(jobject)env->CallObjectMethodA(instance, methodID, jargs.data());
env->CallObjectMethodA(instance, methodID, jargs.data());
checkJNIErrorForMethodCall();
TMPL::syncMethodCallExecutionEnd(moduleName, methodName);