Files
gasm-sdk/verify/sigparse_test.go
T

154 lines
3.8 KiB
Go
Raw Normal View History

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
package verify
import (
"testing"
)
func TestParseFuncSigExported(t *testing.T) {
tests := []struct {
comment string
wantName string
nParams int
nResults int
}{
{"// func add(a int64, b int64) int64", "add", 2, 1},
{"// func wideCopy(dst []byte, src []byte)", "wideCopy", 2, 0},
{"// func decodeBlockAVX2(src, dst []byte) (n int, code int)", "decodeBlockAVX2", 2, 2},
{"// func analyzeO1RangeAVX2(swin []int32, dstP []uint32, hist *[32]uint16) (partSum uint64, overflow bool)", "analyzeO1RangeAVX2", 3, 2},
{"// not a func", "", 0, 0},
{"// func", "", 0, 0},
}
for _, tt := range tests {
sig, ok := ParseFuncSig(tt.comment)
if tt.wantName == "" {
if ok {
t.Errorf("ParseFuncSig(%q): expected not ok", tt.comment)
}
continue
}
if !ok {
t.Errorf("ParseFuncSig(%q): expected ok", tt.comment)
continue
}
if sig.Name != tt.wantName {
t.Errorf("ParseFuncSig(%q).Name = %q, want %q", tt.comment, sig.Name, tt.wantName)
}
if len(sig.Params) != tt.nParams {
t.Errorf("ParseFuncSig(%q): %d params, want %d", tt.comment, len(sig.Params), tt.nParams)
}
if len(sig.Results) != tt.nResults {
t.Errorf("ParseFuncSig(%q): %d results, want %d", tt.comment, len(sig.Results), tt.nResults)
}
}
}
func TestExtractFuncSig(t *testing.T) {
src := `// func add(a int64, b int64) int64
TEXT ·add(SB), NOSPLIT, $0-24
// func wideCopyAVX2(dst, src []byte)
TEXT ·wideCopyAVX2(SB), NOSPLIT, $0-48
`
sig, ok := ExtractFuncSig(src, "add")
if !ok {
t.Fatal("ExtractFuncSig(add): not found")
}
if sig.Name != "add" {
t.Errorf("Name = %q, want %q", sig.Name, "add")
}
if len(sig.Params) != 2 {
t.Errorf("params = %d, want 2", len(sig.Params))
}
sig, ok = ExtractFuncSig(src, "wideCopyAVX2")
if !ok {
t.Fatal("ExtractFuncSig(wideCopyAVX2): not found")
}
if len(sig.Params) != 2 {
t.Errorf("params = %d, want 2", len(sig.Params))
}
_, ok = ExtractFuncSig(src, "nonexistent")
if ok {
t.Error("ExtractFuncSig(nonexistent): expected not found")
}
}
func TestArgLayout(t *testing.T) {
sig := FuncSig{
Name: "wideCopyAVX2",
Params: []Param{
{Name: "dst", Typ: "[]byte"},
{Name: "src", Typ: "[]byte"},
},
}
layout := ArgLayout(sig)
if len(layout) != 2 {
t.Fatalf("ArgLayout: %d entries, want 2", len(layout))
}
// dst: offset 0, size 24 (slice)
if layout[0].Name != "dst" || layout[0].Offset != 0 || layout[0].Size != 24 || !layout[0].IsPtr {
t.Errorf("layout[0] = %+v", layout[0])
}
// src: offset 24, size 24 (slice)
if layout[1].Name != "src" || layout[1].Offset != 24 || layout[1].Size != 24 || !layout[1].IsPtr {
t.Errorf("layout[1] = %+v", layout[1])
}
}
func TestArgLayoutMixed(t *testing.T) {
sig := FuncSig{
Name: "decodeBlockAVX2",
Params: []Param{
{Name: "src", Typ: "[]byte"},
{Name: "dst", Typ: "[]byte"},
},
Results: []Param{
{Name: "n", Typ: "int"},
{Name: "code", Typ: "int"},
},
}
layout := ArgLayout(sig)
if len(layout) != 2 {
t.Fatalf("ArgLayout: %d entries, want 2", len(layout))
}
// Two slices: 24 + 24 = 48 bytes of params.
if layout[1].Offset != 24 {
t.Errorf("src offset = %d, want 24", layout[1].Offset)
}
}
func TestParamSize(t *testing.T) {
tests := []struct {
typ string
want int
}{
{"[]byte", 24},
{"[]int32", 24},
{"*uint16", 8},
{"*[32]uint16", 8},
{"int", 8},
{"int64", 8},
{"uint64", 8},
{"uintptr", 8},
{"int32", 4},
{"uint32", 4},
{"float32", 4},
{"int16", 2},
{"uint16", 2},
{"int8", 1},
{"uint8", 1},
{"byte", 1},
{"bool", 1},
{"string", 8}, // unknown type defaults to 8
}
for _, tt := range tests {
if got := paramSize(tt.typ); got != tt.want {
t.Errorf("paramSize(%q) = %d, want %d", tt.typ, got, tt.want)
}
}
}