erlang: exit/1 + process termination (+9 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-24 21:34:21 +00:00
parent e2e801e38a
commit 97513e5b96
4 changed files with 83 additions and 1 deletions

View File

@@ -231,6 +231,22 @@
er-proc-mailbox-size
(fn (pid) (er-q-len (er-proc-field pid :mailbox))))
;; Main process is always pid 0 (scheduler starts with next-pid 0 and
;; erlang-eval-ast calls er-proc-new! first). Returns nil if no eval
;; has run.
(define
er-main-pid
(fn () (er-mk-pid 0)))
(define
er-last-main-exit-reason
(fn
()
(if
(er-proc-exists? (er-main-pid))
(er-proc-field (er-main-pid) :exit-reason)
nil)))
;; ── process BIFs ────────────────────────────────────────────────
(define
er-bif-is-pid
@@ -272,6 +288,20 @@
(dict-set! proc :initial-fun fv)
(get proc :pid)))))
(define
er-bif-exit
(fn
(vs)
(cond
(= (len vs) 1)
(let
((reason (nth vs 0)))
(shift k (er-mk-exit-marker reason)))
(= (len vs) 2)
(error
"Erlang: exit/2 (signal another process) deferred to Phase 4 (links)")
:else (error "Erlang: exit: wrong arity"))))
;; ── scheduler loop ──────────────────────────────────────────────
;; Each process's entry runs inside a `reset`; `receive` uses `shift`
;; to suspend (saving a continuation on the proc record). When a `!`
@@ -288,6 +318,18 @@
(= (type-of v) "dict")
(= (get v :tag) "er-suspend-marker"))))
(define
er-exited?
(fn
(v)
(and
(= (type-of v) "dict")
(= (get v :tag) "er-exit-marker"))))
(define
er-mk-exit-marker
(fn (reason) {:tag "er-exit-marker" :reason reason}))
(define
er-sched-run-all!
(fn
@@ -351,6 +393,12 @@
((r (nth result-ref 0)))
(cond
(er-suspended? r) nil
(er-exited? r)
(do
(er-proc-set! pid :state "dead")
(er-proc-set! pid :exit-reason (get r :reason))
(er-proc-set! pid :exit-result nil)
(er-proc-set! pid :continuation nil))
:else (do
(er-proc-set! pid :state "dead")
(er-proc-set! pid :exit-reason (er-mk-atom "normal"))