--- nono/lib/header.h 2026/04/29 17:04:34 1.1.1.4 +++ nono/lib/header.h 2026/04/29 17:05:08 1.1.1.15 @@ -4,12 +4,16 @@ // Licensed under nono-license.txt // +// +// 基本ヘッダ +// + #pragma once #define NONO_MAJOR_VER (0) -#define NONO_MINOR_VER (1) +#define NONO_MINOR_VER (3) #define NONO_PATCH_VER (0) -#define NONO_DATE "2020/07/19" +#define NONO_DATE "2022/04/30" #include "config-nono.h" #include @@ -27,7 +31,6 @@ #include #include #include -#include #include using uint8 = uint8_t; @@ -39,18 +42,12 @@ using int16 = int16_t; using int32 = int32_t; using int64 = int64_t; -#if defined(HAVE_ENDIAN_H) -#include -#elif defined(HAVE_SYS_ENDIAN_H) -#include -#else -#include "missing_endian.h" -#endif - #if defined(HAVE_BSD_BSD_H) #include #endif +#include "myendian.h" + #if !defined(__printflike) #if defined(HAVE___ATTRIBUTE_FORMAT) # define __printflike(a,b) __attribute__((__format__(__printf__, (a), (b)))) @@ -114,9 +111,20 @@ using int64 = int64_t; # define NO_SANITIZE(x) #endif +// x86_64 では SSE のために16バイト境界に整列させたいが、ほかの +// アーキテクチャでは alignas(16) がエラーになる場合がある。この場合の +// alignas() は SSE のために必要なので、他アーキテクチャではそもそも +// 指定しなくていい。ということで x86_64 の時に限って指定したい時に使う。 +// うーん、なんだこれ。 +#if defined(__x86_64__) +#define ALIGNAS_IF_X86(n) alignas(n) +#else +#define ALIGNAS_IF_X86(n) /**/ +#endif + // 64ビット数と2つの32ビット数を扱う共用体。 // 構造はまったく同じだが名前だけ場所に合わせてつけたい。 -#if _BYTE_ORDER == _LITTLE_ENDIAN +#if BYTE_ORDER == LITTLE_ENDIAN #define DEF_UNION64(NAME, Q, H, L) \ union NAME { \ uint64 Q; \ @@ -136,17 +144,27 @@ DEF_UNION64(union64, q, h, l); #define countof(x) (sizeof(x) / sizeof(x[0])) #endif +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#ifndef rounddown +#define rounddown(x, y) (((x)/(y))*(y)) +#endif + // メッセージ付きの assert。 -#define assertmsg(expr, fmt, ...) do { \ +// 本当は後ろに足したいのだがそれは無理なので、せめてそれっぽく1行にしてみる。 +#if !defined(NDEBUG) +#define assertmsg(expr, ...) do { \ if (__predict_false(!(expr))) { \ - fprintf(stderr, fmt "\n", __VA_ARGS__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, ": "); \ assert(expr); \ } \ } while (0) - -// 便利マクロ -#define kevent_set(k, e, n) kevent((k), (e), (n), NULL, 0, NULL) -#define kevent_poll(k, e, n, t) kevent((k), NULL, 0, (e), (n), (t)) +#else +#define assertmsg(expr, ...) +#endif // atomic_compare_exchange_strong() の短縮マクロ。 // ライブラリ実装は第2引数の expected が値ではなくポインタなので一旦代入操作を @@ -166,7 +184,12 @@ DEF_UNION64(union64, q, h, l); atomic_compare_exchange_strong((varp), &expected, (uint32)(newval)); \ }) -// ログ +// パニック (PC を表示しない) #define PANIC(...) panic(__PRETTY_FUNCTION__, __VA_ARGS__) [[noreturn]] extern void panic(const char *funcname, const char *fmt, ...) __printflike(2, 3); + +// VM 用パニック (PC を表示する) +#define VMPANIC(...) vmpanic(__PRETTY_FUNCTION__, __VA_ARGS__) +[[noreturn]] extern void vmpanic(const char *funcname, const char *fmt, ...) + __printflike(2, 3);