Resolve .method calls through a priority arm registry

record-method-dispatch was rebound with (set! record-method-dispatch ...) in six
files, each wrapping the previous binding, so precedence was whatever the rt.ss
load order happened to be — the true outermost arm was inst-time's Date arm, not
the one you'd guess. A type-gated wrapper that only whitelists its own methods
then errored on everything else, stealing universal Object methods from the arms
beneath it: (.getClass (java.util.Date.)) threw "No method getClass on Date",
same for File, while (class ...) and (.getClass "s") worked.

Replace the wrapper stack with an ordered list of arms (register-method-arm!,
ascending priority), each returning 'pass to defer. getClass is now one arm at
the top reached by every value, so it can't be shadowed; the three duplicate
getClass checks (dot-forms, host-static, base) collapse into it. Each former
wrapper is an arm at an explicit priority instead of an implicit load-order slot.
A library can register its own arm rather than set!-wrapping the dispatcher.

Runtime only, no re-mint. make test green (0 new/stale divergences), +1 corpus
row for getClass on Date/File.
This commit is contained in:
Yogthos 2026-07-01 15:52:24 -04:00
parent d4acd69a73
commit 0b07b376bb
7 changed files with 46 additions and 33 deletions

View file

@ -240,14 +240,13 @@
(else (loop (- i 1))))))
(else #f))))
(define %io-rmd record-method-dispatch)
(set! record-method-dispatch
(register-method-arm! 41
(lambda (obj method-name rest-args)
(if (jfile? obj)
(let* ((rest (if (jolt-nil? rest-args) '() (seq->list rest-args)))
(r (jfile-method obj method-name rest)))
(if r (car r) (error #f "no File method" method-name)))
(%io-rmd obj method-name rest-args))))
'pass)))
;; .isDirectory / .listFiles emit to jolt-host-call (rt.ss), not record-method-
;; dispatch — the shims there assume a path STRING target. Make them jfile-aware