Skip to content

Commit 951d3bb

Browse files
committed
Make autogenerated headers mostly self-contained
1 parent 8612a82 commit 951d3bb

File tree

5 files changed

+96
-50
lines changed

5 files changed

+96
-50
lines changed

src/compiler/generic/genesis.lisp

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,6 +3130,7 @@ Legal values for OFFSET are -4, -8, -12, ..."
31303130
(write-string "," out))
31313131
(terpri out)))
31323132
(write-line "};" out)))
3133+
(format out "#include <stddef.h>~%") ; for NULL
31333134
(write-tags "static " "-LOWTAG" sb-vm:lowtag-limit 0)
31343135
;; this -2 shift depends on every OTHER-IMMEDIATE-?-LOWTAG
31353136
;; ending with the same 2 bits. (#b10)
@@ -3170,40 +3171,46 @@ Legal values for OFFSET are -4, -8, -12, ..."
31703171
(slots (sb-vm:primitive-object-slots obj))
31713172
(lowtag (or (symbol-value (sb-vm:primitive-object-lowtag obj)) 0)))
31723173
;; writing primitive object layouts
3173-
(format t "#ifndef __ASSEMBLER__~2%")
3174-
(when (eq name 'sb-vm::thread)
3175-
(format t "#define THREAD_HEADER_SLOTS ~d~%" sb-vm::thread-header-slots)
3176-
(dolist (x sb-vm::*thread-header-slot-names*)
3177-
(let ((s (package-symbolicate "SB-VM" "THREAD-" x "-SLOT")))
3178-
(format t "#define ~a ~d~%"
3179-
(c-name (string s)) (symbol-value s))))
3180-
(terpri))
3181-
(format t "struct ~A {~%" c-name)
3182-
(when (sb-vm:primitive-object-widetag obj)
3183-
(format t " lispobj header;~%"))
3184-
(dolist (slot slots)
3185-
(format t " ~A ~A~@[[1]~];~%"
3186-
(getf (sb-vm:slot-options slot) :c-type "lispobj")
3187-
(c-name (string-downcase (sb-vm:slot-name slot)))
3188-
(sb-vm:slot-rest-p slot)))
3189-
(format t "};~%")
3190-
(when (member name '(cons vector symbol fdefn))
3191-
(write-cast-operator name c-name lowtag))
3192-
(format t "~%#else /* __ASSEMBLER__ */~2%")
3193-
(format t "/* These offsets are SLOT-OFFSET * N-WORD-BYTES - LOWTAG~%")
3194-
(format t " * so they work directly on tagged addresses. */~2%")
3195-
(dolist (slot slots)
3196-
(format t "#define ~A_~A_OFFSET ~D~%"
3197-
(c-symbol-name name)
3198-
(c-symbol-name (sb-vm:slot-name slot))
3199-
(- (* (sb-vm:slot-offset slot) sb-vm:n-word-bytes) lowtag)))
3200-
(format t "#define ~A_SIZE ~d~%"
3201-
(string-upcase c-name) (sb-vm:primitive-object-length obj)))
3202-
(format t "~%#endif /* __ASSEMBLER__ */~2%"))
3174+
(flet ((output-c ()
3175+
(when (eq name 'sb-vm::thread)
3176+
(format t "#define THREAD_HEADER_SLOTS ~d~%" sb-vm::thread-header-slots)
3177+
(dolist (x sb-vm::*thread-header-slot-names*)
3178+
(let ((s (package-symbolicate "SB-VM" "THREAD-" x "-SLOT")))
3179+
(format t "#define ~a ~d~%"
3180+
(c-name (string s)) (symbol-value s))))
3181+
(terpri))
3182+
(format t "struct ~A {~%" c-name)
3183+
(when (sb-vm:primitive-object-widetag obj)
3184+
(format t " lispobj header;~%"))
3185+
(dolist (slot slots)
3186+
(format t " ~A ~A~@[[1]~];~%"
3187+
(getf (sb-vm:slot-options slot) :c-type "lispobj")
3188+
(c-name (string-downcase (sb-vm:slot-name slot)))
3189+
(sb-vm:slot-rest-p slot)))
3190+
(format t "};~%")
3191+
(when (member name '(cons vector symbol fdefn))
3192+
(write-cast-operator name c-name lowtag)))
3193+
(output-asm ()
3194+
(format t "/* These offsets are SLOT-OFFSET * N-WORD-BYTES - LOWTAG~%")
3195+
(format t " * so they work directly on tagged addresses. */~2%")
3196+
(dolist (slot slots)
3197+
(format t "#define ~A_~A_OFFSET ~D~%"
3198+
(c-symbol-name name)
3199+
(c-symbol-name (sb-vm:slot-name slot))
3200+
(- (* (sb-vm:slot-offset slot) sb-vm:n-word-bytes) lowtag)))
3201+
(format t "#define ~A_SIZE ~d~%"
3202+
(string-upcase c-name) (sb-vm:primitive-object-length obj))))
3203+
(format t "#ifdef __ASSEMBLER__~2%")
3204+
(output-asm)
3205+
(format t "~%#else /* __ASSEMBLER__ */~2%")
3206+
(format t "#include \"lispobj.h\"~%")
3207+
(output-c)
3208+
(format t "~%#endif /* __ASSEMBLER__ */~%"))))
32033209

