about summary refs log tree commit diff stats
path: root/src/bindings
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-09-12 00:30:21 +0200
committerbptato <nincsnevem662@gmail.com>2022-09-12 00:30:21 +0200
commit51ea622d58bfca19212fac1800cfb033bb85ec39 (patch)
treeb75891690f67b190c60584751f2a30c96f342fdc /src/bindings
parente38402dfa1bbc33db6b9d9736517eb45533d595c (diff)
downloadchawan-51ea622d58bfca19212fac1800cfb033bb85ec39.tar.gz
Add JS binding generation
Diffstat (limited to 'src/bindings')
-rw-r--r--src/bindings/quickjs.nim296
1 files changed, 262 insertions, 34 deletions
diff --git a/src/bindings/quickjs.nim b/src/bindings/quickjs.nim
index edda5c39..bdd156e2 100644
--- a/src/bindings/quickjs.nim
+++ b/src/bindings/quickjs.nim
@@ -26,22 +26,54 @@ when hlib != "":
 when sizeof(int) < sizeof(int64):
   {.passC: "-DJS_NAN_BOXING".}
   type
-    JSValue* {.importc: "JSValue", header: qjsheader.} = uint64
+    JSValue* {.importc, header: qjsheader.} = uint64
   # uh this won't compile you're on your own
 else:
   type
-    JSValueUnion {.union.} = object
-      int32: int32
-      float64: float64
-      `ptr`: pointer
-    JSValue* {.importc: "JSValue", header: qjsheader.} = object
-      u: JSValueUnion
-      tag: int64
+    JSValueUnion* {.importc, header: qjsheader, union.} = object
+      int32*: int32
+      float64*: float64
+      `ptr`*: pointer
+    JSValue* {.importc, header: qjsheader.} = object
+      u*: JSValueUnion
+      tag*: int64
 
 type
   JSRuntime* = ptr object
   JSContext* = ptr object
   JSCFunction* = proc (ctx: JSContext, this_val: JSValue, argc: int, argv: ptr JSValue): JSValue {.cdecl.}
+  JSGetterFunction* = proc(ctx: JSContext, this_val: JSValue): JSValue {.cdecl.}
+  JSSetterFunction* = proc(ctx: JSContext, this_val: JSValue, val: JSValue): JSValue {.cdecl.}
+  JSInterruptHandler* = proc (rt: JSRuntime, opaque: pointer): int {.cdecl.}
+  JSClassID* = uint32
+  JSAtom* = uint32
+  JSClassFinalizer* = proc (rt: JSRuntime, val: JSValue) {.cdecl.}
+  JSClassGCMark* = proc (rt: JSRuntime, val: JSValue, mark_func: JS_MarkFunc) {.cdecl.}
+  JS_MarkFunc* = proc (rt: JSRuntime, gp: ptr JSGCObjectHeader) {.cdecl.}
+  JSGCObjectHeader* {.importc, header: qjsheader.} = object
+  JSClassDef* {.importc, header: qjsheader.} = object
+    class_name*: cstring
+    finalizer*: JSClassFinalizer
+    gc_mark*: JSClassGCMark
+    call*: pointer
+    exotic*: pointer
+  JSMemoryUsage*  = object
+    malloc_size*, malloc_limit*, memory_used_size*: int64
+    malloc_count*: int64
+    memory_used_count*: int64
+    atom_count*, atom_size*: int64
+    str_count*, str_size*: int64
+    obj_count*, obj_size*: int64
+    prop_count*, prop_size*: int64
+    shape_count*, shape_size*: int64
+    js_func_count*, js_func_size*, js_func_code_size*: int64
+    js_func_pc2line_count*, js_func_pc2line_size*: int64
+    c_func_count*, array_count*: int64
+    fast_array_count*, fast_array_elements*: int64
+    binary_object_count*, binary_object_size*: int64
+
+  JSClassDefConst* {.importc: "const JSClassDef *", header: qjsheader.} = ptr JSClassDef
+
   JSCFunctionEnum* {.size: sizeof(cint).} = enum
     JS_CFUNC_generic, JS_CFUNC_generic_magic, JS_CFUNC_constructor,
     JS_CFUNC_constructor_magic, JS_CFUNC_constructor_or_func,
@@ -49,6 +81,61 @@ type
     JS_CFUNC_getter, JS_CFUNC_setter, JS_CFUNC_getter_magic,
     JS_CFUNC_setter_magic, JS_CFUNC_iterator_next
 
