Skip to content

purego: support RegisterFunc and typed callbacks on Windows 386#478

Open
nekohasekai wants to merge 4 commits into
ebitengine:mainfrom
SagerNet:windows-386-abi
Open

purego: support RegisterFunc and typed callbacks on Windows 386#478
nekohasekai wants to merge 4 commits into
ebitengine:mainfrom
SagerNet:windows-386-abi

Conversation

@nekohasekai

Copy link
Copy Markdown

What issue is this addressing?

There is no existing issue. This expands the Windows/386 support currently described in the platform support table.

What type of issue is this addressing?

feature

What this PR does | solves

Windows/386 previously only officially supported SyscallN and NewCallback. The partial RegisterFunc path also treated 64-bit values as a single uintptr, only observed EAX for integer results, and did not retrieve floating-point results from x87.

This change adds the Windows/386 ABI handling needed for typed RegisterFunc/RegisterLibFunc calls and typed callbacks:

  • lays out integer, pointer, bool, string, float32, and float64 arguments on the 32-bit stack;
  • splits 64-bit arguments into little-endian low/high slots and rebuilds integer results from EDX:EAX;
  • saves direct floating-point results from x87 ST(0) and restores callback floating-point results there;
  • decodes 64-bit and floating-point callback arguments, supports 64-bit callback results, and preserves both stdcall and cdecl stack cleanup;
  • passes up to the declared 32 stack slots instead of the old 15-slot fallback;
  • supports by-value struct arguments and returns for direct calls, matching the existing Windows limitation that structs are not supported in callbacks; and
  • adds Windows/386 ABI, x87 edge-case, stack-limit, concurrency, reentrancy, native-thread callback, and callback-table coverage.

The Windows CI jobs now use an explicit MSYS2 MINGW32 GNU toolchain, verify that it can build a 32-bit DLL, and run both Cgo and non-Cgo Windows/386 suites (including unoptimized builds) on Go 1.25, 1.26, and 1.27rc1.

Validation:

@nekohasekai
nekohasekai marked this pull request as ready for review July 14, 2026 09:41
Comment thread .github/workflows/test.yml
@TotallyGamerJet

Copy link
Copy Markdown
Collaborator

Can you create an issue to track this change?

@hajimehoshi

Copy link
Copy Markdown
Member

Update README.md too

@nekohasekai

Copy link
Copy Markdown
Author

The README is already updated in this PR — the platform table now lists Windows 386 with footnote 2 (structs supported as arguments/return values in calls, but not in callbacks), replacing the previous footnotes 3 and 6. Let me know if you'd like it documented differently.

@hajimehoshi

Copy link
Copy Markdown
Member

Ah sorry, I missed that

Comment thread callback_windows_386.go Outdated
Comment thread struct_windows_386.go Outdated
Comment thread sys_windows_386.s Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends PureGo’s Windows/386 support beyond SyscallN/NewCallback by implementing the ABI handling needed for typed RegisterFunc/RegisterLibFunc calls, typed callbacks (including cdecl/stdcall cleanup), 64-bit scalar splitting/reconstruction, and x87 float returns, and adds dedicated Windows/386 ABI and callback test coverage plus CI updates.

Changes:

  • Adds Windows/386 callback trampoline/dispatch path and x87 return handling to support typed callbacks and float/int64 returns.
  • Adds Windows/386 struct-by-value support for direct calls and updates existing struct tests accordingly.
  • Introduces comprehensive Windows/386 ABI tests and updates CI to exercise Windows/386 (cgo + non-cgo, optimized + unoptimized).

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
zcallback_386.s Expands callback trampoline table build coverage to include windows/386.
windows_386_test.go Adds Windows/386 ABI + callback + concurrency/reentrancy + x87 edge-case tests.
wincallback.go Updates generated assembly build constraints to include windows/386.
testdata/structtest/struct_test.c Fixes register-sum computation to be width-safe across architectures.
testdata/abitest/abi_test.c Adds Windows/386-specific ABI/callback test helpers implemented in C.
syscall_windows.go Routes NewCallback through an internal newCallback to enable custom windows/386 behavior.
syscall_32bit.go Adds floatReturn control field used by the 386 bridge to capture x87 results safely.
sys_windows_386.s Implements windows/386 callback trampoline part that restores integer/x87 return conventions.
sys_arm.s Updates struct layout commentary to reflect renamed field.
sys_386.s Enables syscall bridge on windows/386 and adds guarded x87 return capture logic.
struct_windows_386.go Implements windows/386 struct argument packing and struct return reconstruction.
struct_test.go Enables struct tests on windows/386 and fixes type-width expectations.
struct_other.go Excludes windows/386 from “no-struct-support” fallback implementation.
README.md Updates Windows/386 support tier notes to reflect added struct support for direct calls.
func.go Implements windows/386 slot accounting, 64-bit return reconstruction, and x87 float-return modes.
func_test.go Removes windows/386 skips now that CI/tooling is expected to support building test DLLs.
callback_windows_other.go Keeps stdlib-backed callbacks on non-386 Windows.
callback_windows_386.go Adds typed callback decoding/encoding for windows/386 using a stdlib-compatible bridge.
.github/workflows/test.yml Adds MSYS2-based Windows/386 toolchain setup and windows/386 test runs.
Files not reviewed (1)
  • wincallback.go: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/test.yml
Comment thread func.go Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants