diff options
-rw-r--r-- | lib/monoucha0/monoucha/javascript.nim | 16 | ||||
-rw-r--r-- | lib/monoucha0/monoucha/tojs.nim | 90 | ||||
-rw-r--r-- | src/config/config.nim | 8 | ||||
-rw-r--r-- | src/html/dom.nim | 48 | ||||
-rw-r--r-- | src/html/jsintl.nim | 2 | ||||
-rw-r--r-- | src/html/script.nim | 9 | ||||
-rw-r--r-- | src/local/client.nim | 4 |
7 files changed, 115 insertions, 62 deletions
diff --git a/lib/monoucha0/monoucha/javascript.nim b/lib/monoucha0/monoucha/javascript.nim index 2a811ce6..14cd95eb 100644 --- a/lib/monoucha0/monoucha/javascript.nim +++ b/lib/monoucha0/monoucha/javascript.nim @@ -332,19 +332,19 @@ func newJSClass*(ctx: JSContext; cdef: JSClassDefConst; nimt: pointer; if cdef.exotic != nil and cdef.exotic.get_own_property != nil: let val = JS_DupValue(ctx, ctxOpaque.valRefs[jsvArrayPrototypeValues]) let itSym = ctxOpaque.symRefs[jsyIterator] - ctx.defineProperty(proto, itSym, val) + doAssert ctx.defineProperty(proto, itSym, val) == dprSuccess let news = JS_NewAtomString(ctx, cdef.class_name) doAssert not JS_IsException(news) - ctx.definePropertyC(proto, ctxOpaque.symRefs[jsyToStringTag], - JS_DupValue(ctx, news)) + doAssert ctx.definePropertyC(proto, ctxOpaque.symRefs[jsyToStringTag], + JS_DupValue(ctx, news)) == dprSuccess JS_SetClassProto(ctx, result, proto) ctx.addClassUnforgeable(proto, result, parent, unforgeable) if asglobal: let global = ctxOpaque.global assert ctxOpaque.gclass == 0 ctxOpaque.gclass = result - ctx.definePropertyC(global, ctxOpaque.symRefs[jsyToStringTag], - JS_DupValue(ctx, news)) + doAssert ctx.definePropertyC(global, ctxOpaque.symRefs[jsyToStringTag], + JS_DupValue(ctx, news)) == dprSuccess if JS_SetPrototype(ctx, global, proto) != 1: raise newException(Defect, "Failed to set global prototype: " & $cdef.class_name) @@ -370,9 +370,11 @@ func newJSClass*(ctx: JSContext; cdef: JSClassDefConst; nimt: pointer; ctxOpaque.ctors[result] = JS_DupValue(ctx, jctor) if not nointerface: if JS_IsNull(namespace): - ctx.definePropertyCW(ctxOpaque.global, $cdef.class_name, jctor) + doAssert ctx.definePropertyCW(ctxOpaque.global, $cdef.class_name, + jctor) == dprSuccess else: - ctx.definePropertyCW(namespace, $cdef.class_name, jctor) + doAssert ctx.definePropertyCW(namespace, $cdef.class_name, + jctor) == dprSuccess else: JS_FreeValue(ctx, jctor) diff --git a/lib/monoucha0/monoucha/tojs.nim b/lib/monoucha0/monoucha/tojs.nim index 526b41fb..4ced6947 100644 --- a/lib/monoucha0/monoucha/tojs.nim +++ b/lib/monoucha0/monoucha/tojs.nim @@ -98,59 +98,66 @@ makeToJSP(Result) makeToJSP(JSValue) makeToJSP(JSDict) +type DefinePropertyResult* = enum + dprException, dprSuccess, dprFail + # Note: this consumes `prop'. proc defineProperty*(ctx: JSContext; this: JSValue; name: JSAtom; - prop: JSValue; flags = cint(0)) = - if JS_DefinePropertyValue(ctx, this, name, prop, flags) <= 0: - raise newException(Defect, "Failed to define property string") + prop: JSValue; flags = cint(0)): DefinePropertyResult = + return case JS_DefinePropertyValue(ctx, this, name, prop, flags) + of 0: dprFail + of 1: dprSuccess + else: dprException # Note: this consumes `prop'. proc defineProperty(ctx: JSContext; this: JSValue; name: int64; - prop: JSValue; flags = cint(0)) = + prop: JSValue; flags = cint(0)): DefinePropertyResult = let name = JS_NewInt64(ctx, name) let atom = JS_ValueToAtom(ctx, name) JS_FreeValue(ctx, name) if unlikely(atom == JS_ATOM_NULL): - raise newException(Defect, "Failed to define property string") - ctx.defineProperty(this, atom, prop, flags) + return dprException + result = ctx.defineProperty(this, atom, prop, flags) JS_FreeAtom(ctx, atom) proc definePropertyC*(ctx: JSContext; this: JSValue; name: JSAtom; - prop: JSValue) = + prop: JSValue): DefinePropertyResult = ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE) proc defineProperty(ctx: JSContext; this: JSValue; name: string; - prop: JSValue; flags = cint(0)) = - if JS_DefinePropertyValueStr(ctx, this, cstring(name), prop, flags) <= 0: - raise newException(Defect, "Failed to define property string: " & name) + prop: JSValue; flags = cint(0)): DefinePropertyResult = + return case JS_DefinePropertyValueStr(ctx, this, cstring(name), prop, flags) + of 0: dprFail + of 1: dprSuccess + else: dprException proc definePropertyC*(ctx: JSContext; this: JSValue; name: string; - prop: JSValue) = + prop: JSValue): DefinePropertyResult = ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE) proc defineProperty*[T](ctx: JSContext; this: JSValue; name: string; prop: T; - flags = cint(0)) = - defineProperty(ctx, this, name, toJS(ctx, prop), flags) + flags = cint(0)): DefinePropertyResult = + ctx.defineProperty(this, name, ctx.toJS(prop), flags) proc definePropertyE*[T](ctx: JSContext; this: JSValue; name: string; - prop: T) = - defineProperty(ctx, this, name, prop, JS_PROP_ENUMERABLE) + prop: T): DefinePropertyResult = + ctx.defineProperty(this, name, prop, JS_PROP_ENUMERABLE) proc definePropertyCW*[T](ctx: JSContext; this: JSValue; name: string; - prop: T) = - defineProperty(ctx, this, name, prop, JS_PROP_CONFIGURABLE or + prop: T): DefinePropertyResult = + ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE or JS_PROP_WRITABLE) proc definePropertyCWE*[T](ctx: JSContext; this: JSValue; name: string; - prop: T) = - defineProperty(ctx, this, name, prop, JS_PROP_C_W_E) + prop: T): DefinePropertyResult = + ctx.defineProperty(this, name, prop, JS_PROP_C_W_E) proc newFunction*(ctx: JSContext; args: openArray[string]; body: string): JSValue = var paramList: seq[JSValue] = @[] for arg in args: - paramList.add(toJS(ctx, arg)) - paramList.add(toJS(ctx, body)) + paramList.add(ctx.toJS(arg)) + paramList.add(ctx.toJS(body)) let fun = JS_CallConstructor(ctx, ctx.getOpaque().valRefs[jsvFunction], cint(paramList.len), paramList.toJSValueArray()) for param in paramList: @@ -171,9 +178,9 @@ proc toJS*(ctx: JSContext; n: int64): JSValue = proc toJS*(ctx: JSContext; n: int): JSValue = when sizeof(int) > 4: - return toJS(ctx, int64(n)) + return ctx.toJS(int64(n)) else: - return toJS(ctx, int32(n)) + return ctx.toJS(int32(n)) proc toJS*(ctx: JSContext; n: uint16): JSValue = return JS_NewUint32(ctx, uint32(n)) @@ -195,12 +202,16 @@ proc toJS*[U, V](ctx: JSContext; t: Table[U, V]): JSValue = let obj = JS_NewObject(ctx) if not JS_IsException(obj): for k, v in t: - definePropertyCWE(ctx, obj, k, v) + case ctx.definePropertyCWE(obj, k, v) + of dprException: + JS_FreeValue(ctx, obj) + return JS_EXCEPTION + else: discard return obj proc toJS*(ctx: JSContext; opt: Option): JSValue = if opt.isSome: - return toJS(ctx, opt.get) + return ctx.toJS(opt.get) return JS_NULL proc toJS*[T, E](ctx: JSContext; opt: Result[T, E]): JSValue = @@ -222,17 +233,26 @@ proc toJS*(ctx: JSContext; s: seq): JSValue = let val = toJS(ctx, s[i]) if JS_IsException(val): return val - ctx.defineProperty(a, int64(i), val, JS_PROP_C_W_E or JS_PROP_THROW) + case ctx.defineProperty(a, int64(i), val, JS_PROP_C_W_E or JS_PROP_THROW) + of dprException: return JS_EXCEPTION + else: discard return a proc toJS*[T](ctx: JSContext; s: set[T]): JSValue = - #TODO this is a bit lazy :p - var x = newSeq[T]() - for e in s: - x.add(e) - var a = toJS(ctx, x) + let a = JS_NewArray(ctx) if JS_IsException(a): return a + var i = 0i64 + for e in s: + let val = ctx.toJS(e) + if JS_IsException(val): + return val + case ctx.defineProperty(a, i, val, JS_PROP_C_W_E or JS_PROP_THROW) + of dprException: + JS_FreeValue(ctx, a) + return JS_EXCEPTION + else: discard + inc i let ret = JS_CallConstructor(ctx, ctx.getOpaque().valRefs[jsvSet], 1, a.toJSValueArray()) JS_FreeValue(ctx, a) @@ -241,12 +261,16 @@ proc toJS*[T](ctx: JSContext; s: set[T]): JSValue = proc toJS(ctx: JSContext; t: tuple): JSValue = let a = JS_NewArray(ctx) if not JS_IsException(a): - var i = 0 + var i = 0i64 for f in t.fields: let val = toJS(ctx, f) if JS_IsException(val): return val - ctx.defineProperty(a, int64(i), val, JS_PROP_C_W_E or JS_PROP_THROW) + case ctx.defineProperty(a, i, val, JS_PROP_C_W_E or JS_PROP_THROW) + of dprException: + JS_FreeValue(ctx, a) + return JS_EXCEPTION + else: discard inc i return a diff --git a/src/config/config.nim b/src/config/config.nim index 3909e46c..0dbc6877 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -826,7 +826,9 @@ proc initCommands*(config: Config): Err[string] = var prop = JS_GetPropertyStr(ctx, objIt, cstring(ss)) if JS_IsUndefined(prop): prop = JS_NewObject(ctx) - ctx.definePropertyE(objIt, ss, JS_DupValue(ctx, prop)) + case ctx.definePropertyE(objIt, ss, JS_DupValue(ctx, prop)) + of dprException: return err(ctx.getExceptionMsg()) + else: discard if JS_IsException(prop): return err(ctx.getExceptionMsg()) JS_FreeValue(ctx, objIt) @@ -840,7 +842,9 @@ proc initCommands*(config: Config): Err[string] = if not JS_IsFunction(ctx, fun): JS_FreeValue(ctx, fun) return err(k & " is not a function") - ctx.definePropertyE(objIt, name, JS_DupValue(ctx, fun)) + case ctx.definePropertyE(objIt, name, JS_DupValue(ctx, fun)) + of dprException: return err(ctx.getExceptionMsg()) + else: discard config.cmd.map[k] = fun JS_FreeValue(ctx, objIt) config.cmd.jsObj = JS_DupValue(ctx, obj) diff --git a/src/html/dom.nim b/src/html/dom.nim index b0e98d78..48d6655c 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -1476,7 +1476,11 @@ proc parentNodeChildrenImpl(ctx: JSContext; parentNode: Node): JSValue = childonly = true )) let this = ctx.toJS(parentNode) - ctx.definePropertyCW(this, "children", JS_DupValue(ctx, children)) + case ctx.definePropertyCW(this, "children", JS_DupValue(ctx, children)) + of dprException: + JS_FreeValue(ctx, this) + return JS_EXCEPTION + else: discard JS_FreeValue(ctx, this) return children @@ -1497,7 +1501,11 @@ func childNodes(ctx: JSContext; node: Node): JSValue {.jsfget.} = childonly = true )) let this = ctx.toJS(node) - ctx.definePropertyCW(this, "childNodes", JS_DupValue(ctx, childNodes)) + case ctx.definePropertyCW(this, "childNodes", JS_DupValue(ctx, childNodes)) + of dprException: + JS_FreeValue(ctx, this) + return JS_EXCEPTION + else: discard JS_FreeValue(ctx, this) return childNodes @@ -1849,10 +1857,12 @@ proc newLocation*(window: Window): Location = let location = Location(window: window) let ctx = window.jsctx if ctx != nil: - let val = toJS(ctx, location) - let valueOf = ctx.getOpaque().valRefs[jsvObjectPrototypeValueOf] - defineProperty(ctx, val, "valueOf", JS_DupValue(ctx, valueOf)) - defineProperty(ctx, val, "toPrimitive", JS_UNDEFINED) + let val = ctx.toJS(location) + let valueOf0 = ctx.getOpaque().valRefs[jsvObjectPrototypeValueOf] + let valueOf = JS_DupValue(ctx, valueOf0) + doAssert ctx.defineProperty(val, "valueOf", valueOf) != dprException + doAssert ctx.defineProperty(val, "toPrimitive", + JS_UNDEFINED) != dprException #TODO [[DefaultProperties]] JS_FreeValue(ctx, val) return location @@ -3318,8 +3328,12 @@ proc selectedOptions(ctx: JSContext; this: HTMLSelectElement): JSValue childonly = false )) let this = ctx.toJS(this) - ctx.definePropertyCW(this, "selectedOptions", + case ctx.definePropertyCW(this, "selectedOptions", JS_DupValue(ctx, selectedOptions)) + of dprException: + JS_FreeValue(ctx, this) + return JS_EXCEPTION + else: discard JS_FreeValue(ctx, this) return selectedOptions @@ -3441,7 +3455,11 @@ proc tBodies(ctx: JSContext; this: HTMLTableElement): JSValue {.jsfget.} = childonly = true )) let this = ctx.toJS(this) - ctx.definePropertyCW(this, "tBodies", JS_DupValue(ctx, tBodies)) + case ctx.definePropertyCW(this, "tBodies", JS_DupValue(ctx, tBodies)) + of dprException: + JS_FreeValue(ctx, this) + return JS_EXCEPTION + else: discard JS_FreeValue(ctx, this) return tBodies @@ -3561,7 +3579,11 @@ proc cells(ctx: JSContext; this: HTMLTableRowElement): JSValue {.jsfget.} = childonly = true )) let this = ctx.toJS(this) - ctx.definePropertyCW(this, "cells", JS_DupValue(ctx, cells)) + case ctx.definePropertyCW(this, "cells", JS_DupValue(ctx, cells)) + of dprException: + JS_FreeValue(ctx, this) + return JS_EXCEPTION + else: discard JS_FreeValue(ctx, this) return cells @@ -6207,10 +6229,10 @@ return option; doAssert JS_SetConstructorBit(ctx, imageFun, true) doAssert JS_SetConstructorBit(ctx, optionFun, true) let jsWindow = JS_GetGlobalObject(ctx) - ctx.definePropertyCW(jsWindow, "Image", imageFun) - ctx.definePropertyCW(jsWindow, "Option", optionFun) - ctx.definePropertyCW(jsWindow, "HTMLDocument", - JS_GetPropertyStr(ctx, jsWindow, "Document")) + doAssert ctx.definePropertyCW(jsWindow, "Image", imageFun) != dprException + doAssert ctx.definePropertyCW(jsWindow, "Option", optionFun) != dprException + doAssert ctx.definePropertyCW(jsWindow, "HTMLDocument", + JS_GetPropertyStr(ctx, jsWindow, "Document")) != dprException JS_FreeValue(ctx, jsWindow) # Forward declaration hack diff --git a/src/html/jsintl.nim b/src/html/jsintl.nim index 403c6311..c9260932 100644 --- a/src/html/jsintl.nim +++ b/src/html/jsintl.nim @@ -241,5 +241,5 @@ proc addIntlModule*(ctx: JSContext) = let intl = JS_NewObject(ctx) ctx.registerType(NumberFormat, namespace = intl) ctx.registerType(PluralRules, namespace = intl) - ctx.defineProperty(global, "Intl", intl) + doAssert ctx.defineProperty(global, "Intl", intl) != dprException JS_FreeValue(ctx, global) diff --git a/src/html/script.nim b/src/html/script.nim index 9eaa9d7e..d0a8e43a 100644 --- a/src/html/script.nim +++ b/src/html/script.nim @@ -147,8 +147,9 @@ proc setImportMeta*(ctx: JSContext; funcVal: JSValue; isMain: bool) = let m = cast[JSModuleDef](JS_VALUE_GET_PTR(funcVal)) let moduleNameAtom = JS_GetModuleName(ctx, m) let metaObj = JS_GetImportMeta(ctx, m) - definePropertyCWE(ctx, metaObj, "url", JS_AtomToValue(ctx, moduleNameAtom)) - definePropertyCWE(ctx, metaObj, "main", false) + doAssert ctx.definePropertyCWE(metaObj, "url", + JS_AtomToValue(ctx, moduleNameAtom)) == dprSuccess + doAssert ctx.definePropertyCWE(metaObj, "main", false) == dprSuccess JS_FreeValue(ctx, metaObj) JS_FreeAtom(ctx, moduleNameAtom) @@ -181,8 +182,8 @@ proc defineConsts*(ctx: JSContext; classid: JSClassID; consts: typedesc[enum]) = # it isn't... for e in consts: let s = $e - ctx.definePropertyE(proto, s, uint16(e)) - ctx.definePropertyE(ctor, s, uint16(e)) + doAssert ctx.definePropertyE(proto, s, uint16(e)) == dprSuccess + doAssert ctx.definePropertyE(ctor, s, uint16(e)) == dprSuccess JS_FreeValue(ctx, proto) proc identity(ctx: JSContext; this_val: JSValue; argc: cint; diff --git a/src/local/client.nim b/src/local/client.nim index 74472e75..e19a646a 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -173,9 +173,9 @@ proc newClient*(config: Config; forkserver: ForkServer; loaderPid: int; ) client.attrsp = addr client.pager.term.attrs client.timeouts = client.pager.timeouts - let global = JS_GetGlobalObject(jsctx) jsctx.setGlobal(client) - jsctx.definePropertyE(global, "cmd", config.cmd.jsObj) + let global = JS_GetGlobalObject(jsctx) + doAssert jsctx.definePropertyE(global, "cmd", config.cmd.jsObj) != dprException JS_FreeValue(jsctx, global) config.cmd.jsObj = JS_NULL let windowCID = client.addJSModules(jsctx) |