Update of /project/movitz/cvsroot/movitz In directory common-lisp.net:/tmp/cvs-serv6262
Modified Files: special-operators-cl.lisp Log Message: Re-working of non-local control transfer so as to comply with the stack discipline.
Date: Fri Sep 17 13:12:47 2004 Author: ffjeld
Index: movitz/special-operators-cl.lisp diff -u movitz/special-operators-cl.lisp:1.23 movitz/special-operators-cl.lisp:1.24 --- movitz/special-operators-cl.lisp:1.23 Wed Sep 15 12:22:52 2004 +++ movitz/special-operators-cl.lisp Fri Sep 17 13:12:47 2004 @@ -9,7 +9,7 @@ ;;;; Created at: Fri Nov 24 16:31:11 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: special-operators-cl.lisp,v 1.23 2004/09/15 10:22:52 ffjeld Exp $ +;;;; $Id: special-operators-cl.lisp,v 1.24 2004/09/17 11:12:47 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------
@@ -291,6 +291,10 @@ (progn #+ignore (warn "recompile..") (compile-body))) (when (plusp (num-specials local-env)) + `((:movl (:esp ,(+ -4 (* 16 (num-specials local-env)))) :edx) + (:locally (:movl :edx (:edi (:edi-offset dynamic-env)))) + (:leal (:esp ,(* 16 (num-specials local-env))) :esp)) + #+ignore `((:leal (:esp ,(+ -4 (* 16 (num-specials local-env)))) :esp) (:locally (:popl (:edi (:edi-offset dynamic-env))))))))) (compiler-values (body-values) @@ -1183,48 +1187,90 @@ (:locally (:movl :esp (:edi (:edi-offset dynamic-env))))) ; install catch body-code `(,exit-point + (:movl (:esp 12) :edx) + (:locally (:movl :edx (:edi (:edi-offset dynamic-env)))) (:popl :ebp) - (:leal (:esp 8) :esp) ; Skip catch-tag and jumper - (:locally (:popl (:edi (:edi-offset dynamic-env))))))))) + (:leal (:esp 12) :esp) + )))))
(define-special-operator unwind-protect (&all all &form form &env env) (destructuring-bind (protected-form &body cleanup-forms) (cdr form) - (let ((up-env (make-instance 'unwind-protect-env - :uplink env - :funobj (movitz-environment-funobj env)))) - (with-labels (unwind-protect (cleanup-label cleanup-entry)) - (compiler-call #'compile-form - :result-mode :multiple-values - :forward all - :form `(muerte.cl::multiple-value-prog1 - (muerte::with-progn-results (:ignore :multiple-values) - (muerte::with-inline-assembly-case () - (do-case (t :multiple-values) - ;; install up dynamic-env.. - (:locally (:pushl (:edi (:edi-offset dynamic-env)))) - (:declare-label-set ,cleanup-label (,cleanup-entry)) - (:pushl ',cleanup-label) ; jumper index - (:globally (:pushl (:edi (:edi-offset unwind-protect-tag)))) ; tag - (:pushl :ebp) ; stack-frame - (:locally (:movl :esp (:edi (:edi-offset dynamic-env)))))) ; install up-env - (muerte::with-local-env (,up-env) - ,protected-form) - (muerte::with-inline-assembly-case () - (do-case (t :multiple-values) - ;; uninstall dynamic-env.. - (:leal (:esp ,(- 16 4)) :esp) - (:locally (:popl (:edi (:edi-offset dynamic-env))))))) - (muerte::with-inline-assembly-case () - (do-case (t :nothing) - ;; execute cleanup-forms - (:call '(:sub-program (,cleanup-entry) ; label - ,@(compiler-call #'compile-form - :with-stack-used t ; stack distance is _really_ unknown! - :defaults all - :result-mode :ignore - :form `(muerte.cl::progn ,@cleanup-forms)) - (:ret))))))))))) + (let* ((continuation-env (make-instance 'let-env + :uplink env + :funobj (movitz-environment-funobj env))) + (next-continuation-step-binding + (movitz-env-add-binding continuation-env + (make-instance 'located-binding + :name (gensym "up-next-continuation-step-")))) + (unwind-protect-env (make-instance 'unwind-protect-env + :uplink continuation-env + :funobj (movitz-environment-funobj env)))) + (with-labels (unwind-protect (cleanup-label cleanup-entry continue continue-label)) + (compiler-values () + :returns :multiple-values + :code (append + ;; install default continuation dynamic-env.. + `((:locally (:pushl (:edi (:edi-offset dynamic-env)))) ; uplink + (:declare-label-set ,continue-label (,continue)) + (:pushl ',continue-label) + (:locally (:pushl (:edi (:edi-offset unbound-value)))) + (:pushl :ebp) + (:locally (:movl :esp (:edi (:edi-offset dynamic-env))))) + ;; install unwind-protect dynamic-env.. + `((:locally (:pushl (:edi (:edi-offset dynamic-env)))) + (:declare-label-set ,cleanup-label (,cleanup-entry)) + (:pushl ',cleanup-label) ; jumper index + (:globally (:pushl (:edi (:edi-offset unwind-protect-tag)))) ; tag + (:pushl :ebp) ; stack-frame + (:locally (:movl :esp (:edi (:edi-offset dynamic-env))))) ; install up-env + ;; Execute protected form.. + (compiler-call #'compile-form + :env unwind-protect-env + :with-stack-used t + :forward all + :result-mode :multiple-values + :form protected-form) + ;; From now on, take care not to touch current-values from protected-form. + `((:leal (:esp 16) :edx) ; default final continuation + (:locally (:movl :edx (:edi (:edi-offset raw-scratch0)))) + ,cleanup-entry + (:movl (:esp 12) :edx) ; pop out of unwind-protect + (:locally (:movl :edx (:edi (:edi-offset dynamic-env)))) + (:popl :ebp) + (:leal (:esp 12) :esp) + (:locally (:pushl (:edi (:edi-offset raw-scratch0))))) ; push final-continuation + ;; Execute cleanup-forms. + (compiler-call #'compile-form-unprotected + :forward all + :env continuation-env + :with-stack-used t + :result-mode :multiple-values + :form `(muerte::with-cloak (:multiple-values) + ;; Inside here we don't have to mind current-values. + (muerte::with-inline-assembly (:returns :nothing) + ;; First, find next-continuation-step.. + (:locally (:movl (:edi (:edi-offset raw-scratch0)) :eax)) ; final-cont.. + (:locally (:call (:edi (:edi-offset dynamic-unwind-next)))) + (:locally (:bound (:edi (:edi-offset stack-bottom)) :eax)) + (:store-lexical ,next-continuation-step-binding :eax :type t)) + ,@cleanup-forms)) + `((:load-lexical ,next-continuation-step-binding :edx) + (:locally (:popl (:edi (:edi-offset raw-scratch0)))) ; pop final continuation + (:locally (:movl :esi (:edi (:edi-offset scratch1)))) + (:locally (:movl :edx (:edi (:edi-offset dynamic-env)))) + (:movl :edx :esp) ; enter non-local jump stack mode (possibly). + + (:movl (:esp) :edx) ; target stack-frame EBP + (:movl (:edx -4) :esi) ; get target funobj into EDX + + (:movl (:esp 8) :edx) ; target jumper number + (:jmp (:esi :edx ,(slot-offset 'movitz-funobj 'constant0)))) + `(,continue + (:movl (:esp 12) :edx) + (:locally (:movl :edx (:edi (:edi-offset dynamic-env)))) + (:popl :ebp) + (:leal (:esp 12) :esp))))))))
(define-special-operator if (&all all &form form &env env &result-mode result-mode)