diff options
author | bptato <nincsnevem662@gmail.com> | 2024-06-03 20:28:29 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-06-03 20:28:29 +0200 |
commit | dfb03387691e72f8832734255765ddfdd38db372 (patch) | |
tree | 31f2c489859aa8bd7d7bc2b3b1854f11708b45f2 /src/bindings | |
parent | 34b0abd1a5811afa88b16442c0dc327881456d8f (diff) | |
download | chawan-dfb03387691e72f8832734255765ddfdd38db372.tar.gz |
js: fix runtime cleanup
This is a minefield. Intuitively, you would think that just clearing the opaque and manually freeing registered object should be enough. Unfortunately, this is not true; we do not store whether we are actually holding a reference to registered JS objects, so this approach leads to double frees. Instead, we add a QJS callback that is called right after the final GC cleanup, but before the list_free assertion. This way, we can be sure that any object still in our registry is referenced by us, and can therefore unreference them safely.
Diffstat (limited to 'src/bindings')
-rw-r--r-- | src/bindings/quickjs.nim | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/src/bindings/quickjs.nim b/src/bindings/quickjs.nim index 836bedac..20dd048b 100644 --- a/src/bindings/quickjs.nim +++ b/src/bindings/quickjs.nim @@ -132,6 +132,8 @@ type JSClassExoticMethodsConst* {.importc: "const JSClassExoticMethods *", header: qjsheader.} = ptr JSClassExoticMethods + JSRuntimeCleanUpFunc* {.importc.} = proc(rt: JSRuntime) {.cdecl.} + JSClassDef* {.importc, header: qjsheader.} = object class_name*: cstring finalizer*: JSClassFinalizer @@ -555,6 +557,8 @@ proc JS_ExecutePendingJob*(rt: JSRuntime; pctx: ptr JSContext): cint proc JS_GetRuntimeOpaque*(rt: JSRuntime): pointer proc JS_SetRuntimeOpaque*(rt: JSRuntime; p: pointer) +proc JS_SetRuntimeCleanUpFunc*(rt: JSRuntime; + cleanup_func: JSRuntimeCleanUpFunc) proc JS_SetContextOpaque*(ctx: JSContext; opaque: pointer) proc JS_GetContextOpaque*(ctx: JSContext): pointer |