1.0.4.1: fix sb-posix atime/mtime/ctime
[sbcl.git] / tests / alien.impure.lisp
index e215ad2..d1ee3e3 100644 (file)
                          v)))))
   (assert (typep (funcall f "HOME") '(or string null))))
 
+
+;;; CLH: Test for non-standard alignment in alien structs
+;;;
+(sb-alien:define-alien-type align-test-struct
+    (sb-alien:union align-test-union
+                    (s (sb-alien:struct nil
+                                        (s1 sb-alien:unsigned-char)
+                                        (c1 sb-alien:unsigned-char :alignment 16)
+                                        (c2 sb-alien:unsigned-char :alignment 32)
+                                        (c3 sb-alien:unsigned-char :alignment 32)
+                                        (c4 sb-alien:unsigned-char :alignment 8)))
+                    (u (sb-alien:array sb-alien:unsigned-char 16))))
+
+(let ((a1 (sb-alien:make-alien align-test-struct)))
+  (declare (type (sb-alien:alien (* align-test-struct)) a1))
+  (setf (sb-alien:slot (sb-alien:slot a1 's) 's1) 1)
+  (setf (sb-alien:slot (sb-alien:slot a1 's) 'c1) 21)
+  (setf (sb-alien:slot (sb-alien:slot a1 's) 'c2) 41)
+  (setf (sb-alien:slot (sb-alien:slot a1 's) 'c3) 61)
+  (setf (sb-alien:slot (sb-alien:slot a1 's) 'c4) 81)
+  (assert (equal '(1 21 41 61 81)
+                 (list (sb-alien:deref (sb-alien:slot a1 'u) 0)
+                       (sb-alien:deref (sb-alien:slot a1 'u) 2)
+                       (sb-alien:deref (sb-alien:slot a1 'u) 4)
+                       (sb-alien:deref (sb-alien:slot a1 'u) 8)
+                       (sb-alien:deref (sb-alien:slot a1 'u) 9)))))
+
+(handler-bind ((compiler-note (lambda (c)
+                                (error "bad note! ~A" c))))
+  (funcall (compile nil '(lambda () (sb-alien:make-alien sb-alien:int)))))
+
+;;; Test case for unwinding an alien (Win32) exception frame
+;;;
+;;; The basic theory here is that failing to honor a win32
+;;; exception frame during stack unwinding breaks the chain.
+;;; "And if / You don't love me now / You will never love me
+;;; again / I can still hear you saying / You would never break
+;;; the chain."  If the chain is broken and another exception
+;;; occurs (such as an error trap caused by an OBJECT-NOT-TYPE
+;;; error), the system will kill our process.  No mercy, no
+;;; appeal. So, to check that we have done our job properly, we
+;;; need some way to put an exception frame on the stack and then
+;;; unwind through it, then trigger another exception.  (FUNCALL
+;;; 0) will suffice for the latter, and a simple test shows that
+;;; CallWindowProc() establishes a frame and calls a function
+;;; passed to it as an argument.
+#+win32
+(progn
+  (load-shared-object "USER32")
+  (assert
+   (eq :ok
+       (handler-case
+           (tagbody
+              (alien-funcall
+               (extern-alien "CallWindowProcW"
+                             (function unsigned-int
+                                       (* (function int)) unsigned-int
+                                       unsigned-int unsigned-int unsigned-int))
+               (alien-sap
+                (sb-alien::alien-callback (function unsigned-int)
+                                          #'(lambda () (go up))))
+               0 0 0 0)
+            up
+              (funcall 0))
+         (error ()
+           :ok)))))
+
 ;;; success