about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/html/event.nim22
-rw-r--r--src/js/javascript.nim57
-rw-r--r--src/js/opaque.nim4
3 files changed, 47 insertions, 36 deletions
diff --git a/src/html/event.nim b/src/html/event.nim
index 6234f166..47195b82 100644
--- a/src/html/event.nim
+++ b/src/html/event.nim
@@ -38,7 +38,6 @@ type
     isTrusted {.jsufget.}: bool
 
   CustomEvent* = ref object of Event
-    ctx: JSContext #TODO get rid of this
     detail {.jsget.}: JSValue
 
   EventTarget* = ref object of RootObj
@@ -74,8 +73,7 @@ type
     detail: JSValue
 
 # Event
-proc innerEventCreationSteps(event: Event, ctx: JSContext,
-    eventInitDict: EventInit) =
+proc innerEventCreationSteps(event: Event, eventInitDict: EventInit) =
   event.flags = {FLAG_INITIALIZED}
   #TODO this is probably incorrect?
   # I think it measures the time since the first fork. not sure though
@@ -86,10 +84,10 @@ proc innerEventCreationSteps(event: Event, ctx: JSContext,
     event.flags.incl(FLAG_COMPOSED)
 
 #TODO eventInitDict type
-proc newEvent(ctx: JSContext, ctype: string, eventInitDict = EventInit()):
+proc newEvent(ctype: string, eventInitDict = EventInit()):
     JSResult[Event] {.jsctor.} =
   let event = Event()
-  event.innerEventCreationSteps(ctx, eventInitDict)
+  event.innerEventCreationSteps(eventInitDict)
   event.ctype = ctype
   return ok(event)
 
@@ -156,23 +154,21 @@ func composed(this: Event): bool {.jsfget.} =
   return FLAG_COMPOSED in this.flags
 
 # CustomEvent
-proc newCustomEvent(ctx: JSContext, ctype: string,
-    eventInitDict = CustomEventInit()): JSResult[CustomEvent] {.jsctor.} =
+proc newCustomEvent(ctype: string, eventInitDict = CustomEventInit()):
+    JSResult[CustomEvent] {.jsctor.} =
   let event = CustomEvent()
-  event.innerEventCreationSteps(ctx, eventInitDict)
+  event.innerEventCreationSteps(eventInitDict)
   event.detail = eventInitDict.detail
-  event.ctx = ctx
   event.ctype = ctype
   return ok(event)
 
-proc finalize(this: CustomEvent) {.jsfin.} =
-  JS_FreeValue(this.ctx, this.detail)
+proc finalize(rt: JSRuntime, this: CustomEvent) {.jsfin.} =
+  JS_FreeValueRT(rt, this.detail)
 
-proc initCustomEvent(ctx: JSContext, this: CustomEvent, ctype: string,
+proc initCustomEvent(this: CustomEvent, ctype: string,
     bubbles, cancelable: bool, detail: JSValue) {.jsfunc.} =
   if FLAG_DISPATCH notin this.flags:
     this.initialize(ctype, bubbles, cancelable)
-    this.ctx = ctx
     this.detail = detail
 
 # EventTarget
diff --git a/src/js/javascript.nim b/src/js/javascript.nim
index fd0bb818..8f7f445c 100644
--- a/src/js/javascript.nim
+++ b/src/js/javascript.nim
@@ -208,7 +208,7 @@ proc addClassUnforgeable(ctx: JSContext, proto: JSValue,
 
 func newJSClass*(ctx: JSContext, cdef: JSClassDefConst, tname: string,
     nimt: pointer, ctor: JSCFunction, funcs: JSFunctionList, parent: JSClassID,
-    asglobal: bool, nointerface: bool, finalizer: proc(val: JSValue),
+    asglobal: bool, nointerface: bool, finalizer: JSFinalizerFunction,
     namespace: JSValue, errid: Opt[JSErrorEnum],
     unforgeable, staticfuns: JSFunctionList,
     ishtmldda: bool): JSClassID {.discardable.} =
@@ -318,6 +318,7 @@ type
     funcParams: seq[FuncParam]
     passCtx: bool
     thisType: string
+    thisTypeNode: NimNode
     returnType: Option[NimNode]
     newName: NimNode
     newBranchList: seq[NimNode]
@@ -808,24 +809,30 @@ func getErrVal(t: BoundFunctionType): NimNode =
   return quote do: JS_EXCEPTION
 
 proc addJSContext(gen: var JSFuncGenerator) =
-  if gen.funcParams.len > gen.i and
-      gen.funcParams[gen.i].t.eqIdent(ident("JSContext")):
-    gen.passCtx = true
-    gen.jsFunCall.add(ident("ctx"))
-    inc gen.i
+  if gen.funcParams.len > gen.i:
+    if gen.funcParams[gen.i].t.eqIdent(ident("JSContext")):
+      gen.passCtx = true
+      gen.jsFunCall.add(ident("ctx"))
+      inc gen.i
+    elif gen.funcParams[gen.i].t.eqIdent(ident("JSRuntime")):
+      inc gen.i # special case for finalizers that have a JSRuntime param
 
 proc addThisName(gen: var JSFuncGenerator, thisname: Option[string]) =
   if thisname.isSome:
+    gen.thisTypeNode = gen.funcParams[gen.i][1]
     gen.thisType = $gen.funcParams[gen.i][1]
     gen.newName = ident($gen.t & "_" & gen.thisType & "_" & gen.funcName)
   else:
     let rt = gen.returnType.get
     if rt.kind in {nnkRefTy, nnkPtrTy}:
+      gen.thisTypeNode = rt[0]
       gen.thisType = rt[0].strVal
     else:
       if rt.kind == nnkBracketExpr:
+        gen.thisTypeNode = rt[1]
         gen.thisType = rt[1].strVal
       else:
+        gen.thisTypeNode = rt
         gen.thisType = rt.strVal
     gen.newName = ident($gen.t & "_" & gen.funcName)
 
@@ -1112,8 +1119,27 @@ template jsstfunc*(name: static string, fun: typed) =
 
 macro jsfin*(fun: typed) =
   var gen = setupGenerator(fun, FINALIZER, thisname = some("fin"))
-  registerFunction(gen.thisType, FINALIZER, gen.funcName, gen.newName)
-  fun
+  let finName = gen.newName
+  let finFun = ident(gen.funcName)
+  let t = gen.thisTypeNode
+  if gen.minArgs == 1:
+    let jsProc = quote do:
+      proc `finName`(rt: JSRuntime, val: JSValue) =
+        let opaque = JS_GetOpaque(val, JS_GetClassID(val))
+        if opaque != nil:
+          `finFun`(cast[`t`](opaque))
+    gen.registerFunction()
+    result = newStmtList(fun, jsProc)
+  elif gen.minArgs == 2:
+    let jsProc = quote do:
+      proc `finName`(rt: JSRuntime, val: JSValue) =
+        let opaque = JS_GetOpaque(val, JS_GetClassID(val))
+        if opaque != nil:
+          `finFun`(rt, cast[`t`](opaque))
+    gen.registerFunction()
+    result = newStmtList(fun, jsProc)
+  else:
+    error("Expected one or two parameters")
 
 # Having the same names for these and the macros leads to weird bugs, so the
 # macros get an additional f.
@@ -1211,7 +1237,7 @@ proc nim_finalize_for_js*(obj: pointer) =
       let val = JS_MKPTR(JS_TAG_OBJECT, p)
       let classid = JS_GetClassID(val)
       rtOpaque.fins.withValue(classid, fin):
-        fin[](val)
+        fin[](rt, val)
       JS_SetOpaque(val, nil)
       rtOpaque.plist.del(obj)
       if rtOpaque.destroying == obj:
@@ -1433,18 +1459,6 @@ proc bindExtraGetSet(stmts: NimNode, info: var RegistryInfo,
     let m = x.magic
     info.tabList.add(quote do: JS_CGETSET_MAGIC_DEF(`k`, `g`, `s`, `m`))
 
-proc bindFinalizer(stmts: NimNode, info: RegistryInfo) =
-  if info.finFun.kind != nnkNilLit:
-    let t = info.t
-    let finFun = info.finFun
-    let finName = info.finName
-    stmts.add(quote do:
-      proc `finName`(val: JSValue) =
-        let opaque = JS_GetOpaque(val, JS_GetClassID(val))
-        if opaque != nil:
-          `finFun`(cast[`t`](opaque))
-    )
-
 proc bindCheckDestroy(stmts: NimNode, info: RegistryInfo) =
   let t = info.t
   let dfin = info.dfin
@@ -1554,7 +1568,6 @@ macro registerType*(ctx: typed, t: typed, parent: JSClassID = 0,
     # been passed to it at all.
     stmts.bindExtraGetSet(info, extra_getset)
   let sctr = stmts.bindConstructor(info)
-  stmts.bindFinalizer(info)
   stmts.bindCheckDestroy(info)
   let endstmts = newStmtList()
   endstmts.bindEndStmts(info)
diff --git a/src/js/opaque.nim b/src/js/opaque.nim
index 96b8fa55..b1035815 100644
--- a/src/js/opaque.nim
+++ b/src/js/opaque.nim
@@ -36,10 +36,12 @@ type
     err_ctors*: array[JSErrorEnum, JSValue]
     htmldda*: JSClassID # only one of these exists: document.all.
 
+  JSFinalizerFunction* = proc(rt: JSRuntime, val: JSValue) {.nimcall.}
+
   JSRuntimeOpaque* = ref object
     plist*: Table[pointer, pointer] # Nim, JS
     flist*: seq[seq[JSCFunctionListEntry]]
-    fins*: Table[JSClassID, proc(val: JSValue)]
+    fins*: Table[JSClassID, JSFinalizerFunction]
     refmap*: Table[pointer, tuple[cref, cunref: (proc() {.closure.})]]
     destroying*: pointer