From 336b9b33ab9dc51235519d0a7ce2116fe44fbe4e Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Wed, 21 Aug 2024 02:03:02 +0200 Subject: [PATCH 01/24] tinygo: detect GOOS=wasip1 for relative WASI paths via config instead of target name (#4423) --- main.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 8f788efb86..51e62aaaee 100644 --- a/main.go +++ b/main.go @@ -305,13 +305,11 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options // // Ex. run --dir=.. --dir=../.. --dir=../../.. var dirs []string - switch config.Options.Target { + switch config.Target.GOOS { case "wasip1": dirs = dirsToModuleRootRel(result.MainDir, result.ModuleRoot) - case "wasip2": - dirs = dirsToModuleRootAbs(result.MainDir, result.ModuleRoot) default: - return fmt.Errorf("unknown GOOS target: %v", config.Options.Target) + dirs = dirsToModuleRootAbs(result.MainDir, result.ModuleRoot) } args := []string{"run"} From 83c98a23cea4d3d59d228ffa60f69303fd57dbb0 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 21 Aug 2024 16:30:29 +0200 Subject: [PATCH 02/24] mips: fix crash with GOMIPS=softfloat `defer` and `GOMIPS=softfloat` together would result in a crash. This patch fixes this issue. --- compiler/defer.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/defer.go b/compiler/defer.go index df8686957a..677df8f2a1 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -16,6 +16,7 @@ package compiler import ( "go/types" "strconv" + "strings" "github.com/tinygo-org/tinygo/compiler/llvmutil" "golang.org/x/tools/go/ssa" @@ -198,7 +199,13 @@ jal 1f addiu $$ra, 8 sw $$ra, 4($$5) .set at` - constraints = "={$4},{$5},~{$1},~{$2},~{$3},~{$5},~{$6},~{$7},~{$8},~{$9},~{$10},~{$11},~{$12},~{$13},~{$14},~{$15},~{$16},~{$17},~{$18},~{$19},~{$20},~{$21},~{$22},~{$23},~{$24},~{$25},~{$26},~{$27},~{$28},~{$29},~{$30},~{$31},~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f12},~{$f13},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31},~{memory}" + constraints = "={$4},{$5},~{$1},~{$2},~{$3},~{$5},~{$6},~{$7},~{$8},~{$9},~{$10},~{$11},~{$12},~{$13},~{$14},~{$15},~{$16},~{$17},~{$18},~{$19},~{$20},~{$21},~{$22},~{$23},~{$24},~{$25},~{$26},~{$27},~{$28},~{$29},~{$30},~{$31},~{memory}" + if !strings.Contains(b.Features, "+soft-float") { + // Using floating point registers together with GOMIPS=softfloat + // results in a crash: "This value type is not natively supported!" + // So only add them when using hardfloat. + constraints += ",~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f12},~{$f13},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}" + } case "riscv32": asmString = ` la a2, 1f From 1ef1aa78628070f618b732bb68136049511ede4c Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 22 Aug 2024 15:16:15 +0200 Subject: [PATCH 03/24] mips: fix big-endian (GOARCH=mips) support I made an awkward mistake, mixing up GOOS and GOARCH. So here is a fix, with an associated test. --- compileopts/target.go | 2 +- main_test.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compileopts/target.go b/compileopts/target.go index 501d99f119..26a91086b9 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -338,7 +338,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) { case "mips", "mipsle": spec.CPU = "mips32r2" spec.CFlags = append(spec.CFlags, "-fno-pic") - if options.GOOS == "mips" { + if options.GOARCH == "mips" { llvmarch = "mips" // big endian } else { llvmarch = "mipsel" // little endian diff --git a/main_test.go b/main_test.go index 836a4b1730..40002ee871 100644 --- a/main_test.go +++ b/main_test.go @@ -177,6 +177,14 @@ func TestBuild(t *testing.T) { }) } } + t.Run("MIPS big-endian", func(t *testing.T) { + // Run a single test for GOARCH=mips to see whether it works at all. + // Big-endian MIPS isn't fully supported yet, but simple examples + // should work. + t.Parallel() + options := optionsFromOSARCH("linux/mips/softfloat", sema) + runTest("alias.go", options, t, nil, nil) + }) t.Run("WebAssembly", func(t *testing.T) { t.Parallel() runPlatTests(optionsFromTarget("wasm", sema), tests, t) From d144b116111aa5ab8b14672d0692cacae35ec80c Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 23 Aug 2024 12:44:39 +0200 Subject: [PATCH 04/24] fix: add missing Truncate() function stub to os/file for bare-metal systems Signed-off-by: deadprogram --- src/os/file_other.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/os/file_other.go b/src/os/file_other.go index d359b0fb67..977fcac12d 100644 --- a/src/os/file_other.go +++ b/src/os/file_other.go @@ -135,3 +135,17 @@ func Readlink(name string) (string, error) { func tempDir() string { return "/tmp" } + +// Truncate is unsupported on this system. +func Truncate(filename string, size int64) (err error) { + return ErrUnsupported +} + +// Truncate is unsupported on this system. +func (f *File) Truncate(size int64) (err error) { + if f.handle == nil { + return ErrClosed + } + + return Truncate(f.name, size) +} From 753f4b38b49c32b4b604dc5065653910923dfb3e Mon Sep 17 00:00:00 2001 From: sago35 Date: Wed, 21 Aug 2024 09:03:46 +0900 Subject: [PATCH 05/24] version: update to 0.34.0-dev --- goenv/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goenv/version.go b/goenv/version.go index bd773f20a5..1db5a630af 100644 --- a/goenv/version.go +++ b/goenv/version.go @@ -9,7 +9,7 @@ import ( // Version of TinyGo. // Update this value before release of new version of software. -const version = "0.33.0" +const version = "0.34.0-dev" var ( // This variable is set at build time using -ldflags parameters. From 105fe9b25df656b0683174245c2c1f6ccaf5fd66 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 18 Aug 2024 19:33:04 +0200 Subject: [PATCH 06/24] darwin: replace custom syscall package with Go native syscall package This required a few compiler and runtime tricks to work, but I ran a bunch of tests and it seems fine. (CI will of course do more exhaustive testing). The main benefit here is that we don't need to maintain the darwin version of the syscall package, and reduce extra risks for bugs (because we reuse the well-tested syscall package). For example, Go 1.23 needed a bunch of new constants in the syscall package. That would have been avoided if we had used the native syscall package on MacOS. --- compileopts/target.go | 1 + compiler/compiler.go | 9 +- compiler/syscall.go | 62 ++++ lib/macos-minimal-sdk | 2 +- loader/goroot.go | 2 +- src/internal/abi/funcpc.go | 10 +- src/os/dir_darwin.go | 5 +- src/os/file_darwin.go | 7 + src/os/file_notdarwin.go | 9 + src/os/file_unix.go | 2 +- src/runtime/os_darwin.c | 29 +- src/runtime/os_darwin.go | 102 +++++- src/syscall/env_libc.go | 2 +- src/syscall/errno_other.go | 2 +- src/syscall/mmap_unix_test.go | 2 +- src/syscall/syscall_libc.go | 2 +- src/syscall/syscall_libc_darwin.go | 432 ----------------------- src/syscall/syscall_libc_darwin_amd64.go | 43 --- src/syscall/syscall_libc_darwin_arm64.go | 37 -- 19 files changed, 229 insertions(+), 531 deletions(-) create mode 100644 src/os/file_darwin.go create mode 100644 src/os/file_notdarwin.go delete mode 100644 src/syscall/syscall_libc_darwin.go delete mode 100644 src/syscall/syscall_libc_darwin_amd64.go delete mode 100644 src/syscall/syscall_libc_darwin_arm64.go diff --git a/compileopts/target.go b/compileopts/target.go index 26a91086b9..c394fa8ca8 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -389,6 +389,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) { "-platform_version", "macos", platformVersion, platformVersion, ) spec.ExtraFiles = append(spec.ExtraFiles, + "src/runtime/os_darwin.c", "src/runtime/runtime_unix.c") case "linux": spec.Linker = "ld.lld" diff --git a/compiler/compiler.go b/compiler/compiler.go index 201605d78c..6756fe9693 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1847,7 +1847,9 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) case strings.HasPrefix(name, "(device/riscv.CSR)."): return b.emitCSROperation(instr) case strings.HasPrefix(name, "syscall.Syscall") || strings.HasPrefix(name, "syscall.RawSyscall") || strings.HasPrefix(name, "golang.org/x/sys/unix.Syscall") || strings.HasPrefix(name, "golang.org/x/sys/unix.RawSyscall"): - return b.createSyscall(instr) + if b.GOOS != "darwin" { + return b.createSyscall(instr) + } case strings.HasPrefix(name, "syscall.rawSyscallNoError") || strings.HasPrefix(name, "golang.org/x/sys/unix.RawSyscallNoError"): return b.createRawSyscallNoError(instr) case name == "runtime.supportsRecover": @@ -1865,6 +1867,11 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil case name == "runtime/interrupt.New": return b.createInterruptGlobal(instr) + case name == "internal/abi.FuncPCABI0": + retval := b.createDarwinFuncPCABI0Call(instr) + if !retval.IsNil() { + return retval, nil + } } calleeType, callee = b.getFunction(fn) diff --git a/compiler/syscall.go b/compiler/syscall.go index d878df0270..aa40ad1a55 100644 --- a/compiler/syscall.go +++ b/compiler/syscall.go @@ -5,6 +5,7 @@ package compiler import ( "strconv" + "strings" "golang.org/x/tools/go/ssa" "tinygo.org/x/go-llvm" @@ -329,3 +330,64 @@ func (b *builder) createRawSyscallNoError(call *ssa.CallCommon) (llvm.Value, err retval = b.CreateInsertValue(retval, llvm.ConstInt(b.uintptrType, 0, false), 1, "") return retval, nil } + +// Lower a call to internal/abi.FuncPCABI0 on MacOS. +// This function is called like this: +// +// syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) +// +// So we'll want to return a function pointer (as uintptr) that points to the +// libc function. Specifically, we _don't_ want to point to the trampoline +// function (which is implemented in Go assembly which we can't read), but +// rather to the actually intended function. For this we're going to assume that +// all the functions follow a specific pattern: libc__trampoline. +// +// The return value is the function pointer as an uintptr, or a nil value if +// this isn't possible (and a regular call should be made as fallback). +func (b *builder) createDarwinFuncPCABI0Call(instr *ssa.CallCommon) llvm.Value { + if b.GOOS != "darwin" { + // This has only been tested on MacOS (and only seems to be used there). + return llvm.Value{} + } + + // Check that it uses a function call like syscall.libc_*_trampoline + itf := instr.Args[0].(*ssa.MakeInterface) + calledFn := itf.X.(*ssa.Function) + if pkgName := calledFn.Pkg.Pkg.Path(); pkgName != "syscall" && pkgName != "internal/syscall/unix" { + return llvm.Value{} + } + if !strings.HasPrefix(calledFn.Name(), "libc_") || !strings.HasSuffix(calledFn.Name(), "_trampoline") { + + return llvm.Value{} + } + + // Extract the libc function name. + name := strings.TrimPrefix(strings.TrimSuffix(calledFn.Name(), "_trampoline"), "libc_") + if name == "open" { + // Special case: open() is a variadic function and can't be called like + // a regular function. Therefore, we need to use a wrapper implemented + // in C. + name = "syscall_libc_open" + } + if b.GOARCH == "amd64" { + if name == "fdopendir" || name == "readdir_r" { + // Hack to support amd64, which needs the $INODE64 suffix. + // This is also done in upstream Go: + // https://github.com/golang/go/commit/096ab3c21b88ccc7d411379d09fe6274e3159467 + name += "$INODE64" + } + } + + // Obtain the C function. + // Use a simple function (no parameters or return value) because all we need + // is the address of the function. + llvmFn := b.mod.NamedFunction(name) + if llvmFn.IsNil() { + llvmFnType := llvm.FunctionType(b.ctx.VoidType(), nil, false) + llvmFn = llvm.AddFunction(b.mod, name, llvmFnType) + } + + // Cast the function pointer to a uintptr (because that's what + // abi.FuncPCABI0 returns). + return b.CreatePtrToInt(llvmFn, b.uintptrType, "") +} diff --git a/lib/macos-minimal-sdk b/lib/macos-minimal-sdk index 91ac2eabd8..4e4113e3b1 160000 --- a/lib/macos-minimal-sdk +++ b/lib/macos-minimal-sdk @@ -1 +1 @@ -Subproject commit 91ac2eabd80f10d95cb4255c78999d9d2c45a3be +Subproject commit 4e4113e3b1244b8fdc5e1486577f25e22d63f36e diff --git a/loader/goroot.go b/loader/goroot.go index 09edab3203..c7ac029d3d 100644 --- a/loader/goroot.go +++ b/loader/goroot.go @@ -218,7 +218,7 @@ func listGorootMergeLinks(goroot, tinygoroot string, overrides map[string]bool) // with the TinyGo version. This is the case on some targets. func needsSyscallPackage(buildTags []string) bool { for _, tag := range buildTags { - if tag == "baremetal" || tag == "darwin" || tag == "nintendoswitch" || tag == "tinygo.wasm" { + if tag == "baremetal" || tag == "nintendoswitch" || tag == "tinygo.wasm" { return true } } diff --git a/src/internal/abi/funcpc.go b/src/internal/abi/funcpc.go index a926c392f8..0661ed7178 100644 --- a/src/internal/abi/funcpc.go +++ b/src/internal/abi/funcpc.go @@ -4,11 +4,9 @@ package abi // (in particular internal/syscall/unix on MacOS). They do not currently have an // implementation, in part because TinyGo doesn't use ABI0 or ABIInternal (it // uses a C-like calling convention). +// Calls to FuncPCABI0 however are treated specially by the compiler when +// compiling for MacOS. -func FuncPCABI0(f interface{}) uintptr { - panic("unimplemented: internal/abi.FuncPCABI0") -} +func FuncPCABI0(f interface{}) uintptr -func FuncPCABIInternal(f interface{}) uintptr { - panic("unimplemented: internal/abi.FuncPCABIInternal") -} +func FuncPCABIInternal(f interface{}) uintptr diff --git a/src/os/dir_darwin.go b/src/os/dir_darwin.go index 3883a45c6a..645c91f8c1 100644 --- a/src/os/dir_darwin.go +++ b/src/os/dir_darwin.go @@ -135,7 +135,7 @@ func darwinOpenDir(fd syscallFd) (uintptr, string, error) { } var dir uintptr for { - dir, err = syscall.Fdopendir(fd2) + dir, err = fdopendir(fd2) if err != syscall.EINTR { break } @@ -149,6 +149,9 @@ func darwinOpenDir(fd syscallFd) (uintptr, string, error) { // Implemented in syscall/syscall_libc_darwin_*.go. +//go:linkname fdopendir syscall.fdopendir +func fdopendir(fd int) (dir uintptr, err error) + //go:linkname closedir syscall.closedir func closedir(dir uintptr) (err error) diff --git a/src/os/file_darwin.go b/src/os/file_darwin.go new file mode 100644 index 0000000000..8d96b7296e --- /dev/null +++ b/src/os/file_darwin.go @@ -0,0 +1,7 @@ +package os + +import "syscall" + +func pipe(p []int) error { + return syscall.Pipe(p) +} diff --git a/src/os/file_notdarwin.go b/src/os/file_notdarwin.go new file mode 100644 index 0000000000..d59a8eb6c1 --- /dev/null +++ b/src/os/file_notdarwin.go @@ -0,0 +1,9 @@ +//go:build (linux && !baremetal && !wasm_unknown) || wasip1 || wasip2 + +package os + +import "syscall" + +func pipe(p []int) error { + return syscall.Pipe2(p, syscall.O_CLOEXEC) +} diff --git a/src/os/file_unix.go b/src/os/file_unix.go index d8d086e8dc..efbd8ef672 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -70,7 +70,7 @@ func Truncate(name string, size int64) error { func Pipe() (r *File, w *File, err error) { var p [2]int - err = handleSyscallError(syscall.Pipe2(p[:], syscall.O_CLOEXEC)) + err = handleSyscallError(pipe(p[:])) if err != nil { return } diff --git a/src/runtime/os_darwin.c b/src/runtime/os_darwin.c index d5f6c807a7..5d7cd7c71d 100644 --- a/src/runtime/os_darwin.c +++ b/src/runtime/os_darwin.c @@ -1,7 +1,32 @@ -// Wrapper function because 'open' is a variadic function and variadic functions -// use a different (incompatible) calling convention on darwin/arm64. +//go:build none + +// This file is included in the build, despite the //go:build line above. #include + +// Wrapper function because 'open' is a variadic function and variadic functions +// use a different (incompatible) calling convention on darwin/arm64. +// This function is referenced from the compiler, when it sees a +// syscall.libc_open_trampoline function. int syscall_libc_open(const char *pathname, int flags, mode_t mode) { return open(pathname, flags, mode); } + +// The following functions are called by the runtime because Go can't call +// function pointers directly. + +int tinygo_syscall(int (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3), uintptr_t a1, uintptr_t a2, uintptr_t a3) { + return fn(a1, a2, a3); +} + +uintptr_t tinygo_syscallX(uintptr_t (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3), uintptr_t a1, uintptr_t a2, uintptr_t a3) { + return fn(a1, a2, a3); +} + +int tinygo_syscall6(int (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6), uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6) { + return fn(a1, a2, a3, a4, a5, a6); +} + +uintptr_t tinygo_syscall6X(uintptr_t (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6), uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6) { + return fn(a1, a2, a3, a4, a5, a6); +} diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 9255fb90f2..8338d0f18b 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -4,8 +4,6 @@ package runtime import "unsafe" -import "C" // dummy import so that os_darwin.c works - const GOOS = "darwin" const ( @@ -127,7 +125,107 @@ func hardwareRand() (n uint64, ok bool) { return n, true } +//go:linkname syscall_Getpagesize syscall.Getpagesize +func syscall_Getpagesize() int { + return int(libc_getpagesize()) +} + +// Call "system calls" (actually: libc functions) in a special way. +// - Most calls calls return a C int (which is 32-bits), and -1 on failure. +// - syscallX* is for functions that return a 64-bit integer (and also return +// -1 on failure). +// - syscallPtr is for functions that return a pointer on success or NULL on +// failure. +// - rawSyscall seems to avoid some stack modifications, which isn't relevant +// to TinyGo. + +//go:linkname syscall_syscall syscall.syscall +func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + // For TinyGo we don't need to do anything special to call C functions. + return syscall_rawSyscall(fn, a1, a2, a3) +} + +//go:linkname syscall_rawSyscall syscall.rawSyscall +func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + result := call_syscall(fn, a1, a2, a3) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscallX syscall.syscallX +func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + r1 = call_syscallX(fn, a1, a2, a3) + if int64(r1) == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscallPtr syscall.syscallPtr +func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + r1 = call_syscallX(fn, a1, a2, a3) + if r1 == 0 { + // Syscall returns a pointer on success, or NULL on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscall6 syscall.syscall6 +func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + result := call_syscall6(fn, a1, a2, a3, a4, a5, a6) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscall6X syscall.syscall6X +func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + r1 = call_syscall6X(fn, a1, a2, a3, a4, a5, a6) + if int64(r1) == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + // uint32_t arc4random(void); // //export arc4random func libc_arc4random() uint32 + +// int getpagesize(void); +// +//export getpagesize +func libc_getpagesize() int32 + +// This function returns the error location in the darwin ABI. +// Discovered by compiling the following code using Clang: +// +// #include +// int getErrno() { +// return errno; +// } +// +//export __error +func libc___error() *int32 + +//export tinygo_syscall +func call_syscall(fn, a1, a2, a3 uintptr) int32 + +//export tinygo_syscallX +func call_syscallX(fn, a1, a2, a3 uintptr) uintptr + +//export tinygo_syscall6 +func call_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) int32 + +//export tinygo_syscall6X +func call_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) uintptr diff --git a/src/syscall/env_libc.go b/src/syscall/env_libc.go index f558901cf4..4ad078dc54 100644 --- a/src/syscall/env_libc.go +++ b/src/syscall/env_libc.go @@ -1,4 +1,4 @@ -//go:build darwin || nintendoswitch || wasip1 +//go:build nintendoswitch || wasip1 package syscall diff --git a/src/syscall/errno_other.go b/src/syscall/errno_other.go index b988fbc1e0..3a06ac018f 100644 --- a/src/syscall/errno_other.go +++ b/src/syscall/errno_other.go @@ -1,4 +1,4 @@ -//go:build !wasip1 && !wasip2 && !darwin +//go:build !wasip1 && !wasip2 package syscall diff --git a/src/syscall/mmap_unix_test.go b/src/syscall/mmap_unix_test.go index 1946265d8c..62748a9395 100644 --- a/src/syscall/mmap_unix_test.go +++ b/src/syscall/mmap_unix_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build darwin || linux +//go:build linux package syscall_test diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index 2321292d98..67cf6681f7 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -1,4 +1,4 @@ -//go:build darwin || nintendoswitch || wasip1 || wasip2 +//go:build nintendoswitch || wasip1 || wasip2 package syscall diff --git a/src/syscall/syscall_libc_darwin.go b/src/syscall/syscall_libc_darwin.go deleted file mode 100644 index 3b0341880a..0000000000 --- a/src/syscall/syscall_libc_darwin.go +++ /dev/null @@ -1,432 +0,0 @@ -//go:build darwin - -package syscall - -import ( - "internal/itoa" - "unsafe" -) - -// This file defines errno and constants to match the darwin libsystem ABI. -// Values have been copied from src/syscall/zerrors_darwin_amd64.go. - -// This function returns the error location in the darwin ABI. -// Discovered by compiling the following code using Clang: -// -// #include -// int getErrno() { -// return errno; -// } -// -//export __error -func libc___error() *int32 - -// getErrno returns the current C errno. It may not have been caused by the last -// call, so it should only be relied upon when the last call indicates an error -// (for example, by returning -1). -func getErrno() Errno { - errptr := libc___error() - return Errno(uintptr(*errptr)) -} - -func (e Errno) Is(target error) bool { - switch target.Error() { - case "permission denied": - return e == EACCES || e == EPERM - case "file already exists": - return e == EEXIST - case "file does not exist": - return e == ENOENT - } - return false -} - -// Source: upstream zerrors_darwin_amd64.go -const ( - DT_BLK = 0x6 - DT_CHR = 0x2 - DT_DIR = 0x4 - DT_FIFO = 0x1 - DT_LNK = 0xa - DT_REG = 0x8 - DT_SOCK = 0xc - DT_UNKNOWN = 0x0 - DT_WHT = 0xe - F_GETFL = 0x3 - F_SETFL = 0x4 - O_NONBLOCK = 0x4 - TIOCSPGRP = 0x80047476 -) - -// Source: https://opensource.apple.com/source/xnu/xnu-7195.141.2/bsd/sys/errno.h.auto.html -const ( - EPERM Errno = 1 - ENOENT Errno = 2 - ESRCH Errno = 3 - EINTR Errno = 4 - EIO Errno = 5 - ENXIO Errno = 6 - E2BIG Errno = 7 - ENOEXEC Errno = 8 - EBADF Errno = 9 - ECHILD Errno = 10 - EDEADLK Errno = 11 - ENOMEM Errno = 12 - EACCES Errno = 13 - EFAULT Errno = 14 - ENOTBLK Errno = 15 - EBUSY Errno = 16 - EEXIST Errno = 17 - EXDEV Errno = 18 - ENODEV Errno = 19 - ENOTDIR Errno = 20 - EISDIR Errno = 21 - EINVAL Errno = 22 - ENFILE Errno = 23 - EMFILE Errno = 24 - ENOTTY Errno = 25 - ETXTBSY Errno = 26 - EFBIG Errno = 27 - ENOSPC Errno = 28 - ESPIPE Errno = 29 - EROFS Errno = 30 - EMLINK Errno = 31 - EPIPE Errno = 32 - EDOM Errno = 33 - ERANGE Errno = 34 - EAGAIN Errno = 35 - EWOULDBLOCK Errno = EAGAIN - EINPROGRESS Errno = 36 - EALREADY Errno = 37 - ENOTSOCK Errno = 38 - EDESTADDRREQ Errno = 39 - EMSGSIZE Errno = 40 - EPROTOTYPE Errno = 41 - ENOPROTOOPT Errno = 42 - EPROTONOSUPPORT Errno = 43 - ESOCKTNOSUPPORT Errno = 44 - ENOTSUP Errno = 45 - EPFNOSUPPORT Errno = 46 - EAFNOSUPPORT Errno = 47 - EADDRINUSE Errno = 48 - EADDRNOTAVAIL Errno = 49 - ENETDOWN Errno = 50 - ENETUNREACH Errno = 51 - ENETRESET Errno = 52 - ECONNABORTED Errno = 53 - ECONNRESET Errno = 54 - ENOBUFS Errno = 55 - EISCONN Errno = 56 - ENOTCONN Errno = 57 - ESHUTDOWN Errno = 58 - ETOOMANYREFS Errno = 59 - ETIMEDOUT Errno = 60 - ECONNREFUSED Errno = 61 - ELOOP Errno = 62 - ENAMETOOLONG Errno = 63 - EHOSTDOWN Errno = 64 - EHOSTUNREACH Errno = 65 - ENOTEMPTY Errno = 66 - EPROCLIM Errno = 67 - EUSERS Errno = 68 - EDQUOT Errno = 69 - ESTALE Errno = 70 - EREMOTE Errno = 71 - EBADRPC Errno = 72 - ERPCMISMATCH Errno = 73 - EPROGUNAVAIL Errno = 74 - EPROGMISMATCH Errno = 75 - EPROCUNAVAIL Errno = 76 - ENOLCK Errno = 77 - ENOSYS Errno = 78 - EFTYPE Errno = 79 - EAUTH Errno = 80 - ENEEDAUTH Errno = 81 - EPWROFF Errno = 82 - EDEVERR Errno = 83 - EOVERFLOW Errno = 84 - EBADEXEC Errno = 85 - EBADARCH Errno = 86 - ESHLIBVERS Errno = 87 - EBADMACHO Errno = 88 - ECANCELED Errno = 89 - EIDRM Errno = 90 - ENOMSG Errno = 91 - EILSEQ Errno = 92 - ENOATTR Errno = 93 - EBADMSG Errno = 94 - EMULTIHOP Errno = 95 - ENODATA Errno = 96 - ENOLINK Errno = 97 - ENOSR Errno = 98 - ENOSTR Errno = 99 - EPROTO Errno = 100 - ETIME Errno = 101 - EOPNOTSUPP Errno = 102 - ENOPOLICY Errno = 103 - ENOTRECOVERABLE Errno = 104 - EOWNERDEAD Errno = 105 - EQFULL Errno = 106 - ELAST Errno = 106 -) - -type Signal int - -// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/signal.h -const ( - SIGINT Signal = 2 /* interrupt */ - SIGQUIT Signal = 3 /* quit */ - SIGILL Signal = 4 /* illegal instruction (not reset when caught) */ - SIGTRAP Signal = 5 /* trace trap (not reset when caught) */ - SIGABRT Signal = 6 /* abort() */ - SIGFPE Signal = 8 /* floating point exception */ - SIGKILL Signal = 9 /* kill (cannot be caught or ignored) */ - SIGBUS Signal = 10 /* bus error */ - SIGSEGV Signal = 11 /* segmentation violation */ - SIGPIPE Signal = 13 /* write on a pipe with no one to read it */ - SIGTERM Signal = 15 /* software termination signal from kill */ - SIGCHLD Signal = 20 /* to parent on child stop or exit */ -) - -func (s Signal) Signal() {} - -func (s Signal) String() string { - if 0 <= s && int(s) < len(signals) { - str := signals[s] - if str != "" { - return str - } - } - return "signal " + itoa.Itoa(int(s)) -} - -var signals = [...]string{} - -const ( - Stdin = 0 - Stdout = 1 - Stderr = 2 -) - -const ( - O_RDONLY = 0x0 - O_WRONLY = 0x1 - O_RDWR = 0x2 - O_APPEND = 0x8 - O_SYNC = 0x80 - O_CREAT = 0x200 - O_TRUNC = 0x400 - O_EXCL = 0x800 - - O_CLOEXEC = 0x01000000 -) - -// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/mman.h.auto.html -const ( - PROT_NONE = 0x00 // no permissions - PROT_READ = 0x01 // pages can be read - PROT_WRITE = 0x02 // pages can be written - PROT_EXEC = 0x04 // pages can be executed - - MAP_SHARED = 0x0001 // share changes - MAP_PRIVATE = 0x0002 // changes are private - - MAP_FILE = 0x0000 // map from file (default) - MAP_ANON = 0x1000 // allocated from memory, swap space - MAP_ANONYMOUS = MAP_ANON -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -// Unix returns the time stored in ts as seconds plus nanoseconds. -func (ts *Timespec) Unix() (sec int64, nsec int64) { - return int64(ts.Sec), int64(ts.Nsec) -} - -// Source: upstream ztypes_darwin_amd64.go -type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte -} - -type Stat_t struct { - Dev int32 - Mode uint16 - Nlink uint16 - Ino uint64 - Uid uint32 - Gid uint32 - Rdev int32 - Pad_cgo_0 [4]byte - Atimespec Timespec - Mtimespec Timespec - Ctimespec Timespec - Btimespec Timespec - Size int64 - Blocks int64 - Blksize int32 - Flags uint32 - Gen uint32 - Lspare int32 - Qspare [2]int64 -} - -// Source: https://github.com/apple/darwin-xnu/blob/main/bsd/sys/_types/_s_ifmt.h -const ( - S_IEXEC = 0x40 - S_IFBLK = 0x6000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFIFO = 0x1000 - S_IFLNK = 0xa000 - S_IFMT = 0xf000 - S_IFREG = 0x8000 - S_IFSOCK = 0xc000 - S_IFWHT = 0xe000 - S_IREAD = 0x100 - S_IRGRP = 0x20 - S_IROTH = 0x4 - S_IRUSR = 0x100 - S_IRWXG = 0x38 - S_IRWXO = 0x7 - S_IRWXU = 0x1c0 - S_ISGID = 0x400 - S_ISTXT = 0x200 - S_ISUID = 0x800 - S_ISVTX = 0x200 - S_IWGRP = 0x10 - S_IWOTH = 0x2 - S_IWRITE = 0x80 - S_IWUSR = 0x80 - S_IXGRP = 0x8 - S_IXOTH = 0x1 - S_IXUSR = 0x40 -) - -func Stat(path string, p *Stat_t) (err error) { - data := cstring(path) - n := libc_stat(&data[0], unsafe.Pointer(p)) - - if n < 0 { - err = getErrno() - } - return -} - -func Fstat(fd int, p *Stat_t) (err error) { - n := libc_fstat(int32(fd), unsafe.Pointer(p)) - - if n < 0 { - err = getErrno() - } - return -} - -func Lstat(path string, p *Stat_t) (err error) { - data := cstring(path) - n := libc_lstat(&data[0], unsafe.Pointer(p)) - if n < 0 { - err = getErrno() - } - return -} - -func Fdopendir(fd int) (dir uintptr, err error) { - r0 := libc_fdopendir(int32(fd)) - dir = uintptr(r0) - if dir == 0 { - err = getErrno() - } - return -} - -func Pipe2(fds []int, flags int) (err error) { - // Mac only has Pipe, which ignores the flags argument - buf := make([]int32, 2) - fail := int(libc_pipe(&buf[0])) - if fail < 0 { - err = getErrno() - } else { - fds[0] = int(buf[0]) - fds[1] = int(buf[1]) - } - return -} - -func Chmod(path string, mode uint32) (err error) { - data := cstring(path) - fail := int(libc_chmod(&data[0], mode)) - if fail < 0 { - err = getErrno() - } - return -} - -func closedir(dir uintptr) (err error) { - e := libc_closedir(unsafe.Pointer(dir)) - if e != 0 { - err = getErrno() - } - return -} - -func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) { - e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result)) - if e1 != 0 { - err = getErrno() - } - return -} - -func Getpagesize() int { - return int(libc_getpagesize()) -} - -// The following RawSockAddr* types have been copied from the Go source tree and -// are here purely to fix build errors. - -type RawSockaddr struct { - Len uint8 - Family uint8 - Data [14]int8 -} - -type RawSockaddrInet4 struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]int8 -} - -type RawSockaddrInet6 struct { - Len uint8 - Family uint8 - Port uint16 - Flowinfo uint32 - Addr [16]byte /* in6_addr */ - Scope_id uint32 -} - -// int pipe(int32 *fds); -// -//export pipe -func libc_pipe(fds *int32) int32 - -// int getpagesize(); -// -//export getpagesize -func libc_getpagesize() int32 - -// int open(const char *pathname, int flags, mode_t mode); -// -//export syscall_libc_open -func libc_open(pathname *byte, flags int32, mode uint32) int32 diff --git a/src/syscall/syscall_libc_darwin_amd64.go b/src/syscall/syscall_libc_darwin_amd64.go deleted file mode 100644 index 1f5528ec54..0000000000 --- a/src/syscall/syscall_libc_darwin_amd64.go +++ /dev/null @@ -1,43 +0,0 @@ -//go:build darwin - -package syscall - -import ( - "unsafe" -) - -// The odd $INODE64 suffix is an Apple compatibility feature, see -// __DARWIN_INODE64 in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h -// and https://assert.cc/posts/darwin_use_64_bit_inode_vs_ctypes/ -// Without it, you get the old, smaller struct stat from mac os 10.2 or so. -// It not needed on arm64. - -// struct DIR * buf fdopendir(int fd); -// -//export fdopendir$INODE64 -func libc_fdopendir(fd int32) unsafe.Pointer - -// int closedir(struct DIR * buf); -// -//export closedir -func libc_closedir(unsafe.Pointer) int32 - -// int readdir_r(struct DIR * buf, struct dirent *entry, struct dirent **result); -// -//export readdir_r$INODE64 -func libc_readdir_r(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) int32 - -// int stat(const char *path, struct stat * buf); -// -//export stat$INODE64 -func libc_stat(pathname *byte, ptr unsafe.Pointer) int32 - -// int fstat(int fd, struct stat * buf); -// -//export fstat$INODE64 -func libc_fstat(fd int32, ptr unsafe.Pointer) int32 - -// int lstat(const char *path, struct stat * buf); -// -//export lstat$INODE64 -func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32 diff --git a/src/syscall/syscall_libc_darwin_arm64.go b/src/syscall/syscall_libc_darwin_arm64.go deleted file mode 100644 index f9ce3c4e39..0000000000 --- a/src/syscall/syscall_libc_darwin_arm64.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build darwin - -package syscall - -import ( - "unsafe" -) - -// struct DIR * buf fdopendir(int fd); -// -//export fdopendir -func libc_fdopendir(fd int32) unsafe.Pointer - -// int closedir(struct DIR * buf); -// -//export closedir -func libc_closedir(unsafe.Pointer) int32 - -// int readdir_r(struct DIR * buf, struct dirent *entry, struct dirent **result); -// -//export readdir_r -func libc_readdir_r(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) int32 - -// int stat(const char *path, struct stat * buf); -// -//export stat -func libc_stat(pathname *byte, ptr unsafe.Pointer) int32 - -// int fstat(int fd, struct stat * buf); -// -//export fstat -func libc_fstat(fd int32, ptr unsafe.Pointer) int32 - -// int lstat(const char *path, struct stat * buf); -// -//export lstat -func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32 From e39358d0ee9d08fad1a838ecb4ea9322d4f9bbfa Mon Sep 17 00:00:00 2001 From: Roger Standridge <9526806+archie2x@users.noreply.github.com> Date: Wed, 21 Aug 2024 08:32:23 -0700 Subject: [PATCH 07/24] stub runtime_{Before,After}Exec for linkage --- src/runtime/proc.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/runtime/proc.go diff --git a/src/runtime/proc.go b/src/runtime/proc.go new file mode 100644 index 0000000000..e029ffe95f --- /dev/null +++ b/src/runtime/proc.go @@ -0,0 +1,19 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +// Called from syscall package before Exec. +// +//go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec +func syscall_runtime_BeforeExec() { + // Used in BigGo to serialize exec / thread creation. Stubbing to + // satisfy link. +} + +// Called from syscall package after Exec. +// +//go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec +func syscall_runtime_AfterExec() { +} From 25abfff63204f72140ab1b29120ab9b674d5cf41 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 22 Aug 2024 15:53:22 +0200 Subject: [PATCH 08/24] mips: use MIPS32 (instead of MIPS32R2) as the instruction set This should widen compatibility a bit, so that older CPUs can also execute programs built by TinyGo. The performance may be lower, if that's an issue we can look into implementing the proposal here: https://github.com/golang/go/issues/60072 This still wouldn't make programs usable on MIPS II CPUs, I suppose we can lower compatiblity down to that CPU if needed. I tried setting the -cpu flag in the QEMU command line to be able to test this, but it looks like there are no QEMU CPU models that are mips32r1 and have a FPU. So it's difficult to test this. --- compileopts/target.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compileopts/target.go b/compileopts/target.go index c394fa8ca8..41a7babd91 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -336,7 +336,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) { spec.Features = "+fp-armv8,+neon,-fmv,-outline-atomics" } case "mips", "mipsle": - spec.CPU = "mips32r2" + spec.CPU = "mips32" spec.CFlags = append(spec.CFlags, "-fno-pic") if options.GOARCH == "mips" { llvmarch = "mips" // big endian @@ -345,10 +345,10 @@ func defaultTarget(options *Options) (*TargetSpec, error) { } switch options.GOMIPS { case "hardfloat": - spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls" + spec.Features = "+fpxx,+mips32,+nooddspreg,-noabicalls" case "softfloat": spec.SoftFloat = true - spec.Features = "+mips32r2,+soft-float,-noabicalls" + spec.Features = "+mips32,+soft-float,-noabicalls" spec.CFlags = append(spec.CFlags, "-msoft-float") default: return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS) From 73f519b589bf45d8b9a121063bd264357f632c06 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 22 Aug 2024 16:42:03 +0200 Subject: [PATCH 09/24] interp: support big-endian targets The interp package was assuming that all targets were little-endian. But that's not true: we now have a big-endian target (GOARCH=mips). This fixes the interp package to use the appropriate byte order for a given target. --- compiler/llvmutil/llvm.go | 11 +++++ interp/interp.go | 4 ++ interp/interpreter.go | 98 +++++++++++++++++++-------------------- interp/memory.go | 76 ++++++++++++++++-------------- main_test.go | 6 ++- 5 files changed, 110 insertions(+), 85 deletions(-) diff --git a/compiler/llvmutil/llvm.go b/compiler/llvmutil/llvm.go index 607e91e8d8..061bee6c9a 100644 --- a/compiler/llvmutil/llvm.go +++ b/compiler/llvmutil/llvm.go @@ -8,6 +8,7 @@ package llvmutil import ( + "encoding/binary" "strconv" "strings" @@ -216,3 +217,13 @@ func Version() int { } return major } + +// Return the byte order for the given target triple. Most targets are little +// endian, but for example MIPS can be big-endian. +func ByteOrder(target string) binary.ByteOrder { + if strings.HasPrefix(target, "mips-") { + return binary.BigEndian + } else { + return binary.LittleEndian + } +} diff --git a/interp/interp.go b/interp/interp.go index 80afc39c74..30b0872485 100644 --- a/interp/interp.go +++ b/interp/interp.go @@ -3,11 +3,13 @@ package interp import ( + "encoding/binary" "fmt" "os" "strings" "time" + "github.com/tinygo-org/tinygo/compiler/llvmutil" "tinygo.org/x/go-llvm" ) @@ -24,6 +26,7 @@ type runner struct { dataPtrType llvm.Type // often used type so created in advance uintptrType llvm.Type // equivalent to uintptr in Go maxAlign int // maximum alignment of an object, alignment of runtime.alloc() result + byteOrder binary.ByteOrder // big-endian or little-endian debug bool // log debug messages pkgName string // package name of the currently executing package functionCache map[llvm.Value]*function // cache of compiled functions @@ -38,6 +41,7 @@ func newRunner(mod llvm.Module, timeout time.Duration, debug bool) *runner { r := runner{ mod: mod, targetData: llvm.NewTargetData(mod.DataLayout()), + byteOrder: llvmutil.ByteOrder(mod.Target()), debug: debug, functionCache: make(map[llvm.Value]*function), objects: []object{{}}, diff --git a/interp/interpreter.go b/interp/interpreter.go index b35129b814..512d93eb74 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -173,7 +173,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent case 3: // Conditional branch: [cond, thenBB, elseBB] lastBB = currentBB - switch operands[0].Uint() { + switch operands[0].Uint(r) { case 1: // true -> thenBB currentBB = int(operands[1].(literalValue).value.(uint32)) case 0: // false -> elseBB @@ -191,12 +191,12 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent } case llvm.Switch: // Switch statement: [value, defaultLabel, case0, label0, case1, label1, ...] - value := operands[0].Uint() - targetLabel := operands[1].Uint() // default label + value := operands[0].Uint(r) + targetLabel := operands[1].Uint(r) // default label // Do a lazy switch by iterating over all cases. for i := 2; i < len(operands); i += 2 { - if value == operands[i].Uint() { - targetLabel = operands[i+1].Uint() + if value == operands[i].Uint(r) { + targetLabel = operands[i+1].Uint(r) break } } @@ -211,7 +211,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent // Select is much like a ternary operator: it picks a result from // the second and third operand based on the boolean first operand. var result value - switch operands[0].Uint() { + switch operands[0].Uint(r) { case 1: result = operands[1] case 0: @@ -282,7 +282,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent // by creating a global variable. // Get the requested memory size to be allocated. - size := operands[1].Uint() + size := operands[1].Uint(r) // Get the object layout, if it is available. llvmLayoutType := r.getLLVMTypeFromLayout(operands[2]) @@ -318,9 +318,9 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent // memmove(dst, src, n*elemSize) // return int(n) // } - dstLen := operands[3].Uint() - srcLen := operands[4].Uint() - elemSize := operands[5].Uint() + dstLen := operands[3].Uint(r) + srcLen := operands[4].Uint(r) + elemSize := operands[5].Uint(r) n := srcLen if n > dstLen { n = dstLen @@ -374,7 +374,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent if err != nil { return nil, mem, r.errorAt(inst, err) } - nBytes := uint32(operands[3].Uint()) + nBytes := uint32(operands[3].Uint(r)) dstObj := mem.getWritable(dst.index()) dstBuf := dstObj.buffer.asRawValue(r) if mem.get(src.index()).buffer == nil { @@ -661,8 +661,8 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent // pointer into the underlying object. var offset int64 for i := 1; i < len(operands); i += 2 { - index := operands[i].Int() - elementSize := operands[i+1].Int() + index := operands[i].Int(r) + elementSize := operands[i+1].Int(r) if elementSize < 0 { // This is a struct field. offset += index @@ -677,7 +677,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent return nil, mem, r.errorAt(inst, err) } // GEP on fixed pointer value (for example, memory-mapped I/O). - ptrValue := operands[0].Uint() + uint64(offset) + ptrValue := operands[0].Uint(r) + uint64(offset) locals[inst.localIndex] = makeLiteralInt(ptrValue, int(operands[0].len(r)*8)) continue } @@ -739,11 +739,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent var lhs, rhs float64 switch operands[0].len(r) { case 8: - lhs = math.Float64frombits(operands[0].Uint()) - rhs = math.Float64frombits(operands[1].Uint()) + lhs = math.Float64frombits(operands[0].Uint(r)) + rhs = math.Float64frombits(operands[1].Uint(r)) case 4: - lhs = float64(math.Float32frombits(uint32(operands[0].Uint()))) - rhs = float64(math.Float32frombits(uint32(operands[1].Uint()))) + lhs = float64(math.Float32frombits(uint32(operands[0].Uint(r)))) + rhs = float64(math.Float32frombits(uint32(operands[1].Uint(r)))) default: panic("unknown float type") } @@ -782,23 +782,23 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent if inst.opcode == llvm.Add { // This likely means this is part of a // unsafe.Pointer(uintptr(ptr) + offset) pattern. - lhsPtr, err = lhsPtr.addOffset(int64(rhs.Uint())) + lhsPtr, err = lhsPtr.addOffset(int64(rhs.Uint(r))) if err != nil { return nil, mem, r.errorAt(inst, err) } locals[inst.localIndex] = lhsPtr - } else if inst.opcode == llvm.Xor && rhs.Uint() == 0 { + } else if inst.opcode == llvm.Xor && rhs.Uint(r) == 0 { // Special workaround for strings.noescape, see // src/strings/builder.go in the Go source tree. This is // the identity operator, so we can return the input. locals[inst.localIndex] = lhs - } else if inst.opcode == llvm.And && rhs.Uint() < 8 { + } else if inst.opcode == llvm.And && rhs.Uint(r) < 8 { // This is probably part of a pattern to get the lower bits // of a pointer for pointer tagging, like this: // uintptr(unsafe.Pointer(t)) & 0b11 // We can actually support this easily by ANDing with the // pointer offset. - result := uint64(lhsPtr.offset()) & rhs.Uint() + result := uint64(lhsPtr.offset()) & rhs.Uint(r) locals[inst.localIndex] = makeLiteralInt(result, int(lhs.len(r)*8)) } else { // Catch-all for weird operations that should just be done @@ -813,31 +813,31 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent var result uint64 switch inst.opcode { case llvm.Add: - result = lhs.Uint() + rhs.Uint() + result = lhs.Uint(r) + rhs.Uint(r) case llvm.Sub: - result = lhs.Uint() - rhs.Uint() + result = lhs.Uint(r) - rhs.Uint(r) case llvm.Mul: - result = lhs.Uint() * rhs.Uint() + result = lhs.Uint(r) * rhs.Uint(r) case llvm.UDiv: - result = lhs.Uint() / rhs.Uint() + result = lhs.Uint(r) / rhs.Uint(r) case llvm.SDiv: - result = uint64(lhs.Int() / rhs.Int()) + result = uint64(lhs.Int(r) / rhs.Int(r)) case llvm.URem: - result = lhs.Uint() % rhs.Uint() + result = lhs.Uint(r) % rhs.Uint(r) case llvm.SRem: - result = uint64(lhs.Int() % rhs.Int()) + result = uint64(lhs.Int(r) % rhs.Int(r)) case llvm.Shl: - result = lhs.Uint() << rhs.Uint() + result = lhs.Uint(r) << rhs.Uint(r) case llvm.LShr: - result = lhs.Uint() >> rhs.Uint() + result = lhs.Uint(r) >> rhs.Uint(r) case llvm.AShr: - result = uint64(lhs.Int() >> rhs.Uint()) + result = uint64(lhs.Int(r) >> rhs.Uint(r)) case llvm.And: - result = lhs.Uint() & rhs.Uint() + result = lhs.Uint(r) & rhs.Uint(r) case llvm.Or: - result = lhs.Uint() | rhs.Uint() + result = lhs.Uint(r) | rhs.Uint(r) case llvm.Xor: - result = lhs.Uint() ^ rhs.Uint() + result = lhs.Uint(r) ^ rhs.Uint(r) default: panic("unreachable") } @@ -855,11 +855,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent // and then truncating it as necessary. var value uint64 if inst.opcode == llvm.SExt { - value = uint64(operands[0].Int()) + value = uint64(operands[0].Int(r)) } else { - value = operands[0].Uint() + value = operands[0].Uint(r) } - bitwidth := operands[1].Uint() + bitwidth := operands[1].Uint(r) if r.debug { fmt.Fprintln(os.Stderr, indent+instructionNameMap[inst.opcode]+":", value, bitwidth) } @@ -868,11 +868,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent var value float64 switch inst.opcode { case llvm.SIToFP: - value = float64(operands[0].Int()) + value = float64(operands[0].Int(r)) case llvm.UIToFP: - value = float64(operands[0].Uint()) + value = float64(operands[0].Uint(r)) } - bitwidth := operands[1].Uint() + bitwidth := operands[1].Uint(r) if r.debug { fmt.Fprintln(os.Stderr, indent+instructionNameMap[inst.opcode]+":", value, bitwidth) } @@ -918,21 +918,21 @@ func (r *runner) interpretICmp(lhs, rhs value, predicate llvm.IntPredicate) bool } return result case llvm.IntUGT: - return lhs.Uint() > rhs.Uint() + return lhs.Uint(r) > rhs.Uint(r) case llvm.IntUGE: - return lhs.Uint() >= rhs.Uint() + return lhs.Uint(r) >= rhs.Uint(r) case llvm.IntULT: - return lhs.Uint() < rhs.Uint() + return lhs.Uint(r) < rhs.Uint(r) case llvm.IntULE: - return lhs.Uint() <= rhs.Uint() + return lhs.Uint(r) <= rhs.Uint(r) case llvm.IntSGT: - return lhs.Int() > rhs.Int() + return lhs.Int(r) > rhs.Int(r) case llvm.IntSGE: - return lhs.Int() >= rhs.Int() + return lhs.Int(r) >= rhs.Int(r) case llvm.IntSLT: - return lhs.Int() < rhs.Int() + return lhs.Int(r) < rhs.Int(r) case llvm.IntSLE: - return lhs.Int() <= rhs.Int() + return lhs.Int(r) <= rhs.Int(r) default: // _should_ be unreachable, until LLVM adds new icmp operands (unlikely) panic("interp: unsupported icmp") diff --git a/interp/memory.go b/interp/memory.go index 759a1ffe48..176228fdc1 100644 --- a/interp/memory.go +++ b/interp/memory.go @@ -361,8 +361,8 @@ type value interface { clone() value asPointer(*runner) (pointerValue, error) asRawValue(*runner) rawValue - Uint() uint64 - Int() int64 + Uint(*runner) uint64 + Int(*runner) int64 toLLVMValue(llvm.Type, *memoryView) (llvm.Value, error) String() string } @@ -405,7 +405,8 @@ func (v literalValue) len(r *runner) uint32 { } func (v literalValue) String() string { - return strconv.FormatInt(v.Int(), 10) + // Note: passing a nil *runner to v.Int because we know it won't use it. + return strconv.FormatInt(v.Int(nil), 10) } func (v literalValue) clone() value { @@ -421,13 +422,13 @@ func (v literalValue) asRawValue(r *runner) rawValue { switch value := v.value.(type) { case uint64: buf = make([]byte, 8) - binary.LittleEndian.PutUint64(buf, value) + r.byteOrder.PutUint64(buf, value) case uint32: buf = make([]byte, 4) - binary.LittleEndian.PutUint32(buf, uint32(value)) + r.byteOrder.PutUint32(buf, uint32(value)) case uint16: buf = make([]byte, 2) - binary.LittleEndian.PutUint16(buf, uint16(value)) + r.byteOrder.PutUint16(buf, uint16(value)) case uint8: buf = []byte{uint8(value)} default: @@ -440,7 +441,7 @@ func (v literalValue) asRawValue(r *runner) rawValue { return raw } -func (v literalValue) Uint() uint64 { +func (v literalValue) Uint(r *runner) uint64 { switch value := v.value.(type) { case uint64: return value @@ -455,7 +456,7 @@ func (v literalValue) Uint() uint64 { } } -func (v literalValue) Int() int64 { +func (v literalValue) Int(r *runner) int64 { switch value := v.value.(type) { case uint64: return int64(value) @@ -553,11 +554,11 @@ func (v pointerValue) asRawValue(r *runner) rawValue { return rv } -func (v pointerValue) Uint() uint64 { +func (v pointerValue) Uint(r *runner) uint64 { panic("cannot convert pointer to integer") } -func (v pointerValue) Int() int64 { +func (v pointerValue) Int(r *runner) int64 { panic("cannot convert pointer to integer") } @@ -702,7 +703,12 @@ func (v rawValue) String() string { } // Format as number if none of the buf is a pointer. if !v.hasPointer() { - return strconv.FormatInt(v.Int(), 10) + // Construct a fake runner, which is little endian. + // We only use String() for debugging, so this is is good enough + // (the printed value will just be slightly wrong when debugging the + // interp package with GOOS=mips for example). + r := &runner{byteOrder: binary.LittleEndian} + return strconv.FormatInt(v.Int(r), 10) } } return "<[…" + strconv.Itoa(len(v.buf)) + "]>" @@ -738,33 +744,33 @@ func (v rawValue) bytes() []byte { return buf } -func (v rawValue) Uint() uint64 { +func (v rawValue) Uint(r *runner) uint64 { buf := v.bytes() switch len(v.buf) { case 1: return uint64(buf[0]) case 2: - return uint64(binary.LittleEndian.Uint16(buf)) + return uint64(r.byteOrder.Uint16(buf)) case 4: - return uint64(binary.LittleEndian.Uint32(buf)) + return uint64(r.byteOrder.Uint32(buf)) case 8: - return binary.LittleEndian.Uint64(buf) + return r.byteOrder.Uint64(buf) default: panic("unknown integer size") } } -func (v rawValue) Int() int64 { +func (v rawValue) Int(r *runner) int64 { switch len(v.buf) { case 1: - return int64(int8(v.Uint())) + return int64(int8(v.Uint(r))) case 2: - return int64(int16(v.Uint())) + return int64(int16(v.Uint(r))) case 4: - return int64(int32(v.Uint())) + return int64(int32(v.Uint(r))) case 8: - return int64(int64(v.Uint())) + return int64(int64(v.Uint(r))) default: panic("unknown integer size") } @@ -878,11 +884,11 @@ func (v rawValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Value, var n uint64 switch llvmType.IntTypeWidth() { case 64: - n = rawValue{v.buf[:8]}.Uint() + n = rawValue{v.buf[:8]}.Uint(mem.r) case 32: - n = rawValue{v.buf[:4]}.Uint() + n = rawValue{v.buf[:4]}.Uint(mem.r) case 16: - n = rawValue{v.buf[:2]}.Uint() + n = rawValue{v.buf[:2]}.Uint(mem.r) case 8: n = uint64(v.buf[0]) case 1: @@ -951,7 +957,7 @@ func (v rawValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Value, } // This is either a null pointer or a raw pointer for memory-mapped I/O // (such as 0xe000ed00). - ptr := rawValue{v.buf[:mem.r.pointerSize]}.Uint() + ptr := rawValue{v.buf[:mem.r.pointerSize]}.Uint(mem.r) if ptr == 0 { // Null pointer. return llvm.ConstNull(llvmType), nil @@ -969,11 +975,11 @@ func (v rawValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Value, } return llvm.ConstIntToPtr(ptrValue, llvmType), nil case llvm.DoubleTypeKind: - b := rawValue{v.buf[:8]}.Uint() + b := rawValue{v.buf[:8]}.Uint(mem.r) f := math.Float64frombits(b) return llvm.ConstFloat(llvmType, f), nil case llvm.FloatTypeKind: - b := uint32(rawValue{v.buf[:4]}.Uint()) + b := uint32(rawValue{v.buf[:4]}.Uint(mem.r)) f := math.Float32frombits(b) return llvm.ConstFloat(llvmType, float64(f)), nil default: @@ -1065,19 +1071,19 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) { switch llvmValue.Type().IntTypeWidth() { case 64: var buf [8]byte - binary.LittleEndian.PutUint64(buf[:], n) + r.byteOrder.PutUint64(buf[:], n) for i, b := range buf { v.buf[i] = uint64(b) } case 32: var buf [4]byte - binary.LittleEndian.PutUint32(buf[:], uint32(n)) + r.byteOrder.PutUint32(buf[:], uint32(n)) for i, b := range buf { v.buf[i] = uint64(b) } case 16: var buf [2]byte - binary.LittleEndian.PutUint16(buf[:], uint16(n)) + r.byteOrder.PutUint16(buf[:], uint16(n)) for i, b := range buf { v.buf[i] = uint64(b) } @@ -1109,14 +1115,14 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) { case llvm.DoubleTypeKind: f, _ := llvmValue.DoubleValue() var buf [8]byte - binary.LittleEndian.PutUint64(buf[:], math.Float64bits(f)) + r.byteOrder.PutUint64(buf[:], math.Float64bits(f)) for i, b := range buf { v.buf[i] = uint64(b) } case llvm.FloatTypeKind: f, _ := llvmValue.DoubleValue() var buf [4]byte - binary.LittleEndian.PutUint32(buf[:], math.Float32bits(float32(f))) + r.byteOrder.PutUint32(buf[:], math.Float32bits(float32(f))) for i, b := range buf { v.buf[i] = uint64(b) } @@ -1166,11 +1172,11 @@ func (v localValue) asRawValue(r *runner) rawValue { panic("interp: localValue.asRawValue") } -func (v localValue) Uint() uint64 { +func (v localValue) Uint(r *runner) uint64 { panic("interp: localValue.Uint") } -func (v localValue) Int() int64 { +func (v localValue) Int(r *runner) int64 { panic("interp: localValue.Int") } @@ -1254,7 +1260,7 @@ func (r *runner) readObjectLayout(layoutValue value) (uint64, *big.Int) { ptr, err := layoutValue.asPointer(r) if err == errIntegerAsPointer { // It's an integer, which means it's a small object or unknown. - layout := layoutValue.Uint() + layout := layoutValue.Uint(r) if layout == 0 { // Nil pointer, which means the layout is unknown. return 0, nil @@ -1287,7 +1293,7 @@ func (r *runner) readObjectLayout(layoutValue value) (uint64, *big.Int) { // Read the object size in words and the bitmap from the global. buf := r.objects[ptr.index()].buffer.(rawValue) - objectSizeWords := rawValue{buf: buf.buf[:r.pointerSize]}.Uint() + objectSizeWords := rawValue{buf: buf.buf[:r.pointerSize]}.Uint(r) rawByteValues := buf.buf[r.pointerSize:] rawBytes := make([]byte, len(rawByteValues)) for i, v := range rawByteValues { diff --git a/main_test.go b/main_test.go index 40002ee871..80c8a46cd1 100644 --- a/main_test.go +++ b/main_test.go @@ -181,9 +181,13 @@ func TestBuild(t *testing.T) { // Run a single test for GOARCH=mips to see whether it works at all. // Big-endian MIPS isn't fully supported yet, but simple examples // should work. + // Once big-endian is fully supported, we can probably flip this + // around and do full testing of MIPS big-endian support and only do + // limited testing of MIPS little-endian (because the two are some + // similar). t.Parallel() options := optionsFromOSARCH("linux/mips/softfloat", sema) - runTest("alias.go", options, t, nil, nil) + runTest("map.go", options, t, nil, nil) }) t.Run("WebAssembly", func(t *testing.T) { t.Parallel() From 4f1b69827d34d350f0148869c49bf118cd8613ee Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 23 Aug 2024 16:08:43 +0200 Subject: [PATCH 10/24] reflect: support big-endian systems The reflect package needs to know the endianness of the system in a few places. Before this patch, it assumed little-endian systems. But with GOARCH=mips we now have a big-endian system which also needs to be supported. So this patch fixes the reflect package to work on big-endian systems. Also, I've updated the tests for MIPS: instead of running the little-endian tests, I've changed it to run the big-endian tests instead. The two are very similar except for endianness so this should be fine. To be sure we won't accidentally break little-endian support, I've kept a single MIPS little-endian test (the CGo test, which doesn't yet work on big-endian systems anyway). --- main_test.go | 26 +++++++++++++++----------- src/reflect/endian-big.go | 36 ++++++++++++++++++++++++++++++++++++ src/reflect/endian-little.go | 35 +++++++++++++++++++++++++++++++++++ src/reflect/value.go | 31 ++++--------------------------- 4 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 src/reflect/endian-big.go create mode 100644 src/reflect/endian-little.go diff --git a/main_test.go b/main_test.go index 80c8a46cd1..62eb5c51b9 100644 --- a/main_test.go +++ b/main_test.go @@ -36,7 +36,7 @@ var supportedLinuxArches = map[string]string{ "X86Linux": "linux/386", "ARMLinux": "linux/arm/6", "ARM64Linux": "linux/arm64", - "MIPSLinux": "linux/mipsle/hardfloat", + "MIPSLinux": "linux/mips/hardfloat", "WASIp1": "wasip1/wasm", } @@ -177,17 +177,14 @@ func TestBuild(t *testing.T) { }) } } - t.Run("MIPS big-endian", func(t *testing.T) { - // Run a single test for GOARCH=mips to see whether it works at all. - // Big-endian MIPS isn't fully supported yet, but simple examples - // should work. - // Once big-endian is fully supported, we can probably flip this - // around and do full testing of MIPS big-endian support and only do - // limited testing of MIPS little-endian (because the two are some - // similar). + t.Run("MIPS little-endian", func(t *testing.T) { + // Run a single test for GOARCH=mipsle to see whether it works at + // all. It is already mostly tested because GOARCH=mips and + // GOARCH=mipsle are so similar, but it's good to have an extra test + // to be sure. t.Parallel() - options := optionsFromOSARCH("linux/mips/softfloat", sema) - runTest("map.go", options, t, nil, nil) + options := optionsFromOSARCH("linux/mipsle/softfloat", sema) + runTest("cgo/", options, t, nil, nil) }) t.Run("WebAssembly", func(t *testing.T) { t.Parallel() @@ -232,6 +229,13 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) { continue } } + if options.GOOS == "linux" && options.GOARCH == "mips" { + if name == "cgo/" { + // CGo isn't supported yet on big-endian systems (needs updates + // to bitfield access methods). + continue + } + } if options.Target == "simavr" { // Not all tests are currently supported on AVR. // Skip the ones that aren't. diff --git a/src/reflect/endian-big.go b/src/reflect/endian-big.go new file mode 100644 index 0000000000..94951e200d --- /dev/null +++ b/src/reflect/endian-big.go @@ -0,0 +1,36 @@ +//go:build mips + +package reflect + +import "unsafe" + +// loadValue loads a value that may or may not be word-aligned. The number of +// bytes given in size are loaded. The biggest possible size it can load is that +// of an uintptr. +func loadValue(ptr unsafe.Pointer, size uintptr) uintptr { + loadedValue := uintptr(0) + for i := uintptr(0); i < size; i++ { + loadedValue <<= 8 + loadedValue |= uintptr(*(*byte)(ptr)) + ptr = unsafe.Add(ptr, 1) + } + return loadedValue +} + +// storeValue is the inverse of loadValue. It stores a value to a pointer that +// doesn't need to be aligned. +func storeValue(ptr unsafe.Pointer, size, value uintptr) { + // This could perhaps be optimized using bits.ReverseBytes32 if needed. + value <<= (unsafe.Sizeof(uintptr(0)) - size) * 8 + for i := uintptr(0); i < size; i++ { + *(*byte)(ptr) = byte(value >> ((unsafe.Sizeof(uintptr(0)) - 1) * 8)) + ptr = unsafe.Add(ptr, 1) + value <<= 8 + } +} + +// maskAndShift cuts out a part of a uintptr. Note that the offset may not be 0. +func maskAndShift(value, offset, size uintptr) uintptr { + mask := ^uintptr(0) >> ((unsafe.Sizeof(uintptr(0)) - size) * 8) + return (uintptr(value) >> ((unsafe.Sizeof(uintptr(0)) - offset - size) * 8)) & mask +} diff --git a/src/reflect/endian-little.go b/src/reflect/endian-little.go new file mode 100644 index 0000000000..7d7e30059d --- /dev/null +++ b/src/reflect/endian-little.go @@ -0,0 +1,35 @@ +//go:build !mips + +package reflect + +import "unsafe" + +// loadValue loads a value that may or may not be word-aligned. The number of +// bytes given in size are loaded. The biggest possible size it can load is that +// of an uintptr. +func loadValue(ptr unsafe.Pointer, size uintptr) uintptr { + loadedValue := uintptr(0) + shift := uintptr(0) + for i := uintptr(0); i < size; i++ { + loadedValue |= uintptr(*(*byte)(ptr)) << shift + shift += 8 + ptr = unsafe.Add(ptr, 1) + } + return loadedValue +} + +// storeValue is the inverse of loadValue. It stores a value to a pointer that +// doesn't need to be aligned. +func storeValue(ptr unsafe.Pointer, size, value uintptr) { + for i := uintptr(0); i < size; i++ { + *(*byte)(ptr) = byte(value) + ptr = unsafe.Add(ptr, 1) + value >>= 8 + } +} + +// maskAndShift cuts out a part of a uintptr. Note that the offset may not be 0. +func maskAndShift(value, offset, size uintptr) uintptr { + mask := ^uintptr(0) >> ((unsafe.Sizeof(uintptr(0)) - size) * 8) + return (uintptr(value) >> (offset * 8)) & mask +} diff --git a/src/reflect/value.go b/src/reflect/value.go index 9e602f69de..15a900f9e1 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -887,26 +887,6 @@ func (v Value) Index(i int) Value { } } -// loadValue loads a value that may or may not be word-aligned. The number of -// bytes given in size are loaded. The biggest possible size it can load is that -// of an uintptr. -func loadValue(ptr unsafe.Pointer, size uintptr) uintptr { - loadedValue := uintptr(0) - shift := uintptr(0) - for i := uintptr(0); i < size; i++ { - loadedValue |= uintptr(*(*byte)(ptr)) << shift - shift += 8 - ptr = unsafe.Add(ptr, 1) - } - return loadedValue -} - -// maskAndShift cuts out a part of a uintptr. Note that the offset may not be 0. -func maskAndShift(value, offset, size uintptr) uintptr { - mask := ^uintptr(0) >> ((unsafe.Sizeof(uintptr(0)) - size) * 8) - return (uintptr(value) >> (offset * 8)) & mask -} - func (v Value) NumMethod() int { return v.typecode.NumMethod() } @@ -1088,9 +1068,7 @@ func (v Value) Set(x Value) { if v.typecode.Kind() == Interface && x.typecode.Kind() != Interface { // move the value of x back into the interface, if possible if x.isIndirect() && x.typecode.Size() <= unsafe.Sizeof(uintptr(0)) { - var value uintptr - memcpy(unsafe.Pointer(&value), x.value, x.typecode.Size()) - x.value = unsafe.Pointer(value) + x.value = unsafe.Pointer(loadValue(x.value, x.typecode.Size())) } intf := composeInterface(unsafe.Pointer(x.typecode), x.value) @@ -1101,12 +1079,11 @@ func (v Value) Set(x Value) { } size := v.typecode.Size() - xptr := x.value if size <= unsafe.Sizeof(uintptr(0)) && !x.isIndirect() { - value := x.value - xptr = unsafe.Pointer(&value) + storeValue(v.value, size, uintptr(x.value)) + } else { + memcpy(v.value, x.value, size) } - memcpy(v.value, xptr, size) } func (v Value) SetZero() { From ee5bc65c97ddd8ffd54d89a3cda24211a738cbb3 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 31 Aug 2024 13:18:26 +0200 Subject: [PATCH 11/24] compiler: move some code around to make the next bugfix easier This just makes the next fix easier to read. --- compiler/goroutine.go | 64 ++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/compiler/goroutine.go b/compiler/goroutine.go index 95abc77ff9..60fdfaabf5 100644 --- a/compiler/goroutine.go +++ b/compiler/goroutine.go @@ -13,37 +13,7 @@ import ( // createGo emits code to start a new goroutine. func (b *builder) createGo(instr *ssa.Go) { - // Get all function parameters to pass to the goroutine. - var params []llvm.Value - for _, param := range instr.Call.Args { - params = append(params, b.getValue(param, getPos(instr))) - } - - var prefix string - var funcPtr llvm.Value - var funcType llvm.Type - hasContext := false - if callee := instr.Call.StaticCallee(); callee != nil { - // Static callee is known. This makes it easier to start a new - // goroutine. - var context llvm.Value - switch value := instr.Call.Value.(type) { - case *ssa.Function: - // Goroutine call is regular function call. No context is necessary. - case *ssa.MakeClosure: - // A goroutine call on a func value, but the callee is trivial to find. For - // example: immediately applied functions. - funcValue := b.getValue(value, getPos(instr)) - context = b.extractFuncContext(funcValue) - default: - panic("StaticCallee returned an unexpected value") - } - if !context.IsNil() { - params = append(params, context) // context parameter - hasContext = true - } - funcType, funcPtr = b.getFunction(callee) - } else if builtin, ok := instr.Call.Value.(*ssa.Builtin); ok { + if builtin, ok := instr.Call.Value.(*ssa.Builtin); ok { // We cheat. None of the builtins do any long or blocking operation, so // we might as well run these builtins right away without the program // noticing the difference. @@ -74,6 +44,38 @@ func (b *builder) createGo(instr *ssa.Go) { } b.createBuiltin(argTypes, argValues, builtin.Name(), instr.Pos()) return + } + + // Get all function parameters to pass to the goroutine. + var params []llvm.Value + for _, param := range instr.Call.Args { + params = append(params, b.getValue(param, getPos(instr))) + } + + var prefix string + var funcPtr llvm.Value + var funcType llvm.Type + hasContext := false + if callee := instr.Call.StaticCallee(); callee != nil { + // Static callee is known. This makes it easier to start a new + // goroutine. + var context llvm.Value + switch value := instr.Call.Value.(type) { + case *ssa.Function: + // Goroutine call is regular function call. No context is necessary. + case *ssa.MakeClosure: + // A goroutine call on a func value, but the callee is trivial to find. For + // example: immediately applied functions. + funcValue := b.getValue(value, getPos(instr)) + context = b.extractFuncContext(funcValue) + default: + panic("StaticCallee returned an unexpected value") + } + if !context.IsNil() { + params = append(params, context) // context parameter + hasContext = true + } + funcType, funcPtr = b.getFunction(callee) } else if instr.Call.IsInvoke() { // This is a method call on an interface value. itf := b.getValue(instr.Call.Value, getPos(instr)) From d4cb92f27c48148bc269308ff6973338b6f1f7c9 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 31 Aug 2024 13:25:42 +0200 Subject: [PATCH 12/24] compiler: fix passing weirdly-padded structs to new goroutines The values were stored in the passed object as the values itself (not expanded like is common in the calling convention), and read back after assuming they were expanded. This often works for simple parameters (int, pointer, etc), but not for more complex parameters. Especially when there's padding. Found this while working on `//go:wasmexport`. --- compiler/goroutine.go | 2 +- .../testdata/goroutine-cortex-m-qemu-tasks.ll | 12 +++++------- compiler/testdata/goroutine-wasm-asyncify.ll | 12 +++++------- testdata/goroutines.go | 16 ++++++++++++++++ testdata/goroutines.txt | 1 + 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/compiler/goroutine.go b/compiler/goroutine.go index 60fdfaabf5..a235563450 100644 --- a/compiler/goroutine.go +++ b/compiler/goroutine.go @@ -49,7 +49,7 @@ func (b *builder) createGo(instr *ssa.Go) { // Get all function parameters to pass to the goroutine. var params []llvm.Value for _, param := range instr.Call.Args { - params = append(params, b.getValue(param, getPos(instr))) + params = append(params, b.expandFormalParam(b.getValue(param, getPos(instr)))...) } var prefix string diff --git a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll index f0a692c0f2..f149f3a0cf 100644 --- a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll +++ b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll @@ -3,8 +3,6 @@ source_filename = "goroutine.go" target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv7m-unknown-unknown-eabi" -%runtime._string = type { ptr, i32 } - @"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 ; Function Attrs: allockind("alloc,zeroed") allocsize(0) @@ -150,12 +148,12 @@ define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value, entry: %0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9 store ptr %itf.value, ptr %0, align 4 - %1 = getelementptr inbounds { ptr, %runtime._string, ptr }, ptr %0, i32 0, i32 1 + %1 = getelementptr inbounds { ptr, ptr, i32, ptr }, ptr %0, i32 0, i32 1 store ptr @"main$string", ptr %1, align 4 - %.repack1 = getelementptr inbounds { ptr, %runtime._string, ptr }, ptr %0, i32 0, i32 1, i32 1 - store i32 4, ptr %.repack1, align 4 - %2 = getelementptr inbounds { ptr, %runtime._string, ptr }, ptr %0, i32 0, i32 2 - store ptr %itf.typecode, ptr %2, align 4 + %2 = getelementptr inbounds { ptr, ptr, i32, ptr }, ptr %0, i32 0, i32 2 + store i32 4, ptr %2, align 4 + %3 = getelementptr inbounds { ptr, ptr, i32, ptr }, ptr %0, i32 0, i32 3 + store ptr %itf.typecode, ptr %3, align 4 %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr undef) #9 call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9 ret void diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll index 1281857d31..699b9f2057 100644 --- a/compiler/testdata/goroutine-wasm-asyncify.ll +++ b/compiler/testdata/goroutine-wasm-asyncify.ll @@ -3,8 +3,6 @@ source_filename = "goroutine.go" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-wasi" -%runtime._string = type { ptr, i32 } - @"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 ; Function Attrs: allockind("alloc,zeroed") allocsize(0) @@ -161,12 +159,12 @@ entry: %0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9 call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9 store ptr %itf.value, ptr %0, align 4 - %1 = getelementptr inbounds { ptr, %runtime._string, ptr }, ptr %0, i32 0, i32 1 + %1 = getelementptr inbounds { ptr, ptr, i32, ptr }, ptr %0, i32 0, i32 1 store ptr @"main$string", ptr %1, align 4 - %.repack1 = getelementptr inbounds { ptr, %runtime._string, ptr }, ptr %0, i32 0, i32 1, i32 1 - store i32 4, ptr %.repack1, align 4 - %2 = getelementptr inbounds { ptr, %runtime._string, ptr }, ptr %0, i32 0, i32 2 - store ptr %itf.typecode, ptr %2, align 4 + %2 = getelementptr inbounds { ptr, ptr, i32, ptr }, ptr %0, i32 0, i32 2 + store i32 4, ptr %2, align 4 + %3 = getelementptr inbounds { ptr, ptr, i32, ptr }, ptr %0, i32 0, i32 3 + store ptr %itf.typecode, ptr %3, align 4 call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9 ret void } diff --git a/testdata/goroutines.go b/testdata/goroutines.go index 66abc54fde..5ac3b73187 100644 --- a/testdata/goroutines.go +++ b/testdata/goroutines.go @@ -86,6 +86,10 @@ func main() { testCond() testIssue1790() + + done := make(chan int) + go testPaddedParameters(paddedStruct{x: 5, y: 7}, done) + <-done } func acquire(m *sync.Mutex) { @@ -243,3 +247,15 @@ func (f Foo) Wait() { time.Sleep(time.Microsecond) println(" ...waited") } + +type paddedStruct struct { + x uint8 + _ [0]int64 + y uint8 +} + +// Structs with interesting padding used to crash. +func testPaddedParameters(s paddedStruct, done chan int) { + println("paddedStruct:", s.x, s.y) + close(done) +} diff --git a/testdata/goroutines.txt b/testdata/goroutines.txt index 35c0cd44dd..1430ee0a20 100644 --- a/testdata/goroutines.txt +++ b/testdata/goroutines.txt @@ -26,3 +26,4 @@ called: Foo.Nowait called: Foo.Wait ...waited done with 'go on interface' +paddedStruct: 5 7 From 1f3e0004a9db9c238fd451284b8b5b0abf4d57bb Mon Sep 17 00:00:00 2001 From: Warren Guy <5602790+warrenguy@users.noreply.github.com> Date: Thu, 5 Sep 2024 10:49:36 +0100 Subject: [PATCH 13/24] add board: RAKwireless RAK4631 (#4454) targets: add rak4631 --- GNUmakefile | 2 + src/machine/board_rak4631.go | 86 ++++++++++++++++++++++++++++++++++++ targets/rak4631.json | 6 +++ 3 files changed, 94 insertions(+) create mode 100644 src/machine/board_rak4631.go create mode 100644 targets/rak4631.json diff --git a/GNUmakefile b/GNUmakefile index 94d9c357d2..8979e25bef 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -642,6 +642,8 @@ endif @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=xiao examples/blinky1 @$(MD5SUM) test.hex + $(TINYGO) build -size short -o test.hex -target=rak4631 examples/blinky1 + @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=circuitplay-express examples/dac @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=pyportal examples/dac diff --git a/src/machine/board_rak4631.go b/src/machine/board_rak4631.go new file mode 100644 index 0000000000..c59f3717b7 --- /dev/null +++ b/src/machine/board_rak4631.go @@ -0,0 +1,86 @@ +//go:build rak4631 + +package machine + +const HasLowFrequencyCrystal = true + +// Digital Pins +const ( + D0 Pin = P0_28 + D1 Pin = P0_02 +) + +// Analog pins +const ( + A0 Pin = P0_17 + A1 Pin = P1_02 + A2 Pin = P0_21 +) + +// Onboard LEDs +const ( + LED = LED2 + LED1 = P1_03 + LED2 = P1_04 +) + +// UART pins +const ( + // Default to UART1 + UART_RX_PIN = UART0_RX_PIN + UART_TX_PIN = UART0_TX_PIN + + // UART1 + UART0_RX_PIN = P0_19 + UART0_TX_PIN = P0_20 + + // UART2 + UART1_RX_PIN = P0_15 + UART1_TX_PIN = P0_16 +) + +// I2C pins +const ( + SDA_PIN = SDA1_PIN + SCL_PIN = SCL1_PIN + + SDA1_PIN = P0_13 + SCL1_PIN = P0_14 + + SDA2_PIN = P0_24 + SCL2_PIN = P0_25 +) + +// SPI pins +const ( + SPI0_SCK_PIN = P0_03 + SPI0_SDO_PIN = P0_29 + SPI0_SDI_PIN = P0_30 +) + +// Peripherals +const ( + LORA_NSS = P1_10 + LORA_SCK = P1_11 + LORA_MOSI = P1_12 + LORA_MISO = P1_13 + LORA_BUSY = P1_14 + LORA_DIO1 = P1_15 + LORA_NRESET = P1_06 + LORA_POWER = P1_05 +) + +// USB CDC identifiers +const ( + usb_STRING_PRODUCT = "WisCore RAK4631 Board" + usb_STRING_MANUFACTURER = "RAKwireless" +) + +var ( + usb_VID uint16 = 0x239a + usb_PID uint16 = 0x8029 +) + +var ( + DefaultUART = UART0 +) diff --git a/targets/rak4631.json b/targets/rak4631.json new file mode 100644 index 0000000000..cbd8221300 --- /dev/null +++ b/targets/rak4631.json @@ -0,0 +1,6 @@ +{ + "inherits": ["nrf52840", "nrf52840-s140v6-uf2"], + "build-tags": ["rak4631"], + "serial-port": ["239a:8029"], + "msd-volume-name": ["RAK4631"] +} From c931bc73948a794301ebbe33d429614dc9dcf534 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 27 Aug 2024 15:47:19 +0200 Subject: [PATCH 14/24] wasip2: do not export the _start function It seems to have been replaced with the Component Model `run` function. --- src/runtime/runtime_wasm_wasip2.go | 10 +--------- targets/wasip2.json | 3 ++- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/runtime/runtime_wasm_wasip2.go b/src/runtime/runtime_wasm_wasip2.go index ca189aad64..57e6623d33 100644 --- a/src/runtime/runtime_wasm_wasip2.go +++ b/src/runtime/runtime_wasm_wasip2.go @@ -13,19 +13,11 @@ type timeUnit int64 //export wasi:cli/run@0.2.0#run func __wasi_cli_run_run() uint32 { - _start() - return 0 -} - -//export _start -func _start() { // These need to be initialized early so that the heap can be initialized. heapStart = uintptr(unsafe.Pointer(&heapStartSymbol)) heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize) run() -} - -func init() { + return 0 } var args []string diff --git a/targets/wasip2.json b/targets/wasip2.json index 3d6f68c6ec..7735e12dab 100644 --- a/targets/wasip2.json +++ b/targets/wasip2.json @@ -17,7 +17,8 @@ ], "ldflags": [ "--stack-first", - "--no-demangle" + "--no-demangle", + "--no-entry" ], "extra-files": [ "src/runtime/asm_tinygowasm.S" From 78ddc51471984b714ff25db33fe33012ee9a6f19 Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Thu, 5 Sep 2024 11:22:30 -0700 Subject: [PATCH 15/24] internal/wasm-tools: update wasm-tools-go to new repo and version --- internal/wasm-tools/go.mod | 4 ++-- internal/wasm-tools/go.sum | 16 ++++++++-------- internal/wasm-tools/tools.go | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/wasm-tools/go.mod b/internal/wasm-tools/go.mod index 8a0e49351b..cffb52fd11 100644 --- a/internal/wasm-tools/go.mod +++ b/internal/wasm-tools/go.mod @@ -2,11 +2,11 @@ module github.com/tinygo-org/tinygo/internal/tools go 1.22.4 -require github.com/ydnar/wasm-tools-go v0.1.4 +require github.com/ydnar/wasm-tools-go v0.1.5 require ( github.com/coreos/go-semver v0.3.1 // indirect github.com/urfave/cli/v3 v3.0.0-alpha9 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/mod v0.19.0 // indirect + golang.org/x/mod v0.21.0 // indirect ) diff --git a/internal/wasm-tools/go.sum b/internal/wasm-tools/go.sum index b2d0b1e3ac..58528629f4 100644 --- a/internal/wasm-tools/go.sum +++ b/internal/wasm-tools/go.sum @@ -12,14 +12,14 @@ github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkU github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/ydnar/wasm-tools-go v0.1.4 h1:+25WqBj0AhLx8OFvZvrs7bQO6L3WtQ7t6JzQEYsXQb8= -github.com/ydnar/wasm-tools-go v0.1.4/go.mod h1:lQfv2Tde3tRgZDSYriro0EmdSHzP1mrHPMmYNahSS/g= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +github.com/ydnar/wasm-tools-go v0.1.5 h1:ah2WT4gH0IrmN29ZSsjgNC9SPsdXZ+KN+o9uTZqNVSI= +github.com/ydnar/wasm-tools-go v0.1.5/go.mod h1:L3sDi5rbAMJNmMO5cpDRzYYhB0r9xIU0xgpKjwU0Adg= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/wasm-tools/tools.go b/internal/wasm-tools/tools.go index c8eb42fde1..0876ea7331 100644 --- a/internal/wasm-tools/tools.go +++ b/internal/wasm-tools/tools.go @@ -5,7 +5,7 @@ package tools import ( - _ "github.com/ydnar/wasm-tools-go/cmd/wit-bindgen-go" + _ "github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go" ) -//go:generate go install github.com/ydnar/wasm-tools-go/cmd/wit-bindgen-go +//go:generate go install github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go From 9dcb63ca985506d207fc1a2db65251a14abf32cb Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Thu, 5 Sep 2024 11:31:45 -0700 Subject: [PATCH 16/24] internal/wasi: regenerated with wit-bindgen-go@v0.20 --- src/internal/wasi/cli/v0.2.0/command/command.wit.go | 2 -- src/internal/wasi/cli/v0.2.0/environment/environment.wit.go | 2 -- src/internal/wasi/cli/v0.2.0/exit/exit.wit.go | 2 -- src/internal/wasi/cli/v0.2.0/run/run.exports.go | 2 -- src/internal/wasi/cli/v0.2.0/run/run.wit.go | 2 -- src/internal/wasi/cli/v0.2.0/stderr/stderr.wit.go | 2 -- src/internal/wasi/cli/v0.2.0/stdin/stdin.wit.go | 2 -- src/internal/wasi/cli/v0.2.0/stdout/stdout.wit.go | 2 -- .../wasi/cli/v0.2.0/terminal-input/terminal-input.wit.go | 2 -- .../wasi/cli/v0.2.0/terminal-output/terminal-output.wit.go | 2 -- .../wasi/cli/v0.2.0/terminal-stderr/terminal-stderr.wit.go | 2 -- .../wasi/cli/v0.2.0/terminal-stdin/terminal-stdin.wit.go | 2 -- .../wasi/cli/v0.2.0/terminal-stdout/terminal-stdout.wit.go | 2 -- .../wasi/clocks/v0.2.0/monotonic-clock/monotonic-clock.wit.go | 2 -- src/internal/wasi/clocks/v0.2.0/wall-clock/wall-clock.wit.go | 2 -- src/internal/wasi/filesystem/v0.2.0/preopens/preopens.wit.go | 2 -- src/internal/wasi/filesystem/v0.2.0/types/abi.go | 2 -- src/internal/wasi/filesystem/v0.2.0/types/types.wit.go | 2 -- src/internal/wasi/io/v0.2.0/error/error.wit.go | 2 -- src/internal/wasi/io/v0.2.0/poll/poll.wit.go | 2 -- src/internal/wasi/io/v0.2.0/streams/abi.go | 2 -- src/internal/wasi/io/v0.2.0/streams/streams.wit.go | 2 -- .../wasi/random/v0.2.0/insecure-seed/insecure-seed.wit.go | 2 -- src/internal/wasi/random/v0.2.0/insecure/insecure.wit.go | 2 -- src/internal/wasi/random/v0.2.0/random/random.wit.go | 2 -- .../sockets/v0.2.0/instance-network/instance-network.wit.go | 2 -- src/internal/wasi/sockets/v0.2.0/ip-name-lookup/abi.go | 2 -- .../wasi/sockets/v0.2.0/ip-name-lookup/ip-name-lookup.wit.go | 2 -- src/internal/wasi/sockets/v0.2.0/network/abi.go | 2 -- src/internal/wasi/sockets/v0.2.0/network/network.wit.go | 2 -- .../sockets/v0.2.0/tcp-create-socket/tcp-create-socket.wit.go | 2 -- src/internal/wasi/sockets/v0.2.0/tcp/abi.go | 2 -- src/internal/wasi/sockets/v0.2.0/tcp/tcp.wit.go | 2 -- .../sockets/v0.2.0/udp-create-socket/udp-create-socket.wit.go | 2 -- src/internal/wasi/sockets/v0.2.0/udp/abi.go | 2 -- src/internal/wasi/sockets/v0.2.0/udp/udp.wit.go | 2 -- 36 files changed, 72 deletions(-) diff --git a/src/internal/wasi/cli/v0.2.0/command/command.wit.go b/src/internal/wasi/cli/v0.2.0/command/command.wit.go index be6dd30450..cdd985d607 100644 --- a/src/internal/wasi/cli/v0.2.0/command/command.wit.go +++ b/src/internal/wasi/cli/v0.2.0/command/command.wit.go @@ -1,6 +1,4 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package command represents the world "wasi:cli/command@0.2.0". package command diff --git a/src/internal/wasi/cli/v0.2.0/environment/environment.wit.go b/src/internal/wasi/cli/v0.2.0/environment/environment.wit.go index 81fec996ad..a3cd386c22 100644 --- a/src/internal/wasi/cli/v0.2.0/environment/environment.wit.go +++ b/src/internal/wasi/cli/v0.2.0/environment/environment.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package environment represents the imported interface "wasi:cli/environment@0.2.0". package environment diff --git a/src/internal/wasi/cli/v0.2.0/exit/exit.wit.go b/src/internal/wasi/cli/v0.2.0/exit/exit.wit.go index 24aa1b5610..b506fa1857 100644 --- a/src/internal/wasi/cli/v0.2.0/exit/exit.wit.go +++ b/src/internal/wasi/cli/v0.2.0/exit/exit.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package exit represents the imported interface "wasi:cli/exit@0.2.0". package exit diff --git a/src/internal/wasi/cli/v0.2.0/run/run.exports.go b/src/internal/wasi/cli/v0.2.0/run/run.exports.go index 8dfaedec22..ae848313f5 100644 --- a/src/internal/wasi/cli/v0.2.0/run/run.exports.go +++ b/src/internal/wasi/cli/v0.2.0/run/run.exports.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - package run import ( diff --git a/src/internal/wasi/cli/v0.2.0/run/run.wit.go b/src/internal/wasi/cli/v0.2.0/run/run.wit.go index 22e7fc4321..51eb5fb311 100644 --- a/src/internal/wasi/cli/v0.2.0/run/run.wit.go +++ b/src/internal/wasi/cli/v0.2.0/run/run.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package run represents the exported interface "wasi:cli/run@0.2.0". package run diff --git a/src/internal/wasi/cli/v0.2.0/stderr/stderr.wit.go b/src/internal/wasi/cli/v0.2.0/stderr/stderr.wit.go index b57323715b..4486147535 100644 --- a/src/internal/wasi/cli/v0.2.0/stderr/stderr.wit.go +++ b/src/internal/wasi/cli/v0.2.0/stderr/stderr.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package stderr represents the imported interface "wasi:cli/stderr@0.2.0". package stderr diff --git a/src/internal/wasi/cli/v0.2.0/stdin/stdin.wit.go b/src/internal/wasi/cli/v0.2.0/stdin/stdin.wit.go index 664ca14bef..c777175698 100644 --- a/src/internal/wasi/cli/v0.2.0/stdin/stdin.wit.go +++ b/src/internal/wasi/cli/v0.2.0/stdin/stdin.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package stdin represents the imported interface "wasi:cli/stdin@0.2.0". package stdin diff --git a/src/internal/wasi/cli/v0.2.0/stdout/stdout.wit.go b/src/internal/wasi/cli/v0.2.0/stdout/stdout.wit.go index 6b2b28aac5..4a7007f0e0 100644 --- a/src/internal/wasi/cli/v0.2.0/stdout/stdout.wit.go +++ b/src/internal/wasi/cli/v0.2.0/stdout/stdout.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package stdout represents the imported interface "wasi:cli/stdout@0.2.0". package stdout diff --git a/src/internal/wasi/cli/v0.2.0/terminal-input/terminal-input.wit.go b/src/internal/wasi/cli/v0.2.0/terminal-input/terminal-input.wit.go index 318a91ac79..795be5d093 100644 --- a/src/internal/wasi/cli/v0.2.0/terminal-input/terminal-input.wit.go +++ b/src/internal/wasi/cli/v0.2.0/terminal-input/terminal-input.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package terminalinput represents the imported interface "wasi:cli/terminal-input@0.2.0". // // Terminal input. diff --git a/src/internal/wasi/cli/v0.2.0/terminal-output/terminal-output.wit.go b/src/internal/wasi/cli/v0.2.0/terminal-output/terminal-output.wit.go index 6e56faf408..eb97c9ee7e 100644 --- a/src/internal/wasi/cli/v0.2.0/terminal-output/terminal-output.wit.go +++ b/src/internal/wasi/cli/v0.2.0/terminal-output/terminal-output.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package terminaloutput represents the imported interface "wasi:cli/terminal-output@0.2.0". // // Terminal output. diff --git a/src/internal/wasi/cli/v0.2.0/terminal-stderr/terminal-stderr.wit.go b/src/internal/wasi/cli/v0.2.0/terminal-stderr/terminal-stderr.wit.go index d9e32838c0..72215a8b7c 100644 --- a/src/internal/wasi/cli/v0.2.0/terminal-stderr/terminal-stderr.wit.go +++ b/src/internal/wasi/cli/v0.2.0/terminal-stderr/terminal-stderr.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package terminalstderr represents the imported interface "wasi:cli/terminal-stderr@0.2.0". // // An interface providing an optional `terminal-output` for stderr as a diff --git a/src/internal/wasi/cli/v0.2.0/terminal-stdin/terminal-stdin.wit.go b/src/internal/wasi/cli/v0.2.0/terminal-stdin/terminal-stdin.wit.go index 834864f8ea..1a6091d7c8 100644 --- a/src/internal/wasi/cli/v0.2.0/terminal-stdin/terminal-stdin.wit.go +++ b/src/internal/wasi/cli/v0.2.0/terminal-stdin/terminal-stdin.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package terminalstdin represents the imported interface "wasi:cli/terminal-stdin@0.2.0". // // An interface providing an optional `terminal-input` for stdin as a diff --git a/src/internal/wasi/cli/v0.2.0/terminal-stdout/terminal-stdout.wit.go b/src/internal/wasi/cli/v0.2.0/terminal-stdout/terminal-stdout.wit.go index 7dbb2cab1b..3951449458 100644 --- a/src/internal/wasi/cli/v0.2.0/terminal-stdout/terminal-stdout.wit.go +++ b/src/internal/wasi/cli/v0.2.0/terminal-stdout/terminal-stdout.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package terminalstdout represents the imported interface "wasi:cli/terminal-stdout@0.2.0". // // An interface providing an optional `terminal-output` for stdout as a diff --git a/src/internal/wasi/clocks/v0.2.0/monotonic-clock/monotonic-clock.wit.go b/src/internal/wasi/clocks/v0.2.0/monotonic-clock/monotonic-clock.wit.go index 1b1ae5358d..580bd2b552 100644 --- a/src/internal/wasi/clocks/v0.2.0/monotonic-clock/monotonic-clock.wit.go +++ b/src/internal/wasi/clocks/v0.2.0/monotonic-clock/monotonic-clock.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package monotonicclock represents the imported interface "wasi:clocks/monotonic-clock@0.2.0". // // WASI Monotonic Clock is a clock API intended to let users measure elapsed diff --git a/src/internal/wasi/clocks/v0.2.0/wall-clock/wall-clock.wit.go b/src/internal/wasi/clocks/v0.2.0/wall-clock/wall-clock.wit.go index a270f78d6d..a59a313d24 100644 --- a/src/internal/wasi/clocks/v0.2.0/wall-clock/wall-clock.wit.go +++ b/src/internal/wasi/clocks/v0.2.0/wall-clock/wall-clock.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package wallclock represents the imported interface "wasi:clocks/wall-clock@0.2.0". // // WASI Wall Clock is a clock API intended to let users query the current diff --git a/src/internal/wasi/filesystem/v0.2.0/preopens/preopens.wit.go b/src/internal/wasi/filesystem/v0.2.0/preopens/preopens.wit.go index 4638a9a39d..d57dea5179 100644 --- a/src/internal/wasi/filesystem/v0.2.0/preopens/preopens.wit.go +++ b/src/internal/wasi/filesystem/v0.2.0/preopens/preopens.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package preopens represents the imported interface "wasi:filesystem/preopens@0.2.0". package preopens diff --git a/src/internal/wasi/filesystem/v0.2.0/types/abi.go b/src/internal/wasi/filesystem/v0.2.0/types/abi.go index 136fb06c2f..4cf4f32804 100644 --- a/src/internal/wasi/filesystem/v0.2.0/types/abi.go +++ b/src/internal/wasi/filesystem/v0.2.0/types/abi.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - package types import ( diff --git a/src/internal/wasi/filesystem/v0.2.0/types/types.wit.go b/src/internal/wasi/filesystem/v0.2.0/types/types.wit.go index f1f139ed13..ecceefe924 100644 --- a/src/internal/wasi/filesystem/v0.2.0/types/types.wit.go +++ b/src/internal/wasi/filesystem/v0.2.0/types/types.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package types represents the imported interface "wasi:filesystem/types@0.2.0". // // WASI filesystem is a filesystem API primarily intended to let users run WASI diff --git a/src/internal/wasi/io/v0.2.0/error/error.wit.go b/src/internal/wasi/io/v0.2.0/error/error.wit.go index aae635062a..e7f92a8d3f 100644 --- a/src/internal/wasi/io/v0.2.0/error/error.wit.go +++ b/src/internal/wasi/io/v0.2.0/error/error.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package ioerror represents the imported interface "wasi:io/error@0.2.0". package ioerror diff --git a/src/internal/wasi/io/v0.2.0/poll/poll.wit.go b/src/internal/wasi/io/v0.2.0/poll/poll.wit.go index 274a8e8a4b..626ac50e1e 100644 --- a/src/internal/wasi/io/v0.2.0/poll/poll.wit.go +++ b/src/internal/wasi/io/v0.2.0/poll/poll.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package poll represents the imported interface "wasi:io/poll@0.2.0". // // A poll API intended to let users wait for I/O events on multiple handles diff --git a/src/internal/wasi/io/v0.2.0/streams/abi.go b/src/internal/wasi/io/v0.2.0/streams/abi.go index 8d7592070c..5f1500288a 100644 --- a/src/internal/wasi/io/v0.2.0/streams/abi.go +++ b/src/internal/wasi/io/v0.2.0/streams/abi.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - package streams import ( diff --git a/src/internal/wasi/io/v0.2.0/streams/streams.wit.go b/src/internal/wasi/io/v0.2.0/streams/streams.wit.go index 317fdc8820..01fc0288f0 100644 --- a/src/internal/wasi/io/v0.2.0/streams/streams.wit.go +++ b/src/internal/wasi/io/v0.2.0/streams/streams.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package streams represents the imported interface "wasi:io/streams@0.2.0". // // WASI I/O is an I/O abstraction API which is currently focused on providing diff --git a/src/internal/wasi/random/v0.2.0/insecure-seed/insecure-seed.wit.go b/src/internal/wasi/random/v0.2.0/insecure-seed/insecure-seed.wit.go index e9ac780821..3b8f33c065 100644 --- a/src/internal/wasi/random/v0.2.0/insecure-seed/insecure-seed.wit.go +++ b/src/internal/wasi/random/v0.2.0/insecure-seed/insecure-seed.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package insecureseed represents the imported interface "wasi:random/insecure-seed@0.2.0". // // The insecure-seed interface for seeding hash-map DoS resistance. diff --git a/src/internal/wasi/random/v0.2.0/insecure/insecure.wit.go b/src/internal/wasi/random/v0.2.0/insecure/insecure.wit.go index 7b38f0118d..44cdbd7cfd 100644 --- a/src/internal/wasi/random/v0.2.0/insecure/insecure.wit.go +++ b/src/internal/wasi/random/v0.2.0/insecure/insecure.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package insecure represents the imported interface "wasi:random/insecure@0.2.0". // // The insecure interface for insecure pseudo-random numbers. diff --git a/src/internal/wasi/random/v0.2.0/random/random.wit.go b/src/internal/wasi/random/v0.2.0/random/random.wit.go index 05b7556236..cf0929bf5b 100644 --- a/src/internal/wasi/random/v0.2.0/random/random.wit.go +++ b/src/internal/wasi/random/v0.2.0/random/random.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package random represents the imported interface "wasi:random/random@0.2.0". // // WASI Random is a random data API. diff --git a/src/internal/wasi/sockets/v0.2.0/instance-network/instance-network.wit.go b/src/internal/wasi/sockets/v0.2.0/instance-network/instance-network.wit.go index e7d5f0ea7e..4740360171 100644 --- a/src/internal/wasi/sockets/v0.2.0/instance-network/instance-network.wit.go +++ b/src/internal/wasi/sockets/v0.2.0/instance-network/instance-network.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package instancenetwork represents the imported interface "wasi:sockets/instance-network@0.2.0". // // This interface provides a value-export of the default network handle.. diff --git a/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/abi.go b/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/abi.go index 41714d9ec8..fbc790e008 100644 --- a/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/abi.go +++ b/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/abi.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - package ipnamelookup import ( diff --git a/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/ip-name-lookup.wit.go b/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/ip-name-lookup.wit.go index dcd1fd9d95..f4c7632f7b 100644 --- a/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/ip-name-lookup.wit.go +++ b/src/internal/wasi/sockets/v0.2.0/ip-name-lookup/ip-name-lookup.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package ipnamelookup represents the imported interface "wasi:sockets/ip-name-lookup@0.2.0". package ipnamelookup diff --git a/src/internal/wasi/sockets/v0.2.0/network/abi.go b/src/internal/wasi/sockets/v0.2.0/network/abi.go index ef9fc1e8dc..54820be8aa 100644 --- a/src/internal/wasi/sockets/v0.2.0/network/abi.go +++ b/src/internal/wasi/sockets/v0.2.0/network/abi.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - package network import ( diff --git a/src/internal/wasi/sockets/v0.2.0/network/network.wit.go b/src/internal/wasi/sockets/v0.2.0/network/network.wit.go index 5f2403c433..58ad4e9b6e 100644 --- a/src/internal/wasi/sockets/v0.2.0/network/network.wit.go +++ b/src/internal/wasi/sockets/v0.2.0/network/network.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package network represents the imported interface "wasi:sockets/network@0.2.0". package network diff --git a/src/internal/wasi/sockets/v0.2.0/tcp-create-socket/tcp-create-socket.wit.go b/src/internal/wasi/sockets/v0.2.0/tcp-create-socket/tcp-create-socket.wit.go index 20478aaaeb..44e24502b8 100644 --- a/src/internal/wasi/sockets/v0.2.0/tcp-create-socket/tcp-create-socket.wit.go +++ b/src/internal/wasi/sockets/v0.2.0/tcp-create-socket/tcp-create-socket.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package tcpcreatesocket represents the imported interface "wasi:sockets/tcp-create-socket@0.2.0". package tcpcreatesocket diff --git a/src/internal/wasi/sockets/v0.2.0/tcp/abi.go b/src/internal/wasi/sockets/v0.2.0/tcp/abi.go index f986948e37..f6b37f118e 100644 --- a/src/internal/wasi/sockets/v0.2.0/tcp/abi.go +++ b/src/internal/wasi/sockets/v0.2.0/tcp/abi.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - package tcp import ( diff --git a/src/internal/wasi/sockets/v0.2.0/tcp/tcp.wit.go b/src/internal/wasi/sockets/v0.2.0/tcp/tcp.wit.go index e278713101..30eefbd87e 100644 --- a/src/internal/wasi/sockets/v0.2.0/tcp/tcp.wit.go +++ b/src/internal/wasi/sockets/v0.2.0/tcp/tcp.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package tcp represents the imported interface "wasi:sockets/tcp@0.2.0". package tcp diff --git a/src/internal/wasi/sockets/v0.2.0/udp-create-socket/udp-create-socket.wit.go b/src/internal/wasi/sockets/v0.2.0/udp-create-socket/udp-create-socket.wit.go index c06bc96c57..dc21be4d9c 100644 --- a/src/internal/wasi/sockets/v0.2.0/udp-create-socket/udp-create-socket.wit.go +++ b/src/internal/wasi/sockets/v0.2.0/udp-create-socket/udp-create-socket.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package udpcreatesocket represents the imported interface "wasi:sockets/udp-create-socket@0.2.0". package udpcreatesocket diff --git a/src/internal/wasi/sockets/v0.2.0/udp/abi.go b/src/internal/wasi/sockets/v0.2.0/udp/abi.go index 3783acdac3..23a96c983e 100644 --- a/src/internal/wasi/sockets/v0.2.0/udp/abi.go +++ b/src/internal/wasi/sockets/v0.2.0/udp/abi.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - package udp import ( diff --git a/src/internal/wasi/sockets/v0.2.0/udp/udp.wit.go b/src/internal/wasi/sockets/v0.2.0/udp/udp.wit.go index 41b8491c0f..268a8f6c89 100644 --- a/src/internal/wasi/sockets/v0.2.0/udp/udp.wit.go +++ b/src/internal/wasi/sockets/v0.2.0/udp/udp.wit.go @@ -1,7 +1,5 @@ // Code generated by wit-bindgen-go. DO NOT EDIT. -//go:build !wasip1 - // Package udp represents the imported interface "wasi:sockets/udp@0.2.0". package udp From e13d4ba3d0d8851b6a3b73e791d2303992b4d3d5 Mon Sep 17 00:00:00 2001 From: Randy Reddig Date: Thu, 5 Sep 2024 11:40:45 -0700 Subject: [PATCH 17/24] GNUmakefile, internal/wasm-tools: s/ydnar/bytecodealliance/g --- GNUmakefile | 2 +- internal/wasm-tools/go.mod | 2 +- internal/wasm-tools/go.sum | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 8979e25bef..ed1855c833 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -267,7 +267,7 @@ lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a: cd lib/wasi-libc && $(MAKE) -j4 EXTRA_CFLAGS="-O2 -g -DNDEBUG -mnontrapping-fptoint -msign-ext" MALLOC_IMPL=none CC="$(CLANG)" AR=$(LLVM_AR) NM=$(LLVM_NM) # Generate WASI syscall bindings -WASM_TOOLS_MODULE=github.com/ydnar/wasm-tools-go +WASM_TOOLS_MODULE=github.com/bytecodealliance/wasm-tools-go .PHONY: wasi-syscall wasi-syscall: wasi-cm go run -modfile ./internal/wasm-tools/go.mod $(WASM_TOOLS_MODULE)/cmd/wit-bindgen-go generate --versioned -o ./src/internal -p internal --cm internal/cm ./lib/wasi-cli/wit diff --git a/internal/wasm-tools/go.mod b/internal/wasm-tools/go.mod index cffb52fd11..eadddcbbba 100644 --- a/internal/wasm-tools/go.mod +++ b/internal/wasm-tools/go.mod @@ -2,7 +2,7 @@ module github.com/tinygo-org/tinygo/internal/tools go 1.22.4 -require github.com/ydnar/wasm-tools-go v0.1.5 +require github.com/bytecodealliance/wasm-tools-go v0.2.0 require ( github.com/coreos/go-semver v0.3.1 // indirect diff --git a/internal/wasm-tools/go.sum b/internal/wasm-tools/go.sum index 58528629f4..d4fb71dfb0 100644 --- a/internal/wasm-tools/go.sum +++ b/internal/wasm-tools/go.sum @@ -1,3 +1,5 @@ +github.com/bytecodealliance/wasm-tools-go v0.2.0 h1:JdmiZew7ewHjf+ZGGRE4gZM85Ad/PGW/5I57hepEOjQ= +github.com/bytecodealliance/wasm-tools-go v0.2.0/go.mod h1:2GnJCUlcDrslZ/L6+yYqoUnewDlBvqRS2N/0NW9ro6w= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -12,8 +14,6 @@ github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkU github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/ydnar/wasm-tools-go v0.1.5 h1:ah2WT4gH0IrmN29ZSsjgNC9SPsdXZ+KN+o9uTZqNVSI= -github.com/ydnar/wasm-tools-go v0.1.5/go.mod h1:L3sDi5rbAMJNmMO5cpDRzYYhB0r9xIU0xgpKjwU0Adg= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= From 2e47a9c5cdd38025bda8b6a21b356b564111bf3a Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 16 Aug 2024 16:11:31 +0200 Subject: [PATCH 18/24] gen-device: switch generator for Renesas code to use main cmsis-svd repo --- GNUmakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index ed1855c833..7333a6ebc9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -185,7 +185,7 @@ fmt-check: ## Warn if any source needs reformatting @unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1 -gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp ## Generate microcontroller-specific sources +gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp gen-device-renesas ## Generate microcontroller-specific sources ifneq ($(STM32), 0) gen-device: gen-device-stm32 endif @@ -234,7 +234,7 @@ gen-device-rp: build/gen-device-svd GO111MODULE=off $(GO) fmt ./src/device/rp gen-device-renesas: build/gen-device-svd - ./build/gen-device-svd -source=https://github.com/tinygo-org/renesas-svd lib/renesas-svd/ src/device/renesas/ + ./build/gen-device-svd -source=https://github.com/cmsis-svd/cmsis-svd-data/tree/master/data/Renesas lib/cmsis-svd/data/Renesas/ src/device/renesas/ GO111MODULE=off $(GO) fmt ./src/device/renesas $(LLVM_PROJECTDIR)/llvm: From c201faab92f70b05fecb406b69ec619d6f4dd9fc Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 16 Aug 2024 16:12:15 +0200 Subject: [PATCH 19/24] gitignore: ignore device files generated for Renesas Signed-off-by: deadprogram --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7c2f12b312..a2bc8dc444 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,8 @@ src/device/stm32/*.go src/device/stm32/*.s src/device/kendryte/*.go src/device/kendryte/*.s +src/device/renesas/*.go +src/device/renesas/*.s src/device/rp/*.go src/device/rp/*.s ./vendor From b5626e70cbe6e0cb6cba5a462f1f53f503d376fd Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 16 Aug 2024 16:16:53 +0200 Subject: [PATCH 20/24] submodules: remove separate renesas-svd repo in favor of more recent changes. Signed-off-by: deadprogram --- .gitmodules | 3 --- lib/renesas-svd | 1 - 2 files changed, 4 deletions(-) delete mode 160000 lib/renesas-svd diff --git a/.gitmodules b/.gitmodules index 4a8820e3a6..91bd14a7d7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -32,9 +32,6 @@ [submodule "lib/macos-minimal-sdk"] path = lib/macos-minimal-sdk url = https://github.com/aykevl/macos-minimal-sdk.git -[submodule "lib/renesas-svd"] - path = lib/renesas-svd - url = https://github.com/tinygo-org/renesas-svd.git [submodule "src/net"] path = src/net url = https://github.com/tinygo-org/net.git diff --git a/lib/renesas-svd b/lib/renesas-svd deleted file mode 160000 index 03d7688085..0000000000 --- a/lib/renesas-svd +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 03d76880854b9042f5d043f4355cdf8eef522fa5 From f9caa129089da265ce761e9c26a9dd5548f682c9 Mon Sep 17 00:00:00 2001 From: Roger Standridge <9526806+archie2x@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:06:11 -0700 Subject: [PATCH 21/24] Fix #4421: Add `-C DIR` flag Signed-off-by: Roger Standridge <9526806+archie2x@users.noreply.github.com> --- main.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/main.go b/main.go index 51e62aaaee..74db8785bd 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "regexp" "runtime" "runtime/pprof" + "slices" "sort" "strconv" "strings" @@ -1461,6 +1462,7 @@ func main() { // Early command processing, before commands are interpreted by the Go flag // library. + handleChdirFlag() switch command { case "clang", "ld.lld", "wasm-ld": err := builder.RunTool(command, os.Args[2:]...) @@ -1946,3 +1948,44 @@ type outputEntry struct { stderr bool data []byte } + +// handleChdirFlag handles the -C flag before doing anything else. +// The -C flag must be the first flag on the command line, to make it easy to find +// even with commands that have custom flag parsing. +// handleChdirFlag handles the flag by chdir'ing to the directory +// and then removing that flag from the command line entirely. +// +// We have to handle the -C flag this way for two reasons: +// +// 1. Toolchain selection needs to be in the right directory to look for go.mod and go.work. +// +// 2. A toolchain switch later on reinvokes the new go command with the same arguments. +// The parent toolchain has already done the chdir; the child must not try to do it again. +func handleChdirFlag() { + used := 2 // b.c. command at os.Args[1] + if used >= len(os.Args) { + return + } + + var dir string + switch a := os.Args[used]; { + default: + return + + case a == "-C", a == "--C": + if used+1 >= len(os.Args) { + return + } + dir = os.Args[used+1] + os.Args = slices.Delete(os.Args, used, used+2) + + case strings.HasPrefix(a, "-C="), strings.HasPrefix(a, "--C="): + _, dir, _ = strings.Cut(a, "=") + os.Args = slices.Delete(os.Args, used, used+1) + } + + if err := os.Chdir(dir); err != nil { + fmt.Fprintln(os.Stderr, "cannot chdir:", err) + os.Exit(1) + } +} From 628e10770588ebac872221ad2af214e3755ce911 Mon Sep 17 00:00:00 2001 From: Roger Standridge <9526806+archie2x@users.noreply.github.com> Date: Tue, 20 Aug 2024 10:19:23 -0700 Subject: [PATCH 22/24] Fix #4421 `-C DIR` support go1.19 Signed-off-by: Roger Standridge <9526806+archie2x@users.noreply.github.com> --- main.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 74db8785bd..227c869c94 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,6 @@ import ( "regexp" "runtime" "runtime/pprof" - "slices" "sort" "strconv" "strings" @@ -1961,6 +1960,7 @@ type outputEntry struct { // // 2. A toolchain switch later on reinvokes the new go command with the same arguments. // The parent toolchain has already done the chdir; the child must not try to do it again. + func handleChdirFlag() { used := 2 // b.c. command at os.Args[1] if used >= len(os.Args) { @@ -1977,11 +1977,11 @@ func handleChdirFlag() { return } dir = os.Args[used+1] - os.Args = slices.Delete(os.Args, used, used+2) + os.Args = slicesDelete(os.Args, used, used+2) case strings.HasPrefix(a, "-C="), strings.HasPrefix(a, "--C="): _, dir, _ = strings.Cut(a, "=") - os.Args = slices.Delete(os.Args, used, used+1) + os.Args = slicesDelete(os.Args, used, used+1) } if err := os.Chdir(dir); err != nil { @@ -1989,3 +1989,14 @@ func handleChdirFlag() { os.Exit(1) } } + +// go1.19 compatibility: lacks slices package +func slicesDelete[S ~[]E, E any](s S, i, j int) S { + _ = s[i:j:len(s)] // bounds check + + if i == j { + return s + } + + return append(s[:i], s[j:]...) +} From 9c88472d326b2d9e01a897bf48489c17f19b1af7 Mon Sep 17 00:00:00 2001 From: Roger Standridge <9526806+archie2x@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:27:55 -0700 Subject: [PATCH 23/24] Fix #4421 add tests for 'build' and 'run' ('test' already changes directory) Signed-off-by: Roger Standridge <9526806+archie2x@users.noreply.github.com> --- GNUmakefile | 11 ++++++++++- tests/testing/chdir/chdir.go | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/testing/chdir/chdir.go diff --git a/GNUmakefile b/GNUmakefile index 7333a6ebc9..70a7c5f589 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -483,8 +483,17 @@ tinygo-baremetal: # regression test for #2666: e.g. encoding/hex must pass on baremetal $(TINYGO) test -target cortex-m-qemu encoding/hex +.PHONY: testchdir +testchdir: + # test 'build' command with{,out} -C argument + $(TINYGO) build -C tests/testing/chdir chdir.go && rm tests/testing/chdir/chdir + $(TINYGO) build ./tests/testing/chdir/chdir.go && rm chdir + # test 'run' command with{,out} -C argument + EXPECT_DIR=$(PWD)/tests/testing/chdir $(TINYGO) run -C tests/testing/chdir chdir.go + EXPECT_DIR=$(PWD) $(TINYGO) run ./tests/testing/chdir/chdir.go + .PHONY: smoketest -smoketest: +smoketest: testchdir $(TINYGO) version $(TINYGO) targets > /dev/null # regression test for #2892 diff --git a/tests/testing/chdir/chdir.go b/tests/testing/chdir/chdir.go new file mode 100644 index 0000000000..9539738503 --- /dev/null +++ b/tests/testing/chdir/chdir.go @@ -0,0 +1,27 @@ +package main + +import ( + "log" + "os" + "runtime" + "strings" +) + +/* +Test that this program is 'run' in expected directory. 'run' with expected +working-directory in 'EXPECT_DIR' environment variable' with{,out} a -C +argument. +*/ +func main() { + expectDir := os.Getenv("EXPECT_DIR") + cwd, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + if runtime.GOOS == "windows" { + strings.Replace(cwd, "\\", "/", -1) + } + if cwd != expectDir { + log.Fatal("expected:\"%v\" != os.Getwd():\"%v\"", expectDir, cwd) + } +} From 21a6a9281453e838416487fdb68f07123973ece4 Mon Sep 17 00:00:00 2001 From: Roger Standridge <9526806+archie2x@users.noreply.github.com> Date: Wed, 11 Sep 2024 14:00:04 -0700 Subject: [PATCH 24/24] fix test --- tests/testing/chdir/chdir.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testing/chdir/chdir.go b/tests/testing/chdir/chdir.go index 9539738503..75281c21f0 100644 --- a/tests/testing/chdir/chdir.go +++ b/tests/testing/chdir/chdir.go @@ -3,8 +3,8 @@ package main import ( "log" "os" + "path/filepath" "runtime" - "strings" ) /* @@ -19,9 +19,9 @@ func main() { log.Fatal(err) } if runtime.GOOS == "windows" { - strings.Replace(cwd, "\\", "/", -1) + cwd = filepath.ToSlash(cwd) } if cwd != expectDir { - log.Fatal("expected:\"%v\" != os.Getwd():\"%v\"", expectDir, cwd) + log.Fatalf("expected:\"%v\" != os.Getwd():\"%v\"", expectDir, cwd) } }