about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-11-30 22:21:26 +0100
committerbptato <nincsnevem662@gmail.com>2023-11-30 22:28:57 +0100
commitd3a32a80fc8b6111d9e87f0f9eaa4254ef895868 (patch)
tree6cc0ecc3a0bab48881220ecf9c4802adb4be5177
parent06326cdd0ef3381a5d4fe621c10b2754225bb0c8 (diff)
downloadchawan-d3a32a80fc8b6111d9e87f0f9eaa4254ef895868.tar.gz
js: simplify toJSP0
* Expose js_create_from_ctor from QuickJS and directly use that (instead
  of badly recreating it)
* Do not call defineUnforgeable twice (it is inevitably called in toJSP0,
  so jsctor does not need it)
-rw-r--r--lib/quickjs/quickjs.c6
-rw-r--r--lib/quickjs/quickjs.h2
-rw-r--r--src/bindings/quickjs.nim8
-rw-r--r--src/js/javascript.nim4
-rw-r--r--src/js/tojs.nim38
5 files changed, 25 insertions, 33 deletions
diff --git a/lib/quickjs/quickjs.c b/lib/quickjs/quickjs.c
index 697ced39..aea545a6 100644
--- a/lib/quickjs/quickjs.c
+++ b/lib/quickjs/quickjs.c
@@ -18908,6 +18908,12 @@ static JSValue js_create_from_ctor(JSContext *ctx, JSValueConst ctor,
     return obj;
 }
 
+JSValue JS_NewObjectFromCtor(JSContext *ctx, JSValueConst ctor,
+                             JSClassID class_id)
+{
+    return js_create_from_ctor(ctx, ctor, class_id);
+}
+
 /* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */
 static JSValue JS_CallConstructorInternal(JSContext *ctx,
                                           JSValueConst func_obj,
diff --git a/lib/quickjs/quickjs.h b/lib/quickjs/quickjs.h
index c831e3c8..5e11593b 100644
--- a/lib/quickjs/quickjs.h
+++ b/lib/quickjs/quickjs.h
@@ -778,6 +778,8 @@ int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
 
 JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
                 int argc, JSValueConst *argv);
+JSValue JS_NewObjectFromCtor(JSContext *ctx, JSValueConst ctor,
+                             JSClassID class_id);
 JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
                   int argc, JSValueConst *argv);
 JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
diff --git a/src/bindings/quickjs.nim b/src/bindings/quickjs.nim
index 7f27876b..01182b90 100644
--- a/src/bindings/quickjs.nim
+++ b/src/bindings/quickjs.nim
@@ -407,8 +407,12 @@ proc JS_GetOwnPropertyNames*(ctx: JSContext,
     ptab: ptr ptr UncheckedArray[JSPropertyEnum], plen: ptr uint32,
     obj: JSValue, flags: cint): cint
 
-proc JS_GetOwnProperty*(ctx: JSContext, desc: ptr JSPropertyDescriptor, obj: JSValue, prop: JSAtom): cint
-proc JS_Call*(ctx: JSContext, func_obj, this_obj: JSValue, argc: cint, argv: ptr JSValue): JSValue
+proc JS_GetOwnProperty*(ctx: JSContext, desc: ptr JSPropertyDescriptor,
+  obj: JSValue, prop: JSAtom): cint
+proc JS_Call*(ctx: JSContext, func_obj, this_obj: JSValue, argc: cint,
+  argv: ptr JSValue): JSValue
+proc JS_NewObjectFromCtor*(ctx: JSContext, ctor: JSValue,
+  class_id: JSClassID): JSValue
 proc JS_CallConstructor*(ctx: JSContext, func_obj: JSValue, argc: cint,
   argv: ptr JSValue): JSValue
 
