1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-17 09:10:22 +02:00

steps on the way to have the callee check the number of arguments

* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.

* libguile/vm-i-system.c (assert-nargs-ee, assert-nargs-ge)
  (push-rest-list): New instructions, which for now don't actually do
  anything. Renumber the rest of the ops in this file.

* module/language/glil.scm (<glil-arity>): New GLIL type, an entity that
  checks the number of args for a block, optionally consing a rest list,
  and either branching or erroring if the arity doesn't match.

* module/language/glil/compile-assembly.scm (glil->assembly): Compile
  <glil-arity> to assembly. Some of these VM ops are not implemented --
  notably the branching case.

* module/language/tree-il/compile-glil.scm (flatten-lambda): Emit
  <glil-arity>.

* test-suite/tests/tree-il.test: Update.
This commit is contained in:
Andy Wingo 2009-09-27 18:16:56 -04:00
parent 04c68c0391
commit 1e2a8c266d
6 changed files with 172 additions and 104 deletions

View file

@ -27,6 +27,9 @@
glil-program-nargs glil-program-nrest glil-program-nlocs
glil-program-meta glil-program-body
<glil-arity> make-glil-arity glil-arity?
glil-arity-nargs glil-arity-nrest glil-arity-label
<glil-bind> make-glil-bind glil-bind?
glil-bind-vars
@ -72,6 +75,7 @@
(define-type (<glil> #:printer print-glil)
;; Meta operations
(<glil-program> nargs nrest nlocs meta body)
(<glil-arity> nargs nrest label)
(<glil-bind> vars)
(<glil-mv-bind> vars rest)
(<glil-unbind>)
@ -95,6 +99,7 @@
(pmatch x
((program ,nargs ,nrest ,nlocs ,meta . ,body)
(make-glil-program nargs nrest nlocs meta (map parse-glil body)))
((arity ,nargs ,nrest ,label) (make-glil-arity nargs nrest label))
((bind . ,vars) (make-glil-bind vars))
((mv-bind ,vars ,rest) (make-glil-mv-bind vars rest))
((unbind) (make-glil-unbind))
@ -116,6 +121,7 @@
;; meta
((<glil-program> nargs nrest nlocs meta body)
`(program ,nargs ,nrest ,nlocs ,meta ,@(map unparse-glil body)))
((<glil-arity> nargs nrest label) `(arity ,nargs ,nrest ,label))
((<glil-bind> vars) `(bind ,@vars))
((<glil-mv-bind> vars rest) `(mv-bind ,vars ,rest))
((<glil-unbind>) `(unbind))

View file

@ -356,6 +356,26 @@
((<glil-branch> inst label)
(emit-code `((,inst ,label))))
((<glil-arity> nargs nrest label)
(emit-code (if label
(if (zero? nrest)
`((br-if-nargs-ne ,(quotient nargs 256) ,label))
`(,@(if (> nargs 1)
`((br-if-nargs-lt ,(quotient (1- nargs) 256)
,(modulo (1- nargs 256))
,label))
'())
(push-rest-list ,(quotient (1- nargs) 256))))
(if (zero? nrest)
`((assert-nargs-ee ,(quotient nargs 256)
,(modulo nargs 256)))
`(,@(if (> nargs 1)
`((assert-nargs-ge ,(quotient (1- nargs) 256)
,(modulo (1- nargs) 256)))
'())
(push-rest-list ,(quotient (1- nargs) 256)
,(modulo (1- nargs) 256)))))))
;; nargs is number of stack args to insn. probably should rename.
((<glil-call> inst nargs)
(if (not (instruction? inst))

View file

@ -189,21 +189,24 @@
nargs nrest nlocs (lambda-meta x)
(with-output-to-code
(lambda (emit-code)
;; emit label for self tail calls
(if self-label
(emit-code #f (make-glil-label self-label)))
;; write bindings and source debugging info
(if (not (null? ids))
(emit-bindings #f ids vars allocation x emit-code))
;; write source info for proc
(if (lambda-src x)
(emit-code #f (make-glil-source (lambda-src x))))
;; check arity, potentially consing a rest list
(emit-code #f (make-glil-arity nargs nrest #f))
;; write bindings info
(if (not (null? ids))
(emit-bindings #f ids vars allocation x emit-code))
;; emit post-prelude label for self tail calls
(if self-label
(emit-code #f (make-glil-label self-label)))
;; box args if necessary
(for-each
(lambda (v)
(pmatch (hashq-ref (hashq-ref allocation v) x)
((#t #t . ,n)
(emit-code #f (make-glil-lexical #t #f 'ref n))
(emit-code #f (make-glil-lexical #t #t 'box n)))))
((#t #t . ,n)
(emit-code #f (make-glil-lexical #t #f 'ref n))
(emit-code #f (make-glil-lexical #t #t 'box n)))))
vars)
;; and here, here, dear reader: we compile.
(flatten (lambda-body x) allocation x self-label