From 3ba0beee9610d2e173a2420bfa97afde09e4c567 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 9 Sep 2025 13:41:26 +0200 Subject: [PATCH] Support for SysV for CVaList --- lib/std/core/cinterop.c3 | 47 +++++++++++++++++++++++++++++++++++++++- releasenotes.md | 2 +- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/std/core/cinterop.c3 b/lib/std/core/cinterop.c3 index d8a53b8bd..bc3f9073b 100644 --- a/lib/std/core/cinterop.c3 +++ b/lib/std/core/cinterop.c3 @@ -2,6 +2,8 @@ // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. module std::core::cinterop; +import std::core::env; + const C_INT_SIZE = $$C_INT_SIZE; const C_LONG_SIZE = $$C_LONG_SIZE; @@ -60,7 +62,8 @@ macro typeid unsigned_int_from_bitsize(usz $bitsize) @private $endswitch } -module std::core::cinterop @if(env::DARWIN && env::AARCH64); +const USE_STACK_VALIST = env::ARCH_32_BIT || env::WIN32 || (env::DARWIN && env::AARCH64); +module std::core::cinterop @if(USE_STACK_VALIST); typedef CVaList = void*; macro CVaList.next(&self, $Type) @@ -70,3 +73,45 @@ macro CVaList.next(&self, $Type) return *($Type*)ptr; } +module std::core::cinterop @if(env::X86_64 && !env::WIN32); + +struct CVaListData +{ + uint gp_offset; + uint fp_offset; + void *overflow_arg_area; + void *reg_save_area; +} + +typedef CVaList = CVaListData*; + +macro CVaList.next(self, $Type) +{ + CVaListData* data = (CVaListData*)self; + $switch: + $case $Type.kindof == FLOAT ||| ($Type.kindof == VECTOR && $Type.sizeof <= 16): + var $LoadType = $Type.sizeof < 8 ? double : $Type; + if (data.fp_offset < 6 * 8 + 8 * 16 ) + { + defer data.fp_offset += (uint)mem::aligned_offset($Type.sizeof, 16); + return ($Type)*($LoadType*)(data.reg_save_area + data.fp_offset); + } + void* ptr = mem::aligned_pointer(data.overflow_arg_area, max(8, $Type.alignof)); + defer data.overflow_arg_area = ptr + $Type.sizeof; + return ($Type)*($LoadType*)ptr; + $case $Type.kindof == SIGNED_INT || $Type.kindof == UNSIGNED_INT: + var $LoadType = $Type.sizeof < 4 ? int : $Type; + if (data.gp_offset < 6 * 8 && $Type.sizeof <= 8) + { + defer data.gp_offset += (uint)mem::aligned_offset($Type.sizeof, 8); + return ($Type)*($LoadType*)(data.reg_save_area + data.gp_offset); + } + void* ptr = mem::aligned_pointer(data.overflow_arg_area, max(8, $Type.alignof)); + defer data.overflow_arg_area = ptr + $Type.sizeof; + return ($Type)*($LoadType*)ptr; + $default: + void* ptr = mem::aligned_pointer(data.overflow_arg_area, max(8, $Type.alignof)); + defer data.overflow_arg_area = ptr + $Type.sizeof; + return *($Type*)ptr; + $endswitch +} \ No newline at end of file diff --git a/releasenotes.md b/releasenotes.md index fb39ed3e4..b6d575d7e 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -26,7 +26,7 @@ `path::public_share_directory`, `path::templates_directory`, `path::saved_games_directory`, `path::music_directory`, `path::downloads_directory`. - Add `LinkedList` array_view to support `[]` and `foreach`/`foreach_r`. #2438 - Make `LinkedList` printable and add `==` operator. #2438 -- CVaList support on MacOS aarch64. +- CVaList support on MacOS aarch64, SysV ABI x64. ## 0.7.5 Change list