diff --git a/src/js/javascript.nim b/src/js/javascript.nim
index e3406048..d3de6508 100644
--- a/src/js/javascript.nim
+++ b/src/js/javascript.nim
@@ -890,9 +890,7 @@ proc makeCtorJSCallAndRet(gen: var JSFuncGenerator, errstmt: NimNode) =
   let dl = gen.dielabel
   gen.jsCallAndRet = quote do:
     block `dl`:
-      let val = ctx.toJSNew(`jfcl`, this)
-      defineUnforgeable(ctx, val)
-      return val
+      return ctx.toJSNew(`jfcl`, this)
     `errstmt`
 
 macro jsctor*(fun: typed) =
diff --git a/src/js/tojs.nim b/src/js/tojs.nim
index 581534a0..37ad6dbb 100644
--- a/src/js/tojs.nim
+++ b/src/js/tojs.nim
@@ -51,7 +51,7 @@ proc toJS*(ctx: JSContext, dict: JSDict): JSValue
 proc toJSP*(ctx: JSContext, parent: ref object, child: var object): JSValue
 proc toJSP*(ctx: JSContext, parent: ptr object, child: var object): JSValue
 
-# Same as toJSP, but used in constructors. ctor contains the target prototype,
+# Same as toJS, but used in constructors. ctor contains the target prototype,
 # used for subclassing from JS.
 proc toJSNew*(ctx: JSContext, obj: ref object, ctor: JSValue): JSValue
 proc toJSNew*[T, E](ctx: JSContext, opt: Result[T, E], ctor: JSValue): JSValue
@@ -164,41 +164,23 @@ proc toJS(ctx: JSContext, s: seq): JSValue =
         return JS_EXCEPTION
   return a
 
-proc defineUnforgeable*(ctx: JSContext, this: JSValue) =
-  if unlikely(JS_IsException(this)):
-    return
-  let ctxOpaque = ctx.getOpaque()
-  let classid = JS_GetClassID(this)
-  ctxOpaque.unforgeable.withValue(classid, uf):
-    JS_SetPropertyFunctionList(ctx, this, addr uf[][0], cint(uf[].len))
-
 proc toJSP0(ctx: JSContext, p, tp: pointer, ctor: JSValue,
     needsref: var bool): JSValue =
   JS_GetRuntime(ctx).getOpaque().plist.withValue(p, obj):
     # a JSValue already points to this object.
     return JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, obj[]))
   let ctxOpaque = ctx.getOpaque()
-  let clazz = ctxOpaque.typemap[tp]
-  let jsObj = if JS_IsUndefined(ctor):
-    JS_NewObjectClass(ctx, clazz)
-  else:
-    let proto = JS_GetProperty(ctx, ctor, ctxOpaque.str_refs[PROTOTYPE])
-    if JS_IsException(proto):
-      return proto
-    if not JS_IsObject(proto):
-      JS_FreeValue(ctx, proto)
-      #TODO switch ctx to ctor realm
-      JS_NewObjectClass(ctx, clazz)
-    else:
-      let x = JS_NewObjectProtoClass(ctx, proto, clazz)
-      JS_FreeValue(ctx, proto)
-      x
+  let class = ctxOpaque.typemap[tp]
+  let jsObj = JS_NewObjectFromCtor(ctx, ctor, class)
+  if JS_IsException(jsObj):
+    return jsObj
   setOpaque(ctx, jsObj, p)
-  # We are "constructing" a new JS object, so we must add unforgeable
-  # properties here.
-  defineUnforgeable(ctx, jsObj) # not an exception
+  # We are constructing a new JS object, so we must add unforgeable properties
+  # here.
+  ctxOpaque.unforgeable.withValue(class, uf):
+    JS_SetPropertyFunctionList(ctx, jsObj, addr uf[][0], cint(uf[].len))
   needsref = true
-  if unlikely(ctxOpaque.htmldda == clazz):
+  if unlikely(ctxOpaque.htmldda == class):
     JS_SetIsHTMLDDA(ctx, jsObj)
   return jsObj