+type
+  JSCFunctionType* {.importc, union.} = object
+    generic*: JSCFunction
+    getter*: JSGetterFunction
+    setter*: JSSetterFunction
+
+  JSCFunctionListEntryFunc = object
+    length*: uint8
+    cproto*: JSCFunctionEnum
+    cfunc*: JSCFunctionType
+
+  JSCFunctionListEntryGetset = object
+    get*: JSCFunctionType
+    set*: JSCFunctionType
+
+  JSCFunctionListEntryAlias = object
+    name: cstring
+    base: cint
+
+  JSCFunctionListEntryPropList = object
+    tab: ptr JSCfunctionListEntry
+    len: cint
+
+  JSCFunctionListEntryU* {.union.} = object
+    `func`* {.importc: "func".}: JSCFunctionListEntryFunc
+    getset: JSCFunctionListEntryGetset
+    alias: JSCFunctionListEntryAlias
+    prop_list: JSCFunctionListEntryPropList
+    str: cstring
+    i32: int32
+    i64: int64
+    f64: cdouble
+
+  JSCFunctionListEntry* {.importc.} = object
+    name*: cstring
+    prop_flags*: uint8
+    def_type*: uint8
+    magic*: int16
+    u* {.importc.}: JSCFunctionListEntryU
+
+  JSRefCountHeader* {.importc.} = object
+    ref_count* {.importc.}: cint
+
+  JS_BOOL* = distinct cint
+
+  JSPropertyEnum* {.importc.} = object
+    is_enumerable*: JS_BOOL
+    atom*: JSAtom
+
+converter toBool*(js: JS_BOOl): bool {.inline.} =
+  cast[cint](js) != 0
+
+converter toJSBool*(b: bool): JS_BOOL {.inline.} =
+  cast[JS_BOOL](cint(b))
+
 const                         ##  all tags with a reference count are negative
   JS_TAG_FIRST* = -10           ##  first negative tag
   JS_TAG_BIG_INT* = -10
@@ -73,6 +160,15 @@ const                         ##  all tags with a reference count are negative
 template JS_MKVAL*(t, val: untyped): JSValue =
   JSValue(u: JSValueUnion(`int32`: val), tag: t)
 
+template JS_MKPTR*(t, p: untyped): JSValue =
+  JSValue(u: JSValueUnion(`ptr`: p), tag: t)
+
+template JS_VALUE_GET_TAG*(v: untyped): int =
+  cast[int32](v.tag)
+
+template JS_VALUE_GET_PTR*(v: untyped): pointer =
+  cast[pointer](v.u)
+
 const
   JS_NULL* = JS_MKVAL(JS_TAG_NULL, 0)
   JS_UNDEFINED* = JS_MKVAL(JS_TAG_UNDEFINED, 0)
@@ -92,44 +188,176 @@ const
   JS_EVAL_FLAG_STRIP* = (1 shl 4) ##  force 'strip' mode
   JS_EVAL_FLAG_COMPILE_ONLY* = (1 shl 5) ##  internal use
 
-{.push header: qjsheader, cdecl.}
+const
+  JS_DEF_CFUNC* = 0
+  JS_DEF_CGETSET* = 1
+  JS_DEF_CGETSET_MAGIC* = 2
+  JS_DEF_PROP_STRING* = 3
+  JS_DEF_PROP_INT32* = 4
+  JS_DEF_PROP_INT64* = 5
+  JS_DEF_PROP_DOUBLE* = 6
+  JS_DEF_PROP_UNDEFINED* = 7
+  JS_DEF_OBJECT* = 8
+  JS_DEF_ALIAS* = 9
 
