about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-08-30 19:45:21 +0200
committerbptato <nincsnevem662@gmail.com>2023-08-30 19:45:21 +0200
commit8b78543eeb81aa40e1562bd702ccf38c6538547f (patch)
tree4a95de24d07a89eb097a92e89e93c1acd88d8a4e /src
parent47383328e1a861401fd52505642f98fa3524a895 (diff)
downloadchawan-8b78543eeb81aa40e1562bd702ccf38c6538547f.tar.gz
javascript: fix fromJSFunction, simplify setOpaque
* fromJSFunction: dup the value, so that it cannot go out of context.
* setOpaque no longer calls GC_ref, so no need for it to be generic
  instead of just taking a pointer.
Diffstat (limited to 'src')
-rw-r--r--src/js/fromjs.nim4
-rw-r--r--src/js/javascript.nim2
-rw-r--r--src/js/opaque.nim6
3 files changed, 7 insertions, 5 deletions
diff --git a/src/js/fromjs.nim b/src/js/fromjs.nim
index 9c356da0..c7e27110 100644
--- a/src/js/fromjs.nim
+++ b/src/js/fromjs.nim
@@ -267,12 +267,14 @@ proc fromJSTable[A, B](ctx: JSContext, val: JSValue): JSResult[Table[A, B]] =
 #TODO varargs
 proc fromJSFunction1*[T, U](ctx: JSContext, val: JSValue):
     proc(x: U): JSResult[T] =
+  let dupval = JS_DupValue(ctx, JS_DupValue(ctx, val)) # save
   return proc(x: U): JSResult[T] =
     var arg1 = toJS(ctx, x)
     #TODO exceptions?
-    let ret = JS_Call(ctx, val, JS_UNDEFINED, 1, addr arg1)
+    let ret = JS_Call(ctx, dupval, JS_UNDEFINED, 1, addr arg1)
     when T isnot void:
       result = fromJS[T](ctx, ret)
+    JS_FreeValue(ctx, dupval)
     JS_FreeValue(ctx, ret)
 
 proc isErrType(rt: NimNode): bool =
diff --git a/src/js/javascript.nim b/src/js/javascript.nim
index f7b50cfb..06d1a577 100644
--- a/src/js/javascript.nim
+++ b/src/js/javascript.nim
@@ -161,7 +161,7 @@ proc setGlobal*[T](ctx: JSContext, global: JSValue, obj: T) =
   let p = JS_VALUE_GET_PTR(global)
   let header = cast[ptr JSRefCountHeader](p)
   inc header.ref_count
-  ctx.setOpaque(global, obj)
+  ctx.setOpaque(global, cast[pointer](obj))
   GC_ref(obj)
 
 proc setInterruptHandler*(rt: JSRuntime, cb: JSInterruptHandler, opaque: pointer = nil) =
diff --git a/src/js/opaque.nim b/src/js/opaque.nim
index 8e6c2d5d..f132db24 100644
--- a/src/js/opaque.nim
+++ b/src/js/opaque.nim
@@ -79,12 +79,12 @@ func isGlobal*(ctx: JSContext, class: string): bool =
   assert class != ""
   return ctx.getOpaque().gclaz == class
 
-proc setOpaque*[T](ctx: JSContext, val: JSValue, opaque: T) =
+proc setOpaque*(ctx: JSContext, val: JSValue, opaque: pointer) =
   let rt = JS_GetRuntime(ctx)
   let rtOpaque = rt.getOpaque()
   let p = JS_VALUE_GET_PTR(val)
-  rtOpaque.plist[cast[pointer](opaque)] = p
-  JS_SetOpaque(val, cast[pointer](opaque))
+  rtOpaque.plist[opaque] = p
+  JS_SetOpaque(val, opaque)
 
 # getOpaque, but doesn't work for global objects.
 func getOpaque0*(val: JSValue): pointer =