diff options
author | bptato <nincsnevem662@gmail.com> | 2024-05-03 01:41:38 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-05-03 01:58:12 +0200 |
commit | 970378356d0d7239b332baa37470455391b5e6e4 (patch) | |
tree | 87d93162295b12652137193982c5b3c88e1a3758 /src/config | |
parent | c48f2caedabbcda03724c43935f4175aac3ecf90 (diff) | |
download | chawan-970378356d0d7239b332baa37470455391b5e6e4.tar.gz |
js: fix various leaks etc.
Previously we didn't actually free the main JS runtime, probably because you can't do this without first waiting for JS to unwind the stack. (This has the unfortunate effect that code now *can* run after quit(). TODO: find a fix for this.) This isn't a huge problem per se, we only have one of these and the OS can clean it up. However, it also disabled the JS_FreeRuntime leak check, which resulted in sieve-like behavior (manual refcounting is a pain). So now we choose the other tradeoff: quit no longer runs exitnow, but it waits for the event loop to run to the end and only then exits the browser. Then, before exit we free the JS context & runtime, and also all JS values allocated by config. Fixes: * fix `ad' flag not being set for just one siteconf/omnirule * fix various leaks (since leak check is enabled now) * use ptr UncheckedArray[JSValue] for QJS bindings that take an array * allow JSAtom in jsgetprop etc., also disallow int types other than uint32 * do not set a destructor for globals
Diffstat (limited to 'src/config')
-rw-r--r-- | src/config/config.nim | 9 | ||||
-rw-r--r-- | src/config/toml.nim | 3 |
2 files changed, 7 insertions, 5 deletions
diff --git a/src/config/config.nim b/src/config/config.nim index 56c448d7..b38d3129 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -131,6 +131,7 @@ type Config* = ref object jsctx: JSContext + jsvfns*: seq[JSValueFunction] configdir {.jsget.}: string `include` {.jsget.}: seq[ChaPathResolved] start* {.jsget.}: StartConfig @@ -363,7 +364,7 @@ proc parseConfigValue(ctx: var ConfigParser; x: var object; v: TomlValue; k: string) = typeCheck(v, tvtTable, k) for fk, fv in x.fieldPairs: - when typeof(fv) isnot JSContext: + when typeof(fv) isnot JSContext|seq[JSValueFunction]: let kebabk = snakeToKebabCase(fk) if kebabk in v: let kkk = if k != "": @@ -597,6 +598,7 @@ proc parseConfigValue(ctx: var ConfigParser; x: var JSValueFunction; if not JS_IsFunction(ctx.config.jsctx, fun): raise newException(ValueError, k & " is not a function") x = JSValueFunction(fun: fun) + ctx.config.jsvfns.add(x) # so we can clean it up on exit proc parseConfigValue(ctx: var ConfigParser; x: var ChaPathResolved; v: TomlValue; k: string) = @@ -667,8 +669,7 @@ proc parseConfigValue(ctx: var ConfigParser; x: var CommandConfig; v: TomlValue; if vv.t == tvtTable: ctx.parseConfigValue(x, vv, kkk) else: # tvtString - # skip initial "cmd.", we don't need it - x.init.add((kkk.substr("cmd.".len), vv.s)) + x.init.add((kkk, vv.s)) type ParseConfigResult* = object success*: bool @@ -797,9 +798,11 @@ proc initCommands*(config: Config): Err[string] = if JS_IsException(fun): return err(ctx.getExceptionMsg()) if not JS_IsFunction(ctx, fun): + JS_FreeValue(ctx, fun) return err(k & " is not a function") ctx.definePropertyE(objIt, name, JS_DupValue(ctx, fun)) config.cmd.map[k] = fun + JS_FreeValue(ctx, objIt) config.cmd.jsObj = JS_DupValue(ctx, obj) config.cmd.init = @[] ok() diff --git a/src/config/toml.nim b/src/config/toml.nim index f8ab9a08..992a0cbc 100644 --- a/src/config/toml.nim +++ b/src/config/toml.nim @@ -369,12 +369,11 @@ proc consumeNoState(state: var TomlParser): Result[bool, TomlError] = let key = table.key.join('.') return state.err("re-definition of node " & key & " as table array (was " & $last.t & ")") - last.ad = true let val = TomlValue(t: tvtTable, tab: table) last.a.add(val) else: let val = TomlValue(t: tvtTable, tab: table) - let last = TomlValue(t: tvtArray, a: @[val]) + let last = TomlValue(t: tvtArray, a: @[val], ad: true) node.map[table.key[^1]] = last state.currkey = table.key state.node = table |