Test libc.

This commit is contained in:
Nuno Cruces
2025-04-24 23:59:53 +01:00
parent 9ea7099c24
commit e580f080b9
4 changed files with 301 additions and 154 deletions

View File

@@ -23,6 +23,7 @@ EOF
-mbulk-memory -mreference-types \ -mbulk-memory -mreference-types \
-mnontrapping-fptoint -msign-ext \ -mnontrapping-fptoint -msign-ext \
-fno-stack-protector -fno-stack-clash-protection \ -fno-stack-protector -fno-stack-clash-protection \
-Wl,-z,stack-size=1024 \
-Wl,--stack-first \ -Wl,--stack-first \
-Wl,--import-undefined \ -Wl,--import-undefined \
-Wl,--initial-memory=16777216 \ -Wl,--initial-memory=16777216 \

Binary file not shown.

View File

@@ -4,7 +4,7 @@
(type $2 (func (param i32) (result i32))) (type $2 (func (param i32) (result i32)))
(type $3 (func (param i32 i32 i32 i32))) (type $3 (func (param i32 i32 i32 i32)))
(memory $0 256) (memory $0 256)
(data $0 (i32.const 65536) "\01") (data $0 (i32.const 1024) "\01")
(table $0 1 1 funcref) (table $0 1 1 funcref)
(export "memory" (memory $0)) (export "memory" (memory $0))
(export "memset" (func $memset)) (export "memset" (func $memset))
@@ -996,67 +996,67 @@
) )
) )
(v128.store (v128.store
(i32.const 65792) (i32.const 1280)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65776) (i32.const 1264)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65760) (i32.const 1248)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65744) (i32.const 1232)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65728) (i32.const 1216)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65712) (i32.const 1200)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65696) (i32.const 1184)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65680) (i32.const 1168)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65664) (i32.const 1152)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65648) (i32.const 1136)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65632) (i32.const 1120)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65616) (i32.const 1104)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65600) (i32.const 1088)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65584) (i32.const 1072)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65568) (i32.const 1056)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65552) (i32.const 1040)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(local.set $1 (local.set $1
@@ -1072,7 +1072,7 @@
(local.get $2) (local.get $2)
(i32.const 255) (i32.const 255)
) )
(i32.const 65552) (i32.const 1040)
) )
(i32.const 1) (i32.const 1)
) )
@@ -1105,7 +1105,7 @@
(i32.load8_u (i32.load8_u
(local.get $2) (local.get $2)
) )
(i32.const 65552) (i32.const 1040)
) )
) )
) )
@@ -1117,7 +1117,7 @@
(i32.load8_u offset=1 (i32.load8_u offset=1
(local.get $2) (local.get $2)
) )
(i32.const 65552) (i32.const 1040)
) )
) )
) )
@@ -1129,7 +1129,7 @@
(i32.load8_u offset=2 (i32.load8_u offset=2
(local.get $2) (local.get $2)
) )
(i32.const 65552) (i32.const 1040)
) )
) )
) )
@@ -1151,7 +1151,7 @@
) )
(local.get $scratch) (local.get $scratch)
) )
(i32.const 65552) (i32.const 1040)
) )
) )
) )
@@ -1214,67 +1214,67 @@
) )
) )
(v128.store (v128.store
(i32.const 66048) (i32.const 1536)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 66032) (i32.const 1520)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 66016) (i32.const 1504)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 66000) (i32.const 1488)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65984) (i32.const 1472)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65968) (i32.const 1456)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65952) (i32.const 1440)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65936) (i32.const 1424)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65920) (i32.const 1408)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65904) (i32.const 1392)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65888) (i32.const 1376)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65872) (i32.const 1360)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65856) (i32.const 1344)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65840) (i32.const 1328)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65824) (i32.const 1312)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(v128.store (v128.store
(i32.const 65808) (i32.const 1296)
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
) )
(loop $label (loop $label
@@ -1285,7 +1285,7 @@
(local.get $1) (local.get $1)
) )
) )
(i32.const 65808) (i32.const 1296)
) )
(i32.const 1) (i32.const 1)
) )
@@ -1309,7 +1309,7 @@
(i32.load8_u (i32.load8_u
(local.get $1) (local.get $1)
) )
(i32.const 65808) (i32.const 1296)
) )
) )
) )
@@ -1319,7 +1319,7 @@
(i32.load8_u offset=1 (i32.load8_u offset=1
(local.get $1) (local.get $1)
) )
(i32.const 65808) (i32.const 1296)
) )
) )
) )
@@ -1329,7 +1329,7 @@
(i32.load8_u offset=2 (i32.load8_u offset=2
(local.get $1) (local.get $1)
) )
(i32.const 65808) (i32.const 1296)
) )
) )
) )
@@ -1351,7 +1351,7 @@
) )
(local.get $scratch) (local.get $scratch)
) )
(i32.const 65808) (i32.const 1296)
) )
) )
) )

