X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Faliencomp.lisp;h=4321c3174ba69099d534c5917eba053834626003;hb=49e8403800426f37a54d9b87353a31af36e7af40;hp=eff524df5ad6ac07637c2f270cb31060c54f9e06;hpb=367316f5f21281204393853910848fea7fb9a6ab;p=sbcl.git diff --git a/src/compiler/aliencomp.lisp b/src/compiler/aliencomp.lisp index eff524d..4321c31 100644 --- a/src/compiler/aliencomp.lisp +++ b/src/compiler/aliencomp.lisp @@ -190,6 +190,8 @@ (abort-ir1-transform "too many indices for pointer deref: ~W" (length indices))) (let ((element-type (alien-pointer-type-to alien-type))) + (unless element-type + (give-up-ir1-transform "unable to open code deref of wild pointer type")) (if indices (let ((bits (alien-type-bits element-type)) (alignment (alien-type-alignment element-type))) @@ -613,7 +615,36 @@ `(lambda (function ,@names) (alien-funcall (deref function) ,@names)))) -(deftransform alien-funcall ((function &rest args) * * :important t) +;;; 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) + (declare #-sb-xc-host (muffle-conditions compiler-note) + (optimize (speed 3))) + (let* ((fp-and-pc (cons (%caller-frame) + (sap-int (%caller-pc))))) + (declare (truly-dynamic-extent fp-and-pc)) + (let ((*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 *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) * * :node node :important t) (let ((type (lvar-type function))) (unless (alien-type-type-p type) (give-up-ir1-transform "can't tell function type at compile time")) @@ -667,6 +698,12 @@ `(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 + (when (policy node (<= speed debug)) + (setf body `(invoke-with-saved-fp-and-pc (lambda () ,body)))) (/noshow "returning from DEFTRANSFORM ALIEN-FUNCALL" (params) body) `(lambda (function ,@(params)) ,body))))))) @@ -680,7 +717,8 @@ (error "Something is broken.")) (values-specifier-type (compute-alien-rep-type - (alien-fun-type-result-type type))))) + (alien-fun-type-result-type type) + :result)))) (defoptimizer (%alien-funcall ltn-annotate) ((function type &rest args) node ltn-policy)