| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // SPDX-License-Identifier: Apache-2.0
- // SPDX-FileCopyrightText: 2025 The Ebitengine Authors
- package purego
- import (
- "reflect"
- "unsafe"
- )
- func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []any) []any {
- size := v.Type().Size()
- if size == 0 {
- return keepAlive
- }
- // TODO: ARM EABI: small structs are passed in registers or on stack
- // For simplicity, pass by pointer for now
- ptr := v.Addr().UnsafePointer()
- keepAlive = append(keepAlive, ptr)
- if *numInts < 4 {
- addInt(uintptr(ptr))
- *numInts++
- } else {
- addStack(uintptr(ptr))
- *numStack++
- }
- return keepAlive
- }
- func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) {
- outSize := outType.Size()
- if outSize == 0 {
- return reflect.New(outType).Elem()
- }
- if outSize <= 4 {
- // Fits in one register
- return reflect.NewAt(outType, unsafe.Pointer(&struct{ a uintptr }{syscall.a1})).Elem()
- }
- if outSize <= 8 {
- // Fits in two registers
- return reflect.NewAt(outType, unsafe.Pointer(&struct{ a, b uintptr }{syscall.a1, syscall.a2})).Elem()
- }
- // Larger structs returned via pointer in a1
- return reflect.NewAt(outType, *(*unsafe.Pointer)(unsafe.Pointer(&syscall.a1))).Elem()
- }
- func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
- // TODO: For ARM32, just pass the struct data directly
- // This is a simplified implementation
- size := v.Type().Size()
- if size == 0 {
- return
- }
- ptr := unsafe.Pointer(v.UnsafeAddr())
- if size <= 4 {
- addInt(*(*uintptr)(ptr))
- } else if size <= 8 {
- addInt(*(*uintptr)(ptr))
- addInt(*(*uintptr)(unsafe.Add(ptr, 4)))
- }
- }
- // shouldBundleStackArgs always returns false on arm
- // since C-style stack argument bundling is only needed on Darwin ARM64.
- func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
- return false
- }
- // structFitsInRegisters is not used on arm.
- func structFitsInRegisters(val reflect.Value, tempNumInts, tempNumFloats int) (bool, int, int) {
- panic("purego: structFitsInRegisters should not be called on arm")
- }
- // collectStackArgs is not used on arm.
- func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int,
- keepAlive []any, addInt, addFloat, addStack func(uintptr),
- pNumInts, pNumFloats, pNumStack *int) ([]reflect.Value, []any) {
- panic("purego: collectStackArgs should not be called on arm")
- }
- // bundleStackArgs is not used on arm.
- func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
- panic("purego: bundleStackArgs should not be called on arm")
- }
|