From 8c0b63b6002b7a2b18ceea74bed365318e246ad3 Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Tue, 16 Jun 2026 14:50:43 -0400 Subject: [PATCH 1/9] gate typeof --- src/utils.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/utils.h b/src/utils.h index 56503aeb..d61c2743 100644 --- a/src/utils.h +++ b/src/utils.h @@ -10,15 +10,22 @@ #include "real_type.h" +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)) \ + || defined(__GNUC__) || defined(__clang__) || defined(__TINYC__) + #define TYPEOF(x) typeof(x) +#else + #define TYPEOF(x) long long +#endif + #define forEach(type, item, array, count) \ - for (typeof(count) item##_i_ = 0; item##_i_ < (count); item##_i_++) \ + for (TYPEOF(count) item##_i_ = 0; item##_i_ < (count); ++item##_i_) \ for (type* item = &(array)[item##_i_]; item; item = NULL) #define forEachIndexed(type, item, index, array, count) \ - for (typeof(count) index = 0; index < (count); index++) \ + for (TYPEOF(count) index = 0; index < (count); ++index) \ for (type* item = &(array)[index]; item; item = NULL) -#define repeat(n, it) for (typeof(n) it = 0; it < (n); ++it) +#define repeat(n, it) for (TYPEOF(n) it = 0; it < (n); ++it) #define require(condition) \ do { \ @@ -48,17 +55,8 @@ static inline void requireMessageFormatted(const char *file, int line, bool cond abort(); } -#define requireNotNull(ptr) ({ \ -typeof(ptr) _val = (ptr); \ -if (_val == NULL) { \ -fprintf(stderr, "%s:%d: requireNotNull failed: '%s'\n", __FILE__, __LINE__, #ptr); \ -abort(); \ -} \ -_val; \ -}) - #define requireNotNullMessage(ptr, msg) ({ \ -typeof(ptr) _val = (ptr); \ +void *_val = (ptr); \ if (_val == NULL) { \ fprintf(stderr, "%s:%d: requireNotNull failed: %s\n", __FILE__, __LINE__, (msg)); \ abort(); \ @@ -66,6 +64,8 @@ abort(); \ _val; \ }) +#define requireNotNull(ptr) requireNotNullMessage(ptr, #ptr) + // Safe allocation macros - check for nullptr and abort with file/line info #define safeMalloc(size) ({ \ void* _ptr = malloc(size); \ From 152775635dc69ee840bd9dae9f5a2846120d5231 Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Tue, 16 Jun 2026 14:54:29 -0400 Subject: [PATCH 2/9] gate noinline Co-authored-by: Serg One Zero --- src/common.h | 8 ++++++++ src/vm.c | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/common.h b/src/common.h index 9c5949bf..9f3c17ae 100644 --- a/src/common.h +++ b/src/common.h @@ -42,6 +42,14 @@ #define ALIGN(x) #endif +#if defined(__GNUC__) || defined(__TINYC__) + #define NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) && _MSC_VER >= 1400 // VS2005 or later + #define NOINLINE __declspec(noinline) +#else + #define NOINLINE +#endif + #if defined(__GNUC__) || defined(__clang__) #if defined(__x86_64__) || defined(__i386__) #define YIELD() __asm__ volatile("rep; nop" : : : "memory") diff --git a/src/vm.c b/src/vm.c index 86b15289..83c8dfc9 100644 --- a/src/vm.c +++ b/src/vm.c @@ -850,7 +850,7 @@ static void writeSingleInstanceVariable(VMContext* ctx, Instance* inst, Variable } // Force out-of-line so the OP_POP fast path in executeLoop doesn't inline this, because we already have an "optimized" version for common writes -__attribute__((noinline)) +NOINLINE static void resolveVariableWrite(VMContext* ctx, int32_t instanceType, uint32_t varRef, RValue val) { Variable* varDef = resolveVarDef(ctx, varRef); @@ -1468,7 +1468,7 @@ static void handlePopz(VMContext* ctx) { RValue_free(&val); } -__attribute__((noinline)) +NOINLINE static void handleAddString(VMContext* ctx, RValue a, RValue b, uint8_t resultType) { if (a.type == RVALUE_STRING && b.type == RVALUE_STRING) { // String concatenation @@ -1509,7 +1509,7 @@ static void handleAddString(VMContext* ctx, RValue a, RValue b, uint8_t resultTy } } -__attribute__((noinline)) +NOINLINE static void handleMulString(VMContext* ctx, RValue a, RValue b, uint8_t resultType) { // a.type == RVALUE_STRING; b is the repetition count. int count = RValue_toInt32(b); From e9d39c2bf76cbc60847287d950af312b4e9ee0da Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Tue, 16 Jun 2026 14:55:59 -0400 Subject: [PATCH 3/9] use macro --- src/ps2/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ps2/main.c b/src/ps2/main.c index c0bba55e..7de8b027 100644 --- a/src/ps2/main.c +++ b/src/ps2/main.c @@ -63,7 +63,7 @@ static int MAX_MEMORY_BYTES = 0; static int heapCeilingBytes = 0; // 256-byte aligned buffers for libpad (one per port) -static char padBuf[2][256] __attribute__((aligned(64))); +static char padBuf[2][256] ALIGN(64); // Controller button to GML key mapping typedef struct { From eea7f3c53f2e3667284481afee26bf4619beece3 Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Tue, 16 Jun 2026 14:56:45 -0400 Subject: [PATCH 4/9] what about now --- src/utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.h b/src/utils.h index d61c2743..6e227ab8 100644 --- a/src/utils.h +++ b/src/utils.h @@ -56,7 +56,7 @@ static inline void requireMessageFormatted(const char *file, int line, bool cond } #define requireNotNullMessage(ptr, msg) ({ \ -void *_val = (ptr); \ +const void *_val = (ptr); \ if (_val == NULL) { \ fprintf(stderr, "%s:%d: requireNotNull failed: %s\n", __FILE__, __LINE__, (msg)); \ abort(); \ From e1bbff350097efdc3c19ea8a9e43b64b8093f1cd Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Tue, 16 Jun 2026 14:58:48 -0400 Subject: [PATCH 5/9] fix --- src/utils.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/utils.h b/src/utils.h index 6e227ab8..81fd307d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -55,16 +55,15 @@ static inline void requireMessageFormatted(const char *file, int line, bool cond abort(); } -#define requireNotNullMessage(ptr, msg) ({ \ -const void *_val = (ptr); \ -if (_val == NULL) { \ -fprintf(stderr, "%s:%d: requireNotNull failed: %s\n", __FILE__, __LINE__, (msg)); \ -abort(); \ -} \ -_val; \ -}) - -#define requireNotNull(ptr) requireNotNullMessage(ptr, #ptr) +static inline void* requireNotNullFunction(void* ptr, char* file, int line, char* name) { + if (ptr == nullptr) { + fprintf(stderr, "%s:%d: requireNotNull failed: '%s'\n", file, line, name); + abort(); + } + return ptr; +} +#define requireNotNull(ptr) requireNotNullFunction((void*)ptr, __FILE__, __LINE__, #ptr) +#define requireNotNullMessage(ptr, msg) requireNotNullFunction((void*)ptr, __FILE__, __LINE__, msg) // Safe allocation macros - check for nullptr and abort with file/line info #define safeMalloc(size) ({ \ From 1d385c255b7b02f683ae820866bbebf449831b91 Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Tue, 16 Jun 2026 15:00:57 -0400 Subject: [PATCH 6/9] nit --- src/utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.h b/src/utils.h index 81fd307d..d2aa286c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -56,7 +56,7 @@ static inline void requireMessageFormatted(const char *file, int line, bool cond } static inline void* requireNotNullFunction(void* ptr, char* file, int line, char* name) { - if (ptr == nullptr) { + if (!ptr) { fprintf(stderr, "%s:%d: requireNotNull failed: '%s'\n", file, line, name); abort(); } From 1710a4d1966d90b578766a6da5983199c339afff Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Tue, 16 Jun 2026 15:08:54 -0400 Subject: [PATCH 7/9] fixes --- src/math_compat.h | 4 ++++ src/utils.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/math_compat.h b/src/math_compat.h index 24b9deb3..f2db9280 100644 --- a/src/math_compat.h +++ b/src/math_compat.h @@ -108,3 +108,7 @@ static float roundf(float x) { #ifndef INFINITY #define INFINITY (1.0f / 0.0f) #endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif diff --git a/src/utils.h b/src/utils.h index d2aa286c..8060ebce 100644 --- a/src/utils.h +++ b/src/utils.h @@ -6,13 +6,14 @@ #include #include #include +#include #include "math_compat.h" #include "real_type.h" #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)) \ || defined(__GNUC__) || defined(__clang__) || defined(__TINYC__) - #define TYPEOF(x) typeof(x) + #define TYPEOF(x) __typeof__(x) #else #define TYPEOF(x) long long #endif From d62a197461e2b3740cd4ce00bcdf41478c2dad1d Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Fri, 19 Jun 2026 08:03:39 -0400 Subject: [PATCH 8/9] fix --- src/vm_builtins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index b76d7722..23cb2b80 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3960,7 +3960,7 @@ static RValue builtin_method(VMContext* ctx, MAYBE_UNUSED RValue* args, int32_t } if (instanceToBeBound == INSTANCE_SELF) { - instanceToBeBound = requireNotNullMessage(ctx->currentInstance, "Trying to bind method to INSTANCE_SELF while there isn't a instance in the current context!")->instanceId; + instanceToBeBound = ((Instance *)requireNotNullMessage(ctx->currentInstance, "Trying to bind method to INSTANCE_SELF while there isn't a instance in the current context!"))->instanceId; } return RValue_makeMethodFromCodeIndexAndInstanceId(codeIndex, instanceToBeBound); From a69ca2b6dc71d9d9115aa2e4929174508f378b4a Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Fri, 19 Jun 2026 10:59:51 -0400 Subject: [PATCH 9/9] fix --- src/utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.h b/src/utils.h index 8060ebce..c91bec69 100644 --- a/src/utils.h +++ b/src/utils.h @@ -56,7 +56,7 @@ static inline void requireMessageFormatted(const char *file, int line, bool cond abort(); } -static inline void* requireNotNullFunction(void* ptr, char* file, int line, char* name) { +static inline void* requireNotNullFunction(void* ptr, const char* file, int line, const char* name) { if (!ptr) { fprintf(stderr, "%s:%d: requireNotNull failed: '%s'\n", file, line, name); abort();