mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-06 12:03:41 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 98d55ab070 | |||
| 88d273da97 | |||
| adc0cae960 | |||
| 38e3d55e64 | |||
| 66da29e89f | |||
| c180d6fe2f | |||
| cdea833b5c | |||
| c2eaa495df | |||
| 3476100dd0 | |||
| 07c7eff3c3 | |||
| a1be8cd9fe | |||
| 52b9fcd57f | |||
| ea53ace270 | |||
| a6cd072fa1 | |||
| 4372dbdd41 | |||
| 17bb1fec44 | |||
| f4fd79f7be | |||
| 811b13a9d3 | |||
| 6e97079367 | |||
| 9c7bbce029 | |||
| 0ec1cb1e19 | |||
| e7118e5bda | |||
| 150d9d1c6b | |||
| 8fe039156b | |||
| 2d17dec7bf | |||
| c1b267a208 | |||
| f02c56c9e0 | |||
| c5879c682c | |||
| 190c20825f | |||
| d04eea7185 | |||
| f24cd31895 | |||
| 2044f6fbcc | |||
| d55a89f96a | |||
| 080a6648e9 | |||
| ec0a142190 | |||
| b7fcf6ad68 |
@@ -109,9 +109,9 @@ jobs:
|
|||||||
# "make lint" fails before go 1.21 because internal/tools/go.mod specifies packages that require go 1.21
|
# "make lint" fails before go 1.21 because internal/tools/go.mod specifies packages that require go 1.21
|
||||||
fmt-check: false
|
fmt-check: false
|
||||||
resource_class: large
|
resource_class: large
|
||||||
test-llvm19-go123:
|
test-llvm19-go124:
|
||||||
docker:
|
docker:
|
||||||
- image: golang:1.23-bullseye
|
- image: golang:1.24-bullseye
|
||||||
steps:
|
steps:
|
||||||
- test-linux:
|
- test-linux:
|
||||||
llvm: "19"
|
llvm: "19"
|
||||||
@@ -124,4 +124,4 @@ workflows:
|
|||||||
# least the smoke tests still pass.
|
# least the smoke tests still pass.
|
||||||
- test-llvm15-go119
|
- test-llvm15-go119
|
||||||
# This tests LLVM 19 support when linking against system libraries.
|
# This tests LLVM 19 support when linking against system libraries.
|
||||||
- test-llvm19-go123
|
- test-llvm19-go124
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Restore LLVM source cache
|
- name: Restore LLVM source cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
@@ -143,7 +143,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
||||||
run: go install -tags=llvm${{ matrix.version }}
|
run: go install -tags=llvm${{ matrix.version }}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
# statically linked binary.
|
# statically linked binary.
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: golang:1.23-alpine
|
image: golang:1.24-alpine
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.version.outputs.version }}
|
version: ${{ steps.version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
@@ -146,12 +146,12 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Install wasmtime
|
- name: Install wasmtime
|
||||||
uses: bytecodealliance/actions/wasmtime/setup@v1
|
uses: bytecodealliance/actions/wasmtime/setup@v1
|
||||||
with:
|
with:
|
||||||
version: "19.0.1"
|
version: "29.0.1"
|
||||||
- name: Install wasm-tools
|
- name: Install wasm-tools
|
||||||
uses: bytecodealliance/actions/wasm-tools/setup@v1
|
uses: bytecodealliance/actions/wasm-tools/setup@v1
|
||||||
- name: Download release artifact
|
- name: Download release artifact
|
||||||
@@ -169,7 +169,7 @@ jobs:
|
|||||||
assert-test-linux:
|
assert-test-linux:
|
||||||
# Run all tests that can run on Linux, with LLVM assertions enabled to catch
|
# Run all tests that can run on Linux, with LLVM assertions enabled to catch
|
||||||
# potential bugs.
|
# potential bugs.
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -189,7 +189,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
@@ -198,7 +198,7 @@ jobs:
|
|||||||
- name: Install wasmtime
|
- name: Install wasmtime
|
||||||
uses: bytecodealliance/actions/wasmtime/setup@v1
|
uses: bytecodealliance/actions/wasmtime/setup@v1
|
||||||
with:
|
with:
|
||||||
version: "19.0.1"
|
version: "29.0.1"
|
||||||
- name: Setup `wasm-tools`
|
- name: Setup `wasm-tools`
|
||||||
uses: bytecodealliance/actions/wasm-tools/setup@v1
|
uses: bytecodealliance/actions/wasm-tools/setup@v1
|
||||||
- name: Restore LLVM source cache
|
- name: Restore LLVM source cache
|
||||||
@@ -297,7 +297,7 @@ jobs:
|
|||||||
- goarch: arm
|
- goarch: arm
|
||||||
toolchain: arm-linux-gnueabihf
|
toolchain: arm-linux-gnueabihf
|
||||||
libc: armhf
|
libc: armhf
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04 # note: use the oldest image available! (see above)
|
||||||
needs: build-linux
|
needs: build-linux
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -315,7 +315,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Restore LLVM source cache
|
- name: Restore LLVM source cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
@@ -346,7 +346,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-19-linux-${{ matrix.goarch }}-v2
|
key: llvm-build-19-linux-${{ matrix.goarch }}-v3
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Restore cached LLVM source
|
- name: Restore cached LLVM source
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
@@ -109,7 +109,7 @@ jobs:
|
|||||||
C:/Users/runneradmin/go/pkg/mod
|
C:/Users/runneradmin/go/pkg/mod
|
||||||
- name: Install wasmtime
|
- name: Install wasmtime
|
||||||
run: |
|
run: |
|
||||||
scoop install wasmtime@14.0.4
|
scoop install wasmtime@29.0.1
|
||||||
- name: make gen-device
|
- name: make gen-device
|
||||||
run: make -j3 gen-device
|
run: make -j3 gen-device
|
||||||
- name: Test TinyGo
|
- name: Test TinyGo
|
||||||
@@ -156,7 +156,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Download TinyGo build
|
- name: Download TinyGo build
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -186,7 +186,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Download TinyGo build
|
- name: Download TinyGo build
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -216,13 +216,13 @@ jobs:
|
|||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
scoop install binaryen && scoop install wasmtime@14.0.4
|
scoop install binaryen && scoop install wasmtime@29.0.1
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.24'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Download TinyGo build
|
- name: Download TinyGo build
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
# tinygo-llvm stage obtains the llvm source for TinyGo
|
# tinygo-llvm stage obtains the llvm source for TinyGo
|
||||||
FROM golang:1.23 AS tinygo-llvm
|
FROM golang:1.24 AS tinygo-llvm
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y apt-utils make cmake clang-15 ninja-build && \
|
apt-get install -y apt-utils make cmake clang-15 ninja-build && \
|
||||||
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
|
|||||||
|
|
||||||
# tinygo-compiler copies the compiler build over to a base Go container (without
|
# tinygo-compiler copies the compiler build over to a base Go container (without
|
||||||
# all the build tools etc).
|
# all the build tools etc).
|
||||||
FROM golang:1.23 AS tinygo-compiler
|
FROM golang:1.24 AS tinygo-compiler
|
||||||
|
|
||||||
# Copy tinygo build.
|
# Copy tinygo build.
|
||||||
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
||||||
|
|||||||
+19
-10
@@ -309,11 +309,9 @@ TEST_PACKAGES_FAST = \
|
|||||||
container/heap \
|
container/heap \
|
||||||
container/list \
|
container/list \
|
||||||
container/ring \
|
container/ring \
|
||||||
crypto/des \
|
|
||||||
crypto/ecdsa \
|
crypto/ecdsa \
|
||||||
crypto/elliptic \
|
crypto/elliptic \
|
||||||
crypto/md5 \
|
crypto/md5 \
|
||||||
crypto/rc4 \
|
|
||||||
crypto/sha1 \
|
crypto/sha1 \
|
||||||
crypto/sha256 \
|
crypto/sha256 \
|
||||||
crypto/sha512 \
|
crypto/sha512 \
|
||||||
@@ -355,21 +353,16 @@ TEST_PACKAGES_FAST = \
|
|||||||
unique \
|
unique \
|
||||||
$(nil)
|
$(nil)
|
||||||
|
|
||||||
# Assume this will go away before Go2, so only check minor version.
|
|
||||||
ifeq ($(filter $(shell $(GO) env GOVERSION | cut -f 2 -d.), 16 17 18), )
|
|
||||||
TEST_PACKAGES_FAST += crypto/internal/nistec/fiat
|
|
||||||
else
|
|
||||||
TEST_PACKAGES_FAST += crypto/elliptic/internal/fiat
|
|
||||||
endif
|
|
||||||
|
|
||||||
# archive/zip requires os.ReadAt, which is not yet supported on windows
|
# archive/zip requires os.ReadAt, which is not yet supported on windows
|
||||||
# bytes requires mmap
|
# bytes requires mmap
|
||||||
# compress/flate appears to hang on wasi
|
# compress/flate appears to hang on wasi
|
||||||
# crypto/aes fails on wasi, needs panic()/recover()
|
# crypto/aes fails on wasi, needs panic()/recover()
|
||||||
|
# crypto/des fails on wasi, needs panic()/recover()
|
||||||
# crypto/hmac fails on wasi, it exits with a "slice out of range" panic
|
# crypto/hmac fails on wasi, it exits with a "slice out of range" panic
|
||||||
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows
|
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows
|
||||||
# image requires recover(), which is not yet supported on wasi
|
# image requires recover(), which is not yet supported on wasi
|
||||||
# io/ioutil requires os.ReadDir, which is not yet supported on windows or wasi
|
# io/ioutil requires os.ReadDir, which is not yet supported on windows or wasi
|
||||||
|
# math/bits: needs panic()/recover()
|
||||||
# mime: fail on wasi; neds panic()/recover()
|
# mime: fail on wasi; neds panic()/recover()
|
||||||
# mime/multipart: needs wasip1 syscall.FDFLAG_NONBLOCK
|
# mime/multipart: needs wasip1 syscall.FDFLAG_NONBLOCK
|
||||||
# mime/quotedprintable requires syscall.Faccessat
|
# mime/quotedprintable requires syscall.Faccessat
|
||||||
@@ -386,11 +379,15 @@ TEST_PACKAGES_LINUX := \
|
|||||||
archive/zip \
|
archive/zip \
|
||||||
compress/flate \
|
compress/flate \
|
||||||
crypto/aes \
|
crypto/aes \
|
||||||
|
crypto/des \
|
||||||
crypto/hmac \
|
crypto/hmac \
|
||||||
debug/dwarf \
|
debug/dwarf \
|
||||||
debug/plan9obj \
|
debug/plan9obj \
|
||||||
|
encoding/binary \
|
||||||
|
go/constant \
|
||||||
image \
|
image \
|
||||||
io/ioutil \
|
io/ioutil \
|
||||||
|
math/bits \
|
||||||
mime \
|
mime \
|
||||||
mime/multipart \
|
mime/multipart \
|
||||||
mime/quotedprintable \
|
mime/quotedprintable \
|
||||||
@@ -405,10 +402,14 @@ TEST_PACKAGES_LINUX := \
|
|||||||
|
|
||||||
TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
|
TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
|
||||||
|
|
||||||
|
# os/user requires t.Skip() support
|
||||||
TEST_PACKAGES_WINDOWS := \
|
TEST_PACKAGES_WINDOWS := \
|
||||||
compress/flate \
|
compress/flate \
|
||||||
|
crypto/des \
|
||||||
crypto/hmac \
|
crypto/hmac \
|
||||||
os/user \
|
encoding/binary \
|
||||||
|
go/constant \
|
||||||
|
math/bits \
|
||||||
strconv \
|
strconv \
|
||||||
text/template/parse \
|
text/template/parse \
|
||||||
$(nil)
|
$(nil)
|
||||||
@@ -523,6 +524,8 @@ smoketest: testchdir
|
|||||||
# regression test for #2563
|
# regression test for #2563
|
||||||
cd tests/os/smoke && $(TINYGO) test -c -target=pybadge && rm smoke.test
|
cd tests/os/smoke && $(TINYGO) test -c -target=pybadge && rm smoke.test
|
||||||
# test all examples (except pwm)
|
# test all examples (except pwm)
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=pga2350 examples/echo
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=pca10040 examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=pca10040 examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=pca10040 examples/adc
|
$(TINYGO) build -size short -o test.hex -target=pca10040 examples/adc
|
||||||
@@ -745,6 +748,8 @@ endif
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=tiny2350 examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=tiny2350 examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=pico-plus2 examples/blinky1
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo
|
$(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
# test pwm
|
# test pwm
|
||||||
@@ -867,6 +872,10 @@ endif
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=elecrow-rp2350 examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=elecrow-rp2350 examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=hw-651 examples/machinetest
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=hw-651-s110v8 examples/machinetest
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
ifneq ($(WASM), 0)
|
ifneq ($(WASM), 0)
|
||||||
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/export
|
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/export
|
||||||
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/main
|
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/main
|
||||||
|
|||||||
@@ -604,6 +604,11 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the output directory, if needed
|
||||||
|
if err := os.MkdirAll(filepath.Dir(outpath), 0777); err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether we only need to create an object file.
|
// Check whether we only need to create an object file.
|
||||||
// If so, we don't need to link anything and will be finished quickly.
|
// If so, we don't need to link anything and will be finished quickly.
|
||||||
outext := filepath.Ext(outpath)
|
outext := filepath.Ext(outpath)
|
||||||
@@ -667,6 +672,16 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
|||||||
ldflags = append(ldflags, "--no-entry")
|
ldflags = append(ldflags, "--no-entry")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Options.BuildMode == "wasi-legacy" {
|
||||||
|
if !strings.HasPrefix(config.Triple(), "wasm32-") {
|
||||||
|
return result, fmt.Errorf("buildmode wasi-legacy is only supported on wasm")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Options.Scheduler != "none" {
|
||||||
|
return result, fmt.Errorf("buildmode wasi-legacy only supports scheduler=none")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add compiler-rt dependency if needed. Usually this is a simple load from
|
// Add compiler-rt dependency if needed. Usually this is a simple load from
|
||||||
// a cache.
|
// a cache.
|
||||||
if config.Target.RTLib == "compiler-rt" {
|
if config.Target.RTLib == "compiler-rt" {
|
||||||
|
|||||||
+2
-2
@@ -26,7 +26,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
|||||||
|
|
||||||
// Version range supported by TinyGo.
|
// Version range supported by TinyGo.
|
||||||
const minorMin = 19
|
const minorMin = 19
|
||||||
const minorMax = 23
|
const minorMax = 24
|
||||||
|
|
||||||
// Check that we support this Go toolchain version.
|
// Check that we support this Go toolchain version.
|
||||||
gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
|
gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
|
||||||
@@ -36,7 +36,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
|||||||
if gorootMajor != 1 || gorootMinor < minorMin || gorootMinor > minorMax {
|
if gorootMajor != 1 || gorootMinor < minorMin || gorootMinor > minorMax {
|
||||||
// Note: when this gets updated, also update the Go compatibility matrix:
|
// Note: when this gets updated, also update the Go compatibility matrix:
|
||||||
// https://github.com/tinygo-org/tinygo-site/blob/dev/content/docs/reference/go-compat-matrix.md
|
// https://github.com/tinygo-org/tinygo-site/blob/dev/content/docs/reference/go-compat-matrix.md
|
||||||
return nil, fmt.Errorf("requires go version 1.19 through 1.23, got go%d.%d", gorootMajor, gorootMinor)
|
return nil, fmt.Errorf("requires go version 1.%d through 1.%d, got go%d.%d", minorMin, minorMax, gorootMajor, gorootMinor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the Go toolchain version isn't too new, if we haven't been
|
// Check that the Go toolchain version isn't too new, if we haven't been
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ func TestBinarySize(t *testing.T) {
|
|||||||
tests := []sizeTest{
|
tests := []sizeTest{
|
||||||
// microcontrollers
|
// microcontrollers
|
||||||
{"hifive1b", "examples/echo", 4560, 280, 0, 2268},
|
{"hifive1b", "examples/echo", 4560, 280, 0, 2268},
|
||||||
{"microbit", "examples/serial", 2908, 388, 8, 2272},
|
{"microbit", "examples/serial", 2916, 388, 8, 2272},
|
||||||
{"wioterminal", "examples/pininterrupt", 7293, 1487, 116, 6912},
|
{"wioterminal", "examples/pininterrupt", 7359, 1489, 116, 6912},
|
||||||
|
|
||||||
// TODO: also check wasm. Right now this is difficult, because
|
// TODO: also check wasm. Right now this is difficult, because
|
||||||
// wasm binaries are run through wasm-opt and therefore the
|
// wasm binaries are run through wasm-opt and therefore the
|
||||||
|
|||||||
+45
-64
@@ -92,18 +92,18 @@ type noescapingFunc struct {
|
|||||||
// cgoAliases list type aliases between Go and C, for types that are equivalent
|
// cgoAliases list type aliases between Go and C, for types that are equivalent
|
||||||
// in both languages. See addTypeAliases.
|
// in both languages. See addTypeAliases.
|
||||||
var cgoAliases = map[string]string{
|
var cgoAliases = map[string]string{
|
||||||
"C.int8_t": "int8",
|
"_Cgo_int8_t": "int8",
|
||||||
"C.int16_t": "int16",
|
"_Cgo_int16_t": "int16",
|
||||||
"C.int32_t": "int32",
|
"_Cgo_int32_t": "int32",
|
||||||
"C.int64_t": "int64",
|
"_Cgo_int64_t": "int64",
|
||||||
"C.uint8_t": "uint8",
|
"_Cgo_uint8_t": "uint8",
|
||||||
"C.uint16_t": "uint16",
|
"_Cgo_uint16_t": "uint16",
|
||||||
"C.uint32_t": "uint32",
|
"_Cgo_uint32_t": "uint32",
|
||||||
"C.uint64_t": "uint64",
|
"_Cgo_uint64_t": "uint64",
|
||||||
"C.uintptr_t": "uintptr",
|
"_Cgo_uintptr_t": "uintptr",
|
||||||
"C.float": "float32",
|
"_Cgo_float": "float32",
|
||||||
"C.double": "float64",
|
"_Cgo_double": "float64",
|
||||||
"C._Bool": "bool",
|
"_Cgo__Bool": "bool",
|
||||||
}
|
}
|
||||||
|
|
||||||
// builtinAliases are handled specially because they only exist on the Go side
|
// builtinAliases are handled specially because they only exist on the Go side
|
||||||
@@ -145,48 +145,46 @@ typedef unsigned long long _Cgo_ulonglong;
|
|||||||
// The string/bytes functions below implement C.CString etc. To make sure the
|
// The string/bytes functions below implement C.CString etc. To make sure the
|
||||||
// runtime doesn't need to know the C int type, lengths are converted to uintptr
|
// runtime doesn't need to know the C int type, lengths are converted to uintptr
|
||||||
// first.
|
// first.
|
||||||
// These functions will be modified to get a "C." prefix, so the source below
|
|
||||||
// doesn't reflect the final AST.
|
|
||||||
const generatedGoFilePrefixBase = `
|
const generatedGoFilePrefixBase = `
|
||||||
import "syscall"
|
import "syscall"
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
//go:linkname C.CString runtime.cgo_CString
|
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||||
func CString(string) *C.char
|
func _Cgo_CString(string) *_Cgo_char
|
||||||
|
|
||||||
//go:linkname C.GoString runtime.cgo_GoString
|
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||||
func GoString(*C.char) string
|
func _Cgo_GoString(*_Cgo_char) string
|
||||||
|
|
||||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||||
func __GoStringN(*C.char, uintptr) string
|
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||||
|
|
||||||
func GoStringN(cstr *C.char, length C.int) string {
|
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||||
return C.__GoStringN(cstr, uintptr(length))
|
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||||
func __GoBytes(unsafe.Pointer, uintptr) []byte
|
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||||
|
|
||||||
func GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||||
return C.__GoBytes(ptr, uintptr(length))
|
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||||
func __CBytes([]byte) unsafe.Pointer
|
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||||
|
|
||||||
func CBytes(b []byte) unsafe.Pointer {
|
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||||
return C.__CBytes(b)
|
return _Cgo___CBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||||
func __get_errno_num() uintptr
|
func _Cgo___get_errno_num() uintptr
|
||||||
`
|
`
|
||||||
|
|
||||||
const generatedGoFilePrefixOther = generatedGoFilePrefixBase + `
|
const generatedGoFilePrefixOther = generatedGoFilePrefixBase + `
|
||||||
func __get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
return syscall.Errno(C.__get_errno_num())
|
return syscall.Errno(_Cgo___get_errno_num())
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -197,7 +195,7 @@ func __get_errno() error {
|
|||||||
// map the errno values to match the values in the syscall package.
|
// map the errno values to match the values in the syscall package.
|
||||||
// Source of the errno values: lib/mingw-w64/mingw-w64-headers/crt/errno.h
|
// Source of the errno values: lib/mingw-w64/mingw-w64-headers/crt/errno.h
|
||||||
const generatedGoFilePrefixWindows = generatedGoFilePrefixBase + `
|
const generatedGoFilePrefixWindows = generatedGoFilePrefixBase + `
|
||||||
var __errno_mapping = [...]syscall.Errno{
|
var _Cgo___errno_mapping = [...]syscall.Errno{
|
||||||
1: syscall.EPERM,
|
1: syscall.EPERM,
|
||||||
2: syscall.ENOENT,
|
2: syscall.ENOENT,
|
||||||
3: syscall.ESRCH,
|
3: syscall.ESRCH,
|
||||||
@@ -238,10 +236,10 @@ var __errno_mapping = [...]syscall.Errno{
|
|||||||
42: syscall.EILSEQ,
|
42: syscall.EILSEQ,
|
||||||
}
|
}
|
||||||
|
|
||||||
func __get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
num := C.__get_errno_num()
|
num := _Cgo___get_errno_num()
|
||||||
if num < uintptr(len(__errno_mapping)) {
|
if num < uintptr(len(_Cgo___errno_mapping)) {
|
||||||
if mapped := __errno_mapping[num]; mapped != 0 {
|
if mapped := _Cgo___errno_mapping[num]; mapped != 0 {
|
||||||
return mapped
|
return mapped
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,23 +302,6 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
|
|||||||
// If the Comments field is not set to nil, the go/format package will get
|
// If the Comments field is not set to nil, the go/format package will get
|
||||||
// confused about where comments should go.
|
// confused about where comments should go.
|
||||||
p.generated.Comments = nil
|
p.generated.Comments = nil
|
||||||
// Adjust some of the functions in there.
|
|
||||||
for _, decl := range p.generated.Decls {
|
|
||||||
switch decl := decl.(type) {
|
|
||||||
case *ast.FuncDecl:
|
|
||||||
switch decl.Name.Name {
|
|
||||||
case "CString", "GoString", "GoStringN", "__GoStringN", "GoBytes", "__GoBytes", "CBytes", "__CBytes", "__get_errno_num", "__get_errno", "__errno_mapping":
|
|
||||||
// Adjust the name to have a "C." prefix so it is correctly
|
|
||||||
// resolved.
|
|
||||||
decl.Name.Name = "C." + decl.Name.Name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Patch some types, for example *C.char in C.CString.
|
|
||||||
cf := p.newCGoFile(nil, -1) // dummy *cgoFile for the walker
|
|
||||||
astutil.Apply(p.generated, func(cursor *astutil.Cursor) bool {
|
|
||||||
return cf.walker(cursor, nil)
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
// Find `import "C"` C fragments in the file.
|
// Find `import "C"` C fragments in the file.
|
||||||
p.cgoHeaders = make([]string, len(files)) // combined CGo header fragment for each file
|
p.cgoHeaders = make([]string, len(files)) // combined CGo header fragment for each file
|
||||||
@@ -399,7 +380,7 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
|
|||||||
Tok: token.TYPE,
|
Tok: token.TYPE,
|
||||||
}
|
}
|
||||||
for _, name := range builtinAliases {
|
for _, name := range builtinAliases {
|
||||||
typeSpec := p.getIntegerType("C."+name, names["_Cgo_"+name])
|
typeSpec := p.getIntegerType("_Cgo_"+name, names["_Cgo_"+name])
|
||||||
gen.Specs = append(gen.Specs, typeSpec)
|
gen.Specs = append(gen.Specs, typeSpec)
|
||||||
}
|
}
|
||||||
p.generated.Decls = append(p.generated.Decls, gen)
|
p.generated.Decls = append(p.generated.Decls, gen)
|
||||||
@@ -1272,7 +1253,7 @@ func (p *cgoPackage) getUnnamedDeclName(prefix string, itf interface{}) string {
|
|||||||
func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) string {
|
func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) string {
|
||||||
// Some types are defined in stdint.h and map directly to a particular Go
|
// Some types are defined in stdint.h and map directly to a particular Go
|
||||||
// type.
|
// type.
|
||||||
if alias := cgoAliases["C."+name]; alias != "" {
|
if alias := cgoAliases["_Cgo_"+name]; alias != "" {
|
||||||
return alias
|
return alias
|
||||||
}
|
}
|
||||||
node := f.getASTDeclNode(name, found)
|
node := f.getASTDeclNode(name, found)
|
||||||
@@ -1282,7 +1263,7 @@ func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) st
|
|||||||
}
|
}
|
||||||
return node.Name.Name
|
return node.Name.Name
|
||||||
}
|
}
|
||||||
return "C." + name
|
return "_Cgo_" + name
|
||||||
}
|
}
|
||||||
|
|
||||||
// getASTDeclNode will declare the given C AST node (if not already defined) and
|
// getASTDeclNode will declare the given C AST node (if not already defined) and
|
||||||
@@ -1382,8 +1363,8 @@ extern __typeof(%s) %s __attribute__((alias(%#v)));
|
|||||||
case *elaboratedTypeInfo:
|
case *elaboratedTypeInfo:
|
||||||
// Add struct bitfields.
|
// Add struct bitfields.
|
||||||
for _, bitfield := range elaboratedType.bitfields {
|
for _, bitfield := range elaboratedType.bitfields {
|
||||||
f.createBitfieldGetter(bitfield, "C."+name)
|
f.createBitfieldGetter(bitfield, "_Cgo_"+name)
|
||||||
f.createBitfieldSetter(bitfield, "C."+name)
|
f.createBitfieldSetter(bitfield, "_Cgo_"+name)
|
||||||
}
|
}
|
||||||
if elaboratedType.unionSize != 0 {
|
if elaboratedType.unionSize != 0 {
|
||||||
// Create union getters/setters.
|
// Create union getters/setters.
|
||||||
@@ -1392,7 +1373,7 @@ extern __typeof(%s) %s __attribute__((alias(%#v)));
|
|||||||
f.addError(elaboratedType.pos, fmt.Sprintf("union must have field with a single name, it has %d names", len(field.Names)))
|
f.addError(elaboratedType.pos, fmt.Sprintf("union must have field with a single name, it has %d names", len(field.Names)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
f.createUnionAccessor(field, "C."+name)
|
f.createUnionAccessor(field, "_Cgo_"+name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1441,7 +1422,7 @@ func (f *cgoFile) walker(cursor *astutil.Cursor, names map[string]clangCursor) b
|
|||||||
node.Rhs = append(node.Rhs, &ast.CallExpr{
|
node.Rhs = append(node.Rhs, &ast.CallExpr{
|
||||||
Fun: &ast.Ident{
|
Fun: &ast.Ident{
|
||||||
NamePos: node.Lhs[1].End(),
|
NamePos: node.Lhs[1].End(),
|
||||||
Name: "C.__get_errno",
|
Name: "_Cgo___get_errno",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1466,7 +1447,7 @@ func (f *cgoFile) walker(cursor *astutil.Cursor, names map[string]clangCursor) b
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if x.Name == "C" {
|
if x.Name == "C" {
|
||||||
name := "C." + node.Sel.Name
|
name := "_Cgo_" + node.Sel.Name
|
||||||
if found, ok := names[node.Sel.Name]; ok {
|
if found, ok := names[node.Sel.Name]; ok {
|
||||||
name = f.getASTDeclName(node.Sel.Name, found, false)
|
name = f.getASTDeclName(node.Sel.Name, found, false)
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-27
@@ -219,7 +219,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
numArgs := int(C.tinygo_clang_Cursor_getNumArguments(c))
|
numArgs := int(C.tinygo_clang_Cursor_getNumArguments(c))
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Fun,
|
Kind: ast.Fun,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
}
|
}
|
||||||
exportName := name
|
exportName := name
|
||||||
localName := name
|
localName := name
|
||||||
@@ -257,7 +257,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
},
|
},
|
||||||
Name: &ast.Ident{
|
Name: &ast.Ident{
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Name: "C." + localName,
|
Name: "_Cgo_" + localName,
|
||||||
Obj: obj,
|
Obj: obj,
|
||||||
},
|
},
|
||||||
Type: &ast.FuncType{
|
Type: &ast.FuncType{
|
||||||
@@ -319,7 +319,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
return decl, stringSignature
|
return decl, stringSignature
|
||||||
case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
|
case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
|
||||||
typ := f.makeASTRecordType(c, pos)
|
typ := f.makeASTRecordType(c, pos)
|
||||||
typeName := "C." + name
|
typeName := "_Cgo_" + name
|
||||||
typeExpr := typ.typeExpr
|
typeExpr := typ.typeExpr
|
||||||
if typ.unionSize != 0 {
|
if typ.unionSize != 0 {
|
||||||
// Convert to a single-field struct type.
|
// Convert to a single-field struct type.
|
||||||
@@ -340,7 +340,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
obj.Decl = typeSpec
|
obj.Decl = typeSpec
|
||||||
return typeSpec, typ
|
return typeSpec, typ
|
||||||
case C.CXCursor_TypedefDecl:
|
case C.CXCursor_TypedefDecl:
|
||||||
typeName := "C." + name
|
typeName := "_Cgo_" + name
|
||||||
underlyingType := C.tinygo_clang_getTypedefDeclUnderlyingType(c)
|
underlyingType := C.tinygo_clang_getTypedefDeclUnderlyingType(c)
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Typ,
|
Kind: ast.Typ,
|
||||||
@@ -378,12 +378,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
}
|
}
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Var,
|
Kind: ast.Var,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
}
|
}
|
||||||
valueSpec := &ast.ValueSpec{
|
valueSpec := &ast.ValueSpec{
|
||||||
Names: []*ast.Ident{{
|
Names: []*ast.Ident{{
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
Obj: obj,
|
Obj: obj,
|
||||||
}},
|
}},
|
||||||
Type: typeExpr,
|
Type: typeExpr,
|
||||||
@@ -407,12 +407,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
}
|
}
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Con,
|
Kind: ast.Con,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
}
|
}
|
||||||
valueSpec := &ast.ValueSpec{
|
valueSpec := &ast.ValueSpec{
|
||||||
Names: []*ast.Ident{{
|
Names: []*ast.Ident{{
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
Obj: obj,
|
Obj: obj,
|
||||||
}},
|
}},
|
||||||
Values: []ast.Expr{expr},
|
Values: []ast.Expr{expr},
|
||||||
@@ -423,7 +423,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
case C.CXCursor_EnumDecl:
|
case C.CXCursor_EnumDecl:
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Typ,
|
Kind: ast.Typ,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
}
|
}
|
||||||
underlying := C.tinygo_clang_getEnumDeclIntegerType(c)
|
underlying := C.tinygo_clang_getEnumDeclIntegerType(c)
|
||||||
// TODO: gc's CGo implementation uses types such as `uint32` for enums
|
// TODO: gc's CGo implementation uses types such as `uint32` for enums
|
||||||
@@ -431,7 +431,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
typeSpec := &ast.TypeSpec{
|
typeSpec := &ast.TypeSpec{
|
||||||
Name: &ast.Ident{
|
Name: &ast.Ident{
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
Obj: obj,
|
Obj: obj,
|
||||||
},
|
},
|
||||||
Assign: pos,
|
Assign: pos,
|
||||||
@@ -454,12 +454,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
|||||||
}
|
}
|
||||||
obj := &ast.Object{
|
obj := &ast.Object{
|
||||||
Kind: ast.Con,
|
Kind: ast.Con,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
}
|
}
|
||||||
valueSpec := &ast.ValueSpec{
|
valueSpec := &ast.ValueSpec{
|
||||||
Names: []*ast.Ident{{
|
Names: []*ast.Ident{{
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Name: "C." + name,
|
Name: "_Cgo_" + name,
|
||||||
Obj: obj,
|
Obj: obj,
|
||||||
}},
|
}},
|
||||||
Values: []ast.Expr{expr},
|
Values: []ast.Expr{expr},
|
||||||
@@ -745,27 +745,27 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr {
|
|||||||
var typeName string
|
var typeName string
|
||||||
switch typ.kind {
|
switch typ.kind {
|
||||||
case C.CXType_Char_S, C.CXType_Char_U:
|
case C.CXType_Char_S, C.CXType_Char_U:
|
||||||
typeName = "C.char"
|
typeName = "_Cgo_char"
|
||||||
case C.CXType_SChar:
|
case C.CXType_SChar:
|
||||||
typeName = "C.schar"
|
typeName = "_Cgo_schar"
|
||||||
case C.CXType_UChar:
|
case C.CXType_UChar:
|
||||||
typeName = "C.uchar"
|
typeName = "_Cgo_uchar"
|
||||||
case C.CXType_Short:
|
case C.CXType_Short:
|
||||||
typeName = "C.short"
|
typeName = "_Cgo_short"
|
||||||
case C.CXType_UShort:
|
case C.CXType_UShort:
|
||||||
typeName = "C.ushort"
|
typeName = "_Cgo_ushort"
|
||||||
case C.CXType_Int:
|
case C.CXType_Int:
|
||||||
typeName = "C.int"
|
typeName = "_Cgo_int"
|
||||||
case C.CXType_UInt:
|
case C.CXType_UInt:
|
||||||
typeName = "C.uint"
|
typeName = "_Cgo_uint"
|
||||||
case C.CXType_Long:
|
case C.CXType_Long:
|
||||||
typeName = "C.long"
|
typeName = "_Cgo_long"
|
||||||
case C.CXType_ULong:
|
case C.CXType_ULong:
|
||||||
typeName = "C.ulong"
|
typeName = "_Cgo_ulong"
|
||||||
case C.CXType_LongLong:
|
case C.CXType_LongLong:
|
||||||
typeName = "C.longlong"
|
typeName = "_Cgo_longlong"
|
||||||
case C.CXType_ULongLong:
|
case C.CXType_ULongLong:
|
||||||
typeName = "C.ulonglong"
|
typeName = "_Cgo_ulonglong"
|
||||||
case C.CXType_Bool:
|
case C.CXType_Bool:
|
||||||
typeName = "bool"
|
typeName = "bool"
|
||||||
case C.CXType_Float, C.CXType_Double, C.CXType_LongDouble:
|
case C.CXType_Float, C.CXType_Double, C.CXType_LongDouble:
|
||||||
@@ -896,7 +896,7 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr {
|
|||||||
typeSpelling := getString(C.clang_getTypeSpelling(typ))
|
typeSpelling := getString(C.clang_getTypeSpelling(typ))
|
||||||
typeKindSpelling := getString(C.clang_getTypeKindSpelling(typ.kind))
|
typeKindSpelling := getString(C.clang_getTypeKindSpelling(typ.kind))
|
||||||
f.addError(pos, fmt.Sprintf("unknown C type: %v (libclang type kind %s)", typeSpelling, typeKindSpelling))
|
f.addError(pos, fmt.Sprintf("unknown C type: %v (libclang type kind %s)", typeSpelling, typeKindSpelling))
|
||||||
typeName = "C.<unknown>"
|
typeName = "_Cgo_<unknown>"
|
||||||
}
|
}
|
||||||
return &ast.Ident{
|
return &ast.Ident{
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
@@ -913,7 +913,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
|
|||||||
var goName string
|
var goName string
|
||||||
typeSize := C.clang_Type_getSizeOf(underlyingType)
|
typeSize := C.clang_Type_getSizeOf(underlyingType)
|
||||||
switch name {
|
switch name {
|
||||||
case "C.char":
|
case "_Cgo_char":
|
||||||
if typeSize != 1 {
|
if typeSize != 1 {
|
||||||
// This happens for some very special purpose architectures
|
// This happens for some very special purpose architectures
|
||||||
// (DSPs etc.) that are not currently targeted.
|
// (DSPs etc.) that are not currently targeted.
|
||||||
@@ -926,7 +926,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
|
|||||||
case C.CXType_Char_U:
|
case C.CXType_Char_U:
|
||||||
goName = "uint8"
|
goName = "uint8"
|
||||||
}
|
}
|
||||||
case "C.schar", "C.short", "C.int", "C.long", "C.longlong":
|
case "_Cgo_schar", "_Cgo_short", "_Cgo_int", "_Cgo_long", "_Cgo_longlong":
|
||||||
switch typeSize {
|
switch typeSize {
|
||||||
case 1:
|
case 1:
|
||||||
goName = "int8"
|
goName = "int8"
|
||||||
@@ -937,7 +937,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
|
|||||||
case 8:
|
case 8:
|
||||||
goName = "int64"
|
goName = "int64"
|
||||||
}
|
}
|
||||||
case "C.uchar", "C.ushort", "C.uint", "C.ulong", "C.ulonglong":
|
case "_Cgo_uchar", "_Cgo_ushort", "_Cgo_uint", "_Cgo_ulong", "_Cgo_ulonglong":
|
||||||
switch typeSize {
|
switch typeSize {
|
||||||
case 1:
|
case 1:
|
||||||
goName = "uint8"
|
goName = "uint8"
|
||||||
|
|||||||
Vendored
+31
-31
@@ -5,50 +5,50 @@ import "unsafe"
|
|||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
//go:linkname C.CString runtime.cgo_CString
|
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||||
func C.CString(string) *C.char
|
func _Cgo_CString(string) *_Cgo_char
|
||||||
|
|
||||||
//go:linkname C.GoString runtime.cgo_GoString
|
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||||
func C.GoString(*C.char) string
|
func _Cgo_GoString(*_Cgo_char) string
|
||||||
|
|
||||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||||
func C.__GoStringN(*C.char, uintptr) string
|
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||||
|
|
||||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||||
return C.__GoStringN(cstr, uintptr(length))
|
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||||
|
|
||||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||||
return C.__GoBytes(ptr, uintptr(length))
|
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||||
func C.__CBytes([]byte) unsafe.Pointer
|
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||||
|
|
||||||
func C.CBytes(b []byte) unsafe.Pointer {
|
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||||
return C.__CBytes(b)
|
return _Cgo___CBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||||
func C.__get_errno_num() uintptr
|
func _Cgo___get_errno_num() uintptr
|
||||||
|
|
||||||
func C.__get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
return syscall.Errno(C.__get_errno_num())
|
return syscall.Errno(_Cgo___get_errno_num())
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
C.char uint8
|
_Cgo_char uint8
|
||||||
C.schar int8
|
_Cgo_schar int8
|
||||||
C.uchar uint8
|
_Cgo_uchar uint8
|
||||||
C.short int16
|
_Cgo_short int16
|
||||||
C.ushort uint16
|
_Cgo_ushort uint16
|
||||||
C.int int32
|
_Cgo_int int32
|
||||||
C.uint uint32
|
_Cgo_uint uint32
|
||||||
C.long int32
|
_Cgo_long int32
|
||||||
C.ulong uint32
|
_Cgo_ulong uint32
|
||||||
C.longlong int64
|
_Cgo_longlong int64
|
||||||
C.ulonglong uint64
|
_Cgo_ulonglong uint64
|
||||||
)
|
)
|
||||||
|
|||||||
Vendored
+38
-38
@@ -5,58 +5,58 @@ import "unsafe"
|
|||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
//go:linkname C.CString runtime.cgo_CString
|
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||||
func C.CString(string) *C.char
|
func _Cgo_CString(string) *_Cgo_char
|
||||||
|
|
||||||
//go:linkname C.GoString runtime.cgo_GoString
|
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||||
func C.GoString(*C.char) string
|
func _Cgo_GoString(*_Cgo_char) string
|
||||||
|
|
||||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||||
func C.__GoStringN(*C.char, uintptr) string
|
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||||
|
|
||||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||||
return C.__GoStringN(cstr, uintptr(length))
|
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||||
|
|
||||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||||
return C.__GoBytes(ptr, uintptr(length))
|
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||||
func C.__CBytes([]byte) unsafe.Pointer
|
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||||
|
|
||||||
func C.CBytes(b []byte) unsafe.Pointer {
|
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||||
return C.__CBytes(b)
|
return _Cgo___CBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||||
func C.__get_errno_num() uintptr
|
func _Cgo___get_errno_num() uintptr
|
||||||
|
|
||||||
func C.__get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
return syscall.Errno(C.__get_errno_num())
|
return syscall.Errno(_Cgo___get_errno_num())
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
C.char uint8
|
_Cgo_char uint8
|
||||||
C.schar int8
|
_Cgo_schar int8
|
||||||
C.uchar uint8
|
_Cgo_uchar uint8
|
||||||
C.short int16
|
_Cgo_short int16
|
||||||
C.ushort uint16
|
_Cgo_ushort uint16
|
||||||
C.int int32
|
_Cgo_int int32
|
||||||
C.uint uint32
|
_Cgo_uint uint32
|
||||||
C.long int32
|
_Cgo_long int32
|
||||||
C.ulong uint32
|
_Cgo_ulong uint32
|
||||||
C.longlong int64
|
_Cgo_longlong int64
|
||||||
C.ulonglong uint64
|
_Cgo_ulonglong uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
const C.foo = 3
|
const _Cgo_foo = 3
|
||||||
const C.bar = C.foo
|
const _Cgo_bar = _Cgo_foo
|
||||||
const C.unreferenced = 4
|
const _Cgo_unreferenced = 4
|
||||||
const C.referenced = C.unreferenced
|
const _Cgo_referenced = _Cgo_unreferenced
|
||||||
const C.fnlike_val = 5
|
const _Cgo_fnlike_val = 5
|
||||||
const C.square_val = (20 * 20)
|
const _Cgo_square_val = (20 * 20)
|
||||||
const C.add_val = (3 + 5)
|
const _Cgo_add_val = (3 + 5)
|
||||||
|
|||||||
Vendored
+46
-46
@@ -14,16 +14,16 @@
|
|||||||
// testdata/errors.go:3:1: function "unusedFunction" in #cgo noescape line is not used
|
// testdata/errors.go:3:1: function "unusedFunction" in #cgo noescape line is not used
|
||||||
|
|
||||||
// Type checking errors after CGo processing:
|
// Type checking errors after CGo processing:
|
||||||
// testdata/errors.go:102: cannot use 2 << 10 (untyped int constant 2048) as C.char value in variable declaration (overflows)
|
// testdata/errors.go:102: cannot use 2 << 10 (untyped int constant 2048) as _Cgo_char value in variable declaration (overflows)
|
||||||
// testdata/errors.go:105: unknown field z in struct literal
|
// testdata/errors.go:105: unknown field z in struct literal
|
||||||
// testdata/errors.go:108: undefined: C.SOME_CONST_1
|
// testdata/errors.go:108: undefined: _Cgo_SOME_CONST_1
|
||||||
// testdata/errors.go:110: cannot use C.SOME_CONST_3 (untyped int constant 1234) as byte value in variable declaration (overflows)
|
// testdata/errors.go:110: cannot use _Cgo_SOME_CONST_3 (untyped int constant 1234) as byte value in variable declaration (overflows)
|
||||||
// testdata/errors.go:112: undefined: C.SOME_CONST_4
|
// testdata/errors.go:112: undefined: _Cgo_SOME_CONST_4
|
||||||
// testdata/errors.go:114: undefined: C.SOME_CONST_b
|
// testdata/errors.go:114: undefined: _Cgo_SOME_CONST_b
|
||||||
// testdata/errors.go:116: undefined: C.SOME_CONST_startspace
|
// testdata/errors.go:116: undefined: _Cgo_SOME_CONST_startspace
|
||||||
// testdata/errors.go:119: undefined: C.SOME_PARAM_CONST_invalid
|
// testdata/errors.go:119: undefined: _Cgo_SOME_PARAM_CONST_invalid
|
||||||
// testdata/errors.go:122: undefined: C.add_toomuch
|
// testdata/errors.go:122: undefined: _Cgo_add_toomuch
|
||||||
// testdata/errors.go:123: undefined: C.add_toolittle
|
// testdata/errors.go:123: undefined: _Cgo_add_toolittle
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -32,58 +32,58 @@ import "unsafe"
|
|||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
//go:linkname C.CString runtime.cgo_CString
|
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||||
func C.CString(string) *C.char
|
func _Cgo_CString(string) *_Cgo_char
|
||||||
|
|
||||||
//go:linkname C.GoString runtime.cgo_GoString
|
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||||
func C.GoString(*C.char) string
|
func _Cgo_GoString(*_Cgo_char) string
|
||||||
|
|
||||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||||
func C.__GoStringN(*C.char, uintptr) string
|
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||||
|
|
||||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||||
return C.__GoStringN(cstr, uintptr(length))
|
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||||
|
|
||||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||||
return C.__GoBytes(ptr, uintptr(length))
|
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||||
func C.__CBytes([]byte) unsafe.Pointer
|
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||||
|
|
||||||
func C.CBytes(b []byte) unsafe.Pointer {
|
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||||
return C.__CBytes(b)
|
return _Cgo___CBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||||
func C.__get_errno_num() uintptr
|
func _Cgo___get_errno_num() uintptr
|
||||||
|
|
||||||
func C.__get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
return syscall.Errno(C.__get_errno_num())
|
return syscall.Errno(_Cgo___get_errno_num())
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
C.char uint8
|
_Cgo_char uint8
|
||||||
C.schar int8
|
_Cgo_schar int8
|
||||||
C.uchar uint8
|
_Cgo_uchar uint8
|
||||||
C.short int16
|
_Cgo_short int16
|
||||||
C.ushort uint16
|
_Cgo_ushort uint16
|
||||||
C.int int32
|
_Cgo_int int32
|
||||||
C.uint uint32
|
_Cgo_uint uint32
|
||||||
C.long int32
|
_Cgo_long int32
|
||||||
C.ulong uint32
|
_Cgo_ulong uint32
|
||||||
C.longlong int64
|
_Cgo_longlong int64
|
||||||
C.ulonglong uint64
|
_Cgo_ulonglong uint64
|
||||||
)
|
)
|
||||||
type C.struct_point_t struct {
|
type _Cgo_struct_point_t struct {
|
||||||
x C.int
|
x _Cgo_int
|
||||||
y C.int
|
y _Cgo_int
|
||||||
}
|
}
|
||||||
type C.point_t = C.struct_point_t
|
type _Cgo_point_t = _Cgo_struct_point_t
|
||||||
|
|
||||||
const C.SOME_CONST_3 = 1234
|
const _Cgo_SOME_CONST_3 = 1234
|
||||||
const C.SOME_PARAM_CONST_valid = 3 + 4
|
const _Cgo_SOME_PARAM_CONST_valid = 3 + 4
|
||||||
|
|||||||
Vendored
+33
-33
@@ -10,53 +10,53 @@ import "unsafe"
|
|||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
//go:linkname C.CString runtime.cgo_CString
|
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||||
func C.CString(string) *C.char
|
func _Cgo_CString(string) *_Cgo_char
|
||||||
|
|
||||||
//go:linkname C.GoString runtime.cgo_GoString
|
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||||
func C.GoString(*C.char) string
|
func _Cgo_GoString(*_Cgo_char) string
|
||||||
|
|
||||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||||
func C.__GoStringN(*C.char, uintptr) string
|
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||||
|
|
||||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||||
return C.__GoStringN(cstr, uintptr(length))
|
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||||
|
|
||||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||||
return C.__GoBytes(ptr, uintptr(length))
|
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||||
func C.__CBytes([]byte) unsafe.Pointer
|
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||||
|
|
||||||
func C.CBytes(b []byte) unsafe.Pointer {
|
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||||
return C.__CBytes(b)
|
return _Cgo___CBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||||
func C.__get_errno_num() uintptr
|
func _Cgo___get_errno_num() uintptr
|
||||||
|
|
||||||
func C.__get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
return syscall.Errno(C.__get_errno_num())
|
return syscall.Errno(_Cgo___get_errno_num())
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
C.char uint8
|
_Cgo_char uint8
|
||||||
C.schar int8
|
_Cgo_schar int8
|
||||||
C.uchar uint8
|
_Cgo_uchar uint8
|
||||||
C.short int16
|
_Cgo_short int16
|
||||||
C.ushort uint16
|
_Cgo_ushort uint16
|
||||||
C.int int32
|
_Cgo_int int32
|
||||||
C.uint uint32
|
_Cgo_uint uint32
|
||||||
C.long int32
|
_Cgo_long int32
|
||||||
C.ulong uint32
|
_Cgo_ulong uint32
|
||||||
C.longlong int64
|
_Cgo_longlong int64
|
||||||
C.ulonglong uint64
|
_Cgo_ulonglong uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
const C.BAR = 3
|
const _Cgo_BAR = 3
|
||||||
const C.FOO_H = 1
|
const _Cgo_FOO_H = 1
|
||||||
|
|||||||
Vendored
+42
-42
@@ -5,80 +5,80 @@ import "unsafe"
|
|||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
//go:linkname C.CString runtime.cgo_CString
|
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||||
func C.CString(string) *C.char
|
func _Cgo_CString(string) *_Cgo_char
|
||||||
|
|
||||||
//go:linkname C.GoString runtime.cgo_GoString
|
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||||
func C.GoString(*C.char) string
|
func _Cgo_GoString(*_Cgo_char) string
|
||||||
|
|
||||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||||
func C.__GoStringN(*C.char, uintptr) string
|
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||||
|
|
||||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||||
return C.__GoStringN(cstr, uintptr(length))
|
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||||
|
|
||||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||||
return C.__GoBytes(ptr, uintptr(length))
|
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||||
func C.__CBytes([]byte) unsafe.Pointer
|
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||||
|
|
||||||
func C.CBytes(b []byte) unsafe.Pointer {
|
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||||
return C.__CBytes(b)
|
return _Cgo___CBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||||
func C.__get_errno_num() uintptr
|
func _Cgo___get_errno_num() uintptr
|
||||||
|
|
||||||
func C.__get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
return syscall.Errno(C.__get_errno_num())
|
return syscall.Errno(_Cgo___get_errno_num())
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
C.char uint8
|
_Cgo_char uint8
|
||||||
C.schar int8
|
_Cgo_schar int8
|
||||||
C.uchar uint8
|
_Cgo_uchar uint8
|
||||||
C.short int16
|
_Cgo_short int16
|
||||||
C.ushort uint16
|
_Cgo_ushort uint16
|
||||||
C.int int32
|
_Cgo_int int32
|
||||||
C.uint uint32
|
_Cgo_uint uint32
|
||||||
C.long int32
|
_Cgo_long int32
|
||||||
C.ulong uint32
|
_Cgo_ulong uint32
|
||||||
C.longlong int64
|
_Cgo_longlong int64
|
||||||
C.ulonglong uint64
|
_Cgo_ulonglong uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
//export foo
|
//export foo
|
||||||
func C.foo(a C.int, b C.int) C.int
|
func _Cgo_foo(a _Cgo_int, b _Cgo_int) _Cgo_int
|
||||||
|
|
||||||
var C.foo$funcaddr unsafe.Pointer
|
var _Cgo_foo$funcaddr unsafe.Pointer
|
||||||
|
|
||||||
//export variadic0
|
//export variadic0
|
||||||
//go:variadic
|
//go:variadic
|
||||||
func C.variadic0()
|
func _Cgo_variadic0()
|
||||||
|
|
||||||
var C.variadic0$funcaddr unsafe.Pointer
|
var _Cgo_variadic0$funcaddr unsafe.Pointer
|
||||||
|
|
||||||
//export variadic2
|
//export variadic2
|
||||||
//go:variadic
|
//go:variadic
|
||||||
func C.variadic2(x C.int, y C.int)
|
func _Cgo_variadic2(x _Cgo_int, y _Cgo_int)
|
||||||
|
|
||||||
var C.variadic2$funcaddr unsafe.Pointer
|
var _Cgo_variadic2$funcaddr unsafe.Pointer
|
||||||
|
|
||||||
//export _Cgo_static_173c95a79b6df1980521_staticfunc
|
//export _Cgo_static_173c95a79b6df1980521_staticfunc
|
||||||
func C.staticfunc!symbols.go(x C.int)
|
func _Cgo_staticfunc!symbols.go(x _Cgo_int)
|
||||||
|
|
||||||
var C.staticfunc!symbols.go$funcaddr unsafe.Pointer
|
var _Cgo_staticfunc!symbols.go$funcaddr unsafe.Pointer
|
||||||
|
|
||||||
//export notEscapingFunction
|
//export notEscapingFunction
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func C.notEscapingFunction(a *C.int)
|
func _Cgo_notEscapingFunction(a *_Cgo_int)
|
||||||
|
|
||||||
var C.notEscapingFunction$funcaddr unsafe.Pointer
|
var _Cgo_notEscapingFunction$funcaddr unsafe.Pointer
|
||||||
//go:extern someValue
|
//go:extern someValue
|
||||||
var C.someValue C.int
|
var _Cgo_someValue _Cgo_int
|
||||||
|
|||||||
Vendored
+103
-99
@@ -5,158 +5,162 @@ import "unsafe"
|
|||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
//go:linkname C.CString runtime.cgo_CString
|
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||||
func C.CString(string) *C.char
|
func _Cgo_CString(string) *_Cgo_char
|
||||||
|
|
||||||
//go:linkname C.GoString runtime.cgo_GoString
|
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||||
func C.GoString(*C.char) string
|
func _Cgo_GoString(*_Cgo_char) string
|
||||||
|
|
||||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||||
func C.__GoStringN(*C.char, uintptr) string
|
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||||
|
|
||||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||||
return C.__GoStringN(cstr, uintptr(length))
|
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||||
|
|
||||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||||
return C.__GoBytes(ptr, uintptr(length))
|
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||||
func C.__CBytes([]byte) unsafe.Pointer
|
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||||
|
|
||||||
func C.CBytes(b []byte) unsafe.Pointer {
|
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||||
return C.__CBytes(b)
|
return _Cgo___CBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||||
func C.__get_errno_num() uintptr
|
func _Cgo___get_errno_num() uintptr
|
||||||
|
|
||||||
func C.__get_errno() error {
|
func _Cgo___get_errno() error {
|
||||||
return syscall.Errno(C.__get_errno_num())
|
return syscall.Errno(_Cgo___get_errno_num())
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
C.char uint8
|
_Cgo_char uint8
|
||||||
C.schar int8
|
_Cgo_schar int8
|
||||||
C.uchar uint8
|
_Cgo_uchar uint8
|
||||||
C.short int16
|
_Cgo_short int16
|
||||||
C.ushort uint16
|
_Cgo_ushort uint16
|
||||||
C.int int32
|
_Cgo_int int32
|
||||||
C.uint uint32
|
_Cgo_uint uint32
|
||||||
C.long int32
|
_Cgo_long int32
|
||||||
C.ulong uint32
|
_Cgo_ulong uint32
|
||||||
C.longlong int64
|
_Cgo_longlong int64
|
||||||
C.ulonglong uint64
|
_Cgo_ulonglong uint64
|
||||||
)
|
)
|
||||||
type C.myint = C.int
|
type _Cgo_myint = _Cgo_int
|
||||||
type C.struct_point2d_t struct {
|
type _Cgo_struct_point2d_t struct {
|
||||||
x C.int
|
x _Cgo_int
|
||||||
y C.int
|
y _Cgo_int
|
||||||
}
|
}
|
||||||
type C.point2d_t = C.struct_point2d_t
|
type _Cgo_point2d_t = _Cgo_struct_point2d_t
|
||||||
type C.struct_point3d struct {
|
type _Cgo_struct_point3d struct {
|
||||||
x C.int
|
x _Cgo_int
|
||||||
y C.int
|
y _Cgo_int
|
||||||
z C.int
|
z _Cgo_int
|
||||||
}
|
}
|
||||||
type C.point3d_t = C.struct_point3d
|
type _Cgo_point3d_t = _Cgo_struct_point3d
|
||||||
type C.struct_type1 struct {
|
type _Cgo_struct_type1 struct {
|
||||||
_type C.int
|
_type _Cgo_int
|
||||||
__type C.int
|
__type _Cgo_int
|
||||||
___type C.int
|
___type _Cgo_int
|
||||||
}
|
}
|
||||||
type C.struct_type2 struct{ _type C.int }
|
type _Cgo_struct_type2 struct{ _type _Cgo_int }
|
||||||
type C.union_union1_t struct{ i C.int }
|
type _Cgo_union_union1_t struct{ i _Cgo_int }
|
||||||
type C.union1_t = C.union_union1_t
|
type _Cgo_union1_t = _Cgo_union_union1_t
|
||||||
type C.union_union3_t struct{ $union uint64 }
|
type _Cgo_union_union3_t struct{ $union uint64 }
|
||||||
|
|
||||||
func (union *C.union_union3_t) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) }
|
func (union *_Cgo_union_union3_t) unionfield_i() *_Cgo_int {
|
||||||
func (union *C.union_union3_t) unionfield_d() *float64 {
|
return (*_Cgo_int)(unsafe.Pointer(&union.$union))
|
||||||
|
}
|
||||||
|
func (union *_Cgo_union_union3_t) unionfield_d() *float64 {
|
||||||
return (*float64)(unsafe.Pointer(&union.$union))
|
return (*float64)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
func (union *C.union_union3_t) unionfield_s() *C.short {
|
func (union *_Cgo_union_union3_t) unionfield_s() *_Cgo_short {
|
||||||
return (*C.short)(unsafe.Pointer(&union.$union))
|
return (*_Cgo_short)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
|
|
||||||
type C.union3_t = C.union_union3_t
|
type _Cgo_union3_t = _Cgo_union_union3_t
|
||||||
type C.union_union2d struct{ $union [2]uint64 }
|
type _Cgo_union_union2d struct{ $union [2]uint64 }
|
||||||
|
|
||||||
func (union *C.union_union2d) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) }
|
func (union *_Cgo_union_union2d) unionfield_i() *_Cgo_int {
|
||||||
func (union *C.union_union2d) unionfield_d() *[2]float64 {
|
return (*_Cgo_int)(unsafe.Pointer(&union.$union))
|
||||||
|
}
|
||||||
|
func (union *_Cgo_union_union2d) unionfield_d() *[2]float64 {
|
||||||
return (*[2]float64)(unsafe.Pointer(&union.$union))
|
return (*[2]float64)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
|
|
||||||
type C.union2d_t = C.union_union2d
|
type _Cgo_union2d_t = _Cgo_union_union2d
|
||||||
type C.union_unionarray_t struct{ arr [10]C.uchar }
|
type _Cgo_union_unionarray_t struct{ arr [10]_Cgo_uchar }
|
||||||
type C.unionarray_t = C.union_unionarray_t
|
type _Cgo_unionarray_t = _Cgo_union_unionarray_t
|
||||||
type C._Ctype_union___0 struct{ $union [3]uint32 }
|
type _Cgo__Ctype_union___0 struct{ $union [3]uint32 }
|
||||||
|
|
||||||
func (union *C._Ctype_union___0) unionfield_area() *C.point2d_t {
|
func (union *_Cgo__Ctype_union___0) unionfield_area() *_Cgo_point2d_t {
|
||||||
return (*C.point2d_t)(unsafe.Pointer(&union.$union))
|
return (*_Cgo_point2d_t)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
func (union *C._Ctype_union___0) unionfield_solid() *C.point3d_t {
|
func (union *_Cgo__Ctype_union___0) unionfield_solid() *_Cgo_point3d_t {
|
||||||
return (*C.point3d_t)(unsafe.Pointer(&union.$union))
|
return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
|
|
||||||
type C.struct_struct_nested_t struct {
|
type _Cgo_struct_struct_nested_t struct {
|
||||||
begin C.point2d_t
|
begin _Cgo_point2d_t
|
||||||
end C.point2d_t
|
end _Cgo_point2d_t
|
||||||
tag C.int
|
tag _Cgo_int
|
||||||
|
|
||||||
coord C._Ctype_union___0
|
coord _Cgo__Ctype_union___0
|
||||||
}
|
}
|
||||||
type C.struct_nested_t = C.struct_struct_nested_t
|
type _Cgo_struct_nested_t = _Cgo_struct_struct_nested_t
|
||||||
type C.union_union_nested_t struct{ $union [2]uint64 }
|
type _Cgo_union_union_nested_t struct{ $union [2]uint64 }
|
||||||
|
|
||||||
func (union *C.union_union_nested_t) unionfield_point() *C.point3d_t {
|
func (union *_Cgo_union_union_nested_t) unionfield_point() *_Cgo_point3d_t {
|
||||||
return (*C.point3d_t)(unsafe.Pointer(&union.$union))
|
return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
func (union *C.union_union_nested_t) unionfield_array() *C.unionarray_t {
|
func (union *_Cgo_union_union_nested_t) unionfield_array() *_Cgo_unionarray_t {
|
||||||
return (*C.unionarray_t)(unsafe.Pointer(&union.$union))
|
return (*_Cgo_unionarray_t)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
func (union *C.union_union_nested_t) unionfield_thing() *C.union3_t {
|
func (union *_Cgo_union_union_nested_t) unionfield_thing() *_Cgo_union3_t {
|
||||||
return (*C.union3_t)(unsafe.Pointer(&union.$union))
|
return (*_Cgo_union3_t)(unsafe.Pointer(&union.$union))
|
||||||
}
|
}
|
||||||
|
|
||||||
type C.union_nested_t = C.union_union_nested_t
|
type _Cgo_union_nested_t = _Cgo_union_union_nested_t
|
||||||
type C.enum_option = C.int
|
type _Cgo_enum_option = _Cgo_int
|
||||||
type C.option_t = C.enum_option
|
type _Cgo_option_t = _Cgo_enum_option
|
||||||
type C.enum_option2_t = C.uint
|
type _Cgo_enum_option2_t = _Cgo_uint
|
||||||
type C.option2_t = C.enum_option2_t
|
type _Cgo_option2_t = _Cgo_enum_option2_t
|
||||||
type C.struct_types_t struct {
|
type _Cgo_struct_types_t struct {
|
||||||
f float32
|
f float32
|
||||||
d float64
|
d float64
|
||||||
ptr *C.int
|
ptr *_Cgo_int
|
||||||
}
|
}
|
||||||
type C.types_t = C.struct_types_t
|
type _Cgo_types_t = _Cgo_struct_types_t
|
||||||
type C.myIntArray = [10]C.int
|
type _Cgo_myIntArray = [10]_Cgo_int
|
||||||
type C.struct_bitfield_t struct {
|
type _Cgo_struct_bitfield_t struct {
|
||||||
start C.uchar
|
start _Cgo_uchar
|
||||||
__bitfield_1 C.uchar
|
__bitfield_1 _Cgo_uchar
|
||||||
|
|
||||||
d C.uchar
|
d _Cgo_uchar
|
||||||
e C.uchar
|
e _Cgo_uchar
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *C.struct_bitfield_t) bitfield_a() C.uchar { return s.__bitfield_1 & 0x1f }
|
func (s *_Cgo_struct_bitfield_t) bitfield_a() _Cgo_uchar { return s.__bitfield_1 & 0x1f }
|
||||||
func (s *C.struct_bitfield_t) set_bitfield_a(value C.uchar) {
|
func (s *_Cgo_struct_bitfield_t) set_bitfield_a(value _Cgo_uchar) {
|
||||||
s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0
|
s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0
|
||||||
}
|
}
|
||||||
func (s *C.struct_bitfield_t) bitfield_b() C.uchar {
|
func (s *_Cgo_struct_bitfield_t) bitfield_b() _Cgo_uchar {
|
||||||
return s.__bitfield_1 >> 5 & 0x1
|
return s.__bitfield_1 >> 5 & 0x1
|
||||||
}
|
}
|
||||||
func (s *C.struct_bitfield_t) set_bitfield_b(value C.uchar) {
|
func (s *_Cgo_struct_bitfield_t) set_bitfield_b(value _Cgo_uchar) {
|
||||||
s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5
|
s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5
|
||||||
}
|
}
|
||||||
func (s *C.struct_bitfield_t) bitfield_c() C.uchar {
|
func (s *_Cgo_struct_bitfield_t) bitfield_c() _Cgo_uchar {
|
||||||
return s.__bitfield_1 >> 6
|
return s.__bitfield_1 >> 6
|
||||||
}
|
}
|
||||||
func (s *C.struct_bitfield_t) set_bitfield_c(value C.uchar,
|
func (s *_Cgo_struct_bitfield_t) set_bitfield_c(value _Cgo_uchar,
|
||||||
|
|
||||||
) { s.__bitfield_1 = s.__bitfield_1&0x3f | value<<6 }
|
) { s.__bitfield_1 = s.__bitfield_1&0x3f | value<<6 }
|
||||||
|
|
||||||
type C.bitfield_t = C.struct_bitfield_t
|
type _Cgo_bitfield_t = _Cgo_struct_bitfield_t
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
validBuildModeOptions = []string{"default", "c-shared"}
|
validBuildModeOptions = []string{"default", "c-shared", "wasi-legacy"}
|
||||||
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
|
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
|
||||||
validSchedulerOptions = []string{"none", "tasks", "asyncify"}
|
validSchedulerOptions = []string{"none", "tasks", "asyncify"}
|
||||||
validSerialOptions = []string{"none", "uart", "usb", "rtt"}
|
validSerialOptions = []string{"none", "uart", "usb", "rtt"}
|
||||||
|
|||||||
+6
-5
@@ -18,11 +18,12 @@ var stdlibAliases = map[string]string{
|
|||||||
// crypto packages
|
// crypto packages
|
||||||
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
|
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
|
||||||
"crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
|
"crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
|
||||||
"crypto/md5.block": "crypto/md5.blockGeneric",
|
"crypto/md5.block": "crypto/md5.blockGeneric",
|
||||||
"crypto/sha1.block": "crypto/sha1.blockGeneric",
|
"crypto/sha1.block": "crypto/sha1.blockGeneric",
|
||||||
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
|
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
|
||||||
"crypto/sha256.block": "crypto/sha256.blockGeneric",
|
"crypto/sha256.block": "crypto/sha256.blockGeneric",
|
||||||
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
|
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
|
||||||
|
"internal/chacha8rand.block": "internal/chacha8rand.block_generic",
|
||||||
|
|
||||||
// AES
|
// AES
|
||||||
"crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock",
|
"crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock",
|
||||||
|
|||||||
+11
-11
@@ -31,7 +31,7 @@ func (b *builder) createLookupBoundsCheck(arrayLen, index llvm.Value) {
|
|||||||
|
|
||||||
// Now do the bounds check: index >= arrayLen
|
// Now do the bounds check: index >= arrayLen
|
||||||
outOfBounds := b.CreateICmp(llvm.IntUGE, index, arrayLen, "")
|
outOfBounds := b.CreateICmp(llvm.IntUGE, index, arrayLen, "")
|
||||||
b.createRuntimeAssert(outOfBounds, "lookup", "lookupPanic")
|
b.createRuntimeAssert(outOfBounds, "lookup", "lookupPanic", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createSliceBoundsCheck emits a bounds check before a slicing operation to make
|
// createSliceBoundsCheck emits a bounds check before a slicing operation to make
|
||||||
@@ -74,7 +74,7 @@ func (b *builder) createSliceBoundsCheck(capacity, low, high, max llvm.Value, lo
|
|||||||
outOfBounds3 := b.CreateICmp(llvm.IntUGT, max, capacity, "slice.maxcap")
|
outOfBounds3 := b.CreateICmp(llvm.IntUGT, max, capacity, "slice.maxcap")
|
||||||
outOfBounds := b.CreateOr(outOfBounds1, outOfBounds2, "slice.lowmax")
|
outOfBounds := b.CreateOr(outOfBounds1, outOfBounds2, "slice.lowmax")
|
||||||
outOfBounds = b.CreateOr(outOfBounds, outOfBounds3, "slice.lowcap")
|
outOfBounds = b.CreateOr(outOfBounds, outOfBounds3, "slice.lowcap")
|
||||||
b.createRuntimeAssert(outOfBounds, "slice", "slicePanic")
|
b.createRuntimeAssert(outOfBounds, "slice", "slicePanic", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createSliceToArrayPointerCheck adds a check for slice-to-array pointer
|
// createSliceToArrayPointerCheck adds a check for slice-to-array pointer
|
||||||
@@ -86,7 +86,7 @@ func (b *builder) createSliceToArrayPointerCheck(sliceLen llvm.Value, arrayLen i
|
|||||||
// > run-time panic occurs.
|
// > run-time panic occurs.
|
||||||
arrayLenValue := llvm.ConstInt(b.uintptrType, uint64(arrayLen), false)
|
arrayLenValue := llvm.ConstInt(b.uintptrType, uint64(arrayLen), false)
|
||||||
isLess := b.CreateICmp(llvm.IntULT, sliceLen, arrayLenValue, "")
|
isLess := b.CreateICmp(llvm.IntULT, sliceLen, arrayLenValue, "")
|
||||||
b.createRuntimeAssert(isLess, "slicetoarray", "sliceToArrayPointerPanic")
|
b.createRuntimeAssert(isLess, "slicetoarray", "sliceToArrayPointerPanic", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createUnsafeSliceStringCheck inserts a runtime check used for unsafe.Slice
|
// createUnsafeSliceStringCheck inserts a runtime check used for unsafe.Slice
|
||||||
@@ -118,7 +118,7 @@ func (b *builder) createUnsafeSliceStringCheck(name string, ptr, len llvm.Value,
|
|||||||
lenIsNotZero := b.CreateICmp(llvm.IntNE, len, zero, "")
|
lenIsNotZero := b.CreateICmp(llvm.IntNE, len, zero, "")
|
||||||
assert := b.CreateAnd(ptrIsNil, lenIsNotZero, "")
|
assert := b.CreateAnd(ptrIsNil, lenIsNotZero, "")
|
||||||
assert = b.CreateOr(assert, lenOutOfBounds, "")
|
assert = b.CreateOr(assert, lenOutOfBounds, "")
|
||||||
b.createRuntimeAssert(assert, name, "unsafeSlicePanic")
|
b.createRuntimeAssert(assert, name, "unsafeSlicePanic", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createChanBoundsCheck creates a bounds check before creating a new channel to
|
// createChanBoundsCheck creates a bounds check before creating a new channel to
|
||||||
@@ -155,7 +155,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
|
|||||||
|
|
||||||
// Do the check for a too large (or negative) buffer size.
|
// Do the check for a too large (or negative) buffer size.
|
||||||
bufSizeTooBig := b.CreateICmp(llvm.IntUGE, bufSize, maxBufSize, "")
|
bufSizeTooBig := b.CreateICmp(llvm.IntUGE, bufSize, maxBufSize, "")
|
||||||
b.createRuntimeAssert(bufSizeTooBig, "chan", "chanMakePanic")
|
b.createRuntimeAssert(bufSizeTooBig, "chan", "chanMakePanic", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createNilCheck checks whether the given pointer is nil, and panics if it is.
|
// createNilCheck checks whether the given pointer is nil, and panics if it is.
|
||||||
@@ -199,7 +199,7 @@ func (b *builder) createNilCheck(inst ssa.Value, ptr llvm.Value, blockPrefix str
|
|||||||
isnil := b.CreateICmp(llvm.IntEQ, ptr, nilptr, "")
|
isnil := b.CreateICmp(llvm.IntEQ, ptr, nilptr, "")
|
||||||
|
|
||||||
// Emit the nil check in IR.
|
// Emit the nil check in IR.
|
||||||
b.createRuntimeAssert(isnil, blockPrefix, "nilPanic")
|
b.createRuntimeAssert(isnil, blockPrefix, "nilPanic", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createNegativeShiftCheck creates an assertion that panics if the given shift value is negative.
|
// createNegativeShiftCheck creates an assertion that panics if the given shift value is negative.
|
||||||
@@ -212,7 +212,7 @@ func (b *builder) createNegativeShiftCheck(shift llvm.Value) {
|
|||||||
|
|
||||||
// isNegative = shift < 0
|
// isNegative = shift < 0
|
||||||
isNegative := b.CreateICmp(llvm.IntSLT, shift, llvm.ConstInt(shift.Type(), 0, false), "")
|
isNegative := b.CreateICmp(llvm.IntSLT, shift, llvm.ConstInt(shift.Type(), 0, false), "")
|
||||||
b.createRuntimeAssert(isNegative, "shift", "negativeShiftPanic")
|
b.createRuntimeAssert(isNegative, "shift", "negativeShiftPanic", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createDivideByZeroCheck asserts that y is not zero. If it is, a runtime panic
|
// createDivideByZeroCheck asserts that y is not zero. If it is, a runtime panic
|
||||||
@@ -225,12 +225,12 @@ func (b *builder) createDivideByZeroCheck(y llvm.Value) {
|
|||||||
|
|
||||||
// isZero = y == 0
|
// isZero = y == 0
|
||||||
isZero := b.CreateICmp(llvm.IntEQ, y, llvm.ConstInt(y.Type(), 0, false), "")
|
isZero := b.CreateICmp(llvm.IntEQ, y, llvm.ConstInt(y.Type(), 0, false), "")
|
||||||
b.createRuntimeAssert(isZero, "divbyzero", "divideByZeroPanic")
|
b.createRuntimeAssert(isZero, "divbyzero", "divideByZeroPanic", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createRuntimeAssert is a common function to create a new branch on an assert
|
// createRuntimeAssert is a common function to create a new branch on an assert
|
||||||
// bool, calling an assert func if the assert value is true (1).
|
// bool, calling an assert func if the assert value is true (1).
|
||||||
func (b *builder) createRuntimeAssert(assert llvm.Value, blockPrefix, assertFunc string) {
|
func (b *builder) createRuntimeAssert(assert llvm.Value, blockPrefix, assertFunc string, isInvoke bool) {
|
||||||
// Check whether we can resolve this check at compile time.
|
// Check whether we can resolve this check at compile time.
|
||||||
if !assert.IsAConstantInt().IsNil() {
|
if !assert.IsAConstantInt().IsNil() {
|
||||||
val := assert.ZExtValue()
|
val := assert.ZExtValue()
|
||||||
@@ -245,17 +245,17 @@ func (b *builder) createRuntimeAssert(assert llvm.Value, blockPrefix, assertFunc
|
|||||||
// current insert position.
|
// current insert position.
|
||||||
faultBlock := b.ctx.AddBasicBlock(b.llvmFn, blockPrefix+".throw")
|
faultBlock := b.ctx.AddBasicBlock(b.llvmFn, blockPrefix+".throw")
|
||||||
nextBlock := b.insertBasicBlock(blockPrefix + ".next")
|
nextBlock := b.insertBasicBlock(blockPrefix + ".next")
|
||||||
b.blockExits[b.currentBlock] = nextBlock // adjust outgoing block for phi nodes
|
|
||||||
|
|
||||||
// Now branch to the out-of-bounds or the regular block.
|
// Now branch to the out-of-bounds or the regular block.
|
||||||
b.CreateCondBr(assert, faultBlock, nextBlock)
|
b.CreateCondBr(assert, faultBlock, nextBlock)
|
||||||
|
|
||||||
// Fail: the assert triggered so panic.
|
// Fail: the assert triggered so panic.
|
||||||
b.SetInsertPointAtEnd(faultBlock)
|
b.SetInsertPointAtEnd(faultBlock)
|
||||||
b.createRuntimeCall(assertFunc, nil, "")
|
b.createRuntimeCallCommon(assertFunc, nil, "", isInvoke)
|
||||||
b.CreateUnreachable()
|
b.CreateUnreachable()
|
||||||
|
|
||||||
// Ok: assert didn't trigger so continue normally.
|
// Ok: assert didn't trigger so continue normally.
|
||||||
|
b.blockExits[b.currentBlock] = nextBlock // adjust outgoing block for phi nodes
|
||||||
b.SetInsertPointAtEnd(nextBlock)
|
b.SetInsertPointAtEnd(nextBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-5
@@ -283,6 +283,11 @@ func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo {
|
|||||||
info.wasmName = "_start"
|
info.wasmName = "_start"
|
||||||
info.exported = true
|
info.exported = true
|
||||||
}
|
}
|
||||||
|
if info.linkName == "runtime.wasmEntryLegacy" && c.BuildMode == "wasi-legacy" {
|
||||||
|
info.linkName = "_start"
|
||||||
|
info.wasmName = "_start"
|
||||||
|
info.exported = true
|
||||||
|
}
|
||||||
|
|
||||||
// Check for //go: pragmas, which may change the link name (among others).
|
// Check for //go: pragmas, which may change the link name (among others).
|
||||||
c.parsePragmas(&info, f)
|
c.parsePragmas(&info, f)
|
||||||
@@ -427,9 +432,8 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
|
|||||||
// pass for C variadic functions. This includes both explicit
|
// pass for C variadic functions. This includes both explicit
|
||||||
// (with ...) and implicit (no parameters in signature)
|
// (with ...) and implicit (no parameters in signature)
|
||||||
// functions.
|
// functions.
|
||||||
if strings.HasPrefix(f.Name(), "C.") {
|
if strings.HasPrefix(f.Name(), "_Cgo_") {
|
||||||
// This prefix cannot naturally be created, it must have
|
// This prefix was created as a result of CGo preprocessing.
|
||||||
// been created as a result of CGo preprocessing.
|
|
||||||
info.variadic = true
|
info.variadic = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -684,20 +688,25 @@ func (c *compilerContext) getGlobalInfo(g *ssa.Global) globalInfo {
|
|||||||
// Check for //go: pragmas, which may change the link name (among others).
|
// Check for //go: pragmas, which may change the link name (among others).
|
||||||
doc := c.astComments[info.linkName]
|
doc := c.astComments[info.linkName]
|
||||||
if doc != nil {
|
if doc != nil {
|
||||||
info.parsePragmas(doc)
|
info.parsePragmas(doc, g)
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse //go: pragma comments from the source. In particular, it parses the
|
// Parse //go: pragma comments from the source. In particular, it parses the
|
||||||
// //go:extern pragma on globals.
|
// //go:extern pragma on globals.
|
||||||
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
|
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup, g *ssa.Global) {
|
||||||
for _, comment := range doc.List {
|
for _, comment := range doc.List {
|
||||||
if !strings.HasPrefix(comment.Text, "//go:") {
|
if !strings.HasPrefix(comment.Text, "//go:") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
parts := strings.Fields(comment.Text)
|
parts := strings.Fields(comment.Text)
|
||||||
switch parts[0] {
|
switch parts[0] {
|
||||||
|
case "//go:linkname":
|
||||||
|
if len(parts) == 3 && g.Name() == parts[1] {
|
||||||
|
info.linkName = parts[2]
|
||||||
|
info.extern = true
|
||||||
|
}
|
||||||
case "//go:extern":
|
case "//go:extern":
|
||||||
info.extern = true
|
info.extern = true
|
||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package main
|
|||||||
|
|
||||||
import _ "unsafe"
|
import _ "unsafe"
|
||||||
|
|
||||||
|
// Use the go:linkname mechanism to link this global to a different package.
|
||||||
|
// This is used in math/bits.
|
||||||
|
//
|
||||||
|
//go:linkname linknamedGlobal runtime.testLinknamedGlobal
|
||||||
|
var linknamedGlobal int
|
||||||
|
|
||||||
// Creates an external global with name extern_global.
|
// Creates an external global with name extern_global.
|
||||||
//
|
//
|
||||||
//go:extern extern_global
|
//go:extern extern_global
|
||||||
|
|||||||
Vendored
+1
@@ -3,6 +3,7 @@ source_filename = "pragma.go"
|
|||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
|
@runtime.testLinknamedGlobal = external global i32, align 4
|
||||||
@extern_global = external global [0 x i8], align 1
|
@extern_global = external global [0 x i8], align 1
|
||||||
@main.alignedGlobal = hidden global [4 x i32] zeroinitializer, align 32
|
@main.alignedGlobal = hidden global [4 x i32] zeroinitializer, align 32
|
||||||
@main.alignedGlobal16 = hidden global [4 x i32] zeroinitializer, align 16
|
@main.alignedGlobal16 = hidden global [4 x i32] zeroinitializer, align 16
|
||||||
|
|||||||
@@ -970,9 +970,9 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me
|
|||||||
case llvm.Call:
|
case llvm.Call:
|
||||||
llvmFn := operands[len(operands)-1]
|
llvmFn := operands[len(operands)-1]
|
||||||
args := operands[:len(operands)-1]
|
args := operands[:len(operands)-1]
|
||||||
for _, arg := range args {
|
for _, op := range operands {
|
||||||
if arg.Type().TypeKind() == llvm.PointerTypeKind {
|
if op.Type().TypeKind() == llvm.PointerTypeKind {
|
||||||
err := mem.markExternalStore(arg)
|
err := mem.markExternalStore(op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return r.errorAt(inst, err)
|
return r.errorAt(inst, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1501,7 +1501,7 @@ func main() {
|
|||||||
var tags buildutil.TagsFlag
|
var tags buildutil.TagsFlag
|
||||||
flag.Var(&tags, "tags", "a space-separated list of extra build tags")
|
flag.Var(&tags, "tags", "a space-separated list of extra build tags")
|
||||||
target := flag.String("target", "", "chip/board name or JSON target specification file")
|
target := flag.String("target", "", "chip/board name or JSON target specification file")
|
||||||
buildMode := flag.String("buildmode", "", "build mode to use (default, c-shared)")
|
buildMode := flag.String("buildmode", "", "build mode to use (default, c-shared, wasi-legacy)")
|
||||||
var stackSize uint64
|
var stackSize uint64
|
||||||
flag.Func("stack-size", "goroutine stack size (if unknown at compile time)", func(s string) error {
|
flag.Func("stack-size", "goroutine stack size (if unknown at compile time)", func(s string) error {
|
||||||
size, err := bytesize.Parse(s)
|
size, err := bytesize.Parse(s)
|
||||||
|
|||||||
@@ -594,6 +594,15 @@ func TestWasmExport(t *testing.T) {
|
|||||||
noOutput: true, // wasm-unknown cannot produce output
|
noOutput: true, // wasm-unknown cannot produce output
|
||||||
command: true,
|
command: true,
|
||||||
},
|
},
|
||||||
|
// Test buildmode=wasi-legacy with WASI.
|
||||||
|
{
|
||||||
|
name: "WASIp1-legacy",
|
||||||
|
target: "wasip1",
|
||||||
|
buildMode: "wasi-legacy",
|
||||||
|
scheduler: "none",
|
||||||
|
file: "wasmexport-noscheduler.go",
|
||||||
|
command: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
|
|||||||
@@ -17,6 +17,37 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VersionTLS10 = 0x0301
|
||||||
|
VersionTLS11 = 0x0302
|
||||||
|
VersionTLS12 = 0x0303
|
||||||
|
VersionTLS13 = 0x0304
|
||||||
|
|
||||||
|
// Deprecated: SSLv3 is cryptographically broken, and is no longer
|
||||||
|
// supported by this package. See golang.org/issue/32716.
|
||||||
|
VersionSSL30 = 0x0300
|
||||||
|
)
|
||||||
|
|
||||||
|
// VersionName returns the name for the provided TLS version number
|
||||||
|
// (e.g. "TLS 1.3"), or a fallback representation of the value if the
|
||||||
|
// version is not implemented by this package.
|
||||||
|
func VersionName(version uint16) string {
|
||||||
|
switch version {
|
||||||
|
case VersionSSL30:
|
||||||
|
return "SSLv3"
|
||||||
|
case VersionTLS10:
|
||||||
|
return "TLS 1.0"
|
||||||
|
case VersionTLS11:
|
||||||
|
return "TLS 1.1"
|
||||||
|
case VersionTLS12:
|
||||||
|
return "TLS 1.2"
|
||||||
|
case VersionTLS13:
|
||||||
|
return "TLS 1.3"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("0x%04X", version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CurveID is the type of a TLS identifier for an elliptic curve. See
|
// CurveID is the type of a TLS identifier for an elliptic curve. See
|
||||||
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8.
|
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package abi
|
||||||
|
|
||||||
|
type Type struct {
|
||||||
|
// Intentionally left empty. TinyGo uses a different way to represent types,
|
||||||
|
// so this is unimplementable. The type definition here is purely for
|
||||||
|
// compatibility.
|
||||||
|
}
|
||||||
@@ -21,6 +21,9 @@ type Task struct {
|
|||||||
// state is the underlying running state of the task.
|
// state is the underlying running state of the task.
|
||||||
state state
|
state state
|
||||||
|
|
||||||
|
// This is needed for some crypto packages.
|
||||||
|
FipsIndicator uint8
|
||||||
|
|
||||||
// DeferFrame stores a pointer to the (stack allocated) defer frame of the
|
// DeferFrame stores a pointer to the (stack allocated) defer frame of the
|
||||||
// goroutine that is used for the recover builtin.
|
// goroutine that is used for the recover builtin.
|
||||||
DeferFrame unsafe.Pointer
|
DeferFrame unsafe.Pointer
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
//go:build hw_651
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// No-name brand board based on the nRF51822 chip with low frequency crystal on board.
|
||||||
|
// Pinout (reverse engineered from the board) can be found here:
|
||||||
|
// https://aviatorahmet.blogspot.com/2020/12/pinout-of-nrf51822-board.html
|
||||||
|
// https://cr0wg4n.medium.com/pinout-nrf51822-board-hw-651-78da2eda8894
|
||||||
|
|
||||||
|
const HasLowFrequencyCrystal = true
|
||||||
|
|
||||||
|
var DefaultUART = UART0
|
||||||
|
|
||||||
|
// GPIO pins on header J1
|
||||||
|
const (
|
||||||
|
J1_01 = P0_21
|
||||||
|
J1_03 = P0_23
|
||||||
|
J1_04 = P0_22
|
||||||
|
J1_05 = P0_25
|
||||||
|
J1_06 = P0_24
|
||||||
|
J1_09 = P0_29
|
||||||
|
J1_10 = P0_28
|
||||||
|
J1_11 = P0_30
|
||||||
|
J1_13 = P0_00
|
||||||
|
J1_15 = P0_02
|
||||||
|
J1_17 = P0_04
|
||||||
|
J1_16 = P0_01
|
||||||
|
J1_18 = P0_03
|
||||||
|
)
|
||||||
|
|
||||||
|
// GPIO pins on header J2
|
||||||
|
const (
|
||||||
|
J2_01 = P0_20
|
||||||
|
J2_03 = P0_18
|
||||||
|
J2_04 = P0_19
|
||||||
|
J2_07 = P0_16
|
||||||
|
J2_08 = P0_15
|
||||||
|
J2_09 = P0_14
|
||||||
|
J2_10 = P0_13
|
||||||
|
J2_11 = P0_12
|
||||||
|
J2_12 = P0_11
|
||||||
|
J2_13 = P0_10
|
||||||
|
J2_14 = P0_09
|
||||||
|
J2_15 = P0_08
|
||||||
|
J2_16 = P0_07
|
||||||
|
J2_17 = P0_06
|
||||||
|
J2_18 = P0_05
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART pins
|
||||||
|
const (
|
||||||
|
UART_TX_PIN = P0_24 // J1_06 on the board
|
||||||
|
UART_RX_PIN = P0_25 // J1_05 on the board
|
||||||
|
)
|
||||||
|
|
||||||
|
// ADC pins
|
||||||
|
const (
|
||||||
|
ADC0 = P0_03 // J1_18 on the board
|
||||||
|
ADC1 = P0_02 // J1_15 on the board
|
||||||
|
ADC2 = P0_01 // J1_16 on the board
|
||||||
|
ADC3 = P0_04 // J1_17 on the board
|
||||||
|
ADC4 = P0_05 // J2_18 on the board
|
||||||
|
ADC5 = P0_06 // J2_17 on the board
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2C pins
|
||||||
|
const (
|
||||||
|
SDA_PIN = P0_30 // J1_11 on the board
|
||||||
|
SCL_PIN = P0_00 // J1_13 on the board
|
||||||
|
)
|
||||||
|
|
||||||
|
// SPI pins
|
||||||
|
const (
|
||||||
|
SPI0_SCK_PIN = P0_23 // J1_03 on the board
|
||||||
|
SPI0_SDO_PIN = P0_21 // J1_01 on the board
|
||||||
|
SPI0_SDI_PIN = P0_22 // J1_04 on the board
|
||||||
|
)
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
//go:build pga2350
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// PGA2350 pin definitions.
|
||||||
|
const (
|
||||||
|
GP0 = GPIO0
|
||||||
|
GP1 = GPIO1
|
||||||
|
GP2 = GPIO2
|
||||||
|
GP3 = GPIO3
|
||||||
|
GP4 = GPIO4
|
||||||
|
GP5 = GPIO5
|
||||||
|
GP6 = GPIO6
|
||||||
|
GP7 = GPIO7
|
||||||
|
GP8 = GPIO8
|
||||||
|
GP9 = GPIO9
|
||||||
|
GP10 = GPIO10
|
||||||
|
GP11 = GPIO11
|
||||||
|
GP12 = GPIO12
|
||||||
|
GP13 = GPIO13
|
||||||
|
GP14 = GPIO14
|
||||||
|
GP15 = GPIO15
|
||||||
|
GP16 = GPIO16
|
||||||
|
GP17 = GPIO17
|
||||||
|
GP18 = GPIO18
|
||||||
|
GP19 = GPIO19
|
||||||
|
GP20 = GPIO20
|
||||||
|
GP21 = GPIO21
|
||||||
|
GP22 = GPIO22
|
||||||
|
GP26 = GPIO26
|
||||||
|
GP27 = GPIO27
|
||||||
|
GP28 = GPIO28
|
||||||
|
GP29 = GPIO29
|
||||||
|
GP30 = GPIO30 // peripherals: PWM7 channel A
|
||||||
|
GP31 = GPIO31 // peripherals: PWM7 channel B
|
||||||
|
GP32 = GPIO32 // peripherals: PWM8 channel A
|
||||||
|
GP33 = GPIO33 // peripherals: PWM8 channel B
|
||||||
|
GP34 = GPIO34 // peripherals: PWM9 channel A
|
||||||
|
GP35 = GPIO35 // peripherals: PWM9 channel B
|
||||||
|
GP36 = GPIO36 // peripherals: PWM10 channel A
|
||||||
|
GP37 = GPIO37 // peripherals: PWM10 channel B
|
||||||
|
GP38 = GPIO38 // peripherals: PWM11 channel A
|
||||||
|
GP39 = GPIO39 // peripherals: PWM11 channel B
|
||||||
|
GP40 = GPIO40 // peripherals: PWM8 channel A
|
||||||
|
GP41 = GPIO41 // peripherals: PWM8 channel B
|
||||||
|
GP42 = GPIO42 // peripherals: PWM9 channel A
|
||||||
|
GP43 = GPIO43 // peripherals: PWM9 channel B
|
||||||
|
GP44 = GPIO44 // peripherals: PWM10 channel A
|
||||||
|
GP45 = GPIO45 // peripherals: PWM10 channel B
|
||||||
|
GP46 = GPIO46 // peripherals: PWM11 channel A
|
||||||
|
GP47 = GPIO47 // peripherals: PWM11 channel B
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
var DefaultUART = UART0
|
||||||
|
|
||||||
|
// Peripheral defaults.
|
||||||
|
const (
|
||||||
|
xoscFreq = 12 // MHz
|
||||||
|
|
||||||
|
I2C0_SDA_PIN = GP4
|
||||||
|
I2C0_SCL_PIN = GP5
|
||||||
|
|
||||||
|
I2C1_SDA_PIN = GP2
|
||||||
|
I2C1_SCL_PIN = GP3
|
||||||
|
|
||||||
|
// Default Serial Clock Bus 0 for SPI communications
|
||||||
|
SPI0_SCK_PIN = GPIO18
|
||||||
|
// Default Serial Out Bus 0 for SPI communications
|
||||||
|
SPI0_SDO_PIN = GPIO19 // Tx
|
||||||
|
// Default Serial In Bus 0 for SPI communications
|
||||||
|
SPI0_SDI_PIN = GPIO16 // Rx
|
||||||
|
|
||||||
|
// Default Serial Clock Bus 1 for SPI communications
|
||||||
|
SPI1_SCK_PIN = GPIO10
|
||||||
|
// Default Serial Out Bus 1 for SPI communications
|
||||||
|
SPI1_SDO_PIN = GPIO11 // Tx
|
||||||
|
// Default Serial In Bus 1 for SPI communications
|
||||||
|
SPI1_SDI_PIN = GPIO12 // Rx
|
||||||
|
|
||||||
|
UART0_TX_PIN = GPIO0
|
||||||
|
UART0_RX_PIN = GPIO1
|
||||||
|
UART1_TX_PIN = GPIO8
|
||||||
|
UART1_RX_PIN = GPIO9
|
||||||
|
UART_TX_PIN = UART0_TX_PIN
|
||||||
|
UART_RX_PIN = UART0_RX_PIN
|
||||||
|
)
|
||||||
|
|
||||||
|
// USB identifiers
|
||||||
|
const (
|
||||||
|
usb_STRING_PRODUCT = "PGA2350"
|
||||||
|
usb_STRING_MANUFACTURER = "Pimoroni"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
usb_VID uint16 = 0x2E8A
|
||||||
|
usb_PID uint16 = 0x000A
|
||||||
|
)
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
//go:build pico_plus2
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// GPIO pins
|
||||||
|
const (
|
||||||
|
GP0 Pin = GPIO0
|
||||||
|
GP1 Pin = GPIO1
|
||||||
|
GP2 Pin = GPIO2
|
||||||
|
GP3 Pin = GPIO3
|
||||||
|
GP4 Pin = GPIO4
|
||||||
|
GP5 Pin = GPIO5
|
||||||
|
GP6 Pin = GPIO6
|
||||||
|
GP7 Pin = GPIO7
|
||||||
|
GP8 Pin = GPIO8
|
||||||
|
GP9 Pin = GPIO9
|
||||||
|
GP10 Pin = GPIO10
|
||||||
|
GP11 Pin = GPIO11
|
||||||
|
GP12 Pin = GPIO12
|
||||||
|
GP13 Pin = GPIO13
|
||||||
|
GP14 Pin = GPIO14
|
||||||
|
GP15 Pin = GPIO15
|
||||||
|
GP16 Pin = GPIO16
|
||||||
|
GP17 Pin = GPIO17
|
||||||
|
GP18 Pin = GPIO18
|
||||||
|
GP19 Pin = GPIO19
|
||||||
|
GP20 Pin = GPIO20
|
||||||
|
GP21 Pin = GPIO21
|
||||||
|
GP22 Pin = GPIO22
|
||||||
|
GP26 Pin = GPIO26
|
||||||
|
GP27 Pin = GPIO27
|
||||||
|
GP28 Pin = GPIO28
|
||||||
|
GP32 Pin = GPIO32
|
||||||
|
GP33 Pin = GPIO33
|
||||||
|
GP34 Pin = GPIO34
|
||||||
|
GP35 Pin = GPIO35
|
||||||
|
GP36 Pin = GPIO36
|
||||||
|
|
||||||
|
// Onboard LED
|
||||||
|
LED Pin = GPIO25
|
||||||
|
|
||||||
|
// Onboard crystal oscillator frequency, in MHz.
|
||||||
|
xoscFreq = 12 // MHz
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2C Default pins on Raspberry Pico.
|
||||||
|
const (
|
||||||
|
I2C0_SDA_PIN = GP4
|
||||||
|
I2C0_SCL_PIN = GP5
|
||||||
|
|
||||||
|
I2C1_SDA_PIN = GP2
|
||||||
|
I2C1_SCL_PIN = GP3
|
||||||
|
)
|
||||||
|
|
||||||
|
// SPI default pins
|
||||||
|
const (
|
||||||
|
// Default Serial Clock Bus 0 for SPI communications
|
||||||
|
SPI0_SCK_PIN = GPIO18
|
||||||
|
// Default Serial Out Bus 0 for SPI communications
|
||||||
|
SPI0_SDO_PIN = GPIO19 // Tx
|
||||||
|
// Default Serial In Bus 0 for SPI communications
|
||||||
|
SPI0_SDI_PIN = GPIO16 // Rx
|
||||||
|
|
||||||
|
// Default Serial Clock Bus 1 for SPI communications
|
||||||
|
SPI1_SCK_PIN = GPIO10
|
||||||
|
// Default Serial Out Bus 1 for SPI communications
|
||||||
|
SPI1_SDO_PIN = GPIO11 // Tx
|
||||||
|
// Default Serial In Bus 1 for SPI communications
|
||||||
|
SPI1_SDI_PIN = GPIO12 // Rx
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART pins
|
||||||
|
const (
|
||||||
|
UART0_TX_PIN = GPIO0
|
||||||
|
UART0_RX_PIN = GPIO1
|
||||||
|
UART1_TX_PIN = GPIO8
|
||||||
|
UART1_RX_PIN = GPIO9
|
||||||
|
UART_TX_PIN = UART0_TX_PIN
|
||||||
|
UART_RX_PIN = UART0_RX_PIN
|
||||||
|
)
|
||||||
|
|
||||||
|
var DefaultUART = UART0
|
||||||
|
|
||||||
|
// USB identifiers
|
||||||
|
const (
|
||||||
|
usb_STRING_PRODUCT = "Pico Plus2"
|
||||||
|
usb_STRING_MANUFACTURER = "Pimoroni"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
usb_VID uint16 = 0x2E8A
|
||||||
|
usb_PID uint16 = 0x000F
|
||||||
|
)
|
||||||
@@ -64,3 +64,14 @@ type BlockDevice interface {
|
|||||||
// EraseBlockSize to map addresses to blocks.
|
// EraseBlockSize to map addresses to blocks.
|
||||||
EraseBlocks(start, len int64) error
|
EraseBlocks(start, len int64) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pad data if needed so it is long enough for correct byte alignment on writes.
|
||||||
|
func flashPad(p []byte, writeBlockSize int) []byte {
|
||||||
|
overflow := len(p) % writeBlockSize
|
||||||
|
if overflow != 0 {
|
||||||
|
for i := 0; i < writeBlockSize-overflow; i++ {
|
||||||
|
p = append(p, 0xff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"device/arm"
|
"device/arm"
|
||||||
"device/sam"
|
"device/sam"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -1917,7 +1916,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
|||||||
f.ensureInitComplete()
|
f.ensureInitComplete()
|
||||||
|
|
||||||
address := FlashDataStart() + uintptr(off)
|
address := FlashDataStart() + uintptr(off)
|
||||||
padded := f.pad(p)
|
padded := flashPad(p, int(f.WriteBlockSize()))
|
||||||
|
|
||||||
waitWhileFlashBusy()
|
waitWhileFlashBusy()
|
||||||
|
|
||||||
@@ -1992,17 +1991,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// pad data if needed so it is long enough for correct byte alignment on writes.
|
|
||||||
func (f flashBlockDevice) pad(p []byte) []byte {
|
|
||||||
overflow := int64(len(p)) % f.WriteBlockSize()
|
|
||||||
if overflow == 0 {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow))
|
|
||||||
return append(p, padding...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f flashBlockDevice) ensureInitComplete() {
|
func (f flashBlockDevice) ensureInitComplete() {
|
||||||
if f.initComplete {
|
if f.initComplete {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"device/arm"
|
"device/arm"
|
||||||
"device/sam"
|
"device/sam"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -2174,7 +2173,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
address := FlashDataStart() + uintptr(off)
|
address := FlashDataStart() + uintptr(off)
|
||||||
padded := f.pad(p)
|
padded := flashPad(p, int(f.WriteBlockSize()))
|
||||||
|
|
||||||
settings := disableFlashCache()
|
settings := disableFlashCache()
|
||||||
defer restoreFlashCache(settings)
|
defer restoreFlashCache(settings)
|
||||||
@@ -2263,17 +2262,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// pad data if needed so it is long enough for correct byte alignment on writes.
|
|
||||||
func (f flashBlockDevice) pad(p []byte) []byte {
|
|
||||||
overflow := int64(len(p)) % f.WriteBlockSize()
|
|
||||||
if overflow == 0 {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow))
|
|
||||||
return append(p, padding...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func disableFlashCache() uint16 {
|
func disableFlashCache() uint16 {
|
||||||
settings := sam.NVMCTRL.CTRLA.Get()
|
settings := sam.NVMCTRL.CTRLA.Get()
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"device/nrf"
|
"device/nrf"
|
||||||
"internal/binary"
|
"internal/binary"
|
||||||
"runtime/interrupt"
|
"runtime/interrupt"
|
||||||
@@ -386,7 +385,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
address := FlashDataStart() + uintptr(off)
|
address := FlashDataStart() + uintptr(off)
|
||||||
padded := f.pad(p)
|
padded := flashPad(p, int(f.WriteBlockSize()))
|
||||||
|
|
||||||
waitWhileFlashBusy()
|
waitWhileFlashBusy()
|
||||||
|
|
||||||
@@ -444,17 +443,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// pad data if needed so it is long enough for correct byte alignment on writes.
|
|
||||||
func (f flashBlockDevice) pad(p []byte) []byte {
|
|
||||||
overflow := int64(len(p)) % f.WriteBlockSize()
|
|
||||||
if overflow == 0 {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow))
|
|
||||||
return append(p, padding...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitWhileFlashBusy() {
|
func waitWhileFlashBusy() {
|
||||||
for nrf.NVMC.GetREADY() != nrf.NVMC_READY_READY_Ready {
|
for nrf.NVMC.GetREADY() != nrf.NVMC_READY_READY_Ready {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,12 @@ func (a *ADC) Get() uint16 {
|
|||||||
resolutionAdjustment = 4 // 12bit
|
resolutionAdjustment = 4 // 12bit
|
||||||
}
|
}
|
||||||
|
|
||||||
return rawValue.Get() << resolutionAdjustment
|
value := int16(rawValue.Get())
|
||||||
|
if value < 0 {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint16(value << resolutionAdjustment)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPI on the NRF.
|
// SPI on the NRF.
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ const (
|
|||||||
// Note: On RP2350, most spinlocks are unusable due to Errata 2
|
// Note: On RP2350, most spinlocks are unusable due to Errata 2
|
||||||
_NUMSPINLOCKS = 32
|
_NUMSPINLOCKS = 32
|
||||||
_PICO_SPINLOCK_ID_IRQ = 9
|
_PICO_SPINLOCK_ID_IRQ = 9
|
||||||
|
// is48Pin notes whether the chip is RP2040 with 32 pins or RP2350 with 48 pins.
|
||||||
|
is48Pin = _NUMBANK0_GPIOS == 48
|
||||||
)
|
)
|
||||||
|
|
||||||
// UART on the RP2040
|
// UART on the RP2040
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -101,17 +100,6 @@ func (f flashBlockDevice) EraseBlocks(start, length int64) error {
|
|||||||
return f.eraseBlocks(start, length)
|
return f.eraseBlocks(start, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pad data if needed so it is long enough for correct byte alignment on writes.
|
|
||||||
func (f flashBlockDevice) pad(p []byte) []byte {
|
|
||||||
overflow := int64(len(p)) % f.WriteBlockSize()
|
|
||||||
if overflow == 0 {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow))
|
|
||||||
return append(p, padding...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the correct address to be used for write
|
// return the correct address to be used for write
|
||||||
func writeAddress(off int64) uintptr {
|
func writeAddress(off int64) uintptr {
|
||||||
return readAddress(off) - uintptr(memoryStart)
|
return readAddress(off) - uintptr(memoryStart)
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ func (f flashBlockDevice) writeAt(p []byte, off int64) (n int, err error) {
|
|||||||
// e.g. real address 0x10003000 is written to at
|
// e.g. real address 0x10003000 is written to at
|
||||||
// 0x00003000
|
// 0x00003000
|
||||||
address := writeAddress(off)
|
address := writeAddress(off)
|
||||||
padded := f.pad(p)
|
padded := flashPad(p, int(f.WriteBlockSize()))
|
||||||
|
|
||||||
C.flash_range_write(C.uint32_t(address),
|
C.flash_range_write(C.uint32_t(address),
|
||||||
(*C.uint8_t)(unsafe.Pointer(&padded[0])),
|
(*C.uint8_t)(unsafe.Pointer(&padded[0])),
|
||||||
|
|||||||
@@ -45,6 +45,16 @@ const (
|
|||||||
PinPIO1
|
PinPIO1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Analog pins on RP2040.
|
||||||
|
const (
|
||||||
|
ADC0 Pin = GPIO26
|
||||||
|
ADC1 Pin = GPIO27
|
||||||
|
ADC2 Pin = GPIO28
|
||||||
|
ADC3 Pin = GPIO29
|
||||||
|
|
||||||
|
thermADC = 30
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
clkGPOUT0 clockIndex = iota // GPIO Muxing 0
|
clkGPOUT0 clockIndex = iota // GPIO Muxing 0
|
||||||
clkGPOUT1 // GPIO Muxing 1
|
clkGPOUT1 // GPIO Muxing 1
|
||||||
|
|||||||
@@ -126,11 +126,17 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.init()
|
p.init()
|
||||||
mask := uint32(1) << p
|
|
||||||
switch config.Mode {
|
switch config.Mode {
|
||||||
case PinOutput:
|
case PinOutput:
|
||||||
p.setFunc(fnSIO)
|
p.setFunc(fnSIO)
|
||||||
rp.SIO.GPIO_OE_SET.Set(mask)
|
if is48Pin && p >= 32 {
|
||||||
|
mask := uint32(1) << (p % 32)
|
||||||
|
rp.SIO.GPIO_HI_OE_SET.Set(mask)
|
||||||
|
} else {
|
||||||
|
mask := uint32(1) << p
|
||||||
|
rp.SIO.GPIO_OE_SET.Set(mask)
|
||||||
|
}
|
||||||
case PinInput:
|
case PinInput:
|
||||||
p.setFunc(fnSIO)
|
p.setFunc(fnSIO)
|
||||||
p.pulloff()
|
p.pulloff()
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
//go:build rp2350 && !rp2350b
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// Analog pins on RP2350a.
|
||||||
|
const (
|
||||||
|
ADC0 Pin = GPIO26
|
||||||
|
ADC1 Pin = GPIO27
|
||||||
|
ADC2 Pin = GPIO28
|
||||||
|
ADC3 Pin = GPIO29
|
||||||
|
|
||||||
|
// fifth ADC channel.
|
||||||
|
thermADC = 30
|
||||||
|
)
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
//go:build rp2350b
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// RP2350B has additional pins.
|
||||||
|
|
||||||
|
const (
|
||||||
|
GPIO30 Pin = 30 // peripherals: PWM7 channel A
|
||||||
|
GPIO31 Pin = 31 // peripherals: PWM7 channel B
|
||||||
|
GPIO32 Pin = 32 // peripherals: PWM8 channel A
|
||||||
|
GPIO33 Pin = 33 // peripherals: PWM8 channel B
|
||||||
|
GPIO34 Pin = 34 // peripherals: PWM9 channel A
|
||||||
|
GPIO35 Pin = 35 // peripherals: PWM9 channel B
|
||||||
|
GPIO36 Pin = 36 // peripherals: PWM10 channel A
|
||||||
|
GPIO37 Pin = 37 // peripherals: PWM10 channel B
|
||||||
|
GPIO38 Pin = 38 // peripherals: PWM11 channel A
|
||||||
|
GPIO39 Pin = 39 // peripherals: PWM11 channel B
|
||||||
|
GPIO40 Pin = 40 // peripherals: PWM8 channel A
|
||||||
|
GPIO41 Pin = 41 // peripherals: PWM8 channel B
|
||||||
|
GPIO42 Pin = 42 // peripherals: PWM9 channel A
|
||||||
|
GPIO43 Pin = 43 // peripherals: PWM9 channel B
|
||||||
|
GPIO44 Pin = 44 // peripherals: PWM10 channel A
|
||||||
|
GPIO45 Pin = 45 // peripherals: PWM10 channel B
|
||||||
|
GPIO46 Pin = 46 // peripherals: PWM11 channel A
|
||||||
|
GPIO47 Pin = 47 // peripherals: PWM11 channel B
|
||||||
|
)
|
||||||
|
|
||||||
|
// Analog pins on 2350b.
|
||||||
|
const (
|
||||||
|
ADC0 Pin = GPIO40
|
||||||
|
ADC1 Pin = GPIO41
|
||||||
|
ADC2 Pin = GPIO42
|
||||||
|
ADC3 Pin = GPIO43
|
||||||
|
ADC4 Pin = GPIO44
|
||||||
|
ADC5 Pin = GPIO45
|
||||||
|
ADC6 Pin = GPIO46
|
||||||
|
ADC7 Pin = GPIO47
|
||||||
|
// Ninth ADC channel.
|
||||||
|
thermADC = 48
|
||||||
|
)
|
||||||
|
|
||||||
|
// Additional PWMs on the RP2350B.
|
||||||
|
var (
|
||||||
|
PWM8 = getPWMGroup(8)
|
||||||
|
PWM9 = getPWMGroup(9)
|
||||||
|
PWM10 = getPWMGroup(10)
|
||||||
|
PWM11 = getPWMGroup(11)
|
||||||
|
)
|
||||||
@@ -11,15 +11,6 @@ import (
|
|||||||
// ADCChannel is the ADC peripheral mux channel. 0-4.
|
// ADCChannel is the ADC peripheral mux channel. 0-4.
|
||||||
type ADCChannel uint8
|
type ADCChannel uint8
|
||||||
|
|
||||||
// ADC channels. Only ADC_TEMP_SENSOR is public. The other channels are accessed via Machine.ADC objects
|
|
||||||
const (
|
|
||||||
adc0_CH ADCChannel = iota
|
|
||||||
adc1_CH
|
|
||||||
adc2_CH
|
|
||||||
adc3_CH // Note: GPIO29 not broken out on pico board
|
|
||||||
adcTempSensor // Internal temperature sensor channel
|
|
||||||
)
|
|
||||||
|
|
||||||
// Used to serialise ADC sampling
|
// Used to serialise ADC sampling
|
||||||
var adcLock sync.Mutex
|
var adcLock sync.Mutex
|
||||||
|
|
||||||
@@ -58,20 +49,10 @@ func (a ADC) Get() uint16 {
|
|||||||
|
|
||||||
// GetADCChannel returns the channel associated with the ADC pin.
|
// GetADCChannel returns the channel associated with the ADC pin.
|
||||||
func (a ADC) GetADCChannel() (c ADCChannel, err error) {
|
func (a ADC) GetADCChannel() (c ADCChannel, err error) {
|
||||||
err = nil
|
if a.Pin < ADC0 {
|
||||||
switch a.Pin {
|
return 0, errors.New("no ADC channel for pin value")
|
||||||
case ADC0:
|
|
||||||
c = adc0_CH
|
|
||||||
case ADC1:
|
|
||||||
c = adc1_CH
|
|
||||||
case ADC2:
|
|
||||||
c = adc2_CH
|
|
||||||
case ADC3:
|
|
||||||
c = adc3_CH
|
|
||||||
default:
|
|
||||||
err = errors.New("no ADC channel for pin value")
|
|
||||||
}
|
}
|
||||||
return c, err
|
return ADCChannel(a.Pin - ADC0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure sets the channel's associated pin to analog input mode.
|
// Configure sets the channel's associated pin to analog input mode.
|
||||||
@@ -113,12 +94,12 @@ func ReadTemperature() (millicelsius int32) {
|
|||||||
if rp.ADC.CS.Get()&rp.ADC_CS_EN == 0 {
|
if rp.ADC.CS.Get()&rp.ADC_CS_EN == 0 {
|
||||||
InitADC()
|
InitADC()
|
||||||
}
|
}
|
||||||
|
thermChan, _ := ADC{Pin: thermADC}.GetADCChannel()
|
||||||
// Enable temperature sensor bias source
|
// Enable temperature sensor bias source
|
||||||
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
||||||
|
|
||||||
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
||||||
return (27000<<16 - (int32(adcTempSensor.getVoltage())-706<<16)*581) >> 16
|
return (27000<<16 - (int32(thermChan.getVoltage())-706<<16)*581) >> 16
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForReady spins waiting for the ADC peripheral to become ready.
|
// waitForReady spins waiting for the ADC peripheral to become ready.
|
||||||
@@ -129,18 +110,5 @@ func waitForReady() {
|
|||||||
|
|
||||||
// The Pin method returns the GPIO Pin associated with the ADC mux channel, if it has one.
|
// The Pin method returns the GPIO Pin associated with the ADC mux channel, if it has one.
|
||||||
func (c ADCChannel) Pin() (p Pin, err error) {
|
func (c ADCChannel) Pin() (p Pin, err error) {
|
||||||
err = nil
|
return Pin(c) + ADC0, nil
|
||||||
switch c {
|
|
||||||
case adc0_CH:
|
|
||||||
p = ADC0
|
|
||||||
case adc1_CH:
|
|
||||||
p = ADC1
|
|
||||||
case adc2_CH:
|
|
||||||
p = ADC2
|
|
||||||
case adc3_CH:
|
|
||||||
p = ADC3
|
|
||||||
default:
|
|
||||||
err = errors.New("no associated pin for channel")
|
|
||||||
}
|
|
||||||
return p, err
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,6 @@ func CPUFrequency() uint32 {
|
|||||||
return 125 * MHz
|
return 125 * MHz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the period of a clock cycle for the raspberry pi pico in nanoseconds.
|
|
||||||
// Used in PWM API.
|
|
||||||
func cpuPeriod() uint32 {
|
|
||||||
return 1e9 / CPUFrequency()
|
|
||||||
}
|
|
||||||
|
|
||||||
// clockIndex identifies a hardware clock
|
// clockIndex identifies a hardware clock
|
||||||
type clockIndex uint8
|
type clockIndex uint8
|
||||||
|
|
||||||
@@ -143,6 +137,8 @@ func (clk *clock) configure(src, auxsrc, srcFreq, freq uint32) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pllsysFB, pllsysPD1, pllsysPD2 uint32 = 125, 6, 2 // RP2040 running 125MHz with 1500MHz VCO.
|
||||||
|
|
||||||
// init initializes the clock hardware.
|
// init initializes the clock hardware.
|
||||||
//
|
//
|
||||||
// Must be called before any other clock function.
|
// Must be called before any other clock function.
|
||||||
@@ -169,8 +165,8 @@ func (clks *clocksType) init() {
|
|||||||
// REF FBDIV VCO POSTDIV
|
// REF FBDIV VCO POSTDIV
|
||||||
// pllSys: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
|
// pllSys: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
|
||||||
// pllUSB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz
|
// pllUSB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz
|
||||||
pllSys.init(1, 1500*MHz, 6, 2)
|
pllSys.init(1, uint32(pllsysFB), uint32(pllsysPD1), uint32(pllsysPD2))
|
||||||
pllUSB.init(1, 480*MHz, 5, 2)
|
pllUSB.init(1, 40, 5, 2)
|
||||||
|
|
||||||
// Configure clocks
|
// Configure clocks
|
||||||
// clkRef = xosc (12MHz) / 1 = 12MHz
|
// clkRef = xosc (12MHz) / 1 = 12MHz
|
||||||
|
|||||||
@@ -63,8 +63,13 @@ func (p Pin) PortMaskSet() (*uint32, uint32) {
|
|||||||
|
|
||||||
// set drives the pin high
|
// set drives the pin high
|
||||||
func (p Pin) set() {
|
func (p Pin) set() {
|
||||||
mask := uint32(1) << p
|
if is48Pin && p >= 32 {
|
||||||
rp.SIO.GPIO_OUT_SET.Set(mask)
|
mask := uint32(1) << (p % 32)
|
||||||
|
rp.SIO.GPIO_HI_OUT_SET.Set(mask)
|
||||||
|
} else {
|
||||||
|
mask := uint32(1) << p
|
||||||
|
rp.SIO.GPIO_OUT_SET.Set(mask)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Pin) PortMaskClear() (*uint32, uint32) {
|
func (p Pin) PortMaskClear() (*uint32, uint32) {
|
||||||
@@ -73,18 +78,31 @@ func (p Pin) PortMaskClear() (*uint32, uint32) {
|
|||||||
|
|
||||||
// clr drives the pin low
|
// clr drives the pin low
|
||||||
func (p Pin) clr() {
|
func (p Pin) clr() {
|
||||||
mask := uint32(1) << p
|
if is48Pin && p >= 32 {
|
||||||
rp.SIO.GPIO_OUT_CLR.Set(mask)
|
mask := uint32(1) << (p % 32)
|
||||||
|
rp.SIO.GPIO_HI_OUT_CLR.Set(mask)
|
||||||
|
} else {
|
||||||
|
mask := uint32(1) << p
|
||||||
|
rp.SIO.GPIO_OUT_CLR.Set(mask)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// xor toggles the pin
|
// xor toggles the pin
|
||||||
func (p Pin) xor() {
|
func (p Pin) xor() {
|
||||||
mask := uint32(1) << p
|
if is48Pin && p >= 32 {
|
||||||
rp.SIO.GPIO_OUT_XOR.Set(mask)
|
mask := uint32(1) << (p % 32)
|
||||||
|
rp.SIO.GPIO_HI_OUT_XOR.Set(mask)
|
||||||
|
} else {
|
||||||
|
mask := uint32(1) << p
|
||||||
|
rp.SIO.GPIO_OUT_XOR.Set(mask)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get returns the pin value
|
// get returns the pin value
|
||||||
func (p Pin) get() bool {
|
func (p Pin) get() bool {
|
||||||
|
if is48Pin && p >= 32 {
|
||||||
|
return rp.SIO.GPIO_HI_IN.HasBits(1 << (p % 32))
|
||||||
|
}
|
||||||
return rp.SIO.GPIO_IN.HasBits(1 << p)
|
return rp.SIO.GPIO_IN.HasBits(1 << p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,8 +152,13 @@ func (p Pin) setFunc(fn pinFunc) {
|
|||||||
|
|
||||||
// init initializes the gpio pin
|
// init initializes the gpio pin
|
||||||
func (p Pin) init() {
|
func (p Pin) init() {
|
||||||
mask := uint32(1) << p
|
if is48Pin && p >= 32 {
|
||||||
rp.SIO.GPIO_OE_CLR.Set(mask)
|
mask := uint32(1) << (p % 32)
|
||||||
|
rp.SIO.GPIO_HI_OE_CLR.Set(mask)
|
||||||
|
} else {
|
||||||
|
mask := uint32(1) << p
|
||||||
|
rp.SIO.GPIO_OE_CLR.Set(mask)
|
||||||
|
}
|
||||||
p.clr()
|
p.clr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build rp2040 || rp2350 || ae_rp2040 || badger2040 || challenger_rp2040 || feather_rp2040 || gopher_badge || kb2040 || macropad_rp2040 || nano_rp2040 || pico || qtpy_rp2040 || thingplus_rp2040 || thumby || tufty2040 || waveshare_rp2040_zero || xiao_rp2040
|
//go:build rp2040 || rp2350 || gopher_badge
|
||||||
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
@@ -34,10 +34,4 @@ const (
|
|||||||
GPIO27 Pin = 27 // peripherals: PWM5 channel B
|
GPIO27 Pin = 27 // peripherals: PWM5 channel B
|
||||||
GPIO28 Pin = 28 // peripherals: PWM6 channel A
|
GPIO28 Pin = 28 // peripherals: PWM6 channel A
|
||||||
GPIO29 Pin = 29 // peripherals: PWM6 channel B
|
GPIO29 Pin = 29 // peripherals: PWM6 channel B
|
||||||
|
|
||||||
// Analog pins
|
|
||||||
ADC0 Pin = GPIO26
|
|
||||||
ADC1 Pin = GPIO27
|
|
||||||
ADC2 Pin = GPIO28
|
|
||||||
ADC3 Pin = GPIO29
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ package machine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"device/rp"
|
"device/rp"
|
||||||
|
"errors"
|
||||||
|
"math"
|
||||||
|
"math/bits"
|
||||||
"runtime/volatile"
|
"runtime/volatile"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@@ -29,12 +32,11 @@ var (
|
|||||||
// Post Divider 1, postDiv1 with range 1-7 and be >= postDiv2.
|
// Post Divider 1, postDiv1 with range 1-7 and be >= postDiv2.
|
||||||
//
|
//
|
||||||
// Post Divider 2, postDiv2 with range 1-7.
|
// Post Divider 2, postDiv2 with range 1-7.
|
||||||
func (pll *pll) init(refdiv, vcoFreq, postDiv1, postDiv2 uint32) {
|
func (pll *pll) init(refdiv, fbdiv, postDiv1, postDiv2 uint32) {
|
||||||
refFreq := xoscFreq / refdiv
|
refFreq := xoscFreq / refdiv
|
||||||
|
|
||||||
// What are we multiplying the reference clock by to get the vco freq
|
// What are we multiplying the reference clock by to get the vco freq
|
||||||
// (The regs are called div, because you divide the vco output and compare it to the refclk)
|
// (The regs are called div, because you divide the vco output and compare it to the refclk)
|
||||||
fbdiv := vcoFreq / (refFreq * MHz)
|
|
||||||
|
|
||||||
// Check fbdiv range
|
// Check fbdiv range
|
||||||
if !(fbdiv >= 16 && fbdiv <= 320) {
|
if !(fbdiv >= 16 && fbdiv <= 320) {
|
||||||
@@ -54,13 +56,14 @@ func (pll *pll) init(refdiv, vcoFreq, postDiv1, postDiv2 uint32) {
|
|||||||
panic("postdiv1 should be greater than or equal to postdiv2")
|
panic("postdiv1 should be greater than or equal to postdiv2")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that reference frequency is no greater than vco / 16
|
// Check that reference frequency is no greater than vcoFreq / 16
|
||||||
|
vcoFreq := calcVCO(xoscFreq, fbdiv, refdiv)
|
||||||
if refFreq > vcoFreq/16 {
|
if refFreq > vcoFreq/16 {
|
||||||
panic("reference frequency should not be greater than vco frequency divided by 16")
|
panic("reference frequency should not be greater than vco frequency divided by 16")
|
||||||
}
|
}
|
||||||
|
|
||||||
// div1 feeds into div2 so if div1 is 5 and div2 is 2 then you get a divide by 10
|
// div1 feeds into div2 so if div1 is 5 and div2 is 2 then you get a divide by 10
|
||||||
pdiv := postDiv1<<rp.PLL_SYS_PRIM_POSTDIV1_Pos | postDiv2<<rp.PLL_SYS_PRIM_POSTDIV2_Pos
|
pdiv := uint32(postDiv1)<<rp.PLL_SYS_PRIM_POSTDIV1_Pos | uint32(postDiv2)<<rp.PLL_SYS_PRIM_POSTDIV2_Pos
|
||||||
|
|
||||||
if pll.cs.HasBits(rp.PLL_SYS_CS_LOCK) &&
|
if pll.cs.HasBits(rp.PLL_SYS_CS_LOCK) &&
|
||||||
refdiv == pll.cs.Get()&rp.PLL_SYS_CS_REFDIV_Msk &&
|
refdiv == pll.cs.Get()&rp.PLL_SYS_CS_REFDIV_Msk &&
|
||||||
@@ -98,3 +101,179 @@ func (pll *pll) init(refdiv, vcoFreq, postDiv1, postDiv2 uint32) {
|
|||||||
pll.pwr.ClearBits(rp.PLL_SYS_PWR_POSTDIVPD)
|
pll.pwr.ClearBits(rp.PLL_SYS_PWR_POSTDIVPD)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errVCOOverflow = errors.New("VCO calculation overflow; use lower MHz")
|
||||||
|
|
||||||
|
// pllSearch enables searching for a good PLL configuration.
|
||||||
|
// Example for 12MHz crystal and RP2040:
|
||||||
|
//
|
||||||
|
// fbdiv, refdiv, pd1, pd2, _ := pllSearch{LockRefDiv:1}.CalcDivs(12*MHz, 125*MHz, MHz)
|
||||||
|
//
|
||||||
|
// Example for 12MHz crystal and RP2350:
|
||||||
|
//
|
||||||
|
// fbdiv, refdiv, pd1, pd2, _ := pllSearch{LockRefDiv:1}.CalcDivs(12*MHz, 133*MHz, MHz)
|
||||||
|
type pllSearch struct {
|
||||||
|
LowerVCO bool
|
||||||
|
LockRefDiv uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps pllSearch) CalcDivs(xoscRef, targetFreq, MHz uint64) (fbdiv uint64, refdiv, pd1, pd2 uint8, err error) {
|
||||||
|
genTable()
|
||||||
|
var bestFreq, bestFbdiv uint64
|
||||||
|
var bestRefdiv, bestpd1, bestpd2 uint8
|
||||||
|
maxVCO, minVCO := 1600*MHz, 750*MHz
|
||||||
|
var bestMargin int64 = int64(maxVCO)
|
||||||
|
iters := 0
|
||||||
|
for refdiv = 1; refdiv < 64; refdiv++ {
|
||||||
|
if ps.LockRefDiv != 0 && refdiv != ps.LockRefDiv {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
firstFBDiv := minVCO * uint64(refdiv) / xoscRef
|
||||||
|
for fbdiv = firstFBDiv; fbdiv < 321; fbdiv++ {
|
||||||
|
overflow, vco := bits.Mul64(xoscRef, fbdiv)
|
||||||
|
vco /= uint64(refdiv)
|
||||||
|
if overflow != 0 {
|
||||||
|
return fbdiv, refdiv, pd1, pd2, errVCOOverflow
|
||||||
|
} else if vco > maxVCO {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
calcPD12 := vco / targetFreq
|
||||||
|
if calcPD12 < 1 {
|
||||||
|
calcPD12 = 1
|
||||||
|
} else if calcPD12 > 49 {
|
||||||
|
calcPD12 = 49
|
||||||
|
}
|
||||||
|
iters++
|
||||||
|
pd1 = pdTable[calcPD12].hivco[0]
|
||||||
|
pd2 = pdTable[calcPD12].hivco[1]
|
||||||
|
fout, err := pllFreqOutPostdiv(xoscRef, fbdiv, MHz, refdiv, pd1, pd2)
|
||||||
|
found := false
|
||||||
|
margin := abs(int64(fout) - int64(targetFreq))
|
||||||
|
if err == nil && margin <= bestMargin {
|
||||||
|
found = true
|
||||||
|
bestFreq = fout
|
||||||
|
bestFbdiv = fbdiv
|
||||||
|
bestpd1 = pd1
|
||||||
|
bestpd2 = pd2
|
||||||
|
bestRefdiv = refdiv
|
||||||
|
bestMargin = margin
|
||||||
|
}
|
||||||
|
pd1 = pdTable[calcPD12].lovco[0]
|
||||||
|
pd2 = pdTable[calcPD12].lovco[1]
|
||||||
|
fout, err = pllFreqOutPostdiv(xoscRef, fbdiv, MHz, refdiv, pd1, pd2)
|
||||||
|
margin = abs(int64(fout) - int64(targetFreq))
|
||||||
|
if err == nil && margin <= bestMargin {
|
||||||
|
found = true
|
||||||
|
bestFreq = fout
|
||||||
|
bestFbdiv = fbdiv
|
||||||
|
bestpd1 = pd1
|
||||||
|
bestpd2 = pd2
|
||||||
|
bestRefdiv = refdiv
|
||||||
|
bestMargin = margin
|
||||||
|
}
|
||||||
|
if found && ps.LowerVCO {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bestFreq == 0 {
|
||||||
|
return fbdiv, refdiv, pd1, pd2, errors.New("no best frequency found")
|
||||||
|
}
|
||||||
|
return bestFbdiv, bestRefdiv, bestpd1, bestpd2, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func abs(a int64) int64 {
|
||||||
|
if a == math.MinInt64 {
|
||||||
|
return math.MaxInt64
|
||||||
|
} else if a < 0 {
|
||||||
|
return -a
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func pllFreqOutPostdiv(xosc, fbdiv, MHz uint64, refdiv, postdiv1, postdiv2 uint8) (foutpostdiv uint64, err error) {
|
||||||
|
// testing grounds.
|
||||||
|
const (
|
||||||
|
mhz = 1
|
||||||
|
cfref = 12 * mhz // given by crystal oscillator selection.
|
||||||
|
crefd = 1
|
||||||
|
cfbdiv = 100
|
||||||
|
cvco = cfref * cfbdiv / crefd
|
||||||
|
cpd1 = 6
|
||||||
|
cpd2 = 2
|
||||||
|
foutpd = (cfref / crefd) * cfbdiv / (cpd1 * cpd2)
|
||||||
|
)
|
||||||
|
refFreq := xosc / uint64(refdiv)
|
||||||
|
overflow, vco := bits.Mul64(xosc, fbdiv)
|
||||||
|
vco /= uint64(refdiv)
|
||||||
|
foutpostdiv = vco / uint64(postdiv1*postdiv2)
|
||||||
|
switch {
|
||||||
|
case refdiv < 1 || refdiv > 63:
|
||||||
|
err = errors.New("reference divider out of range")
|
||||||
|
case fbdiv < 16 || fbdiv > 320:
|
||||||
|
err = errors.New("feedback divider out of range")
|
||||||
|
case postdiv1 < 1 || postdiv1 > 7:
|
||||||
|
err = errors.New("postdiv1 out of range")
|
||||||
|
case postdiv2 < 1 || postdiv2 > 7:
|
||||||
|
err = errors.New("postdiv2 out of range")
|
||||||
|
case postdiv1 < postdiv2:
|
||||||
|
err = errors.New("user error: use higher value for postdiv1 for lower power consumption")
|
||||||
|
case vco < 750*MHz || vco > 1600*MHz:
|
||||||
|
err = errors.New("VCO out of range")
|
||||||
|
case refFreq < 5*MHz:
|
||||||
|
err = errors.New("minimum reference frequency breach")
|
||||||
|
case refFreq > vco/16:
|
||||||
|
err = errors.New("maximum reference frequency breach")
|
||||||
|
case vco > 1200*MHz && vco < 1600*MHz && xosc < 75*MHz && refdiv != 1:
|
||||||
|
err = errors.New("refdiv should be 1 for given VCO and reference frequency")
|
||||||
|
case overflow != 0:
|
||||||
|
err = errVCOOverflow
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return foutpostdiv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcVCO(xoscFreq, fbdiv, refdiv uint32) uint32 {
|
||||||
|
const maxXoscMHz = math.MaxUint32 / 320 / MHz // 13MHz maximum xosc apparently.
|
||||||
|
if fbdiv > 320 || xoscFreq > math.MaxUint32/320 {
|
||||||
|
panic("invalid VCO calculation args")
|
||||||
|
}
|
||||||
|
return xoscFreq * fbdiv / refdiv
|
||||||
|
}
|
||||||
|
|
||||||
|
var pdTable = [50]struct {
|
||||||
|
hivco [2]uint8
|
||||||
|
lovco [2]uint8
|
||||||
|
}{}
|
||||||
|
|
||||||
|
func genTable() {
|
||||||
|
if pdTable[1].hivco[1] != 0 {
|
||||||
|
return // Already generated.
|
||||||
|
}
|
||||||
|
for product := 1; product < len(pdTable); product++ {
|
||||||
|
bestProdhi := 255
|
||||||
|
bestProdlo := 255
|
||||||
|
for pd1 := 7; pd1 > 0; pd1-- {
|
||||||
|
for pd2 := pd1; pd2 > 0; pd2-- {
|
||||||
|
gotprod := pd1 * pd2
|
||||||
|
if abs(int64(gotprod-product)) < abs(int64(bestProdlo-product)) {
|
||||||
|
bestProdlo = gotprod
|
||||||
|
pdTable[product].lovco[0] = uint8(pd1)
|
||||||
|
pdTable[product].lovco[1] = uint8(pd2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for pd1 := 1; pd1 < 8; pd1++ {
|
||||||
|
for pd2 := 1; pd2 <= pd1; pd2++ {
|
||||||
|
gotprod := pd1 * pd2
|
||||||
|
if abs(int64(gotprod-product)) < abs(int64(bestProdhi-product)) {
|
||||||
|
bestProdhi = gotprod
|
||||||
|
pdTable[product].hivco[0] = uint8(pd1)
|
||||||
|
pdTable[product].hivco[1] = uint8(pd2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build rp2040
|
//go:build rp2040 || rp2350
|
||||||
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxPWMPins = 29
|
maxPWMPins = _NUMBANK0_GPIOS - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// pwmGroup is one PWM peripheral, which consists of a counter and two output
|
// pwmGroup is one PWM peripheral, which consists of a counter and two output
|
||||||
@@ -146,12 +146,14 @@ func (p *pwmGroup) Counter() uint32 {
|
|||||||
|
|
||||||
// Period returns the used PWM period in nanoseconds.
|
// Period returns the used PWM period in nanoseconds.
|
||||||
func (p *pwmGroup) Period() uint64 {
|
func (p *pwmGroup) Period() uint64 {
|
||||||
periodPerCycle := cpuPeriod()
|
// Lines below can overflow if operations done without care.
|
||||||
|
// maxInt=255, maxFrac=15, maxTop=65536, maxPHC=1 => maxProduct= (16*255+15) * (65536*2*1e9) = 5.3673e17 < MaxUint64=1.8e19 (close call.)
|
||||||
|
const compileTimeCheckPeriod uint64 = (255*16 + 15) * (65535 + 1) * 2 * 1e9
|
||||||
|
freq := uint64(CPUFrequency())
|
||||||
top := p.getWrap()
|
top := p.getWrap()
|
||||||
phc := p.getPhaseCorrect()
|
phc := p.getPhaseCorrect()
|
||||||
Int, frac := p.getClockDiv()
|
Int, frac := p.getClockDiv()
|
||||||
// Line below can overflow if operations done without care.
|
return (16*uint64(Int) + uint64(frac)) * uint64((top+1)*(phc+1)*1e9) / (16 * freq) // cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
||||||
return (16*uint64(Int) + uint64(frac)) * uint64((top+1)*(phc+1)*periodPerCycle) / 16 // cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetInverting sets whether to invert the output of this channel.
|
// SetInverting sets whether to invert the output of this channel.
|
||||||
@@ -266,6 +268,9 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
|
|||||||
// Maximum Period is 268369920ns on rp2040, given by (16*255+15)*8*(1+0xffff)*(1+1)/16
|
// Maximum Period is 268369920ns on rp2040, given by (16*255+15)*8*(1+0xffff)*(1+1)/16
|
||||||
// With no phase shift max period is half of this value.
|
// With no phase shift max period is half of this value.
|
||||||
maxPeriod = 268 * milliseconds
|
maxPeriod = 268 * milliseconds
|
||||||
|
// This will be a compile time error if this method is at risk of overflowing. cpufreq=155MHz for typical RP2350.
|
||||||
|
maxCPUFreq = 4 * GHz // Can go up to 4GHz without overflowing :)
|
||||||
|
compileTimeCheckSetPeriod uint64 = 16 * maxPeriod * maxCPUFreq
|
||||||
)
|
)
|
||||||
|
|
||||||
if period > maxPeriod || period < 8 {
|
if period > maxPeriod || period < 8 {
|
||||||
@@ -279,11 +284,13 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
|
|||||||
// DIV_INT + DIV_FRAC/16 = cycles / ( (TOP+1) * (CSRPHCorrect+1) ) // DIV_FRAC/16 is always 0 in this equation
|
// DIV_INT + DIV_FRAC/16 = cycles / ( (TOP+1) * (CSRPHCorrect+1) ) // DIV_FRAC/16 is always 0 in this equation
|
||||||
// where cycles must be converted to time:
|
// where cycles must be converted to time:
|
||||||
// target_period = cycles * period_per_cycle ==> cycles = target_period/period_per_cycle
|
// target_period = cycles * period_per_cycle ==> cycles = target_period/period_per_cycle
|
||||||
periodPerCycle := uint64(cpuPeriod())
|
var (
|
||||||
phc := uint64(pwm.getPhaseCorrect())
|
freq = uint64(CPUFrequency())
|
||||||
rhs := 16 * period / ((1 + phc) * periodPerCycle * (1 + topStart)) // right-hand-side of equation, scaled so frac is not divided
|
phc = uint64(pwm.getPhaseCorrect())
|
||||||
whole := rhs / 16
|
rhs = 16 * period * freq / ((1 + phc) * 1e9 * (1 + topStart)) // right-hand-side of equation, scaled so frac is not divided
|
||||||
frac := rhs % 16
|
whole = rhs / 16
|
||||||
|
frac = rhs % 16
|
||||||
|
)
|
||||||
switch {
|
switch {
|
||||||
case whole > 0xff:
|
case whole > 0xff:
|
||||||
whole = 0xff
|
whole = 0xff
|
||||||
@@ -296,7 +303,7 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
|
|||||||
|
|
||||||
// Step 2 is acquiring a better top value. Clearing the equation:
|
// Step 2 is acquiring a better top value. Clearing the equation:
|
||||||
// TOP = cycles / ( (DIVINT+DIVFRAC/16) * (CSRPHCorrect+1) ) - 1
|
// TOP = cycles / ( (DIVINT+DIVFRAC/16) * (CSRPHCorrect+1) ) - 1
|
||||||
top := 16*period/((16*whole+frac)*periodPerCycle*(1+phc)) - 1
|
top := 16*period*freq/((1+phc)*1e9*(16*whole+frac)) - 1
|
||||||
if top > maxTop {
|
if top > maxTop {
|
||||||
top = maxTop
|
top = maxTop
|
||||||
}
|
}
|
||||||
@@ -400,6 +407,9 @@ func (pwm *pwmGroup) getClockDiv() (Int, frac uint8) {
|
|||||||
// pwmGPIOToSlice Determine the PWM channel that is attached to the specified GPIO.
|
// pwmGPIOToSlice Determine the PWM channel that is attached to the specified GPIO.
|
||||||
// gpio must be less than 30. Returns the PWM slice number that controls the specified GPIO.
|
// gpio must be less than 30. Returns the PWM slice number that controls the specified GPIO.
|
||||||
func pwmGPIOToSlice(gpio Pin) (slicenum uint8) {
|
func pwmGPIOToSlice(gpio Pin) (slicenum uint8) {
|
||||||
|
if is48Pin && gpio >= 32 {
|
||||||
|
return uint8(8 + ((gpio-32)/2)%4)
|
||||||
|
}
|
||||||
return (uint8(gpio) >> 1) & 7
|
return (uint8(gpio) >> 1) & 7
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5,7 +5,6 @@ package machine
|
|||||||
import (
|
import (
|
||||||
"device/stm32"
|
"device/stm32"
|
||||||
|
|
||||||
"bytes"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,7 +40,8 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
|||||||
unlockFlash()
|
unlockFlash()
|
||||||
defer lockFlash()
|
defer lockFlash()
|
||||||
|
|
||||||
return writeFlashData(FlashDataStart()+uintptr(off), f.pad(p))
|
p = flashPad(p, int(f.WriteBlockSize()))
|
||||||
|
return writeFlashData(FlashDataStart()+uintptr(off), p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the number of bytes in this block device.
|
// Size returns the number of bytes in this block device.
|
||||||
@@ -90,17 +90,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// pad data if needed so it is long enough for correct byte alignment on writes.
|
|
||||||
func (f flashBlockDevice) pad(p []byte) []byte {
|
|
||||||
overflow := int64(len(p)) % f.WriteBlockSize()
|
|
||||||
if overflow == 0 {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow))
|
|
||||||
return append(p, padding...)
|
|
||||||
}
|
|
||||||
|
|
||||||
const memoryStart = 0x08000000
|
const memoryStart = 0x08000000
|
||||||
|
|
||||||
func unlockFlash() {
|
func unlockFlash() {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package descriptor
|
package descriptor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"internal/binary"
|
"internal/binary"
|
||||||
|
"internal/bytealg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var configurationCDCHID = [configurationTypeLen]byte{
|
var configurationCDCHID = [configurationTypeLen]byte{
|
||||||
@@ -87,7 +87,7 @@ func FindClassHIDType(des, class []byte) (ClassHIDType, error) {
|
|||||||
|
|
||||||
// search only for ClassHIDType without the ClassLength,
|
// search only for ClassHIDType without the ClassLength,
|
||||||
// in case it has already been set.
|
// in case it has already been set.
|
||||||
idx := bytes.Index(des, class[:ClassHIDTypeLen-2])
|
idx := bytealg.Index(des, class[:ClassHIDTypeLen-2])
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
return ClassHIDType{}, errNoClassHIDFound
|
return ClassHIDType{}, errNoClassHIDFound
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
Submodule src/net updated: a237059610...ca7cd08f85
@@ -307,6 +307,28 @@ func (f *File) Sync() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chmod changes the mode of the file to mode. If there is an error, it will be
|
||||||
|
// of type *PathError.
|
||||||
|
func (f *File) Chmod(mode FileMode) (err error) {
|
||||||
|
if f.handle == nil {
|
||||||
|
err = ErrClosed
|
||||||
|
} else {
|
||||||
|
err = f.chmod(mode)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chdir changes the current working directory to the file, which must be a
|
||||||
|
// directory. If there is an error, it will be of type *PathError.
|
||||||
|
func (f *File) Chdir() (err error) {
|
||||||
|
if f.handle == nil {
|
||||||
|
err = ErrClosed
|
||||||
|
} else {
|
||||||
|
err = f.chdir()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// LinkError records an error during a link or symlink or rename system call and
|
// LinkError records an error during a link or symlink or rename system call and
|
||||||
// the paths that caused it.
|
// the paths that caused it.
|
||||||
type LinkError struct {
|
type LinkError struct {
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ func NewFile(fd uintptr, name string) *File {
|
|||||||
return &File{&file{handle: stdioFileHandle(fd), name: name}}
|
return &File{&file{handle: stdioFileHandle(fd), name: name}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chdir changes the current working directory to the named directory.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
func Chdir(dir string) error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// Rename renames (moves) oldpath to newpath.
|
// Rename renames (moves) oldpath to newpath.
|
||||||
// If newpath already exists and is not a directory, Rename replaces it.
|
// If newpath already exists and is not a directory, Rename replaces it.
|
||||||
// OS-specific restrictions may apply when oldpath and newpath are in different directories.
|
// OS-specific restrictions may apply when oldpath and newpath are in different directories.
|
||||||
@@ -149,3 +155,11 @@ func (f *File) Truncate(size int64) (err error) {
|
|||||||
|
|
||||||
return Truncate(f.name, size)
|
return Truncate(f.name, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *File) chmod(mode FileMode) error {
|
||||||
|
return ErrUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) chdir() error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|||||||
@@ -151,6 +151,37 @@ func (f *File) Truncate(size int64) (err error) {
|
|||||||
return Truncate(f.name, size)
|
return Truncate(f.name, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *File) chmod(mode FileMode) error {
|
||||||
|
if f.handle == nil {
|
||||||
|
return ErrClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
longName := fixLongPath(f.name)
|
||||||
|
e := ignoringEINTR(func() error {
|
||||||
|
return syscall.Chmod(longName, syscallMode(mode))
|
||||||
|
})
|
||||||
|
if e != nil {
|
||||||
|
return &PathError{Op: "chmod", Path: f.name, Err: e}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) chdir() error {
|
||||||
|
if f.handle == nil {
|
||||||
|
return ErrClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use syscall.Fchdir instead
|
||||||
|
longName := fixLongPath(f.name)
|
||||||
|
e := ignoringEINTR(func() error {
|
||||||
|
return syscall.Chdir(longName)
|
||||||
|
})
|
||||||
|
if e != nil {
|
||||||
|
return &PathError{Op: "chdir", Path: f.name, Err: e}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ReadAt reads up to len(b) bytes from the File starting at the given absolute offset.
|
// ReadAt reads up to len(b) bytes from the File starting at the given absolute offset.
|
||||||
// It returns the number of bytes read and any error encountered, possibly io.EOF.
|
// It returns the number of bytes read and any error encountered, possibly io.EOF.
|
||||||
// At end of file, Pread returns 0, io.EOF.
|
// At end of file, Pread returns 0, io.EOF.
|
||||||
|
|||||||
@@ -142,3 +142,11 @@ func isWindowsNulName(name string) bool {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *File) chmod(mode FileMode) error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) chdir() error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|||||||
@@ -271,6 +271,10 @@ func (v Value) Comparable() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Value) Equal(u Value) bool {
|
||||||
|
panic("unimplemented: reflect.Value.Equal")
|
||||||
|
}
|
||||||
|
|
||||||
func (v Value) Addr() Value {
|
func (v Value) Addr() Value {
|
||||||
if !v.CanAddr() {
|
if !v.CanAddr() {
|
||||||
panic("reflect.Value.Addr of unaddressable value")
|
panic("reflect.Value.Addr of unaddressable value")
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ func fastrand() uint32 {
|
|||||||
return xorshift32State
|
return xorshift32State
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func initRand() {
|
||||||
r, _ := hardwareRand()
|
r, _ := hardwareRand()
|
||||||
xorshift64State = uint64(r | 1) // protect against 0
|
xorshift64State = uint64(r | 1) // protect against 0
|
||||||
xorshift32State = uint32(xorshift64State)
|
xorshift32State = uint32(xorshift64State)
|
||||||
}
|
}
|
||||||
|
|
||||||
var xorshift32State uint32
|
var xorshift32State uint32 = 1
|
||||||
|
|
||||||
func xorshift32(x uint32) uint32 {
|
func xorshift32(x uint32) uint32 {
|
||||||
// Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs".
|
// Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs".
|
||||||
@@ -49,7 +49,7 @@ func fastrand64() uint64 {
|
|||||||
return xorshift64State
|
return xorshift64State
|
||||||
}
|
}
|
||||||
|
|
||||||
var xorshift64State uint64
|
var xorshift64State uint64 = 1
|
||||||
|
|
||||||
// 64-bit xorshift multiply rng from http://vigna.di.unimi.it/ftp/papers/xorshift.pdf
|
// 64-bit xorshift multiply rng from http://vigna.di.unimi.it/ftp/papers/xorshift.pdf
|
||||||
func xorshiftMult64(x uint64) uint64 {
|
func xorshiftMult64(x uint64) uint64 {
|
||||||
|
|||||||
@@ -4,5 +4,23 @@ package runtime
|
|||||||
type Error interface {
|
type Error interface {
|
||||||
error
|
error
|
||||||
|
|
||||||
|
// Method to indicate this is indeed a runtime error.
|
||||||
RuntimeError()
|
RuntimeError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type runtimeError struct {
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r runtimeError) Error() string {
|
||||||
|
return r.msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purely here to satisfy the Error interface.
|
||||||
|
func (r runtimeError) RuntimeError() {}
|
||||||
|
|
||||||
|
var (
|
||||||
|
divideError error = runtimeError{"runtime error: integer divide by zero"}
|
||||||
|
lookupError error = runtimeError{"runtime error: index out of range"}
|
||||||
|
overflowError error = runtimeError{"runtime error: integer overflow"}
|
||||||
|
)
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ func nilMapPanic() {
|
|||||||
|
|
||||||
// Panic when trying to access an array or slice out of bounds.
|
// Panic when trying to access an array or slice out of bounds.
|
||||||
func lookupPanic() {
|
func lookupPanic() {
|
||||||
runtimePanicAt(returnAddress(0), "index out of range")
|
_panic(lookupError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panic when trying to slice a slice out of bounds.
|
// Panic when trying to slice a slice out of bounds.
|
||||||
@@ -220,9 +220,14 @@ func negativeShiftPanic() {
|
|||||||
|
|
||||||
// Panic when there is a divide by zero.
|
// Panic when there is a divide by zero.
|
||||||
func divideByZeroPanic() {
|
func divideByZeroPanic() {
|
||||||
runtimePanicAt(returnAddress(0), "divide by zero")
|
_panic(divideError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func blockingPanic() {
|
func blockingPanic() {
|
||||||
runtimePanicAt(returnAddress(0), "trying to do blocking operation in exported function")
|
runtimePanicAt(returnAddress(0), "trying to do blocking operation in exported function")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname fips_fatal crypto/internal/fips140.fatal
|
||||||
|
func fips_fatal(msg string) {
|
||||||
|
runtimePanic(msg)
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ func wasmEntryReactor() {
|
|||||||
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
|
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
|
||||||
heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
|
heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
|
||||||
initHeap()
|
initHeap()
|
||||||
|
initRand()
|
||||||
|
|
||||||
if hasScheduler {
|
if hasScheduler {
|
||||||
// A package initializer might do funky stuff like start a goroutine and
|
// A package initializer might do funky stuff like start a goroutine and
|
||||||
@@ -51,6 +52,15 @@ func wasmEntryReactor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is the _start entry point, when using -buildmode=wasi-legacy.
|
||||||
|
func wasmEntryLegacy() {
|
||||||
|
// These need to be initialized early so that the heap can be initialized.
|
||||||
|
initializeCalled = true
|
||||||
|
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
|
||||||
|
heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
|
||||||
|
run()
|
||||||
|
}
|
||||||
|
|
||||||
// Whether the runtime was initialized by a call to _initialize or _start.
|
// Whether the runtime was initialized by a call to _initialize or _start.
|
||||||
var initializeCalled bool
|
var initializeCalled bool
|
||||||
|
|
||||||
|
|||||||
@@ -31,3 +31,14 @@ func scheduleLogChan(msg string, ch *channel, t *task.Task) {
|
|||||||
func Goexit() {
|
func Goexit() {
|
||||||
panicOrGoexit(nil, panicGoexit)
|
panicOrGoexit(nil, panicGoexit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname fips_getIndicator crypto/internal/fips140.getIndicator
|
||||||
|
func fips_getIndicator() uint8 {
|
||||||
|
return task.Current().FipsIndicator
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname fips_setIndicator crypto/internal/fips140.setIndicator
|
||||||
|
func fips_setIndicator(indicator uint8) {
|
||||||
|
// This indicator is stored per goroutine.
|
||||||
|
task.Current().FipsIndicator = indicator
|
||||||
|
}
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ func sleep(duration int64) {
|
|||||||
// With a scheduler, init and the main function are invoked in a goroutine before starting the scheduler.
|
// With a scheduler, init and the main function are invoked in a goroutine before starting the scheduler.
|
||||||
func run() {
|
func run() {
|
||||||
initHeap()
|
initHeap()
|
||||||
|
initRand()
|
||||||
go func() {
|
go func() {
|
||||||
initAll()
|
initAll()
|
||||||
callMain()
|
callMain()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const hasParallelism = false
|
|||||||
// With the "none" scheduler, init and the main function are invoked directly.
|
// With the "none" scheduler, init and the main function are invoked directly.
|
||||||
func run() {
|
func run() {
|
||||||
initHeap()
|
initHeap()
|
||||||
|
initRand()
|
||||||
initAll()
|
initAll()
|
||||||
callMain()
|
callMain()
|
||||||
mainExited = true
|
mainExited = true
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package runtime
|
||||||
|
|
||||||
|
// Dummy implementation of synctest functions (we don't support synctest at the
|
||||||
|
// moment).
|
||||||
|
|
||||||
|
//go:linkname synctest_acquire internal/synctest.acquire
|
||||||
|
func synctest_acquire() any {
|
||||||
|
// Dummy: we don't support synctest.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname synctest_release internal/synctest.release
|
||||||
|
func synctest_release(sg any) {
|
||||||
|
// Dummy: we don't support synctest.
|
||||||
|
}
|
||||||
@@ -1,5 +1,18 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
|
//go:linkname time_runtimeNano time.runtimeNano
|
||||||
|
func time_runtimeNano() int64 {
|
||||||
|
// Note: we're ignoring sync groups here (package testing/synctest).
|
||||||
|
// See: https://github.com/golang/go/issues/67434
|
||||||
|
return nanotime()
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname time_runtimeNow time.runtimeNow
|
||||||
|
func time_runtimeNow() (sec int64, nsec int32, mono int64) {
|
||||||
|
// Also ignoring the sync group here, like time_runtimeNano above.
|
||||||
|
return now()
|
||||||
|
}
|
||||||
|
|
||||||
// timerNode is an element in a linked list of timers.
|
// timerNode is an element in a linked list of timers.
|
||||||
type timerNode struct {
|
type timerNode struct {
|
||||||
next *timerNode
|
next *timerNode
|
||||||
|
|||||||
@@ -233,6 +233,10 @@ func (w WaitStatus) Continued() bool { return false }
|
|||||||
func (w WaitStatus) StopSignal() Signal { return 0 }
|
func (w WaitStatus) StopSignal() Signal { return 0 }
|
||||||
func (w WaitStatus) TrapCause() int { return 0 }
|
func (w WaitStatus) TrapCause() int { return 0 }
|
||||||
|
|
||||||
|
// Purely here for compatibility.
|
||||||
|
type Rusage struct {
|
||||||
|
}
|
||||||
|
|
||||||
// since rusage is quite a big struct and we stub it out anyway no need to define it here
|
// since rusage is quite a big struct and we stub it out anyway no need to define it here
|
||||||
func Wait4(pid int, wstatus *WaitStatus, options int, rusage uintptr) (wpid int, err error) {
|
func Wait4(pid int, wstatus *WaitStatus, options int, rusage uintptr) (wpid int, err error) {
|
||||||
return 0, ENOSYS // TODO
|
return 0, ENOSYS // TODO
|
||||||
|
|||||||
@@ -120,8 +120,11 @@ const (
|
|||||||
SYS_FCNTL64
|
SYS_FCNTL64
|
||||||
SYS_FSTATAT64
|
SYS_FSTATAT64
|
||||||
SYS_IOCTL
|
SYS_IOCTL
|
||||||
|
SYS_MKDIRAT
|
||||||
SYS_OPENAT
|
SYS_OPENAT
|
||||||
|
SYS_READLINKAT
|
||||||
SYS_UNLINKAT
|
SYS_UNLINKAT
|
||||||
|
SYS_WAITID
|
||||||
PATH_MAX = 4096
|
PATH_MAX = 4096
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -438,6 +441,13 @@ type RawSockaddrInet6 struct {
|
|||||||
// stub
|
// stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RandomGet(b []byte) error {
|
||||||
|
if len(b) > 0 {
|
||||||
|
libc_arc4random_buf(unsafe.Pointer(&b[0]), uint(len(b)))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// This is a stub, it is not functional.
|
// This is a stub, it is not functional.
|
||||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
@@ -483,3 +493,8 @@ func libc_fdclosedir(unsafe.Pointer) int32
|
|||||||
//
|
//
|
||||||
//export readdir
|
//export readdir
|
||||||
func libc_readdir(unsafe.Pointer) *Dirent
|
func libc_readdir(unsafe.Pointer) *Dirent
|
||||||
|
|
||||||
|
// void arc4random_buf(void *buf, size_t buflen);
|
||||||
|
//
|
||||||
|
//export arc4random_buf
|
||||||
|
func libc_arc4random_buf(buf unsafe.Pointer, buflen uint)
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -390,6 +392,49 @@ func (c *common) Setenv(key, value string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chdir calls os.Chdir(dir) and uses Cleanup to restore the current
|
||||||
|
// working directory to its original value after the test. On Unix, it
|
||||||
|
// also sets PWD environment variable for the duration of the test.
|
||||||
|
//
|
||||||
|
// Because Chdir affects the whole process, it cannot be used
|
||||||
|
// in parallel tests or tests with parallel ancestors.
|
||||||
|
func (c *common) Chdir(dir string) {
|
||||||
|
// Note: function copied from the Go 1.24.0 source tree.
|
||||||
|
|
||||||
|
oldwd, err := os.Open(".")
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.Chdir(dir); err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
// On POSIX platforms, PWD represents “an absolute pathname of the
|
||||||
|
// current working directory.” Since we are changing the working
|
||||||
|
// directory, we should also set or update PWD to reflect that.
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows", "plan9":
|
||||||
|
// Windows and Plan 9 do not use the PWD variable.
|
||||||
|
default:
|
||||||
|
if !filepath.IsAbs(dir) {
|
||||||
|
dir, err = os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Setenv("PWD", dir)
|
||||||
|
}
|
||||||
|
c.Cleanup(func() {
|
||||||
|
err := oldwd.Chdir()
|
||||||
|
oldwd.Close()
|
||||||
|
if err != nil {
|
||||||
|
// It's not safe to continue with tests if we can't
|
||||||
|
// get back to the original working directory. Since
|
||||||
|
// we are holding a dirfd, this is highly unlikely.
|
||||||
|
panic("testing.Chdir: " + err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// runCleanup is called at the end of the test.
|
// runCleanup is called at the end of the test.
|
||||||
func (c *common) runCleanup() {
|
func (c *common) runCleanup() {
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["rp2040"],
|
"inherits": ["rp2040"],
|
||||||
"build-tags": ["elecrow_rp2040"],
|
"build-tags": ["elecrow_rp2040", "comboat_fw"],
|
||||||
"serial-port": ["2e8a:000a"],
|
"serial-port": ["2e8a:000a"],
|
||||||
"default-stack-size": 8192,
|
"default-stack-size": 8192,
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["rp2350"],
|
"inherits": ["rp2350"],
|
||||||
"build-tags": ["elecrow_rp2350"],
|
"build-tags": ["elecrow_rp2350", "comboat_fw"],
|
||||||
"serial-port": ["2e8a:000f"],
|
"serial-port": ["2e8a:000f"],
|
||||||
"default-stack-size": 8192,
|
"default-stack-size": 8192,
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"inherits": ["hw-651", "nrf51-s110v8"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"inherits": ["nrf51"],
|
||||||
|
"build-tags": ["hw_651"],
|
||||||
|
"serial": "uart",
|
||||||
|
"flash-method": "openocd",
|
||||||
|
"openocd-interface": "cmsis-dap"
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"inherits": ["rp2350b"],
|
||||||
|
"build-tags": ["pga2350"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"inherits": [
|
||||||
|
"rp2350b"
|
||||||
|
],
|
||||||
|
"build-tags": ["pico_plus2"],
|
||||||
|
"ldflags": [
|
||||||
|
"--defsym=__flash_size=16M"
|
||||||
|
],
|
||||||
|
"serial-port": ["2e8a:000F"],
|
||||||
|
"default-stack-size": 8192
|
||||||
|
}
|
||||||
+2
-1
@@ -3,5 +3,6 @@
|
|||||||
"rp2350"
|
"rp2350"
|
||||||
],
|
],
|
||||||
"build-tags": ["pico2"],
|
"build-tags": ["pico2"],
|
||||||
"serial-port": ["2e8a:000A"]
|
"serial-port": ["2e8a:000A"],
|
||||||
|
"default-stack-size": 8192
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"inherits": ["rp2350"],
|
||||||
|
"build-tags": ["rp2350b"],
|
||||||
|
"serial-port": ["2e8a:000f"]
|
||||||
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
],
|
],
|
||||||
"linkerscript": "targets/tkey.ld",
|
"linkerscript": "targets/tkey.ld",
|
||||||
"scheduler": "none",
|
"scheduler": "none",
|
||||||
"gc": "leaking",
|
"gc": "conservative",
|
||||||
"flash-command": "tkey-runapp {bin}",
|
"flash-command": "tkey-runapp {bin}",
|
||||||
"serial": "uart"
|
"serial": "uart"
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-3
@@ -303,9 +303,20 @@
|
|||||||
|
|
||||||
// func finalizeRef(v ref)
|
// func finalizeRef(v ref)
|
||||||
"syscall/js.finalizeRef": (v_ref) => {
|
"syscall/js.finalizeRef": (v_ref) => {
|
||||||
// Note: TinyGo does not support finalizers so this should never be
|
// Note: TinyGo does not support finalizers so this is only called
|
||||||
// called.
|
// for one specific case, by js.go:jsString. and can/might leak memory.
|
||||||
console.error('syscall/js.finalizeRef not implemented');
|
const id = v_ref & 0xffffffffn;
|
||||||
|
if (this._goRefCounts?.[id] !== undefined) {
|
||||||
|
this._goRefCounts[id]--;
|
||||||
|
if (this._goRefCounts[id] === 0) {
|
||||||
|
const v = this._values[id];
|
||||||
|
this._values[id] = null;
|
||||||
|
this._ids.delete(v);
|
||||||
|
this._idPool.push(id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("syscall/js.finalizeRef: unknown id", id);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// func stringVal(value string) ref
|
// func stringVal(value string) ref
|
||||||
|
|||||||
Vendored
+24
@@ -30,6 +30,10 @@ func main() {
|
|||||||
println("\n# defer panic")
|
println("\n# defer panic")
|
||||||
deferPanic()
|
deferPanic()
|
||||||
|
|
||||||
|
println("\n# runtime panics")
|
||||||
|
runtimePanicDivByZero(1, 0)
|
||||||
|
runtimePanicLookup([]int{1, 2, 3}, 10)
|
||||||
|
|
||||||
println("\n# runtime.Goexit")
|
println("\n# runtime.Goexit")
|
||||||
runtimeGoexit()
|
runtimeGoexit()
|
||||||
}
|
}
|
||||||
@@ -114,6 +118,26 @@ func deferPanic() {
|
|||||||
println("defer panic")
|
println("defer panic")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runtimePanicDivByZero(a, b int) int {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
println("recovered:", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return a / b
|
||||||
|
}
|
||||||
|
|
||||||
|
func runtimePanicLookup(slice []int, index int) int {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
println("recovered:", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return slice[index]
|
||||||
|
}
|
||||||
|
|
||||||
func runtimeGoexit() {
|
func runtimeGoexit() {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
@@ -33,8 +33,16 @@ func runargs(t *testing.T, args ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func chromectx(t *testing.T) context.Context {
|
func chromectx(t *testing.T) context.Context {
|
||||||
|
// see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md
|
||||||
|
opts := append(chromedp.DefaultExecAllocatorOptions[:],
|
||||||
|
chromedp.NoSandbox,
|
||||||
|
)
|
||||||
|
|
||||||
|
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
|
||||||
|
t.Cleanup(cancel)
|
||||||
|
|
||||||
// looks for locally installed Chrome
|
// looks for locally installed Chrome
|
||||||
ctx, ccancel := chromedp.NewContext(context.Background(), chromedp.WithErrorf(t.Errorf), chromedp.WithDebugf(t.Logf), chromedp.WithLogf(t.Logf))
|
ctx, ccancel := chromedp.NewContext(allocCtx, chromedp.WithErrorf(t.Errorf), chromedp.WithDebugf(t.Logf), chromedp.WithLogf(t.Logf))
|
||||||
t.Cleanup(ccancel)
|
t.Cleanup(ccancel)
|
||||||
|
|
||||||
// Wait for browser to be ready.
|
// Wait for browser to be ready.
|
||||||
|
|||||||
Reference in New Issue
Block a user