32043210
(defun write-structure-object (dd *standard-output* &optional structname)
32053211
(flet ((cstring (designator) (c-name (string-downcase designator))))
32063212
(format t "#ifndef __ASSEMBLER__~2%")
3213+
(format t "#include \"lispobj.h\"~%")
32073214
(format t "struct ~A {~%" (or structname (cstring (dd-name dd))))
32083215
(format t " lispobj header; // = word_0_~%")
32093216
;; "self layout" slots are named '_layout' instead of 'layout' so that
@@ -3846,19 +3853,40 @@ III. initially undefined function references (alphabetically):
38463853
(ensure-directories-exist filename)
38473854
(with-open-file (stream filename :direction :output :if-exists :supersede)
38483855
(write-makefile-features stream)))
3849-
3850-
(macrolet ((out-to (name &body body) ; write boilerplate and inclusion guard
3851-
(let ((headerp (if (and (stringp name) (position #\. name)) nil ".h")))
3852-
`(with-open-file (stream (format nil "~A/~A~@[~A~]"
3853-
c-header-dir-name ,name ,headerp)
3854-
:direction :output :if-exists :supersede)
3855-
(write-boilerplate stream)
3856-
,(when headerp
3857-
`(format stream
3858-
"#ifndef SBCL_GENESIS_~A~%#define SBCL_GENESIS_~:*~A~%"
3859-
(c-name (string-upcase ,name))))
3860-
,@body
3861-
,(when headerp `(format stream "#endif~%"))))))
3856+
(write-c-headers c-header-dir-name))))
3857+
3858+
(defun write-c-headers (c-header-dir-name)
3859+
(macrolet ((out-to (name &body body) ; write boilerplate and inclusion guard
3860+
`(actually-out-to ,name (lambda (stream) ,@body))))
3861+
(flet ((actually-out-to (name lambda)
3862+
;; A file gets a '.inc' extension, not '.h' for either or both
3863+
;; of two reasons:
3864+
;; - if it isn't self-contained, meaning that in order to #include it,
3865+
;; the consumer of it has to know something about which other headers
3866+
;; need to be #included first.
3867+
;; - it is not intended to be directly consumed because any use would
3868+
;; typically need to wrap each slot in some small calculation
3869+
;; such as native_pointer(), but we don't want to embed the wrapper
3870+
;; accessors into the autogenerated header. So there would instead be
3871+
;; a "src/runtime/foo.h" which includes "src/runtime/genesis/foo.inc"
3872+
;; 'thread.h' and 'gc-tables.h' violate the naming convention
3873+
;; by being non-self-contained.
3874+
(let* ((extension
3875+
(cond ((and (stringp name) (position #\. name)) nil)
3876+
(t ".h")))
3877+
(inclusion-guardp
3878+
(string= extension ".h")))
3879+
(with-open-file (stream (format nil "~A/~A~@[~A~]"
3880+
c-header-dir-name name extension)
3881+
:direction :output :if-exists :supersede)
3882+
(write-boilerplate stream)
3883+
(when inclusion-guardp
3884+
(format stream
3885+
"#ifndef SBCL_GENESIS_~A~%#define SBCL_GENESIS_~:*~A~%"
3886+
(c-name (string-upcase name))))
3887+
(funcall lambda stream)
3888+
(when inclusion-guardp
3889+
(format stream "#endif~%"))))))
38623890
(out-to "config" (write-config-h stream))
38633891
(out-to "constants" (write-constants-h stream))
38643892
(out-to "regnames" (write-regnames-h stream))
@@ -3888,7 +3916,7 @@ III. initially undefined function references (alphabetically):
38883916
(write-boilerplate stream) ; no inclusion guard, it's not a ".h" file
38893917
(write-thread-init stream))
38903918
(out-to "static-symbols" (write-static-symbols stream))
3891-
(out-to "sc-offset" (write-sc+offset-coding stream))))))
3919+
(out-to "sc-offset" (write-sc+offset-coding stream)))))
38923920

38933921
;;; Invert the action of HOST-CONSTANT-TO-CORE. If STRICTP is given as NIL,
38943922
;;; then we can produce a host object even if it is not a faithful rendition.

src/compiler/generic/late-objdef.lisp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127

128128
#+sb-xc-host
129129
(defun write-gc-tables (stream)
130+
(format stream "#include \"lispobj.h\"~%")
130131
;; Compute a bitmask of all specialized vector types,
131132
;; not including array headers, for maybe_adjust_large_object().
132133
(let ((min #xff) (bits 0))
@@ -135,14 +136,14 @@
135136
(let ((widetag (saetp-typecode saetp)))
136137
(setf min (min widetag min)
137138
bits (logior bits (ash 1 (ash widetag -2)))))))
138-
(format stream "static inline boolean specialized_vector_widetag_p(unsigned char widetag) {
139+
(format stream "static inline int specialized_vector_widetag_p(unsigned char widetag) {
139140
return widetag>=0x~X && (0x~8,'0XU >> ((widetag-0x80)>>2)) & 1;~%}~%"
140141
min (ldb (byte 32 32) bits))
141142
;; Union in the bits for other unboxed object types.
142143
(dolist (entry *scav/trans/size*)
143144
(when (string= (second entry) "unboxed")
144145
(setf bits (logior bits (ash 1 (ash (car entry) -2))))))
145-
(format stream "static inline boolean leaf_obj_widetag_p(unsigned char widetag) {~%")
146+
(format stream "static inline int leaf_obj_widetag_p(unsigned char widetag) {~%")
146147
#+64-bit (format stream " return (0x~XLU >> (widetag>>2)) & 1;" bits)
147148
#-64-bit (format stream " int bit = widetag>>2;
148149
return (bit<32 ? 0x~XU >> bit : 0x~XU >> (bit-32)) & 1;"

src/runtime/lispobj.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef _RUNTIME_LISPOBJ_H_
2+
#define _RUNTIME_LISPOBJ_H_
3+
4+
#include <stdint.h>
5+
typedef intptr_t sword_t;
6+
typedef uintptr_t uword_t;
7+
typedef uword_t lispobj;
8+
9+
#endif

src/runtime/runtime.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#ifndef _SBCL_RUNTIME_H_
1616
#define _SBCL_RUNTIME_H_
1717

18+
#include "lispobj.h"
19+
1820
#if defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD)
1921
# include "pthreads_win32.h"
2022
#else
@@ -192,11 +194,7 @@ void dyndebug_init(void);
192194

193195
#include <sys/types.h>
194196

195-
typedef uintptr_t uword_t;
196-
typedef intptr_t sword_t;
197-
198197
#define OBJ_FMTX PRIxPTR
199-
typedef uintptr_t lispobj;
200198

201199
static inline int
202200
lowtag_of(lispobj obj)

verify-header-parsing.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/sh
2+
3+
# This script is not part of the build, but running it tells you
4+
# whether each genesis headers can be included without fussing
5+
# around with all sorts of other headers.
6+
for i in src/runtime/genesis/*.h
7+
do
8+
echo '#include "'$i'"' > tmp.c
9+
cc -Isrc/runtime -c tmp.c
10+
done

0 commit comments

Comments
 (0)