about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer/container.nim2
-rw-r--r--src/config/config.nim2
-rw-r--r--src/display/client.nim5
-rw-r--r--src/display/pager.nim2
-rw-r--r--src/html/dom.nim53
-rw-r--r--src/html/htmlparser.nim2
-rw-r--r--src/io/lineedit.nim2
-rw-r--r--src/io/request.nim3
-rw-r--r--src/io/response.nim2
-rw-r--r--src/js/exception.nim2
-rw-r--r--src/js/intl.nim2
-rw-r--r--src/js/javascript.nim13
-rw-r--r--src/types/blob.nim3
-rw-r--r--src/types/cookie.nim2
-rw-r--r--src/types/formdata.nim3
-rw-r--r--src/types/url.nim3
16 files changed, 98 insertions, 3 deletions
diff --git a/src/buffer/container.nim b/src/buffer/container.nim
index a2bbaa3a..21b11af6 100644
--- a/src/buffer/container.nim
+++ b/src/buffer/container.nim
@@ -97,6 +97,8 @@ type
     hasstart: bool
     redirectdepth*: int
 
+jsDestructor(Container)
+
 proc newBuffer*(dispatcher: Dispatcher, config: BufferConfig,
                 source: BufferSource, title = "", redirectdepth = 0): Container =
   let attrs = getWindowAttributes(stdout)
diff --git a/src/config/config.nim b/src/config/config.nim
index 51051048..9d0a9350 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -125,6 +125,8 @@ type
     tmpdir*: string
     ambiguous_double*: bool
 
