feat(verify): add the JIT execution substrate and gasm verify subcommand

Assisted-by: Qwen 3.8 Max Preview
This commit is contained in:
2026-08-02 23:11:30 +02:00
parent 5af12e15ac
commit c9775c2b95
11 changed files with 785 additions and 2 deletions
+159
View File
@@ -0,0 +1,159 @@
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
package verify
import (
"bytes"
"testing"
"unsafe"
)
func loadBasic(t *testing.T) *Kernel {
t.Helper()
k, err := Load("../testdata/verify/basic_amd64.s")
if err != nil {
t.Fatalf("Load: %v", err)
}
t.Cleanup(k.Close)
return k
}
func TestJITAdd(t *testing.T) {
k := loadBasic(t)
tests := []struct {
a, b, want int64
}{
{0, 0, 0},
{1, 2, 3},
{-1, 1, 0},
{1 << 62, 1 << 62, -9223372036854775808}, // overflow wraps (MinInt64)
{-100, -200, -300},
}
for _, tt := range tests {
args := make([]byte, 24)
PutUint64(args, 0, uint64(tt.a))
PutUint64(args, 8, uint64(tt.b))
out, err := k.CallFunc("add", args)
if err != nil {
t.Fatalf("CallFunc(add, %d, %d): %v", tt.a, tt.b, err)
}
got := int64(GetUint64(out, 16))
if got != tt.want {
t.Errorf("add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.want)
}
}
}
func TestJITSum(t *testing.T) {
k := loadBasic(t)
tests := []struct {
data []int64
want int64
}{
{nil, 0},
{[]int64{1}, 1},
{[]int64{1, 2, 3, 4, 5}, 15},
{[]int64{-10, 20, -30, 40}, 20},
}
for _, tt := range tests {
args := make([]byte, 32)
if len(tt.data) > 0 {
PutPtr(args, 0, unsafe.Pointer(&tt.data[0]))
}
PutUint64(args, 8, uint64(len(tt.data)))
PutUint64(args, 16, uint64(cap(tt.data)))
out, err := k.CallFunc("sum", args)
if err != nil {
t.Fatalf("CallFunc(sum, %v): %v", tt.data, err)
}
got := int64(GetUint64(out, 24))
if got != tt.want {
t.Errorf("sum(%v) = %d, want %d", tt.data, got, tt.want)
}
}
}
func TestJITWideCopy(t *testing.T) {
k := loadBasic(t)
tests := []struct {
name string
n int
}{
{"empty", 0},
{"tiny", 7},
{"exact32", 32},
{"overlap_range", 48},
{"exact64", 64},
{"unaligned", 45},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
src := make([]byte, tt.n)
for i := range src {
src[i] = byte(i * 7)
}
dst := make([]byte, tt.n)
args := make([]byte, 48)
if tt.n > 0 {
PutPtr(args, 0, unsafe.Pointer(&dst[0]))
PutPtr(args, 24, unsafe.Pointer(&src[0]))
}
PutUint64(args, 8, uint64(tt.n)) // dst_len
PutUint64(args, 16, uint64(tt.n)) // dst_cap
PutUint64(args, 32, uint64(tt.n)) // src_len
PutUint64(args, 40, uint64(tt.n)) // src_cap
_, err := k.CallFunc("wideCopy", args)
if err != nil {
t.Fatalf("CallFunc(wideCopy): %v", err)
}
if !bytes.Equal(dst, src) {
t.Errorf("wideCopy: dst ≠ src\n got %x\n want %x", dst, src)
}
})
}
}
func TestKernelFuncNames(t *testing.T) {
k := loadBasic(t)
names := k.FuncNames()
want := []string{"add", "sum", "wideCopy"}
if len(names) != len(want) {
t.Fatalf("FuncNames() = %v, want %v", names, want)
}
for i, n := range names {
if n != want[i] {
t.Errorf("FuncNames()[%d] = %q, want %q", i, n, want[i])
}
}
}
func TestKernelFuncNotFound(t *testing.T) {
k := loadBasic(t)
_, err := k.CallFunc("nonexistent", make([]byte, 8))
if err == nil {
t.Fatal("expected error for nonexistent function")
}
}
func TestKernelArgTooSmall(t *testing.T) {
k := loadBasic(t)
_, err := k.CallFunc("add", make([]byte, 8)) // needs 24
if err == nil {
t.Fatal("expected error for too-small arg block")
}
}
func TestMapZeroLength(t *testing.T) {
_, err := Map(nil)
if err == nil {
t.Fatal("expected error for zero-length code")
}
}