mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Fix frame-call-representation for callees without closures
* module/system/vm/assembler.scm (<arity>): Add new "has-closure?" flag. (begin-kw-arity, pack-arity-flags, write-arities): Write "elided-closure?" flag into binary. A negative flag for compat reasons. * module/system/vm/debug.scm (elided-closure?, arity-has-closure?): Add arity-has-closure? accessor. * module/system/vm/frame.scm (frame-call-representation): Count from 0 for callees with elided closures.
This commit is contained in:
parent
08bd2f0dcb
commit
7190905109
3 changed files with 20 additions and 6 deletions
|
@ -451,7 +451,7 @@ N-byte unit."
|
|||
|
||||
;; Metadata for one <lambda-case>.
|
||||
(define-record-type <arity>
|
||||
(make-arity req opt rest kw-indices allow-other-keys?
|
||||
(make-arity req opt rest kw-indices allow-other-keys? has-closure?
|
||||
low-pc high-pc definitions)
|
||||
arity?
|
||||
(req arity-req)
|
||||
|
@ -459,6 +459,7 @@ N-byte unit."
|
|||
(rest arity-rest)
|
||||
(kw-indices arity-kw-indices)
|
||||
(allow-other-keys? arity-allow-other-keys?)
|
||||
(has-closure? arity-has-closure?)
|
||||
(low-pc arity-low-pc)
|
||||
(high-pc arity-high-pc set-arity-high-pc!)
|
||||
(definitions arity-definitions set-arity-definitions!))
|
||||
|
@ -1499,6 +1500,7 @@ returned instead."
|
|||
(assert-match alternate (or #f (? exact-integer?) (? symbol?)) "#f or symbol")
|
||||
(let* ((meta (car (asm-meta asm)))
|
||||
(arity (make-arity req opt rest kw-indices allow-other-keys?
|
||||
has-closure?
|
||||
;; Include the initial instrument-entry in
|
||||
;; the first arity.
|
||||
(if (null? (meta-arities meta))
|
||||
|
@ -2243,6 +2245,7 @@ procedure with label @var{rw-init}. @var{rw-init} may be false. If
|
|||
;;; #x4: has-keyword-args?
|
||||
;;; #x8: is-case-lambda?
|
||||
;;; #x10: is-in-case-lambda?
|
||||
;;; #x20: elided-closure?
|
||||
;;;
|
||||
;;; Functions with a single arity specify their number of required and
|
||||
;;; optional arguments in nreq and nopt, and do not have the
|
||||
|
@ -2269,6 +2272,11 @@ procedure with label @var{rw-init}. @var{rw-init} may be false. If
|
|||
;;; set. In this way the whole headers array is sorted in increasing
|
||||
;;; low-pc order, and case-lambda clauses are contained within the
|
||||
;;; [low-pc, high-pc] of the case-lambda header.
|
||||
;;;
|
||||
;;; Normally the 0th argument is the closure for the function being
|
||||
;;; called. However if the function is "well-known" -- all of its call
|
||||
;;; sites are visible -- then the compiler may elide the closure, and
|
||||
;;; the 0th argument is the first user-visible argument.
|
||||
|
||||
;; Length of the prefix to the arities section, in bytes.
|
||||
(define arities-prefix-len 4)
|
||||
|
@ -2299,12 +2307,13 @@ procedure with label @var{rw-init}. @var{rw-init} may be false. If
|
|||
|
||||
(define-inline (pack-arity-flags has-rest? allow-other-keys?
|
||||
has-keyword-args? is-case-lambda?
|
||||
is-in-case-lambda?)
|
||||
is-in-case-lambda? elided-closure?)
|
||||
(logior (if has-rest? (ash 1 0) 0)
|
||||
(if allow-other-keys? (ash 1 1) 0)
|
||||
(if has-keyword-args? (ash 1 2) 0)
|
||||
(if is-case-lambda? (ash 1 3) 0)
|
||||
(if is-in-case-lambda? (ash 1 4) 0)))
|
||||
(if is-in-case-lambda? (ash 1 4) 0)
|
||||
(if elided-closure? (ash 1 5) 0)))
|
||||
|
||||
(define (write-arities asm metas headers names-port strtab)
|
||||
(define (write-header pos low-pc high-pc offset flags nreq nopt nlocals)
|
||||
|
@ -2336,7 +2345,8 @@ procedure with label @var{rw-init}. @var{rw-init} may be false. If
|
|||
(arity-allow-other-keys? arity)
|
||||
(pair? (arity-kw-indices arity))
|
||||
#f
|
||||
in-case-lambda?)
|
||||
in-case-lambda?
|
||||
(not (arity-has-closure? arity)))
|
||||
(length (arity-req arity))
|
||||
(length (arity-opt arity))
|
||||
(length (arity-definitions arity)))
|
||||
|
@ -2384,7 +2394,7 @@ procedure with label @var{rw-init}. @var{rw-init} may be false. If
|
|||
;; Write a case-lambda header, then individual arities.
|
||||
;; The case-lambda header's offset link is 0.
|
||||
(write-header pos (meta-low-pc meta) (meta-high-pc meta) 0
|
||||
(pack-arity-flags #f #f #f #t #f) 0 0 0)
|
||||
(pack-arity-flags #f #f #f #t #f #f) 0 0 0)
|
||||
(let lp* ((arities arities) (pos (+ pos arity-header-len))
|
||||
(relocs relocs))
|
||||
(match arities
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
arity?
|
||||
arity-low-pc
|
||||
arity-high-pc
|
||||
arity-has-closure?
|
||||
arity-nreq
|
||||
arity-nopt
|
||||
arity-nlocals
|
||||
|
@ -281,12 +282,14 @@ section of the ELF image. Returns an ELF symbol, or @code{#f}."
|
|||
;;; #x4: has-keyword-args?
|
||||
;;; #x8: is-case-lambda?
|
||||
;;; #x10: is-in-case-lambda?
|
||||
;;; #x20: elided-closure?
|
||||
|
||||
(define (has-rest? flags) (not (zero? (logand flags (ash 1 0)))))
|
||||
(define (allow-other-keys? flags) (not (zero? (logand flags (ash 1 1)))))
|
||||
(define (has-keyword-args? flags) (not (zero? (logand flags (ash 1 2)))))
|
||||
(define (is-case-lambda? flags) (not (zero? (logand flags (ash 1 3)))))
|
||||
(define (is-in-case-lambda? flags) (not (zero? (logand flags (ash 1 4)))))
|
||||
(define (elided-closure? flags) (not (zero? (logand flags (ash 1 5)))))
|
||||
|
||||
(define (arity-low-pc arity)
|
||||
(let ((ctx (arity-context arity)))
|
||||
|
@ -318,6 +321,7 @@ section of the ELF image. Returns an ELF symbol, or @code{#f}."
|
|||
(arity-flags* (elf-bytes (debug-context-elf (arity-context arity)))
|
||||
(arity-header-offset arity)))
|
||||
|
||||
(define (arity-has-closure? arity) (not (elided-closure? (arity-flags arity))))
|
||||
(define (arity-has-rest? arity) (has-rest? (arity-flags arity)))
|
||||
(define (arity-allow-other-keys? arity) (allow-other-keys? (arity-flags arity)))
|
||||
(define (arity-has-keyword-args? arity) (has-keyword-args? (arity-flags arity)))
|
||||
|
|
|
@ -428,7 +428,7 @@
|
|||
(arity-nopt arity)
|
||||
(arity-keyword-args arity)
|
||||
(arity-has-rest? arity)
|
||||
1))))
|
||||
(if (arity-has-closure? arity) 1 0)))))
|
||||
((and (primitive-code? ip)
|
||||
(program-arguments-alist (frame-local-ref frame 0 'scm) ip))
|
||||
=> (lambda (args)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue