diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/html/event.nim | 22 | ||||
-rw-r--r-- | src/js/javascript.nim | 57 | ||||
-rw-r--r-- | src/js/opaque.nim | 4 |
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 |