about summary refs log tree commit diff stats
path: root/src/local
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-03-12 18:20:21 +0100
committerbptato <nincsnevem662@gmail.com>2025-03-12 18:20:21 +0100
commit84b12b22dfc218f7f353ab51d1a3235ce6d8596b (patch)
tree39b4fe4c97ead5bf3dada23701a7bd83003abc77 /src/local
parent9424b6910b3944731857d9b014ac37aec392b9d5 (diff)
downloadchawan-84b12b22dfc218f7f353ab51d1a3235ce6d8596b.tar.gz
Re-add JSValueConst
This time, I've also ported over the consistency check to prevent some
ownership bugs.

Unfortunately, the check is very limited, and it is still possible to
double-free or leak JSValues.  I think it would be possible to make
coverage 100%, but only with ARC...
Diffstat (limited to 'src/local')
-rw-r--r--src/local/client.nim8
-rw-r--r--src/local/pager.nim23
2 files changed, 16 insertions, 15 deletions
diff --git a/src/local/client.nim b/src/local/client.nim
index d71fc7cf..e45d41f5 100644
--- a/src/local/client.nim
+++ b/src/local/client.nim
@@ -95,13 +95,13 @@ proc writeFile(ctx: JSContext; client: Client; path, content: string): JSValue
   return JS_UNDEFINED
 
 proc getenv(ctx: JSContext; client: Client; s: string;
-    fallback = JS_NULL): JSValue {.jsfunc.} =
+    fallback: JSValueConst = JS_NULL): JSValue {.jsfunc.} =
   if not existsEnv(s):
-    return fallback
+    return JS_DupValue(ctx, fallback)
   return ctx.toJS(getEnv(s))
 
-proc setenv(ctx: JSContext; client: Client; s: string; val: JSValue): JSValue
-    {.jsfunc.} =
+proc setenv(ctx: JSContext; client: Client; s: string; val: JSValueConst):
+    JSValue {.jsfunc.} =
   try:
     if JS_IsNull(val):
       delEnv(s)
diff --git a/src/local/pager.nim b/src/local/pager.nim
index 4139e337..3fe65ee5 100644
--- a/src/local/pager.nim
+++ b/src/local/pager.nim
@@ -283,9 +283,9 @@ proc setContainer(pager: Pager; c: Container) {.jsfunc.} =
     c.queueDraw()
     pager.term.setTitle(c.getTitle())
 
-proc reflect(ctx: JSContext; this_val: JSValue; argc: cint;
-    argv: ptr UncheckedArray[JSValue]; magic: cint;
-    func_data: ptr UncheckedArray[JSValue]): JSValue {.cdecl.} =
+proc reflect(ctx: JSContext; this_val: JSValueConst; argc: cint;
+    argv: JSValueConstArray; magic: cint; func_data: JSValueConstArray): JSValue
+    {.cdecl.} =
   let obj = func_data[0]
   let fun = func_data[1]
   return JS_Call(ctx, fun, obj, argc, argv)
@@ -391,8 +391,8 @@ proc isearchBackward(pager: Pager) {.jsfunc.} =
   pager.container.markPos0()
   pager.setLineEdit(lmISearchB)
 
-proc gotoLine(ctx: JSContext; pager: Pager; val = JS_UNDEFINED): Opt[void]
-    {.jsfunc.} =
+proc gotoLine(ctx: JSContext; pager: Pager; val: JSValueConst = JS_UNDEFINED):
+    Opt[void] {.jsfunc.} =
   var n: int
   if ctx.fromJS(val, n).isSome:
     pager.container.gotoLine(n)
@@ -1603,7 +1603,7 @@ template myExec(cmd: string) =
   discard execl("/bin/sh", "sh", "-c", cstring(cmd), nil)
   exitnow(127)
 
-proc setEnvVars(pager: Pager; env: JSValue) =
+proc setEnvVars(pager: Pager; env: JSValueConst) =
   try:
     if pager.container != nil and JS_IsUndefined(env):
       putEnv("CHA_URL", $pager.container.url)
@@ -1619,7 +1619,7 @@ proc setEnvVars(pager: Pager; env: JSValue) =
 # Run process (and suspend the terminal controller).
 # For the most part, this emulates system(3).
 proc runCommand(pager: Pager; cmd: string; suspend, wait: bool;
-    env: JSValue): bool =
+    env: JSValueConst): bool =
   if suspend:
     pager.term.quit()
   var oldint, oldquit, act: Sigaction
@@ -2278,8 +2278,8 @@ type GotoURLDict = object of JSDict
   save {.jsdefault.}: bool
   history {.jsdefault.}: bool
 
-proc jsGotoURL(pager: Pager; v: JSValue; t = GotoURLDict()): JSResult[Container]
-    {.jsfunc: "gotoURL".} =
+proc jsGotoURL(pager: Pager; v: JSValueConst; t = GotoURLDict()):
+    JSResult[Container] {.jsfunc: "gotoURL".} =
   var request: Request = nil
   var jsRequest: JSRequest = nil
   if pager.jsctx.fromJS(v, jsRequest).isSome:
@@ -2303,7 +2303,7 @@ proc reload(pager: Pager) {.jsfunc.} =
   container.copyCursorPos(old)
 
 type ExternDict = object of JSDict
-  env {.jsdefault: JS_UNDEFINED.}: JSValue
+  env {.jsdefault: JS_UNDEFINED.}: JSValueConst
   suspend {.jsdefault: true.}: bool
   wait {.jsdefault: false.}: bool
 
@@ -2966,7 +2966,8 @@ if (replace.alive) {
 }
 """)
   let args = [ctx.toJS(url), ctx.toJS(container)]
-  discard pager.timeouts.setTimeout(ttTimeout, fun, int32(n), args)
+  discard pager.timeouts.setTimeout(ttTimeout, fun, int32(n),
+    cast[JSValueConstArray](unsafeAddr args[0]).toOpenArray(0, args.high))
   JS_FreeValue(ctx, fun)
   for arg in args:
     JS_FreeValue(ctx, arg)