make runtime compatible with wasm

This commit is contained in:
Li Jie
2025-04-08 16:50:47 +08:00
parent 7c81d9293b
commit be4737461a
183 changed files with 14122 additions and 647 deletions

View File

@@ -0,0 +1,181 @@
package test
/*
#include <time.h>
#include <pthread.h>
#include <setjmp.h>
#include <sys/types.h>
*/
import "C"
import (
"runtime"
"unsafe"
_ "github.com/goplus/llgo/c"
)
var mode C.mode_t
var uid C.uid_t
var gid C.gid_t
var off C.off_t
var dev C.dev_t
var once C.pthread_once_t
var mutex C.pthread_mutex_t
var cond C.pthread_cond_t
var rwlock C.pthread_rwlock_t
var mutexattr C.pthread_mutexattr_t
var condattr C.pthread_condattr_t
var rwlockattr C.pthread_rwlockattr_t
var clock C.clock_t
var sigjmpbuf C.sigjmp_buf
var jmpbuf C.jmp_buf
const (
// Real sizes from the current platform
pthreadOnceSizeReal = unsafe.Sizeof(once)
pthreadMutexSizeReal = unsafe.Sizeof(mutex)
pthreadMutexAttrSizeReal = unsafe.Sizeof(mutexattr)
pthreadCondSizeReal = unsafe.Sizeof(cond)
pthreadCondAttrSizeReal = unsafe.Sizeof(condattr)
pthreadRWLockSizeReal = unsafe.Sizeof(rwlock)
pthreadRWLockAttrSizeReal = unsafe.Sizeof(rwlockattr)
clockSizeReal = unsafe.Sizeof(clock)
sigjmpBufSizeReal = unsafe.Sizeof(sigjmpbuf)
jmpBufSizeReal = unsafe.Sizeof(jmpbuf)
)
// Linux amd64 specific sizes
var linuxAmd64 = runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
// Linux arm64 specific sizes
var linuxArm64 = runtime.GOOS == "linux" && runtime.GOARCH == "arm64"
// macOS amd64 specific sizes
var darwinAmd64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64"
// macOS arm64 specific sizes
var darwinArm64 = runtime.GOOS == "darwin" && runtime.GOARCH == "arm64"
const (
// Linux amd64 pthread sizes
pthreadOnceSizeLinuxAmd64 = 4
pthreadMutexSizeLinuxAmd64 = 40
pthreadMutexAttrSizeLinuxAmd64 = 4
pthreadCondSizeLinuxAmd64 = 48
pthreadCondAttrSizeLinuxAmd64 = 4
pthreadRWLockSizeLinuxAmd64 = 56
pthreadRWLockAttrSizeLinuxAmd64 = 8
clockSizeLinuxAmd64 = 8
sigjmpBufSizeLinuxAmd64 = 200
jmpBufSizeLinuxAmd64 = 200
// Linux arm64 pthread sizes
pthreadOnceSizeLinuxArm64 = 4
pthreadMutexSizeLinuxArm64 = 48
pthreadMutexAttrSizeLinuxArm64 = 8
pthreadCondSizeLinuxArm64 = 48
pthreadCondAttrSizeLinuxArm64 = 8
pthreadRWLockSizeLinuxArm64 = 56
pthreadRWLockAttrSizeLinuxArm64 = 8
clockSizeLinuxArm64 = 8
sigjmpBufSizeLinuxArm64 = 312
jmpBufSizeLinuxArm64 = 312
// macOS amd64 pthread sizes
pthreadOnceSizeDarwinAmd64 = 16
pthreadMutexSizeDarwinAmd64 = 56
pthreadMutexAttrSizeDarwinAmd64 = 8
pthreadCondSizeDarwinAmd64 = 40
pthreadCondAttrSizeDarwinAmd64 = 8
pthreadRWLockSizeDarwinAmd64 = 192
pthreadRWLockAttrSizeDarwinAmd64 = 16
clockSizeDarwinAmd64 = 8
sigjmpBufSizeDarwinAmd64 = 196
jmpBufSizeDarwinAmd64 = 196
// macOS arm64 pthread sizes
pthreadOnceSizeDarwinArm64 = 16
pthreadMutexSizeDarwinArm64 = 64
pthreadMutexAttrSizeDarwinArm64 = 16
pthreadCondSizeDarwinArm64 = 48
pthreadCondAttrSizeDarwinArm64 = 16
pthreadRWLockSizeDarwinArm64 = 200
pthreadRWLockAttrSizeDarwinArm64 = 24
clockSizeDarwinArm64 = 8
sigjmpBufSizeDarwinArm64 = 196
jmpBufSizeDarwinArm64 = 192
)
// Get architecture-specific pthread sizes based on the current platform
func getPlatformPthreadSizes() (onceSize, mutexSize, mutexAttrSize, condSize, condAttrSize, rwlockSize, rwlockAttrSize int) {
switch {
case linuxAmd64:
return pthreadOnceSizeLinuxAmd64, pthreadMutexSizeLinuxAmd64, pthreadMutexAttrSizeLinuxAmd64,
pthreadCondSizeLinuxAmd64, pthreadCondAttrSizeLinuxAmd64, pthreadRWLockSizeLinuxAmd64, pthreadRWLockAttrSizeLinuxAmd64
case linuxArm64:
return pthreadOnceSizeLinuxArm64, pthreadMutexSizeLinuxArm64, pthreadMutexAttrSizeLinuxArm64,
pthreadCondSizeLinuxArm64, pthreadCondAttrSizeLinuxArm64, pthreadRWLockSizeLinuxArm64, pthreadRWLockAttrSizeLinuxArm64
case darwinAmd64:
return pthreadOnceSizeDarwinAmd64, pthreadMutexSizeDarwinAmd64, pthreadMutexAttrSizeDarwinAmd64,
pthreadCondSizeDarwinAmd64, pthreadCondAttrSizeDarwinAmd64, pthreadRWLockSizeDarwinAmd64, pthreadRWLockAttrSizeDarwinAmd64
case darwinArm64:
return pthreadOnceSizeDarwinArm64, pthreadMutexSizeDarwinArm64, pthreadMutexAttrSizeDarwinArm64,
pthreadCondSizeDarwinArm64, pthreadCondAttrSizeDarwinArm64, pthreadRWLockSizeDarwinArm64, pthreadRWLockAttrSizeDarwinArm64
default:
panic("Unsupported platform: " + runtime.GOOS + ", " + runtime.GOARCH)
}
}
func getPlatformClockSizes() (clockSize int) {
switch {
case linuxAmd64:
return clockSizeLinuxAmd64
case linuxArm64:
return clockSizeLinuxArm64
case darwinAmd64:
return clockSizeDarwinAmd64
case darwinArm64:
return clockSizeDarwinArm64
default:
panic("Unsupported platform: " + runtime.GOOS + ", " + runtime.GOARCH)
}
}
func getPlatformJmpBufSizes() (sigjmpBufSize, jmpBufSize int) {
switch {
case linuxAmd64:
return sigjmpBufSizeLinuxAmd64, jmpBufSizeLinuxAmd64
case linuxArm64:
return sigjmpBufSizeLinuxArm64, jmpBufSizeLinuxArm64
case darwinAmd64:
return sigjmpBufSizeDarwinAmd64, jmpBufSizeDarwinAmd64
case darwinArm64:
return sigjmpBufSizeDarwinArm64, jmpBufSizeDarwinArm64
default:
panic("Unsupported platform: " + runtime.GOOS + ", " + runtime.GOARCH)
}
}
func max(a int, others ...int) int {
max := a
for _, v := range others {
if v > max {
max = v
}
}
return max
}
var (
pthreadOnceSize = max(pthreadOnceSizeLinuxAmd64, pthreadOnceSizeDarwinAmd64, pthreadOnceSizeLinuxArm64, pthreadOnceSizeDarwinArm64)
pthreadMutexSize = max(pthreadMutexSizeLinuxAmd64, pthreadMutexSizeLinuxArm64, pthreadMutexSizeDarwinAmd64, pthreadMutexSizeDarwinArm64)
pthreadMutexAttrSize = max(pthreadMutexAttrSizeLinuxAmd64, pthreadMutexAttrSizeLinuxArm64, pthreadMutexAttrSizeDarwinAmd64, pthreadMutexAttrSizeDarwinArm64)
pthreadCondSize = max(pthreadCondSizeLinuxAmd64, pthreadCondSizeLinuxArm64, pthreadCondSizeDarwinAmd64, pthreadCondSizeDarwinArm64)
pthreadCondAttrSize = max(pthreadCondAttrSizeLinuxAmd64, pthreadCondAttrSizeLinuxArm64, pthreadCondAttrSizeDarwinAmd64, pthreadCondAttrSizeDarwinArm64)
pthreadRWLockSize = max(pthreadRWLockSizeLinuxAmd64, pthreadRWLockSizeLinuxArm64, pthreadRWLockSizeDarwinAmd64, pthreadRWLockSizeDarwinArm64)
pthreadRWLockAttrSize = max(pthreadRWLockAttrSizeLinuxAmd64, pthreadRWLockAttrSizeLinuxArm64, pthreadRWLockAttrSizeDarwinAmd64, pthreadRWLockAttrSizeDarwinArm64)
clockSize = max(clockSizeLinuxAmd64, clockSizeLinuxArm64, clockSizeDarwinAmd64, clockSizeDarwinArm64)
sigjmpBufSize = max(sigjmpBufSizeLinuxAmd64, sigjmpBufSizeLinuxArm64, sigjmpBufSizeDarwinAmd64, sigjmpBufSizeDarwinArm64)
jmpBufSize = max(jmpBufSizeLinuxAmd64, jmpBufSizeLinuxArm64, jmpBufSizeDarwinAmd64, jmpBufSizeDarwinArm64)
)