View File

@@ -14,6 +14,7 @@ import (
var binary []byte var binary []byte
const ( const (
page = 64 * 1024
size = 1024 * 1024 * 4 size = 1024 * 1024 * 4
ptr1 = 1024 * 1024 ptr1 = 1024 * 1024
ptr2 = ptr1 + size ptr2 = ptr1 + size
@@ -35,10 +36,13 @@ var (
stack [8]uint64 stack [8]uint64
) )
func call(fn api.Function, arg ...uint64) uint32 { func call(fn api.Function, arg ...uint64) uint64 {
copy(stack[:], arg) copy(stack[:], arg)
fn.CallWithStack(context.Background(), stack[:]) err := fn.CallWithStack(context.Background(), stack[:])
return uint32(stack[0]) if err != nil {
panic(err)
}
return stack[0]
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
@@ -74,170 +78,97 @@ func Benchmark_memset(b *testing.B) {
for range b.N { for range b.N {
call(memset, ptr1, 3, size) call(memset, ptr1, 3, size)
} }
b.StopTimer()
for i, got := range memory[ptr1 : ptr1+size] {
if got != 3 {
b.Fatal(i, got)
}
}
} }
func Benchmark_memcpy(b *testing.B) { func Benchmark_memcpy(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr2, 5, size) fill(memory[ptr2:ptr2+size], 5)
b.SetBytes(size) b.SetBytes(size)
b.ResetTimer() b.ResetTimer()
for range b.N { for range b.N {
call(memcpy, ptr1, ptr2, size) call(memcpy, ptr1, ptr2, size)
} }
b.StopTimer()
for i, got := range memory[ptr1 : ptr1+size] {
if got != 5 {
b.Fatal(i, got)
}
}
} }
func Benchmark_memchr(b *testing.B) { func Benchmark_memchr(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 7, size) fill(memory[ptr1:ptr1+size/2], 7)
call(memset, ptr1+size/2, 5, size/2) fill(memory[ptr1+size/2:ptr1+size], 5)
b.SetBytes(size/2 + 1) b.SetBytes(size/2 + 1)
b.ResetTimer() b.ResetTimer()
for range b.N { for range b.N {
call(memchr, ptr1, 5, size) call(memchr, ptr1, 5, size)
} }
b.StopTimer()
if got := call(memchr, ptr1, 5, size); got != ptr1+size/2 {
b.Fatal(got)
}
if got := call(memchr, ptr1, 5, size/2); got != 0 {
b.Fatal(got, ptr1+size/2)
}
} }
func Benchmark_memcmp(b *testing.B) { func Benchmark_memcmp(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 7, size) fill(memory[ptr1:ptr1+size], 7)
call(memset, ptr2, 7, size) fill(memory[ptr2:ptr2+size/2], 7)
call(memset, ptr2+size/2, 5, size/2) fill(memory[ptr2+size/2:ptr2+size], 5)
b.SetBytes(size/2 + 1) b.SetBytes(size/2 + 1)
b.ResetTimer() b.ResetTimer()
for range b.N { for range b.N {
call(memcmp, ptr1, ptr2, size) call(memcmp, ptr1, ptr2, size)
} }
b.StopTimer()
// ptr1 > ptr2
if got := int32(call(memcmp, ptr1, ptr2, size)); got <= 0 {
b.Fatal(got)
}
// ptr1[:size/2] == ptr2[:size/2]
if got := int32(call(memcmp, ptr1, ptr2, size/2)); got != 0 {
b.Fatal(got)
}
} }
func Benchmark_strlen(b *testing.B) { func Benchmark_strlen(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 5, size-1) fill(memory[ptr1:ptr1+size-1], 5)
b.SetBytes(size) b.SetBytes(size)
b.ResetTimer() b.ResetTimer()
for range b.N { for range b.N {
call(strlen, ptr1) call(strlen, ptr1)
} }
b.StopTimer()
if got := int32(call(strlen, ptr1)); got != size-1 {
b.Fatal(got)
}
} }
func Benchmark_strchr(b *testing.B) { func Benchmark_strchr(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 7, size-1) fill(memory[ptr1:ptr1+size/2], 7)
call(memset, ptr1+size/2, 5, size/2-1) fill(memory[ptr1+size/2:ptr1+size-1], 5)
b.SetBytes(size/2 + 1) b.SetBytes(size/2 + 1)
b.ResetTimer() b.ResetTimer()
for range b.N { for range b.N {
call(strchr, ptr1, 5) call(strchr, ptr1, 5)
} }
b.StopTimer()
if got := call(strchr, ptr1, 5); got != ptr1+size/2 {
b.Fatal(got)
}
} }
func Benchmark_strcmp(b *testing.B) { func Benchmark_strcmp(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 7, size-1) fill(memory[ptr1:ptr1+size-1], 7)
call(memset, ptr2, 7, size-1) fill(memory[ptr2:ptr2+size/2], 7)
call(memset, ptr2+size/2, 5, size/2-1) fill(memory[ptr2+size/2:ptr2+size-1], 5)
b.SetBytes(size/2 + 1) b.SetBytes(size/2 + 1)
b.ResetTimer() b.ResetTimer()
for range b.N { for range b.N {
call(strcmp, ptr1, ptr2, size) call(strcmp, ptr1, ptr2, size)
} }
b.StopTimer()
// ptr1 > ptr2
if got := int32(call(strcmp, ptr1, ptr2)); got <= 0 {
b.Fatal(got)
}
// make ptr1 < ptr2
memory[ptr1+size/2] = 0
if got := int32(call(strcmp, ptr1, ptr2)); got >= 0 {
b.Fatal(got)
}
memory[ptr2+size/2] = 0
// make ptr1 == ptr2
if got := int32(call(strcmp, ptr1, ptr2)); got != 0 {
b.Fatal(got)
}
} }
func Benchmark_strncmp(b *testing.B) { func Benchmark_strncmp(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 7, size-1) fill(memory[ptr1:ptr1+size-1], 7)
call(memset, ptr2, 7, size-1) fill(memory[ptr2:ptr2+size/2], 7)
call(memset, ptr2+size/2, 5, size/2-1) fill(memory[ptr2+size/2:ptr2+size-1], 5)
b.SetBytes(size/2 + 1) b.SetBytes(size/2 + 1)
b.ResetTimer() b.ResetTimer()
for range b.N { for range b.N {
call(strncmp, ptr1, ptr2, size-1) call(strncmp, ptr1, ptr2, size-1)
} }
b.StopTimer()
// ptr1 > ptr2
if got := int32(call(strncmp, ptr1, ptr2, size-1)); got <= 0 {
b.Fatal(got)
}
// make ptr1 < ptr2
memory[ptr1+size/2] = 0
if got := int32(call(strncmp, ptr1, ptr2, size-1)); got >= 0 {
b.Fatal(got)
}
// ptr1[:size/2] == ptr2[:size/2]
if got := int32(call(strncmp, ptr1, ptr2, size/2-1)); got != 0 {
b.Fatal(got)
}
} }
func Benchmark_strspn(b *testing.B) { func Benchmark_strspn(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 7, size-1) fill(memory[ptr1:ptr1+size/2], 7)
call(memset, ptr1+size/2, 5, size/2-1) fill(memory[ptr1+size/2:ptr1+size-1], 5)
memory[ptr2+0] = 3 memory[ptr2+0] = 3
memory[ptr2+1] = 5 memory[ptr2+1] = 5
memory[ptr2+2] = 7 memory[ptr2+2] = 7
@@ -248,21 +179,12 @@ func Benchmark_strspn(b *testing.B) {
for range b.N { for range b.N {
call(strspn, ptr1, ptr2) call(strspn, ptr1, ptr2)
} }
b.StopTimer()
if got := int32(call(strspn, ptr1, ptr2)); got != size-1 {
b.Fatal(got)
}
memory[ptr1+size/2] = 11
if got := int32(call(strspn, ptr1, ptr2)); got != size/2 {
b.Fatal(got)
}
} }
func Benchmark_strcspn(b *testing.B) { func Benchmark_strcspn(b *testing.B) {
clear(memory) clear(memory)
call(memset, ptr1, 7, size-1) fill(memory[ptr1:ptr1+size/2], 7)
call(memset, ptr1+size/2, 5, size/2-1) fill(memory[ptr1+size/2:ptr1+size-1], 5)
memory[ptr2+0] = 3 memory[ptr2+0] = 3
memory[ptr2+1] = 9 memory[ptr2+1] = 9
@@ -271,13 +193,237 @@ func Benchmark_strcspn(b *testing.B) {
for range b.N { for range b.N {
call(strcspn, ptr1, ptr2) call(strcspn, ptr1, ptr2)
} }
b.StopTimer() }
if got := int32(call(strcspn, ptr1, ptr2)); got != size-1 { func Test_memchr(t *testing.T) {
b.Fatal(got) for length := range 64 {
} for pos := range length + 2 {
memory[ptr1+size/2] = 3 for alignment := range 24 {
if got := int32(call(strcspn, ptr1, ptr2)); got != size/2 { clear(memory[:2*page])
b.Fatal(got)
ptr := (page - 8) + alignment
fill(memory[ptr:ptr+max(pos, length)], 5)
memory[ptr+pos] = 7
want := 0
if pos < length {
want = ptr + pos
}
got := call(memchr, uint64(ptr), 7, uint64(length))
if uint32(got) != uint32(want) {
t.Errorf("memchr(%d, %d, %d) = %d, want %d",
ptr, 7, uint64(length), uint32(got), uint32(want))
}
}
}
clear(memory)
ptr := len(memory) - length
fill(memory[ptr:ptr+length], 5)
memory[len(memory)-1] = 7
want := len(memory) - 1
if length == 0 {
want = 0
}
got := call(memchr, uint64(ptr), 7, uint64(length))
if uint32(got) != uint32(want) {
t.Errorf("memchr(%d, %d, %d) = %d, want %d",
ptr, 7, uint64(length), uint32(got), uint32(want))
}
}
}
func Test_strlen(t *testing.T) {
for length := range 64 {
for alignment := range 24 {
clear(memory[:2*page])
ptr := (page - 8) + alignment
fill(memory[ptr:ptr+length], 5)
got := call(strlen, uint64(ptr))
if uint32(got) != uint32(length) {
t.Errorf("strlen(%d) = %d, want %d",
ptr, uint32(got), uint32(length))
}
memory[ptr-1] = 5
got = call(strlen, uint64(ptr))
if uint32(got) != uint32(length) {
t.Errorf("strlen(%d) = %d, want %d",
ptr, uint32(got), uint32(length))
}
}
clear(memory)
ptr := len(memory) - length - 1
fill(memory[ptr:ptr+length], 5)
got := call(strlen, uint64(ptr))
if uint32(got) != uint32(length) {
t.Errorf("strlen(%d) = %d, want %d",
ptr, uint32(got), uint32(length))
}
}
}
func Test_strchr(t *testing.T) {
for length := range 64 {
for pos := range length + 2 {
for alignment := range 24 {
clear(memory[:2*page])
ptr := (page - 8) + alignment
fill(memory[ptr:ptr+max(pos, length)], 5)
memory[ptr+pos] = 7
memory[ptr+length] = 0
want := 0
if pos < length {
want = ptr + pos
}
got := call(strchr, uint64(ptr), 7)
if uint32(got) != uint32(want) {
t.Errorf("strchr(%d, %d) = %d, want %d",
ptr, 7, uint32(got), uint32(want))
}
}
}
clear(memory)
ptr := len(memory) - length
fill(memory[ptr:ptr+length], 5)
memory[len(memory)-1] = 7
want := len(memory) - 1
if length == 0 {
continue
}
got := call(strchr, uint64(ptr), 7)
if uint32(got) != uint32(want) {
t.Errorf("strchr(%d, %d) = %d, want %d",
ptr, 7, uint32(got), uint32(want))
}
}
}
func Test_strspn(t *testing.T) {
for length := range 64 {
for pos := range length + 2 {
for alignment := range 24 {
clear(memory[:2*page])
ptr := (page - 8) + alignment
fill(memory[ptr:ptr+max(pos, length)], 5)
memory[ptr+pos] = 7
memory[ptr+length] = 0
memory[128] = 3
memory[129] = 5
want := min(pos, length)
got := call(strspn, uint64(ptr), 129)
if uint32(got) != uint32(want) {
t.Errorf("strspn(%d, %d) = %d, want %d",
ptr, 129, uint32(got), uint32(want))
}
got = call(strspn, uint64(ptr), 128)
if uint32(got) != uint32(want) {
t.Errorf("strspn(%d, %d) = %d, want %d",
ptr, 128, uint32(got), uint32(want))
}
}
}
clear(memory)
ptr := len(memory) - length
fill(memory[ptr:ptr+length], 5)
memory[len(memory)-1] = 7
memory[128] = 3
memory[129] = 5
want := length - 1
if length == 0 {
continue
}
got := call(strspn, uint64(ptr), 129)
if uint32(got) != uint32(want) {
t.Errorf("strspn(%d, %d) = %d, want %d",
ptr, 129, uint32(got), uint32(want))
}
got = call(strspn, uint64(ptr), 128)
if uint32(got) != uint32(want) {
t.Errorf("strspn(%d, %d) = %d, want %d",
ptr, 128, uint32(got), uint32(want))
}
}
}
func Test_strcspn(t *testing.T) {
for length := range 64 {
for pos := range length + 2 {
for alignment := range 24 {
clear(memory[:2*page])
ptr := (page - 8) + alignment
fill(memory[ptr:ptr+max(pos, length)], 5)
memory[ptr+pos] = 7
memory[ptr+length] = 0
memory[128] = 3
memory[129] = 7
want := min(pos, length)
got := call(strcspn, uint64(ptr), 129)
if uint32(got) != uint32(want) {
t.Errorf("strcspn(%d, %d) = %d, want %d",
ptr, 129, uint32(got), uint32(want))
}
got = call(strcspn, uint64(ptr), 128)
if uint32(got) != uint32(want) {
t.Errorf("strcspn(%d, %d) = %d, want %d",
ptr, 128, uint32(got), uint32(want))
}
}
}
clear(memory)
ptr := len(memory) - length
fill(memory[ptr:ptr+length], 5)
memory[len(memory)-1] = 7
memory[128] = 3
memory[129] = 7
want := length - 1
if length == 0 {
continue
}
got := call(strcspn, uint64(ptr), 129)
if uint32(got) != uint32(want) {
t.Errorf("strcspn(%d, %d) = %d, want %d",
ptr, 129, uint32(got), uint32(want))
}
got = call(strcspn, uint64(ptr), 128)
if uint32(got) != uint32(want) {
t.Errorf("strcspn(%d, %d) = %d, want %d",
ptr, 128, uint32(got), uint32(want))
}
}
}
func fill(s []byte, v byte) {
for i := range s {
s[i] = v
} }
} }