From 8c2c58ae77fe3afce6ac4d027e9e47157a535961 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Tue, 15 Dec 2015 19:15:23 +0000 Subject: [PATCH] Add a new class slot `align', holding the instance layout alignment. Or at least a conservative approximation of it. --- doc/structures.tex | 3 +++ lib/sod-structs.3 | 4 ++++ lib/sod.h | 32 +++++++++++++++++++++++++++++++- src/builtin.lisp | 3 +++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/doc/structures.tex b/doc/structures.tex index d379c99..b63a336 100644 --- a/doc/structures.tex +++ b/doc/structures.tex @@ -139,6 +139,7 @@ recommended. const char *name; \\ const char *nick; \\ size_t initsz; \\ + size_t align; \\ void *(*imprint)(void *@

); \\ void *(*init)(void *@

); \\ size_t n_supers; \\ @@ -167,6 +168,8 @@ recommended. \item[initsz] The size in bytes required to store an instance of the class. + \item[align] A sufficient alignment for the class's instance storage. + \item[imprint] A pointer to a function: given a pointer @

to at least @ bytes of appropriately aligned memory, `imprint' this memory it so that it becomes a minimally functional instance of the class: all of diff --git a/lib/sod-structs.3 b/lib/sod-structs.3 index a6c9db2..5624d33 100644 --- a/lib/sod-structs.3 +++ b/lib/sod-structs.3 @@ -95,6 +95,7 @@ struct SodObject__ilayout { \h'8n'const char *name; \h'8n'const char *nick; \h'8n'size_t initsz; +\h'8n'size_t align; \h'8n'void *(*imprint)(void *\fIp\fB); \h'8n'void *(*init)(void *\fIp\fB); \h'8n'size_t n_supers; @@ -253,6 +254,9 @@ A pointer to the class's nickname. .B size_t initsz; The size in bytes required to store an instance of the class. .TP +.B size_t align; +A sufficient alignment for the class's instance storage. +.TP .BI "void *(*imprint)(void *" p ); A pointer to a function: given a pointer diff --git a/lib/sod.h b/lib/sod.h index 360afa8..943ed4b 100644 --- a/lib/sod.h +++ b/lib/sod.h @@ -34,6 +34,16 @@ /*----- Preliminary utilities ---------------------------------------------*/ +/* Various hacks for checking compiler versions. */ +#define SOD__GCC_P(maj, min) \ + (__GNUC__ > (maj) || (__GNUC__ == (maj) && __GNUC_MINOR__ >= (min))) + +#ifdef __GNUC__ +# define SOD__EXTENSION __extension__ +#else +# define SOD__EXTENSION +#endif + /* --- @SOD__HAVE_VARARGS_MACROS@ --- * * * Use: Defined if the compiler supports C99-style variadic macros. @@ -49,7 +59,7 @@ # define SOD__HAVE_VARARGS_MACROS -#elif __GNUC__ >= 3 +#elif SOD__GCC_P(3, 0) /* We're using GCC, which is trying to deny it but we don't believe it. * Unfortunately there's a fly in the ointment: if `-pedantic' -- or, * worse, `-pedantic-errors' -- is set, then GCC will warn about these @@ -77,6 +87,26 @@ /* We're going to want to make use of this ourselves. */ SOD__VARARGS_MACROS_PREAMBLE +/* --- @SOD__ALIGNOF@ --- * + * + * Arguments: @type@ = a C type name, consisting of declaration specifiers + * and `*[QUALIFIERS]' declarator operators + * + * Returns: A sufficient alignment for objects of the given @type@, as a + * @size_t@. + */ + +#if __STDC_VERSION__ >= 201112 +# define SOD__ALIGNOF(type) _Alignof(type) +#elif SOD__GCC_P(4, 7) +# define SOD__ALIGNOF(type) __extension__ _Alignof(type) +#elif defined(__GNUC__) +# define SOD__ALIGNOF(type) __alignof__(type) +#else +# define SOD__ALIGNOF(type) \ +offsetof(struct { char sod__x; type sod__y; }, sod__y) +#endif + /* --- @SOD__CAR@ --- * * * Arguments: @...@ = a nonempty list of arguments diff --git a/src/builtin.lisp b/src/builtin.lisp index 1c14f19..fbef93b 100644 --- a/src/builtin.lisp +++ b/src/builtin.lisp @@ -85,6 +85,9 @@ (define-class-slot "initsz" (class) size-t (format nil "sizeof(struct ~A)" (ilayout-struct-tag class))) +(define-class-slot "align" (class) size-t + (format nil "SOD__ALIGNOF(struct ~A)" (ilayout-struct-tag class))) + (define-class-slot "imprint" (class stream) (* (fun (* void) ("/*p*/" (* void)))) (format nil "~A__imprint" class) -- 2.11.0