-proc JS_NewRuntime*(): JSRuntime {.importc: "JS_NewRuntime".}
-proc JS_FreeRuntime*(rt: JSRuntime) {.importc: "JS_FreeRuntime".}
+const
+  JS_PROP_CONFIGURABLE* = (1 shl 0)
+  JS_PROP_WRITABLE* = (1 shl 1)
+  JS_PROP_ENUMERABLE* = (1 shl 2)
+  JS_PROP_C_W_E* = (JS_PROP_CONFIGURABLE or JS_PROP_WRITABLE or JS_PROP_ENUMERABLE)
+  JS_PROP_LENGTH* = (1 shl 3) # used internally in Arrays
+  JS_PROP_TMASK* = (3 shl 4) # mask for NORMAL, GETSET, VARREF, AUTOINIT
+  JS_PROP_NORMAL* = (0 shl 4)
+  JS_PROP_GETSET* = (1 shl 4)
+  JS_PROP_VARREF* = (2 shl 4) # used internally
+  JS_PROP_AUTOINIT* = (3 shl 4) # used internally
+
+const
+  JS_GPN_STRING_MASK* = (1 shl 0)
+  JS_GPN_SYMBOL_MASK* = (1 shl 1)
+  JS_GPN_PRIVATE_MASK* = (1 shl 2)
+  JS_GPN_ENUM_ONLY* = (1 shl 3)
+  JS_GPN_SET_ENUM* = (1 shl 4)
+
+
+template JS_CFUNC_DEF*(n: string, len: uint8, func1: JSCFunction): JSCFunctionListEntry = 
+  JSCFunctionListEntry(name: cstring(n),
+                       prop_flags: JS_PROP_WRITABLE or JS_PROP_CONFIGURABLE,
+                       def_type: JS_DEF_CFUNC,
+                       u: JSCFunctionListEntryU(
+                         `func`: JSCFunctionListEntryFunc(length: len,
+                                                          cproto: JS_CFUNC_generic,
+                                                          cfunc: JSCFunctionType(generic: func1))))
+
+template JS_CGETSET_DEF*(n: string, fgetter, fsetter: untyped): JSCFunctionListEntry =
+  JSCFunctionListEntry(name: cstring(n),
+                       prop_flags: JS_PROP_CONFIGURABLE,
+                       def_type: JS_DEF_CGETSET,
+                       u: JSCFunctionListEntryU(
+                         getset: JSCFunctionListEntryGetSet(get: JSCFunctionType(getter: fgetter),
+                                                            set: JSCFunctionType(setter: fsetter))))
+
+{.push header: qjsheader, importc, cdecl.}
+
+proc JS_NewRuntime*(): JSRuntime
+proc JS_FreeRuntime*(rt: JSRuntime)
+proc JS_GetRuntime*(ctx: JSContext): JSRuntime
+
+proc JS_ComputeMemoryUsage*(rt: JSRuntime, s: ptr JSMemoryUsage)
 
-proc JS_NewContext*(rt: JSRuntime): JSContext {.importc: "JS_NewContext".}
-proc JS_NewContextRaw*(rt: JSRuntime): JSContext {.importc: "JS_NewContextRaw".}
-proc JS_FreeContext*(ctx: JSContext) {.importc: "JS_FreeContext".}
+proc JS_NewContext*(rt: JSRuntime): JSContext
+proc JS_NewContextRaw*(rt: JSRuntime): JSContext
+proc JS_FreeContext*(ctx: JSContext)
 
-proc JS_GetGlobalObject*(ctx: JSContext): JSValue {.importc: "JS_GetGlobalObject".}
+proc JS_GetGlobalObject*(ctx: JSContext): JSValue
+proc JS_IsInstanceOf*(ctx: JSContext, val: JSValue, obj: JSValue): cint
 
-proc JS_NewObject*(ctx: JSContext): JSValue {.importc: "JS_NewObject".}
+proc JS_NewObject*(ctx: JSContext): JSValue
+proc JS_NewObjectClass*(ctx: JSContext, class_id: JSClassID): JSValue
+proc JS_NewObjectProto*(ctx: JSContext, proto: JSValue): JSValue
+proc JS_SetOpaque*(obj: JSValue, opaque: pointer)
+proc JS_GetOpaque*(obj: JSValue, class_id: JSClassID): pointer
+proc JS_GetOpaque2*(ctx: JSContext, obj: JSValue, class_id: JSClassID): pointer
 
-proc JS_NewCFunction2*(ctx: JSContext, cfunc: JSCFunction, name: cstring, length: int, proto: JSCFunctionEnum, magic: int): JSValue {.importc: "JS_NewCFunction2".}
-proc JS_NewCFunction*(ctx: JSContext, cfunc: JSCFunction, name: cstring, length: int): JSValue  {.importc: "JS_NewCFunction".}
+proc JS_NewClassID*(pclass_id: ptr JSClassID): JSClassID
+proc JS_NewClass*(rt: JSRuntime, class_id: JSClassID, class_def: ptr JSClassDef): cint
+proc JS_IsRegisteredClass*(rt: JSRuntime, class_id: JSClassID): cint
+proc JS_SetClassProto*(ctx: JSContext, class_id: JSClassID, obj: JSValue)
+proc JS_GetClassProto*(ctx: JSContext, class_id: JSClassID): JSValue
+proc JS_SetConstructor*(ctx: JSContext, func_obj: JSValue, proto: JSValue)
+proc JS_SetPrototype*(ctx: JSContext, obj: JSValue, proto_val: JSValue): cint
 