View File

@@ -0,0 +1,202 @@
package test
import (
"runtime"
"testing"
"unsafe"
"github.com/goplus/llgo/runtime/internal/clite/os"
"github.com/goplus/llgo/runtime/internal/clite/pthread/sync"
"github.com/goplus/llgo/runtime/internal/clite/setjmp"
"github.com/goplus/llgo/runtime/internal/clite/time"
)
func TestOSTypes(t *testing.T) {
if unsafe.Sizeof(mode) != unsafe.Sizeof(os.ModeT(0)) {
t.Fatalf("mode size mismatch: %d != %d", unsafe.Sizeof(mode), unsafe.Sizeof(os.ModeT(0)))
}
if unsafe.Sizeof(uid) != unsafe.Sizeof(os.UidT(0)) {
t.Fatalf("uid size mismatch: %d != %d", unsafe.Sizeof(uid), unsafe.Sizeof(os.UidT(0)))
}
if unsafe.Sizeof(gid) != unsafe.Sizeof(os.GidT(0)) {
t.Fatalf("gid size mismatch: %d != %d", unsafe.Sizeof(gid), unsafe.Sizeof(os.GidT(0)))
}
if unsafe.Sizeof(off) != unsafe.Sizeof(os.OffT(0)) {
t.Fatalf("off size mismatch: %d != %d", unsafe.Sizeof(off), unsafe.Sizeof(os.OffT(0)))
}
if unsafe.Sizeof(dev) != unsafe.Sizeof(os.DevT(0)) {
t.Fatalf("dev size mismatch: %d != %d", unsafe.Sizeof(dev), unsafe.Sizeof(os.DevT(0)))
}
}
func TestTypeSizes(t *testing.T) {
// Test platform-specific sizes based on OS and architecture
switch {
case runtime.GOOS == "linux" && runtime.GOARCH == "amd64":
// Linux amd64 specific tests
if pthreadOnceSizeLinuxAmd64 != pthreadOnceSizeReal {
t.Fatalf("pthreadOnceSizeLinuxAmd64 mismatch: %d != %d", pthreadOnceSizeLinuxAmd64, pthreadOnceSizeReal)
}
if pthreadMutexSizeLinuxAmd64 != pthreadMutexSizeReal {
t.Fatalf("pthreadMutexSizeLinuxAmd64 mismatch: %d != %d", pthreadMutexSizeLinuxAmd64, pthreadMutexSizeReal)
}
if pthreadMutexAttrSizeLinuxAmd64 != pthreadMutexAttrSizeReal {
t.Fatalf("pthreadMutexAttrSizeLinuxAmd64 mismatch: %d != %d", pthreadMutexAttrSizeLinuxAmd64, pthreadMutexAttrSizeReal)
}
if pthreadCondSizeLinuxAmd64 != pthreadCondSizeReal {
t.Fatalf("pthreadCondSizeLinuxAmd64 mismatch: %d != %d", pthreadCondSizeLinuxAmd64, pthreadCondSizeReal)
}
if pthreadCondAttrSizeLinuxAmd64 != pthreadCondAttrSizeReal {
t.Fatalf("pthreadCondAttrSizeLinuxAmd64 mismatch: %d != %d", pthreadCondAttrSizeLinuxAmd64, pthreadCondAttrSizeReal)
}
if pthreadRWLockSizeLinuxAmd64 != pthreadRWLockSizeReal {
t.Fatalf("pthreadRWLockSizeLinuxAmd64 mismatch: %d != %d", pthreadRWLockSizeLinuxAmd64, pthreadRWLockSizeReal)
}
if pthreadRWLockAttrSizeLinuxAmd64 != pthreadRWLockAttrSizeReal {
t.Fatalf("pthreadRWLockAttrSizeLinuxAmd64 mismatch: %d != %d", pthreadRWLockAttrSizeLinuxAmd64, pthreadRWLockAttrSizeReal)
}
if clockSizeLinuxAmd64 != clockSizeReal {
t.Fatalf("clockSizeLinuxAmd64 mismatch: %d != %d", clockSizeLinuxAmd64, clockSizeReal)
}
if sigjmpBufSizeLinuxAmd64 != sigjmpBufSizeReal {
t.Fatalf("sigjmpBufSizeLinuxAmd64 mismatch: %d != %d", sigjmpBufSizeLinuxAmd64, sigjmpBufSizeReal)
}
if jmpBufSizeLinuxAmd64 != jmpBufSizeReal {
t.Fatalf("jmpBufSizeLinuxAmd64 mismatch: %d != %d", jmpBufSizeLinuxAmd64, jmpBufSizeReal)
}
case runtime.GOOS == "linux" && runtime.GOARCH == "arm64":
// Linux arm64 specific tests
if pthreadOnceSizeLinuxArm64 != pthreadOnceSizeReal {
t.Fatalf("pthreadOnceSizeLinuxArm64 mismatch: %d != %d", pthreadOnceSizeLinuxArm64, pthreadOnceSizeReal)
}
if pthreadMutexSizeLinuxArm64 != pthreadMutexSizeReal {
t.Fatalf("pthreadMutexSizeLinuxArm64 mismatch: %d != %d", pthreadMutexSizeLinuxArm64, pthreadMutexSizeReal)
}
if pthreadMutexAttrSizeLinuxArm64 != pthreadMutexAttrSizeReal {
t.Fatalf("pthreadMutexAttrSizeLinuxArm64 mismatch: %d != %d", pthreadMutexAttrSizeLinuxArm64, pthreadMutexAttrSizeReal)
}
if pthreadCondSizeLinuxArm64 != pthreadCondSizeReal {
t.Fatalf("pthreadCondSizeLinuxArm64 mismatch: %d != %d", pthreadCondSizeLinuxArm64, pthreadCondSizeReal)
}
if pthreadCondAttrSizeLinuxArm64 != pthreadCondAttrSizeReal {
t.Fatalf("pthreadCondAttrSizeLinuxArm64 mismatch: %d != %d", pthreadCondAttrSizeLinuxArm64, pthreadCondAttrSizeReal)
}
if pthreadRWLockSizeLinuxArm64 != pthreadRWLockSizeReal {
t.Fatalf("pthreadRWLockSizeLinuxArm64 mismatch: %d != %d", pthreadRWLockSizeLinuxArm64, pthreadRWLockSizeReal)
}
if pthreadRWLockAttrSizeLinuxArm64 != pthreadRWLockAttrSizeReal {
t.Fatalf("pthreadRWLockAttrSizeLinuxArm64 mismatch: %d != %d", pthreadRWLockAttrSizeLinuxArm64, pthreadRWLockAttrSizeReal)
}
if clockSizeLinuxArm64 != clockSizeReal {
t.Fatalf("clockSizeLinuxArm64 mismatch: %d != %d", clockSizeLinuxArm64, clockSizeReal)
}
if sigjmpBufSizeLinuxArm64 != sigjmpBufSizeReal {
t.Fatalf("sigjmpBufSizeLinuxArm64 mismatch: %d != %d", sigjmpBufSizeLinuxArm64, sigjmpBufSizeReal)
}
if jmpBufSizeLinuxArm64 != jmpBufSizeReal {
t.Fatalf("jmpBufSizeLinuxArm64 mismatch: %d != %d", jmpBufSizeLinuxArm64, jmpBufSizeReal)
}
case runtime.GOOS == "darwin" && runtime.GOARCH == "amd64":
// macOS amd64 specific tests
if pthreadOnceSizeDarwinAmd64 != pthreadOnceSizeReal {
t.Fatalf("pthreadOnceSizeDarwinAmd64 mismatch: %d != %d", pthreadOnceSizeDarwinAmd64, pthreadOnceSizeReal)
}
if pthreadMutexSizeDarwinAmd64 != pthreadMutexSizeReal {
t.Fatalf("pthreadMutexSizeDarwinAmd64 mismatch: %d != %d", pthreadMutexSizeDarwinAmd64, pthreadMutexSizeReal)
}
if pthreadMutexAttrSizeDarwinAmd64 != pthreadMutexAttrSizeReal {
t.Fatalf("pthreadMutexAttrSizeDarwinAmd64 mismatch: %d != %d", pthreadMutexAttrSizeDarwinAmd64, pthreadMutexAttrSizeReal)
}
if pthreadCondSizeDarwinAmd64 != pthreadCondSizeReal {
t.Fatalf("pthreadCondSizeDarwinAmd64 mismatch: %d != %d", pthreadCondSizeDarwinAmd64, pthreadCondSizeReal)
}
if pthreadCondAttrSizeDarwinAmd64 != pthreadCondAttrSizeReal {
t.Fatalf("pthreadCondAttrSizeDarwinAmd64 mismatch: %d != %d", pthreadCondAttrSizeDarwinAmd64, pthreadCondAttrSizeReal)
}
if pthreadRWLockSizeDarwinAmd64 != pthreadRWLockSizeReal {
t.Fatalf("pthreadRWLockSizeDarwinAmd64 mismatch: %d != %d", pthreadRWLockSizeDarwinAmd64, pthreadRWLockSizeReal)
}
if pthreadRWLockAttrSizeDarwinAmd64 != pthreadRWLockAttrSizeReal {
t.Fatalf("pthreadRWLockAttrSizeDarwinAmd64 mismatch: %d != %d", pthreadRWLockAttrSizeDarwinAmd64, pthreadRWLockAttrSizeReal)
}
if clockSizeDarwinAmd64 != clockSizeReal {
t.Fatalf("clockSizeDarwinAmd64 mismatch: %d != %d", clockSizeDarwinAmd64, clockSizeReal)
}
if sigjmpBufSizeDarwinAmd64 != sigjmpBufSizeReal {
t.Fatalf("sigjmpBufSizeDarwinAmd64 mismatch: %d != %d", sigjmpBufSizeDarwinAmd64, sigjmpBufSizeReal)
}
if jmpBufSizeDarwinAmd64 != jmpBufSizeReal {
t.Fatalf("jmpBufSizeDarwinAmd64 mismatch: %d != %d", jmpBufSizeDarwinAmd64, jmpBufSizeReal)
}
case runtime.GOOS == "darwin" && runtime.GOARCH == "arm64":
// macOS arm64 specific tests
if pthreadOnceSizeDarwinArm64 != pthreadOnceSizeReal {
t.Fatalf("pthreadOnceSizeDarwinArm64 mismatch: %d != %d", pthreadOnceSizeDarwinArm64, pthreadOnceSizeReal)
}
if pthreadMutexSizeDarwinArm64 != pthreadMutexSizeReal {
t.Fatalf("pthreadMutexSizeDarwinArm64 mismatch: %d != %d", pthreadMutexSizeDarwinArm64, pthreadMutexSizeReal)
}
if pthreadMutexAttrSizeDarwinArm64 != pthreadMutexAttrSizeReal {
t.Fatalf("pthreadMutexAttrSizeDarwinArm64 mismatch: %d != %d", pthreadMutexAttrSizeDarwinArm64, pthreadMutexAttrSizeReal)
}
if pthreadCondSizeDarwinArm64 != pthreadCondSizeReal {
t.Fatalf("pthreadCondSizeDarwinArm64 mismatch: %d != %d", pthreadCondSizeDarwinArm64, pthreadCondSizeReal)
}
if pthreadCondAttrSizeDarwinArm64 != pthreadCondAttrSizeReal {
t.Fatalf("pthreadCondAttrSizeDarwinArm64 mismatch: %d != %d", pthreadCondAttrSizeDarwinArm64, pthreadCondAttrSizeReal)
}
if pthreadRWLockSizeDarwinArm64 != pthreadRWLockSizeReal {
t.Fatalf("pthreadRWLockSizeDarwinArm64 mismatch: %d != %d", pthreadRWLockSizeDarwinArm64, pthreadRWLockSizeReal)
}
if pthreadRWLockAttrSizeDarwinArm64 != pthreadRWLockAttrSizeReal {
t.Fatalf("pthreadRWLockAttrSizeDarwinArm64 mismatch: %d != %d", pthreadRWLockAttrSizeDarwinArm64, pthreadRWLockAttrSizeReal)
}
if clockSizeDarwinArm64 != clockSizeReal {
t.Fatalf("clockSizeDarwinArm64 mismatch: %d != %d", clockSizeDarwinArm64, clockSizeReal)
}
if sigjmpBufSizeDarwinArm64 != sigjmpBufSizeReal {
t.Fatalf("sigjmpBufSizeDarwinArm64 mismatch: %d != %d", sigjmpBufSizeDarwinArm64, sigjmpBufSizeReal)
}
if jmpBufSizeDarwinArm64 != jmpBufSizeReal {
t.Fatalf("jmpBufSizeDarwinArm64 mismatch: %d != %d", jmpBufSizeDarwinArm64, jmpBufSizeReal)
}
default:
t.Fatalf("Unsupported platform: %s, %s", runtime.GOOS, runtime.GOARCH)
}
// Sync package size checks
onceSize, mutexSize, mutexAttrSize, condSize, condAttrSize, rwlockSize, rwlockAttrSize := getPlatformPthreadSizes()
clockSize := getPlatformClockSizes()
sigjmpBufSize, jmpBufSize := getPlatformJmpBufSizes()
if sync.PthreadOnceSize != onceSize {
t.Fatalf("PthreadOnceSize mismatch: %d != %d", sync.PthreadOnceSize, onceSize)
}
if sync.PthreadMutexSize != mutexSize {
t.Fatalf("PthreadMutexSize mismatch: %d != %d", sync.PthreadMutexSize, mutexSize)
}
if sync.PthreadMutexAttrSize != mutexAttrSize {
t.Fatalf("PthreadMutexAttrSize mismatch: %d != %d", sync.PthreadMutexAttrSize, mutexAttrSize)
}
if sync.PthreadCondSize != condSize {
t.Fatalf("PthreadCondSize mismatch: %d != %d", sync.PthreadCondSize, condSize)
}
if sync.PthreadCondAttrSize != condAttrSize {
t.Fatalf("PthreadCondAttrSize mismatch: %d != %d", sync.PthreadCondAttrSize, condAttrSize)
}
if sync.PthreadRWLockSize != rwlockSize {
t.Fatalf("PthreadRWLockSize mismatch: %d != %d", sync.PthreadRWLockSize, rwlockSize)
}
if sync.PthreadRWLockAttrSize != rwlockAttrSize {
t.Fatalf("PthreadRWLockAttrSize mismatch: %d != %d", sync.PthreadRWLockAttrSize, rwlockAttrSize)
}
if time.ClockTSize != clockSize {
t.Fatalf("ClockSize mismatch: %d != %d", time.ClockTSize, clockSize)
}
if setjmp.SigjmpBufSize != sigjmpBufSize {
t.Fatalf("SigjmpBufSize mismatch: %d != %d", setjmp.SigjmpBufSize, sigjmpBufSize)
}
if setjmp.JmpBufSize != jmpBufSize {
t.Fatalf("JmpBufSize mismatch: %d != %d", setjmp.JmpBufSize, jmpBufSize)
}
}