mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 14:48:40 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e60eeb368 | |||
| e5a8d69300 | |||
| 4f8672c9ab | |||
| a7416e7300 | |||
| d63d8e0899 | |||
| 8e009de8a8 | |||
| d6527ece02 | |||
| 211425c3e9 | |||
| 429aea8e74 | |||
| 7755780a49 | |||
| 3a7c25f987 | |||
| a4cbe3326e | |||
| 5282b4efac | |||
| 6a25fd494e | |||
| d95c1b5982 | |||
| 24eed9e376 | |||
| c2af1d183e | |||
| 64651115c2 | |||
| b6c3d142db | |||
| fafe80704f | |||
| a2be2f3330 | |||
| 05fc49a0cf | |||
| 417aa4312e | |||
| bf88cdea90 | |||
| c8d0b87a67 | |||
| 99a618385b | |||
| 9e143efd73 | |||
| d5c70a1cd3 | |||
| bbb2b0c95b | |||
| 4768c7d431 | |||
| 4f7c64cb24 | |||
| ff2a79de7c | |||
| 04c7057ea6 | |||
| f76e8d2812 | |||
| bcdc5e0097 | |||
| 2bee29959b |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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).
|
||||
|
||||
@@ -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
@@ -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=
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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()
|
||||
}
|
||||
@@ -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,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].
|
||||
|
||||
@@ -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.
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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()]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ var (
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI3 = SPI{
|
||||
SPI3 = &SPI{
|
||||
Bus: stm32.SPI3,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import "device/sifive"
|
||||
|
||||
// SPI on the HiFive1.
|
||||
var (
|
||||
SPI1 = SPI{
|
||||
SPI1 = &SPI{
|
||||
Bus: sifive.QSPI1,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -84,10 +84,10 @@ var (
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
SPI1 = SPI0
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -85,7 +85,7 @@ var (
|
||||
I2C0 = I2C2
|
||||
|
||||
// SPI
|
||||
SPI3 = SPI{
|
||||
SPI3 = &SPI{
|
||||
Bus: stm32.SPI3,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -86,11 +86,11 @@ var (
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI0 = SPI{
|
||||
SPI0 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: 0,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
SPI1 = SPI0
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -84,7 +84,7 @@ var (
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI3 = SPI{
|
||||
SPI3 = &SPI{
|
||||
Bus: stm32.SPI3,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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,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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -25,7 +25,7 @@ var I2C0 = &I2C{
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
var SPI0 = &SPI{
|
||||
spcr: avr.SPCR,
|
||||
spdr: avr.SPDR,
|
||||
spsr: avr.SPSR,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user