X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Faliencomp.lisp;h=3635cb4c16437a247eca371451bb0180502a816d;hb=07ab1e4811ab16f95a9a5e8d767426a0787f22c0;hp=eff524df5ad6ac07637c2f270cb31060c54f9e06;hpb=367316f5f21281204393853910848fea7fb9a6ab;p=sbcl.git diff --git a/src/compiler/aliencomp.lisp b/src/compiler/aliencomp.lisp index eff524d..3635cb4 100644 --- a/src/compiler/aliencomp.lisp +++ b/src/compiler/aliencomp.lisp @@ -613,6 +613,33 @@ `(lambda (function ,@names) (alien-funcall (deref function) ,@names)))) +;;; Frame pointer, program counter conses. In each thread it's bound +;;; locally or not bound at all. +(defvar *saved-fp-and-pcs*) + +#!+:c-stack-is-control-stack +(declaim (inline invoke-with-saved-fp-and-pc)) +#!+:c-stack-is-control-stack +(defun invoke-with-saved-fp-and-pc (fn) + (let* ((fp-and-pc (multiple-value-bind (fp pc) + (%caller-frame-and-pc) + (cons fp pc))) + (*saved-fp-and-pcs* (if (boundp '*saved-fp-and-pcs*) + (cons fp-and-pc *saved-fp-and-pcs*) + (list fp-and-pc)))) + (declare (truly-dynamic-extent fp-and-pc *saved-fp-and-pcs*)) + (funcall fn))) + +(defun find-saved-fp-and-pc (fp) + (when (boundp '*saved-fp-and-pcs*) + (dolist (x *saved-fp-and-pcs*) + (when (#!+:stack-grows-downward-not-upward + sap> + #!-:stack-grows-downward-not-upward + sap< + (int-sap (get-lisp-obj-address (car x))) fp) + (return (values (car x) (cdr x))))))) + (deftransform alien-funcall ((function &rest args) * * :important t) (let ((type (lvar-type function))) (unless (alien-type-type-p type) @@ -667,6 +694,11 @@ `(multiple-value-bind ,(temps) ,body (values ,@(results))))) (setf body `(naturalize ,body ',return-type))) + ;; Remember this frame to make sure that we can get back + ;; to it later regardless of how the foreign stack looks + ;; like. + #!+:c-stack-is-control-stack + (setf body `(invoke-with-saved-fp-and-pc (lambda () ,body))) (/noshow "returning from DEFTRANSFORM ALIEN-FUNCALL" (params) body) `(lambda (function ,@(params)) ,body)))))))