-proc JS_SetPropertyStr*(ctx: JSContext, this_obj: JSValue, prop: cstring, val: JSValue): int 
- {.importc: "JS_SetPropertyStr".}
+proc JS_NewBool*(ctx: JSContext, val: JS_BOOL): JSValue
+proc JS_NewInt32*(ctx: JSContext, val: int32): JSValue
+proc JS_NewCatchOffset*(ctx: JSContext, val: int32): JSValue
+proc JS_NewInt64*(ctx: JSContext, val: int64): JSValue
+proc JS_NewUint32*(ctx: JSContext, val: uint32): JSValue
+proc JS_NewUint64*(ctx: JSContext, val: uint64): JSValue
+proc JS_NewBigInt64*(ctx: JSContext, val: int64): JSValue
+proc JS_NewBigUInt64*(ctx: JSContext, val: uint64): JSValue
+proc JS_NewFloat64*(ctx: JSContext, val: uint64): JSValue
+
+proc JS_NewAtomLen*(ctx: JSContext, str: cstring, len: csize_t): JSAtom
+proc JS_ValueToAtom*(ctx: JSContext, val: JSValue): JSAtom
+proc JS_AtomToValue*(ctx: JSContext, atom: JSAtom): JSValue
+proc JS_FreeAtom*(ctx: JSContext, atom: JSAtom)
+proc JS_FreeAtomRT*(rt: JSRuntime, atom: JSAtom)
+
+proc JS_NewCFunction2*(ctx: JSContext, cfunc: JSCFunction, name: cstring, length: cint, proto: JSCFunctionEnum, magic: cint): JSValue
+proc JS_NewCFunction*(ctx: JSContext, cfunc: JSCFunction, name: cstring, length: cint): JSValue
+
+proc JS_NewString*(ctx: JSContext, str: cstring): JSValue
+
+proc JS_SetPropertyStr*(ctx: JSContext, this_obj: JSValue, prop: cstring, val: JSValue): cint
+proc JS_SetPropertyFunctionList*(ctx: JSContext, obj: JSValue, tab: ptr JSCFunctionListEntry, len: cint)
+proc JS_GetProperty*(ctx: JSContext, this_obj: JSValue, prop: JSAtom): JSValue
 proc JS_GetPropertyStr*(ctx: JSContext, this_obj: JSValue, prop: cstring): JSValue
- {.importc: "JS_GetPropertyStr".}
+proc JS_GetPropertyUint32*(ctx: JSContext, this_obj: JSValue, idx: uint32): JSValue
+proc JS_GetOwnPropertyNames*(ctx: JSContext, ptab: ptr ptr JSPropertyEnum, plen: ptr uint32, obj: JSValue, flags: cint): int
+
+proc JS_Call*(ctx: JSContext, func_obj, this_obj: JSValue, argc: cint, argv: ptr JSValue): JSValue
+
+proc JS_DefineProperty*(ctx: JSContext, this_obj: JSValue, prop: JSAtom, val: JSValue, getter: JSValue, setter: JSValue, flags: cint): cint
+proc JS_DefinePropertyValue*(ctx: JSContext, this_obj: JSValue, prop: JSAtom, val: JSValue, flags: cint): cint
+proc JS_DefinePropertyValueUint32*(ctx: JSContext, this_obj: JSValue, idx: uint32, val: JSValue, flags: cint): cint
+proc JS_DefinePropertyValueStr*(ctx: JSContext, this_obj: JSValue, prop: cstring, val: JSValue, flags: cint): cint
+proc JS_DefinePropertyValueGetSet*(ctx: JSContext, this_obj: JSValue, prop: JSAtom, getter: JSValue, setter: JSValue, flags: cint): cint
+
+proc JS_FreeValue*(ctx: JSContext, v: JSValue)
+proc JS_FreeValueRT*(rt: JSRuntime, v: JSValue)
+proc JS_DupValue*(ctx: JSContext, v: JSValue): JSValue
+
+proc JS_ToBool*(ctx: JSContext, val: JSValue): cint # return -1 for JS_EXCEPTION
+proc JS_ToInt32*(ctx: JSContext, pres: ptr int32, val: JSValue): cint
+proc JS_ToUint32*(ctx: JSContext, pres: ptr uint32, val: JSValue): cint
+proc JS_ToInt64*(ctx: JSContext, pres: ptr int64, val: JSValue): cint
+proc JS_ToIndex*(ctx: JSContext, plen: ptr uint64, val: JSValue): cint
+proc JS_ToFloat64*(ctx: JSContext, pres: ptr float64, val: JSValue): cint
+# return an exception if 'val' is a Number
+proc JS_ToBigInt64*(ctx: JSContext, pres: ptr int64, val: JSValue): cint
+# same as JS_ToInt64 but allow BigInt
+proc JS_ToInt64Ext*(ctx: JSContext, pres: ptr int64, val: JSValue): cint
+
+proc JS_ToCStringLen*(ctx: JSContext, plen: ptr csize_t, val1: JSValue): cstring
+proc JS_ToCString*(ctx: JSContext, val1: JSValue): cstring
+proc JS_FreeCString*(ctx: JSContext, `ptr`: cstring)
 
