Skip to content

Commit

Permalink
Add compiler macro foreign-type-size
Browse files Browse the repository at this point in the history
The compiler macro is a first-pass that should fix most use cases
without breakage. It checks to see if the foreign type is constant, and
if so, expands into its foreign type size, falling back to the old form
if an error is signaled.
  • Loading branch information
samuel-hunter committed Nov 7, 2022
1 parent d4216a3 commit 64140b4
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/early-types.lisp
Expand Up @@ -164,6 +164,13 @@ Signals an error if FOREIGN-TYPE is undefined."))
(:documentation
"Return the size in bytes of a foreign type."))

(define-compiler-macro foreign-type-size (&whole form foreign-type)
;; Don't pass &environment to CONSTANTP or MACROEXPAND as LOAD-TIME-VALUE is
;; executed in a null lexical environment.
(if (constantp (macroexpand foreign-type))
`(load-time-value (locally (declare (notinline foreign-type-size)) ,form))
form))

(defgeneric unparse-type (foreign-type)
(:documentation
"Unparse FOREIGN-TYPE to a type specification (symbol or list)."))
Expand Down
30 changes: 30 additions & 0 deletions tests/misc.lisp
Expand Up @@ -130,3 +130,33 @@
(strcpy pointer "xpto")
(return vector))))
#(120 112 116 111 0))

;;; Inline foreign-type-size

(deftest foreign-type-size.inline.int
(eql (foreign-type-size :int) (locally (declare (notinline foreign-type-size)) (foreign-type-size :int)))
t)

(deftest foreign-type-size.inline.uint32
(eql (foreign-type-size :uint32) (locally (declare (notinline foreign-type-size)) (foreign-type-size :uint32)))
t)

(deftest foreign-type-size.inline.ptrdiff
(eql (foreign-type-size :ptrdiff) (locally (declare (notinline foreign-type-size)) (foreign-type-size :ptrdiff)))
t)

(deftest foreign-type-size.inline.size
(eql (foreign-type-size :size) (locally (declare (notinline foreign-type-size)) (foreign-type-size :size)))
t)

(deftest foreign-type-size.inline.offset
(eql (foreign-type-size :offset) (locally (declare (notinline foreign-type-size)) (foreign-type-size :offset)))
t)

(deftest foreign-type-size.inline.uintptr
(eql (foreign-type-size :uintptr) (locally (declare (notinline foreign-type-size)) (foreign-type-size :uintptr)))
t)

(deftest foreign-type-size.inline.intptr
(eql (foreign-type-size :intptr) (locally (declare (notinline foreign-type-size)) (foreign-type-size :intptr)))
t)

0 comments on commit 64140b4

Please sign in to comment.