Files
Nim/lib/std/exitprocs.nim
ASVIEST 20d79c9fb0 Deprecate asm stmt for js target (#23149)
why ?

- We already have an emit that does the same thing
- The name asm itself is a bit confusing, you might think it's an alias
for asm.js or something else.
- The asm keyword is used differently on different compiler targets (it
makes it inexpressive).
- Does anyone (other than some compiler libraries) use asm instead of
emit ? If yes, it's a bit strange to use asm somewhere and emit
somewhere. By making the asm keyword for js target deprecated, there
would be even less use of the asm keyword for js target, reducing the
amount of confusion.
- New users might accidentally use a non-universal approach via the asm
keyword instead of emit, and then when they learn about asm, try to
figure out what the differences are.

see https://forum.nim-lang.org/t/10821

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2024-01-02 07:49:54 +01:00

88 lines
2.3 KiB
Nim

#
#
# Nim's Runtime Library
# (c) Copyright 2020 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module allows adding hooks to program exit.
import std/locks
when defined(js) and not defined(nodejs):
import std/assertions
type
FunKind = enum kClosure, kNoconv # extend as needed
Fun = object
case kind: FunKind
of kClosure: fun1: proc () {.closure.}
of kNoconv: fun2: proc () {.noconv.}
var
gFunsLock: Lock
gFuns {.cursor.}: seq[Fun] #Intentionally use the cursor to break up the lifetime trace and make it compatible with JS.
initLock(gFunsLock)
when defined(js):
proc addAtExit(quitProc: proc() {.noconv.}) =
when defined(nodejs):
{.emit: """
process.on('exit', `quitProc`);
""".}
elif defined(js):
{.emit: """
window.onbeforeunload = `quitProc`;
""".}
else:
proc addAtExit(quitProc: proc() {.noconv.}) {.
importc: "atexit", header: "<stdlib.h>".}
proc callClosures() {.noconv.} =
withLock gFunsLock:
for i in countdown(gFuns.len-1, 0):
let fun = gFuns[i]
case fun.kind
of kClosure: fun.fun1()
of kNoconv: fun.fun2()
gFuns.setLen(0)
template fun() =
if gFuns.len == 0:
addAtExit(callClosures)
proc addExitProc*(cl: proc () {.closure.}) =
## Adds/registers a quit procedure. Each call to `addExitProc` registers
## another quit procedure. They are executed on a last-in, first-out basis.
# Support for `addExitProc` is done by Ansi C's facilities here.
# In case of an unhandled exception the exit handlers should
# not be called explicitly! The user may decide to do this manually though.
withLock gFunsLock:
fun()
gFuns.add Fun(kind: kClosure, fun1: cl)
proc addExitProc*(cl: proc() {.noconv.}) =
## overload for `noconv` procs.
withLock gFunsLock:
fun()
gFuns.add Fun(kind: kNoconv, fun2: cl)
when not defined(nimscript) and (not defined(js) or defined(nodejs)):
proc getProgramResult*(): int =
when defined(js) and defined(nodejs):
{.emit: """
`result` = process.exitCode;
""".}
else:
result = programResult
proc setProgramResult*(a: int) =
when defined(js) and defined(nodejs):
{.emit: """
process.exitCode = `a`;
""".}
else:
programResult = a