Compare commits

...

36 Commits

Author SHA1 Message Date
deadprogram 3e60eeb368 Prepare for release 0.37.0
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-03-19 07:32:48 +01:00
Randy Reddig e5a8d69300 internal/wasm-tools: update to go.bytecodealliance.org@v0.6.2 2025-03-18 15:40:46 +01:00
Randy Reddig 4f8672c9ab internal/cm: change error type from struct{string}
This is a temporary fix until cm@v0.2.2 is released, and package internal/cm and internal/wasi can be regenerated.

See #4810 for more information.
2025-03-18 15:40:46 +01:00
Randy Reddig a7416e7300 internal/wasi: remove x bit from generated files 2025-03-18 15:40:46 +01:00
Randy Reddig d63d8e0899 internal/wasm-tools, internal/cm: udpate to go.bytecodealliance.org@v0.6.1 and cm@v0.2.1 2025-03-18 15:40:46 +01:00
Randy Reddig 8e009de8a8 internal/cm: remove go.mod file 2025-03-18 15:40:46 +01:00
Randy Reddig d6527ece02 internal/cm: exclude certain files when copying package 2025-03-18 15:40:46 +01:00
Randy Reddig 211425c3e9 internal/wasi: regenerate WASI 0.2 bindings
Use go.bytecodealliance.org/cmd/wit-bindgen-go@v0.6.0
2025-03-18 15:40:46 +01:00
Randy Reddig 429aea8e74 internal/cm: update to go.bytecodealliance.org/cm@v0.2.0 2025-03-18 15:40:46 +01:00
Randy Reddig 7755780a49 GNUmakefile, internal/wasm-tools: update to go.bytecodealliance.org@v0.6.0 2025-03-18 15:40:46 +01:00
Ayke van Laethem 3a7c25f987 all: add the Boehm-Demers-Weiser GC on Linux
This adds support for the well-known Boehm GC. It's significantly faster
than our own naive GC and could be used as an alternative on bigger
systems.

In the future, this GC might also be supported on WebAssembly with some
extra work. Right now it's Linux only (though Windows/MacOS shouldn't be
too difficult to add).
2025-03-18 10:31:38 +01:00
Ayke van Laethem a4cbe3326e runtime: only allocate heap memory when needed
For example, with -gc=none and -gc=leaking, no heap needs to be
allocated when initializing the runtime. And some GCs (like -gc=custom)
are responsible for allocating the heap themselves.
2025-03-18 10:31:38 +01:00
Ayke van Laethem 5282b4efac runtime: remove unused file func.go
This was used in the past, but we don't use it anymore.
2025-03-17 22:13:17 +01:00
Randy Reddig 6a25fd494e reflect, internal/reflectlite: add Value.SetIter{Key,Value} and MapIter.Reset
Fixes #4790. Depends on #4787 (merge that first).
2025-03-17 20:44:20 +01:00
Randy Reddig d95c1b5982 reflect: remove unused go:linkname functions 2025-03-17 18:23:28 +01:00
Randy Reddig 24eed9e376 reflect: remove strconv.go 2025-03-17 18:23:28 +01:00
Randy Reddig c2af1d183e reflect: panic on Type.CanSeq[2] instead of returning false
PR feedback.
2025-03-17 18:23:28 +01:00
Randy Reddig 64651115c2 reflect: Value.Seq iteration value types should match
Implementation of https://github.com/golang/go/issues/71905

194696f1d1f6e5609f96d0fb0192595e7e0f5b90
2025-03-17 18:23:28 +01:00
Randy Reddig b6c3d142db reflect: copy reflect iter tests from upstream Go 2025-03-17 18:23:28 +01:00
Randy Reddig fafe80704f loader, iter, reflect: use build tags for package iter and iter methods on reflect.Value 2025-03-17 18:23:28 +01:00
Randy Reddig a2be2f3330 loader, iter: add shim for go1.22 and earlier 2025-03-17 18:23:28 +01:00
Randy Reddig 05fc49a0cf internal/reflectlite: remove old reflect.go 2025-03-17 18:23:28 +01:00
Randy Reddig 417aa4312e internal/reflectlite, reflect: move StringHeader and SliceHeader back to package reflect 2025-03-17 18:23:28 +01:00
Randy Reddig bf88cdea90 transform: cherry-pick from #4774 2025-03-17 18:23:28 +01:00
Randy Reddig c8d0b87a67 internal/reflectlite, reflect: handle different StructField 2025-03-17 18:23:28 +01:00
Randy Reddig 99a618385b runtime: use package reflectlite 2025-03-17 18:23:28 +01:00
Randy Reddig 9e143efd73 reflect: add Go 1.24 iter.Seq[2] methods 2025-03-17 18:23:28 +01:00
Randy Reddig d5c70a1cd3 reflect, internal/reflectlite: embed reflectlite types into reflect types 2025-03-17 18:23:28 +01:00
Ayke van Laethem bbb2b0c95b builder: use a separate module for command-line set strings
Strings that are set via the command line (as in -ldflags="-X ...") are
now created in a separate module to avoid type renaming issues. LLVM
sometimes renames types or merges types that are structurally the same,
and putting these strings in a separate module avoids this issue (and
lets llvm.LinkModules deal with the difference).

