X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Faliencomp.lisp;h=4321c3174ba69099d534c5917eba053834626003;hb=49e8403800426f37a54d9b87353a31af36e7af40;hp=bc5b11a2ac8117e7aa3d42f8e09c28454b9049a1;hpb=60053af56e69de2fd251cde8fcdb2ea7f01d0b01;p=sbcl.git diff --git a/src/compiler/aliencomp.lisp b/src/compiler/aliencomp.lisp index bc5b11a..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))) @@ -349,28 +351,26 @@ (/noshow (local-alien-info-force-to-memory-p info)) (/noshow alien-type (unparse-alien-type alien-type) (alien-type-bits alien-type)) (if (local-alien-info-force-to-memory-p info) - #!+(or x86 x86-64) - `(truly-the system-area-pointer - (%primitive alloc-alien-stack-space - ,(ceiling (alien-type-bits alien-type) - sb!vm:n-byte-bits))) - #!-(or x86 x86-64) - `(truly-the system-area-pointer - (%primitive alloc-number-stack-space - ,(ceiling (alien-type-bits alien-type) - sb!vm:n-byte-bits))) - (let* ((alien-rep-type-spec (compute-alien-rep-type alien-type)) - (alien-rep-type (specifier-type alien-rep-type-spec))) - (cond ((csubtypep (specifier-type 'system-area-pointer) - alien-rep-type) - '(int-sap 0)) - ((ctypep 0 alien-rep-type) 0) - ((ctypep 0.0f0 alien-rep-type) 0.0f0) - ((ctypep 0.0d0 alien-rep-type) 0.0d0) - (t - (compiler-error - "Aliens of type ~S cannot be represented immediately." - (unparse-alien-type alien-type)))))))) + #!+(or x86 x86-64) + `(%primitive alloc-alien-stack-space + ,(ceiling (alien-type-bits alien-type) + sb!vm:n-byte-bits)) + #!-(or x86 x86-64) + `(%primitive alloc-number-stack-space + ,(ceiling (alien-type-bits alien-type) + sb!vm:n-byte-bits)) + (let* ((alien-rep-type-spec (compute-alien-rep-type alien-type)) + (alien-rep-type (specifier-type alien-rep-type-spec))) + (cond ((csubtypep (specifier-type 'system-area-pointer) + alien-rep-type) + '(int-sap 0)) + ((ctypep 0 alien-rep-type) 0) + ((ctypep 0.0f0 alien-rep-type) 0.0f0) + ((ctypep 0.0d0 alien-rep-type) 0.0d0) + (t + (compiler-error + "Aliens of type ~S cannot be represented immediately." + (unparse-alien-type alien-type)))))))) (deftransform note-local-alien-type ((info var) * * :important t) ;; FIXME: This test and error occur about a zillion times. They @@ -615,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")) @@ -669,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))))))) @@ -682,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)