-proc JS_FreeValue*(ctx: JSContext, v: JSValue) {.importc: "JS_FreeValue".}
+proc JS_Eval*(ctx: JSContext, input: cstring, input_len: cint, filename: cstring, eval_flags: cint): JSValue
+proc JS_SetInterruptHandler*(rt: JSRuntime, cb: JSInterruptHandler, opaque: pointer)
+proc JS_SetCanBlock*(rt: JSRuntime, can_block: JS_BOOL)
 
-# use toString if possible
-proc JS_ToCStringLen*(ctx: JSContext, plen: ptr int, val1: JSValue): cstring {.importc: "JS_ToCStringLen".}
-proc JS_ToCString*(ctx: JSContext, val1: JSValue): cstring {.importc: "JS_ToCString".}
-proc JS_FreeCString*(ctx: JSContext, `ptr`: cstring) {.importc: "JS_FreeCString".}
+#TODO these should be remapped
+proc JS_IsNumber*(v: JSValue): JS_BOOL
+proc JS_IsBigInt*(v: JSValue): JS_BOOL
+proc JS_IsBigFloat*(v: JSValue): JS_BOOL
+proc JS_IsBigDecimal*(v: JSValue): JS_BOOL
+proc JS_IsBool*(v: JSValue): JS_BOOL
+proc JS_IsNull*(v: JSValue): JS_BOOL
+proc JS_IsUndefined*(v: JSValue): JS_BOOL
+proc JS_IsException*(v: JSValue): JS_BOOL
+proc JS_IsUninitialized*(v: JSValue): JS_BOOL
+proc JS_IsString*(v: JSValue): JS_BOOL
+proc JS_IsSymbol*(v: JSValue): JS_BOOL
+proc JS_IsObject*(v: JSValue): JS_BOOL
 
-proc JS_Eval*(ctx: JSContext, input: cstring, input_len: int, filename: cstring, eval_flags: int): JSValue {.importc: "JS_Eval".}
+proc JS_IsFunction*(ctx: JSContext, val: JSValue): JS_BOOL
+proc JS_IsArray*(ctx: JSContext, v: JSValue): cint
 
-proc JS_IsException*(v: JSValue): bool {.importc: "JS_IsException".}
-proc JS_IsError*(v: JSValue): bool {.importc: "JS_IsError".}
-proc JS_IsUndefined*(v: JSValue): bool {.importc: "JS_IsUndefined".}
+proc JS_Throw*(ctx: JSContext, obj: JSValue): JSValue
+proc JS_GetException*(ctx: JSContext): JSValue
+proc JS_IsError*(ctx: JSContext, v: JSValue): JS_BOOL
+proc JS_ThrowSyntaxError*(ctx: JSContext, fmt: cstring): JSValue {.varargs, discardable.}
+proc JS_ThrowTypeError*(ctx: JSContext, fmt: cstring): JSValue {.varargs, discardable.}
+proc JS_ThrowReferenceError*(ctx: JSContext, fmt: cstring): JSValue {.varargs, discardable.}
+proc JS_ThrowRangeError*(ctx: JSContext, fmt: cstring): JSValue {.varargs, discardable.}
+proc JS_ThrowInternalError*(ctx: JSContext, fmt: cstring): JSValue {.varargs, discardable.}
 
-proc JS_GetException*(ctx: JSContext): JSValue {.importc: "JS_GetException".}
+proc JS_GetRuntimeOpaque*(rt: JSRuntime): pointer
+proc JS_SetRuntimeOpaque*(rt: JSRuntime, p: pointer)
 
-proc JS_SetContextOpaque*(ctx: JSContext, opaque: pointer) {.importc: "JS_SetContextOpaque".}
-proc JS_GetContextOpaque*(ctx: JSContext): pointer {.importc: "JS_GetContextOpaque".}
+proc JS_SetContextOpaque*(ctx: JSContext, opaque: pointer)
+proc JS_GetContextOpaque*(ctx: JSContext): pointer
 
-proc js_free_rt*(rt: JSRuntime, p: pointer) {.importc: "js_free_rt".}
+proc js_free_rt*(rt: JSRuntime, p: pointer)
+proc js_free*(ctx: JSContext, p: pointer)
 {.pop.}