forked from ebitengine/purego
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6319229
commit 39be9b4
Showing
11 changed files
with
195 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors | ||
|
||
//go:build darwin || (!cgo && linux) | ||
|
||
package purego_test | ||
import ( | ||
"testing" | ||
|
||
"github.com/ebitengine/purego" | ||
) | ||
|
||
func TestNewCallbackFloat64(t *testing.T) { | ||
// This tests the maximum number of arguments a function to NewCallback can take | ||
const ( | ||
expectCbTotal = -3 | ||
expectedCbTotalF = float64(36) | ||
) | ||
var cbTotal int | ||
var cbTotalF float64 | ||
imp := purego.NewCallback(func(a1, a2, a3, a4, a5, a6, a7, a8, a9 int, | ||
f1, f2, f3, f4, f5, f6, f7, f8 float64) { | ||
cbTotal = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 | ||
cbTotalF = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 | ||
}) | ||
var fn func(a1, a2, a3, a4, a5, a6, a7, a8, a9 int, | ||
f1, f2, f3, f4, f5, f6, f7, f8 float64) | ||
purego.RegisterFunc(&fn, imp) | ||
fn(1, 2, -3, 4, -5, 6, -7, 8, -9, | ||
1, 2, 3, 4, 5, 6, 7, 8) | ||
|
||
if cbTotal != expectCbTotal { | ||
t.Errorf("cbTotal not correct got %d but wanted %d", cbTotal, expectCbTotal) | ||
} | ||
if cbTotalF != expectedCbTotalF { | ||
t.Errorf("cbTotalF not correct got %f but wanted %f", cbTotalF, expectedCbTotalF) | ||
} | ||
} | ||
|
||
func TestNewCallbackFloat32(t *testing.T) { | ||
// This tests the maximum number of float32 arguments a function to NewCallback can take | ||
const ( | ||
expectCbTotal = 6 | ||
expectedCbTotalF = float32(45) | ||
) | ||
var cbTotal int | ||
var cbTotalF float32 | ||
imp := purego.NewCallback(func(a1, a2, a3, a4, a5, a6, a7, a8 int, | ||
f1, f2, f3, f4, f5, f6, f7, f8, f9 float32) { | ||
cbTotal = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 | ||
cbTotalF = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 | ||
}) | ||
var fn func(a1, a2, a3, a4, a5, a6, a7, a8 int, | ||
f1, f2, f3, f4, f5, f6, f7, f8, f9 float32) | ||
purego.RegisterFunc(&fn, imp) | ||
fn(1, 2, -3, 4, -5, 6, -7, 8, | ||
1, 2, 3, 4, 5, 6, 7, 8, 9) | ||
|
||
if cbTotal != expectCbTotal { | ||
t.Errorf("cbTotal not correct got %d but wanted %d", cbTotal, expectCbTotal) | ||
} | ||
if cbTotalF != expectedCbTotalF { | ||
t.Errorf("cbTotalF not correct got %f but wanted %f", cbTotalF, expectedCbTotalF) | ||
} | ||
} | ||
|
||
func TestNewCallbackFloat32AndFloat64(t *testing.T) { | ||
// This tests that calling a function with a mix of float32 and float64 arguments works | ||
const ( | ||
expectedCbTotalF32 = float32(30) | ||
expectedCbTotalF64 = float64(15) | ||
) | ||
var cbTotalF32 float32 | ||
var cbTotalF64 float64 | ||
imp := purego.NewCallback(func(f1, f2, f3 float32, f4, f5, f6 float64, f7, f8, f9 float32) { | ||
cbTotalF32 = f1 + f2 + f3 + f7 + f8 + f9 | ||
cbTotalF64 = f4 + f5 + f6 | ||
|
||
}) | ||
var fn func(f1, f2, f3 float32, f4, f5, f6 float64, f7, f8, f9 float32) | ||
purego.RegisterFunc(&fn, imp) | ||
fn(1, 2, 3, 4, 5, 6, 7, 8, 9) | ||
|
||
if cbTotalF32 != expectedCbTotalF32 { | ||
t.Errorf("cbTotalF32 not correct got %f but wanted %f", cbTotalF32, expectedCbTotalF32) | ||
} | ||
if cbTotalF64 != expectedCbTotalF64 { | ||
t.Errorf("cbTotalF64 not correct got %f but wanted %f", cbTotalF64, expectedCbTotalF64) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors | ||
|
||
//go:build darwin || freebsd || linux | ||
|
||
#include "textflag.h" | ||
#include "abi_amd64.h" | ||
#include "go_asm.h" | ||
#include "funcdata.h" | ||
|
||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0 | ||
// remove return address from stack, we are not returning to callbackasm, but to its caller. | ||
MOVQ 0(SP), AX | ||
ADDQ $8, SP | ||
|
||
MOVQ 0(SP), R10 // get the return SP so that we can align register args with stack args | ||
|
||
// make space for first six int and 8 float arguments below the frame | ||
ADJSP $14*8, SP | ||
MOVSD X0, (1*8)(SP) | ||
MOVSD X1, (2*8)(SP) | ||
MOVSD X2, (3*8)(SP) | ||
MOVSD X3, (4*8)(SP) | ||
MOVSD X4, (5*8)(SP) | ||
MOVSD X5, (6*8)(SP) | ||
MOVSD X6, (7*8)(SP) | ||
MOVSD X7, (8*8)(SP) | ||
MOVQ DI, (9*8)(SP) | ||
MOVQ SI, (10*8)(SP) | ||
MOVQ DX, (11*8)(SP) | ||
MOVQ CX, (12*8)(SP) | ||
MOVQ R8, (13*8)(SP) | ||
MOVQ R9, (14*8)(SP) | ||
LEAQ 8(SP), R8 // R8 = address of args vector | ||
|
||
MOVQ R10, 0(SP) // push the stack pointer below registers | ||
|
||
// determine index into runtime·cbs table | ||
MOVQ $callbackasm(SB), DX | ||
SUBQ DX, AX | ||
MOVQ $0, DX | ||
MOVQ $5, CX // divide by 5 because each call instruction in ·callbacks is 5 bytes long | ||
DIVL CX | ||
SUBQ $1, AX // subtract 1 because return PC is to the next slot | ||
|
||
// Switch from the host ABI to the Go ABI. | ||
PUSH_REGS_HOST_TO_ABI0() | ||
|
||
// Create a struct callbackArgs on our stack to be passed as | ||
// the "frame" to cgocallback and on to callbackWrap. | ||
// $24 to make enough room for the arguments to runtime.cgocallback | ||
SUBQ $(24+callbackArgs__size), SP | ||
MOVQ AX, (24+callbackArgs_index)(SP) // callback index | ||
MOVQ R8, (24+callbackArgs_args)(SP) // address of args vector | ||
MOVQ $0, (24+callbackArgs_result)(SP) // result | ||
LEAQ 24(SP), AX // take the address of callbackArgs | ||
|
||
// Call cgocallback, which will call callbackWrap(frame). | ||
MOVQ ·callbackWrap_call(SB), DI // Get the ABIInternal function pointer | ||
MOVQ (DI), DI // without <ABIInternal> by using a closure. | ||
MOVQ AX, SI // frame (address of callbackArgs) | ||
MOVQ $0, CX // context | ||
|
||
CALL crosscall2(SB) // runtime.cgocallback(fn, frame, ctxt uintptr) | ||
|
||
// Get callback result. | ||
MOVQ (24+callbackArgs_result)(SP), AX | ||
ADDQ $(24+callbackArgs__size), SP // remove callbackArgs struct | ||
|
||
POP_REGS_HOST_TO_ABI0() | ||
|
||
MOVQ 0(SP), R10 // get the SP back | ||
|
||
ADJSP $-14*8, SP // remove arguments | ||
|
||
MOVQ R10, 0(SP) | ||
|
||
RET |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.