Skip to content

Commit

Permalink
Add implementation/test for GlobalString destruction.
Browse files Browse the repository at this point in the history
This was actually causing premature releases of `GlobalString` when directly constructed with arguments because it wasn't promoting its `LocalObject` after construction.

Also, add tests for graceful destruction of GlobalObject which isn't returned.

PiperOrigin-RevId: 674475063
  • Loading branch information
jwhpryor authored and copybara-github committed Sep 13, 2024
1 parent 690a918 commit 954558c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 3 deletions.
6 changes: 6 additions & 0 deletions implementation/global_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ class GlobalString : public GlobalStringImpl {
GlobalString(LocalString &&local_string)
: Base(LifecycleT::Promote(local_string.Release())) {}

template <typename... Ts>
GlobalString(Ts &&...vals) : Base(std::forward<Ts &&>(vals)...) {
RefBase<jstring>::object_ref_ =
LifecycleT::Promote(RefBase<jstring>::object_ref_);
}

// Returns a StringView which possibly performs an expensive pinning
// operation. String objects can be pinned multiple times.
UtfStringView Pin() { return {RefBase<jstring>::object_ref_}; }
Expand Down
9 changes: 7 additions & 2 deletions javatests/com/jnibind/test/GlobalObjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ public static void doShutDown() {
jniTearDown();
}

static native void jniObjectGracefullyDies();

@Test
public void objectGracefullyDies() {
jniObjectGracefullyDies();
}

@Test
public void createNewGlobalObjectUsingNoArgConstructor() {
assertThat(jniCreateNewObject()).isNotEqualTo(null);
Expand Down Expand Up @@ -87,7 +94,6 @@ public void createFromCopyAssignmentIntoGlobal() {
native ObjectTestHelper jniBuildNewObjectsFromExistingObjects(
GlobalObjectTest testHelperObject, ObjectTestHelper objectToMutate);


ObjectTestHelper methodTakesGlobalObjectReturnsNewObject(ObjectTestHelper object) {
return new ObjectTestHelper(object.intVal1 + 5, object.intVal2 + 6, object.intVal3 + 7);
}
Expand Down Expand Up @@ -136,5 +142,4 @@ public void materializeNewGlobalObjectSetIntVal159() {
assertThat(object.intVal2).isEqualTo(11);
assertThat(object.intVal3).isEqualTo(16);
}

}
8 changes: 7 additions & 1 deletion javatests/com/jnibind/test/StringTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ public void multiFormPassTest() {
native void jniVoidMethodTakesFiveStrings(
StringTestHelper helper, String s1, String s2, String s3, String s4, String s5);


// Calls each of the above native methods which will then call the similarly named method on the
// StringTestHelper. E.g. jniVoidMethodTakesString calls voidMethodTakesString.
@Test
Expand Down Expand Up @@ -140,4 +139,11 @@ public void nullStringTests() {
verify(rJniStringTestHelper).stringMethodTakesString(null);
}
*/

native void jniReturnsAGlobalString();

@Test
public void globalReturnsCorrectlyOverJniBoundary() {
jniReturnsAGlobalString();
}
}
6 changes: 6 additions & 0 deletions javatests/com/jnibind/test/global_object_test_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ Java_com_jnibind_test_GlobalObjectTest_jniCreateNewObject(JNIEnv* env, jclass) {
return jni::GlobalObject<kObjectTestHelperClass>{1, 2, 3}.Release();
}

JNIEXPORT void JNICALL
Java_com_jnibind_test_GlobalObjectTest_jniObjectGracefullyDies(JNIEnv* env,
jclass) {
jni::GlobalObject<kObjectTestHelperClass>{1, 2, 3};
}

JNIEXPORT jobject JNICALL
Java_com_jnibind_test_GlobalObjectTest_jniCreateNewGlobalObjectSetIntVal123(
JNIEnv* env, jclass) {
Expand Down
5 changes: 5 additions & 0 deletions javatests/com/jnibind/test/string_test_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,9 @@ Java_com_jnibind_test_StringTest_jniStringMethodTakesFiveStrings(
.Release();
}

JNIEXPORT void JNICALL
Java_com_jnibind_test_StringTest_jniReturnsAGlobalString(JNIEnv* env, jclass) {
GlobalString g{"fake"};
}

} // extern "C"

0 comments on commit 954558c

Please sign in to comment.