+jsDestructor(Config)
+
 const DefaultHeaders* = {
   "User-Agent": "chawan",
   "Accept": "text/html,text/*;q=0.5",
diff --git a/src/display/client.nim b/src/display/client.nim
index 721af4a0..3f4039df 100644
--- a/src/display/client.nim
+++ b/src/display/client.nim
@@ -77,6 +77,9 @@ type
     ibuf: string
     tty: File
 
+jsDestructor(Client)
+jsDestructor(Console)
+
 proc readChar(console: Console): char =
   if console.ibuf == "":
     try:
@@ -86,7 +89,7 @@ proc readChar(console: Console): char =
   result = console.ibuf[0]
   console.ibuf = console.ibuf.substr(1)
 
-proc `=destroy`(client: var ClientObj) =
+proc finalize(client: Client) {.jsfin.} =
   if client.jsctx != nil:
     free(client.jsctx)
   if client.jsrt != nil:
diff --git a/src/display/pager.nim b/src/display/pager.nim
index fedd3b88..b95fa6ea 100644
--- a/src/display/pager.nim
+++ b/src/display/pager.nim
@@ -68,6 +68,8 @@ type
     omnirules: seq[OmniRule]
     cookiejars: Table[string, CookieJar]
 
+jsDestructor(Pager)
+
 func attrs(pager: Pager): WindowAttributes = pager.term.attrs
 
 func getRoot(container: Container): Container =
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 048e40af..bf8e0fcc 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -367,6 +367,59 @@ type
   HTMLImageElement* = ref object of HTMLElement
     bitmap*: Bitmap
 
+jsDestructor(Navigator)
+jsDestructor(PluginArray)
+jsDestructor(MimeTypeArray)
+jsDestructor(Window)
+
+jsDestructor(console)
+jsDestructor(Element)
+jsDestructor(HTMLElement)
+jsDestructor(HTMLInputElement)
+jsDestructor(HTMLAnchorElement)
+jsDestructor(HTMLSelectElement)
+jsDestructor(HTMLSpanElement)
+jsDestructor(HTMLOptGroupElement)
+jsDestructor(HTMLOptionElement)
+jsDestructor(HTMLHeadingElement)
+jsDestructor(HTMLBRElement)
+jsDestructor(HTMLMenuElement)
+jsDestructor(HTMLUListElement)
+jsDestructor(HTMLOListElement)
+jsDestructor(HTMLLIElement)
+jsDestructor(HTMLStyleElement)
+jsDestructor(HTMLLinkElement)
+jsDestructor(HTMLFormElement)
+jsDestructor(HTMLTemplateElement)
+jsDestructor(HTMLUnknownElement)
+jsDestructor(HTMLScriptElement)
+jsDestructor(HTMLBaseElement)
+jsDestructor(HTMLAreaElement)
+jsDestructor(HTMLButtonElement)
+jsDestructor(HTMLTextAreaElement)
+jsDestructor(HTMLLabelElement)
+jsDestructor(HTMLCanvasElement)
+jsDestructor(HTMLImageElement)
+jsDestructor(EventTarget)
+jsDestructor(Node)
+jsDestructor(NodeList)
+jsDestructor(HTMLCollection)
+jsDestructor(Location)
+jsDestructor(Document)
+jsDestructor(DOMImplementation)
+jsDestructor(DOMTokenList)
+jsDestructor(Comment)
+jsDestructor(CDATASection)
+jsDestructor(DocumentFragment)
+jsDestructor(ProcessingInstruction)
+jsDestructor(CharacterData)
+jsDestructor(Text)
+jsDestructor(DocumentType)
+jsDestructor(Attr)
+jsDestructor(NamedNodeMap)
+jsDestructor(CanvasRenderingContext2D)
+jsDestructor(TextMetrics)
+
 proc parseColor(element: Element, s: string): RGBAColor
 
 proc resetTransform(state: var DrawingState) =
diff --git a/src/html/htmlparser.nim b/src/html/htmlparser.nim
index c3df8e3d..9f9d4b85 100644
--- a/src/html/htmlparser.nim
+++ b/src/html/htmlparser.nim
@@ -60,6 +60,8 @@ type
     AFTER_BODY, IN_FRAMESET, AFTER_FRAMESET, AFTER_AFTER_BODY,
     AFTER_AFTER_FRAMESET
 
+jsDestructor(DOMParser)
+
 proc resetInsertionMode(parser: var HTML5Parser) =
   template switch_insertion_mode_and_return(mode: InsertionMode) =
     parser.insertionMode = mode
diff --git a/src/io/lineedit.nim b/src/io/lineedit.nim
index 51bf7cd9..66a4eede 100644
--- a/src/io/lineedit.nim
+++ b/src/io/lineedit.nim
@@ -37,6 +37,8 @@ type
     histindex: int
     histtmp: string
 
+jsDestructor(LineEdit)
+
 func newLineHistory*(): LineHistory =
   return LineHistory()
 
diff --git a/src/io/request.nim b/src/io/request.nim
index 86c8a38d..93ec9b7d 100644
--- a/src/io/request.nim
+++ b/src/io/request.nim
@@ -83,6 +83,9 @@ type
   Headers* = ref object
     table* {.jsget.}: Table[string, seq[string]]
 
+jsDestructor(Request)
+jsDestructor(Headers)
+
 proc js_url(this: Request): string {.jsfget: "url".} =
   return $this.url
 
diff --git a/src/io/response.nim b/src/io/response.nim
index fbe5339e..5c0253e9 100644
--- a/src/io/response.nim
+++ b/src/io/response.nim
@@ -21,6 +21,8 @@ type
     unregisterFun*: proc()
     bodyRead*: Promise[string]
 
+jsDestructor(Response)
+
 proc newResponse*(res: int, request: Request, fd = -1, stream: Stream = nil):
     Response =
   return Response(
diff --git a/src/js/exception.nim b/src/js/exception.nim
index f30c4898..44b178ba 100644
--- a/src/js/exception.nim
+++ b/src/js/exception.nim
@@ -31,6 +31,8 @@ const NamesTable = {
 type DOMException* = ref object of JSError
   name* {.jsget.}: string
 
+jsDestructor(DOMException)
+
 type
   JSResult*[T] = Result[T, JSError]
 
diff --git a/src/js/intl.nim b/src/js/intl.nim
index f37789ad..054e5d04 100644
--- a/src/js/intl.nim
+++ b/src/js/intl.nim
@@ -6,6 +6,8 @@ import js/javascript
 type
   NumberFormat = ref object
 
+jsDestructor(NumberFormat)
+
 #TODO ...yeah
 proc newNumberFormat(name: string = "en-US",
     options = none(JSValue)): NumberFormat {.jsctor.} =
diff --git a/src/js/javascript.nim b/src/js/javascript.nim
index 39d22532..b2334be6 100644
--- a/src/js/javascript.nim
+++ b/src/js/javascript.nim
@@ -1346,6 +1346,7 @@ proc finishFunCallList(gen: var JSFuncGenerator) =
 
 var js_funcs {.compileTime.}: Table[string, JSFuncGenerator]
 var existing_funcs {.compileTime.}: HashSet[string]
+var js_dtors {.compileTime.}: HashSet[string]
 
 proc registerFunction(typ: string, t: BoundFunctionType, name: string, id: NimNode, magic: uint16 = 0) =
   let nf = BoundFunction(t: t, name: name, id: id, magic: magic)
@@ -1710,7 +1711,7 @@ proc findPragmas(t: NimNode): JSObjectPragmas =
             of "jsset": result.jsset.add(op)
             of "jsinclude": result.jsinclude.add(op)
 
-proc nim_finalize_for_js[T](obj: T) =
+proc nim_finalize_for_js*[T](obj: ptr T) =
   for rt in runtimes:
     let rtOpaque = rt.getOpaque()
     rtOpaque.plist.withValue(cast[pointer](obj), v):
@@ -1734,12 +1735,20 @@ type
     name*: string
     fun*: JSCFunction
 
+template jsDestructor*[U](T: typedesc[ref U]) =
+  static:
+    js_dtors.incl($T)
+  proc `=destroy`(obj: var U) =
+    nim_finalize_for_js(addr obj)
+
 macro registerType*(ctx: typed, t: typed, parent: JSClassID = 0,
     asglobal = false, nointerface = false, name: static string = "",
     extra_getset: static openarray[TabGetSet] = [],
     namespace: JSValue = JS_NULL, errid = opt(JSErrorEnum)): JSClassID =
   result = newStmtList()
   let tname = t.strVal # the nim type's name.
+  if tname notin js_dtors:
+    warning("No destructor has been defined for type " & tname)
   let name = if name == "": tname else: name # possibly a different name, e.g. Buffer for Container
   var sctr = ident("js_illegal_ctor")
   # constructor
@@ -1907,7 +1916,7 @@ static JSClassDef """, `cdname`, """ = {
     # We exploit this by setting a finalizer here, which can then unregister
     # any associated JS object from all relevant runtimes.
     var x: `t`
-    new(x, nim_finalize_for_js)
+    new(x)
     `ctx`.newJSClass(`classDef`, `tname`, `sctr`, `tabList`, getTypePtr(x),
       `parent`, `asglobal`, `nointerface`, `finName`, `namespace`, `errid`)
   )
diff --git a/src/types/blob.nim b/src/types/blob.nim
index d72d0505..505e4f7c 100644
--- a/src/types/blob.nim
+++ b/src/types/blob.nim
@@ -19,6 +19,9 @@ type
     path*: string
     file: File #TODO maybe use fd?
 
+jsDestructor(Blob)
+jsDestructor(WebFile)
+
 proc newBlob*(buffer: pointer, size: int, ctype: string,
     deallocFun: DeallocFun): Blob =
   return Blob(
diff --git a/src/types/cookie.nim b/src/types/cookie.nim
index c6b526ee..7418963d 100644
--- a/src/types/cookie.nim
+++ b/src/types/cookie.nim
@@ -25,6 +25,8 @@ type
     filter*: URLFilter
     cookies*: seq[Cookie]
 
+jsDestructor(Cookie)
+
 proc parseCookieDate(val: string): Option[DateTime] =
   # cookie-date
   const Delimiters = {'\t', ' '..'/', ';'..'@', '['..'`', '{'..'~'}
diff --git a/src/types/formdata.nim b/src/types/formdata.nim
index 983508bf..2bc26e22 100644
--- a/src/types/formdata.nim
+++ b/src/types/formdata.nim
@@ -1,3 +1,4 @@
+import js/javascript
 import types/blob
 
 type
@@ -13,6 +14,8 @@ type
   FormData* = ref object
     entries*: seq[FormDataEntry]
 
+jsDestructor(FormData)
+
 iterator items*(this: FormData): FormDataEntry {.inline.} =
   for entry in this.entries:
     yield entry
diff --git a/src/types/url.nim b/src/types/url.nim
index 968e642c..3eb6889c 100644
--- a/src/types/url.nim
+++ b/src/types/url.nim
@@ -60,6 +60,9 @@ type
     domain: Option[string]
   ]]
 
+jsDestructor(URL)
+jsDestructor(URLSearchParams)
+
 const EmptyPath = UrlPath(opaque: true, s: "")
 const EmptyHost = Host(domain: "").some