This fixes https://github.com/tinygo-org/tinygo/issues/4810.
2025-03-17 07:13:32 -07:00
Michael Smith 4768c7d431 machine/rp2350: add flash support for rp2350 (#4803)
* machine/rp2350: add flash support for rp2350
* combine duplicate files
* clean things up and group by source file
* add stubbed out xip cache clean func if needed in the future
* update flash_enable_xip_via_boot2
* remove unused macros and fix inconsistent formatting
* make flash size configurable like rp2040
* add missing flash size configs
* retain big Go CGo compatibility per #4103
* clarify CS0_SIZE source and remove single-use typedef
2025-03-16 09:45:53 +01:00
あーるどん 4f7c64cb24 fix(rp2040): replace loop counter with hw timer for USB SetAddressReq… (#4796)
* fix(rp2040/rp2350): replace loop counter with hw timer for USB SetAddressRequest timeout.

* fix code format.

---------

Co-authored-by: rdon <you@example.com>
2025-03-13 16:39:43 +01:00
Ayke van Laethem ff2a79de7c riscv-qemu: increase stack size
Bumping the stack size to 8kb (previous was 4kb) gets most remaining
tests to pass on baremetal.
2025-03-13 06:43:39 -07:00
soypat 04c7057ea6 add goroutine benchmark to examples 2025-03-11 13:10:41 -07:00
Ron Evans f76e8d2812 fix: ensure use of pointers for SPI interface on atsam21/atsam51 and other machines/boards that were missing implementation. (#4798)
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-03-11 12:50:31 -03:00
deadprogram bcdc5e0097 chore: update version to 0.37.0-dev
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-03-11 07:24:17 -07:00
deadprogram 2bee29959b refactor: use *SPI everywhere to make consistant for implementations.
Fixes #4663 "in reverse" by making SPI a pointer everywhere, as discussed
in the comments.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-03-11 06:06:31 -07:00
143 changed files with 5932 additions and 6060 deletions
+2 -2
View File
@@ -22,9 +22,9 @@ jobs:
run: sudo apt-get remove llvm-18
- name: Checkout
uses: actions/checkout@v4
- name: Pull musl
- name: Pull musl, bdwgc
run: |
git submodule update --init lib/musl
git submodule update --init lib/musl lib/bdwgc
- name: Restore LLVM source cache
uses: actions/cache/restore@v4
id: cache-llvm-source
+3
View File
@@ -39,3 +39,6 @@
[submodule "lib/wasi-cli"]
path = lib/wasi-cli
url = https://github.com/WebAssembly/wasi-cli
[submodule "lib/bdwgc"]
path = lib/bdwgc
url = https://github.com/ivmai/bdwgc.git
+50
View File
@@ -1,3 +1,53 @@
0.37.0
---
* **general**
- add the Boehm-Demers-Weiser GC on Linux
* **ci**
- add more tests for wasm and baremetal
* **compiler**
- crypto/internal/sysrand is allowed to use unsafe signatures
* **examples**
- add goroutine benchmark to examples
* **fixes**
- ensure use of pointers for SPI interface on atsam21/atsam51 and other machines/boards that were missing implementation (#4798)
- replace loop counter with hw timer for USB SetAddressReq on rp2040 (#4796)
* **internal**
- update to go.bytecodealliance.org@v0.6.2 in GNUmakefile and internal/wasm-tools
- exclude certain files when copying package in internal/cm
- update to go.bytecodealliance.org/cm@v0.2.2 in internal/cm
- remove old reflect.go in internal/reflectlite
* **loader**
- use build tags for package iter and iter methods on reflect.Value in loader, iter, reflect
- add shim for go1.22 and earlier in loader, iter
* **machine**
- bump rp2040 to 200MHz (#4768)
- correct register address for Pin.SetInterrupt for rp2350 (#4782)
- don't block the rp2xxx UART interrupt handler
- fix RP2040 Pico board on the playground
- add flash support for rp2350 (#4803)
* **os**
- add stub Symlink for wasm
* **refactor**
- use *SPI everywhere to make consistent for implementations. Fixes #4663 "in reverse" by making SPI a pointer everywhere, as discussed in the comments.
* **reflect**
- add Value.SetIter{Key,Value} and MapIter.Reset in reflect, internal/reflectlite
- embed reflectlite types into reflect types in reflect, internal/reflectlite
- add Go 1.24 iter.Seq[2] methods
- copy reflect iter tests from upstream Go
- panic on Type.CanSeq[2] instead of returning false
- remove strconv.go
- remove unused go:linkname functions
* **riscv-qemu**
- add VirtIO RNG device
- increase stack size
* **runtime**
- only allocate heap memory when needed
- remove unused file func.go
- use package reflectlite
* **transform**
- cherry-pick from #4774
0.36.0
---
* **general**
+9 -10
View File
@@ -267,16 +267,17 @@ lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a:
cd lib/wasi-libc && $(MAKE) -j4 EXTRA_CFLAGS="-O2 -g -DNDEBUG -mnontrapping-fptoint -msign-ext" MALLOC_IMPL=none CC="$(CLANG)" AR=$(LLVM_AR) NM=$(LLVM_NM)
# Generate WASI syscall bindings
WASM_TOOLS_MODULE=github.com/bytecodealliance/wasm-tools-go
WASM_TOOLS_MODULE=go.bytecodealliance.org
.PHONY: wasi-syscall
wasi-syscall: wasi-cm
rm -rf ./src/internal/wasi/*
go run -modfile ./internal/wasm-tools/go.mod $(WASM_TOOLS_MODULE)/cmd/wit-bindgen-go generate --versioned -o ./src/internal -p internal --cm internal/cm ./lib/wasi-cli/wit
# Copy package cm into src/internal/cm
.PHONY: wasi-cm
wasi-cm:
# rm -rf ./src/internal/cm
rsync -rv --delete --exclude '*_test.go' $(shell go list -modfile ./internal/wasm-tools/go.mod -m -f {{.Dir}} $(WASM_TOOLS_MODULE))/cm ./src/internal/
rm -rf ./src/internal/cm/*
rsync -rv --delete --exclude go.mod --exclude '*_test.go' --exclude '*_json.go' --exclude '*.md' --exclude LICENSE $(shell go list -modfile ./internal/wasm-tools/go.mod -m -f {{.Dir}} $(WASM_TOOLS_MODULE)/cm)/ ./src/internal/cm
# Check for Node.js used during WASM tests.
NODEJS_VERSION := $(word 1,$(subst ., ,$(shell node -v | cut -c 2-)))
@@ -431,17 +432,10 @@ TEST_PACKAGES_NONWASM = \
# (just like wasm).
# * picolibc math functions apparently are less precise, the math package
# fails on baremetal.
# * Some packages fail or hang for an unknown reason, this should be
# investigated and fixed.
TEST_PACKAGES_BAREMETAL = $(filter-out $(TEST_PACKAGES_NONBAREMETAL), $(TEST_PACKAGES_FAST))
TEST_PACKAGES_NONBAREMETAL = \
$(TEST_PACKAGES_NONWASM) \
crypto/elliptic \
math \
reflect \
encoding/asn1 \
encoding/base32 \
go/ast \
$(nil)
# Report platforms on which each standard library package is known to pass tests
@@ -947,6 +941,7 @@ wasmtest:
build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binaryen)
@mkdir -p build/release/tinygo/bin
@mkdir -p build/release/tinygo/lib/bdwgc
@mkdir -p build/release/tinygo/lib/clang/include
@mkdir -p build/release/tinygo/lib/CMSIS/CMSIS
@mkdir -p build/release/tinygo/lib/macos-minimal-sdk
@@ -968,6 +963,7 @@ build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN
ifneq ($(USE_SYSTEM_BINARYEN),1)
@cp -p build/wasm-opt$(EXE) build/release/tinygo/bin
endif
@cp -rp lib/bdwgc/* build/release/tinygo/lib/bdwgc
@cp -p $(abspath $(CLANG_SRC))/lib/Headers/*.h build/release/tinygo/lib/clang/include
@cp -rp lib/CMSIS/CMSIS/Include build/release/tinygo/lib/CMSIS/CMSIS
@cp -rp lib/CMSIS/README.md build/release/tinygo/lib/CMSIS
@@ -981,6 +977,7 @@ endif
@cp -rp lib/musl/crt/crt1.c build/release/tinygo/lib/musl/crt
@cp -rp lib/musl/COPYRIGHT build/release/tinygo/lib/musl
@cp -rp lib/musl/include build/release/tinygo/lib/musl
@cp -rp lib/musl/src/ctype build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/env build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/errno build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/exit build/release/tinygo/lib/musl/src
@@ -995,8 +992,10 @@ endif
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/misc build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/multibyte build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/sched build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/stdlib build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/thread build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/time build/release/tinygo/lib/musl/src
+71
View File
@@ -0,0 +1,71 @@
package builder
// The well-known conservative Boehm-Demers-Weiser GC.
// This file provides a way to compile this GC for use with TinyGo.
import (
"path/filepath"
"github.com/tinygo-org/tinygo/goenv"
)
var BoehmGC = Library{
name: "bdwgc",
cflags: func(target, headerPath string) []string {
libdir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/bdwgc")
return []string{
// use a modern environment
"-DUSE_MMAP", // mmap is available
"-DUSE_MUNMAP", // return memory to the OS using munmap
"-DGC_BUILTIN_ATOMIC", // use compiler intrinsics for atomic operations
"-DNO_EXECUTE_PERMISSION", // don't make the heap executable
// specific flags for TinyGo
"-DALL_INTERIOR_POINTERS", // scan interior pointers (needed for Go)
"-DIGNORE_DYNAMIC_LOADING", // we don't support dynamic loading at the moment
"-DNO_GETCONTEXT", // musl doesn't support getcontext()
// Special flag to work around the lack of __data_start in ld.lld.
// TODO: try to fix this in LLVM/lld directly so we don't have to
// work around it anymore.
"-DGC_DONT_REGISTER_MAIN_STATIC_DATA",
// Do not scan the stack. We have our own mechanism to do this.
"-DSTACK_NOT_SCANNED",
// Assertions can be enabled while debugging GC issues.
//"-DGC_ASSERTIONS",
// Threading is not yet supported, so these are disabled.
//"-DGC_THREADS",
//"-DTHREAD_LOCAL_ALLOC",
"-I" + libdir + "/include",
}
},
sourceDir: func() string {
return filepath.Join(goenv.Get("TINYGOROOT"), "lib/bdwgc")
},
librarySources: func(target string) ([]string, error) {
return []string{
"allchblk.c",
"alloc.c",
"blacklst.c",
"dbg_mlc.c",
"dyn_load.c",
"finalize.c",
"headers.c",
"mach_dep.c",
"malloc.c",
"mark.c",
"mark_rts.c",
"misc.c",
"new_hblk.c",
"obj_map.c",
"os_dep.c",
"pthread_stop_world.c",
"pthread_support.c",
"reclaim.c",
}, nil
},
}
+62 -48
View File
@@ -147,20 +147,22 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
// the libc needs them.
root := goenv.Get("TINYGOROOT")
var libcDependencies []*compileJob
var libcJob *compileJob
switch config.Target.Libc {
case "darwin-libSystem":
job := makeDarwinLibSystemJob(config, tmpdir)
libcDependencies = append(libcDependencies, job)
case "musl":
job, unlock, err := libMusl.load(config, tmpdir)
var unlock func()
libcJob, unlock, err = libMusl.load(config, tmpdir, nil)
if err != nil {
return BuildResult{}, err
}
defer unlock()
libcDependencies = append(libcDependencies, dummyCompileJob(filepath.Join(filepath.Dir(job.result), "crt1.o")))
libcDependencies = append(libcDependencies, job)
libcDependencies = append(libcDependencies, dummyCompileJob(filepath.Join(filepath.Dir(libcJob.result), "crt1.o")))
libcDependencies = append(libcDependencies, libcJob)
case "picolibc":
libcJob, unlock, err := libPicolibc.load(config, tmpdir)
libcJob, unlock, err := libPicolibc.load(config, tmpdir, nil)
if err != nil {
return BuildResult{}, err
}
@@ -173,14 +175,14 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
}
libcDependencies = append(libcDependencies, dummyCompileJob(path))
case "wasmbuiltins":
libcJob, unlock, err := libWasmBuiltins.load(config, tmpdir)
libcJob, unlock, err := libWasmBuiltins.load(config, tmpdir, nil)
if err != nil {
return BuildResult{}, err
}
defer unlock()
libcDependencies = append(libcDependencies, libcJob)
case "mingw-w64":
job, unlock, err := libMinGW.load(config, tmpdir)
job, unlock, err := libMinGW.load(config, tmpdir, nil)
if err != nil {
return BuildResult{}, err
}
@@ -449,8 +451,15 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
if global.IsNil() {
return errors.New("global not found: " + globalName)
}
globalType := global.GlobalValueType()
if globalType.TypeKind() != llvm.StructTypeKind || globalType.StructName() != "runtime._string" {
// Verify this is indeed a string. This is needed so
// that makeGlobalsModule can just create the right
// globals of string type without checking.
return fmt.Errorf("%s: not a string", globalName)
}
name := global.Name()
newGlobal := llvm.AddGlobal(mod, global.GlobalValueType(), name+".tmp")
newGlobal := llvm.AddGlobal(mod, globalType, name+".tmp")
global.ReplaceAllUsesWith(newGlobal)
global.EraseFromParentAsGlobal()
newGlobal.SetName(name)
@@ -538,6 +547,15 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
}
}
// Insert values from -ldflags="-X ..." into the IR.
// This is a separate module, so that the "runtime._string" type
// doesn't need to match precisely. LLVM tends to rename that type
// sometimes, leading to errors. But linking in a separate module
// works fine. See:
// https://github.com/tinygo-org/tinygo/issues/4810
globalsMod := makeGlobalsModule(ctx, globalValues, machine)
llvm.LinkModules(mod, globalsMod)
// Create runtime.initAll function that calls the runtime
// initializer of each package.
llvmInitFn := mod.NamedFunction("runtime.initAll")
@@ -590,7 +608,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
// Run all optimization passes, which are much more effective now
// that the optimizer can see the whole program at once.
err := optimizeProgram(mod, config, globalValues)
err := optimizeProgram(mod, config)
if err != nil {
return err
}
@@ -685,7 +703,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
// Add compiler-rt dependency if needed. Usually this is a simple load from
// a cache.
if config.Target.RTLib == "compiler-rt" {
job, unlock, err := libCompilerRT.load(config, tmpdir)
job, unlock, err := libCompilerRT.load(config, tmpdir, nil)
if err != nil {
return result, err
}
@@ -693,6 +711,19 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
linkerDependencies = append(linkerDependencies, job)
}
// The Boehm collector is stored in a separate C library.
if config.GC() == "boehm" {
if libcJob == nil {
return BuildResult{}, fmt.Errorf("boehm GC isn't supported with libc %s", config.Target.Libc)
}
job, unlock, err := BoehmGC.load(config, tmpdir, libcJob)
if err != nil {
return BuildResult{}, err
}
defer unlock()
linkerDependencies = append(linkerDependencies, job)
}
// Add jobs to compile extra files. These files are in C or assembly and
// contain things like the interrupt vector table and low level operations
// such as stack switching.
@@ -1145,7 +1176,7 @@ func createEmbedObjectFile(data, hexSum, sourceFile, sourceDir, tmpdir string, c
// optimizeProgram runs a series of optimizations and transformations that are
// needed to convert a program to its final form. Some transformations are not
// optional and must be run as the compiler expects them to run.
func optimizeProgram(mod llvm.Module, config *compileopts.Config, globalValues map[string]map[string]string) error {
func optimizeProgram(mod llvm.Module, config *compileopts.Config) error {
err := interp.Run(mod, config.Options.InterpTimeout, config.DumpSSA())
if err != nil {
return err
@@ -1163,12 +1194,6 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config, globalValues m
}
}
// Insert values from -ldflags="-X ..." into the IR.
err = setGlobalValues(mod, globalValues)
if err != nil {
return err
}
// Run most of the whole-program optimizations (including the whole
// O0/O1/O2/Os/Oz optimization pipeline).
errs := transform.Optimize(mod, config)
@@ -1182,10 +1207,19 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config, globalValues m
return nil
}
// setGlobalValues sets the global values from the -ldflags="-X ..." compiler
// option in the given module. An error may be returned if the global is not of
// the expected type.
func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) error {
func makeGlobalsModule(ctx llvm.Context, globals map[string]map[string]string, machine llvm.TargetMachine) llvm.Module {
mod := ctx.NewModule("cmdline-globals")
targetData := machine.CreateTargetData()
defer targetData.Dispose()
mod.SetDataLayout(targetData.String())
stringType := ctx.StructCreateNamed("runtime._string")
uintptrType := ctx.IntType(targetData.PointerSize() * 8)
stringType.StructSetBody([]llvm.Type{
llvm.PointerType(ctx.Int8Type(), 0),
uintptrType,
}, false)
var pkgPaths []string
for pkgPath := range globals {
pkgPaths = append(pkgPaths, pkgPath)
@@ -1201,24 +1235,6 @@ func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) erro
for _, name := range names {
value := pkg[name]
globalName := pkgPath + "." + name
global := mod.NamedGlobal(globalName)
if global.IsNil() || !global.Initializer().IsNil() {
// The global either does not exist (optimized away?) or has
// some value, in which case it has already been initialized at
// package init time.
continue
}
// A strin is a {ptr, len} pair. We need these types to build the
// initializer.
initializerType := global.GlobalValueType()
if initializerType.TypeKind() != llvm.StructTypeKind || initializerType.StructName() == "" {
return fmt.Errorf("%s: not a string", globalName)
}
elementTypes := initializerType.StructElementTypes()
if len(elementTypes) != 2 {
return fmt.Errorf("%s: not a string", globalName)
}
// Create a buffer for the string contents.
bufInitializer := mod.Context().ConstString(value, false)
@@ -1229,22 +1245,20 @@ func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) erro
buf.SetLinkage(llvm.PrivateLinkage)
// Create the string value, which is a {ptr, len} pair.
zero := llvm.ConstInt(mod.Context().Int32Type(), 0, false)
ptr := llvm.ConstGEP(bufInitializer.Type(), buf, []llvm.Value{zero, zero})
if ptr.Type() != elementTypes[0] {
return fmt.Errorf("%s: not a string", globalName)
}
length := llvm.ConstInt(elementTypes[1], uint64(len(value)), false)
initializer := llvm.ConstNamedStruct(initializerType, []llvm.Value{
ptr,
length := llvm.ConstInt(uintptrType, uint64(len(value)), false)
initializer := llvm.ConstNamedStruct(stringType, []llvm.Value{
buf,
length,
})
// Set the initializer. No initializer should be set at this point.
// Create the string global.
global := llvm.AddGlobal(mod, stringType, globalName)
global.SetInitializer(initializer)
global.SetAlignment(targetData.PrefTypeAlignment(stringType))
}
}
return nil
return mod
}
// functionStackSizes keeps stack size information about a single function
+20 -5
View File
@@ -43,7 +43,11 @@ type Library struct {
// output archive file, it is expected to be removed after use.
// As a side effect, this call creates the library header files if they didn't
// exist yet.
func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJob, abortLock func(), err error) {
// The provided libc job (if not null) will cause this libc to be added as a
// dependency for all C compiler jobs, and adds libc headers for the given
// target config. In other words, pass this libc if the library needs a libc to
// compile.
func (l *Library) load(config *compileopts.Config, tmpdir string, libc *compileJob) (job *compileJob, abortLock func(), err error) {
outdir, precompiled := config.LibcPath(l.name)
archiveFilePath := filepath.Join(outdir, "lib.a")
if precompiled {
@@ -181,6 +185,9 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
args = append(args, "-mfpu=vfpv2")
}
}
if libc != nil {
args = append(args, config.LibcCFlags()...)
}
var once sync.Once
@@ -233,7 +240,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
objpath := filepath.Join(dir, cleanpath+".o")
os.MkdirAll(filepath.Dir(objpath), 0o777)
objs = append(objs, objpath)
job.dependencies = append(job.dependencies, &compileJob{
objfile := &compileJob{
description: "compile " + srcpath,
run: func(*compileJob) error {
var compileArgs []string
@@ -248,7 +255,11 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
}
return nil
},
})
}
if libc != nil {
objfile.dependencies = append(objfile.dependencies, libc)
}
job.dependencies = append(job.dependencies, objfile)
}
// Create crt1.o job, if needed.
@@ -257,7 +268,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
// won't make much of a difference in speed).
if l.crt1Source != "" {
srcpath := filepath.Join(sourceDir, l.crt1Source)
job.dependencies = append(job.dependencies, &compileJob{
crt1Job := &compileJob{
description: "compile " + srcpath,
run: func(*compileJob) error {
var compileArgs []string
@@ -277,7 +288,11 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
}
return os.Rename(tmpfile.Name(), filepath.Join(outdir, "crt1.o"))
},
})
}
if libc != nil {
crt1Job.dependencies = append(crt1Job.dependencies, libc)
}
job.dependencies = append(job.dependencies, crt1Job)
}
ok = true
+6
View File
@@ -113,26 +113,32 @@ var libMusl = Library{
librarySources: func(target string) ([]string, error) {
arch := compileopts.MuslArchitecture(target)
globs := []string{
"ctype/*.c",
"env/*.c",
"errno/*.c",
"exit/*.c",
"fcntl/*.c",
"internal/defsysinfo.c",
"internal/intscan.c",
"internal/libc.c",
"internal/shgetc.c",
"internal/syscall_ret.c",
"internal/vdso.c",
"legacy/*.c",
"locale/*.c",
"linux/*.c",
"locale/*.c",
"malloc/*.c",
"malloc/mallocng/*.c",
"mman/*.c",
"math/*.c",
"misc/*.c",
"multibyte/*.c",
"sched/*.c",
"signal/" + arch + "/*.s",
"signal/*.c",
"stdio/*.c",
"stdlib/*.c",
"string/*.c",
"thread/" + arch + "/*.s",
"thread/*.c",
+67 -53
View File
@@ -261,6 +261,10 @@ func (c *Config) LibcPath(name string) (path string, precompiled bool) {
if c.Target.SoftFloat {
archname += "-softfloat"
}
if name == "bdwgc" {
// Boehm GC is compiled against a particular libc.
archname += "-" + c.Target.Libc
}
// Try to load a precompiled library.
precompiledDir := filepath.Join(goenv.Get("TINYGOROOT"), "pkg", archname, name)
@@ -315,59 +319,7 @@ func (c *Config) CFlags(libclang bool) []string {
"-resource-dir="+resourceDir,
)
}
switch c.Target.Libc {
case "darwin-libSystem":
root := goenv.Get("TINYGOROOT")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(root, "lib/macos-minimal-sdk/src/usr/include"),
)
case "picolibc":
root := goenv.Get("TINYGOROOT")
picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc")
path, _ := c.LibcPath("picolibc")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(picolibcDir, "include"),
"-isystem", filepath.Join(picolibcDir, "tinystdio"),
"-D__PICOLIBC_ERRNO_FUNCTION=__errno_location",
)
case "musl":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("musl")
arch := MuslArchitecture(c.Triple())
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "musl", "arch", arch),
"-isystem", filepath.Join(root, "lib", "musl", "arch", "generic"),
"-isystem", filepath.Join(root, "lib", "musl", "include"),
)
case "wasi-libc":
root := goenv.Get("TINYGOROOT")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", root+"/lib/wasi-libc/sysroot/include")
case "wasmbuiltins":
// nothing to add (library is purely for builtins)
case "mingw-w64":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("mingw-w64")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"),
"-D_UCRT",
)
case "":
// No libc specified, nothing to add.
default:
// Incorrect configuration. This could be handled in a better way, but
// usually this will be found by developers (not by TinyGo users).
panic("unknown libc: " + c.Target.Libc)
}
cflags = append(cflags, c.LibcCFlags()...)
// Always emit debug information. It is optionally stripped at link time.
cflags = append(cflags, "-gdwarf-4")
// Use the same optimization level as TinyGo.
@@ -394,6 +346,68 @@ func (c *Config) CFlags(libclang bool) []string {
return cflags
}
// LibcCFlags returns the C compiler flags for the configured libc.
// It only uses flags that are part of the libc path (triple, cpu, abi, libc
// name) so it can safely be used to compile another C library.
func (c *Config) LibcCFlags() []string {
switch c.Target.Libc {
case "darwin-libSystem":
root := goenv.Get("TINYGOROOT")
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(root, "lib/macos-minimal-sdk/src/usr/include"),
}
case "picolibc":
root := goenv.Get("TINYGOROOT")
picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc")
path, _ := c.LibcPath("picolibc")
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(picolibcDir, "include"),
"-isystem", filepath.Join(picolibcDir, "tinystdio"),
"-D__PICOLIBC_ERRNO_FUNCTION=__errno_location",
}
case "musl":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("musl")
arch := MuslArchitecture(c.Triple())
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "musl", "arch", arch),
"-isystem", filepath.Join(root, "lib", "musl", "arch", "generic"),
"-isystem", filepath.Join(root, "lib", "musl", "include"),
}
case "wasi-libc":
root := goenv.Get("TINYGOROOT")
return []string{
"-nostdlibinc",
"-isystem", root + "/lib/wasi-libc/sysroot/include",
}
case "wasmbuiltins":
// nothing to add (library is purely for builtins)
return nil
case "mingw-w64":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("mingw-w64")
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"),
"-D_UCRT",
}
case "":
// No libc specified, nothing to add.
return nil
default:
// Incorrect configuration. This could be handled in a better way, but
// usually this will be found by developers (not by TinyGo users).
panic("unknown libc: " + c.Target.Libc)
}
}
// LDFlags returns the flags to pass to the linker. A few more flags are needed
// (like the one for the compiler runtime), but this represents the majority of
// the flags.
+1 -1
View File
@@ -9,7 +9,7 @@ import (
var (
validBuildModeOptions = []string{"default", "c-shared", "wasi-legacy"}
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise", "boehm"}
validSchedulerOptions = []string{"none", "tasks", "asyncify"}
validSerialOptions = []string{"none", "uart", "usb", "rtt"}
validPrintSizeOptions = []string{"none", "short", "full", "html"}
+1 -1
View File
@@ -9,7 +9,7 @@ import (
func TestVerifyOptions(t *testing.T) {
expectedGCError := errors.New(`invalid gc option 'incorrect': valid values are none, leaking, conservative, custom, precise`)
expectedGCError := errors.New(`invalid gc option 'incorrect': valid values are none, leaking, conservative, custom, precise, boehm`)
expectedSchedulerError := errors.New(`invalid scheduler option 'incorrect': valid values are none, tasks, asyncify`)
expectedPrintSizeError := errors.New(`invalid size option 'incorrect': valid values are none, short, full, html`)
expectedPanicStrategyError := errors.New(`invalid panic option 'incorrect': valid values are print, trap`)
+3 -1
View File
@@ -247,7 +247,6 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
GOOS: options.GOOS,
GOARCH: options.GOARCH,
BuildTags: []string{options.GOOS, options.GOARCH},
GC: "precise",
Scheduler: "tasks",
Linker: "cc",
DefaultStackSize: 1024 * 64, // 64kB
@@ -366,6 +365,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
llvmvendor := "unknown"
switch options.GOOS {
case "darwin":
spec.GC = "precise"
platformVersion := "10.12.0"
if options.GOARCH == "arm64" {
platformVersion = "11.0.0" // first macosx platform with arm64 support
@@ -388,6 +388,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
"src/runtime/runtime_unix.c",
"src/runtime/signal.c")
case "linux":
spec.GC = "boehm"
spec.Linker = "ld.lld"
spec.RTLib = "compiler-rt"
spec.Libc = "musl"
@@ -411,6 +412,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
"src/runtime/runtime_unix.c",
"src/runtime/signal.c")
case "windows":
spec.GC = "precise"
spec.Linker = "ld.lld"
spec.Libc = "mingw-w64"
// Note: using a medium code model, low image base and no ASLR
-7
View File
@@ -371,13 +371,6 @@ func (c *compilerContext) getPointerBitmap(typ llvm.Type, pos token.Pos) *big.In
return big.NewInt(1)
case llvm.StructTypeKind:
ptrs := big.NewInt(0)
if typ.StructName() == "runtime.funcValue" {
// Hack: the type runtime.funcValue contains an 'id' field which is
// of type uintptr, but before the LowerFuncValues pass it actually
// contains a pointer (ptrtoint) to a global. This trips up the
// interp package. Therefore, make the id field a pointer for now.
typ = c.ctx.StructType([]llvm.Type{c.dataPtrType, c.dataPtrType}, false)
}
for i, subtyp := range typ.StructElementTypes() {
subptrs := c.getPointerBitmap(subtyp, pos)
if subptrs.BitLen() == 0 {
+1 -1
View File
@@ -10,7 +10,7 @@ import (
// Version of TinyGo.
// Update this value before release of new version of software.
const version = "0.36.0"
const version = "0.37.0"
// Return TinyGo version, either in the form 0.30.0 or as a development version
// (like 0.30.0-dev-abcd012).
+12 -8
View File
@@ -1,18 +1,22 @@
module github.com/tinygo-org/tinygo/internal/tools
module github.com/tinygo-org/tinygo/internal/wasm-tools
go 1.22.4
go 1.23.0
require github.com/bytecodealliance/wasm-tools-go v0.3.1
require (
go.bytecodealliance.org v0.6.2
go.bytecodealliance.org/cm v0.2.2
)
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/klauspost/compress v1.18.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/regclient/regclient v0.7.1 // indirect
github.com/regclient/regclient v0.8.2 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tetratelabs/wazero v1.9.0 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/urfave/cli/v3 v3.0.0-alpha9.2 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/sys v0.26.0 // indirect
github.com/urfave/cli/v3 v3.0.0-beta1 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/sys v0.31.0 // indirect
)
+22 -18
View File
@@ -1,5 +1,3 @@
github.com/bytecodealliance/wasm-tools-go v0.3.1 h1:9Q9PjSzkbiVmkUvZ7nYCfJ02mcQDBalxycA3s8g7kR4=
github.com/bytecodealliance/wasm-tools-go v0.3.1/go.mod h1:vNAQ8DAEp6xvvk+TUHah5DslLEa76f4H6e737OeaxuY=
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=
@@ -7,16 +5,16 @@ 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/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/olareg/olareg v0.1.1 h1:Ui7q93zjcoF+U9U71sgqgZWByDoZOpqHitUXEu2xV+g=
github.com/olareg/olareg v0.1.1/go.mod h1:w8NP4SWrHHtxsFaUiv1lnCnYPm4sN1seCd2h7FK/dc0=
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/regclient/regclient v0.8.2 h1:23BQ3jWgKYHHIXUhp/S9laVJDHDoOQaQCzXMJ4undVE=
github.com/regclient/regclient v0.8.2/go.mod h1:uGyetv0o6VLyRDjtfeBqp/QBwRLJ3Hcn07/+8QbhNcM=
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=
@@ -25,19 +23,25 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
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.2 h1:CL8llQj3dGRLVQQzHxS+ZYRLanOuhyK1fXgLKD+qV+Y=
github.com/urfave/cli/v3 v3.0.0-alpha9.2/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
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=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
go.bytecodealliance.org v0.6.2 h1:Jy4u5DVmSkXgsnwojBhJ+AD/YsJsR3VzVnxF0xRCqTQ=
go.bytecodealliance.org v0.6.2/go.mod h1:gqjTJm0y9NSksG4py/lSjIQ/SNuIlOQ+hCIEPQwtJgA=
go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA=
go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
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=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
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=
+3 -2
View File
@@ -5,7 +5,8 @@
package tools
import (
_ "github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go"
_ "go.bytecodealliance.org/cm"
_ "go.bytecodealliance.org/cmd/wit-bindgen-go"
)
//go:generate go install github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go
//go:generate go install go.bytecodealliance.org/cmd/wit-bindgen-go
-13
View File
@@ -824,19 +824,6 @@ func (v rawValue) rawLLVMValue(mem *memoryView) (llvm.Value, error) {
if err != nil {
return llvm.Value{}, err
}
if !field.IsAGlobalVariable().IsNil() {
elementType := field.GlobalValueType()
if elementType.TypeKind() == llvm.StructTypeKind {
// There are some special pointer types that should be used
// as a ptrtoint, so that they can be used in certain
// optimizations.
name := elementType.StructName()
if name == "runtime.funcValueWithSignature" {
uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8)
field = llvm.ConstPtrToInt(field, uintptrType)
}
}
}
structFields = append(structFields, field)
i += mem.r.pointerSize
continue
Submodule
+1
Submodule lib/bdwgc added at d1ff06cc50
+40
View File
@@ -0,0 +1,40 @@
package main
import (
"machine"
"runtime"
"sync"
"time"
)
const N = 500000
const Ngoro = 4
func main() {
start := time.Now()
var wg sync.WaitGroup
wg.Add(Ngoro)
for i := 0; i < Ngoro; i++ {
go adder(&wg, N)
}
wg.Wait()
elapsed := time.Since(start)
goroutineCtxSwitchOverhead := (elapsed / (Ngoro * N)).String()
elapsedstr := elapsed.String()
machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
for {
println("bench:", elapsedstr, "goroutine ctx switch:", goroutineCtxSwitchOverhead)
machine.LED.High()
time.Sleep(elapsed)
machine.LED.Low()
time.Sleep(elapsed)
}
}
func adder(wg *sync.WaitGroup, num int) {
for i := 0; i < num; i++ {
runtime.Gosched()
}
wg.Done()
}
+51
View File
@@ -0,0 +1,51 @@
package cm
// CaseUnmarshaler returns an function that can unmarshal text into
// [variant] or [enum] case T.
//
// [enum]: https://component-model.bytecodealliance.org/design/wit.html#enums
// [variant]: https://component-model.bytecodealliance.org/design/wit.html#variants
func CaseUnmarshaler[T ~uint8 | ~uint16 | ~uint32](cases []string) func(v *T, text []byte) error {
if len(cases) <= linearScanThreshold {
return func(v *T, text []byte) error {
if len(text) == 0 {
return &emptyTextError{}
}
s := string(text)
for i := 0; i < len(cases); i++ {
if cases[i] == s {
*v = T(i)
return nil
}
}
return &noMatchingCaseError{}
}
}
m := make(map[string]T, len(cases))
for i, v := range cases {
m[v] = T(i)
}
return func(v *T, text []byte) error {
if len(text) == 0 {
return &emptyTextError{}
}
c, ok := m[string(text)]
if !ok {
return &noMatchingCaseError{}
}
*v = c
return nil
}
}
const linearScanThreshold = 16
type emptyTextError struct{}
func (*emptyTextError) Error() string { return "empty text" }
type noMatchingCaseError struct{}
func (*noMatchingCaseError) Error() string { return "no matching case" }
+1 -1
View File
@@ -1,4 +1,4 @@
// Package cm contains types and functions for interfacing with the WebAssembly Component Model.
// Package cm provides types and functions for interfacing with the WebAssembly Component Model.
//
// The types in this package (such as [List], [Option], [Result], and [Variant]) are designed to match the memory layout
// of [Component Model] types as specified in the [Canonical ABI].
+3
View File
@@ -0,0 +1,3 @@
// This file exists for testing this package without WebAssembly,
// allowing empty function bodies with a //go:wasmimport directive.
// See https://pkg.go.dev/cmd/compile for more information.
+40
View File
@@ -0,0 +1,40 @@
package cm
import "unsafe"
// ErrorContext represents the Component Model [error-context] type,
// an immutable, non-deterministic, host-defined value meant to aid in debugging.
//
// [error-context]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-context-type
type ErrorContext struct {
_ HostLayout
errorContext
}
type errorContext uint32
// Error implements the [error] interface. It returns the debug message associated with err.
func (err errorContext) Error() string {
return err.DebugMessage()
}
// String implements [fmt.Stringer].
func (err errorContext) String() string {
return err.DebugMessage()
}
// DebugMessage represents the Canonical ABI [error-context.debug-message] function.
//
// [error-context.debug-message]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-contextdebug-message
func (err errorContext) DebugMessage() string {
var s string
wasmimport_errorContextDebugMessage(err, unsafe.Pointer(&s))
return s
}
// Drop represents the Canonical ABI [error-context.drop] function.
//
// [error-context.drop]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-contextdrop
func (err errorContext) Drop() {
wasmimport_errorContextDrop(err)
}
+13
View File
@@ -0,0 +1,13 @@
package cm
import "unsafe"
// msg uses unsafe.Pointer for compatibility with go1.23 and lower.
//
//go:wasmimport canon error-context.debug-message
//go:noescape
func wasmimport_errorContextDebugMessage(err errorContext, msg unsafe.Pointer)
//go:wasmimport canon error-context.drop
//go:noescape
func wasmimport_errorContextDrop(err errorContext)
+15
View File
@@ -0,0 +1,15 @@
package cm
// Future represents the Component Model [future] type.
// A future is a special case of stream. In non-error cases,
// a future delivers exactly one value before being automatically closed.
//
// [future]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#asynchronous-value-types
type Future[T any] struct {
_ HostLayout
future[T]
}
type future[T any] uint32
// TODO: implement methods on type future
+3 -1
View File
@@ -1,6 +1,8 @@
package cm
import "unsafe"
import (
"unsafe"
)
// List represents a Component Model list.
// The binary representation of list<T> is similar to a Go slice minus the cap field.
+15
View File
@@ -0,0 +1,15 @@
package cm
// Stream represents the Component Model [stream] type.
// A stream is a special case of stream. In non-error cases,
// a stream delivers exactly one value before being automatically closed.
//
// [stream]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#asynchronous-value-types
type Stream[T any] struct {
_ HostLayout
stream[T]
}
type stream[T any] uint32
// TODO: implement methods on type stream
+2 -3
View File
@@ -3,10 +3,9 @@ package cm
import "unsafe"
// Discriminant is the set of types that can represent the tag or discriminator of a variant.
// Use bool for 2-case variant types, result<T>, or option<T> types, uint8 where there are 256 or
// fewer cases, uint16 for up to 65,536 cases, or uint32 for anything greater.
// Use uint8 where there are 256 or fewer cases, uint16 for up to 65,536 cases, or uint32 for anything greater.
type Discriminant interface {
bool | uint8 | uint16 | uint32
uint8 | uint16 | uint32
}
// Variant represents a loosely-typed Component Model variant.
+196
View File
@@ -0,0 +1,196 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Deep equality test via reflection
package reflectlite
import "unsafe"
// During deepValueEqual, must keep track of checks that are
// in progress. The comparison algorithm assumes that all
// checks in progress are true when it reencounters them.
// Visited comparisons are stored in a map indexed by visit.
type visit struct {
a1 unsafe.Pointer
a2 unsafe.Pointer
typ *RawType
}
// Tests for deep equality using reflected types. The map argument tracks
// comparisons that have already been seen, which allows short circuiting on
// recursive types.
func deepValueEqual(v1, v2 Value, visited map[visit]struct{}) bool {
if !v1.IsValid() || !v2.IsValid() {
return v1.IsValid() == v2.IsValid()
}
if v1.typecode != v2.typecode {
return false
}
// We want to avoid putting more in the visited map than we need to.
// For any possible reference cycle that might be encountered,
// hard(v1, v2) needs to return true for at least one of the types in the cycle,
// and it's safe and valid to get Value's internal pointer.
hard := func(v1, v2 Value) bool {
switch v1.Kind() {
case Map, Slice, Ptr, Interface:
// Nil pointers cannot be cyclic. Avoid putting them in the visited map.
return !v1.IsNil() && !v2.IsNil()
}
return false
}
if hard(v1, v2) {
addr1 := v1.pointer()
addr2 := v2.pointer()
if uintptr(addr1) > uintptr(addr2) {
// Canonicalize order to reduce number of entries in visited.
// Assumes non-moving garbage collector.
addr1, addr2 = addr2, addr1
}
// Short circuit if references are already seen.
v := visit{addr1, addr2, v1.typecode}
if _, ok := visited[v]; ok {
return true
}
// Remember for later.
visited[v] = struct{}{}
}
switch v1.Kind() {
case Array:
for i := 0; i < v1.Len(); i++ {
if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
return false
}
}
return true
case Slice:
if v1.IsNil() != v2.IsNil() {
return false
}
if v1.Len() != v2.Len() {
return false
}
if v1.UnsafePointer() == v2.UnsafePointer() {
return true
}
for i := 0; i < v1.Len(); i++ {
if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
return false
}
}
return true
case Interface:
if v1.IsNil() || v2.IsNil() {
return v1.IsNil() == v2.IsNil()
}
return deepValueEqual(v1.Elem(), v2.Elem(), visited)
case Ptr:
if v1.UnsafePointer() == v2.UnsafePointer() {
return true
}
return deepValueEqual(v1.Elem(), v2.Elem(), visited)
case Struct:
for i, n := 0, v1.NumField(); i < n; i++ {
if !deepValueEqual(v1.Field(i), v2.Field(i), visited) {
return false
}
}
return true
case Map:
if v1.IsNil() != v2.IsNil() {
return false
}
if v1.Len() != v2.Len() {
return false
}
if v1.UnsafePointer() == v2.UnsafePointer() {
return true
}
for _, k := range v1.MapKeys() {
val1 := v1.MapIndex(k)
val2 := v2.MapIndex(k)
if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited) {
return false
}
}
return true
case Func:
if v1.IsNil() && v2.IsNil() {
return true
}
// Can't do better than this:
return false
default:
// Normal equality suffices
return valueInterfaceUnsafe(v1) == valueInterfaceUnsafe(v2)
}
}
// DeepEqual reports whether x and y are “deeply equal”, defined as follows.
// Two values of identical type are deeply equal if one of the following cases applies.
// Values of distinct types are never deeply equal.
//
// Array values are deeply equal when their corresponding elements are deeply equal.
//
// Struct values are deeply equal if their corresponding fields,
// both exported and unexported, are deeply equal.
//
// Func values are deeply equal if both are nil; otherwise they are not deeply equal.
//
// Interface values are deeply equal if they hold deeply equal concrete values.
//
// Map values are deeply equal when all of the following are true:
// they are both nil or both non-nil, they have the same length,
// and either they are the same map object or their corresponding keys
// (matched using Go equality) map to deeply equal values.
//
// Pointer values are deeply equal if they are equal using Go's == operator
// or if they point to deeply equal values.
//
// Slice values are deeply equal when all of the following are true:
// they are both nil or both non-nil, they have the same length,
// and either they point to the same initial entry of the same underlying array
// (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal.
// Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil))
// are not deeply equal.
//
// Other values - numbers, bools, strings, and channels - are deeply equal
// if they are equal using Go's == operator.
//
// In general DeepEqual is a recursive relaxation of Go's == operator.
// However, this idea is impossible to implement without some inconsistency.
// Specifically, it is possible for a value to be unequal to itself,
// either because it is of func type (uncomparable in general)
// or because it is a floating-point NaN value (not equal to itself in floating-point comparison),
// or because it is an array, struct, or interface containing
// such a value.
// On the other hand, pointer values are always equal to themselves,
// even if they point at or contain such problematic values,
// because they compare equal using Go's == operator, and that
// is a sufficient condition to be deeply equal, regardless of content.
// DeepEqual has been defined so that the same short-cut applies
// to slices and maps: if x and y are the same slice or the same map,
// they are deeply equal regardless of content.
//
// As DeepEqual traverses the data values it may find a cycle. The
// second and subsequent times that DeepEqual compares two pointer
// values that have been compared before, it treats the values as
// equal rather than examining the values to which they point.
// This ensures that DeepEqual terminates.
func DeepEqual(x, y interface{}) bool {
if x == nil || y == nil {
return x == y
}
v1 := ValueOf(x)
v2 := ValueOf(y)
if v1.typecode != v2.typecode {
return false
}
return deepValueEqual(v1, v2, make(map[visit]struct{}))
}
@@ -1,6 +1,6 @@
//go:build mips
package reflect
package reflectlite
import "unsafe"
@@ -1,6 +1,6 @@
//go:build !mips
package reflect
package reflectlite
import "unsafe"
-51
View File
@@ -1,51 +0,0 @@
package reflectlite
import "reflect"
func Swapper(slice interface{}) func(i, j int) {
return reflect.Swapper(slice)
}
type Kind = reflect.Kind
type Type = reflect.Type
type Value = reflect.Value
const (
Invalid Kind = reflect.Invalid
Bool Kind = reflect.Bool
Int Kind = reflect.Int
Int8 Kind = reflect.Int8
Int16 Kind = reflect.Int16
Int32 Kind = reflect.Int32
Int64 Kind = reflect.Int64
Uint Kind = reflect.Uint
Uint8 Kind = reflect.Uint8
Uint16 Kind = reflect.Uint16
Uint32 Kind = reflect.Uint32
Uint64 Kind = reflect.Uint64
Uintptr Kind = reflect.Uintptr
Float32 Kind = reflect.Float32
Float64 Kind = reflect.Float64
Complex64 Kind = reflect.Complex64
Complex128 Kind = reflect.Complex128
Array Kind = reflect.Array
Chan Kind = reflect.Chan
Func Kind = reflect.Func
Interface Kind = reflect.Interface
Map Kind = reflect.Map
Ptr Kind = reflect.Ptr
Slice Kind = reflect.Slice
String Kind = reflect.String
Struct Kind = reflect.Struct
UnsafePointer Kind = reflect.UnsafePointer
)
func ValueOf(i interface{}) reflect.Value {
return reflect.ValueOf(i)
}
func TypeOf(i interface{}) reflect.Type {
return reflect.TypeOf(i)
}
type ValueError = reflect.ValueError
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package reflect
package reflectlite
import (
"unicode/utf8"
+40
View File
@@ -0,0 +1,40 @@
package reflectlite
import "unsafe"
// Some of code here has been copied from the Go sources:
// https://github.com/golang/go/blob/go1.15.2/src/reflect/swapper.go
// It has the following copyright note:
//
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
func Swapper(slice interface{}) func(i, j int) {
v := ValueOf(slice)
if v.Kind() != Slice {
panic(&ValueError{Method: "Swapper"})
}
// Just return Nop func if nothing to swap.
if v.Len() < 2 {
return func(i, j int) {}
}
typ := v.typecode.Elem()
size := typ.Size()
header := (*sliceHeader)(v.value)
tmp := unsafe.Pointer(&make([]byte, size)[0])
return func(i, j int) {
if uint(i) >= uint(header.len) || uint(j) >= uint(header.len) {
panic("reflect: slice index out of range")
}
val1 := unsafe.Add(header.data, uintptr(i)*size)
val2 := unsafe.Add(header.data, uintptr(j)*size)
memcpy(tmp, val1, size)
memcpy(val1, val2, size)
memcpy(val2, tmp, size)
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+105
View File
@@ -0,0 +1,105 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package reflectlite
// VisibleFields returns all the visible fields in t, which must be a
// struct type. A field is defined as visible if it's accessible
// directly with a FieldByName call. The returned fields include fields
// inside anonymous struct members and unexported fields. They follow
// the same order found in the struct, with anonymous fields followed
// immediately by their promoted fields.
//
// For each element e of the returned slice, the corresponding field
// can be retrieved from a value v of type t by calling v.FieldByIndex(e.Index).
func VisibleFields(t Type) []StructField {
if t == nil {
panic("reflect: VisibleFields(nil)")
}
if t.Kind() != Struct {
panic("reflect.VisibleFields of non-struct type")
}
w := &visibleFieldsWalker{
byName: make(map[string]int),
visiting: make(map[Type]bool),
fields: make([]StructField, 0, t.NumField()),
index: make([]int, 0, 2),
}
w.walk(t)
// Remove all the fields that have been hidden.
// Use an in-place removal that avoids copying in
// the common case that there are no hidden fields.
j := 0
for i := range w.fields {
f := &w.fields[i]
if f.Name == "" {
continue
}
if i != j {
// A field has been removed. We need to shuffle
// all the subsequent elements up.
w.fields[j] = *f
}
j++
}
return w.fields[:j]
}
type visibleFieldsWalker struct {
byName map[string]int
visiting map[Type]bool
fields []StructField
index []int
}
// walk walks all the fields in the struct type t, visiting
// fields in index preorder and appending them to w.fields
// (this maintains the required ordering).
// Fields that have been overridden have their
// Name field cleared.
func (w *visibleFieldsWalker) walk(t Type) {
if w.visiting[t] {
return
}
w.visiting[t] = true
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
w.index = append(w.index, i)
add := true
if oldIndex, ok := w.byName[f.Name]; ok {
old := &w.fields[oldIndex]
if len(w.index) == len(old.Index) {
// Fields with the same name at the same depth
// cancel one another out. Set the field name
// to empty to signify that has happened, and
// there's no need to add this field.
old.Name = ""
add = false
} else if len(w.index) < len(old.Index) {
// The old field loses because it's deeper than the new one.
old.Name = ""
} else {
// The old field wins because it's shallower than the new one.
add = false
}
}
if add {
// Copy the index so that it's not overwritten
// by the other appends.
f.Index = append([]int(nil), w.index...)
w.byName[f.Name] = len(w.fields)
w.fields = append(w.fields, f)
}
if f.Anonymous {
if f.Type.Kind() == Pointer {
f.Type = f.Type.Elem()
}
if f.Type.Kind() == Struct {
w.walk(f.Type)
}
}
w.index = w.index[:len(w.index)-1]
}
delete(w.visiting, t)
}
File diff suppressed because it is too large Load Diff
@@ -15,7 +15,7 @@ import (
//
//go:nosplit
func Exit(status cm.BoolResult) {
status0 := cm.BoolToU32(status)
status0 := (uint32)(cm.BoolToU32(status))
wasmimport_Exit((uint32)(status0))
return
}
+1 -1
View File
@@ -12,6 +12,6 @@ import (
//export wasi:cli/run@0.2.0#run
func wasmexport_Run() (result0 uint32) {
result := Exports.Run()
result0 = cm.BoolToU32(result)
result0 = (uint32)(cm.BoolToU32(result))
return
}
@@ -31,9 +31,9 @@ import (
// nanoseconds: u32,
// }
type DateTime struct {
_ cm.HostLayout
Seconds uint64
Nanoseconds uint32
_ cm.HostLayout `json:"-"`
Seconds uint64 `json:"seconds"`
Nanoseconds uint32 `json:"nanoseconds"`
}
// Now represents the imported function "now".
@@ -30,7 +30,7 @@ func lower_NewTimestamp(v NewTimestamp) (f0 uint32, f1 uint64, f2 uint32) {
f0 = (uint32)(v.Tag())
switch f0 {
case 2: // timestamp
v1, v2 := lower_DateTime(*v.Timestamp())
v1, v2 := lower_DateTime(*cm.Case[DateTime](&v, 2))
f1 = (uint64)(v1)
f2 = (uint32)(v2)
}
@@ -106,7 +106,7 @@ const (
DescriptorTypeSocket
)
var stringsDescriptorType = [8]string{
var _DescriptorTypeStrings = [8]string{
"unknown",
"block-device",
"character-device",
@@ -119,9 +119,22 @@ var stringsDescriptorType = [8]string{
// String implements [fmt.Stringer], returning the enum case name of e.
func (e DescriptorType) String() string {
return stringsDescriptorType[e]
return _DescriptorTypeStrings[e]
}
// MarshalText implements [encoding.TextMarshaler].
func (e DescriptorType) MarshalText() ([]byte, error) {
return []byte(e.String()), nil
}
// UnmarshalText implements [encoding.TextUnmarshaler], unmarshaling into an enum
// case. Returns an error if the supplied text is not one of the enum cases.
func (e *DescriptorType) UnmarshalText(text []byte) error {
return _DescriptorTypeUnmarshalCase(e, text)
}
var _DescriptorTypeUnmarshalCase = cm.CaseUnmarshaler[DescriptorType](_DescriptorTypeStrings[:])
// DescriptorFlags represents the flags "wasi:filesystem/types@0.2.0#descriptor-flags".
//
// Descriptor flags.
@@ -246,34 +259,34 @@ type LinkCount uint64
// status-change-timestamp: option<datetime>,
// }
type DescriptorStat struct {
_ cm.HostLayout
_ cm.HostLayout `json:"-"`
// File type.
Type DescriptorType
Type DescriptorType `json:"type"`
// Number of hard links to the file.
LinkCount LinkCount
LinkCount LinkCount `json:"link-count"`
// For regular files, the file size in bytes. For symbolic links, the
// length in bytes of the pathname contained in the symbolic link.
Size FileSize
Size FileSize `json:"size"`
// Last data access timestamp.
//
// If the `option` is none, the platform doesn't maintain an access
// timestamp for this file.
DataAccessTimestamp cm.Option[DateTime]
DataAccessTimestamp cm.Option[DateTime] `json:"data-access-timestamp"`
// Last data modification timestamp.
//
// If the `option` is none, the platform doesn't maintain a
// modification timestamp for this file.
DataModificationTimestamp cm.Option[DateTime]
DataModificationTimestamp cm.Option[DateTime] `json:"data-modification-timestamp"`
// 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[DateTime]
StatusChangeTimestamp cm.Option[DateTime] `json:"status-change-timestamp"`
}
// NewTimestamp represents the variant "wasi:filesystem/types@0.2.0#new-timestamp".
@@ -326,7 +339,7 @@ func (self *NewTimestamp) Timestamp() *DateTime {
return cm.Case[DateTime](self, 2)
}
var stringsNewTimestamp = [3]string{
var _NewTimestampStrings = [3]string{
"no-change",
"now",
"timestamp",
@@ -334,7 +347,7 @@ var stringsNewTimestamp = [3]string{
// String implements [fmt.Stringer], returning the variant case name of v.
func (v NewTimestamp) String() string {
return stringsNewTimestamp[v.Tag()]
return _NewTimestampStrings[v.Tag()]
}
// DirectoryEntry represents the record "wasi:filesystem/types@0.2.0#directory-entry".
@@ -346,12 +359,12 @@ func (v NewTimestamp) String() string {
// name: string,
// }
type DirectoryEntry struct {
_ cm.HostLayout
_ cm.HostLayout `json:"-"`
// The type of the file referred to by this directory entry.
Type DescriptorType
Type DescriptorType `json:"type"`
// The name of the object.
Name string
Name string `json:"name"`
}
// ErrorCode represents the enum "wasi:filesystem/types@0.2.0#error-code".
@@ -516,7 +529,7 @@ const (
ErrorCodeCrossDevice
)
var stringsErrorCode = [37]string{
var _ErrorCodeStrings = [37]string{
"access",
"would-block",
"already",
@@ -558,9 +571,22 @@ var stringsErrorCode = [37]string{
// String implements [fmt.Stringer], returning the enum case name of e.
func (e ErrorCode) String() string {
return stringsErrorCode[e]
return _ErrorCodeStrings[e]
}
// MarshalText implements [encoding.TextMarshaler].
func (e ErrorCode) MarshalText() ([]byte, error) {
return []byte(e.String()), nil
}
// UnmarshalText implements [encoding.TextUnmarshaler], unmarshaling into an enum
// case. Returns an error if the supplied text is not one of the enum cases.
func (e *ErrorCode) UnmarshalText(text []byte) error {
return _ErrorCodeUnmarshalCase(e, text)
}
var _ErrorCodeUnmarshalCase = cm.CaseUnmarshaler[ErrorCode](_ErrorCodeStrings[:])
// Advice represents the enum "wasi:filesystem/types@0.2.0#advice".
//
// File or memory access pattern advisory information.
@@ -601,7 +627,7 @@ const (
AdviceNoReuse
)
var stringsAdvice = [6]string{
var _AdviceStrings = [6]string{
"normal",
"sequential",
"random",
@@ -612,9 +638,22 @@ var stringsAdvice = [6]string{
// String implements [fmt.Stringer], returning the enum case name of e.
func (e Advice) String() string {
return stringsAdvice[e]
return _AdviceStrings[e]
}
// MarshalText implements [encoding.TextMarshaler].
func (e Advice) MarshalText() ([]byte, error) {
return []byte(e.String()), nil
}
// UnmarshalText implements [encoding.TextUnmarshaler], unmarshaling into an enum
// case. Returns an error if the supplied text is not one of the enum cases.
func (e *Advice) UnmarshalText(text []byte) error {
return _AdviceUnmarshalCase(e, text)
}
var _AdviceUnmarshalCase = cm.CaseUnmarshaler[Advice](_AdviceStrings[:])
// MetadataHashValue represents the record "wasi:filesystem/types@0.2.0#metadata-hash-value".
//
// A 128-bit hash value, split into parts because wasm doesn't have a
@@ -625,12 +664,12 @@ func (e Advice) String() string {
// upper: u64,
// }
type MetadataHashValue struct {
_ cm.HostLayout
_ cm.HostLayout `json:"-"`
// 64 bits of a 128-bit hash value.
Lower uint64
Lower uint64 `json:"lower"`
// Another 64 bits of a 128-bit hash value.
Upper uint64
Upper uint64 `json:"upper"`
}
// Descriptor represents the imported resource "wasi:filesystem/types@0.2.0#descriptor".
@@ -761,7 +800,7 @@ func (self Descriptor) IsSameObject(other Descriptor) (result bool) {
self0 := cm.Reinterpret[uint32](self)
other0 := cm.Reinterpret[uint32](other)
result0 := wasmimport_DescriptorIsSameObject((uint32)(self0), (uint32)(other0))
result = cm.U32ToBool((uint32)(result0))
result = (bool)(cm.U32ToBool((uint32)(result0)))
return
}
+1 -1
View File
@@ -57,7 +57,7 @@ func (self Pollable) Block() {
func (self Pollable) Ready() (result bool) {
self0 := cm.Reinterpret[uint32](self)
result0 := wasmimport_PollableReady((uint32)(self0))
result = cm.U32ToBool((uint32)(result0))
result = (bool)(cm.U32ToBool((uint32)(result0)))
return
}
@@ -1,12 +0,0 @@
// Code generated by wit-bindgen-go. DO NOT EDIT.
package streams
import (
"unsafe"
)
// StreamErrorShape is used for storage in variant or result types.
type StreamErrorShape struct {
shape [unsafe.Sizeof(StreamError{})]byte
}
@@ -64,14 +64,14 @@ func (self *StreamError) Closed() bool {
return self.Tag() == 1
}
var stringsStreamError = [2]string{
var _StreamErrorStrings = [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()]
return _StreamErrorStrings[v.Tag()]
}
// InputStream represents the imported resource "wasi:io/streams@0.2.0#input-stream".
@@ -273,13 +273,13 @@ func (self OutputStream) BlockingSplice(src InputStream, len_ uint64) (result cm
//
// let pollable = this.subscribe();
// while !contents.is_empty() {
// // Wait for the stream to become writable
// pollable.block();
// let Ok(n) = this.check-write(); // eliding error handling
// let len = min(n, contents.len());
// let (chunk, rest) = contents.split_at(len);
// this.write(chunk ); // eliding error handling
// contents = rest;
// // Wait for the stream to become writable
// pollable.block();
// let Ok(n) = this.check-write(); // eliding error handling
// let len = min(n, contents.len());
// let (chunk, rest) = contents.split_at(len);
// this.write(chunk ); // eliding error handling
// contents = rest;
// }
// this.flush();
// // Wait for completion of `flush`
@@ -309,12 +309,12 @@ func (self OutputStream) BlockingWriteAndFlush(contents cm.List[uint8]) (result
//
// let pollable = this.subscribe();
// while num_zeroes != 0 {
// // Wait for the stream to become writable
// pollable.block();
// let Ok(n) = this.check-write(); // eliding error handling
// let len = min(n, num_zeroes);
// this.write-zeroes(len); // eliding error handling
// num_zeroes -= len;
// // Wait for the stream to become writable
// pollable.block();
// let Ok(n) = this.check-write(); // eliding error handling
// let len = min(n, num_zeroes);
// this.write-zeroes(len); // eliding error handling
// num_zeroes -= len;
// }
// this.flush();
// // Wait for completion of `flush`
@@ -153,7 +153,7 @@ const (
ErrorCodePermanentResolverFailure
)
var stringsErrorCode = [21]string{
var _ErrorCodeStrings = [21]string{
"unknown",
"access-denied",
"not-supported",
@@ -179,9 +179,22 @@ var stringsErrorCode = [21]string{
// String implements [fmt.Stringer], returning the enum case name of e.
func (e ErrorCode) String() string {
return stringsErrorCode[e]
return _ErrorCodeStrings[e]
}
// MarshalText implements [encoding.TextMarshaler].
func (e ErrorCode) MarshalText() ([]byte, error) {
return []byte(e.String()), nil
}
// UnmarshalText implements [encoding.TextUnmarshaler], unmarshaling into an enum
// case. Returns an error if the supplied text is not one of the enum cases.
func (e *ErrorCode) UnmarshalText(text []byte) error {
return _ErrorCodeUnmarshalCase(e, text)
}
var _ErrorCodeUnmarshalCase = cm.CaseUnmarshaler[ErrorCode](_ErrorCodeStrings[:])
// IPAddressFamily represents the enum "wasi:sockets/network@0.2.0#ip-address-family".
//
// enum ip-address-family {
@@ -198,16 +211,29 @@ const (
IPAddressFamilyIPv6
)
var stringsIPAddressFamily = [2]string{
var _IPAddressFamilyStrings = [2]string{
"ipv4",
"ipv6",
}
// String implements [fmt.Stringer], returning the enum case name of e.
func (e IPAddressFamily) String() string {
return stringsIPAddressFamily[e]
return _IPAddressFamilyStrings[e]
}
// MarshalText implements [encoding.TextMarshaler].
func (e IPAddressFamily) MarshalText() ([]byte, error) {
return []byte(e.String()), nil
}
// UnmarshalText implements [encoding.TextUnmarshaler], unmarshaling into an enum
// case. Returns an error if the supplied text is not one of the enum cases.
func (e *IPAddressFamily) UnmarshalText(text []byte) error {
return _IPAddressFamilyUnmarshalCase(e, text)
}
var _IPAddressFamilyUnmarshalCase = cm.CaseUnmarshaler[IPAddressFamily](_IPAddressFamilyStrings[:])
// IPv4Address represents the tuple "wasi:sockets/network@0.2.0#ipv4-address".
//
// type ipv4-address = tuple<u8, u8, u8, u8>
@@ -246,14 +272,14 @@ func (self *IPAddress) IPv6() *IPv6Address {
return cm.Case[IPv6Address](self, 1)
}
var stringsIPAddress = [2]string{
var _IPAddressStrings = [2]string{
"ipv4",
"ipv6",
}
// String implements [fmt.Stringer], returning the variant case name of v.
func (v IPAddress) String() string {
return stringsIPAddress[v.Tag()]
return _IPAddressStrings[v.Tag()]
}
// IPv4SocketAddress represents the record "wasi:sockets/network@0.2.0#ipv4-socket-address".
@@ -263,12 +289,12 @@ func (v IPAddress) String() string {
// address: ipv4-address,
// }
type IPv4SocketAddress struct {
_ cm.HostLayout
_ cm.HostLayout `json:"-"`
// sin_port
Port uint16
Port uint16 `json:"port"`
// sin_addr
Address IPv4Address
Address IPv4Address `json:"address"`
}
// IPv6SocketAddress represents the record "wasi:sockets/network@0.2.0#ipv6-socket-address".
@@ -280,18 +306,18 @@ type IPv4SocketAddress struct {
// scope-id: u32,
// }
type IPv6SocketAddress struct {
_ cm.HostLayout
_ cm.HostLayout `json:"-"`
// sin6_port
Port uint16
Port uint16 `json:"port"`
// sin6_flowinfo
FlowInfo uint32
FlowInfo uint32 `json:"flow-info"`
// sin6_addr
Address IPv6Address
Address IPv6Address `json:"address"`
// sin6_scope_id
ScopeID uint32
ScopeID uint32 `json:"scope-id"`
}
// IPSocketAddress represents the variant "wasi:sockets/network@0.2.0#ip-socket-address".
@@ -322,12 +348,12 @@ func (self *IPSocketAddress) IPv6() *IPv6SocketAddress {
return cm.Case[IPv6SocketAddress](self, 1)
}
var stringsIPSocketAddress = [2]string{
var _IPSocketAddressStrings = [2]string{
"ipv4",
"ipv6",
}
// String implements [fmt.Stringer], returning the variant case name of v.
func (v IPSocketAddress) String() string {
return stringsIPSocketAddress[v.Tag()]
return _IPSocketAddressStrings[v.Tag()]
}
+3 -3
View File
@@ -23,7 +23,7 @@ type TupleInputStreamOutputStreamShape struct {
// IPSocketAddressShape is used for storage in variant or result types.
type IPSocketAddressShape struct {
_ cm.HostLayout
shape [unsafe.Sizeof(network.IPSocketAddress{})]byte
shape [unsafe.Sizeof(IPSocketAddress{})]byte
}
func lower_IPv4Address(v network.IPv4Address) (f0 uint32, f1 uint32, f2 uint32, f3 uint32) {
@@ -64,14 +64,14 @@ func lower_IPSocketAddress(v network.IPSocketAddress) (f0 uint32, f1 uint32, f2
f0 = (uint32)(v.Tag())
switch f0 {
case 0: // ipv4
v1, v2, v3, v4, v5 := lower_IPv4SocketAddress(*v.IPv4())
v1, v2, v3, v4, v5 := lower_IPv4SocketAddress(*cm.Case[network.IPv4SocketAddress](&v, 0))
f1 = (uint32)(v1)
f2 = (uint32)(v2)
f3 = (uint32)(v3)
f4 = (uint32)(v4)
f5 = (uint32)(v5)
case 1: // ipv6
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 := lower_IPv6SocketAddress(*v.IPv6())
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 := lower_IPv6SocketAddress(*cm.Case[network.IPv6SocketAddress](&v, 1))
f1 = (uint32)(v1)
f2 = (uint32)(v2)
f3 = (uint32)(v3)
@@ -46,7 +46,7 @@ func wasmimport_TCPSocketKeepAliveCount(self0 uint32, result *cm.Result[uint32,
//go:wasmimport wasi:sockets/tcp@0.2.0 [method]tcp-socket.keep-alive-enabled
//go:noescape
func wasmimport_TCPSocketKeepAliveEnabled(self0 uint32, result *cm.Result[bool, bool, ErrorCode])
func wasmimport_TCPSocketKeepAliveEnabled(self0 uint32, result *cm.Result[ErrorCode, bool, ErrorCode])
//go:wasmimport wasi:sockets/tcp@0.2.0 [method]tcp-socket.keep-alive-idle-time
//go:noescape
@@ -71,7 +71,7 @@ const (
ShutdownTypeBoth
)
var stringsShutdownType = [3]string{
var _ShutdownTypeStrings = [3]string{
"receive",
"send",
"both",
@@ -79,9 +79,22 @@ var stringsShutdownType = [3]string{
// String implements [fmt.Stringer], returning the enum case name of e.
func (e ShutdownType) String() string {
return stringsShutdownType[e]
return _ShutdownTypeStrings[e]
}
// MarshalText implements [encoding.TextMarshaler].
func (e ShutdownType) MarshalText() ([]byte, error) {
return []byte(e.String()), nil
}
// UnmarshalText implements [encoding.TextUnmarshaler], unmarshaling into an enum
// case. Returns an error if the supplied text is not one of the enum cases.
func (e *ShutdownType) UnmarshalText(text []byte) error {
return _ShutdownTypeUnmarshalCase(e, text)
}
var _ShutdownTypeUnmarshalCase = cm.CaseUnmarshaler[ShutdownType](_ShutdownTypeStrings[:])
// TCPSocket represents the imported resource "wasi:sockets/tcp@0.2.0#tcp-socket".
//
// A TCP socket resource.
@@ -241,7 +254,7 @@ func (self TCPSocket) HopLimit() (result cm.Result[uint8, uint8, ErrorCode]) {
func (self TCPSocket) IsListening() (result bool) {
self0 := cm.Reinterpret[uint32](self)
result0 := wasmimport_TCPSocketIsListening((uint32)(self0))
result = cm.U32ToBool((uint32)(result0))
result = (bool)(cm.U32ToBool((uint32)(result0)))
return
}
@@ -285,7 +298,7 @@ func (self TCPSocket) KeepAliveCount() (result cm.Result[uint32, uint32, ErrorCo
// keep-alive-enabled: func() -> result<bool, error-code>
//
//go:nosplit
func (self TCPSocket) KeepAliveEnabled() (result cm.Result[bool, bool, ErrorCode]) {
func (self TCPSocket) KeepAliveEnabled() (result cm.Result[ErrorCode, bool, ErrorCode]) {
self0 := cm.Reinterpret[uint32](self)
wasmimport_TCPSocketKeepAliveEnabled((uint32)(self0), &result)
return
@@ -457,7 +470,7 @@ func (self TCPSocket) SetKeepAliveCount(value uint32) (result cm.Result[ErrorCod
//go:nosplit
func (self TCPSocket) SetKeepAliveEnabled(value bool) (result cm.Result[ErrorCode, struct{}, ErrorCode]) {
self0 := cm.Reinterpret[uint32](self)
value0 := cm.BoolToU32(value)
value0 := (uint32)(cm.BoolToU32(value))
wasmimport_TCPSocketSetKeepAliveEnabled((uint32)(self0), (uint32)(value0), &result)
return
}
+3 -3
View File
@@ -11,7 +11,7 @@ import (
// IPSocketAddressShape is used for storage in variant or result types.
type IPSocketAddressShape struct {
_ cm.HostLayout
shape [unsafe.Sizeof(network.IPSocketAddress{})]byte
shape [unsafe.Sizeof(IPSocketAddress{})]byte
}
func lower_IPv4Address(v network.IPv4Address) (f0 uint32, f1 uint32, f2 uint32, f3 uint32) {
@@ -52,14 +52,14 @@ func lower_IPSocketAddress(v network.IPSocketAddress) (f0 uint32, f1 uint32, f2
f0 = (uint32)(v.Tag())
switch f0 {
case 0: // ipv4
v1, v2, v3, v4, v5 := lower_IPv4SocketAddress(*v.IPv4())
v1, v2, v3, v4, v5 := lower_IPv4SocketAddress(*cm.Case[network.IPv4SocketAddress](&v, 0))
f1 = (uint32)(v1)
f2 = (uint32)(v2)
f3 = (uint32)(v3)
f4 = (uint32)(v4)
f5 = (uint32)(v5)
case 1: // ipv6
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 := lower_IPv6SocketAddress(*v.IPv6())
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 := lower_IPv6SocketAddress(*cm.Case[network.IPv6SocketAddress](&v, 1))
f1 = (uint32)(v1)
f2 = (uint32)(v2)
f3 = (uint32)(v3)
@@ -43,11 +43,11 @@ type IPAddressFamily = network.IPAddressFamily
// remote-address: ip-socket-address,
// }
type IncomingDatagram struct {
_ cm.HostLayout
_ cm.HostLayout `json:"-"`
// The payload.
//
// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes.
Data cm.List[uint8]
Data cm.List[uint8] `json:"data"`
// The source address.
//
@@ -55,7 +55,7 @@ type IncomingDatagram struct {
// with, if any.
//
// Equivalent to the `src_addr` out parameter of `recvfrom`.
RemoteAddress IPSocketAddress
RemoteAddress IPSocketAddress `json:"remote-address"`
}
// OutgoingDatagram represents the record "wasi:sockets/udp@0.2.0#outgoing-datagram".
@@ -67,9 +67,9 @@ type IncomingDatagram struct {
// remote-address: option<ip-socket-address>,
// }
type OutgoingDatagram struct {
_ cm.HostLayout
_ cm.HostLayout `json:"-"`
// The payload.
Data cm.List[uint8]
Data cm.List[uint8] `json:"data"`
// The destination address.
//
@@ -80,7 +80,7 @@ type OutgoingDatagram struct {
//
// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise
// it is equivalent to `sendto`.
RemoteAddress cm.Option[IPSocketAddress]
RemoteAddress cm.Option[IPSocketAddress] `json:"remote-address"`
}
// UDPSocket represents the imported resource "wasi:sockets/udp@0.2.0#udp-socket".
@@ -321,10 +321,10 @@ func (self UDPSocket) StartBind(network_ Network, localAddress IPSocketAddress)
// The POSIX equivalent in pseudo-code is:
//
// if (was previously connected) {
// connect(s, AF_UNSPEC)
// connect(s, AF_UNSPEC)
// }
// if (remote_address is Some) {
// connect(s, remote_address)
// connect(s, remote_address)
// }
//
// Unlike in POSIX, the socket must already be explicitly bound.
+3 -3
View File
@@ -186,15 +186,15 @@ const (
)
var (
SPI1 = SPI{
SPI1 = &SPI{
Bus: stm32.SPI2,
AltFuncSelector: AF5_SPI1_SPI2,
}
SPI2 = SPI{
SPI2 = &SPI{
Bus: stm32.SPI3,
AltFuncSelector: AF6_SPI3,
}
SPI3 = SPI{
SPI3 = &SPI{
Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2,
}
+1 -1
View File
@@ -77,7 +77,7 @@ var (
I2C0 = I2C1
// SPI
SPI3 = SPI{
SPI3 = &SPI{
Bus: stm32.SPI3,
}
)
+1 -1
View File
@@ -6,7 +6,7 @@ import "device/sifive"
// SPI on the HiFive1.
var (
SPI1 = SPI{
SPI1 = &SPI{
Bus: sifive.QSPI1,
}
)
+2 -2
View File
@@ -84,10 +84,10 @@ var (
I2C0 = I2C1
// SPI
SPI0 = SPI{
SPI0 = &SPI{
Bus: stm32.SPI1,
}
SPI1 = &SPI0
SPI1 = SPI0
)
func init() {
+1 -1
View File
@@ -85,7 +85,7 @@ var (
I2C0 = I2C2
// SPI
SPI3 = SPI{
SPI3 = &SPI{
Bus: stm32.SPI3,
}
)
+2 -2
View File
@@ -6,10 +6,10 @@ import "device/kendryte"
// SPI on the MAix Bit.
var (
SPI0 = SPI{
SPI0 = &SPI{
Bus: kendryte.SPI0,
}
SPI1 = SPI{
SPI1 = &SPI{
Bus: kendryte.SPI1,
}
)
+2 -2
View File
@@ -89,11 +89,11 @@ const (
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
var (
SPI0 = SPI{
SPI0 = &SPI{
Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2,
}
SPI1 = &SPI0
SPI1 = SPI0
)
const (
+2 -2
View File
@@ -86,11 +86,11 @@ var (
I2C0 = I2C1
// SPI
SPI0 = SPI{
SPI0 = &SPI{
Bus: stm32.SPI1,
AltFuncSelector: 0,
}
SPI1 = &SPI0
SPI1 = SPI0
)
func init() {
+1 -1
View File
@@ -84,7 +84,7 @@ var (
I2C0 = I2C1
// SPI
SPI3 = SPI{
SPI3 = &SPI{
Bus: stm32.SPI3,
}
)
+2 -2
View File
@@ -59,11 +59,11 @@ const (
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
// TODO: implement SPI2 and SPI3.
var (
SPI0 = SPI{
SPI0 = &SPI{
Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2,
}
SPI1 = &SPI0
SPI1 = SPI0
)
const (
+2 -2
View File
@@ -86,11 +86,11 @@ const (
// Since the first interface is named SPI1, both SPI0 and SPI1 refer to SPI1.
// TODO: implement SPI2 and SPI3.
var (
SPI0 = SPI{
SPI0 = &SPI{
Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_SPI2,
}
SPI1 = &SPI0
SPI1 = SPI0
)
const (
+4 -7
View File
@@ -263,9 +263,8 @@ const (
)
var (
SPI0 = SPI1 // SPI0 is an alias of SPI1 (LPSPI4)
SPI1 = &_SPI1
_SPI1 = SPI{
SPI0 = SPI1 // SPI0 is an alias of SPI1 (LPSPI4)
SPI1 = &SPI{
Bus: nxp.LPSPI4,
muxSDI: muxSelect{ // D12 (PB1 [B0_01])
mux: nxp.IOMUXC_LPSPI4_SDI_SELECT_INPUT_DAISY_GPIO_B0_01_ALT3,
@@ -284,8 +283,7 @@ var (
sel: &nxp.IOMUXC.LPSPI4_PCS0_SELECT_INPUT,
},
}
SPI2 = &_SPI2
_SPI2 = SPI{
SPI2 = &SPI{
Bus: nxp.LPSPI3,
muxSDI: muxSelect{ // D1 (PA2 [AD_B0_02])
mux: nxp.IOMUXC_LPSPI3_SDI_SELECT_INPUT_DAISY_GPIO_AD_B0_02_ALT7,
@@ -304,8 +302,7 @@ var (
sel: &nxp.IOMUXC.LPSPI3_PCS0_SELECT_INPUT,
},
}
SPI3 = &_SPI3
_SPI3 = SPI{
SPI3 = &SPI{
Bus: nxp.LPSPI1,
muxSDI: muxSelect{ // D34 (PC15 [SD_B0_03])
mux: nxp.IOMUXC_LPSPI1_SDI_SELECT_INPUT_DAISY_GPIO_SD_B0_03_ALT4,
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build nrf || nrf51 || nrf52 || nrf528xx || stm32f4 || stm32l4 || stm32wlx || atsamd21 || atsamd51 || atsame5x || rp2040
//go:build nrf || nrf51 || nrf52 || nrf528xx || stm32f4 || stm32l4 || stm32wlx || atsamd21 || atsamd51 || atsame5x || rp2040 || rp2350
package machine
+2 -2
View File
@@ -257,7 +257,7 @@ type SPI struct {
}
// Configure is intended to setup the SPI interface.
func (s SPI) Configure(config SPIConfig) error {
func (s *SPI) Configure(config SPIConfig) error {
// This is only here to help catch a bug with the configuration
// where a machine missed a value.
@@ -330,7 +330,7 @@ func (s SPI) Configure(config SPIConfig) error {
}
// Transfer writes the byte into the register and returns the read content
func (s SPI) Transfer(b byte) (byte, error) {
func (s *SPI) Transfer(b byte) (byte, error) {
s.spdr.Set(uint8(b))
for !s.spsr.HasBits(s.spsrSPIF) {
+1 -1
View File
@@ -927,7 +927,7 @@ func (pwm PWM) Set(channel uint8, value uint32) {
}
// SPI configuration
var SPI0 = SPI{
var SPI0 = &SPI{
spcr: avr.SPCR,
spdr: avr.SPDR,
spsr: avr.SPSR,
+1 -1
View File
@@ -71,7 +71,7 @@ func (p Pin) getPortMask() (*volatile.Register8, uint8) {
}
// SPI configuration
var SPI0 = SPI{
var SPI0 = &SPI{
spcr: avr.SPCR,
spsr: avr.SPSR,
spdr: avr.SPDR,
+1 -1
View File
@@ -131,7 +131,7 @@ func (p Pin) getPortMask() (*volatile.Register8, uint8) {
}
// SPI configuration
var SPI0 = SPI{
var SPI0 = &SPI{
spcr: avr.SPCR,
spdr: avr.SPDR,
spsr: avr.SPSR,
+1 -1
View File
@@ -25,7 +25,7 @@ var I2C0 = &I2C{
}
// SPI configuration
var SPI0 = SPI{
var SPI0 = &SPI{
spcr: avr.SPCR,
spdr: avr.SPDR,
spsr: avr.SPSR,
+2 -2
View File
@@ -60,7 +60,7 @@ var I2C1 = &I2C{
}
// SPI configuration
var SPI0 = SPI{
var SPI0 = &SPI{
spcr: avr.SPCR0,
spdr: avr.SPDR0,
spsr: avr.SPSR0,
@@ -82,7 +82,7 @@ var SPI0 = SPI{
cs: PB2,
}
var SPI1 = SPI{
var SPI1 = &SPI{
spcr: avr.SPCR1,
spdr: avr.SPDR1,
spsr: avr.SPSR1,
+6 -6
View File
@@ -1224,7 +1224,7 @@ type SPIConfig struct {
}
// Configure is intended to setup the SPI interface.
func (spi SPI) Configure(config SPIConfig) error {
func (spi *SPI) Configure(config SPIConfig) error {
// Use default pins if not set.
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
config.SCK = SPI0_SCK_PIN
@@ -1346,7 +1346,7 @@ func (spi SPI) Configure(config SPIConfig) error {
}
// Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) {
func (spi *SPI) Transfer(w byte) (byte, error) {
// write data
spi.Bus.DATA.Set(uint32(w))
@@ -1375,7 +1375,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
//
// spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error {
func (spi *SPI) Tx(w, r []byte) error {
switch {
case w == nil:
// read only, so write zero and read a result.
@@ -1396,7 +1396,7 @@ func (spi SPI) Tx(w, r []byte) error {
return nil
}
func (spi SPI) tx(tx []byte) {
func (spi *SPI) tx(tx []byte) {
for i := 0; i < len(tx); i++ {
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) {
}
@@ -1411,7 +1411,7 @@ func (spi SPI) tx(tx []byte) {
}
}
func (spi SPI) rx(rx []byte) {
func (spi *SPI) rx(rx []byte) {
spi.Bus.DATA.Set(0)
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) {
}
@@ -1427,7 +1427,7 @@ func (spi SPI) rx(rx []byte) {
rx[len(rx)-1] = byte(spi.Bus.DATA.Get())
}
func (spi SPI) txrx(tx, rx []byte) {
func (spi *SPI) txrx(tx, rx []byte) {
spi.Bus.DATA.Set(uint32(tx[0]))
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPI_INTFLAG_DRE) {
}
+4 -4
View File
@@ -22,10 +22,10 @@ var (
sercomI2CM2 = &I2C{Bus: sam.SERCOM2_I2CM, SERCOM: 2}
sercomI2CM3 = &I2C{Bus: sam.SERCOM3_I2CM, SERCOM: 3}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPI, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPI, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPI, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPI, SERCOM: 3}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPI, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPI, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPI, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPI, SERCOM: 3}
)
func init() {
+6 -6
View File
@@ -26,12 +26,12 @@ var (
sercomI2CM4 = &I2C{Bus: sam.SERCOM4_I2CM, SERCOM: 4}
sercomI2CM5 = &I2C{Bus: sam.SERCOM5_I2CM, SERCOM: 5}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPI, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPI, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPI, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPI, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPI, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPI, SERCOM: 5}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPI, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPI, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPI, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPI, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPI, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPI, SERCOM: 5}
)
func init() {
+6 -6
View File
@@ -1431,7 +1431,7 @@ type SPIConfig struct {
}
// Configure is intended to setup the SPI interface.
func (spi SPI) Configure(config SPIConfig) error {
func (spi *SPI) Configure(config SPIConfig) error {
// Use default pins if not set.
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
config.SCK = SPI0_SCK_PIN
@@ -1574,7 +1574,7 @@ func (spi SPI) Configure(config SPIConfig) error {
}
// Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) {
func (spi *SPI) Transfer(w byte) (byte, error) {
// write data
spi.Bus.DATA.Set(uint32(w))
@@ -1603,7 +1603,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
//
// spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error {
func (spi *SPI) Tx(w, r []byte) error {
switch {
case w == nil:
// read only, so write zero and read a result.
@@ -1624,7 +1624,7 @@ func (spi SPI) Tx(w, r []byte) error {
return nil
}
func (spi SPI) tx(tx []byte) {
func (spi *SPI) tx(tx []byte) {
for i := 0; i < len(tx); i++ {
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
}
@@ -1639,7 +1639,7 @@ func (spi SPI) tx(tx []byte) {
}
}
func (spi SPI) rx(rx []byte) {
func (spi *SPI) rx(rx []byte) {
spi.Bus.DATA.Set(0)
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
}
@@ -1655,7 +1655,7 @@ func (spi SPI) rx(rx []byte) {
rx[len(rx)-1] = byte(spi.Bus.DATA.Get())
}
func (spi SPI) txrx(tx, rx []byte) {
func (spi *SPI) txrx(tx, rx []byte) {
spi.Bus.DATA.Set(uint32(tx[0]))
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
}
+6 -6
View File
@@ -18,12 +18,12 @@ var (
sercomI2CM4 = &I2C{Bus: sam.SERCOM4_I2CM, SERCOM: 4}
sercomI2CM5 = &I2C{Bus: sam.SERCOM5_I2CM, SERCOM: 5}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
)
// setSERCOMClockGenerator sets the GCLK for sercom
+6 -6
View File
@@ -18,12 +18,12 @@ var (
sercomI2CM4 = &I2C{Bus: sam.SERCOM4_I2CM, SERCOM: 4}
sercomI2CM5 = &I2C{Bus: sam.SERCOM5_I2CM, SERCOM: 5}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
)
// setSERCOMClockGenerator sets the GCLK for sercom
+6 -6
View File
@@ -18,12 +18,12 @@ var (
sercomI2CM4 = &I2C{Bus: sam.SERCOM4_I2CM, SERCOM: 4}
sercomI2CM5 = &I2C{Bus: sam.SERCOM5_I2CM, SERCOM: 5}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
)
// setSERCOMClockGenerator sets the GCLK for sercom
+8 -8
View File
@@ -20,14 +20,14 @@ var (
sercomI2CM6 = &I2C{Bus: sam.SERCOM6_I2CM, SERCOM: 6}
sercomI2CM7 = &I2C{Bus: sam.SERCOM7_I2CM, SERCOM: 7}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM6 = SPI{Bus: sam.SERCOM6_SPIM, SERCOM: 6}
sercomSPIM7 = SPI{Bus: sam.SERCOM7_SPIM, SERCOM: 7}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM6 = &SPI{Bus: sam.SERCOM6_SPIM, SERCOM: 6}
sercomSPIM7 = &SPI{Bus: sam.SERCOM7_SPIM, SERCOM: 7}
)
// setSERCOMClockGenerator sets the GCLK for sercom
+8 -8
View File
@@ -20,14 +20,14 @@ var (
sercomI2CM6 = &I2C{Bus: sam.SERCOM6_I2CM, SERCOM: 6}
sercomI2CM7 = &I2C{Bus: sam.SERCOM7_I2CM, SERCOM: 7}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM6 = SPI{Bus: sam.SERCOM6_SPIM, SERCOM: 6}
sercomSPIM7 = SPI{Bus: sam.SERCOM7_SPIM, SERCOM: 7}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM6 = &SPI{Bus: sam.SERCOM6_SPIM, SERCOM: 6}
sercomSPIM7 = &SPI{Bus: sam.SERCOM7_SPIM, SERCOM: 7}
)
// setSERCOMClockGenerator sets the GCLK for sercom
+6 -6
View File
@@ -18,12 +18,12 @@ var (
sercomI2CM4 = &I2C{Bus: sam.SERCOM4_I2CM, SERCOM: 4}
sercomI2CM5 = &I2C{Bus: sam.SERCOM5_I2CM, SERCOM: 5}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
)
// setSERCOMClockGenerator sets the GCLK for sercom
+8 -8
View File
@@ -20,14 +20,14 @@ var (
sercomI2CM6 = &I2C{Bus: sam.SERCOM6_I2CM, SERCOM: 6}
sercomI2CM7 = &I2C{Bus: sam.SERCOM7_I2CM, SERCOM: 7}
sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM6 = SPI{Bus: sam.SERCOM6_SPIM, SERCOM: 6}
sercomSPIM7 = SPI{Bus: sam.SERCOM7_SPIM, SERCOM: 7}
sercomSPIM0 = &SPI{Bus: sam.SERCOM0_SPIM, SERCOM: 0}
sercomSPIM1 = &SPI{Bus: sam.SERCOM1_SPIM, SERCOM: 1}
sercomSPIM2 = &SPI{Bus: sam.SERCOM2_SPIM, SERCOM: 2}
sercomSPIM3 = &SPI{Bus: sam.SERCOM3_SPIM, SERCOM: 3}
sercomSPIM4 = &SPI{Bus: sam.SERCOM4_SPIM, SERCOM: 4}
sercomSPIM5 = &SPI{Bus: sam.SERCOM5_SPIM, SERCOM: 5}
sercomSPIM6 = &SPI{Bus: sam.SERCOM6_SPIM, SERCOM: 6}
sercomSPIM7 = &SPI{Bus: sam.SERCOM7_SPIM, SERCOM: 7}
)
// setSERCOMClockGenerator sets the GCLK for sercom
+5 -5
View File
@@ -334,8 +334,8 @@ type SPI struct {
var (
// SPI0 and SPI1 are reserved for use by the caching system etc.
SPI2 = SPI{esp.SPI2}
SPI3 = SPI{esp.SPI3}
SPI2 = &SPI{esp.SPI2}
SPI3 = &SPI{esp.SPI3}
)
// SPIConfig configures a SPI peripheral on the ESP32. Make sure to set at least
@@ -354,7 +354,7 @@ type SPIConfig struct {
}
// Configure and make the SPI peripheral ready to use.
func (spi SPI) Configure(config SPIConfig) error {
func (spi *SPI) Configure(config SPIConfig) error {
if config.Frequency == 0 {
config.Frequency = 4e6 // default to 4MHz
}
@@ -445,7 +445,7 @@ func (spi SPI) Configure(config SPIConfig) error {
// Transfer writes/reads a single byte using the SPI interface. If you need to
// transfer larger amounts of data, Tx will be faster.
func (spi SPI) Transfer(w byte) (byte, error) {
func (spi *SPI) Transfer(w byte) (byte, error) {
spi.Bus.MISO_DLEN.Set(7 << esp.SPI_MISO_DLEN_USR_MISO_DBITLEN_Pos)
spi.Bus.MOSI_DLEN.Set(7 << esp.SPI_MOSI_DLEN_USR_MOSI_DBITLEN_Pos)
@@ -464,7 +464,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// interface, there must always be the same number of bytes written as bytes read.
// This is accomplished by sending zero bits if r is bigger than w or discarding
// the incoming data if w is bigger than r.
func (spi SPI) Tx(w, r []byte) error {
func (spi *SPI) Tx(w, r []byte) error {
toTransfer := len(w)
if len(r) > toTransfer {
toTransfer = len(r)
+4 -4
View File
@@ -52,7 +52,7 @@ type SPI struct {
var (
// SPI0 and SPI1 are reserved for use by the caching system etc.
SPI2 = SPI{esp.SPI2}
SPI2 = &SPI{esp.SPI2}
)
// SPIConfig is used to store config info for SPI.
@@ -114,7 +114,7 @@ func freqToClockDiv(hz uint32) uint32 {
}
// Configure and make the SPI peripheral ready to use.
func (spi SPI) Configure(config SPIConfig) error {
func (spi *SPI) Configure(config SPIConfig) error {
// right now this is only setup to work for the esp32c3 spi2 bus
if spi.Bus != esp.SPI2 {
return ErrInvalidSPIBus
@@ -216,7 +216,7 @@ func (spi SPI) Configure(config SPIConfig) error {
// Transfer writes/reads a single byte using the SPI interface. If you need to
// transfer larger amounts of data, Tx will be faster.
func (spi SPI) Transfer(w byte) (byte, error) {
func (spi *SPI) Transfer(w byte) (byte, error) {
spi.Bus.SetMS_DLEN_MS_DATA_BITLEN(7)
spi.Bus.SetW0(uint32(w))
@@ -238,7 +238,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// interface, there must always be the same number of bytes written as bytes read.
// This is accomplished by sending zero bits if r is bigger than w or discarding
// the incoming data if w is bigger than r.
func (spi SPI) Tx(w, r []byte) error {
func (spi *SPI) Tx(w, r []byte) error {
toTransfer := len(w)
if len(r) > toTransfer {
toTransfer = len(r)
+2 -2
View File
@@ -140,7 +140,7 @@ type SPIConfig struct {
}
// Configure is intended to setup the SPI interface.
func (spi SPI) Configure(config SPIConfig) error {
func (spi *SPI) Configure(config SPIConfig) error {
// Use default pins if not set.
if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 {
config.SCK = SPI0_SCK_PIN
@@ -197,7 +197,7 @@ func (spi SPI) Configure(config SPIConfig) error {
}
// Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) {
func (spi *SPI) Transfer(w byte) (byte, error) {
// wait for tx ready
for spi.Bus.TXDATA.HasBits(sifive.QSPI_TXDATA_FULL) {
}
+11 -11
View File
@@ -60,13 +60,13 @@ type SPIConfig struct {
Mode uint8
}
func (spi SPI) Configure(config SPIConfig) error {
func (spi *SPI) Configure(config SPIConfig) error {
spiConfigure(spi.Bus, config.SCK, config.SDO, config.SDI)
return nil
}
// Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) {
func (spi *SPI) Transfer(w byte) (byte, error) {
return spiTransfer(spi.Bus, w), nil
}
@@ -87,7 +87,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
//
// spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error {
func (spi *SPI) Tx(w, r []byte) error {
var wptr, rptr *byte
var wlen, rlen int
if len(w) != 0 {
@@ -248,14 +248,14 @@ var (
sercomI2CM6 = &I2C{6}
sercomI2CM7 = &I2C{7}
sercomSPIM0 = SPI{0}
sercomSPIM1 = SPI{1}
sercomSPIM2 = SPI{2}
sercomSPIM3 = SPI{3}
sercomSPIM4 = SPI{4}
sercomSPIM5 = SPI{5}
sercomSPIM6 = SPI{6}
sercomSPIM7 = SPI{7}
sercomSPIM0 = &SPI{0}
sercomSPIM1 = &SPI{1}
sercomSPIM2 = &SPI{2}
sercomSPIM3 = &SPI{3}
sercomSPIM4 = &SPI{4}
sercomSPIM5 = &SPI{5}
sercomSPIM6 = &SPI{6}
sercomSPIM7 = &SPI{7}
)
// GetRNG returns 32 bits of random data from the WASI random source.

Some files were not shown because too many files have changed in this diff Show More