From 1725623db22ce44bb4833f20c06c5effff25dd03 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 10 Aug 2023 22:36:35 +0200 Subject: [PATCH] wasm: add support for GOOS=wasip1 --- Makefile | 2 ++ builder/builder_test.go | 1 + compileopts/target.go | 31 +++++++++++++++++++++++- main_test.go | 1 + src/os/dir_unix.go | 2 +- src/os/dir_wasi.go | 2 +- src/os/exec_posix.go | 2 +- src/os/file_other.go | 2 +- src/os/file_unix.go | 2 +- src/os/types_unix.go | 2 +- src/runtime/os_wasip1.go | 8 ++++++ src/runtime/runtime_wasm_js_scheduler.go | 2 +- src/runtime/runtime_wasm_wasi.go | 2 +- src/syscall/errno_other.go | 2 +- src/syscall/proc_emulated.go | 2 +- src/syscall/proc_hosted.go | 2 +- src/syscall/syscall_libc.go | 2 +- src/syscall/syscall_libc_wasi.go | 2 +- 18 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 src/runtime/os_wasip1.go diff --git a/Makefile b/Makefile index 1bb84463b0..541c08b7f4 100644 --- a/Makefile +++ b/Makefile @@ -417,6 +417,8 @@ tinygo-bench-fast: # Same thing, except for wasi rather than the current platform. tinygo-test-wasi: $(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi +tinygo-test-wasip1: + GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi tinygo-test-wasi-fast: $(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) ./tests/runtime_wasi tinygo-bench-wasi: diff --git a/builder/builder_test.go b/builder/builder_test.go index f8bdd51341..03a33b9d49 100644 --- a/builder/builder_test.go +++ b/builder/builder_test.go @@ -60,6 +60,7 @@ func TestClangAttributes(t *testing.T) { {GOOS: "darwin", GOARCH: "arm64"}, {GOOS: "windows", GOARCH: "amd64"}, {GOOS: "windows", GOARCH: "arm64"}, + {GOOS: "wasip1", GOARCH: "wasm"}, } { name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH if options.GOARCH == "arm" { diff --git a/compileopts/target.go b/compileopts/target.go index 3040f9022f..b0608fce82 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -191,12 +191,15 @@ func LoadTarget(options *Options) (*TargetSpec, error) { default: return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM) } + case "wasm": + llvmarch = "wasm32" default: llvmarch = options.GOARCH } llvmvendor := "unknown" llvmos := options.GOOS - if llvmos == "darwin" { + switch llvmos { + case "darwin": // Use macosx* instead of darwin, otherwise darwin/arm64 will refer // to iOS! llvmos = "macosx10.12.0" @@ -207,6 +210,8 @@ func LoadTarget(options *Options) (*TargetSpec, error) { llvmos = "macosx11.0.0" } llvmvendor = "apple" + case "wasip1": + llvmos = "wasi" } // Target triples (which actually have four components, but are called // triples for historical reasons) have the form: @@ -277,6 +282,15 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { case "arm64": spec.CPU = "generic" spec.Features = "+neon" + case "wasm": + spec.CPU = "generic" + spec.Features = "+bulk-memory,+nontrapping-fptoint,+sign-ext" + spec.BuildTags = append(spec.BuildTags, "tinygo.wasm") + spec.CFlags = append(spec.CFlags, + "-mbulk-memory", + "-mnontrapping-fptoint", + "-msign-ext", + ) } if goos == "darwin" { spec.Linker = "ld.lld" @@ -320,6 +334,21 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { "--no-insert-timestamp", "--no-dynamicbase", ) + } else if goos == "wasip1" { + spec.Scheduler = "asyncify" + spec.Linker = "wasm-ld" + spec.RTLib = "compiler-rt" + spec.Libc = "wasi-libc" + spec.DefaultStackSize = 1024 * 16 // 16kB + spec.LDFlags = append(spec.LDFlags, + "--stack-first", + "--no-demangle", + ) + spec.Emulator = "wasmtime --mapdir=/tmp::{tmpDir} {}" + spec.ExtraFiles = append(spec.ExtraFiles, + "src/runtime/asm_tinygowasm.S", + "src/internal/task/task_asyncify_wasm.S", + ) } else { spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie } diff --git a/main_test.go b/main_test.go index 32d13f9103..72057941e4 100644 --- a/main_test.go +++ b/main_test.go @@ -34,6 +34,7 @@ var supportedLinuxArches = map[string]string{ "X86Linux": "linux/386", "ARMLinux": "linux/arm/6", "ARM64Linux": "linux/arm64", + "WASIp1": "wasip1/wasm", } var sema = make(chan struct{}, runtime.NumCPU()) diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go index f290ea38e7..baacdd68dc 100644 --- a/src/os/dir_unix.go +++ b/src/os/dir_unix.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 linux && !baremetal && !wasi +//go:build linux && !baremetal && !wasi && !wasip1 package os diff --git a/src/os/dir_wasi.go b/src/os/dir_wasi.go index 60a941f24f..23be3950ee 100644 --- a/src/os/dir_wasi.go +++ b/src/os/dir_wasi.go @@ -6,7 +6,7 @@ // fairly similar: we use fdopendir, fdclosedir, and readdir from wasi-libc in // a similar way that the darwin code uses functions from libc. -//go:build wasi +//go:build wasi || wasip1 package os diff --git a/src/os/exec_posix.go b/src/os/exec_posix.go index 151520cca7..3ccb6963bb 100644 --- a/src/os/exec_posix.go +++ b/src/os/exec_posix.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 aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || windows +//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || wasip1 || windows package os diff --git a/src/os/file_other.go b/src/os/file_other.go index 7e5833d353..d093e3d184 100644 --- a/src/os/file_other.go +++ b/src/os/file_other.go @@ -1,4 +1,4 @@ -//go:build baremetal || (wasm && !wasi) +//go:build baremetal || (wasm && !wasi && !wasip1) package os diff --git a/src/os/file_unix.go b/src/os/file_unix.go index 6314db8fae..665fb0937e 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -1,4 +1,4 @@ -//go:build darwin || (linux && !baremetal) +//go:build darwin || (linux && !baremetal) || wasip1 // target wasi sets GOOS=linux and thus the +linux build tag, // even though it doesn't show up in "tinygo info target -wasi" diff --git a/src/os/types_unix.go b/src/os/types_unix.go index 68a4e628ad..943fc00f52 100644 --- a/src/os/types_unix.go +++ b/src/os/types_unix.go @@ -1,4 +1,4 @@ -//go:build darwin || (linux && !baremetal) +//go:build darwin || (linux && !baremetal) || wasip1 // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/src/runtime/os_wasip1.go b/src/runtime/os_wasip1.go new file mode 100644 index 0000000000..52ee295e90 --- /dev/null +++ b/src/runtime/os_wasip1.go @@ -0,0 +1,8 @@ +package runtime + +// The actual GOOS=wasip1, as newly added in the Go 1.21 toolchain. +// Previously we supported -target=wasi, but that was essentially faked by using +// linux/arm instead because that was the closest thing that was already +// supported in the Go standard library. + +const GOOS = "wasip1" diff --git a/src/runtime/runtime_wasm_js_scheduler.go b/src/runtime/runtime_wasm_js_scheduler.go index 8f8823fef2..fc599a2a82 100644 --- a/src/runtime/runtime_wasm_js_scheduler.go +++ b/src/runtime/runtime_wasm_js_scheduler.go @@ -1,4 +1,4 @@ -//go:build wasm && !wasi && !scheduler.none +//go:build wasm && !wasi && !scheduler.none && !wasip1 package runtime diff --git a/src/runtime/runtime_wasm_wasi.go b/src/runtime/runtime_wasm_wasi.go index aec27e4c81..f258039ae6 100644 --- a/src/runtime/runtime_wasm_wasi.go +++ b/src/runtime/runtime_wasm_wasi.go @@ -1,4 +1,4 @@ -//go:build tinygo.wasm && wasi +//go:build tinygo.wasm && (wasi || wasip1) package runtime diff --git a/src/syscall/errno_other.go b/src/syscall/errno_other.go index 19822a1c6c..a001096525 100644 --- a/src/syscall/errno_other.go +++ b/src/syscall/errno_other.go @@ -1,4 +1,4 @@ -//go:build !wasi && !darwin +//go:build !wasi && !wasip1 && !darwin package syscall diff --git a/src/syscall/proc_emulated.go b/src/syscall/proc_emulated.go index 46570f5304..d8e7ff7a92 100644 --- a/src/syscall/proc_emulated.go +++ b/src/syscall/proc_emulated.go @@ -1,4 +1,4 @@ -//go:build baremetal || wasi || wasm +//go:build baremetal || tinygo.wasm // This file emulates some process-related functions that are only available // under a real operating system. diff --git a/src/syscall/proc_hosted.go b/src/syscall/proc_hosted.go index ab35762d06..05c509e6ff 100644 --- a/src/syscall/proc_hosted.go +++ b/src/syscall/proc_hosted.go @@ -1,4 +1,4 @@ -//go:build !baremetal && !wasi && !wasm +//go:build !baremetal && !tinygo.wasm // This file assumes there is a libc available that runs on a real operating // system. diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index ea0a000d18..7a13245b6d 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -1,4 +1,4 @@ -//go:build darwin || nintendoswitch || wasi +//go:build darwin || nintendoswitch || wasi || wasip1 package syscall diff --git a/src/syscall/syscall_libc_wasi.go b/src/syscall/syscall_libc_wasi.go index a3bd3a4872..5e6a231dff 100644 --- a/src/syscall/syscall_libc_wasi.go +++ b/src/syscall/syscall_libc_wasi.go @@ -1,4 +1,4 @@ -//go:build wasi +//go:build wasi || wasip1 package syscall