Skip to content

Commit 6cb357e

Browse files
Free RustCallStatus pointer after every Rust call (#38)
The call-status pointer allocated by createPointer in makeRustCall was never released. ffi-rs's createPointer Box-allocates non-StackStruct values via Box::into_raw(Box::new(generate_c_struct(...))), and the JsExternal wrapper does not free that memory on garbage collection per ffi-rs's documented contract. Neither restorePointer nor unwrapPointer free anything either. Result: every synchronous Rust call leaked the RustCallStatus struct plus its wrapper Box, and method calls leaked twice (once for clonePointer, once for the call itself). Wrap the call site in try/finally and call freePointer with the same struct paramsType so the allocation is reclaimed regardless of whether the call returned normally or threw.
1 parent 31ed6eb commit 6cb357e

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

templates/sys.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,23 @@ class UniffiFfiRsRustCaller {
195195
_checkUniffiLoaded();
196196

197197
const $callStatus = this.createCallStatus();
198-
let returnedVal = caller(unwrapPointer($callStatus)[0]);
198+
try {
199+
let returnedVal = caller(unwrapPointer($callStatus)[0]);
199200

200-
const [callStatus] = restorePointer({
201-
retType: [DataType_UniffiRustCallStatus],
202-
paramsValue: $callStatus,
203-
});
204-
uniffiCheckCallStatus(callStatus, liftString, liftError);
201+
const [callStatus] = restorePointer({
202+
retType: [DataType_UniffiRustCallStatus],
203+
paramsValue: $callStatus,
204+
});
205+
uniffiCheckCallStatus(callStatus, liftString, liftError);
205206

206-
return returnedVal;
207+
return returnedVal;
208+
} finally {
209+
freePointer({
210+
paramsType: [DataType_UniffiRustCallStatus],
211+
paramsValue: $callStatus,
212+
pointerType: PointerType.RsPointer,
213+
});
214+
}
207215
}
208216
}
209217

0 commit comments

Comments
 (0)