Skip to content

Commit f013ddb

Browse files
committed
fix: not correctly released when an exception occurs during function execution
1 parent d04394f commit f013ddb

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

native/cpp/quickjs_wrapper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ jobject QuickJSWrapper::call(JNIEnv *env, jobject thiz, jlong func, jlong this_o
551551

552552
JSValue ret = JS_Call(context, jsFunc, jsObj, arguments.size(), arguments.data());
553553
if (JS_IsException(ret)) {
554+
JS_FreeValue(context, ret);
554555
throwJSException(env, context);
555556
return nullptr;
556557
}

wrapper-android/src/androidTest/java/com/whl/quickjs/wrapper/QuickJSTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,4 +1331,26 @@ public void testArraySameRefToMap() {
13311331
}
13321332
}
13331333

1334+
@Test
1335+
public void testCallThrowError() {
1336+
QuickJSContext context = createContext();
1337+
JSFunction function = null;
1338+
try {
1339+
function = (JSFunction) context.evaluate("function testThrowError() {\n" +
1340+
"\tthrow new Error(\"test\");\n" +
1341+
"}\n" +
1342+
"\n" +
1343+
"testThrowError;");
1344+
function.call();
1345+
} catch (Exception e) {
1346+
if (function != null) {
1347+
// 测试
1348+
function.release();
1349+
}
1350+
int defaultLength = 1;
1351+
assertEquals(defaultLength, context.getObjectRecords().size());
1352+
context.destroy();
1353+
}
1354+
}
1355+
13341356
}

wrapper-java/src/main/java/com/whl/quickjs/wrapper/QuickJSFunction.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,22 @@ public Object call(Object... args) {
4444
checkRefCountIsZero();
4545

4646
currentStatus = Status.CALLING;
47-
Object ret = getContext().call(this, thisPointer, thisPointerTag, args);
48-
currentStatus = Status.CALLED;
47+
Object ret;
48+
try {
49+
ret = getContext().call(this, thisPointer, thisPointerTag, args);
50+
} finally {
51+
// call 可能会抛出异常,需要保障以下代码被执行,不然因为状态不对,导致无法正常 release。
52+
currentStatus = Status.CALLED;
4953

50-
if (stashTimes > 0) {
51-
// 如果有暂存,这里需要恢复下 release 操作
52-
for (int i = 0; i < stashTimes; i++) {
53-
release();
54+
if (stashTimes > 0) {
55+
// 如果有暂存,这里需要恢复下 release 操作
56+
for (int i = 0; i < stashTimes; i++) {
57+
release();
58+
}
59+
stashTimes = 0;
5460
}
55-
stashTimes = 0;
5661
}
62+
5763
return ret;
5864
}
5965

0 commit comments

Comments
 (0)