diff options
author | bptato <nincsnevem662@gmail.com> | 2025-02-19 18:54:44 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2025-02-19 19:35:07 +0100 |
commit | 3f663454031657610bddceb169cd881754ec232a (patch) | |
tree | ae088232c3bdbe9f74cfaf19a5d9b99e0dfc8131 /lib/monoucha0 | |
parent | b65993b77789ddbde72f65db648ab993a5097121 (diff) | |
download | chawan-3f663454031657610bddceb169cd881754ec232a.tar.gz |
fromjs, javascript: optimize out class name registry
Instead of hashing the class name for isInstanceOf, we now just reuse the Nim type pointer -> JSClassID map, which should be more efficient. This removes getClass and hasClass; these can be replaced by just reusing the class ID returned from registerType.
Diffstat (limited to 'lib/monoucha0')
-rw-r--r-- | lib/monoucha0/monoucha/fromjs.nim | 27 | ||||
-rw-r--r-- | lib/monoucha0/monoucha/javascript.nim | 21 | ||||
-rw-r--r-- | lib/monoucha0/monoucha/jsopaque.nim | 1 |
3 files changed, 21 insertions, 28 deletions
diff --git a/lib/monoucha0/monoucha/fromjs.nim b/lib/monoucha0/monoucha/fromjs.nim index 7cf5db9a..ece36119 100644 --- a/lib/monoucha0/monoucha/fromjs.nim +++ b/lib/monoucha0/monoucha/fromjs.nim @@ -7,6 +7,7 @@ import jsopaque import jstypes import optshim import quickjs +import tojs proc fromJS*(ctx: JSContext; val: JSValue; res: out string): Opt[void] proc fromJS*(ctx: JSContext; val: JSValue; res: out int32): Opt[void] @@ -31,10 +32,9 @@ proc fromJS*(ctx: JSContext; val: JSValue; res: out JSArrayBufferView): Opt[void] proc fromJS*(ctx: JSContext; val: JSValue; res: out JSValue): Opt[void] -func isInstanceOf*(ctx: JSContext; val: JSValue; class: cstring): bool = +func isInstanceOf*(ctx: JSContext; val: JSValue; tclassid: JSClassID): bool = let ctxOpaque = ctx.getOpaque() var classid = JS_GetClassID(val) - let tclassid = ctxOpaque.creg.getOrDefault(class, JS_CLASS_OBJECT) if classid == JS_CLASS_OBJECT: let p0 = JS_VALUE_GET_PTR(ctxOpaque.global) let p1 = JS_VALUE_GET_PTR(val) @@ -328,7 +328,7 @@ proc fromJS*[T: enum](ctx: JSContext; val: JSValue; res: out T): Opt[void] = res = default(T) return err() -proc fromJS(ctx: JSContext; val: JSValue; t: cstring; res: out pointer): +proc fromJS(ctx: JSContext; val: JSValue; nimt: pointer; res: out pointer): Opt[void] = if not JS_IsObject(val): if not JS_IsException(val): @@ -336,25 +336,34 @@ proc fromJS(ctx: JSContext; val: JSValue; t: cstring; res: out pointer): res = nil return err() let p = JS_GetOpaque(val, JS_GetClassID(val)) - if p == nil or not ctx.isInstanceOf(val, t): - JS_ThrowTypeError(ctx, "%s expected", t) + let ctxOpaque = ctx.getOpaque() + let tclassid = ctxOpaque.typemap.getOrDefault(nimt, JS_CLASS_OBJECT) + if p == nil or not ctx.isInstanceOf(val, tclassid): res = nil + let proto = JS_GetClassProto(ctx, tclassid) + let name = JS_GetProperty(ctx, proto, ctxOpaque.symRefs[jsyToStringTag]) + JS_FreeValue(ctx, proto) + defer: JS_FreeValue(ctx, name) + var s: string + if ctx.fromJS(name, s).isNone: + return err() + JS_ThrowTypeError(ctx, "%s expected", cstring(s)) return err() res = p return ok() proc fromJS*[T](ctx: JSContext; val: JSValue; res: out ptr T): Opt[void] = + let nimt = getTypePtr(T) var x: pointer - const tname = cstring($T) - ?ctx.fromJS(val, tname, x) + ?ctx.fromJS(val, nimt, x) res = cast[ptr T](x) return ok() proc fromJS*[T: ref object](ctx: JSContext; val: JSValue; res: out T): Opt[void] = + let nimt = getTypePtr(T) var x: pointer - const tname = cstring($T) - ?ctx.fromJS(val, tname, x) + ?ctx.fromJS(val, nimt, x) res = cast[T](x) return ok() diff --git a/lib/monoucha0/monoucha/javascript.nim b/lib/monoucha0/monoucha/javascript.nim index 75b1548a..1f921d5d 100644 --- a/lib/monoucha0/monoucha/javascript.nim +++ b/lib/monoucha0/monoucha/javascript.nim @@ -191,19 +191,6 @@ proc newJSContext*(rt: JSRuntime): JSContext = JS_SetContextOpaque(ctx, cast[pointer](opaque)) return ctx -func getClass*(ctx: JSContext; class: cstring): JSClassID = - ## Get the class ID of the registered class `class'. - ## Note: this uses the Nim type's name, **not** the JS type's name. - try: - return ctx.getOpaque().creg[class] - except KeyError: - raise newException(Defect, "Class does not exist") - -func hasClass*(ctx: JSContext; class: cstring): bool = - ## Check if `class' is registered. - ## Note: this uses the Nim type's name, **not** the JS type's name. - return class in ctx.getOpaque().creg - proc free*(ctx: JSContext) = ## Free the JSContext and associated resources. ## Note: this is not an alias of `JS_FreeContext`; `free` also frees various @@ -311,8 +298,8 @@ proc newCtorFunFromParentClass(ctx: JSContext; ctor: JSCFunction; 0, ctx.getOpaque().ctors[parent]) return JS_NewCFunction2(ctx, ctor, className, 0, JS_CFUNC_constructor, 0) -func newJSClass*(ctx: JSContext; cdef: JSClassDefConst; tname: cstring; - nimt: pointer; ctor: JSCFunction; funcs: JSFunctionList; parent: JSClassID; +func newJSClass*(ctx: JSContext; cdef: JSClassDefConst; nimt: pointer; + ctor: JSCFunction; funcs: JSFunctionList; parent: JSClassID; asglobal, nointerface, ishtmldda: bool; finalizer: JSFinalizerFunction; namespace: JSValue; errid: Opt[JSErrorEnum]; unforgeable, staticfuns: JSFunctionList): JSClassID @@ -327,7 +314,6 @@ func newJSClass*(ctx: JSContext; cdef: JSClassDefConst; tname: cstring; $cdef.class_name) ctxOpaque.typemap[nimt] = result rtOpaque.inverseTypemap[result] = nimt - ctxOpaque.creg[tname] = result if ctxOpaque.parents.len <= int(result): ctxOpaque.parents.setLen(int(result) + 1) ctxOpaque.parents[result] = parent @@ -1509,12 +1495,11 @@ macro registerType*(ctx: JSContext; t: typed; parent: JSClassID = 0; endstmts.bindEndStmts(info) let tabList = info.tabList let finName = info.finName - let tname = info.tname let unforgeable = info.tabUnforgeable let staticfuns = info.tabStatic let global = asglobal and not globalparent endstmts.add(quote do: - `ctx`.newJSClass(classDef, `tname`, getTypePtr(`t`), `sctr`, `tabList`, + `ctx`.newJSClass(classDef, getTypePtr(`t`), `sctr`, `tabList`, `parent`, `global`, `nointerface`, `ishtmldda`, `finName`, `namespace`, `errid`, `unforgeable`, `staticfuns`) ) diff --git a/lib/monoucha0/monoucha/jsopaque.nim b/lib/monoucha0/monoucha/jsopaque.nim index 7b90329a..e7920ea2 100644 --- a/lib/monoucha0/monoucha/jsopaque.nim +++ b/lib/monoucha0/monoucha/jsopaque.nim @@ -27,7 +27,6 @@ type jsvFunction = "Function" JSContextOpaque* = ref object - creg*: Table[cstring, JSClassID] typemap*: Table[pointer, JSClassID] ctors*: seq[JSValue] # JSClassID -> JSValue parents*: seq[JSClassID] # JSClassID -> JSClassID |