X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=tests%2Falien.impure.lisp;h=6637dba7fb5f4ef24aad96ce962de66ae7c6dd55;hb=31f68584d0732dc0d17f379773e5f87f1e5a78ad;hp=d1ee3e3adf0c3bcf1f8a32062cdbf0f5a20896b1;hpb=389b5755b2eab960c1f4c14045a26de5dbd510c1;p=sbcl.git diff --git a/tests/alien.impure.lisp b/tests/alien.impure.lisp index d1ee3e3..6637dba 100644 --- a/tests/alien.impure.lisp +++ b/tests/alien.impure.lisp @@ -20,8 +20,8 @@ ;;; In sbcl-0.6.10, Douglas Brebner reported that (SETF EXTERN-ALIEN) ;;; was messed up so badly that trying to execute expressions like ;;; this signalled an error. -(setf (sb-alien:extern-alien "current_control_stack_pointer" sb-alien:unsigned) - (sb-alien:extern-alien "current_control_stack_pointer" sb-alien:unsigned)) +(setf (sb-alien:extern-alien "thread_control_stack_size" sb-alien:unsigned) + (sb-alien:extern-alien "thread_control_stack_size" sb-alien:unsigned)) ;;; bug 133, fixed in 0.7.0.5: Somewhere in 0.pre7.*, C void returns ;;; were broken ("unable to use values types here") when @@ -203,4 +203,214 @@ (error () :ok))))) +;;; Unused local alien caused a compiler error +(with-test (:name :unused-local-alien) + (let ((fun `(lambda () + (sb-alien:with-alien ((alien1923 (array (sb-alien:unsigned 8) 72))) + (values))))) + (assert (not (funcall (compile nil fun)))))) + +;;; Non-local exit from WITH-ALIEN caused alien stack to be leaked. +(defvar *sap-int*) +(defun try-to-leak-alien-stack (x) + (with-alien ((alien (array (sb-alien:unsigned 8) 72))) + (let ((sap-int (sb-sys:sap-int (alien-sap alien)))) + (if *sap-int* + (assert (= *sap-int* sap-int)) + (setf *sap-int* sap-int))) + (when x + (return-from try-to-leak-alien-stack 'going)) + (never))) +(with-test (:name :nlx-causes-alien-stack-leak) + (let ((*sap-int* nil)) + (loop repeat 1024 + do (try-to-leak-alien-stack t)))) + +;;; bug 431 +(with-test (:name :alien-struct-redefinition) + (eval '(progn + (define-alien-type nil (struct mystruct (myshort short) (mychar char))) + (with-alien ((myst (struct mystruct))) + (with-alien ((mysh short (slot myst 'myshort))) + (assert (integerp mysh)))))) + (let ((restarted 0)) + (handler-bind ((error (lambda (e) + (let ((cont (find-restart 'continue e))) + (when cont + (incf restarted) + (invoke-restart cont)))))) + (eval '(define-alien-type nil (struct mystruct (myint int) (mychar char))))) + (assert (= 1 restarted))) + (eval '(with-alien ((myst (struct mystruct))) + (with-alien ((myin int (slot myst 'myint))) + (assert (integerp myin)))))) + +;;; void conflicted with derived type +(declaim (inline bug-316075)) +#-win32 ;kludge: This reader conditional masks a bug, but allows the test + ;to fail cleanly. +(sb-alien:define-alien-routine bug-316075 void (result char :out)) +(with-test (:name :bug-316075 :fails-on :win32) + #+win32 (error "fail") + (handler-bind ((warning #'error)) + (compile nil '(lambda () (multiple-value-list (bug-316075)))))) + + +;;; Bug #316325: "return values of alien calls assumed truncated to +;;; correct width on x86" +#+x86-64 +(sb-alien::define-alien-callback truncation-test (unsigned 64) + ((foo (unsigned 64))) + foo) +#+x86 +(sb-alien::define-alien-callback truncation-test (unsigned 32) + ((foo (unsigned 32))) + foo) + +(with-test (:name :bug-316325 :skipped-on '(not (or :x86-64 :x86))) + ;; This test works by defining a callback function that provides an + ;; identity transform over a full-width machine word, then calling + ;; it as if it returned a narrower type and checking to see if any + ;; noise in the high bits of the result are properly ignored. + (macrolet ((verify (type input output) + `(with-alien ((fun (* (function ,type + #+x86-64 (unsigned 64) + #+x86 (unsigned 32))) + :local (alien-sap truncation-test))) + (let ((result (alien-funcall fun ,input))) + (assert (= result ,output)))))) + #+x86-64 + (progn + (verify (unsigned 64) #x8000000000000000 #x8000000000000000) + (verify (signed 64) #x8000000000000000 #x-8000000000000000) + (verify (signed 64) #x7fffffffffffffff #x7fffffffffffffff) + (verify (unsigned 32) #x0000000180000042 #x80000042) + (verify (signed 32) #x0000000180000042 #x-7fffffbe) + (verify (signed 32) #xffffffff7fffffff #x7fffffff)) + #+x86 + (progn + (verify (unsigned 32) #x80000042 #x80000042) + (verify (signed 32) #x80000042 #x-7fffffbe) + (verify (signed 32) #x7fffffff #x7fffffff)) + (verify (unsigned 16) #x00018042 #x8042) + (verify (signed 16) #x003f8042 #x-7fbe) + (verify (signed 16) #x003f7042 #x7042))) + +(with-test (:name :bug-654485) + ;; DEBUG 2 used to prevent let-conversion of the open-coded ALIEN-FUNCALL body, + ;; which in turn led the dreaded %SAP-ALIEN note. + (handler-case + (compile nil + `(lambda (program argv) + (declare (optimize (debug 2))) + (with-alien ((sys-execv1 (function int c-string (* c-string)) :extern + "execv")) + (values (alien-funcall sys-execv1 program argv))))) + (compiler-note (n) + (error "bad note: ~A" n)))) + +(with-test (:name :bug-721087 :fails-on :win32) + (assert (typep nil '(alien c-string))) + (assert (not (typep nil '(alien (c-string :not-null t))))) + (assert (eq :ok + (handler-case + (posix-getenv nil) + (type-error (e) + (when (and (null (type-error-datum e)) + (equal (type-error-expected-type e) + '(alien (c-string :not-null t)))) + :ok)))))) + +(with-test (:name :make-alien-string) + (let ((alien (sb-alien::make-alien-string "This comes from lisp!"))) + (gc :full t) + (assert (equal "This comes from lisp!" (cast alien c-string))) + (free-alien alien))) + +(with-test (:name :malloc-failure) + (assert (eq :enomem + (handler-case + (loop repeat 128 + collect (sb-alien:make-alien char (1- array-total-size-limit))) + (storage-condition () + :enomem))))) + +(with-test (:name :bug-985505) + ;; Check that correct octets are reported for a c-string-decoding error. + (assert + (eq :unibyte + (handler-case + (let ((c-string (coerce #(70 111 195 182 0) + '(vector (unsigned-byte 8))))) + (sb-sys:with-pinned-objects (c-string) + (sb-alien::c-string-to-string (sb-sys:vector-sap c-string) + :ascii 'character))) + (sb-int:c-string-decoding-error (e) + (assert (equalp #(195) (sb-int:character-decoding-error-octets e))) + :unibyte)))) + (assert + (eq :multibyte-4 + (handler-case + ;; KLUDGE, sort of. + ;; + ;; C-STRING decoding doesn't know how long the string is, and since this + ;; looks like a 4-byte sequence, it will grab 4 octets off the end. + ;; + ;; So we pad the vector for safety's sake. + (let ((c-string (coerce #(70 111 246 0 0 0) + '(vector (unsigned-byte 8))))) + (sb-sys:with-pinned-objects (c-string) + (sb-alien::c-string-to-string (sb-sys:vector-sap c-string) + :utf-8 'character))) + (sb-int:c-string-decoding-error (e) + (assert (equalp #(246 0 0 0) + (sb-int:character-decoding-error-octets e))) + :multibyte-4)))) + (assert + (eq :multibyte-2 + (handler-case + (let ((c-string (coerce #(70 195 1 182 195 182 0) '(vector (unsigned-byte 8))))) + (sb-sys:with-pinned-objects (c-string) + (sb-alien::c-string-to-string (sb-sys:vector-sap c-string) + :utf-8 'character))) + (sb-int:c-string-decoding-error (e) + (assert (equalp #(195 1) + (sb-int:character-decoding-error-octets e))) + :multibyte-2))))) + +(with-test (:name :stream-to-c-string-decoding-restart-leakage) + ;; Restarts for stream decoding errors didn't use to be associated with + ;; their conditions, so they could get confused with c-string decoding errors. + (assert (eq :nesting-ok + (catch 'out + (handler-bind ((sb-int:character-decoding-error + (lambda (stream-condition) + (handler-bind ((sb-int:character-decoding-error + (lambda (c-string-condition) + (throw 'out + (if (find-restart + 'sb-impl::input-replacement + c-string-condition) + :bad-restart + :nesting-ok))))) + (let ((c-string (coerce #(70 195 1 182 195 182 0) + '(vector (unsigned-byte 8))))) + (sb-sys:with-pinned-objects (c-string) + (sb-alien::c-string-to-string + (sb-sys:vector-sap c-string) + :utf-8 'character))))))) + (let ((namestring "alien.impure.tmp")) + (unwind-protect + (progn + (with-open-file (f namestring + :element-type '(unsigned-byte 8) + :direction :output + :if-exists :supersede) + (dolist (b '(70 195 1 182 195 182 0)) + (write-byte b f))) + (with-open-file (f namestring + :external-format :utf-8) + (read-line f))) + (delete-file namestring)))))))) + ;;; success