mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 14:48:40 +00:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a76ceb7dd | |||
| 69263e7319 | |||
| 9a6397b325 | |||
| b8420e78bb | |||
| f0d523f778 | |||
| 6e6507bf77 | |||
| b8fe75a9dd | |||
| 0f95b4102d | |||
| 24c11d4ba5 | |||
| 3dcac3b539 | |||
| e615c25319 | |||
| b2fbbeb771 | |||
| bcfe751f62 | |||
| a191326ea8 | |||
| 23d3a31107 | |||
| 0dfa57ea04 | |||
| 2f9e39e21c | |||
| cd2bb8333d | |||
| 5e3c816373 | |||
| 951e50c06f | |||
| 40c9c66c1d | |||
| 01dac8ba8e | |||
| ac5f84e3d7 | |||
| 9583439be4 | |||
| 2690b243ea | |||
| df724f5827 | |||
| 539cc5c47b | |||
| 45cc5b58cd | |||
| c6acaa981d | |||
| 4ef5109a07 | |||
| 6016d0c739 | |||
| 07d23c9d83 | |||
| d5f195387d | |||
| a0d4ecb607 | |||
| 505e68057d | |||
| 87c6e19921 | |||
| 62c1555aa8 | |||
| e62fc43b05 | |||
| 158be02ef7 | |||
| fbb125131d | |||
| c77ed8e50e | |||
| d1b7238a36 | |||
| 453a1d35c3 | |||
| 9da8b5c786 | |||
| 407889864f | |||
| e17daf165d | |||
| 666d2bd501 | |||
| 9d14489547 | |||
| f3dfe1d49e | |||
| b3e1974c30 | |||
| fa12450552 | |||
| b3c040e9f7 | |||
| 52788e5826 | |||
| bcd4c6b658 | |||
| 37460ad60a | |||
| dcca47f1f6 | |||
| 892efaec97 | |||
| 84048f299f | |||
| a9bf981d92 | |||
| d4729f92bd | |||
| 5a014dd6a3 | |||
| d948941d82 | |||
| 5abf1e998d |
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
open_collective: tinygo
|
||||
@@ -16,11 +16,11 @@ jobs:
|
||||
name: build-macos
|
||||
strategy:
|
||||
matrix:
|
||||
# macos-12: amd64 (oldest supported version as of 05-02-2024)
|
||||
# macos-13: amd64 (oldest supported version as of 18-10-2024)
|
||||
# macos-14: arm64 (oldest arm64 version)
|
||||
os: [macos-12, macos-14]
|
||||
os: [macos-13, macos-14]
|
||||
include:
|
||||
- os: macos-12
|
||||
- os: macos-13
|
||||
goarch: amd64
|
||||
- os: macos-14
|
||||
goarch: arm64
|
||||
|
||||
@@ -15,6 +15,11 @@ jobs:
|
||||
nix-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Uninstall system LLVM
|
||||
# Hack to work around issue where we still include system headers for
|
||||
# some reason.
|
||||
# See: https://github.com/tinygo-org/tinygo/pull/4516#issuecomment-2416363668
|
||||
run: sudo apt-get remove llvm-18
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Pull musl
|
||||
|
||||
@@ -1,3 +1,53 @@
|
||||
0.34.0
|
||||
---
|
||||
* **general**
|
||||
- fix `GOOS=wasip1` for `tinygo test`
|
||||
- add `-C DIR` flag
|
||||
- add initial documentation for project governance
|
||||
- add `-ldflags='-extldflags=...'` support
|
||||
- improve usage message with `tinygo help` and when passing invalid parameters
|
||||
* **compiler**
|
||||
- `builder`: remove environment variables when invoking Clang, to avoid the environment changing the behavior
|
||||
- `builder`: check for the Go toolchain version used to compile TinyGo
|
||||
- `cgo`: add `C.CBytes` implementation
|
||||
- `compiler`: fix passing weirdly-padded structs as parameters to new goroutines
|
||||
- `compiler`: support pragmas on generic functions
|
||||
- `compiler`: do not let the slice buffer escape when casting a `[]byte` or `[]rune` to a string, to help escape analysis
|
||||
- `compiler`: conform to the latest iteration of the wasm types proposal
|
||||
- `loader`: don't panic when main package is not named 'main'
|
||||
- `loader`: make sure we always return type checker errors even without type errors
|
||||
- `transform`: optimize range over `[]byte(string)`
|
||||
* **standard library**
|
||||
- `crypto/x509`: add package stub to build crypto/x509 on macOS
|
||||
- `machine/usb/adc/midi`: fix `PitchBend`
|
||||
- `os`: add `Truncate` stub for baremetal
|
||||
- `os`: add stubs for `os.File` deadlines
|
||||
- `os`: add internal `net.newUnixFile` for the net package
|
||||
- `runtime`: stub runtime_{Before,After}Exec for linkage
|
||||
- `runtime`: randomize map accesses
|
||||
- `runtime`: support `maps.Clone`
|
||||
- `runtime`: add more fields to `MemStats`
|
||||
- `runtime`: implement newcoro, coroswitch to support package iter
|
||||
- `runtime`: disallow defer in interrupts
|
||||
- `runtime`: add support for os/signal on Linux and MacOS
|
||||
- `runtime`: add gc layout info for some basic types to help the precise GC
|
||||
- `runtime`: bump GC mark stack size to avoid excessive heap rescans
|
||||
* **targets**
|
||||
- `darwin`: use Go standard library syscall package instead of a custom one
|
||||
- `fe310`: support GPIO `PinInput`
|
||||
- `mips`: fix compiler crash with GOMIPS=softfloat and defer
|
||||
- `mips`: add big-endian (GOARCH=mips) support
|
||||
- `mips`: use MIPS32 (instead of MIPS32R2) as the instruction set for wider compatibility
|
||||
- `wasi`: add relative and absolute --dir options to wasmtime args
|
||||
- `wasip2`: add wasmtime -S args to support network interfaces
|
||||
- `wasm`: add `//go:wasmexport` support (for all WebAssembly targets)
|
||||
- `wasm`: use precise instead of conservative GC for WebAssembly (including WASI)
|
||||
- `wasm-unknown`: add bulk memory flags since basically every runtime has it now
|
||||
* **boards**
|
||||
- add RAKwireless RAK4631
|
||||
- add WaveShare ESP-C3-32S-Kit
|
||||
|
||||
|
||||
0.33.0
|
||||
---
|
||||
|
||||
|
||||
+39
-2
@@ -293,7 +293,7 @@ tinygo: ## Build the TinyGo compiler
|
||||
@if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " $(MAKE) llvm-source"; echo " $(MAKE) $(LLVM_BUILDDIR)"; exit 1; fi
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOENVFLAGS) $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags "byollvm osusergo" -ldflags="-X github.com/tinygo-org/tinygo/goenv.GitSha1=`git rev-parse --short HEAD`" .
|
||||
test: wasi-libc check-nodejs-version
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags "byollvm osusergo" $(GOTESTPKGS)
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags "byollvm osusergo" $(GOTESTPKGS)
|
||||
|
||||
# Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi
|
||||
TEST_PACKAGES_SLOW = \
|
||||
@@ -303,26 +303,34 @@ TEST_PACKAGES_SLOW = \
|
||||
|
||||
# Standard library packages that pass tests quickly on darwin, linux, wasi, and windows
|
||||
TEST_PACKAGES_FAST = \
|
||||
cmp \
|
||||
compress/lzw \
|
||||
compress/zlib \
|
||||
container/heap \
|
||||
container/list \
|
||||
container/ring \
|
||||
crypto/des \
|
||||
crypto/ecdsa \
|
||||
crypto/elliptic \
|
||||
crypto/md5 \
|
||||
crypto/rc4 \
|
||||
crypto/sha1 \
|
||||
crypto/sha256 \
|
||||
crypto/sha512 \
|
||||
database/sql/driver \
|
||||
debug/macho \
|
||||
embed/internal/embedtest \
|
||||
encoding \
|
||||
encoding/ascii85 \
|
||||
encoding/asn1 \
|
||||
encoding/base32 \
|
||||
encoding/base64 \
|
||||
encoding/csv \
|
||||
encoding/hex \
|
||||
go/ast \
|
||||
go/format \
|
||||
go/scanner \
|
||||
go/version \
|
||||
hash \
|
||||
hash/adler32 \
|
||||
hash/crc64 \
|
||||
@@ -357,11 +365,17 @@ endif
|
||||
# archive/zip requires os.ReadAt, which is not yet supported on windows
|
||||
# bytes requires mmap
|
||||
# compress/flate appears to hang on wasi
|
||||
# crypto/aes fails on wasi, needs panic()/recover()
|
||||
# crypto/hmac fails on wasi, it exits with a "slice out of range" panic
|
||||
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows
|
||||
# image requires recover(), which is not yet supported on wasi
|
||||
# io/ioutil requires os.ReadDir, which is not yet supported on windows or wasi
|
||||
# mime: fail on wasi; neds panic()/recover()
|
||||
# mime/multipart: needs wasip1 syscall.FDFLAG_NONBLOCK
|
||||
# mime/quotedprintable requires syscall.Faccessat
|
||||
# net/mail: needs wasip1 syscall.FDFLAG_NONBLOCK
|
||||
# net/ntextproto: needs wasip1 syscall.FDFLAG_NONBLOCK
|
||||
# regexp/syntax: fails on wasip1; needs panic()/recover()
|
||||
# strconv requires recover() which is not yet supported on wasi
|
||||
# text/tabwriter requires recover(), which is not yet supported on wasi
|
||||
# text/template/parse requires recover(), which is not yet supported on wasi
|
||||
@@ -371,14 +385,20 @@ endif
|
||||
TEST_PACKAGES_LINUX := \
|
||||
archive/zip \
|
||||
compress/flate \
|
||||
crypto/aes \
|
||||
crypto/hmac \
|
||||
debug/dwarf \
|
||||
debug/plan9obj \
|
||||
image \
|
||||
io/ioutil \
|
||||
mime \
|
||||
mime/multipart \
|
||||
mime/quotedprintable \
|
||||
net \
|
||||
net/mail \
|
||||
net/textproto \
|
||||
os/user \
|
||||
regexp/syntax \
|
||||
strconv \
|
||||
text/tabwriter \
|
||||
text/template/parse
|
||||
@@ -483,8 +503,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
|
||||
@@ -806,12 +835,20 @@ ifneq ($(XTENSA), 0)
|
||||
$(TINYGO) build -size short -o test.bin -target mch2022 examples/machinetest
|
||||
@$(MD5SUM) test.bin
|
||||
endif
|
||||
$(TINYGO) build -size short -o test.bin -target=esp-c3-32s-kit examples/blinky1
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target=qtpy-esp32c3 examples/machinetest
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target=m5stamp-c3 examples/machinetest
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target=xiao-esp32c3 examples/machinetest
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target=esp32-c3-devkit-rust-1 examples/blinky1
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target=esp32c3-12f examples/blinky1
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target=makerfabs-esp32c3spi35 examples/machinetest
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.hex -target=hifive1b examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=maixbit examples/blinky1
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
TinyGo Team Members
|
||||
===================
|
||||
|
||||
The team of humans who maintain TinyGo.
|
||||
|
||||
* **Purpose**: To maintain the community, code, documentation, and tools for the TinyGo compiler.
|
||||
* **Board**: The group of people who share responsibility for key decisions for the TinyGo organization.
|
||||
* **Majority Voting**: The board makes decisions by majority vote.
|
||||
* **Membership**: The board elects its own members.
|
||||
* **Do-ocracy**: Those who step forward to do a given task propose how it should be done. Then other interested people can make comments.
|
||||
* **Proof of Work**: Power in decision-making is slightly weighted based on a participant's labor for the community.
|
||||
* **Initiation**: We need to establish a procedure for how people join the team of maintainers.
|
||||
* **Transparency**: Important information should be made publicly available, ideally in a way that allows for public comment.
|
||||
* **Code of Conduct**: Participants agree to abide by the current project Code of Conduct.
|
||||
|
||||
## Members
|
||||
|
||||
* Ayke van Laethem (@aykevl)
|
||||
* Daniel Esteban (@conejoninja)
|
||||
* Ron Evans (@deadprogram)
|
||||
* Damian Gryski (@dgryski)
|
||||
* Masaaki Takasago (@sago35)
|
||||
* Patricio Whittingslow (@soypat)
|
||||
* Yurii Soldak (@ysoldak)
|
||||
|
||||
## Experimental
|
||||
|
||||
* **Monthly Meeting**: A monthly meeting for the team and any other interested participants.
|
||||
Duration: 1 hour
|
||||
Facilitation: @deadprogram
|
||||
Schedule: See https://github.com/tinygo-org/tinygo/wiki/Meetings for more information
|
||||
|
||||
+22
-16
@@ -197,6 +197,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
ABI: config.ABI(),
|
||||
GOOS: config.GOOS(),
|
||||
GOARCH: config.GOARCH(),
|
||||
BuildMode: config.BuildMode(),
|
||||
CodeModel: config.CodeModel(),
|
||||
RelocationModel: config.RelocationModel(),
|
||||
SizeLevel: sizeLevel,
|
||||
@@ -649,6 +650,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
result.Binary = result.Executable // final file
|
||||
ldflags := append(config.LDFlags(), "-o", result.Executable)
|
||||
|
||||
if config.Options.BuildMode == "c-shared" {
|
||||
if !strings.HasPrefix(config.Triple(), "wasm32-") {
|
||||
return result, fmt.Errorf("buildmode c-shared is only supported on wasm at the moment")
|
||||
}
|
||||
ldflags = append(ldflags, "--no-entry")
|
||||
}
|
||||
|
||||
// Add compiler-rt dependency if needed. Usually this is a simple load from
|
||||
// a cache.
|
||||
if config.Target.RTLib == "compiler-rt" {
|
||||
@@ -823,19 +831,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
args = append(args, "--asyncify")
|
||||
}
|
||||
|
||||
exeunopt := result.Executable
|
||||
|
||||
if config.Options.Work {
|
||||
// Keep the work direction around => don't overwrite the .wasm binary with the optimized version
|
||||
exeunopt += ".pre-wasm-opt"
|
||||
os.Rename(result.Executable, exeunopt)
|
||||
}
|
||||
|
||||
inputFile := result.Binary
|
||||
result.Binary = result.Executable + ".wasmopt"
|
||||
args = append(args,
|
||||
opt,
|
||||
"-g",
|
||||
exeunopt,
|
||||
"--output", result.Executable,
|
||||
inputFile,
|
||||
"--output", result.Binary,
|
||||
)
|
||||
|
||||
wasmopt := goenv.Get("WASMOPT")
|
||||
@@ -865,13 +867,15 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
|
||||
// wasm-tools component embed -w wasi:cli/command
|
||||
// $$(tinygo env TINYGOROOT)/lib/wasi-cli/wit/ main.wasm -o embedded.wasm
|
||||
componentEmbedInputFile := result.Binary
|
||||
result.Binary = result.Executable + ".wasm-component-embed"
|
||||
args := []string{
|
||||
"component",
|
||||
"embed",
|
||||
"-w", witWorld,
|
||||
witPackage,
|
||||
result.Executable,
|
||||
"-o", result.Executable,
|
||||
componentEmbedInputFile,
|
||||
"-o", result.Binary,
|
||||
}
|
||||
|
||||
wasmtools := goenv.Get("WASMTOOLS")
|
||||
@@ -884,15 +888,17 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("wasm-tools failed: %w", err)
|
||||
return fmt.Errorf("`wasm-tools component embed` failed: %w", err)
|
||||
}
|
||||
|
||||
// wasm-tools component new embedded.wasm -o component.wasm
|
||||
componentNewInputFile := result.Binary
|
||||
result.Binary = result.Executable + ".wasm-component-new"
|
||||
args = []string{
|
||||
"component",
|
||||
"new",
|
||||
result.Executable,
|
||||
"-o", result.Executable,
|
||||
componentNewInputFile,
|
||||
"-o", result.Binary,
|
||||
}
|
||||
|
||||
if config.Options.PrintCommands != nil {
|
||||
@@ -904,7 +910,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("wasm-tools failed: %w", err)
|
||||
return fmt.Errorf("`wasm-tools component new` failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package builder
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -76,14 +75,3 @@ func LookupCommand(name string) (string, error) {
|
||||
}
|
||||
return "", errors.New("none of these commands were found in your $PATH: " + strings.Join(commands[name], " "))
|
||||
}
|
||||
|
||||
func execCommand(name string, args ...string) error {
|
||||
name, err := LookupCommand(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command(name, args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
+22
-4
@@ -2,6 +2,7 @@ package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
@@ -23,20 +24,37 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
||||
spec.OpenOCDCommands = options.OpenOCDCommands
|
||||
}
|
||||
|
||||
major, minor, err := goenv.GetGorootVersion()
|
||||
// Version range supported by TinyGo.
|
||||
const minorMin = 19
|
||||
const minorMax = 23
|
||||
|
||||
// Check that we support this Go toolchain version.
|
||||
gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if major != 1 || minor < 19 || minor > 23 {
|
||||
if gorootMajor != 1 || gorootMinor < minorMin || gorootMinor > minorMax {
|
||||
// Note: when this gets updated, also update the Go compatibility matrix:
|
||||
// https://github.com/tinygo-org/tinygo-site/blob/dev/content/docs/reference/go-compat-matrix.md
|
||||
return nil, fmt.Errorf("requires go version 1.19 through 1.23, got go%d.%d", major, minor)
|
||||
return nil, fmt.Errorf("requires go version 1.19 through 1.23, got go%d.%d", gorootMajor, gorootMinor)
|
||||
}
|
||||
|
||||
// Check that the Go toolchain version isn't too new, if we haven't been
|
||||
// compiled with the latest Go version.
|
||||
// This may be a bit too aggressive: if the newer version doesn't change the
|
||||
// Go language we will most likely be able to compile it.
|
||||
buildMajor, buildMinor, _, err := goenv.Parse(runtime.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buildMajor != 1 || buildMinor < gorootMinor {
|
||||
return nil, fmt.Errorf("cannot compile with Go toolchain version go%d.%d (TinyGo was built using toolchain version %s)", gorootMajor, gorootMinor, runtime.Version())
|
||||
}
|
||||
|
||||
return &compileopts.Config{
|
||||
Options: options,
|
||||
Target: spec,
|
||||
GoMinorVersion: minor,
|
||||
GoMinorVersion: gorootMinor,
|
||||
TestConfig: options.TestConfig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
+6
-16
@@ -17,14 +17,6 @@ import (
|
||||
// concurrency or performance issues.
|
||||
const jobRunnerDebug = false
|
||||
|
||||
type jobState uint8
|
||||
|
||||
const (
|
||||
jobStateQueued jobState = iota // not yet running
|
||||
jobStateRunning // running
|
||||
jobStateFinished // finished running
|
||||
)
|
||||
|
||||
// compileJob is a single compiler job, comparable to a single Makefile target.
|
||||
// It is used to orchestrate various compiler tasks that can be run in parallel
|
||||
// but that have dependencies and thus have limitations in how they can be run.
|
||||
@@ -55,12 +47,11 @@ func dummyCompileJob(result string) *compileJob {
|
||||
// ordered as such in the job dependencies.
|
||||
func runJobs(job *compileJob, sema chan struct{}) error {
|
||||
if sema == nil {
|
||||
// Have a default, if the semaphore isn't set. This is useful for
|
||||
// tests.
|
||||
// Have a default, if the semaphore isn't set. This is useful for tests.
|
||||
sema = make(chan struct{}, runtime.NumCPU())
|
||||
}
|
||||
if cap(sema) == 0 {
|
||||
return errors.New("cannot 0 jobs at a time")
|
||||
return errors.New("cannot run 0 jobs at a time")
|
||||
}
|
||||
|
||||
// Create a slice of jobs to run, where all dependencies are run in order.
|
||||
@@ -81,10 +72,10 @@ func runJobs(job *compileJob, sema chan struct{}) error {
|
||||
|
||||
waiting := make(map[*compileJob]map[*compileJob]struct{}, len(jobs))
|
||||
dependents := make(map[*compileJob][]*compileJob, len(jobs))
|
||||
jidx := make(map[*compileJob]int)
|
||||
compileJobs := make(map[*compileJob]int)
|
||||
var ready intHeap
|
||||
for i, job := range jobs {
|
||||
jidx[job] = i
|
||||
compileJobs[job] = i
|
||||
if len(job.dependencies) == 0 {
|
||||
// This job is ready to run.
|
||||
ready.Push(i)
|
||||
@@ -105,8 +96,7 @@ func runJobs(job *compileJob, sema chan struct{}) error {
|
||||
// Create a channel to accept notifications of completion.
|
||||
doneChan := make(chan *compileJob)
|
||||
|
||||
// Send each job in the jobs slice to a worker, taking care of job
|
||||
// dependencies.
|
||||
// Send each job in the jobs slice to a worker, taking care of job dependencies.
|
||||
numRunningJobs := 0
|
||||
var totalTime time.Duration
|
||||
start := time.Now()
|
||||
@@ -156,7 +146,7 @@ func runJobs(job *compileJob, sema chan struct{}) error {
|
||||
delete(wait, completed)
|
||||
if len(wait) == 0 {
|
||||
// This job is now ready to run.
|
||||
ready.Push(jidx[j])
|
||||
ready.Push(compileJobs[j])
|
||||
delete(waiting, j)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ var libMusl = Library{
|
||||
"mman/*.c",
|
||||
"math/*.c",
|
||||
"multibyte/*.c",
|
||||
"signal/" + arch + "/*.s",
|
||||
"signal/*.c",
|
||||
"stdio/*.c",
|
||||
"string/*.c",
|
||||
|
||||
@@ -41,9 +41,9 @@ func TestBinarySize(t *testing.T) {
|
||||
// This is a small number of very diverse targets that we want to test.
|
||||
tests := []sizeTest{
|
||||
// microcontrollers
|
||||
{"hifive1b", "examples/echo", 4484, 280, 0, 2252},
|
||||
{"microbit", "examples/serial", 2732, 388, 8, 2256},
|
||||
{"wioterminal", "examples/pininterrupt", 6016, 1484, 116, 6816},
|
||||
{"hifive1b", "examples/echo", 4568, 280, 0, 2268},
|
||||
{"microbit", "examples/serial", 2868, 388, 8, 2272},
|
||||
{"wioterminal", "examples/pininterrupt", 6104, 1484, 116, 6832},
|
||||
|
||||
// TODO: also check wasm. Right now this is difficult, because
|
||||
// wasm binaries are run through wasm-opt and therefore the
|
||||
|
||||
+19
-6
@@ -14,16 +14,29 @@ import (
|
||||
|
||||
// runCCompiler invokes a C compiler with the given arguments.
|
||||
func runCCompiler(flags ...string) error {
|
||||
// Find the right command to run Clang.
|
||||
var cmd *exec.Cmd
|
||||
if hasBuiltinTools {
|
||||
// Compile this with the internal Clang compiler.
|
||||
cmd := exec.Command(os.Args[0], append([]string{"clang"}, flags...)...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
cmd = exec.Command(os.Args[0], append([]string{"clang"}, flags...)...)
|
||||
} else {
|
||||
// Compile this with an external invocation of the Clang compiler.
|
||||
name, err := LookupCommand("clang")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd = exec.Command(name, flags...)
|
||||
}
|
||||
|
||||
// Compile this with an external invocation of the Clang compiler.
|
||||
return execCommand("clang", flags...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
// Make sure the command doesn't use any environmental variables.
|
||||
// Most importantly, it should not use C_INCLUDE_PATH and the like. But
|
||||
// removing all environmental variables also works.
|
||||
cmd.Env = []string{}
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// link invokes a linker with the given name and flags.
|
||||
|
||||
+8
-1
@@ -162,6 +162,13 @@ func __GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
func GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func __CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
`
|
||||
|
||||
// Process extracts `import "C"` statements from the AST, parses the comment
|
||||
@@ -218,7 +225,7 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
|
||||
switch decl := decl.(type) {
|
||||
case *ast.FuncDecl:
|
||||
switch decl.Name.Name {
|
||||
case "CString", "GoString", "GoStringN", "__GoStringN", "GoBytes", "__GoBytes":
|
||||
case "CString", "GoString", "GoStringN", "__GoStringN", "GoBytes", "__GoBytes", "CBytes", "__CBytes":
|
||||
// Adjust the name to have a "C." prefix so it is correctly
|
||||
// resolved.
|
||||
decl.Name.Name = "C." + decl.Name.Name
|
||||
|
||||
Vendored
+7
@@ -24,6 +24,13 @@ func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
type (
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
|
||||
Vendored
+7
@@ -24,6 +24,13 @@ func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
type (
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
|
||||
Vendored
+7
@@ -44,6 +44,13 @@ func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
type (
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
|
||||
Vendored
+7
@@ -29,6 +29,13 @@ func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
type (
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
|
||||
Vendored
+7
@@ -24,6 +24,13 @@ func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
type (
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
|
||||
Vendored
+7
@@ -24,6 +24,13 @@ func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
type (
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
|
||||
@@ -33,6 +33,17 @@ func (c *Config) CPU() string {
|
||||
return c.Target.CPU
|
||||
}
|
||||
|
||||
// The current build mode (like the `-buildmode` command line flag).
|
||||
func (c *Config) BuildMode() string {
|
||||
if c.Options.BuildMode != "" {
|
||||
return c.Options.BuildMode
|
||||
}
|
||||
if c.Target.BuildMode != "" {
|
||||
return c.Target.BuildMode
|
||||
}
|
||||
return "default"
|
||||
}
|
||||
|
||||
// Features returns a list of features this CPU supports. For example, for a
|
||||
// RISC-V processor, that could be "+a,+c,+m". For many targets, an empty list
|
||||
// will be returned.
|
||||
@@ -395,6 +406,16 @@ func (c *Config) LDFlags() []string {
|
||||
if c.Target.LinkerScript != "" {
|
||||
ldflags = append(ldflags, "-T", c.Target.LinkerScript)
|
||||
}
|
||||
|
||||
if c.Options.ExtLDFlags != "" {
|
||||
ext, err := shlex.Split(c.Options.ExtLDFlags)
|
||||
if err != nil {
|
||||
// if shlex can't split it, pass it as-is and let the external linker complain
|
||||
ext = []string{c.Options.ExtLDFlags}
|
||||
}
|
||||
ldflags = append(ldflags, ext...)
|
||||
}
|
||||
|
||||
return ldflags
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
validBuildModeOptions = []string{"default", "c-shared"}
|
||||
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
|
||||
validSchedulerOptions = []string{"none", "tasks", "asyncify"}
|
||||
validSerialOptions = []string{"none", "uart", "usb", "rtt"}
|
||||
@@ -26,6 +27,7 @@ type Options struct {
|
||||
GOMIPS string // environment variable (only used with GOARCH=mips and GOARCH=mipsle)
|
||||
Directory string // working dir, leave it unset to use the current working dir
|
||||
Target string
|
||||
BuildMode string // -buildmode flag
|
||||
Opt string
|
||||
GC string
|
||||
PanicStrategy string
|
||||
@@ -56,10 +58,19 @@ type Options struct {
|
||||
Timeout time.Duration
|
||||
WITPackage string // pass through to wasm-tools component embed invocation
|
||||
WITWorld string // pass through to wasm-tools component embed -w option
|
||||
ExtLDFlags string
|
||||
}
|
||||
|
||||
// Verify performs a validation on the given options, raising an error if options are not valid.
|
||||
func (o *Options) Verify() error {
|
||||
if o.BuildMode != "" {
|
||||
valid := isInArray(validBuildModeOptions, o.BuildMode)
|
||||
if !valid {
|
||||
return fmt.Errorf(`invalid buildmode option '%s': valid values are %s`,
|
||||
o.BuildMode,
|
||||
strings.Join(validBuildModeOptions, ", "))
|
||||
}
|
||||
}
|
||||
if o.GC != "" {
|
||||
valid := isInArray(validGCOptions, o.GC)
|
||||
if !valid {
|
||||
|
||||
@@ -32,6 +32,7 @@ type TargetSpec struct {
|
||||
GOARCH string `json:"goarch,omitempty"`
|
||||
SoftFloat bool // used for non-baremetal systems (GOMIPS=softfloat etc)
|
||||
BuildTags []string `json:"build-tags,omitempty"`
|
||||
BuildMode string `json:"buildmode,omitempty"` // default build mode (if nothing specified)
|
||||
GC string `json:"gc,omitempty"`
|
||||
Scheduler string `json:"scheduler,omitempty"`
|
||||
Serial string `json:"serial,omitempty"` // which serial output to use (uart, usb, none)
|
||||
@@ -390,7 +391,8 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
)
|
||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||
"src/runtime/os_darwin.c",
|
||||
"src/runtime/runtime_unix.c")
|
||||
"src/runtime/runtime_unix.c",
|
||||
"src/runtime/signal.c")
|
||||
case "linux":
|
||||
spec.Linker = "ld.lld"
|
||||
spec.RTLib = "compiler-rt"
|
||||
@@ -411,7 +413,8 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
spec.CFlags = append(spec.CFlags, "-mno-outline-atomics")
|
||||
}
|
||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||
"src/runtime/runtime_unix.c")
|
||||
"src/runtime/runtime_unix.c",
|
||||
"src/runtime/signal.c")
|
||||
case "windows":
|
||||
spec.Linker = "ld.lld"
|
||||
spec.Libc = "mingw-w64"
|
||||
|
||||
@@ -44,6 +44,7 @@ type Config struct {
|
||||
ABI string
|
||||
GOOS string
|
||||
GOARCH string
|
||||
BuildMode string
|
||||
CodeModel string
|
||||
RelocationModel string
|
||||
SizeLevel int
|
||||
@@ -1384,6 +1385,11 @@ func (b *builder) createFunction() {
|
||||
b.llvmFn.SetLinkage(llvm.InternalLinkage)
|
||||
b.createFunction()
|
||||
}
|
||||
|
||||
// Create wrapper function that can be called externally.
|
||||
if b.info.wasmExport != "" {
|
||||
b.createWasmExport()
|
||||
}
|
||||
}
|
||||
|
||||
// posser is an interface that's implemented by both ssa.Value and
|
||||
|
||||
+253
-20
@@ -7,6 +7,7 @@ import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||
"golang.org/x/tools/go/ssa"
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
@@ -101,7 +102,7 @@ func (b *builder) createGo(instr *ssa.Go) {
|
||||
|
||||
paramBundle := b.emitPointerPack(params)
|
||||
var stackSize llvm.Value
|
||||
callee := b.createGoroutineStartWrapper(funcType, funcPtr, prefix, hasContext, instr.Pos())
|
||||
callee := b.createGoroutineStartWrapper(funcType, funcPtr, prefix, hasContext, false, instr.Pos())
|
||||
if b.AutomaticStackSize {
|
||||
// The stack size is not known until after linking. Call a dummy
|
||||
// function that will be replaced with a load from a special ELF
|
||||
@@ -121,6 +122,147 @@ func (b *builder) createGo(instr *ssa.Go) {
|
||||
b.createCall(fnType, start, []llvm.Value{callee, paramBundle, stackSize, llvm.Undef(b.dataPtrType)}, "")
|
||||
}
|
||||
|
||||
// Create an exported wrapper function for functions with the //go:wasmexport
|
||||
// pragma. This wrapper function is quite complex when the scheduler is enabled:
|
||||
// it needs to start a new goroutine each time the exported function is called.
|
||||
func (b *builder) createWasmExport() {
|
||||
pos := b.info.wasmExportPos
|
||||
if b.info.exported {
|
||||
// //export really shouldn't be used anymore when //go:wasmexport is
|
||||
// available, because //go:wasmexport is much better defined.
|
||||
b.addError(pos, "cannot use //export and //go:wasmexport at the same time")
|
||||
return
|
||||
}
|
||||
|
||||
const suffix = "#wasmexport"
|
||||
|
||||
// Declare the exported function.
|
||||
paramTypes := b.llvmFnType.ParamTypes()
|
||||
exportedFnType := llvm.FunctionType(b.llvmFnType.ReturnType(), paramTypes[:len(paramTypes)-1], false)
|
||||
exportedFn := llvm.AddFunction(b.mod, b.fn.RelString(nil)+suffix, exportedFnType)
|
||||
b.addStandardAttributes(exportedFn)
|
||||
llvmutil.AppendToGlobal(b.mod, "llvm.used", exportedFn)
|
||||
exportedFn.AddFunctionAttr(b.ctx.CreateStringAttribute("wasm-export-name", b.info.wasmExport))
|
||||
|
||||
// Create a builder for this wrapper function.
|
||||
builder := newBuilder(b.compilerContext, b.ctx.NewBuilder(), b.fn)
|
||||
defer builder.Dispose()
|
||||
|
||||
// Define this function as a separate function in DWARF
|
||||
if b.Debug {
|
||||
if b.fn.Syntax() != nil {
|
||||
// Create debug info file if needed.
|
||||
pos := b.program.Fset.Position(pos)
|
||||
builder.difunc = builder.attachDebugInfoRaw(b.fn, exportedFn, suffix, pos.Filename, pos.Line)
|
||||
}
|
||||
builder.setDebugLocation(pos)
|
||||
}
|
||||
|
||||
// Create a single basic block inside of it.
|
||||
bb := llvm.AddBasicBlock(exportedFn, "entry")
|
||||
builder.SetInsertPointAtEnd(bb)
|
||||
|
||||
// Insert an assertion to make sure this //go:wasmexport function is not
|
||||
// called at a time when it is not allowed (for example, before the runtime
|
||||
// is initialized).
|
||||
builder.createRuntimeCall("wasmExportCheckRun", nil, "")
|
||||
|
||||
if b.Scheduler == "none" {
|
||||
// When the scheduler has been disabled, this is really trivial: just
|
||||
// call the function.
|
||||
params := exportedFn.Params()
|
||||
params = append(params, llvm.ConstNull(b.dataPtrType)) // context parameter
|
||||
retval := builder.CreateCall(b.llvmFnType, b.llvmFn, params, "")
|
||||
if b.fn.Signature.Results() == nil {
|
||||
builder.CreateRetVoid()
|
||||
} else {
|
||||
builder.CreateRet(retval)
|
||||
}
|
||||
|
||||
} else {
|
||||
// The scheduler is enabled, so we need to start a new goroutine, wait
|
||||
// for it to complete, and read the result value.
|
||||
|
||||
// Build a function that looks like this:
|
||||
//
|
||||
// func foo#wasmexport(param0, param1, ..., paramN) {
|
||||
// var state *stateStruct
|
||||
//
|
||||
// // 'done' must be explicitly initialized ('state' is not zeroed)
|
||||
// state.done = false
|
||||
//
|
||||
// // store the parameters in the state object
|
||||
// state.param0 = param0
|
||||
// state.param1 = param1
|
||||
// ...
|
||||
// state.paramN = paramN
|
||||
//
|
||||
// // create a goroutine and push it to the runqueue
|
||||
// task.start(uintptr(gowrapper), &state)
|
||||
//
|
||||
// // run the scheduler
|
||||
// runtime.wasmExportRun(&state.done)
|
||||
//
|
||||
// // if there is a return value, load it and return
|
||||
// return state.result
|
||||
// }
|
||||
|
||||
hasReturn := b.fn.Signature.Results() != nil
|
||||
|
||||
// Build the state struct type.
|
||||
// It stores the function parameters, the 'done' flag, and reserves
|
||||
// space for a return value if needed.
|
||||
stateFields := exportedFnType.ParamTypes()
|
||||
numParams := len(stateFields)
|
||||
stateFields = append(stateFields, b.ctx.Int1Type()) // 'done' field
|
||||
if hasReturn {
|
||||
stateFields = append(stateFields, b.llvmFnType.ReturnType())
|
||||
}
|
||||
stateStruct := b.ctx.StructType(stateFields, false)
|
||||
|
||||
// Allocate the state struct on the stack.
|
||||
statePtr := builder.CreateAlloca(stateStruct, "status")
|
||||
|
||||
// Initialize the 'done' field.
|
||||
doneGEP := builder.CreateInBoundsGEP(stateStruct, statePtr, []llvm.Value{
|
||||
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(b.ctx.Int32Type(), uint64(numParams), false),
|
||||
}, "done.gep")
|
||||
builder.CreateStore(llvm.ConstNull(b.ctx.Int1Type()), doneGEP)
|
||||
|
||||
// Store all parameters in the state object.
|
||||
for i, param := range exportedFn.Params() {
|
||||
gep := builder.CreateInBoundsGEP(stateStruct, statePtr, []llvm.Value{
|
||||
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false),
|
||||
}, "")
|
||||
builder.CreateStore(param, gep)
|
||||
}
|
||||
|
||||
// Create a new goroutine and add it to the runqueue.
|
||||
wrapper := b.createGoroutineStartWrapper(b.llvmFnType, b.llvmFn, "", false, true, pos)
|
||||
stackSize := llvm.ConstInt(b.uintptrType, b.DefaultStackSize, false)
|
||||
taskStartFnType, taskStartFn := builder.getFunction(b.program.ImportedPackage("internal/task").Members["start"].(*ssa.Function))
|
||||
builder.createCall(taskStartFnType, taskStartFn, []llvm.Value{wrapper, statePtr, stackSize, llvm.Undef(b.dataPtrType)}, "")
|
||||
|
||||
// Run the scheduler.
|
||||
builder.createRuntimeCall("wasmExportRun", []llvm.Value{doneGEP}, "")
|
||||
|
||||
// Read the return value (if any) and return to the caller of the
|
||||
// //go:wasmexport function.
|
||||
if hasReturn {
|
||||
gep := builder.CreateInBoundsGEP(stateStruct, statePtr, []llvm.Value{
|
||||
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(b.ctx.Int32Type(), uint64(numParams)+1, false),
|
||||
}, "")
|
||||
retval := builder.CreateLoad(b.llvmFnType.ReturnType(), gep, "retval")
|
||||
builder.CreateRet(retval)
|
||||
} else {
|
||||
builder.CreateRetVoid()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// createGoroutineStartWrapper creates a wrapper for the task-based
|
||||
// implementation of goroutines. For example, to call a function like this:
|
||||
//
|
||||
@@ -144,7 +286,7 @@ func (b *builder) createGo(instr *ssa.Go) {
|
||||
// to last parameter of the function) is used for this wrapper. If hasContext is
|
||||
// false, the parameter bundle is assumed to have no context parameter and undef
|
||||
// is passed instead.
|
||||
func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.Value, prefix string, hasContext bool, pos token.Pos) llvm.Value {
|
||||
func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.Value, prefix string, hasContext, isWasmExport bool, pos token.Pos) llvm.Value {
|
||||
var wrapper llvm.Value
|
||||
|
||||
b := &builder{
|
||||
@@ -162,14 +304,18 @@ func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.
|
||||
if !fn.IsAFunction().IsNil() {
|
||||
// See whether this wrapper has already been created. If so, return it.
|
||||
name := fn.Name()
|
||||
wrapper = c.mod.NamedFunction(name + "$gowrapper")
|
||||
wrapperName := name + "$gowrapper"
|
||||
if isWasmExport {
|
||||
wrapperName += "-wasmexport"
|
||||
}
|
||||
wrapper = c.mod.NamedFunction(wrapperName)
|
||||
if !wrapper.IsNil() {
|
||||
return llvm.ConstPtrToInt(wrapper, c.uintptrType)
|
||||
}
|
||||
|
||||
// Create the wrapper.
|
||||
wrapperType := llvm.FunctionType(c.ctx.VoidType(), []llvm.Type{c.dataPtrType}, false)
|
||||
wrapper = llvm.AddFunction(c.mod, name+"$gowrapper", wrapperType)
|
||||
wrapper = llvm.AddFunction(c.mod, wrapperName, wrapperType)
|
||||
c.addStandardAttributes(wrapper)
|
||||
wrapper.SetLinkage(llvm.LinkOnceODRLinkage)
|
||||
wrapper.SetUnnamedAddr(true)
|
||||
@@ -199,23 +345,110 @@ func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.
|
||||
b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{})
|
||||
}
|
||||
|
||||
// Create the list of params for the call.
|
||||
paramTypes := fnType.ParamTypes()
|
||||
if !hasContext {
|
||||
paramTypes = paramTypes[:len(paramTypes)-1] // strip context parameter
|
||||
}
|
||||
params := b.emitPointerUnpack(wrapper.Param(0), paramTypes)
|
||||
if !hasContext {
|
||||
params = append(params, llvm.Undef(c.dataPtrType)) // add dummy context parameter
|
||||
}
|
||||
if !isWasmExport {
|
||||
// Regular 'go' instruction.
|
||||
|
||||
// Create the call.
|
||||
b.CreateCall(fnType, fn, params, "")
|
||||
// Create the list of params for the call.
|
||||
paramTypes := fnType.ParamTypes()
|
||||
if !hasContext {
|
||||
paramTypes = paramTypes[:len(paramTypes)-1] // strip context parameter
|
||||
}
|
||||
|
||||
if c.Scheduler == "asyncify" {
|
||||
b.CreateCall(deadlockType, deadlock, []llvm.Value{
|
||||
llvm.Undef(c.dataPtrType),
|
||||
}, "")
|
||||
params := b.emitPointerUnpack(wrapper.Param(0), paramTypes)
|
||||
if !hasContext {
|
||||
params = append(params, llvm.Undef(c.dataPtrType)) // add dummy context parameter
|
||||
}
|
||||
|
||||
// Create the call.
|
||||
b.CreateCall(fnType, fn, params, "")
|
||||
|
||||
if c.Scheduler == "asyncify" {
|
||||
b.CreateCall(deadlockType, deadlock, []llvm.Value{
|
||||
llvm.Undef(c.dataPtrType),
|
||||
}, "")
|
||||
}
|
||||
} else {
|
||||
// Goroutine started from a //go:wasmexport pragma.
|
||||
// The function looks like this:
|
||||
//
|
||||
// func foo$gowrapper-wasmexport(state *stateStruct) {
|
||||
// // load values
|
||||
// param0 := state.params[0]
|
||||
// param1 := state.params[1]
|
||||
//
|
||||
// // call wrapped functions
|
||||
// result := foo(param0, param1, ...)
|
||||
//
|
||||
// // store result value (if there is any)
|
||||
// state.result = result
|
||||
//
|
||||
// // finish exported function
|
||||
// state.done = true
|
||||
// runtime.wasmExportExit()
|
||||
// }
|
||||
//
|
||||
// The state object here looks like:
|
||||
//
|
||||
// struct state {
|
||||
// param0
|
||||
// param1
|
||||
// param* // etc
|
||||
// done bool
|
||||
// result returnType
|
||||
// }
|
||||
|
||||
returnType := fnType.ReturnType()
|
||||
hasReturn := returnType != b.ctx.VoidType()
|
||||
statePtr := wrapper.Param(0)
|
||||
|
||||
// Create the state struct (it must match the type in createWasmExport).
|
||||
stateFields := fnType.ParamTypes()
|
||||
numParams := len(stateFields) - 1
|
||||
stateFields = stateFields[:numParams:numParams] // strip 'context' parameter
|
||||
stateFields = append(stateFields, c.ctx.Int1Type()) // 'done' bool
|
||||
if hasReturn {
|
||||
stateFields = append(stateFields, returnType)
|
||||
}
|
||||
stateStruct := b.ctx.StructType(stateFields, false)
|
||||
|
||||
// Extract parameters from the state object, and call the function
|
||||
// that's being wrapped.
|
||||
var callParams []llvm.Value
|
||||
for i := 0; i < numParams; i++ {
|
||||
gep := b.CreateInBoundsGEP(stateStruct, statePtr, []llvm.Value{
|
||||
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false),
|
||||
}, "")
|
||||
param := b.CreateLoad(stateFields[i], gep, "")
|
||||
callParams = append(callParams, param)
|
||||
}
|
||||
callParams = append(callParams, llvm.ConstNull(c.dataPtrType)) // add 'context' parameter
|
||||
result := b.CreateCall(fnType, fn, callParams, "")
|
||||
|
||||
// Store the return value back into the shared state.
|
||||
// Unlike regular goroutines, these special //go:wasmexport
|
||||
// goroutines can return a value.
|
||||
if hasReturn {
|
||||
gep := b.CreateInBoundsGEP(stateStruct, statePtr, []llvm.Value{
|
||||
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(c.ctx.Int32Type(), uint64(numParams)+1, false),
|
||||
}, "result.ptr")
|
||||
b.CreateStore(result, gep)
|
||||
}
|
||||
|
||||
// Mark this function as having finished executing.
|
||||
// This is important so the runtime knows the exported function
|
||||
// didn't block.
|
||||
doneGEP := b.CreateInBoundsGEP(stateStruct, statePtr, []llvm.Value{
|
||||
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
|
||||
llvm.ConstInt(c.ctx.Int32Type(), uint64(numParams), false),
|
||||
}, "done.gep")
|
||||
b.CreateStore(llvm.ConstInt(b.ctx.Int1Type(), 1, false), doneGEP)
|
||||
|
||||
// Call back into the runtime. This will exit the goroutine, switch
|
||||
// back to the scheduler, which will in turn return from the
|
||||
// //go:wasmexport function.
|
||||
b.createRuntimeCall("wasmExportExit", nil, "")
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -297,5 +530,5 @@ func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.
|
||||
}
|
||||
|
||||
// Return a ptrtoint of the wrapper, not the function itself.
|
||||
return b.CreatePtrToInt(wrapper, c.uintptrType, "")
|
||||
return llvm.ConstPtrToInt(wrapper, c.uintptrType)
|
||||
}
|
||||
|
||||
+182
-103
@@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
"github.com/tinygo-org/tinygo/loader"
|
||||
"golang.org/x/tools/go/ssa"
|
||||
"tinygo.org/x/go-llvm"
|
||||
@@ -23,15 +24,17 @@ import (
|
||||
// The linkName value contains a valid link name, even if //go:linkname is not
|
||||
// present.
|
||||
type functionInfo struct {
|
||||
wasmModule string // go:wasm-module
|
||||
wasmName string // wasm-export-name or wasm-import-name in the IR
|
||||
linkName string // go:linkname, go:export - the IR function name
|
||||
section string // go:section - object file section name
|
||||
exported bool // go:export, CGo
|
||||
interrupt bool // go:interrupt
|
||||
nobounds bool // go:nobounds
|
||||
variadic bool // go:variadic (CGo only)
|
||||
inline inlineType // go:inline
|
||||
wasmModule string // go:wasm-module
|
||||
wasmName string // wasm-export-name or wasm-import-name in the IR
|
||||
wasmExport string // go:wasmexport is defined (export is unset, this adds an exported wrapper)
|
||||
wasmExportPos token.Pos // position of //go:wasmexport comment
|
||||
linkName string // go:linkname, go:export - the IR function name
|
||||
section string // go:section - object file section name
|
||||
exported bool // go:export, CGo
|
||||
interrupt bool // go:interrupt
|
||||
nobounds bool // go:nobounds
|
||||
variadic bool // go:variadic (CGo only)
|
||||
inline inlineType // go:inline
|
||||
}
|
||||
|
||||
type inlineType int
|
||||
@@ -170,6 +173,12 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
case "runtime.stringFromBytes":
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
case "runtime.stringFromRunes":
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
case "runtime.trackPointer":
|
||||
// This function is necessary for tracking pointers on the stack in a
|
||||
// portable way (see gc_stack_portable.go). Indicate to the optimizer
|
||||
@@ -241,8 +250,22 @@ func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo {
|
||||
// Pick the default linkName.
|
||||
linkName: f.RelString(nil),
|
||||
}
|
||||
|
||||
// Check for a few runtime functions that are treated specially.
|
||||
if info.linkName == "runtime.wasmEntryReactor" && c.BuildMode == "c-shared" {
|
||||
info.linkName = "_initialize"
|
||||
info.wasmName = "_initialize"
|
||||
info.exported = true
|
||||
}
|
||||
if info.linkName == "runtime.wasmEntryCommand" && c.BuildMode == "default" {
|
||||
info.linkName = "_start"
|
||||
info.wasmName = "_start"
|
||||
info.exported = true
|
||||
}
|
||||
|
||||
// Check for //go: pragmas, which may change the link name (among others).
|
||||
c.parsePragmas(&info, f)
|
||||
|
||||
c.functionInfos[f] = info
|
||||
return info
|
||||
}
|
||||
@@ -250,126 +273,164 @@ func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo {
|
||||
// parsePragmas is used by getFunctionInfo to parse function pragmas such as
|
||||
// //export or //go:noinline.
|
||||
func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
|
||||
if f.Syntax() == nil {
|
||||
syntax := f.Syntax()
|
||||
if f.Origin() != nil {
|
||||
syntax = f.Origin().Syntax()
|
||||
}
|
||||
if syntax == nil {
|
||||
return
|
||||
}
|
||||
if decl, ok := f.Syntax().(*ast.FuncDecl); ok && decl.Doc != nil {
|
||||
|
||||
// Read all pragmas of this function.
|
||||
var pragmas []*ast.Comment
|
||||
hasWasmExport := false
|
||||
if decl, ok := syntax.(*ast.FuncDecl); ok && decl.Doc != nil {
|
||||
for _, comment := range decl.Doc.List {
|
||||
text := comment.Text
|
||||
if strings.HasPrefix(text, "//export ") {
|
||||
// Rewrite '//export' to '//go:export' for compatibility with
|
||||
// gc.
|
||||
text = "//go:" + text[2:]
|
||||
if strings.HasPrefix(text, "//go:") || strings.HasPrefix(text, "//export ") {
|
||||
pragmas = append(pragmas, comment)
|
||||
if strings.HasPrefix(comment.Text, "//go:wasmexport ") {
|
||||
hasWasmExport = true
|
||||
}
|
||||
}
|
||||
if !strings.HasPrefix(text, "//go:") {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse each pragma.
|
||||
for _, comment := range pragmas {
|
||||
parts := strings.Fields(comment.Text)
|
||||
switch parts[0] {
|
||||
case "//export", "//go:export":
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
if hasWasmExport {
|
||||
// //go:wasmexport overrides //export.
|
||||
continue
|
||||
}
|
||||
parts := strings.Fields(text)
|
||||
switch parts[0] {
|
||||
case "//go:export":
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
info.linkName = parts[1]
|
||||
info.wasmName = info.linkName
|
||||
info.exported = true
|
||||
case "//go:interrupt":
|
||||
if hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.interrupt = true
|
||||
}
|
||||
case "//go:wasm-module":
|
||||
// Alternative comment for setting the import module.
|
||||
// This is deprecated, use //go:wasmimport instead.
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
info.wasmModule = parts[1]
|
||||
case "//go:wasmimport":
|
||||
// Import a WebAssembly function, for example a WASI function.
|
||||
// Original proposal: https://github.com/golang/go/issues/38248
|
||||
// Allow globally: https://github.com/golang/go/issues/59149
|
||||
if len(parts) != 3 {
|
||||
continue
|
||||
}
|
||||
c.checkWasmImport(f, comment.Text)
|
||||
info.exported = true
|
||||
info.wasmModule = parts[1]
|
||||
info.wasmName = parts[2]
|
||||
case "//go:inline":
|
||||
info.inline = inlineHint
|
||||
case "//go:noinline":
|
||||
info.linkName = parts[1]
|
||||
info.wasmName = info.linkName
|
||||
info.exported = true
|
||||
case "//go:interrupt":
|
||||
if hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.interrupt = true
|
||||
}
|
||||
case "//go:wasm-module":
|
||||
// Alternative comment for setting the import module.
|
||||
// This is deprecated, use //go:wasmimport instead.
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
info.wasmModule = parts[1]
|
||||
case "//go:wasmimport":
|
||||
// Import a WebAssembly function, for example a WASI function.
|
||||
// Original proposal: https://github.com/golang/go/issues/38248
|
||||
// Allow globally: https://github.com/golang/go/issues/59149
|
||||
if len(parts) != 3 {
|
||||
continue
|
||||
}
|
||||
if f.Blocks != nil {
|
||||
// Defined functions cannot be exported.
|
||||
c.addError(f.Pos(), "can only use //go:wasmimport on declarations")
|
||||
continue
|
||||
}
|
||||
c.checkWasmImportExport(f, comment.Text)
|
||||
info.exported = true
|
||||
info.wasmModule = parts[1]
|
||||
info.wasmName = parts[2]
|
||||
case "//go:wasmexport":
|
||||
if f.Blocks == nil {
|
||||
c.addError(f.Pos(), "can only use //go:wasmexport on definitions")
|
||||
continue
|
||||
}
|
||||
if len(parts) != 2 {
|
||||
c.addError(f.Pos(), fmt.Sprintf("expected one parameter to //go:wasmimport, not %d", len(parts)-1))
|
||||
continue
|
||||
}
|
||||
name := parts[1]
|
||||
if name == "_start" || name == "_initialize" {
|
||||
c.addError(f.Pos(), fmt.Sprintf("//go:wasmexport does not allow %#v", name))
|
||||
continue
|
||||
}
|
||||
if c.BuildMode != "c-shared" && f.RelString(nil) == "main.main" {
|
||||
c.addError(f.Pos(), fmt.Sprintf("//go:wasmexport does not allow main.main to be exported with -buildmode=%s", c.BuildMode))
|
||||
continue
|
||||
}
|
||||
if c.archFamily() != "wasm32" {
|
||||
c.addError(f.Pos(), "//go:wasmexport is only supported on wasm")
|
||||
}
|
||||
c.checkWasmImportExport(f, comment.Text)
|
||||
info.wasmExport = name
|
||||
info.wasmExportPos = comment.Slash
|
||||
case "//go:inline":
|
||||
info.inline = inlineHint
|
||||
case "//go:noinline":
|
||||
info.inline = inlineNone
|
||||
case "//go:linkname":
|
||||
if len(parts) != 3 || parts[1] != f.Name() {
|
||||
continue
|
||||
}
|
||||
// Only enable go:linkname when the package imports "unsafe".
|
||||
// This is a slightly looser requirement than what gc uses: gc
|
||||
// requires the file to import "unsafe", not the package as a
|
||||
// whole.
|
||||
if hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.linkName = parts[2]
|
||||
}
|
||||
case "//go:section":
|
||||
// Only enable go:section when the package imports "unsafe".
|
||||
// go:section also implies go:noinline since inlining could
|
||||
// move the code to a different section than that requested.
|
||||
if len(parts) == 2 && hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.section = parts[1]
|
||||
info.inline = inlineNone
|
||||
case "//go:linkname":
|
||||
if len(parts) != 3 || parts[1] != f.Name() {
|
||||
continue
|
||||
}
|
||||
// Only enable go:linkname when the package imports "unsafe".
|
||||
// This is a slightly looser requirement than what gc uses: gc
|
||||
// requires the file to import "unsafe", not the package as a
|
||||
// whole.
|
||||
if hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.linkName = parts[2]
|
||||
}
|
||||
case "//go:section":
|
||||
// Only enable go:section when the package imports "unsafe".
|
||||
// go:section also implies go:noinline since inlining could
|
||||
// move the code to a different section than that requested.
|
||||
if len(parts) == 2 && hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.section = parts[1]
|
||||
info.inline = inlineNone
|
||||
}
|
||||
case "//go:nobounds":
|
||||
// Skip bounds checking in this function. Useful for some
|
||||
// runtime functions.
|
||||
// This is somewhat dangerous and thus only imported in packages
|
||||
// that import unsafe.
|
||||
if hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.nobounds = true
|
||||
}
|
||||
case "//go:variadic":
|
||||
// The //go:variadic pragma is emitted by the CGo preprocessing
|
||||
// pass for C variadic functions. This includes both explicit
|
||||
// (with ...) and implicit (no parameters in signature)
|
||||
// functions.
|
||||
if strings.HasPrefix(f.Name(), "C.") {
|
||||
// This prefix cannot naturally be created, it must have
|
||||
// been created as a result of CGo preprocessing.
|
||||
info.variadic = true
|
||||
}
|
||||
}
|
||||
case "//go:nobounds":
|
||||
// Skip bounds checking in this function. Useful for some
|
||||
// runtime functions.
|
||||
// This is somewhat dangerous and thus only imported in packages
|
||||
// that import unsafe.
|
||||
if hasUnsafeImport(f.Pkg.Pkg) {
|
||||
info.nobounds = true
|
||||
}
|
||||
case "//go:variadic":
|
||||
// The //go:variadic pragma is emitted by the CGo preprocessing
|
||||
// pass for C variadic functions. This includes both explicit
|
||||
// (with ...) and implicit (no parameters in signature)
|
||||
// functions.
|
||||
if strings.HasPrefix(f.Name(), "C.") {
|
||||
// This prefix cannot naturally be created, it must have
|
||||
// been created as a result of CGo preprocessing.
|
||||
info.variadic = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether this function cannot be used in //go:wasmimport. It will add an
|
||||
// error if this is the case.
|
||||
// Check whether this function can be used in //go:wasmimport or
|
||||
// //go:wasmexport. It will add an error if this is not the case.
|
||||
//
|
||||
// The list of allowed types is based on this proposal:
|
||||
// https://github.com/golang/go/issues/59149
|
||||
func (c *compilerContext) checkWasmImport(f *ssa.Function, pragma string) {
|
||||
func (c *compilerContext) checkWasmImportExport(f *ssa.Function, pragma string) {
|
||||
if c.pkg.Path() == "runtime" || c.pkg.Path() == "syscall/js" || c.pkg.Path() == "syscall" {
|
||||
// The runtime is a special case. Allow all kinds of parameters
|
||||
// (importantly, including pointers).
|
||||
return
|
||||
}
|
||||
if f.Blocks != nil {
|
||||
// Defined functions cannot be exported.
|
||||
c.addError(f.Pos(), "can only use //go:wasmimport on declarations")
|
||||
return
|
||||
}
|
||||
if f.Signature.Results().Len() > 1 {
|
||||
c.addError(f.Signature.Results().At(1).Pos(), fmt.Sprintf("%s: too many return values", pragma))
|
||||
} else if f.Signature.Results().Len() == 1 {
|
||||
result := f.Signature.Results().At(0)
|
||||
if !isValidWasmType(result.Type(), siteResult) {
|
||||
if !c.isValidWasmType(result.Type(), siteResult) {
|
||||
c.addError(result.Pos(), fmt.Sprintf("%s: unsupported result type %s", pragma, result.Type().String()))
|
||||
}
|
||||
}
|
||||
for _, param := range f.Params {
|
||||
// Check whether the type is allowed.
|
||||
// Only a very limited number of types can be mapped to WebAssembly.
|
||||
if !isValidWasmType(param.Type(), siteParam) {
|
||||
if !c.isValidWasmType(param.Type(), siteParam) {
|
||||
c.addError(param.Pos(), fmt.Sprintf("%s: unsupported parameter type %s", pragma, param.Type().String()))
|
||||
}
|
||||
}
|
||||
@@ -382,13 +443,15 @@ func (c *compilerContext) checkWasmImport(f *ssa.Function, pragma string) {
|
||||
//
|
||||
// This previously reflected the additional restrictions documented here:
|
||||
// https://github.com/golang/go/issues/59149
|
||||
func isValidWasmType(typ types.Type, site wasmSite) bool {
|
||||
func (c *compilerContext) isValidWasmType(typ types.Type, site wasmSite) bool {
|
||||
switch typ := typ.Underlying().(type) {
|
||||
case *types.Basic:
|
||||
switch typ.Kind() {
|
||||
case types.Bool:
|
||||
return true
|
||||
case types.Int, types.Uint, types.Int8, types.Uint8, types.Int16, types.Uint16, types.Int32, types.Uint32, types.Int64, types.Uint64:
|
||||
case types.Int8, types.Uint8, types.Int16, types.Uint16:
|
||||
return site == siteIndirect
|
||||
case types.Int32, types.Uint32, types.Int64, types.Uint64:
|
||||
return true
|
||||
case types.Float32, types.Float64:
|
||||
return true
|
||||
@@ -399,19 +462,35 @@ func isValidWasmType(typ types.Type, site wasmSite) bool {
|
||||
return site == siteParam || site == siteIndirect
|
||||
}
|
||||
case *types.Array:
|
||||
return site == siteIndirect && isValidWasmType(typ.Elem(), siteIndirect)
|
||||
return site == siteIndirect && c.isValidWasmType(typ.Elem(), siteIndirect)
|
||||
case *types.Struct:
|
||||
if site != siteIndirect {
|
||||
return false
|
||||
}
|
||||
// Structs with no fields do not need structs.HostLayout
|
||||
if typ.NumFields() == 0 {
|
||||
return true
|
||||
}
|
||||
hasHostLayout := true // default to true before detecting Go version
|
||||
// (*types.Package).GoVersion added in go1.21
|
||||
if gv, ok := any(c.pkg).(interface{ GoVersion() string }); ok {
|
||||
if goenv.Compare(gv.GoVersion(), "go1.23") >= 0 {
|
||||
hasHostLayout = false // package structs added in go1.23
|
||||
}
|
||||
}
|
||||
for i := 0; i < typ.NumFields(); i++ {
|
||||
if !isValidWasmType(typ.Field(i).Type(), siteIndirect) {
|
||||
ftyp := typ.Field(i).Type()
|
||||
if ftyp.String() == "structs.HostLayout" {
|
||||
hasHostLayout = true
|
||||
continue
|
||||
}
|
||||
if !c.isValidWasmType(ftyp, siteIndirect) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
return hasHostLayout
|
||||
case *types.Pointer:
|
||||
return isValidWasmType(typ.Elem(), siteIndirect)
|
||||
return c.isValidWasmType(typ.Elem(), siteIndirect)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Vendored
+37
-7
@@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"structs"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:wasmimport modulename empty
|
||||
func empty()
|
||||
@@ -14,31 +17,37 @@ func implementation() {
|
||||
type Uint uint32
|
||||
|
||||
type S struct {
|
||||
_ structs.HostLayout
|
||||
a [4]uint32
|
||||
b uintptr
|
||||
c int
|
||||
d float32
|
||||
e float64
|
||||
}
|
||||
|
||||
//go:wasmimport modulename validparam
|
||||
func validparam(a int32, b uint64, c float64, d unsafe.Pointer, e Uint, f uintptr, g string, h *int32, i *S)
|
||||
func validparam(a int32, b uint64, c float64, d unsafe.Pointer, e Uint, f uintptr, g string, h *int32, i *S, j *struct{}, k *[8]uint8)
|
||||
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type [4]uint32
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type []byte
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type struct{a int}
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type chan struct{}
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type func()
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type int
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type uint
|
||||
// ERROR: //go:wasmimport modulename invalidparam: unsupported parameter type [8]int
|
||||
//
|
||||
//go:wasmimport modulename invalidparam
|
||||
func invalidparam(a [4]uint32, b []byte, c struct{ a int }, d chan struct{}, e func())
|
||||
func invalidparam(a [4]uint32, b []byte, c struct{ a int }, d chan struct{}, e func(), f int, g uint, h [8]int)
|
||||
|
||||
// ERROR: //go:wasmimport modulename invalidparam_no_hostlayout: unsupported parameter type *struct{int}
|
||||
// ERROR: //go:wasmimport modulename invalidparam_no_hostlayout: unsupported parameter type *struct{string}
|
||||
//
|
||||
//go:wasmimport modulename invalidparam_no_hostlayout
|
||||
func invalidparam_no_hostlayout(a *struct{ int }, b *struct{ string })
|
||||
|
||||
//go:wasmimport modulename validreturn_int32
|
||||
func validreturn_int32() int32
|
||||
|
||||
//go:wasmimport modulename validreturn_int
|
||||
func validreturn_int() int
|
||||
|
||||
//go:wasmimport modulename validreturn_ptr_int32
|
||||
func validreturn_ptr_int32() *int32
|
||||
|
||||
@@ -48,6 +57,12 @@ func validreturn_ptr_string() *string
|
||||
//go:wasmimport modulename validreturn_ptr_struct
|
||||
func validreturn_ptr_struct() *S
|
||||
|
||||
//go:wasmimport modulename validreturn_ptr_struct
|
||||
func validreturn_ptr_empty_struct() *struct{}
|
||||
|
||||
//go:wasmimport modulename validreturn_ptr_array
|
||||
func validreturn_ptr_array() *[8]uint8
|
||||
|
||||
//go:wasmimport modulename validreturn_unsafe_pointer
|
||||
func validreturn_unsafe_pointer() unsafe.Pointer
|
||||
|
||||
@@ -56,11 +71,26 @@ func validreturn_unsafe_pointer() unsafe.Pointer
|
||||
//go:wasmimport modulename manyreturns
|
||||
func manyreturns() (int32, int32)
|
||||
|
||||
// ERROR: //go:wasmimport modulename invalidreturn_int: unsupported result type int
|
||||
//
|
||||
//go:wasmimport modulename invalidreturn_int
|
||||
func invalidreturn_int() int
|
||||
|
||||
// ERROR: //go:wasmimport modulename invalidreturn_int: unsupported result type uint
|
||||
//
|
||||
//go:wasmimport modulename invalidreturn_int
|
||||
func invalidreturn_uint() uint
|
||||
|
||||
// ERROR: //go:wasmimport modulename invalidreturn_func: unsupported result type func()
|
||||
//
|
||||
//go:wasmimport modulename invalidreturn_func
|
||||
func invalidreturn_func() func()
|
||||
|
||||
// ERROR: //go:wasmimport modulename invalidreturn_pointer_array_int: unsupported result type *[8]int
|
||||
//
|
||||
//go:wasmimport modulename invalidreturn_pointer_array_int
|
||||
func invalidreturn_pointer_array_int() *[8]int
|
||||
|
||||
// ERROR: //go:wasmimport modulename invalidreturn_slice_byte: unsupported result type []byte
|
||||
//
|
||||
//go:wasmimport modulename invalidreturn_slice_byte
|
||||
|
||||
Vendored
+16
@@ -48,6 +48,22 @@ func inlineFunc() {
|
||||
func noinlineFunc() {
|
||||
}
|
||||
|
||||
type Int interface {
|
||||
int8 | int16
|
||||
}
|
||||
|
||||
// Same for generic functions (but the compiler may miss the pragma due to it
|
||||
// being generic).
|
||||
//
|
||||
//go:noinline
|
||||
func noinlineGenericFunc[T Int]() {
|
||||
}
|
||||
|
||||
func useGeneric() {
|
||||
// Make sure the generic function above is instantiated.
|
||||
noinlineGenericFunc[int8]()
|
||||
}
|
||||
|
||||
// This function should have the specified section.
|
||||
//
|
||||
//go:section .special_function_section
|
||||
|
||||
Vendored
+13
@@ -48,6 +48,19 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.useGeneric(ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
call void @"main.noinlineGenericFunc[int8]"(ptr undef)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define linkonce_odr hidden void @"main.noinlineGenericFunc[int8]"(ptr %context) unnamed_addr #5 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define hidden void @main.functionInSection(ptr %context) unnamed_addr #5 section ".special_function_section" {
|
||||
entry:
|
||||
|
||||
@@ -24,6 +24,8 @@ func TestErrors(t *testing.T) {
|
||||
{name: "cgo"},
|
||||
{name: "compiler"},
|
||||
{name: "interp"},
|
||||
{name: "invalidmain"},
|
||||
{name: "invalidname"},
|
||||
{name: "linker-flashoverflow", target: "cortex-m-qemu"},
|
||||
{name: "linker-ramoverflow", target: "cortex-m-qemu"},
|
||||
{name: "linker-undefined", target: "darwin/arm64"},
|
||||
|
||||
Generated
+4
-4
@@ -20,16 +20,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1703068421,
|
||||
"narHash": "sha256-WSw5Faqlw75McIflnl5v7qVD/B3S2sLh+968bpOGrWA=",
|
||||
"lastModified": 1728500571,
|
||||
"narHash": "sha256-dOymOQ3AfNI4Z337yEwHGohrVQb4yPODCW9MDUyAc4w=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d65bceaee0fb1e64363f7871bc43dc1c6ecad99f",
|
||||
"rev": "d51c28603def282a24fa034bcb007e2bcb5b5dd0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-23.11",
|
||||
"ref": "nixos-24.05",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
inputs = {
|
||||
# Use a recent stable release, but fix the version to make it reproducible.
|
||||
# This version should be updated from time to time.
|
||||
nixpkgs.url = "nixpkgs/nixos-23.11";
|
||||
nixpkgs.url = "nixpkgs/nixos-24.05";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
@@ -49,11 +49,11 @@
|
||||
buildInputs = [
|
||||
# These dependencies are required for building tinygo (go install).
|
||||
go
|
||||
llvmPackages_17.llvm
|
||||
llvmPackages_17.libclang
|
||||
llvmPackages_18.llvm
|
||||
llvmPackages_18.libclang
|
||||
# Additional dependencies needed at runtime, for building and/or
|
||||
# flashing.
|
||||
llvmPackages_17.lld
|
||||
llvmPackages_18.lld
|
||||
avrdude
|
||||
binaryen
|
||||
# Additional dependencies needed for on-chip debugging.
|
||||
@@ -68,7 +68,7 @@
|
||||
# Without setting these explicitly, Homebrew versions might be used
|
||||
# or the default `ar` and `nm` tools might be used (which don't
|
||||
# support wasi).
|
||||
export CLANG="clang-17 -resource-dir ${llvmPackages_17.clang.cc.lib}/lib/clang/17"
|
||||
export CLANG="clang-18 -resource-dir ${llvmPackages_18.clang.cc.lib}/lib/clang/18"
|
||||
export LLVM_AR=llvm-ar
|
||||
export LLVM_NM=llvm-nm
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
export MD5SUM=md5sum
|
||||
|
||||
# Ugly hack to make the Clang resources directory available.
|
||||
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_17.clang.cc.lib}/lib/clang/17\" -tags=llvm17"
|
||||
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_18.clang.cc.lib}/lib/clang/18\" -tags=llvm18"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ require (
|
||||
github.com/mattn/go-colorable v0.1.13
|
||||
github.com/mattn/go-tty v0.0.4
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
|
||||
github.com/tetratelabs/wazero v1.6.0
|
||||
go.bug.st/serial v1.6.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/sys v0.21.0
|
||||
|
||||
@@ -12,7 +12,6 @@ github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moA
|
||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
@@ -45,19 +44,18 @@ github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3px
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tetratelabs/wazero v1.6.0 h1:z0H1iikCdP8t+q341xqepY4EWvHEw8Es7tlqiVzlP3g=
|
||||
github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
|
||||
go.bug.st/serial v1.6.0 h1:mAbRGN4cKE2J5gMwsMHC2KQisdLRQssO9WSM+rbZJ8A=
|
||||
go.bug.st/serial v1.6.0/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -76,6 +74,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240627184919-3b50c76783a8 h1:bLsZXRUBavt++CJlMN7sppNziqu3LyamESLhFJcpqFQ=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240627184919-3b50c76783a8/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
|
||||
+46
-9
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
// Version of TinyGo.
|
||||
// Update this value before release of new version of software.
|
||||
const version = "0.34.0-dev"
|
||||
const version = "0.34.0"
|
||||
|
||||
var (
|
||||
// This variable is set at build time using -ldflags parameters.
|
||||
@@ -34,27 +34,64 @@ func GetGorootVersion() (major, minor int, err error) {
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
major, minor, _, err = Parse(s)
|
||||
return major, minor, err
|
||||
}
|
||||
|
||||
if s == "" || s[:2] != "go" {
|
||||
return 0, 0, errors.New("could not parse Go version: version does not start with 'go' prefix")
|
||||
// Parse parses the Go version (like "go1.3.2") in the parameter and return the
|
||||
// major, minor, and patch version: 1, 3, and 2 in this example.
|
||||
// If there is an error, (0, 0, 0) and an error will be returned.
|
||||
func Parse(version string) (major, minor, patch int, err error) {
|
||||
if version == "" || version[:2] != "go" {
|
||||
return 0, 0, 0, errors.New("could not parse Go version: version does not start with 'go' prefix")
|
||||
}
|
||||
|
||||
parts := strings.Split(s[2:], ".")
|
||||
parts := strings.Split(version[2:], ".")
|
||||
if len(parts) < 2 {
|
||||
return 0, 0, errors.New("could not parse Go version: version has less than two parts")
|
||||
return 0, 0, 0, errors.New("could not parse Go version: version has less than two parts")
|
||||
}
|
||||
|
||||
// Ignore the errors, we don't really handle errors here anyway.
|
||||
var trailing string
|
||||
n, err := fmt.Sscanf(s, "go%d.%d%s", &major, &minor, &trailing)
|
||||
if n == 2 && err == io.EOF {
|
||||
n, err := fmt.Sscanf(version, "go%d.%d.%d%s", &major, &minor, &patch, &trailing)
|
||||
if n == 2 {
|
||||
n, err = fmt.Sscanf(version, "go%d.%d%s", &major, &minor, &trailing)
|
||||
}
|
||||
if n >= 2 && err == io.EOF {
|
||||
// Means there were no trailing characters (i.e., not an alpha/beta)
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to parse version: %s", err)
|
||||
return 0, 0, 0, fmt.Errorf("failed to parse version: %s", err)
|
||||
}
|
||||
|
||||
return major, minor, patch, nil
|
||||
}
|
||||
|
||||
// Compare compares two Go version strings.
|
||||
// The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
|
||||
// If either a or b is not a valid Go version, it is treated as "go0.0"
|
||||
// and compared lexicographically.
|
||||
// See [Parse] for more information.
|
||||
func Compare(a, b string) int {
|
||||
aMajor, aMinor, aPatch, _ := Parse(a)
|
||||
bMajor, bMinor, bPatch, _ := Parse(b)
|
||||
switch {
|
||||
case aMajor < bMajor:
|
||||
return -1
|
||||
case aMajor > bMajor:
|
||||
return +1
|
||||
case aMinor < bMinor:
|
||||
return -1
|
||||
case aMinor > bMinor:
|
||||
return +1
|
||||
case aPatch < bPatch:
|
||||
return -1
|
||||
case aPatch > bPatch:
|
||||
return +1
|
||||
default:
|
||||
return strings.Compare(a, b)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GorootVersionString returns the version string as reported by the Go
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package goenv
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
v string
|
||||
major int
|
||||
minor int
|
||||
patch int
|
||||
wantErr bool
|
||||
}{
|
||||
{"", 0, 0, 0, true},
|
||||
{"go", 0, 0, 0, true},
|
||||
{"go1", 0, 0, 0, true},
|
||||
{"go.0", 0, 0, 0, true},
|
||||
{"go1.0", 1, 0, 0, false},
|
||||
{"go1.1", 1, 1, 0, false},
|
||||
{"go1.23", 1, 23, 0, false},
|
||||
{"go1.23.5", 1, 23, 5, false},
|
||||
{"go1.23.5-rc6", 1, 23, 5, false},
|
||||
{"go2.0", 2, 0, 0, false},
|
||||
{"go2.0.15", 2, 0, 15, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.v, func(t *testing.T) {
|
||||
major, minor, patch, err := Parse(tt.v)
|
||||
if err == nil && tt.wantErr {
|
||||
t.Errorf("Parse(%q): expected err != nil", tt.v)
|
||||
}
|
||||
if err != nil && !tt.wantErr {
|
||||
t.Errorf("Parse(%q): expected err == nil", tt.v)
|
||||
}
|
||||
if major != tt.major || minor != tt.minor || patch != tt.patch {
|
||||
t.Errorf("Parse(%q): expected %d, %d, %d, nil; got %d, %d, %d, %v",
|
||||
tt.v, tt.major, tt.minor, tt.patch, major, minor, patch, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompare(t *testing.T) {
|
||||
tests := []struct {
|
||||
a string
|
||||
b string
|
||||
want int
|
||||
}{
|
||||
{"", "", 0},
|
||||
{"go0", "go0", 0},
|
||||
{"go0", "go1", -1},
|
||||
{"go1", "go0", 1},
|
||||
{"go1", "go2", -1},
|
||||
{"go2", "go1", 1},
|
||||
{"go1.1", "go1.2", -1},
|
||||
{"go1.2", "go1.1", 1},
|
||||
{"go1.1.0", "go1.2.0", -1},
|
||||
{"go1.2.0", "go1.1.0", 1},
|
||||
{"go1.2.0", "go2.3.0", -1},
|
||||
{"go1.23.2", "go1.23.10", -1},
|
||||
{"go0.1.22", "go1.23.101", -1},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.a+" "+tt.b, func(t *testing.T) {
|
||||
got := Compare(tt.a, tt.b)
|
||||
if got != tt.want {
|
||||
t.Errorf("Compare(%q, %q): expected %d; got %d",
|
||||
tt.a, tt.b, tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,18 @@ module github.com/tinygo-org/tinygo/internal/tools
|
||||
|
||||
go 1.22.4
|
||||
|
||||
require github.com/bytecodealliance/wasm-tools-go v0.2.0
|
||||
require github.com/bytecodealliance/wasm-tools-go v0.3.0
|
||||
|
||||
require (
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/regclient/regclient v0.7.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/ulikunitz/xz v0.5.12 // 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.21.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,15 +1,32 @@
|
||||
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/bytecodealliance/wasm-tools-go v0.3.0 h1:9aeDFYpbi3gtIW/nJCH+P+LhFMqezGoOfzqbUZLadho=
|
||||
github.com/bytecodealliance/wasm-tools-go v0.3.0/go.mod h1:VY+9FlpLi6jnhCrZLkyJjF9rjU4aEekgaRTk28MS2JE=
|
||||
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.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/olareg/olareg v0.1.0 h1:1dXBOgPrig5N7zoXyIZVQqU0QBo6sD9pbL6UYjY75CA=
|
||||
github.com/olareg/olareg v0.1.0/go.mod h1:RBuU7JW7SoIIxZKzLRhq8sVtQeAHzCAtRrXEBx2KlM4=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/regclient/regclient v0.7.1 h1:qEsJrTmZd98fZKjueAbrZCSNGU+ifnr6xjlSAs3WOPs=
|
||||
github.com/regclient/regclient v0.7.1/go.mod h1:+w/BFtJuw0h0nzIw/z2+1FuA2/dVXBzDq4rYmziJpMc=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo=
|
||||
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=
|
||||
@@ -18,8 +35,12 @@ 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=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
+28
-24
@@ -229,30 +229,34 @@ func needsSyscallPackage(buildTags []string) bool {
|
||||
// means use the TinyGo version.
|
||||
func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
|
||||
paths := map[string]bool{
|
||||
"": true,
|
||||
"crypto/": true,
|
||||
"crypto/rand/": false,
|
||||
"crypto/tls/": false,
|
||||
"device/": false,
|
||||
"examples/": false,
|
||||
"internal/": true,
|
||||
"internal/abi/": false,
|
||||
"internal/binary/": false,
|
||||
"internal/bytealg/": false,
|
||||
"internal/cm/": false,
|
||||
"internal/fuzz/": false,
|
||||
"internal/reflectlite/": false,
|
||||
"internal/task/": false,
|
||||
"internal/wasi/": false,
|
||||
"machine/": false,
|
||||
"net/": true,
|
||||
"net/http/": false,
|
||||
"os/": true,
|
||||
"reflect/": false,
|
||||
"runtime/": false,
|
||||
"sync/": true,
|
||||
"testing/": true,
|
||||
"unique/": false,
|
||||
"": true,
|
||||
"crypto/": true,
|
||||
"crypto/rand/": false,
|
||||
"crypto/tls/": false,
|
||||
"crypto/x509/": true,
|
||||
"crypto/x509/internal/": true,
|
||||
"crypto/x509/internal/macos/": false,
|
||||
"device/": false,
|
||||
"examples/": false,
|
||||
"internal/": true,
|
||||
"internal/abi/": false,
|
||||
"internal/binary/": false,
|
||||
"internal/bytealg/": false,
|
||||
"internal/cm/": false,
|
||||
"internal/fuzz/": false,
|
||||
"internal/reflectlite/": false,
|
||||
"internal/gclayout": false,
|
||||
"internal/task/": false,
|
||||
"internal/wasi/": false,
|
||||
"machine/": false,
|
||||
"net/": true,
|
||||
"net/http/": false,
|
||||
"os/": true,
|
||||
"reflect/": false,
|
||||
"runtime/": false,
|
||||
"sync/": true,
|
||||
"testing/": true,
|
||||
"unique/": false,
|
||||
}
|
||||
|
||||
if goMinor >= 19 {
|
||||
|
||||
+15
-3
@@ -418,8 +418,12 @@ func (p *Package) Check() error {
|
||||
packageName := p.ImportPath
|
||||
if p == p.program.MainPkg() {
|
||||
if p.Name != "main" {
|
||||
// Sanity check. Should not ever trigger.
|
||||
panic("expected main package to have name 'main'")
|
||||
return Errors{p, []error{
|
||||
scanner.Error{
|
||||
Pos: p.program.fset.Position(p.Files[0].Name.Pos()),
|
||||
Msg: fmt.Sprintf("expected main package to have name \"main\", not %#v", p.Name),
|
||||
},
|
||||
}}
|
||||
}
|
||||
packageName = "main"
|
||||
}
|
||||
@@ -428,7 +432,15 @@ func (p *Package) Check() error {
|
||||
if err, ok := err.(Errors); ok {
|
||||
return err
|
||||
}
|
||||
return Errors{p, typeErrors}
|
||||
if len(typeErrors) != 0 {
|
||||
// Got type errors, so return them.
|
||||
return Errors{p, typeErrors}
|
||||
}
|
||||
// This can happen in some weird cases.
|
||||
// The only case I know is when compiling a Go 1.23 program, with a
|
||||
// TinyGo version that supports Go 1.23 but is compiled using Go 1.22.
|
||||
// So this should be pretty rare.
|
||||
return Errors{p, []error{err}}
|
||||
}
|
||||
p.Pkg = typesPkg
|
||||
|
||||
|
||||
@@ -283,46 +283,6 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
|
||||
// Tests are always run in the package directory.
|
||||
cmd.Dir = result.MainDir
|
||||
|
||||
// wasmtime is the default emulator used for `-target=wasip1`. wasmtime
|
||||
// is a WebAssembly runtime CLI with WASI enabled by default. However,
|
||||
// only stdio are allowed by default. For example, while STDOUT routes
|
||||
// to the host, other files don't. It also does not inherit environment
|
||||
// variables from the host. Some tests read testdata files, often from
|
||||
// outside the package directory. Other tests require temporary
|
||||
// writeable directories. We allow this by adding wasmtime flags below.
|
||||
if config.EmulatorName() == "wasmtime" {
|
||||
// At this point, The current working directory is at the package
|
||||
// directory. Ex. $GOROOT/src/compress/flate for compress/flate.
|
||||
// buildAndRun has already added arguments for wasmtime, that allow
|
||||
// read-access to files such as "testdata/huffman-zero.in".
|
||||
//
|
||||
// Ex. main(.wasm) --dir=. -- -test.v
|
||||
|
||||
// Below adds additional wasmtime flags in case a test reads files
|
||||
// outside its directory, like "../testdata/e.txt". This allows any
|
||||
// relative directory up to the module root, even if the test never
|
||||
// reads any files.
|
||||
//
|
||||
// Ex. run --dir=.. --dir=../.. --dir=../../..
|
||||
var dirs []string
|
||||
switch config.Target.GOOS {
|
||||
case "wasip1":
|
||||
dirs = dirsToModuleRootRel(result.MainDir, result.ModuleRoot)
|
||||
default:
|
||||
dirs = dirsToModuleRootAbs(result.MainDir, result.ModuleRoot)
|
||||
}
|
||||
|
||||
args := []string{"run"}
|
||||
for _, d := range dirs {
|
||||
args = append(args, "--dir="+d)
|
||||
}
|
||||
|
||||
args = append(args, "--env=PWD="+cmd.Dir)
|
||||
|
||||
args = append(args, cmd.Args[1:]...)
|
||||
cmd.Args = args
|
||||
}
|
||||
|
||||
// Run the test.
|
||||
start := time.Now()
|
||||
err = cmd.Run()
|
||||
@@ -848,12 +808,11 @@ func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, c
|
||||
for _, v := range environmentVars {
|
||||
emuArgs = append(emuArgs, "--env", v)
|
||||
}
|
||||
if len(cmdArgs) != 0 {
|
||||
// Use of '--' argument no longer necessary as of Wasmtime v14:
|
||||
// https://github.com/bytecodealliance/wasmtime/pull/6946
|
||||
// args = append(args, "--")
|
||||
args = append(args, cmdArgs...)
|
||||
}
|
||||
|
||||
// Use of '--' argument no longer necessary as of Wasmtime v14:
|
||||
// https://github.com/bytecodealliance/wasmtime/pull/6946
|
||||
// args = append(args, "--")
|
||||
args = append(args, cmdArgs...)
|
||||
|
||||
// Set this for nicer backtraces during tests, but don't override the user.
|
||||
if _, ok := os.LookupEnv("WASMTIME_BACKTRACE_DETAILS"); !ok {
|
||||
@@ -903,21 +862,36 @@ func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, c
|
||||
|
||||
name = emulator[0]
|
||||
|
||||
// wasmtime is a WebAssembly runtime CLI with WASI enabled by default.
|
||||
// By default, only stdio is allowed. For example, while STDOUT routes
|
||||
// to the host, other files don't. It also does not inherit environment
|
||||
// variables from the host. Some tests read testdata files, often from
|
||||
// outside the package directory. Other tests require temporary
|
||||
// writeable directories. We allow this by adding wasmtime flags below.
|
||||
if name == "wasmtime" {
|
||||
// Wasmtime needs some special flags to pass environment variables
|
||||
// and allow reading from the current directory.
|
||||
switch config.Options.Target {
|
||||
case "wasip1":
|
||||
emuArgs = append(emuArgs, "--dir=.")
|
||||
case "wasip2":
|
||||
dir := result.MainDir
|
||||
if isSingleFile {
|
||||
cwd, _ := os.Getwd()
|
||||
dir = cwd
|
||||
// Below adds additional wasmtime flags in case a test reads files
|
||||
// outside its directory, like "../testdata/e.txt". This allows any
|
||||
// relative directory up to the module root, even if the test never
|
||||
// reads any files.
|
||||
if config.TestConfig.CompileTestBinary {
|
||||
// Add relative dirs (../, ../..) up to module root (for wasip1)
|
||||
dirs := dirsToModuleRootRel(result.MainDir, result.ModuleRoot)
|
||||
|
||||
// Add absolute dirs up to module root (for wasip2)
|
||||
dirs = append(dirs, dirsToModuleRootAbs(result.MainDir, result.ModuleRoot)...)
|
||||
|
||||
for _, d := range dirs {
|
||||
emuArgs = append(emuArgs, "--dir="+d)
|
||||
}
|
||||
emuArgs = append(emuArgs, "--dir="+dir)
|
||||
emuArgs = append(emuArgs, "--env=PWD="+dir)
|
||||
}
|
||||
|
||||
dir := result.MainDir
|
||||
if isSingleFile {
|
||||
dir, _ = os.Getwd()
|
||||
}
|
||||
emuArgs = append(emuArgs, "--dir=.")
|
||||
emuArgs = append(emuArgs, "--dir="+dir)
|
||||
emuArgs = append(emuArgs, "--env=PWD="+dir)
|
||||
}
|
||||
|
||||
emuArgs = append(emuArgs, emulator[1:]...)
|
||||
@@ -1256,36 +1230,169 @@ func getBMPPorts() (gdbPort, uartPort string, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func usage(command string) {
|
||||
switch command {
|
||||
default:
|
||||
fmt.Fprintln(os.Stderr, "TinyGo is a Go compiler for small places.")
|
||||
fmt.Fprintln(os.Stderr, "version:", goenv.Version())
|
||||
fmt.Fprintf(os.Stderr, "usage: %s <command> [arguments]\n", os.Args[0])
|
||||
fmt.Fprintln(os.Stderr, "\ncommands:")
|
||||
fmt.Fprintln(os.Stderr, " build: compile packages and dependencies")
|
||||
fmt.Fprintln(os.Stderr, " run: compile and run immediately")
|
||||
fmt.Fprintln(os.Stderr, " test: test packages")
|
||||
fmt.Fprintln(os.Stderr, " flash: compile and flash to the device")
|
||||
fmt.Fprintln(os.Stderr, " gdb: run/flash and immediately enter GDB")
|
||||
fmt.Fprintln(os.Stderr, " lldb: run/flash and immediately enter LLDB")
|
||||
fmt.Fprintln(os.Stderr, " monitor: open communication port")
|
||||
fmt.Fprintln(os.Stderr, " ports: list available serial ports")
|
||||
fmt.Fprintln(os.Stderr, " env: list environment variables used during build")
|
||||
fmt.Fprintln(os.Stderr, " list: run go list using the TinyGo root")
|
||||
fmt.Fprintln(os.Stderr, " clean: empty cache directory ("+goenv.Get("GOCACHE")+")")
|
||||
fmt.Fprintln(os.Stderr, " targets: list targets")
|
||||
fmt.Fprintln(os.Stderr, " info: show info for specified target")
|
||||
fmt.Fprintln(os.Stderr, " version: show version")
|
||||
fmt.Fprintln(os.Stderr, " help: print this help text")
|
||||
const (
|
||||
usageBuild = `Build compiles the packages named by the import paths, along with their
|
||||
dependencies, but it does not install the results. The output binary is
|
||||
specified using the -o parameter. The generated file type depends on the
|
||||
extension:
|
||||
|
||||
.o:
|
||||
Create a relocatable object file. You can use this option if you
|
||||
don't want to use the TinyGo build system or want to do other custom
|
||||
things.
|
||||
|
||||
.ll:
|
||||
Create textual LLVM IR, after optimization. This is mainly useful
|
||||
for debugging.
|
||||
|
||||
.bc:
|
||||
Create LLVM bitcode, after optimization. This may be useful for
|
||||
debugging or for linking into other programs using LTO.
|
||||
|
||||
.hex:
|
||||
Create an Intel HEX file to flash it to a microcontroller.
|
||||
|
||||
.bin:
|
||||
Similar, but create a binary file.
|
||||
|
||||
.wasm:
|
||||
Compile and link a WebAssembly file.
|
||||
|
||||
(all other) Compile and link the program into a regular executable. For
|
||||
microcontrollers, it is common to use the .elf file extension to indicate a
|
||||
linked ELF file is generated. For Linux, it is common to build binaries with no
|
||||
extension at all.`
|
||||
|
||||
usageRun = `Run the program, either directly on the host or in an emulated environment
|
||||
(depending on -target).`
|
||||
|
||||
usageFlash = `Flash the program to a microcontroller. Some common flags are described below.
|
||||
|
||||
-target={name}:
|
||||
Specifies the type of microcontroller that is used. The name of the
|
||||
microcontroller is given on the individual pages for each board type
|
||||
listed under Microcontrollers
|
||||
(https://tinygo.org/docs/reference/microcontrollers/).
|
||||
Examples: "arduino-nano", "d1mini", "xiao".
|
||||
|
||||
-monitor:
|
||||
Start the serial monitor (see below) immediately after
|
||||
flashing. However, some microcontrollers need a split second
|
||||
or two to configure the serial port after flashing, and
|
||||
using the "-monitor" flag can fail because the serial
|
||||
monitor starts too quickly. In that case, use the "tinygo
|
||||
monitor" command explicitly.`
|
||||
|
||||
usageMonitor = `Start the serial monitor on the serial port that is connected to the
|
||||
microcontroller. If there is only a single board attached to the host computer,
|
||||
the default values for various options should be sufficient. In other
|
||||
situations, particularly if you have multiple microcontrollers attached, some
|
||||
parameters may need to be overridden using the following flags:
|
||||
|
||||
-port={port}:
|
||||
If there are multiple microcontroller attached, an error
|
||||
message will display a list of potential serial ports. The
|
||||
appropriate port can be specified by this flag. On Linux,
|
||||
the port will be something like /dev/ttyUSB0 or /dev/ttyACM1.
|
||||
On MacOS, the port will look like /dev/cu.usbserial-1420. On
|
||||
Windows, the port will be something like COM1 or COM31.
|
||||
|
||||
-baudrate={rate}:
|
||||
The default baud rate is 115200. Boards using the AVR
|
||||
processor (e.g. Arduino Nano, Arduino Mega 2560) use 9600
|
||||
instead.
|
||||
|
||||
-target={name}:
|
||||
If you have more than one microcontrollers attached, you can
|
||||
sometimes just specify the target name and let tinygo
|
||||
monitor figure out the port. Sometimes, this does not work
|
||||
and you have to explicitly use the -port flag.
|
||||
|
||||
The serial monitor intercepts several control characters for its own use instead of sending them
|
||||
to the microcontroller:
|
||||
|
||||
Control-C: terminates the tinygo monitor
|
||||
Control-Z: suspends the tinygo monitor and drops back into shell
|
||||
Control-\: terminates the tinygo monitor with a stack trace
|
||||
Control-S: flow control, suspends output to the console
|
||||
Control-Q: flow control, resumes output to the console
|
||||
Control-@: thrown away by tinygo monitor
|
||||
|
||||
Note: If you are using os.Stdin on the microcontroller, you may find that a CR
|
||||
character on the host computer (also known as Enter, ^M, or \r) is transmitted
|
||||
to the microcontroller without conversion, so os.Stdin returns a \r character
|
||||
instead of the expected \n (also known as ^J, NL, or LF) to indicate
|
||||
end-of-line. You may be able to get around this problem by hitting Control-J in
|
||||
tinygo monitor to transmit the \n end-of-line character.`
|
||||
|
||||
usageGdb = `Build the program, optionally flash it to a microcontroller if it is a remote
|
||||
target, and drop into a GDB shell. From there you can set breakpoints, start the
|
||||
program with "run" or "continue" ("run" for a local program, continue for
|
||||
on-chip debugging), single-step, show a backtrace, break and resume the program
|
||||
with Ctrl-C/"continue", etc. You may need to install extra tools (like openocd
|
||||
and arm-none-eabi-gdb) to be able to do this. Also, you may need a dedicated
|
||||
debugger to be able to debug certain boards if no debugger is integrated. Some
|
||||
boards (like the BBC micro:bit and most professional evaluation boards) have an
|
||||
integrated debugger.`
|
||||
|
||||
usageClean = `Clean the cache directory, normally stored in $HOME/.cache/tinygo. This is not
|
||||
normally needed.`
|
||||
|
||||
usageHelp = `Print a short summary of the available commands, plus a list of command flags.`
|
||||
usageVersion = `Print the version of the command and the version of the used $GOROOT.`
|
||||
usageEnv = `Print a list of environment variables that affect TinyGo (as a shell script).
|
||||
If one or more variable names are given as arguments, env prints the value of
|
||||
each on a new line.`
|
||||
|
||||
usageDefault = `TinyGo is a Go compiler for small places.
|
||||
version: %s
|
||||
usage: %s <command> [arguments]
|
||||
commands:
|
||||
build: compile packages and dependencies
|
||||
run: compile and run immediately
|
||||
test: test packages
|
||||
flash: compile and flash to the device
|
||||
gdb: run/flash and immediately enter GDB
|
||||
lldb: run/flash and immediately enter LLDB
|
||||
monitor: open communication port
|
||||
ports: list available serial ports
|
||||
env: list environment variables used during build
|
||||
list: run go list using the TinyGo root
|
||||
clean: empty cache directory (%s)
|
||||
targets: list targets
|
||||
info: show info for specified target
|
||||
version: show version
|
||||
help: print this help text`
|
||||
)
|
||||
|
||||
var (
|
||||
commandHelp = map[string]string{
|
||||
"build": usageBuild,
|
||||
"run": usageRun,
|
||||
"flash": usageFlash,
|
||||
"monitor": usageMonitor,
|
||||
"gdb": usageGdb,
|
||||
"clean": usageClean,
|
||||
"help": usageHelp,
|
||||
"version": usageVersion,
|
||||
"env": usageEnv,
|
||||
}
|
||||
)
|
||||
|
||||
func usage(command string) {
|
||||
val, ok := commandHelp[command]
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr, usageDefault, goenv.Version(), os.Args[0], goenv.Get("GOCACHE"))
|
||||
if flag.Parsed() {
|
||||
fmt.Fprintln(os.Stderr, "\nflags:")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stderr, "\nfor more details, see https://tinygo.org/docs/reference/usage/")
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, val)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func handleCompilerError(err error) {
|
||||
@@ -1330,19 +1437,20 @@ func (m globalValuesFlag) Set(value string) error {
|
||||
|
||||
// parseGoLinkFlag parses the -ldflags parameter. Its primary purpose right now
|
||||
// is the -X flag, for setting the value of global string variables.
|
||||
func parseGoLinkFlag(flagsString string) (map[string]map[string]string, error) {
|
||||
func parseGoLinkFlag(flagsString string) (map[string]map[string]string, string, error) {
|
||||
set := flag.NewFlagSet("link", flag.ExitOnError)
|
||||
globalVarValues := make(globalValuesFlag)
|
||||
set.Var(globalVarValues, "X", "Set the value of the string variable to the given value.")
|
||||
extLDFlags := set.String("extldflags", "", "additional flags to pass to external linker")
|
||||
flags, err := shlex.Split(flagsString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", err
|
||||
}
|
||||
err = set.Parse(flags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", err
|
||||
}
|
||||
return map[string]map[string]string(globalVarValues), nil
|
||||
return map[string]map[string]string(globalVarValues), *extLDFlags, nil
|
||||
}
|
||||
|
||||
// getListOfPackages returns a standard list of packages for a given list that might
|
||||
@@ -1392,6 +1500,7 @@ func main() {
|
||||
var tags buildutil.TagsFlag
|
||||
flag.Var(&tags, "tags", "a space-separated list of extra build tags")
|
||||
target := flag.String("target", "", "chip/board name or JSON target specification file")
|
||||
buildMode := flag.String("buildmode", "", "build mode to use (default, c-shared)")
|
||||
var stackSize uint64
|
||||
flag.Func("stack-size", "goroutine stack size (if unknown at compile time)", func(s string) error {
|
||||
size, err := bytesize.Parse(s)
|
||||
@@ -1461,6 +1570,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:]...)
|
||||
@@ -1473,7 +1583,7 @@ func main() {
|
||||
}
|
||||
|
||||
flag.CommandLine.Parse(os.Args[2:])
|
||||
globalVarValues, err := parseGoLinkFlag(*ldflags)
|
||||
globalVarValues, extLDFlags, err := parseGoLinkFlag(*ldflags)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
@@ -1499,6 +1609,7 @@ func main() {
|
||||
GOARM: goenv.Get("GOARM"),
|
||||
GOMIPS: goenv.Get("GOMIPS"),
|
||||
Target: *target,
|
||||
BuildMode: *buildMode,
|
||||
StackSize: stackSize,
|
||||
Opt: *opt,
|
||||
GC: *gc,
|
||||
@@ -1528,6 +1639,7 @@ func main() {
|
||||
Timeout: *timeout,
|
||||
WITPackage: witPackage,
|
||||
WITWorld: witWorld,
|
||||
ExtLDFlags: extLDFlags,
|
||||
}
|
||||
if *printCommands {
|
||||
options.PrintCommands = printCommand
|
||||
@@ -1946,3 +2058,56 @@ 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 = slicesDelete(os.Args, used, used+2)
|
||||
|
||||
case strings.HasPrefix(a, "-C="), strings.HasPrefix(a, "--C="):
|
||||
_, dir, _ = strings.Cut(a, "=")
|
||||
os.Args = slicesDelete(os.Args, used, used+1)
|
||||
}
|
||||
|
||||
if err := os.Chdir(dir); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "cannot chdir:", err)
|
||||
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:]...)
|
||||
}
|
||||
|
||||
+279
-21
@@ -6,6 +6,7 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"io"
|
||||
@@ -21,6 +22,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aykevl/go-wasm"
|
||||
"github.com/tetratelabs/wazero"
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
|
||||
"github.com/tinygo-org/tinygo/builder"
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/diagnostics"
|
||||
@@ -75,6 +79,7 @@ func TestBuild(t *testing.T) {
|
||||
"oldgo/",
|
||||
"print.go",
|
||||
"reflect.go",
|
||||
"signal.go",
|
||||
"slice.go",
|
||||
"sort.go",
|
||||
"stdlib.go",
|
||||
@@ -213,6 +218,7 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
// isWebAssembly := strings.HasPrefix(spec.Triple, "wasm")
|
||||
isWASI := strings.HasPrefix(options.Target, "wasi")
|
||||
isWebAssembly := isWASI || strings.HasPrefix(options.Target, "wasm") || (options.Target == "" && strings.HasPrefix(options.GOARCH, "wasm"))
|
||||
isBaremetal := options.Target == "simavr" || options.Target == "cortex-m-qemu" || options.Target == "riscv-qemu"
|
||||
|
||||
for _, name := range tests {
|
||||
if options.GOOS == "linux" && (options.GOARCH == "arm" || options.GOARCH == "386") {
|
||||
@@ -277,6 +283,13 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if isWebAssembly || isBaremetal || options.GOOS == "windows" {
|
||||
switch name {
|
||||
case "signal.go":
|
||||
// Signals only work on POSIX-like systems.
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
name := name // redefine to avoid race condition
|
||||
t.Run(name, func(t *testing.T) {
|
||||
@@ -392,17 +405,13 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
|
||||
// of the path.
|
||||
path := TESTDATA + "/" + name
|
||||
// Get the expected output for this test.
|
||||
txtpath := path[:len(path)-3] + ".txt"
|
||||
expectedOutputPath := path[:len(path)-3] + ".txt"
|
||||
pkgName := "./" + path
|
||||
if path[len(path)-1] == '/' {
|
||||
txtpath = path + "out.txt"
|
||||
expectedOutputPath = path + "out.txt"
|
||||
options.Directory = path
|
||||
pkgName = "."
|
||||
}
|
||||
expected, err := os.ReadFile(txtpath)
|
||||
if err != nil {
|
||||
t.Fatal("could not read expected output file:", err)
|
||||
}
|
||||
|
||||
config, err := builder.NewConfig(&options)
|
||||
if err != nil {
|
||||
@@ -424,10 +433,7 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
|
||||
return
|
||||
}
|
||||
|
||||
// putchar() prints CRLF, convert it to LF.
|
||||
actual := bytes.Replace(stdout.Bytes(), []byte{'\r', '\n'}, []byte{'\n'}, -1)
|
||||
expected = bytes.Replace(expected, []byte{'\r', '\n'}, []byte{'\n'}, -1) // for Windows
|
||||
|
||||
actual := stdout.Bytes()
|
||||
if config.EmulatorName() == "simavr" {
|
||||
// Strip simavr log formatting.
|
||||
actual = bytes.Replace(actual, []byte{0x1b, '[', '3', '2', 'm'}, nil, -1)
|
||||
@@ -442,17 +448,12 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
|
||||
}
|
||||
|
||||
// Check whether the command ran successfully.
|
||||
fail := false
|
||||
if err != nil {
|
||||
t.Log("failed to run:", err)
|
||||
fail = true
|
||||
} else if !bytes.Equal(expected, actual) {
|
||||
t.Logf("output did not match (expected %d bytes, got %d bytes):", len(expected), len(actual))
|
||||
t.Logf(string(Diff("expected", expected, "actual", actual)))
|
||||
fail = true
|
||||
t.Error("failed to run:", err)
|
||||
}
|
||||
checkOutput(t, expectedOutputPath, actual)
|
||||
|
||||
if fail {
|
||||
if t.Failed() {
|
||||
r := bufio.NewReader(bytes.NewReader(actual))
|
||||
for {
|
||||
line, err := r.ReadString('\n')
|
||||
@@ -470,20 +471,21 @@ func TestWebAssembly(t *testing.T) {
|
||||
t.Parallel()
|
||||
type testCase struct {
|
||||
name string
|
||||
target string
|
||||
panicStrategy string
|
||||
imports []string
|
||||
}
|
||||
for _, tc := range []testCase{
|
||||
// Test whether there really are no imports when using -panic=trap. This
|
||||
// tests the bugfix for https://github.com/tinygo-org/tinygo/issues/4161.
|
||||
{name: "panic-default", imports: []string{"wasi_snapshot_preview1.fd_write"}},
|
||||
{name: "panic-trap", panicStrategy: "trap", imports: []string{}},
|
||||
{name: "panic-default", target: "wasip1", imports: []string{"wasi_snapshot_preview1.fd_write", "wasi_snapshot_preview1.random_get"}},
|
||||
{name: "panic-trap", target: "wasm-unknown", panicStrategy: "trap", imports: []string{}},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
tmpdir := t.TempDir()
|
||||
options := optionsFromTarget("wasi", sema)
|
||||
options := optionsFromTarget(tc.target, sema)
|
||||
options.PanicStrategy = tc.panicStrategy
|
||||
config, err := builder.NewConfig(&options)
|
||||
if err != nil {
|
||||
@@ -523,6 +525,262 @@ func TestWebAssembly(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWasmExport(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
target string
|
||||
buildMode string
|
||||
scheduler string
|
||||
file string
|
||||
noOutput bool
|
||||
command bool // call _start (command mode) instead of _initialize
|
||||
}
|
||||
|
||||
tests := []testCase{
|
||||
// "command mode" WASI
|
||||
{
|
||||
name: "WASIp1-command",
|
||||
target: "wasip1",
|
||||
command: true,
|
||||
},
|
||||
// "reactor mode" WASI (with -buildmode=c-shared)
|
||||
{
|
||||
name: "WASIp1-reactor",
|
||||
target: "wasip1",
|
||||
buildMode: "c-shared",
|
||||
},
|
||||
// Make sure reactor mode also works without a scheduler.
|
||||
{
|
||||
name: "WASIp1-reactor-noscheduler",
|
||||
target: "wasip1",
|
||||
buildMode: "c-shared",
|
||||
scheduler: "none",
|
||||
file: "wasmexport-noscheduler.go",
|
||||
},
|
||||
// Test -target=wasm-unknown with the default build mode (which is
|
||||
// c-shared).
|
||||
{
|
||||
name: "wasm-unknown-reactor",
|
||||
target: "wasm-unknown",
|
||||
file: "wasmexport-noscheduler.go",
|
||||
noOutput: true, // wasm-unknown cannot produce output
|
||||
},
|
||||
// Test -target=wasm-unknown with -buildmode=default, which makes it run
|
||||
// in command mode.
|
||||
{
|
||||
name: "wasm-unknown-command",
|
||||
target: "wasm-unknown",
|
||||
buildMode: "default",
|
||||
file: "wasmexport-noscheduler.go",
|
||||
noOutput: true, // wasm-unknown cannot produce output
|
||||
command: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Build the wasm binary.
|
||||
tmpdir := t.TempDir()
|
||||
options := optionsFromTarget(tc.target, sema)
|
||||
options.BuildMode = tc.buildMode
|
||||
options.Scheduler = tc.scheduler
|
||||
buildConfig, err := builder.NewConfig(&options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
filename := "wasmexport.go"
|
||||
if tc.file != "" {
|
||||
filename = tc.file
|
||||
}
|
||||
result, err := builder.Build("testdata/"+filename, ".wasm", tmpdir, buildConfig)
|
||||
if err != nil {
|
||||
t.Fatal("failed to build binary:", err)
|
||||
}
|
||||
|
||||
// Read the wasm binary back into memory.
|
||||
data, err := os.ReadFile(result.Binary)
|
||||
if err != nil {
|
||||
t.Fatal("could not read wasm binary: ", err)
|
||||
}
|
||||
|
||||
// Set up the wazero runtime.
|
||||
output := &bytes.Buffer{}
|
||||
ctx := context.Background()
|
||||
r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
|
||||
defer r.Close(ctx)
|
||||
config := wazero.NewModuleConfig().
|
||||
WithStdout(output).WithStderr(output).
|
||||
WithStartFunctions()
|
||||
|
||||
// Prepare for testing.
|
||||
var mod api.Module
|
||||
mustCall := func(results []uint64, err error) []uint64 {
|
||||
if err != nil {
|
||||
t.Error("failed to run function:", err)
|
||||
}
|
||||
return results
|
||||
}
|
||||
checkResult := func(name string, results []uint64, expected []uint64) {
|
||||
if len(results) != len(expected) {
|
||||
t.Errorf("%s: expected %v but got %v", name, expected, results)
|
||||
}
|
||||
for i, result := range results {
|
||||
if result != expected[i] {
|
||||
t.Errorf("%s: expected %v but got %v", name, expected, results)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
runTests := func() {
|
||||
// Test an exported function without params or return value.
|
||||
checkResult("hello()", mustCall(mod.ExportedFunction("hello").Call(ctx)), nil)
|
||||
|
||||
// Test that we can call an exported function more than once.
|
||||
checkResult("add(3, 5)", mustCall(mod.ExportedFunction("add").Call(ctx, 3, 5)), []uint64{8})
|
||||
checkResult("add(7, 9)", mustCall(mod.ExportedFunction("add").Call(ctx, 7, 9)), []uint64{16})
|
||||
checkResult("add(6, 1)", mustCall(mod.ExportedFunction("add").Call(ctx, 6, 1)), []uint64{7})
|
||||
|
||||
// Test that imported functions can call exported functions
|
||||
// again.
|
||||
checkResult("reentrantCall(2, 3)", mustCall(mod.ExportedFunction("reentrantCall").Call(ctx, 2, 3)), []uint64{5})
|
||||
checkResult("reentrantCall(1, 8)", mustCall(mod.ExportedFunction("reentrantCall").Call(ctx, 1, 8)), []uint64{9})
|
||||
}
|
||||
|
||||
// Add wasip1 module.
|
||||
wasi_snapshot_preview1.MustInstantiate(ctx, r)
|
||||
|
||||
// Add custom "tester" module.
|
||||
callOutside := func(a, b int32) int32 {
|
||||
results, err := mod.ExportedFunction("add").Call(ctx, uint64(a), uint64(b))
|
||||
if err != nil {
|
||||
t.Error("could not call exported add function:", err)
|
||||
}
|
||||
return int32(results[0])
|
||||
}
|
||||
callTestMain := func() {
|
||||
runTests()
|
||||
}
|
||||
builder := r.NewHostModuleBuilder("tester")
|
||||
builder.NewFunctionBuilder().WithFunc(callOutside).Export("callOutside")
|
||||
builder.NewFunctionBuilder().WithFunc(callTestMain).Export("callTestMain")
|
||||
_, err = builder.Instantiate(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Parse and instantiate the wasm.
|
||||
mod, err = r.InstantiateWithConfig(ctx, data, config)
|
||||
if err != nil {
|
||||
t.Fatal("could not instantiate wasm module:", err)
|
||||
}
|
||||
|
||||
// Initialize the module and run the tests.
|
||||
if tc.command {
|
||||
// Call _start (the entry point), which calls
|
||||
// tester.callTestMain, which then runs all the tests.
|
||||
mustCall(mod.ExportedFunction("_start").Call(ctx))
|
||||
} else {
|
||||
// Run the _initialize call, because this is reactor mode wasm.
|
||||
mustCall(mod.ExportedFunction("_initialize").Call(ctx))
|
||||
runTests()
|
||||
}
|
||||
|
||||
// Check that the output matches the expected output.
|
||||
// (Skip this for wasm-unknown because it can't produce output).
|
||||
if !tc.noOutput {
|
||||
checkOutput(t, "testdata/wasmexport.txt", output.Bytes())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Test js.FuncOf (for syscall/js).
|
||||
// This test might be extended in the future to cover more cases in syscall/js.
|
||||
func TestWasmFuncOf(t *testing.T) {
|
||||
// Build the wasm binary.
|
||||
tmpdir := t.TempDir()
|
||||
options := optionsFromTarget("wasm", sema)
|
||||
buildConfig, err := builder.NewConfig(&options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result, err := builder.Build("testdata/wasmfunc.go", ".wasm", tmpdir, buildConfig)
|
||||
if err != nil {
|
||||
t.Fatal("failed to build binary:", err)
|
||||
}
|
||||
|
||||
// Test the resulting binary using NodeJS.
|
||||
output := &bytes.Buffer{}
|
||||
cmd := exec.Command("node", "testdata/wasmfunc.js", result.Binary, buildConfig.BuildMode())
|
||||
cmd.Stdout = output
|
||||
cmd.Stderr = output
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
t.Error("failed to run node:", err)
|
||||
}
|
||||
checkOutput(t, "testdata/wasmfunc.txt", output.Bytes())
|
||||
}
|
||||
|
||||
// Test //go:wasmexport in JavaScript (using NodeJS).
|
||||
func TestWasmExportJS(t *testing.T) {
|
||||
type testCase struct {
|
||||
name string
|
||||
buildMode string
|
||||
}
|
||||
|
||||
tests := []testCase{
|
||||
{name: "default"},
|
||||
{name: "c-shared", buildMode: "c-shared"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Build the wasm binary.
|
||||
tmpdir := t.TempDir()
|
||||
options := optionsFromTarget("wasm", sema)
|
||||
options.BuildMode = tc.buildMode
|
||||
buildConfig, err := builder.NewConfig(&options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result, err := builder.Build("testdata/wasmexport-noscheduler.go", ".wasm", tmpdir, buildConfig)
|
||||
if err != nil {
|
||||
t.Fatal("failed to build binary:", err)
|
||||
}
|
||||
|
||||
// Test the resulting binary using NodeJS.
|
||||
output := &bytes.Buffer{}
|
||||
cmd := exec.Command("node", "testdata/wasmexport.js", result.Binary, buildConfig.BuildMode())
|
||||
cmd.Stdout = output
|
||||
cmd.Stderr = output
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
t.Error("failed to run node:", err)
|
||||
}
|
||||
checkOutput(t, "testdata/wasmexport.txt", output.Bytes())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the output of a test equals the expected output.
|
||||
func checkOutput(t *testing.T, filename string, actual []byte) {
|
||||
expectedOutput, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatal("could not read output file:", err)
|
||||
}
|
||||
expectedOutput = bytes.ReplaceAll(expectedOutput, []byte("\r\n"), []byte("\n"))
|
||||
actual = bytes.ReplaceAll(actual, []byte("\r\n"), []byte("\n"))
|
||||
|
||||
if !bytes.Equal(actual, expectedOutput) {
|
||||
t.Errorf("output did not match (expected %d bytes, got %d bytes):", len(expectedOutput), len(actual))
|
||||
t.Error(string(Diff("expected", expectedOutput, "actual", actual)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestTest(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
package macos
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Exported symbols copied from Big Go, but stripped of functionality.
|
||||
// Allows building of crypto/x509 on macOS.
|
||||
|
||||
const (
|
||||
ErrSecCertificateExpired = -67818
|
||||
ErrSecHostNameMismatch = -67602
|
||||
ErrSecNotTrusted = -67843
|
||||
)
|
||||
|
||||
var ErrNoTrustSettings = errors.New("no trust settings found")
|
||||
var SecPolicyAppleSSL = StringToCFString("1.2.840.113635.100.1.3") // defined by POLICYMACRO
|
||||
var SecPolicyOid = StringToCFString("SecPolicyOid")
|
||||
var SecTrustSettingsPolicy = StringToCFString("kSecTrustSettingsPolicy")
|
||||
var SecTrustSettingsPolicyString = StringToCFString("kSecTrustSettingsPolicyString")
|
||||
var SecTrustSettingsResultKey = StringToCFString("kSecTrustSettingsResult")
|
||||
|
||||
func CFArrayAppendValue(array CFRef, val CFRef) {}
|
||||
|
||||
func CFArrayGetCount(array CFRef) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFDataGetBytePtr(data CFRef) uintptr {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFDataGetLength(data CFRef) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFDataToSlice(data CFRef) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func CFEqual(a, b CFRef) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func CFErrorGetCode(errRef CFRef) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFNumberGetValue(num CFRef) (int32, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func CFRelease(ref CFRef) {}
|
||||
|
||||
func CFStringToString(ref CFRef) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func ReleaseCFArray(array CFRef) {}
|
||||
|
||||
func SecCertificateCopyData(cert CFRef) ([]byte, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustGetCertificateCount(trustObj CFRef) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func SecTrustGetResult(trustObj CFRef, result CFRef) (CFRef, CFRef, error) {
|
||||
return 0, 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustSetVerifyDate(trustObj CFRef, dateRef CFRef) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
type CFRef uintptr
|
||||
|
||||
func BytesToCFData(b []byte) CFRef {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFArrayCreateMutable() CFRef {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFArrayGetValueAtIndex(array CFRef, index int) CFRef {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFDateCreate(seconds float64) CFRef {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFDictionaryGetValueIfPresent(dict CFRef, key CFString) (value CFRef, ok bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func CFErrorCopyDescription(errRef CFRef) CFRef {
|
||||
return 0
|
||||
}
|
||||
|
||||
func CFStringCreateExternalRepresentation(strRef CFRef) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecCertificateCreateWithData(b []byte) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecPolicyCreateSSL(name string) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustCreateWithCertificates(certs CFRef, policies CFRef) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustEvaluate(trustObj CFRef) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustGetCertificateAtIndex(trustObj CFRef, i int) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustSettingsCopyCertificates(domain SecTrustSettingsDomain) (certArray CFRef, err error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustSettingsCopyTrustSettings(cert CFRef, domain SecTrustSettingsDomain) (trustSettings CFRef, err error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func TimeToCFDateRef(t time.Time) CFRef {
|
||||
return 0
|
||||
}
|
||||
|
||||
type CFString CFRef
|
||||
|
||||
func StringToCFString(s string) CFString {
|
||||
return 0
|
||||
}
|
||||
|
||||
type OSStatus struct {
|
||||
// Has unexported fields.
|
||||
}
|
||||
|
||||
func (s OSStatus) Error() string
|
||||
|
||||
type SecTrustResultType int32
|
||||
|
||||
const (
|
||||
SecTrustResultInvalid SecTrustResultType = iota
|
||||
SecTrustResultProceed
|
||||
SecTrustResultConfirm // deprecated
|
||||
SecTrustResultDeny
|
||||
SecTrustResultUnspecified
|
||||
SecTrustResultRecoverableTrustFailure
|
||||
SecTrustResultFatalTrustFailure
|
||||
SecTrustResultOtherError
|
||||
)
|
||||
|
||||
type SecTrustSettingsDomain int32
|
||||
|
||||
const (
|
||||
SecTrustSettingsDomainUser SecTrustSettingsDomain = iota
|
||||
SecTrustSettingsDomainAdmin
|
||||
SecTrustSettingsDomainSystem
|
||||
)
|
||||
|
||||
type SecTrustSettingsResult int32
|
||||
|
||||
const (
|
||||
SecTrustSettingsResultInvalid SecTrustSettingsResult = iota
|
||||
SecTrustSettingsResultTrustRoot
|
||||
SecTrustSettingsResultTrustAsRoot
|
||||
SecTrustSettingsResultDeny
|
||||
SecTrustSettingsResultUnspecified
|
||||
)
|
||||
@@ -30,3 +30,8 @@ func (littleEndian) AppendUint16(b []byte, v uint16) []byte {
|
||||
func (littleEndian) Uint32(b []byte) uint32 {
|
||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
}
|
||||
|
||||
func (littleEndian) Uint64(b []byte) uint64 {
|
||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||
}
|
||||
|
||||
+28
-4
@@ -2,6 +2,11 @@ package cm
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// AnyInteger is a type constraint for any integer type.
|
||||
type AnyInteger interface {
|
||||
~int | ~uint | ~uintptr | ~int8 | ~uint8 | ~int16 | ~uint16 | ~int32 | ~uint32 | ~int64 | ~uint64
|
||||
}
|
||||
|
||||
// Reinterpret reinterprets the bits of type From into type T.
|
||||
// Will panic if the size of From is smaller than the size of To.
|
||||
func Reinterpret[T, From any](from From) (to T) {
|
||||
@@ -19,19 +24,19 @@ func LowerString[S ~string](s S) (*byte, uint32) {
|
||||
}
|
||||
|
||||
// LiftString lifts Core WebAssembly types into a [string].
|
||||
func LiftString[T ~string, Data unsafe.Pointer | uintptr | *uint8, Len uint | uintptr | uint32 | uint64](data Data, len Len) T {
|
||||
func LiftString[T ~string, Data unsafe.Pointer | uintptr | *uint8, Len AnyInteger](data Data, len Len) T {
|
||||
return T(unsafe.String((*uint8)(unsafe.Pointer(data)), int(len)))
|
||||
}
|
||||
|
||||
// LowerList lowers a [List] into a pair of Core WebAssembly types.
|
||||
func LowerList[L ~struct{ list[T] }, T any](list L) (*T, uint32) {
|
||||
func LowerList[L AnyList[T], T any](list L) (*T, uint32) {
|
||||
l := (*List[T])(unsafe.Pointer(&list))
|
||||
return l.data, uint32(l.len)
|
||||
}
|
||||
|
||||
// LiftList lifts Core WebAssembly types into a [List].
|
||||
func LiftList[L List[T], T any, Data unsafe.Pointer | uintptr | *T, Len uint | uintptr | uint32 | uint64](data Data, len Len) L {
|
||||
return L(NewList((*T)(unsafe.Pointer(data)), uint(len)))
|
||||
func LiftList[L AnyList[T], T any, Data unsafe.Pointer | uintptr | *T, Len AnyInteger](data Data, len Len) L {
|
||||
return L(NewList((*T)(unsafe.Pointer(data)), len))
|
||||
}
|
||||
|
||||
// BoolToU32 converts a value whose underlying type is [bool] into a [uint32].
|
||||
@@ -84,6 +89,25 @@ func F64ToU64(v float64) uint64 { return *(*uint64)(unsafe.Pointer(&v)) }
|
||||
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
|
||||
func U64ToF64(v uint64) float64 { return *(*float64)(unsafe.Pointer(&v)) }
|
||||
|
||||
// F32ToU64 maps the bits of a [float32] into a [uint64].
|
||||
// Used to lower a [float32] into a Core WebAssembly i64 when required by the [Canonical ABI].
|
||||
//
|
||||
// [float32]: https://pkg.go.dev/builtin#float32
|
||||
// [uint64]: https://pkg.go.dev/builtin#uint64
|
||||
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
|
||||
func F32ToU64(v float32) uint64 { return uint64(*(*uint32)(unsafe.Pointer(&v))) }
|
||||
|
||||
// U64ToF32 maps the bits of a [uint64] into a [float32].
|
||||
// Used to lift a Core WebAssembly i64 into a [float32] when required by the [Canonical ABI].
|
||||
//
|
||||
// [uint64]: https://pkg.go.dev/builtin#uint64
|
||||
// [float32]: https://pkg.go.dev/builtin#float32
|
||||
// [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
|
||||
func U64ToF32(v uint64) float32 {
|
||||
truncated := uint32(v)
|
||||
return *(*float32)(unsafe.Pointer(&truncated))
|
||||
}
|
||||
|
||||
// PointerToU32 converts a pointer of type *T into a [uint32].
|
||||
// Used to lower a pointer into a Core WebAssembly i32 as specified in the [Canonical ABI].
|
||||
//
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
//go:build !go1.23
|
||||
|
||||
package cm
|
||||
|
||||
// HostLayout marks a struct as using host memory layout.
|
||||
// See [structs.HostLayout] in Go 1.23 or later.
|
||||
type HostLayout struct {
|
||||
_ hostLayout // prevent accidental conversion with plain struct{}
|
||||
}
|
||||
|
||||
type hostLayout struct{}
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build go1.23
|
||||
|
||||
package cm
|
||||
|
||||
import "structs"
|
||||
|
||||
// HostLayout marks a struct as using host memory layout.
|
||||
// See [structs.HostLayout] in Go 1.23 or later.
|
||||
type HostLayout = structs.HostLayout
|
||||
+20
-8
@@ -4,14 +4,25 @@ import "unsafe"
|
||||
|
||||
// List represents a Component Model list.
|
||||
// The binary representation of list<T> is similar to a Go slice minus the cap field.
|
||||
type List[T any] struct{ list[T] }
|
||||
type List[T any] struct {
|
||||
_ HostLayout
|
||||
list[T]
|
||||
}
|
||||
|
||||
// AnyList is a type constraint for generic functions that accept any [List] type.
|
||||
type AnyList[T any] interface {
|
||||
~struct {
|
||||
_ HostLayout
|
||||
list[T]
|
||||
}
|
||||
}
|
||||
|
||||
// NewList returns a List[T] from data and len.
|
||||
func NewList[T any](data *T, len uint) List[T] {
|
||||
func NewList[T any, Len AnyInteger](data *T, len Len) List[T] {
|
||||
return List[T]{
|
||||
list[T]{
|
||||
list: list[T]{
|
||||
data: data,
|
||||
len: len,
|
||||
len: uintptr(len),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -20,15 +31,16 @@ func NewList[T any](data *T, len uint) List[T] {
|
||||
// The underlying slice data is not copied, and the resulting List points at the
|
||||
// same array storage as the slice.
|
||||
func ToList[S ~[]T, T any](s S) List[T] {
|
||||
return NewList[T](unsafe.SliceData([]T(s)), uint(len(s)))
|
||||
return NewList[T](unsafe.SliceData([]T(s)), uintptr(len(s)))
|
||||
}
|
||||
|
||||
// list represents the internal representation of a Component Model list.
|
||||
// It is intended to be embedded in a [List], so embedding types maintain
|
||||
// the methods defined on this type.
|
||||
type list[T any] struct {
|
||||
_ HostLayout
|
||||
data *T
|
||||
len uint
|
||||
len uintptr
|
||||
}
|
||||
|
||||
// Slice returns a Go slice representing the List.
|
||||
@@ -42,7 +54,7 @@ func (l list[T]) Data() *T {
|
||||
}
|
||||
|
||||
// Len returns the length of the list.
|
||||
// TODO: should this return an int instead of a uint?
|
||||
func (l list[T]) Len() uint {
|
||||
// TODO: should this return an int instead of a uintptr?
|
||||
func (l list[T]) Len() uintptr {
|
||||
return l.len
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package cm
|
||||
// Option represents a Component Model [option<T>] type.
|
||||
//
|
||||
// [option<T>]: https://component-model.bytecodealliance.org/design/wit.html#options
|
||||
type Option[T any] struct{ option[T] }
|
||||
type Option[T any] struct {
|
||||
_ HostLayout
|
||||
option[T]
|
||||
}
|
||||
|
||||
// None returns an [Option] representing the none case,
|
||||
// equivalent to the zero value.
|
||||
@@ -14,7 +17,7 @@ func None[T any]() Option[T] {
|
||||
// Some returns an [Option] representing the some case.
|
||||
func Some[T any](v T) Option[T] {
|
||||
return Option[T]{
|
||||
option[T]{
|
||||
option: option[T]{
|
||||
isSome: true,
|
||||
some: v,
|
||||
},
|
||||
@@ -25,6 +28,7 @@ func Some[T any](v T) Option[T] {
|
||||
// The first byte is a bool representing none or some,
|
||||
// followed by storage for the associated type T.
|
||||
type option[T any] struct {
|
||||
_ HostLayout
|
||||
isSome bool
|
||||
some T
|
||||
}
|
||||
@@ -42,3 +46,14 @@ func (o *option[T]) Some() *T {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns T if o represents the some case,
|
||||
// or the zero value of T if o represents the none case.
|
||||
// This does not have a pointer receiver, so it can be chained.
|
||||
func (o option[T]) Value() T {
|
||||
if !o.isSome {
|
||||
var zero T
|
||||
return zero
|
||||
}
|
||||
return o.some
|
||||
}
|
||||
|
||||
@@ -17,10 +17,22 @@ type BoolResult bool
|
||||
// Result represents a result sized to hold the Shape type.
|
||||
// The size of the Shape type must be greater than or equal to the size of OK and Err types.
|
||||
// For results with two zero-length types, use [BoolResult].
|
||||
type Result[Shape, OK, Err any] struct{ result[Shape, OK, Err] }
|
||||
type Result[Shape, OK, Err any] struct {
|
||||
_ HostLayout
|
||||
result[Shape, OK, Err]
|
||||
}
|
||||
|
||||
// AnyResult is a type constraint for generic functions that accept any [Result] type.
|
||||
type AnyResult[Shape, OK, Err any] interface {
|
||||
~struct {
|
||||
_ HostLayout
|
||||
result[Shape, OK, Err]
|
||||
}
|
||||
}
|
||||
|
||||
// result represents the internal representation of a Component Model result type.
|
||||
type result[Shape, OK, Err any] struct {
|
||||
_ HostLayout
|
||||
isErr bool
|
||||
_ [0]OK
|
||||
_ [0]Err
|
||||
@@ -88,8 +100,8 @@ func (r *result[Shape, OK, Err]) validate() {
|
||||
|
||||
// OK returns an OK result with shape Shape and type OK and Err.
|
||||
// Pass Result[OK, OK, Err] or Result[Err, OK, Err] as the first type argument.
|
||||
func OK[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](ok OK) R {
|
||||
var r struct{ result[Shape, OK, Err] }
|
||||
func OK[R AnyResult[Shape, OK, Err], Shape, OK, Err any](ok OK) R {
|
||||
var r Result[Shape, OK, Err]
|
||||
r.validate()
|
||||
r.isErr = ResultOK
|
||||
*((*OK)(unsafe.Pointer(&r.data))) = ok
|
||||
@@ -98,8 +110,8 @@ func OK[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](ok OK) R {
|
||||
|
||||
// Err returns an error result with shape Shape and type OK and Err.
|
||||
// Pass Result[OK, OK, Err] or Result[Err, OK, Err] as the first type argument.
|
||||
func Err[R ~struct{ result[Shape, OK, Err] }, Shape, OK, Err any](err Err) R {
|
||||
var r struct{ result[Shape, OK, Err] }
|
||||
func Err[R AnyResult[Shape, OK, Err], Shape, OK, Err any](err Err) R {
|
||||
var r Result[Shape, OK, Err]
|
||||
r.validate()
|
||||
r.isErr = ResultErr
|
||||
*((*Err)(unsafe.Pointer(&r.data))) = err
|
||||
|
||||
@@ -4,6 +4,7 @@ package cm
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple[T0, T1 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
}
|
||||
@@ -12,6 +13,7 @@ type Tuple[T0, T1 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple3[T0, T1, T2 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -21,6 +23,7 @@ type Tuple3[T0, T1, T2 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple4[T0, T1, T2, T3 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -31,6 +34,7 @@ type Tuple4[T0, T1, T2, T3 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple5[T0, T1, T2, T3, T4 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -42,6 +46,7 @@ type Tuple5[T0, T1, T2, T3, T4 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple6[T0, T1, T2, T3, T4, T5 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -54,6 +59,7 @@ type Tuple6[T0, T1, T2, T3, T4, T5 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple7[T0, T1, T2, T3, T4, T5, T6 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -67,6 +73,7 @@ type Tuple7[T0, T1, T2, T3, T4, T5, T6 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple8[T0, T1, T2, T3, T4, T5, T6, T7 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -81,6 +88,7 @@ type Tuple8[T0, T1, T2, T3, T4, T5, T6, T7 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -96,6 +104,7 @@ type Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -112,6 +121,7 @@ type Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -129,6 +139,7 @@ type Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -147,6 +158,7 @@ type Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -166,6 +178,7 @@ type Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any] struct {
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -186,6 +199,7 @@ type Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any] str
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
@@ -207,6 +221,7 @@ type Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any
|
||||
//
|
||||
// [Component Model tuple]: https://component-model.bytecodealliance.org/design/wit.html#tuples
|
||||
type Tuple16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any] struct {
|
||||
_ HostLayout
|
||||
F0 T0
|
||||
F1 T1
|
||||
F2 T2
|
||||
|
||||
@@ -12,7 +12,18 @@ type Discriminant interface {
|
||||
// Variant represents a loosely-typed Component Model variant.
|
||||
// Shape and Align must be non-zero sized types. To create a variant with no associated
|
||||
// types, use an enum.
|
||||
type Variant[Tag Discriminant, Shape, Align any] struct{ variant[Tag, Shape, Align] }
|
||||
type Variant[Tag Discriminant, Shape, Align any] struct {
|
||||
_ HostLayout
|
||||
variant[Tag, Shape, Align]
|
||||
}
|
||||
|
||||
// AnyVariant is a type constraint for generic functions that accept any [Variant] type.
|
||||
type AnyVariant[Tag Discriminant, Shape, Align any] interface {
|
||||
~struct {
|
||||
_ HostLayout
|
||||
variant[Tag, Shape, Align]
|
||||
}
|
||||
}
|
||||
|
||||
// NewVariant returns a [Variant] with tag of type Disc, storage and GC shape of type Shape,
|
||||
// aligned to type Align, with a value of type T.
|
||||
@@ -26,7 +37,7 @@ func NewVariant[Tag Discriminant, Shape, Align any, T any](tag Tag, data T) Vari
|
||||
|
||||
// New returns a [Variant] with tag of type Disc, storage and GC shape of type Shape,
|
||||
// aligned to type Align, with a value of type T.
|
||||
func New[V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shape, Align any, T any](tag Tag, data T) V {
|
||||
func New[V AnyVariant[Tag, Shape, Align], Tag Discriminant, Shape, Align any, T any](tag Tag, data T) V {
|
||||
validateVariant[Tag, Shape, Align, T]()
|
||||
var v variant[Tag, Shape, Align]
|
||||
v.tag = tag
|
||||
@@ -35,7 +46,7 @@ func New[V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shape, Align
|
||||
}
|
||||
|
||||
// Case returns a non-nil *T if the [Variant] case is equal to tag, otherwise it returns nil.
|
||||
func Case[T any, V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shape, Align any](v *V, tag Tag) *T {
|
||||
func Case[T any, V AnyVariant[Tag, Shape, Align], Tag Discriminant, Shape, Align any](v *V, tag Tag) *T {
|
||||
validateVariant[Tag, Shape, Align, T]()
|
||||
v2 := (*variant[Tag, Shape, Align])(unsafe.Pointer(v))
|
||||
if v2.tag == tag {
|
||||
@@ -47,6 +58,7 @@ func Case[T any, V ~struct{ variant[Tag, Shape, Align] }, Tag Discriminant, Shap
|
||||
// variant is the internal representation of a Component Model variant.
|
||||
// Shape and Align must be non-zero sized types.
|
||||
type variant[Tag Discriminant, Shape, Align any] struct {
|
||||
_ HostLayout
|
||||
tag Tag
|
||||
_ [0]Align
|
||||
data Shape // [unsafe.Sizeof(*(*Shape)(unsafe.Pointer(nil)))]byte
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package gclayout
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Internal constants for gc layout
|
||||
// See runtime/gc_precise.go
|
||||
|
||||
var (
|
||||
NoPtrs unsafe.Pointer
|
||||
Pointer unsafe.Pointer
|
||||
String unsafe.Pointer
|
||||
Slice unsafe.Pointer
|
||||
)
|
||||
|
||||
func init() {
|
||||
var sizeBits uintptr
|
||||
|
||||
switch unsafe.Sizeof(uintptr(0)) {
|
||||
case 8:
|
||||
sizeBits = 6
|
||||
case 4:
|
||||
sizeBits = 5
|
||||
case 2:
|
||||
sizeBits = 4
|
||||
}
|
||||
|
||||
var sizeShift = sizeBits + 1
|
||||
|
||||
NoPtrs = unsafe.Pointer(uintptr(0b0<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||
Pointer = unsafe.Pointer(uintptr(0b1<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||
String = unsafe.Pointer(uintptr(0b01<<sizeShift) | uintptr(0b10<<1) | uintptr(1))
|
||||
Slice = unsafe.Pointer(uintptr(0b001<<sizeShift) | uintptr(0b11<<1) | uintptr(1))
|
||||
}
|
||||
@@ -30,3 +30,6 @@ type Task struct {
|
||||
// the given function and falls back to the default stack size. It is replaced
|
||||
// with a load from a special section just before codegen.
|
||||
func getGoroutineStackSize(fn uintptr) uintptr
|
||||
|
||||
//go:linkname runtime_alloc runtime.alloc
|
||||
func runtime_alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
|
||||
|
||||
@@ -35,11 +35,16 @@ type state struct {
|
||||
type stackState struct {
|
||||
// asyncify is the stack pointer of the asyncify stack.
|
||||
// This starts from the bottom and grows upwards.
|
||||
asyncifysp uintptr
|
||||
asyncifysp unsafe.Pointer
|
||||
|
||||
// asyncify is stack pointer of the C stack.
|
||||
// This starts from the top and grows downwards.
|
||||
csp uintptr
|
||||
csp unsafe.Pointer
|
||||
|
||||
// Pointer to the first (lowest address) of the stack. It must never be
|
||||
// overwritten. It can be checked from time to time to see whether a stack
|
||||
// overflow happened in the past.
|
||||
canaryPtr *uintptr
|
||||
}
|
||||
|
||||
// start creates and starts a new goroutine with the given function and arguments.
|
||||
@@ -63,12 +68,18 @@ func (s *state) initialize(fn uintptr, args unsafe.Pointer, stackSize uintptr) {
|
||||
s.args = args
|
||||
|
||||
// Create a stack.
|
||||
stack := make([]uintptr, stackSize/unsafe.Sizeof(uintptr(0)))
|
||||
stack := runtime_alloc(stackSize, nil)
|
||||
|
||||
// Set up the stack canary, a random number that should be checked when
|
||||
// switching from the task back to the scheduler. The stack canary pointer
|
||||
// points to the first word of the stack. If it has changed between now and
|
||||
// the next stack switch, there was a stack overflow.
|
||||
s.canaryPtr = (*uintptr)(stack)
|
||||
*s.canaryPtr = stackCanary
|
||||
|
||||
// Calculate stack base addresses.
|
||||
s.asyncifysp = uintptr(unsafe.Pointer(&stack[0]))
|
||||
s.csp = uintptr(unsafe.Pointer(&stack[0])) + uintptr(len(stack))*unsafe.Sizeof(uintptr(0))
|
||||
stack[0] = stackCanary
|
||||
s.asyncifysp = unsafe.Add(stack, unsafe.Sizeof(uintptr(0)))
|
||||
s.csp = unsafe.Add(stack, stackSize)
|
||||
}
|
||||
|
||||
//go:linkname runqueuePushBack runtime.runqueuePushBack
|
||||
@@ -85,14 +96,11 @@ func Current() *Task {
|
||||
// Pause suspends the current task and returns to the scheduler.
|
||||
// This function may only be called when running on a goroutine stack, not when running on the system stack.
|
||||
func Pause() {
|
||||
// This is mildly unsafe but this is also the only place we can do this.
|
||||
if *(*uintptr)(unsafe.Pointer(currentTask.state.asyncifysp)) != stackCanary {
|
||||
if *currentTask.state.canaryPtr != stackCanary {
|
||||
runtimePanic("stack overflow")
|
||||
}
|
||||
|
||||
currentTask.state.unwind()
|
||||
|
||||
*(*uintptr)(unsafe.Pointer(currentTask.state.asyncifysp)) = stackCanary
|
||||
}
|
||||
|
||||
//export tinygo_unwind
|
||||
@@ -113,7 +121,7 @@ func (t *Task) Resume() {
|
||||
}
|
||||
currentTask = prevTask
|
||||
t.gcData.swap()
|
||||
if t.state.asyncifysp > t.state.csp {
|
||||
if uintptr(t.state.asyncifysp) > uintptr(t.state.csp) {
|
||||
runtimePanic("stack overflow")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,6 @@ var startTask [0]uint8
|
||||
//go:linkname runqueuePushBack runtime.runqueuePushBack
|
||||
func runqueuePushBack(*Task)
|
||||
|
||||
//go:linkname runtime_alloc runtime.alloc
|
||||
func runtime_alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
|
||||
|
||||
// start creates and starts a new goroutine with the given function and arguments.
|
||||
// The new goroutine is scheduled to run later.
|
||||
func start(fn uintptr, args unsafe.Pointer, stackSize uintptr) {
|
||||
|
||||
+2099
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package environment
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/environment@0.2.0 get-environment
|
||||
//go:noescape
|
||||
func wasmimport_GetEnvironment(result *cm.List[[2]string])
|
||||
|
||||
//go:wasmimport wasi:cli/environment@0.2.0 get-arguments
|
||||
//go:noescape
|
||||
func wasmimport_GetArguments(result *cm.List[string])
|
||||
|
||||
//go:wasmimport wasi:cli/environment@0.2.0 initial-cwd
|
||||
//go:noescape
|
||||
func wasmimport_InitialCWD(result *cm.Option[string])
|
||||
@@ -26,10 +26,6 @@ func GetEnvironment() (result cm.List[[2]string]) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/environment@0.2.0 get-environment
|
||||
//go:noescape
|
||||
func wasmimport_GetEnvironment(result *cm.List[[2]string])
|
||||
|
||||
// GetArguments represents the imported function "get-arguments".
|
||||
//
|
||||
// Get the POSIX-style arguments to the program.
|
||||
@@ -42,10 +38,6 @@ func GetArguments() (result cm.List[string]) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/environment@0.2.0 get-arguments
|
||||
//go:noescape
|
||||
func wasmimport_GetArguments(result *cm.List[string])
|
||||
|
||||
// InitialCWD represents the imported function "initial-cwd".
|
||||
//
|
||||
// Return a path that programs should use as their initial current working
|
||||
@@ -58,7 +50,3 @@ func InitialCWD() (result cm.Option[string]) {
|
||||
wasmimport_InitialCWD(&result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/environment@0.2.0 initial-cwd
|
||||
//go:noescape
|
||||
func wasmimport_InitialCWD(result *cm.Option[string])
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package exit
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/exit@0.2.0 exit
|
||||
//go:noescape
|
||||
func wasmimport_Exit(status0 uint32)
|
||||
@@ -19,7 +19,3 @@ func Exit(status cm.BoolResult) {
|
||||
wasmimport_Exit((uint32)(status0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/exit@0.2.0 exit
|
||||
//go:noescape
|
||||
func wasmimport_Exit(status0 uint32)
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package run
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmexport wasi:cli/run@0.2.0#run
|
||||
//export wasi:cli/run@0.2.0#run
|
||||
func wasmexport_Run() (result0 uint32) {
|
||||
result := Exports.Run()
|
||||
result0 = cm.BoolToU32(result)
|
||||
return
|
||||
}
|
||||
@@ -2,15 +2,3 @@
|
||||
|
||||
// Package run represents the exported interface "wasi:cli/run@0.2.0".
|
||||
package run
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
//go:wasmexport wasi:cli/run@0.2.0#run
|
||||
//export wasi:cli/run@0.2.0#run
|
||||
func wasmexport_Run() (result0 uint32) {
|
||||
result := Exports.Run()
|
||||
result0 = cm.BoolToU32(result)
|
||||
return
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package stderr
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/stderr@0.2.0 get-stderr
|
||||
//go:noescape
|
||||
func wasmimport_GetStderr() (result0 uint32)
|
||||
@@ -8,17 +8,18 @@ import (
|
||||
"internal/wasi/io/v0.2.0/streams"
|
||||
)
|
||||
|
||||
// OutputStream represents the imported type alias "wasi:cli/stderr@0.2.0#output-stream".
|
||||
//
|
||||
// See [streams.OutputStream] for more information.
|
||||
type OutputStream = streams.OutputStream
|
||||
|
||||
// GetStderr represents the imported function "get-stderr".
|
||||
//
|
||||
// get-stderr: func() -> output-stream
|
||||
//
|
||||
//go:nosplit
|
||||
func GetStderr() (result streams.OutputStream) {
|
||||
func GetStderr() (result OutputStream) {
|
||||
result0 := wasmimport_GetStderr()
|
||||
result = cm.Reinterpret[streams.OutputStream]((uint32)(result0))
|
||||
result = cm.Reinterpret[OutputStream]((uint32)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/stderr@0.2.0 get-stderr
|
||||
//go:noescape
|
||||
func wasmimport_GetStderr() (result0 uint32)
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package stdin
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/stdin@0.2.0 get-stdin
|
||||
//go:noescape
|
||||
func wasmimport_GetStdin() (result0 uint32)
|
||||
@@ -8,17 +8,18 @@ import (
|
||||
"internal/wasi/io/v0.2.0/streams"
|
||||
)
|
||||
|
||||
// InputStream represents the imported type alias "wasi:cli/stdin@0.2.0#input-stream".
|
||||
//
|
||||
// See [streams.InputStream] for more information.
|
||||
type InputStream = streams.InputStream
|
||||
|
||||
// GetStdin represents the imported function "get-stdin".
|
||||
//
|
||||
// get-stdin: func() -> input-stream
|
||||
//
|
||||
//go:nosplit
|
||||
func GetStdin() (result streams.InputStream) {
|
||||
func GetStdin() (result InputStream) {
|
||||
result0 := wasmimport_GetStdin()
|
||||
result = cm.Reinterpret[streams.InputStream]((uint32)(result0))
|
||||
result = cm.Reinterpret[InputStream]((uint32)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/stdin@0.2.0 get-stdin
|
||||
//go:noescape
|
||||
func wasmimport_GetStdin() (result0 uint32)
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package stdout
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/stdout@0.2.0 get-stdout
|
||||
//go:noescape
|
||||
func wasmimport_GetStdout() (result0 uint32)
|
||||
@@ -8,17 +8,18 @@ import (
|
||||
"internal/wasi/io/v0.2.0/streams"
|
||||
)
|
||||
|
||||
// OutputStream represents the imported type alias "wasi:cli/stdout@0.2.0#output-stream".
|
||||
//
|
||||
// See [streams.OutputStream] for more information.
|
||||
type OutputStream = streams.OutputStream
|
||||
|
||||
// GetStdout represents the imported function "get-stdout".
|
||||
//
|
||||
// get-stdout: func() -> output-stream
|
||||
//
|
||||
//go:nosplit
|
||||
func GetStdout() (result streams.OutputStream) {
|
||||
func GetStdout() (result OutputStream) {
|
||||
result0 := wasmimport_GetStdout()
|
||||
result = cm.Reinterpret[streams.OutputStream]((uint32)(result0))
|
||||
result = cm.Reinterpret[OutputStream]((uint32)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/stdout@0.2.0 get-stdout
|
||||
//go:noescape
|
||||
func wasmimport_GetStdout() (result0 uint32)
|
||||
|
||||
@@ -30,7 +30,3 @@ func (self TerminalInput) ResourceDrop() {
|
||||
wasmimport_TerminalInputResourceDrop((uint32)(self0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-input@0.2.0 [resource-drop]terminal-input
|
||||
//go:noescape
|
||||
func wasmimport_TerminalInputResourceDrop(self0 uint32)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package terminalinput
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-input@0.2.0 [resource-drop]terminal-input
|
||||
//go:noescape
|
||||
func wasmimport_TerminalInputResourceDrop(self0 uint32)
|
||||
@@ -30,7 +30,3 @@ func (self TerminalOutput) ResourceDrop() {
|
||||
wasmimport_TerminalOutputResourceDrop((uint32)(self0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-output@0.2.0 [resource-drop]terminal-output
|
||||
//go:noescape
|
||||
func wasmimport_TerminalOutputResourceDrop(self0 uint32)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package terminaloutput
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-output@0.2.0 [resource-drop]terminal-output
|
||||
//go:noescape
|
||||
func wasmimport_TerminalOutputResourceDrop(self0 uint32)
|
||||
@@ -11,6 +11,11 @@ import (
|
||||
terminaloutput "internal/wasi/cli/v0.2.0/terminal-output"
|
||||
)
|
||||
|
||||
// TerminalOutput represents the imported type alias "wasi:cli/terminal-stderr@0.2.0#terminal-output".
|
||||
//
|
||||
// See [terminaloutput.TerminalOutput] for more information.
|
||||
type TerminalOutput = terminaloutput.TerminalOutput
|
||||
|
||||
// GetTerminalStderr represents the imported function "get-terminal-stderr".
|
||||
//
|
||||
// If stderr is connected to a terminal, return a `terminal-output` handle
|
||||
@@ -19,11 +24,7 @@ import (
|
||||
// get-terminal-stderr: func() -> option<terminal-output>
|
||||
//
|
||||
//go:nosplit
|
||||
func GetTerminalStderr() (result cm.Option[terminaloutput.TerminalOutput]) {
|
||||
func GetTerminalStderr() (result cm.Option[TerminalOutput]) {
|
||||
wasmimport_GetTerminalStderr(&result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-stderr@0.2.0 get-terminal-stderr
|
||||
//go:noescape
|
||||
func wasmimport_GetTerminalStderr(result *cm.Option[terminaloutput.TerminalOutput])
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package terminalstderr
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-stderr@0.2.0 get-terminal-stderr
|
||||
//go:noescape
|
||||
func wasmimport_GetTerminalStderr(result *cm.Option[TerminalOutput])
|
||||
@@ -11,6 +11,11 @@ import (
|
||||
terminalinput "internal/wasi/cli/v0.2.0/terminal-input"
|
||||
)
|
||||
|
||||
// TerminalInput represents the imported type alias "wasi:cli/terminal-stdin@0.2.0#terminal-input".
|
||||
//
|
||||
// See [terminalinput.TerminalInput] for more information.
|
||||
type TerminalInput = terminalinput.TerminalInput
|
||||
|
||||
// GetTerminalStdin represents the imported function "get-terminal-stdin".
|
||||
//
|
||||
// If stdin is connected to a terminal, return a `terminal-input` handle
|
||||
@@ -19,11 +24,7 @@ import (
|
||||
// get-terminal-stdin: func() -> option<terminal-input>
|
||||
//
|
||||
//go:nosplit
|
||||
func GetTerminalStdin() (result cm.Option[terminalinput.TerminalInput]) {
|
||||
func GetTerminalStdin() (result cm.Option[TerminalInput]) {
|
||||
wasmimport_GetTerminalStdin(&result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-stdin@0.2.0 get-terminal-stdin
|
||||
//go:noescape
|
||||
func wasmimport_GetTerminalStdin(result *cm.Option[terminalinput.TerminalInput])
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package terminalstdin
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-stdin@0.2.0 get-terminal-stdin
|
||||
//go:noescape
|
||||
func wasmimport_GetTerminalStdin(result *cm.Option[TerminalInput])
|
||||
@@ -11,6 +11,11 @@ import (
|
||||
terminaloutput "internal/wasi/cli/v0.2.0/terminal-output"
|
||||
)
|
||||
|
||||
// TerminalOutput represents the imported type alias "wasi:cli/terminal-stdout@0.2.0#terminal-output".
|
||||
//
|
||||
// See [terminaloutput.TerminalOutput] for more information.
|
||||
type TerminalOutput = terminaloutput.TerminalOutput
|
||||
|
||||
// GetTerminalStdout represents the imported function "get-terminal-stdout".
|
||||
//
|
||||
// If stdout is connected to a terminal, return a `terminal-output` handle
|
||||
@@ -19,11 +24,7 @@ import (
|
||||
// get-terminal-stdout: func() -> option<terminal-output>
|
||||
//
|
||||
//go:nosplit
|
||||
func GetTerminalStdout() (result cm.Option[terminaloutput.TerminalOutput]) {
|
||||
func GetTerminalStdout() (result cm.Option[TerminalOutput]) {
|
||||
wasmimport_GetTerminalStdout(&result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-stdout@0.2.0 get-terminal-stdout
|
||||
//go:noescape
|
||||
func wasmimport_GetTerminalStdout(result *cm.Option[terminaloutput.TerminalOutput])
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package terminalstdout
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:cli@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:cli/terminal-stdout@0.2.0 get-terminal-stdout
|
||||
//go:noescape
|
||||
func wasmimport_GetTerminalStdout(result *cm.Option[TerminalOutput])
|
||||
@@ -19,6 +19,11 @@ import (
|
||||
"internal/wasi/io/v0.2.0/poll"
|
||||
)
|
||||
|
||||
// Pollable represents the imported type alias "wasi:clocks/monotonic-clock@0.2.0#pollable".
|
||||
//
|
||||
// See [poll.Pollable] for more information.
|
||||
type Pollable = poll.Pollable
|
||||
|
||||
// Instant represents the u64 "wasi:clocks/monotonic-clock@0.2.0#instant".
|
||||
//
|
||||
// An instant in time, in nanoseconds. An instant is relative to an
|
||||
@@ -51,10 +56,6 @@ func Now() (result Instant) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 now
|
||||
//go:noescape
|
||||
func wasmimport_Now() (result0 uint64)
|
||||
|
||||
// Resolution represents the imported function "resolution".
|
||||
//
|
||||
// Query the resolution of the clock. Returns the duration of time
|
||||
@@ -69,10 +70,6 @@ func Resolution() (result Duration) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 resolution
|
||||
//go:noescape
|
||||
func wasmimport_Resolution() (result0 uint64)
|
||||
|
||||
// SubscribeInstant represents the imported function "subscribe-instant".
|
||||
//
|
||||
// Create a `pollable` which will resolve once the specified instant
|
||||
@@ -81,17 +78,13 @@ func wasmimport_Resolution() (result0 uint64)
|
||||
// subscribe-instant: func(when: instant) -> pollable
|
||||
//
|
||||
//go:nosplit
|
||||
func SubscribeInstant(when Instant) (result poll.Pollable) {
|
||||
func SubscribeInstant(when Instant) (result Pollable) {
|
||||
when0 := (uint64)(when)
|
||||
result0 := wasmimport_SubscribeInstant((uint64)(when0))
|
||||
result = cm.Reinterpret[poll.Pollable]((uint32)(result0))
|
||||
result = cm.Reinterpret[Pollable]((uint32)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 subscribe-instant
|
||||
//go:noescape
|
||||
func wasmimport_SubscribeInstant(when0 uint64) (result0 uint32)
|
||||
|
||||
// SubscribeDuration represents the imported function "subscribe-duration".
|
||||
//
|
||||
// Create a `pollable` which will resolve once the given duration has
|
||||
@@ -101,13 +94,9 @@ func wasmimport_SubscribeInstant(when0 uint64) (result0 uint32)
|
||||
// subscribe-duration: func(when: duration) -> pollable
|
||||
//
|
||||
//go:nosplit
|
||||
func SubscribeDuration(when Duration) (result poll.Pollable) {
|
||||
func SubscribeDuration(when Duration) (result Pollable) {
|
||||
when0 := (uint64)(when)
|
||||
result0 := wasmimport_SubscribeDuration((uint64)(when0))
|
||||
result = cm.Reinterpret[poll.Pollable]((uint32)(result0))
|
||||
result = cm.Reinterpret[Pollable]((uint32)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 subscribe-duration
|
||||
//go:noescape
|
||||
func wasmimport_SubscribeDuration(when0 uint64) (result0 uint32)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package monotonicclock
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:clocks@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 now
|
||||
//go:noescape
|
||||
func wasmimport_Now() (result0 uint64)
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 resolution
|
||||
//go:noescape
|
||||
func wasmimport_Resolution() (result0 uint64)
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 subscribe-instant
|
||||
//go:noescape
|
||||
func wasmimport_SubscribeInstant(when0 uint64) (result0 uint32)
|
||||
|
||||
//go:wasmimport wasi:clocks/monotonic-clock@0.2.0 subscribe-duration
|
||||
//go:noescape
|
||||
func wasmimport_SubscribeDuration(when0 uint64) (result0 uint32)
|
||||
@@ -18,6 +18,10 @@
|
||||
// It is intended for reporting the current date and time for humans.
|
||||
package wallclock
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// DateTime represents the record "wasi:clocks/wall-clock@0.2.0#datetime".
|
||||
//
|
||||
// A time and date in seconds plus nanoseconds.
|
||||
@@ -27,6 +31,7 @@ package wallclock
|
||||
// nanoseconds: u32,
|
||||
// }
|
||||
type DateTime struct {
|
||||
_ cm.HostLayout
|
||||
Seconds uint64
|
||||
Nanoseconds uint32
|
||||
}
|
||||
@@ -55,10 +60,6 @@ func Now() (result DateTime) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:clocks/wall-clock@0.2.0 now
|
||||
//go:noescape
|
||||
func wasmimport_Now(result *DateTime)
|
||||
|
||||
// Resolution represents the imported function "resolution".
|
||||
//
|
||||
// Query the resolution of the clock.
|
||||
@@ -72,7 +73,3 @@ func Resolution() (result DateTime) {
|
||||
wasmimport_Resolution(&result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:clocks/wall-clock@0.2.0 resolution
|
||||
//go:noescape
|
||||
func wasmimport_Resolution(result *DateTime)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package wallclock
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:clocks@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:clocks/wall-clock@0.2.0 now
|
||||
//go:noescape
|
||||
func wasmimport_Now(result *DateTime)
|
||||
|
||||
//go:wasmimport wasi:clocks/wall-clock@0.2.0 resolution
|
||||
//go:noescape
|
||||
func wasmimport_Resolution(result *DateTime)
|
||||
@@ -0,0 +1,13 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package preopens
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:filesystem@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:filesystem/preopens@0.2.0 get-directories
|
||||
//go:noescape
|
||||
func wasmimport_GetDirectories(result *cm.List[cm.Tuple[Descriptor, string]])
|
||||
@@ -8,6 +8,11 @@ import (
|
||||
"internal/wasi/filesystem/v0.2.0/types"
|
||||
)
|
||||
|
||||
// Descriptor represents the imported type alias "wasi:filesystem/preopens@0.2.0#descriptor".
|
||||
//
|
||||
// See [types.Descriptor] for more information.
|
||||
type Descriptor = types.Descriptor
|
||||
|
||||
// GetDirectories represents the imported function "get-directories".
|
||||
//
|
||||
// Return the set of preopened directories, and their path.
|
||||
@@ -15,11 +20,7 @@ import (
|
||||
// get-directories: func() -> list<tuple<descriptor, string>>
|
||||
//
|
||||
//go:nosplit
|
||||
func GetDirectories() (result cm.List[cm.Tuple[types.Descriptor, string]]) {
|
||||
func GetDirectories() (result cm.List[cm.Tuple[Descriptor, string]]) {
|
||||
wasmimport_GetDirectories(&result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/preopens@0.2.0 get-directories
|
||||
//go:noescape
|
||||
func wasmimport_GetDirectories(result *cm.List[cm.Tuple[types.Descriptor, string]])
|
||||
|
||||
@@ -8,18 +8,15 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// DateTimeShape is used for storage in variant or result types.
|
||||
type DateTimeShape struct {
|
||||
shape [unsafe.Sizeof(wallclock.DateTime{})]byte
|
||||
}
|
||||
|
||||
// MetadataHashValueShape is used for storage in variant or result types.
|
||||
type MetadataHashValueShape struct {
|
||||
_ cm.HostLayout
|
||||
shape [unsafe.Sizeof(MetadataHashValue{})]byte
|
||||
}
|
||||
|
||||
// TupleListU8BoolShape is used for storage in variant or result types.
|
||||
type TupleListU8BoolShape struct {
|
||||
_ cm.HostLayout
|
||||
shape [unsafe.Sizeof(cm.Tuple[cm.List[uint8], bool]{})]byte
|
||||
}
|
||||
|
||||
@@ -42,10 +39,12 @@ func lower_NewTimestamp(v NewTimestamp) (f0 uint32, f1 uint64, f2 uint32) {
|
||||
|
||||
// DescriptorStatShape is used for storage in variant or result types.
|
||||
type DescriptorStatShape struct {
|
||||
_ cm.HostLayout
|
||||
shape [unsafe.Sizeof(DescriptorStat{})]byte
|
||||
}
|
||||
|
||||
// OptionDirectoryEntryShape is used for storage in variant or result types.
|
||||
type OptionDirectoryEntryShape struct {
|
||||
_ cm.HostLayout
|
||||
shape [unsafe.Sizeof(cm.Option[DirectoryEntry]{})]byte
|
||||
}
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:filesystem@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [resource-drop]descriptor
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorResourceDrop(self0 uint32)
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.advise
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorAdvise(self0 uint32, offset0 uint64, length0 uint64, advice0 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.append-via-stream
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorAppendViaStream(self0 uint32, result *cm.Result[OutputStream, OutputStream, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.create-directory-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorCreateDirectoryAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.get-flags
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorGetFlags(self0 uint32, result *cm.Result[DescriptorFlags, DescriptorFlags, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.get-type
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorGetType(self0 uint32, result *cm.Result[DescriptorType, DescriptorType, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.is-same-object
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorIsSameObject(self0 uint32, other0 uint32) (result0 uint32)
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.link-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorLinkAt(self0 uint32, oldPathFlags0 uint32, oldPath0 *uint8, oldPath1 uint32, newDescriptor0 uint32, newPath0 *uint8, newPath1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.metadata-hash
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorMetadataHash(self0 uint32, result *cm.Result[MetadataHashValueShape, MetadataHashValue, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.metadata-hash-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorMetadataHashAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, result *cm.Result[MetadataHashValueShape, MetadataHashValue, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.open-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorOpenAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, openFlags0 uint32, flags0 uint32, result *cm.Result[Descriptor, Descriptor, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.read
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorRead(self0 uint32, length0 uint64, offset0 uint64, result *cm.Result[TupleListU8BoolShape, cm.Tuple[cm.List[uint8], bool], ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.read-directory
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorReadDirectory(self0 uint32, result *cm.Result[DirectoryEntryStream, DirectoryEntryStream, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.read-via-stream
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorReadViaStream(self0 uint32, offset0 uint64, result *cm.Result[InputStream, InputStream, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.readlink-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorReadLinkAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[string, string, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.remove-directory-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorRemoveDirectoryAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.rename-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorRenameAt(self0 uint32, oldPath0 *uint8, oldPath1 uint32, newDescriptor0 uint32, newPath0 *uint8, newPath1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.set-size
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSetSize(self0 uint32, size0 uint64, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.set-times
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSetTimes(self0 uint32, dataAccessTimestamp0 uint32, dataAccessTimestamp1 uint64, dataAccessTimestamp2 uint32, dataModificationTimestamp0 uint32, dataModificationTimestamp1 uint64, dataModificationTimestamp2 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.set-times-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSetTimesAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, dataAccessTimestamp0 uint32, dataAccessTimestamp1 uint64, dataAccessTimestamp2 uint32, dataModificationTimestamp0 uint32, dataModificationTimestamp1 uint64, dataModificationTimestamp2 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.stat
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorStat(self0 uint32, result *cm.Result[DescriptorStatShape, DescriptorStat, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.stat-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorStatAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, result *cm.Result[DescriptorStatShape, DescriptorStat, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.symlink-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSymlinkAt(self0 uint32, oldPath0 *uint8, oldPath1 uint32, newPath0 *uint8, newPath1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.sync
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSync(self0 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.sync-data
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSyncData(self0 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.unlink-file-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorUnlinkFileAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.write
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorWrite(self0 uint32, buffer0 *uint8, buffer1 uint32, offset0 uint64, result *cm.Result[uint64, FileSize, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.write-via-stream
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorWriteViaStream(self0 uint32, offset0 uint64, result *cm.Result[OutputStream, OutputStream, ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [resource-drop]directory-entry-stream
|
||||
//go:noescape
|
||||
func wasmimport_DirectoryEntryStreamResourceDrop(self0 uint32)
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]directory-entry-stream.read-directory-entry
|
||||
//go:noescape
|
||||
func wasmimport_DirectoryEntryStreamReadDirectoryEntry(self0 uint32, result *cm.Result[OptionDirectoryEntryShape, cm.Option[DirectoryEntry], ErrorCode])
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 filesystem-error-code
|
||||
//go:noescape
|
||||
func wasmimport_FilesystemErrorCode(err0 uint32, result *cm.Option[ErrorCode])
|
||||
@@ -31,10 +31,29 @@ package types
|
||||
import (
|
||||
"internal/cm"
|
||||
wallclock "internal/wasi/clocks/v0.2.0/wall-clock"
|
||||
ioerror "internal/wasi/io/v0.2.0/error"
|
||||
"internal/wasi/io/v0.2.0/streams"
|
||||
)
|
||||
|
||||
// InputStream represents the imported type alias "wasi:filesystem/types@0.2.0#input-stream".
|
||||
//
|
||||
// See [streams.InputStream] for more information.
|
||||
type InputStream = streams.InputStream
|
||||
|
||||
// OutputStream represents the imported type alias "wasi:filesystem/types@0.2.0#output-stream".
|
||||
//
|
||||
// See [streams.OutputStream] for more information.
|
||||
type OutputStream = streams.OutputStream
|
||||
|
||||
// Error represents the imported type alias "wasi:filesystem/types@0.2.0#error".
|
||||
//
|
||||
// See [streams.Error] for more information.
|
||||
type Error = streams.Error
|
||||
|
||||
// DateTime represents the type alias "wasi:filesystem/types@0.2.0#datetime".
|
||||
//
|
||||
// See [wallclock.DateTime] for more information.
|
||||
type DateTime = wallclock.DateTime
|
||||
|
||||
// FileSize represents the u64 "wasi:filesystem/types@0.2.0#filesize".
|
||||
//
|
||||
// File size or length of a region within a file.
|
||||
@@ -227,6 +246,7 @@ type LinkCount uint64
|
||||
// status-change-timestamp: option<datetime>,
|
||||
// }
|
||||
type DescriptorStat struct {
|
||||
_ cm.HostLayout
|
||||
// File type.
|
||||
Type DescriptorType
|
||||
|
||||
@@ -241,19 +261,19 @@ type DescriptorStat struct {
|
||||
//
|
||||
// If the `option` is none, the platform doesn't maintain an access
|
||||
// timestamp for this file.
|
||||
DataAccessTimestamp cm.Option[wallclock.DateTime]
|
||||
DataAccessTimestamp cm.Option[DateTime]
|
||||
|
||||
// Last data modification timestamp.
|
||||
//
|
||||
// If the `option` is none, the platform doesn't maintain a
|
||||
// modification timestamp for this file.
|
||||
DataModificationTimestamp cm.Option[wallclock.DateTime]
|
||||
DataModificationTimestamp cm.Option[DateTime]
|
||||
|
||||
// Last file status-change timestamp.
|
||||
//
|
||||
// If the `option` is none, the platform doesn't maintain a
|
||||
// status-change timestamp for this file.
|
||||
StatusChangeTimestamp cm.Option[wallclock.DateTime]
|
||||
StatusChangeTimestamp cm.Option[DateTime]
|
||||
}
|
||||
|
||||
// NewTimestamp represents the variant "wasi:filesystem/types@0.2.0#new-timestamp".
|
||||
@@ -265,7 +285,7 @@ type DescriptorStat struct {
|
||||
// now,
|
||||
// timestamp(datetime),
|
||||
// }
|
||||
type NewTimestamp cm.Variant[uint8, wallclock.DateTime, wallclock.DateTime]
|
||||
type NewTimestamp cm.Variant[uint8, DateTime, DateTime]
|
||||
|
||||
// NewTimestampNoChange returns a [NewTimestamp] of case "no-change".
|
||||
//
|
||||
@@ -297,13 +317,24 @@ func (self *NewTimestamp) Now() bool {
|
||||
// NewTimestampTimestamp returns a [NewTimestamp] of case "timestamp".
|
||||
//
|
||||
// Set the timestamp to the given value.
|
||||
func NewTimestampTimestamp(data wallclock.DateTime) NewTimestamp {
|
||||
func NewTimestampTimestamp(data DateTime) NewTimestamp {
|
||||
return cm.New[NewTimestamp](2, data)
|
||||
}
|
||||
|
||||
// Timestamp returns a non-nil *[wallclock.DateTime] if [NewTimestamp] represents the variant case "timestamp".
|
||||
func (self *NewTimestamp) Timestamp() *wallclock.DateTime {
|
||||
return cm.Case[wallclock.DateTime](self, 2)
|
||||
// Timestamp returns a non-nil *[DateTime] if [NewTimestamp] represents the variant case "timestamp".
|
||||
func (self *NewTimestamp) Timestamp() *DateTime {
|
||||
return cm.Case[DateTime](self, 2)
|
||||
}
|
||||
|
||||
var stringsNewTimestamp = [3]string{
|
||||
"no-change",
|
||||
"now",
|
||||
"timestamp",
|
||||
}
|
||||
|
||||
// String implements [fmt.Stringer], returning the variant case name of v.
|
||||
func (v NewTimestamp) String() string {
|
||||
return stringsNewTimestamp[v.Tag()]
|
||||
}
|
||||
|
||||
// DirectoryEntry represents the record "wasi:filesystem/types@0.2.0#directory-entry".
|
||||
@@ -315,6 +346,7 @@ func (self *NewTimestamp) Timestamp() *wallclock.DateTime {
|
||||
// name: string,
|
||||
// }
|
||||
type DirectoryEntry struct {
|
||||
_ cm.HostLayout
|
||||
// The type of the file referred to by this directory entry.
|
||||
Type DescriptorType
|
||||
|
||||
@@ -593,6 +625,7 @@ func (e Advice) String() string {
|
||||
// upper: u64,
|
||||
// }
|
||||
type MetadataHashValue struct {
|
||||
_ cm.HostLayout
|
||||
// 64 bits of a 128-bit hash value.
|
||||
Lower uint64
|
||||
|
||||
@@ -620,10 +653,6 @@ func (self Descriptor) ResourceDrop() {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [resource-drop]descriptor
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorResourceDrop(self0 uint32)
|
||||
|
||||
// Advise represents the imported method "advise".
|
||||
//
|
||||
// Provide file advisory information on a descriptor.
|
||||
@@ -642,10 +671,6 @@ func (self Descriptor) Advise(offset FileSize, length FileSize, advice Advice) (
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.advise
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorAdvise(self0 uint32, offset0 uint64, length0 uint64, advice0 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// AppendViaStream represents the imported method "append-via-stream".
|
||||
//
|
||||
// Return a stream for appending to a file, if available.
|
||||
@@ -658,16 +683,12 @@ func wasmimport_DescriptorAdvise(self0 uint32, offset0 uint64, length0 uint64, a
|
||||
// append-via-stream: func() -> result<output-stream, error-code>
|
||||
//
|
||||
//go:nosplit
|
||||
func (self Descriptor) AppendViaStream() (result cm.Result[streams.OutputStream, streams.OutputStream, ErrorCode]) {
|
||||
func (self Descriptor) AppendViaStream() (result cm.Result[OutputStream, OutputStream, ErrorCode]) {
|
||||
self0 := cm.Reinterpret[uint32](self)
|
||||
wasmimport_DescriptorAppendViaStream((uint32)(self0), &result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.append-via-stream
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorAppendViaStream(self0 uint32, result *cm.Result[streams.OutputStream, streams.OutputStream, ErrorCode])
|
||||
|
||||
// CreateDirectoryAt represents the imported method "create-directory-at".
|
||||
//
|
||||
// Create a directory.
|
||||
@@ -684,10 +705,6 @@ func (self Descriptor) CreateDirectoryAt(path string) (result cm.Result[ErrorCod
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.create-directory-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorCreateDirectoryAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// GetFlags represents the imported method "get-flags".
|
||||
//
|
||||
// Get flags associated with a descriptor.
|
||||
@@ -706,10 +723,6 @@ func (self Descriptor) GetFlags() (result cm.Result[DescriptorFlags, DescriptorF
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.get-flags
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorGetFlags(self0 uint32, result *cm.Result[DescriptorFlags, DescriptorFlags, ErrorCode])
|
||||
|
||||
// GetType represents the imported method "get-type".
|
||||
//
|
||||
// Get the dynamic type of a descriptor.
|
||||
@@ -732,10 +745,6 @@ func (self Descriptor) GetType() (result cm.Result[DescriptorType, DescriptorTyp
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.get-type
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorGetType(self0 uint32, result *cm.Result[DescriptorType, DescriptorType, ErrorCode])
|
||||
|
||||
// IsSameObject represents the imported method "is-same-object".
|
||||
//
|
||||
// Test whether two descriptors refer to the same filesystem object.
|
||||
@@ -756,10 +765,6 @@ func (self Descriptor) IsSameObject(other Descriptor) (result bool) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.is-same-object
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorIsSameObject(self0 uint32, other0 uint32) (result0 uint32)
|
||||
|
||||
// LinkAt represents the imported method "link-at".
|
||||
//
|
||||
// Create a hard link.
|
||||
@@ -780,10 +785,6 @@ func (self Descriptor) LinkAt(oldPathFlags PathFlags, oldPath string, newDescrip
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.link-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorLinkAt(self0 uint32, oldPathFlags0 uint32, oldPath0 *uint8, oldPath1 uint32, newDescriptor0 uint32, newPath0 *uint8, newPath1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// MetadataHash represents the imported method "metadata-hash".
|
||||
//
|
||||
// Return a hash of the metadata associated with a filesystem object referred
|
||||
@@ -815,10 +816,6 @@ func (self Descriptor) MetadataHash() (result cm.Result[MetadataHashValueShape,
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.metadata-hash
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorMetadataHash(self0 uint32, result *cm.Result[MetadataHashValueShape, MetadataHashValue, ErrorCode])
|
||||
|
||||
// MetadataHashAt represents the imported method "metadata-hash-at".
|
||||
//
|
||||
// Return a hash of the metadata associated with a filesystem object referred
|
||||
@@ -838,10 +835,6 @@ func (self Descriptor) MetadataHashAt(pathFlags PathFlags, path string) (result
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.metadata-hash-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorMetadataHashAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, result *cm.Result[MetadataHashValueShape, MetadataHashValue, ErrorCode])
|
||||
|
||||
// OpenAt represents the imported method "open-at".
|
||||
//
|
||||
// Open a file or directory.
|
||||
@@ -877,10 +870,6 @@ func (self Descriptor) OpenAt(pathFlags PathFlags, path string, openFlags OpenFl
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.open-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorOpenAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, openFlags0 uint32, flags0 uint32, result *cm.Result[Descriptor, Descriptor, ErrorCode])
|
||||
|
||||
// Read represents the imported method "read".
|
||||
//
|
||||
// Read from a descriptor, without using and updating the descriptor's offset.
|
||||
@@ -907,10 +896,6 @@ func (self Descriptor) Read(length FileSize, offset FileSize) (result cm.Result[
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.read
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorRead(self0 uint32, length0 uint64, offset0 uint64, result *cm.Result[TupleListU8BoolShape, cm.Tuple[cm.List[uint8], bool], ErrorCode])
|
||||
|
||||
// ReadDirectory represents the imported method "read-directory".
|
||||
//
|
||||
// Read directory entries from a directory.
|
||||
@@ -932,10 +917,6 @@ func (self Descriptor) ReadDirectory() (result cm.Result[DirectoryEntryStream, D
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.read-directory
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorReadDirectory(self0 uint32, result *cm.Result[DirectoryEntryStream, DirectoryEntryStream, ErrorCode])
|
||||
|
||||
// ReadViaStream represents the imported method "read-via-stream".
|
||||
//
|
||||
// Return a stream for reading from a file, if available.
|
||||
@@ -950,17 +931,13 @@ func wasmimport_DescriptorReadDirectory(self0 uint32, result *cm.Result[Director
|
||||
// read-via-stream: func(offset: filesize) -> result<input-stream, error-code>
|
||||
//
|
||||
//go:nosplit
|
||||
func (self Descriptor) ReadViaStream(offset FileSize) (result cm.Result[streams.InputStream, streams.InputStream, ErrorCode]) {
|
||||
func (self Descriptor) ReadViaStream(offset FileSize) (result cm.Result[InputStream, InputStream, ErrorCode]) {
|
||||
self0 := cm.Reinterpret[uint32](self)
|
||||
offset0 := (uint64)(offset)
|
||||
wasmimport_DescriptorReadViaStream((uint32)(self0), (uint64)(offset0), &result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.read-via-stream
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorReadViaStream(self0 uint32, offset0 uint64, result *cm.Result[streams.InputStream, streams.InputStream, ErrorCode])
|
||||
|
||||
// ReadLinkAt represents the imported method "readlink-at".
|
||||
//
|
||||
// Read the contents of a symbolic link.
|
||||
@@ -980,10 +957,6 @@ func (self Descriptor) ReadLinkAt(path string) (result cm.Result[string, string,
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.readlink-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorReadLinkAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[string, string, ErrorCode])
|
||||
|
||||
// RemoveDirectoryAt represents the imported method "remove-directory-at".
|
||||
//
|
||||
// Remove a directory.
|
||||
@@ -1002,10 +975,6 @@ func (self Descriptor) RemoveDirectoryAt(path string) (result cm.Result[ErrorCod
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.remove-directory-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorRemoveDirectoryAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// RenameAt represents the imported method "rename-at".
|
||||
//
|
||||
// Rename a filesystem object.
|
||||
@@ -1025,10 +994,6 @@ func (self Descriptor) RenameAt(oldPath string, newDescriptor Descriptor, newPat
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.rename-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorRenameAt(self0 uint32, oldPath0 *uint8, oldPath1 uint32, newDescriptor0 uint32, newPath0 *uint8, newPath1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// SetSize represents the imported method "set-size".
|
||||
//
|
||||
// Adjust the size of an open file. If this increases the file's size, the
|
||||
@@ -1046,10 +1011,6 @@ func (self Descriptor) SetSize(size FileSize) (result cm.Result[ErrorCode, struc
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.set-size
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSetSize(self0 uint32, size0 uint64, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// SetTimes represents the imported method "set-times".
|
||||
//
|
||||
// Adjust the timestamps of an open file or directory.
|
||||
@@ -1070,10 +1031,6 @@ func (self Descriptor) SetTimes(dataAccessTimestamp NewTimestamp, dataModificati
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.set-times
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSetTimes(self0 uint32, dataAccessTimestamp0 uint32, dataAccessTimestamp1 uint64, dataAccessTimestamp2 uint32, dataModificationTimestamp0 uint32, dataModificationTimestamp1 uint64, dataModificationTimestamp2 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// SetTimesAt represents the imported method "set-times-at".
|
||||
//
|
||||
// Adjust the timestamps of a file or directory.
|
||||
@@ -1097,10 +1054,6 @@ func (self Descriptor) SetTimesAt(pathFlags PathFlags, path string, dataAccessTi
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.set-times-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSetTimesAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, dataAccessTimestamp0 uint32, dataAccessTimestamp1 uint64, dataAccessTimestamp2 uint32, dataModificationTimestamp0 uint32, dataModificationTimestamp1 uint64, dataModificationTimestamp2 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// Stat represents the imported method "stat".
|
||||
//
|
||||
// Return the attributes of an open file or directory.
|
||||
@@ -1122,10 +1075,6 @@ func (self Descriptor) Stat() (result cm.Result[DescriptorStatShape, DescriptorS
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.stat
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorStat(self0 uint32, result *cm.Result[DescriptorStatShape, DescriptorStat, ErrorCode])
|
||||
|
||||
// StatAt represents the imported method "stat-at".
|
||||
//
|
||||
// Return the attributes of a file or directory.
|
||||
@@ -1148,10 +1097,6 @@ func (self Descriptor) StatAt(pathFlags PathFlags, path string) (result cm.Resul
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.stat-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorStatAt(self0 uint32, pathFlags0 uint32, path0 *uint8, path1 uint32, result *cm.Result[DescriptorStatShape, DescriptorStat, ErrorCode])
|
||||
|
||||
// SymlinkAt represents the imported method "symlink-at".
|
||||
//
|
||||
// Create a symbolic link (also known as a "symlink").
|
||||
@@ -1172,10 +1117,6 @@ func (self Descriptor) SymlinkAt(oldPath string, newPath string) (result cm.Resu
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.symlink-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSymlinkAt(self0 uint32, oldPath0 *uint8, oldPath1 uint32, newPath0 *uint8, newPath1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// Sync represents the imported method "sync".
|
||||
//
|
||||
// Synchronize the data and metadata of a file to disk.
|
||||
@@ -1194,10 +1135,6 @@ func (self Descriptor) Sync() (result cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.sync
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSync(self0 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// SyncData represents the imported method "sync-data".
|
||||
//
|
||||
// Synchronize the data of a file to disk.
|
||||
@@ -1216,10 +1153,6 @@ func (self Descriptor) SyncData() (result cm.Result[ErrorCode, struct{}, ErrorCo
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.sync-data
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorSyncData(self0 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// UnlinkFileAt represents the imported method "unlink-file-at".
|
||||
//
|
||||
// Unlink a filesystem object that is not a directory.
|
||||
@@ -1237,10 +1170,6 @@ func (self Descriptor) UnlinkFileAt(path string) (result cm.Result[ErrorCode, st
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.unlink-file-at
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorUnlinkFileAt(self0 uint32, path0 *uint8, path1 uint32, result *cm.Result[ErrorCode, struct{}, ErrorCode])
|
||||
|
||||
// Write represents the imported method "write".
|
||||
//
|
||||
// Write to a descriptor, without using and updating the descriptor's offset.
|
||||
@@ -1264,10 +1193,6 @@ func (self Descriptor) Write(buffer cm.List[uint8], offset FileSize) (result cm.
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.write
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorWrite(self0 uint32, buffer0 *uint8, buffer1 uint32, offset0 uint64, result *cm.Result[uint64, FileSize, ErrorCode])
|
||||
|
||||
// WriteViaStream represents the imported method "write-via-stream".
|
||||
//
|
||||
// Return a stream for writing to a file, if available.
|
||||
@@ -1280,17 +1205,13 @@ func wasmimport_DescriptorWrite(self0 uint32, buffer0 *uint8, buffer1 uint32, of
|
||||
// write-via-stream: func(offset: filesize) -> result<output-stream, error-code>
|
||||
//
|
||||
//go:nosplit
|
||||
func (self Descriptor) WriteViaStream(offset FileSize) (result cm.Result[streams.OutputStream, streams.OutputStream, ErrorCode]) {
|
||||
func (self Descriptor) WriteViaStream(offset FileSize) (result cm.Result[OutputStream, OutputStream, ErrorCode]) {
|
||||
self0 := cm.Reinterpret[uint32](self)
|
||||
offset0 := (uint64)(offset)
|
||||
wasmimport_DescriptorWriteViaStream((uint32)(self0), (uint64)(offset0), &result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]descriptor.write-via-stream
|
||||
//go:noescape
|
||||
func wasmimport_DescriptorWriteViaStream(self0 uint32, offset0 uint64, result *cm.Result[streams.OutputStream, streams.OutputStream, ErrorCode])
|
||||
|
||||
// DirectoryEntryStream represents the imported resource "wasi:filesystem/types@0.2.0#directory-entry-stream".
|
||||
//
|
||||
// A stream of directory entries.
|
||||
@@ -1309,10 +1230,6 @@ func (self DirectoryEntryStream) ResourceDrop() {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [resource-drop]directory-entry-stream
|
||||
//go:noescape
|
||||
func wasmimport_DirectoryEntryStreamResourceDrop(self0 uint32)
|
||||
|
||||
// ReadDirectoryEntry represents the imported method "read-directory-entry".
|
||||
//
|
||||
// Read a single directory entry from a `directory-entry-stream`.
|
||||
@@ -1326,10 +1243,6 @@ func (self DirectoryEntryStream) ReadDirectoryEntry() (result cm.Result[OptionDi
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 [method]directory-entry-stream.read-directory-entry
|
||||
//go:noescape
|
||||
func wasmimport_DirectoryEntryStreamReadDirectoryEntry(self0 uint32, result *cm.Result[OptionDirectoryEntryShape, cm.Option[DirectoryEntry], ErrorCode])
|
||||
|
||||
// FilesystemErrorCode represents the imported function "filesystem-error-code".
|
||||
//
|
||||
// Attempts to extract a filesystem-related `error-code` from the stream
|
||||
@@ -1346,12 +1259,8 @@ func wasmimport_DirectoryEntryStreamReadDirectoryEntry(self0 uint32, result *cm.
|
||||
// filesystem-error-code: func(err: borrow<error>) -> option<error-code>
|
||||
//
|
||||
//go:nosplit
|
||||
func FilesystemErrorCode(err ioerror.Error) (result cm.Option[ErrorCode]) {
|
||||
func FilesystemErrorCode(err Error) (result cm.Option[ErrorCode]) {
|
||||
err0 := cm.Reinterpret[uint32](err)
|
||||
wasmimport_FilesystemErrorCode((uint32)(err0), &result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:filesystem/types@0.2.0 filesystem-error-code
|
||||
//go:noescape
|
||||
func wasmimport_FilesystemErrorCode(err0 uint32, result *cm.Option[ErrorCode])
|
||||
|
||||
@@ -43,10 +43,6 @@ func (self Error) ResourceDrop() {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/error@0.2.0 [resource-drop]error
|
||||
//go:noescape
|
||||
func wasmimport_ErrorResourceDrop(self0 uint32)
|
||||
|
||||
// ToDebugString represents the imported method "to-debug-string".
|
||||
//
|
||||
// Returns a string that is suitable to assist humans in debugging
|
||||
@@ -65,7 +61,3 @@ func (self Error) ToDebugString() (result string) {
|
||||
wasmimport_ErrorToDebugString((uint32)(self0), &result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/error@0.2.0 [method]error.to-debug-string
|
||||
//go:noescape
|
||||
func wasmimport_ErrorToDebugString(self0 uint32, result *string)
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package ioerror
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:io@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:io/error@0.2.0 [resource-drop]error
|
||||
//go:noescape
|
||||
func wasmimport_ErrorResourceDrop(self0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/error@0.2.0 [method]error.to-debug-string
|
||||
//go:noescape
|
||||
func wasmimport_ErrorToDebugString(self0 uint32, result *string)
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package poll
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:io@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 [resource-drop]pollable
|
||||
//go:noescape
|
||||
func wasmimport_PollableResourceDrop(self0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 [method]pollable.block
|
||||
//go:noescape
|
||||
func wasmimport_PollableBlock(self0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 [method]pollable.ready
|
||||
//go:noescape
|
||||
func wasmimport_PollableReady(self0 uint32) (result0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 poll
|
||||
//go:noescape
|
||||
func wasmimport_Poll(in0 *Pollable, in1 uint32, result *cm.List[uint32])
|
||||
@@ -28,10 +28,6 @@ func (self Pollable) ResourceDrop() {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 [resource-drop]pollable
|
||||
//go:noescape
|
||||
func wasmimport_PollableResourceDrop(self0 uint32)
|
||||
|
||||
// Block represents the imported method "block".
|
||||
//
|
||||
// `block` returns immediately if the pollable is ready, and otherwise
|
||||
@@ -49,10 +45,6 @@ func (self Pollable) Block() {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 [method]pollable.block
|
||||
//go:noescape
|
||||
func wasmimport_PollableBlock(self0 uint32)
|
||||
|
||||
// Ready represents the imported method "ready".
|
||||
//
|
||||
// Return the readiness of a pollable. This function never blocks.
|
||||
@@ -69,10 +61,6 @@ func (self Pollable) Ready() (result bool) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 [method]pollable.ready
|
||||
//go:noescape
|
||||
func wasmimport_PollableReady(self0 uint32) (result0 uint32)
|
||||
|
||||
// Poll represents the imported function "poll".
|
||||
//
|
||||
// Poll for completion on a set of pollables.
|
||||
@@ -102,7 +90,3 @@ func Poll(in cm.List[Pollable]) (result cm.List[uint32]) {
|
||||
wasmimport_Poll((*Pollable)(in0), (uint32)(in1), &result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/poll@0.2.0 poll
|
||||
//go:noescape
|
||||
func wasmimport_Poll(in0 *Pollable, in1 uint32, result *cm.List[uint32])
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package streams
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:io@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [resource-drop]input-stream
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamResourceDrop(self0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.blocking-read
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamBlockingRead(self0 uint32, len0 uint64, result *cm.Result[cm.List[uint8], cm.List[uint8], StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.blocking-skip
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamBlockingSkip(self0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.read
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamRead(self0 uint32, len0 uint64, result *cm.Result[cm.List[uint8], cm.List[uint8], StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.skip
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamSkip(self0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.subscribe
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamSubscribe(self0 uint32) (result0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [resource-drop]output-stream
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamResourceDrop(self0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingFlush(self0 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-splice
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingSplice(self0 uint32, src0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-write-and-flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingWriteAndFlush(self0 uint32, contents0 *uint8, contents1 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-write-zeroes-and-flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingWriteZeroesAndFlush(self0 uint32, len0 uint64, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.check-write
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamCheckWrite(self0 uint32, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamFlush(self0 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.splice
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamSplice(self0 uint32, src0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.subscribe
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamSubscribe(self0 uint32) (result0 uint32)
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.write
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamWrite(self0 uint32, contents0 *uint8, contents1 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.write-zeroes
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamWriteZeroes(self0 uint32, len0 uint64, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
@@ -15,6 +15,16 @@ import (
|
||||
"internal/wasi/io/v0.2.0/poll"
|
||||
)
|
||||
|
||||
// Error represents the imported type alias "wasi:io/streams@0.2.0#error".
|
||||
//
|
||||
// See [ioerror.Error] for more information.
|
||||
type Error = ioerror.Error
|
||||
|
||||
// Pollable represents the imported type alias "wasi:io/streams@0.2.0#pollable".
|
||||
//
|
||||
// See [poll.Pollable] for more information.
|
||||
type Pollable = poll.Pollable
|
||||
|
||||
// StreamError represents the imported variant "wasi:io/streams@0.2.0#stream-error".
|
||||
//
|
||||
// An error for input-stream and output-stream operations.
|
||||
@@ -23,20 +33,20 @@ import (
|
||||
// last-operation-failed(error),
|
||||
// closed,
|
||||
// }
|
||||
type StreamError cm.Variant[uint8, ioerror.Error, ioerror.Error]
|
||||
type StreamError cm.Variant[uint8, Error, Error]
|
||||
|
||||
// StreamErrorLastOperationFailed returns a [StreamError] of case "last-operation-failed".
|
||||
//
|
||||
// The last operation (a write or flush) failed before completion.
|
||||
//
|
||||
// More information is available in the `error` payload.
|
||||
func StreamErrorLastOperationFailed(data ioerror.Error) StreamError {
|
||||
func StreamErrorLastOperationFailed(data Error) StreamError {
|
||||
return cm.New[StreamError](0, data)
|
||||
}
|
||||
|
||||
// LastOperationFailed returns a non-nil *[ioerror.Error] if [StreamError] represents the variant case "last-operation-failed".
|
||||
func (self *StreamError) LastOperationFailed() *ioerror.Error {
|
||||
return cm.Case[ioerror.Error](self, 0)
|
||||
// LastOperationFailed returns a non-nil *[Error] if [StreamError] represents the variant case "last-operation-failed".
|
||||
func (self *StreamError) LastOperationFailed() *Error {
|
||||
return cm.Case[Error](self, 0)
|
||||
}
|
||||
|
||||
// StreamErrorClosed returns a [StreamError] of case "closed".
|
||||
@@ -54,6 +64,16 @@ func (self *StreamError) Closed() bool {
|
||||
return self.Tag() == 1
|
||||
}
|
||||
|
||||
var stringsStreamError = [2]string{
|
||||
"last-operation-failed",
|
||||
"closed",
|
||||
}
|
||||
|
||||
// String implements [fmt.Stringer], returning the variant case name of v.
|
||||
func (v StreamError) String() string {
|
||||
return stringsStreamError[v.Tag()]
|
||||
}
|
||||
|
||||
// InputStream represents the imported resource "wasi:io/streams@0.2.0#input-stream".
|
||||
//
|
||||
// An input bytestream.
|
||||
@@ -79,10 +99,6 @@ func (self InputStream) ResourceDrop() {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [resource-drop]input-stream
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamResourceDrop(self0 uint32)
|
||||
|
||||
// BlockingRead represents the imported method "blocking-read".
|
||||
//
|
||||
// Read bytes from a stream, after blocking until at least one byte can
|
||||
@@ -98,10 +114,6 @@ func (self InputStream) BlockingRead(len_ uint64) (result cm.Result[cm.List[uint
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.blocking-read
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamBlockingRead(self0 uint32, len0 uint64, result *cm.Result[cm.List[uint8], cm.List[uint8], StreamError])
|
||||
|
||||
// BlockingSkip represents the imported method "blocking-skip".
|
||||
//
|
||||
// Skip bytes from a stream, after blocking until at least one byte
|
||||
@@ -117,10 +129,6 @@ func (self InputStream) BlockingSkip(len_ uint64) (result cm.Result[uint64, uint
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.blocking-skip
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamBlockingSkip(self0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
// Read represents the imported method "read".
|
||||
//
|
||||
// Perform a non-blocking read from the stream.
|
||||
@@ -160,10 +168,6 @@ func (self InputStream) Read(len_ uint64) (result cm.Result[cm.List[uint8], cm.L
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.read
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamRead(self0 uint32, len0 uint64, result *cm.Result[cm.List[uint8], cm.List[uint8], StreamError])
|
||||
|
||||
// Skip represents the imported method "skip".
|
||||
//
|
||||
// Skip bytes from a stream. Returns number of bytes skipped.
|
||||
@@ -181,10 +185,6 @@ func (self InputStream) Skip(len_ uint64) (result cm.Result[uint64, uint64, Stre
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.skip
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamSkip(self0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
// Subscribe represents the imported method "subscribe".
|
||||
//
|
||||
// Create a `pollable` which will resolve once either the specified stream
|
||||
@@ -197,17 +197,13 @@ func wasmimport_InputStreamSkip(self0 uint32, len0 uint64, result *cm.Result[uin
|
||||
// subscribe: func() -> pollable
|
||||
//
|
||||
//go:nosplit
|
||||
func (self InputStream) Subscribe() (result poll.Pollable) {
|
||||
func (self InputStream) Subscribe() (result Pollable) {
|
||||
self0 := cm.Reinterpret[uint32](self)
|
||||
result0 := wasmimport_InputStreamSubscribe((uint32)(self0))
|
||||
result = cm.Reinterpret[poll.Pollable]((uint32)(result0))
|
||||
result = cm.Reinterpret[Pollable]((uint32)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]input-stream.subscribe
|
||||
//go:noescape
|
||||
func wasmimport_InputStreamSubscribe(self0 uint32) (result0 uint32)
|
||||
|
||||
// OutputStream represents the imported resource "wasi:io/streams@0.2.0#output-stream".
|
||||
//
|
||||
// An output bytestream.
|
||||
@@ -233,10 +229,6 @@ func (self OutputStream) ResourceDrop() {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [resource-drop]output-stream
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamResourceDrop(self0 uint32)
|
||||
|
||||
// BlockingFlush represents the imported method "blocking-flush".
|
||||
//
|
||||
// Request to flush buffered output, and block until flush completes
|
||||
@@ -251,10 +243,6 @@ func (self OutputStream) BlockingFlush() (result cm.Result[StreamError, struct{}
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingFlush(self0 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
// BlockingSplice represents the imported method "blocking-splice".
|
||||
//
|
||||
// Read from one stream and write to another, with blocking.
|
||||
@@ -274,10 +262,6 @@ func (self OutputStream) BlockingSplice(src InputStream, len_ uint64) (result cm
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-splice
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingSplice(self0 uint32, src0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
// BlockingWriteAndFlush represents the imported method "blocking-write-and-flush".
|
||||
//
|
||||
// Perform a write of up to 4096 bytes, and then flush the stream. Block
|
||||
@@ -313,10 +297,6 @@ func (self OutputStream) BlockingWriteAndFlush(contents cm.List[uint8]) (result
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-write-and-flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingWriteAndFlush(self0 uint32, contents0 *uint8, contents1 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
// BlockingWriteZeroesAndFlush represents the imported method "blocking-write-zeroes-and-flush".
|
||||
//
|
||||
// Perform a write of up to 4096 zeroes, and then flush the stream.
|
||||
@@ -352,10 +332,6 @@ func (self OutputStream) BlockingWriteZeroesAndFlush(len_ uint64) (result cm.Res
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.blocking-write-zeroes-and-flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamBlockingWriteZeroesAndFlush(self0 uint32, len0 uint64, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
// CheckWrite represents the imported method "check-write".
|
||||
//
|
||||
// Check readiness for writing. This function never blocks.
|
||||
@@ -377,10 +353,6 @@ func (self OutputStream) CheckWrite() (result cm.Result[uint64, uint64, StreamEr
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.check-write
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamCheckWrite(self0 uint32, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
// Flush represents the imported method "flush".
|
||||
//
|
||||
// Request to flush buffered output. This function never blocks.
|
||||
@@ -403,10 +375,6 @@ func (self OutputStream) Flush() (result cm.Result[StreamError, struct{}, Stream
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.flush
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamFlush(self0 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
// Splice represents the imported method "splice".
|
||||
//
|
||||
// Read from one stream and write to another.
|
||||
@@ -434,10 +402,6 @@ func (self OutputStream) Splice(src InputStream, len_ uint64) (result cm.Result[
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.splice
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamSplice(self0 uint32, src0 uint32, len0 uint64, result *cm.Result[uint64, uint64, StreamError])
|
||||
|
||||
// Subscribe represents the imported method "subscribe".
|
||||
//
|
||||
// Create a `pollable` which will resolve once the output-stream
|
||||
@@ -454,17 +418,13 @@ func wasmimport_OutputStreamSplice(self0 uint32, src0 uint32, len0 uint64, resul
|
||||
// subscribe: func() -> pollable
|
||||
//
|
||||
//go:nosplit
|
||||
func (self OutputStream) Subscribe() (result poll.Pollable) {
|
||||
func (self OutputStream) Subscribe() (result Pollable) {
|
||||
self0 := cm.Reinterpret[uint32](self)
|
||||
result0 := wasmimport_OutputStreamSubscribe((uint32)(self0))
|
||||
result = cm.Reinterpret[poll.Pollable]((uint32)(result0))
|
||||
result = cm.Reinterpret[Pollable]((uint32)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.subscribe
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamSubscribe(self0 uint32) (result0 uint32)
|
||||
|
||||
// Write represents the imported method "write".
|
||||
//
|
||||
// Perform a write. This function never blocks.
|
||||
@@ -491,10 +451,6 @@ func (self OutputStream) Write(contents cm.List[uint8]) (result cm.Result[Stream
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.write
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamWrite(self0 uint32, contents0 *uint8, contents1 uint32, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
// WriteZeroes represents the imported method "write-zeroes".
|
||||
//
|
||||
// Write zeroes to a stream.
|
||||
@@ -513,7 +469,3 @@ func (self OutputStream) WriteZeroes(len_ uint64) (result cm.Result[StreamError,
|
||||
wasmimport_OutputStreamWriteZeroes((uint32)(self0), (uint64)(len0), &result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:io/streams@0.2.0 [method]output-stream.write-zeroes
|
||||
//go:noescape
|
||||
func wasmimport_OutputStreamWriteZeroes(self0 uint32, len0 uint64, result *cm.Result[StreamError, struct{}, StreamError])
|
||||
|
||||
@@ -35,7 +35,3 @@ func InsecureSeed() (result [2]uint64) {
|
||||
wasmimport_InsecureSeed(&result)
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:random/insecure-seed@0.2.0 insecure-seed
|
||||
//go:noescape
|
||||
func wasmimport_InsecureSeed(result *[2]uint64)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package insecureseed
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:random@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:random/insecure-seed@0.2.0 insecure-seed
|
||||
//go:noescape
|
||||
func wasmimport_InsecureSeed(result *[2]uint64)
|
||||
@@ -0,0 +1,17 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package insecure
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:random@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:random/insecure@0.2.0 get-insecure-random-bytes
|
||||
//go:noescape
|
||||
func wasmimport_GetInsecureRandomBytes(len0 uint64, result *cm.List[uint8])
|
||||
|
||||
//go:wasmimport wasi:random/insecure@0.2.0 get-insecure-random-u64
|
||||
//go:noescape
|
||||
func wasmimport_GetInsecureRandomU64() (result0 uint64)
|
||||
@@ -32,10 +32,6 @@ func GetInsecureRandomBytes(len_ uint64) (result cm.List[uint8]) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:random/insecure@0.2.0 get-insecure-random-bytes
|
||||
//go:noescape
|
||||
func wasmimport_GetInsecureRandomBytes(len0 uint64, result *cm.List[uint8])
|
||||
|
||||
// GetInsecureRandomU64 represents the imported function "get-insecure-random-u64".
|
||||
//
|
||||
// Return an insecure pseudo-random `u64` value.
|
||||
@@ -51,7 +47,3 @@ func GetInsecureRandomU64() (result uint64) {
|
||||
result = (uint64)((uint64)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:random/insecure@0.2.0 get-insecure-random-u64
|
||||
//go:noescape
|
||||
func wasmimport_GetInsecureRandomU64() (result0 uint64)
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Code generated by wit-bindgen-go. DO NOT EDIT.
|
||||
|
||||
package random
|
||||
|
||||
import (
|
||||
"internal/cm"
|
||||
)
|
||||
|
||||
// This file contains wasmimport and wasmexport declarations for "wasi:random@0.2.0".
|
||||
|
||||
//go:wasmimport wasi:random/random@0.2.0 get-random-bytes
|
||||
//go:noescape
|
||||
func wasmimport_GetRandomBytes(len0 uint64, result *cm.List[uint8])
|
||||
|
||||
//go:wasmimport wasi:random/random@0.2.0 get-random-u64
|
||||
//go:noescape
|
||||
func wasmimport_GetRandomU64() (result0 uint64)
|
||||
@@ -36,10 +36,6 @@ func GetRandomBytes(len_ uint64) (result cm.List[uint8]) {
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:random/random@0.2.0 get-random-bytes
|
||||
//go:noescape
|
||||
func wasmimport_GetRandomBytes(len0 uint64, result *cm.List[uint8])
|
||||
|
||||
// GetRandomU64 represents the imported function "get-random-u64".
|
||||
//
|
||||
// Return a cryptographically-secure random or pseudo-random `u64` value.
|
||||
@@ -55,7 +51,3 @@ func GetRandomU64() (result uint64) {
|
||||
result = (uint64)((uint64)(result0))
|
||||
return
|
||||
}
|
||||
|
||||
//go:wasmimport wasi:random/random@0.2.0 get-random-u64
|
||||
//go:noescape
|
||||
func wasmimport_GetRandomU64() (result0 uint64)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user