Fix the issue that local reference overflows in Yoga 1 (#1308)

Summary:
X-link: https://github.com/facebook/react-native/pull/37929

X-link: https://github.com/facebook/litho/pull/952

Pull Request resolved: https://github.com/facebook/yoga/pull/1308

Long story in short, we're trying to fix an issue with Yoga that could potentially lead to an overflow in the JNI local reference table.

Reviewed By: NickGerleman, astreet

Differential Revision: D46653732

fbshipit-source-id: 0bc34bd5a819037c046c62b651e414b249cbdcb8
This commit is contained in:
Andrew Wang
2023-06-16 06:15:07 -07:00
committed by Facebook GitHub Bot
parent ca4cf852aa
commit f3e9b6bfb0
6 changed files with 24 additions and 5 deletions

View File

@@ -280,7 +280,8 @@ static void YGTransferLayoutOutputsRecursive(
JNIEnv* env,
jobject thiz,
YGNodeRef root,
void* layoutContext) {
void* layoutContext,
bool shouldCleanLocalRef) {
if (!YGNodeGetHasNewLayout(root)) {
return;
}
@@ -346,11 +347,16 @@ static void YGTransferLayoutOutputsRecursive(
env->SetFloatArrayRegion(arrFinal.get(), 0, arrSize, arr);
env->SetObjectField(obj.get(), arrField, arrFinal.get());
if (shouldCleanLocalRef) {
objectClass.reset();
arrFinal.reset();
}
YGNodeSetHasNewLayout(root, false);
for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) {
YGTransferLayoutOutputsRecursive(
env, thiz, YGNodeGetChild(root, i), layoutContext);
env, thiz, YGNodeGetChild(root, i), layoutContext, shouldCleanLocalRef);
}
}
@@ -372,13 +378,17 @@ static void jni_YGNodeCalculateLayoutJNI(
}
const YGNodeRef root = _jlong2YGNodeRef(nativePointer);
const bool shouldCleanLocalRef =
root->getConfig()->isExperimentalFeatureEnabled(
YGExperimentalFeatureFixJNILocalRefOverflows);
YGNodeCalculateLayoutWithContext(
root,
static_cast<float>(width),
static_cast<float>(height),
YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer)),
layoutContext);
YGTransferLayoutOutputsRecursive(env, obj, root, layoutContext);
YGTransferLayoutOutputsRecursive(
env, obj, root, layoutContext, shouldCleanLocalRef);
} catch (const YogaJniException& jniException) {
ScopedLocalRef<jthrowable> throwable = jniException.getThrowable();
if (throwable.get()) {