mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-01 09:37:48 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| feac8ca0f9 |
+9
-11
@@ -92,28 +92,26 @@ commands:
|
||||
- /go/pkg/mod
|
||||
|
||||
jobs:
|
||||
test-oldest:
|
||||
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
||||
# least the smoke tests still pass.
|
||||
test-llvm15-go122:
|
||||
docker:
|
||||
- image: golang:1.22-bullseye
|
||||
steps:
|
||||
- test-linux:
|
||||
llvm: "15"
|
||||
resource_class: large
|
||||
test-newest:
|
||||
# This tests the latest supported LLVM version when linking against system
|
||||
# libraries.
|
||||
test-llvm20-go124:
|
||||
docker:
|
||||
- image: golang:1.25-bullseye
|
||||
- image: golang:1.24-bullseye
|
||||
steps:
|
||||
- test-linux:
|
||||
llvm: "21"
|
||||
llvm: "20"
|
||||
resource_class: large
|
||||
|
||||
workflows:
|
||||
test-all:
|
||||
jobs:
|
||||
- test-oldest
|
||||
# disable this test, since CircleCI seems unable to download due to rate-limits on Dockerhub.
|
||||
# - test-newest
|
||||
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
||||
# least the smoke tests still pass.
|
||||
- test-llvm15-go122
|
||||
# This tests LLVM 20 support when linking against system libraries.
|
||||
- test-llvm20-go124
|
||||
|
||||
@@ -30,16 +30,16 @@ jobs:
|
||||
run: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu binaryen
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Extract TinyGo version
|
||||
id: version
|
||||
run: ./.github/workflows/tinygo-extract-version.sh | tee -a "$GITHUB_OUTPUT"
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.1'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
rm -rf llvm-project
|
||||
make llvm-source
|
||||
# install dependencies
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install ninja
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake ninja
|
||||
# build!
|
||||
make llvm-build
|
||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
version: [16, 17, 18, 19, 20, 21]
|
||||
version: [16, 17, 18, 19, 20]
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
@@ -130,19 +130,19 @@ jobs:
|
||||
run: |
|
||||
brew install llvm@${{ matrix.version }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.1'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
||||
run: go install -tags=llvm${{ matrix.version }}
|
||||
- name: Check binary
|
||||
run: tinygo version
|
||||
- name: Build TinyGo (default LLVM)
|
||||
if: matrix.version == 21
|
||||
if: matrix.version == 20
|
||||
run: go install
|
||||
- name: Check binary
|
||||
if: matrix.version == 21
|
||||
if: matrix.version == 20
|
||||
run: tinygo version
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
# statically linked binary.
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: golang:1.25-alpine
|
||||
image: golang:1.24-alpine
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
# tar: needed for actions/cache@v4
|
||||
# git+openssh: needed for checkout (I think?)
|
||||
# ruby: needed to install fpm
|
||||
run: apk add tar git openssh make g++ ruby-dev mold
|
||||
run: apk add tar git openssh make g++ ruby-dev
|
||||
- name: Work around CVE-2022-24765
|
||||
# We're not on a multi-user machine, so this is safe.
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-20-linux-alpine-v1
|
||||
key: llvm-build-20-linux-alpine-v2
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
@@ -137,7 +137,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Install wasmtime
|
||||
uses: bytecodealliance/actions/wasmtime/setup@v1
|
||||
@@ -181,7 +181,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
@@ -222,7 +222,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-20-linux-asserts-v1
|
||||
key: llvm-build-20-linux-asserts-v2
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
@@ -298,7 +298,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -329,7 +329,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-20-linux-${{ matrix.goarch }}-v1
|
||||
key: llvm-build-20-linux-${{ matrix.goarch }}-v4
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
# still works after checking out the dev branch (that is, when going from LLVM
|
||||
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
|
||||
|
||||
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-21 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
sudo apt-get install --no-install-recommends -y \
|
||||
llvm-21-dev \
|
||||
clang-21 \
|
||||
libclang-21-dev \
|
||||
lld-21
|
||||
llvm-20-dev \
|
||||
clang-20 \
|
||||
libclang-20-dev \
|
||||
lld-20
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Restore cached LLVM source
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -177,7 +177,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -213,7 +213,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.24'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
url = https://github.com/tinygo-org/stm32-svd
|
||||
[submodule "lib/musl"]
|
||||
path = lib/musl
|
||||
url = https://github.com/tinygo-org/musl-libc.git
|
||||
url = git://git.musl-libc.org/musl
|
||||
[submodule "lib/binaryen"]
|
||||
path = lib/binaryen
|
||||
url = https://github.com/WebAssembly/binaryen.git
|
||||
|
||||
@@ -1,55 +1,3 @@
|
||||
0.39.0
|
||||
---
|
||||
* **general**
|
||||
- all: add Go 1.25 support
|
||||
- net: update to latest tinygo net package
|
||||
- docs: clarify build verification step for macOS users
|
||||
- Add flag to skip Renesas SVD builds
|
||||
* **build**
|
||||
- Makefile: install missing dlmalloc files
|
||||
- flash: add -o flag support to save built binary (Fixes #4937) (#4942)
|
||||
- fix: update version of clang to 17 to accommodate latest Go 1.25 docker base image
|
||||
* **ci**
|
||||
- chore: update all CI builds to test Go 1.25 release
|
||||
- fix: disable test-newest since CircleCI seems unable to download due to rate-limits on Dockerhub
|
||||
- ci: rename some jobs to avoid churn on every Go/LLVM version bump
|
||||
- ci: make the goroutines test less racy
|
||||
- tests: de-flake goroutines test
|
||||
* **compiler**
|
||||
- compiler: implement internal/abi.Escape
|
||||
* **main**
|
||||
- main: show the compiler error (if any) for `tinygo test -c`
|
||||
- chore: correct GOOS=js name in error messages for WASM
|
||||
* **machine**
|
||||
- machine: add international keys
|
||||
- machine: remove some unnecessary "// peripherals:" comments
|
||||
- machine: add I2C pin comments
|
||||
- machine: standardize I2C errors with "i2c:" prefix
|
||||
- machine: make I2C usable in the simulator
|
||||
- fix: add SPI and I2C to teensy 4.1 (#4943)
|
||||
- `rp2`: use the correct channel mask for rp2350 ADC; hold lock during read (#4938)
|
||||
- `rp2`: disable digital input for analog inputs
|
||||
* **runtime**
|
||||
- runtime: ensure time.Sleep(d) sleeps at least d
|
||||
- runtime: stub out weak pointer support
|
||||
- runtime: implement dummy AddCleanup
|
||||
- runtime: enable multi-core scheduler for rp2350
|
||||
- `internal/task`: use -stack-size flag when starting a new thread
|
||||
- `internal/task`: add SA_RESTART flag to GC interrupts
|
||||
- `internal/task`: a few small correctness fixes
|
||||
- `internal/gclayout`: make gclayout values constants
|
||||
- darwin: add threading support and use it by default
|
||||
* **standard library**
|
||||
- `sync`: implement sync.Swap
|
||||
- `reflect`: implement Method.IsExported
|
||||
* **testing**
|
||||
- testing: stub out testing.B.Loop
|
||||
* **targets**
|
||||
- `stm32`: add support for the STM32L031G6U6
|
||||
- add metro-rp2350 board definition (#4989)
|
||||
- `rp2040/rp2350`: set the default stack size to 8k for rp2040/rp2350 based boards where this was not already the case
|
||||
|
||||
|
||||
0.38.0
|
||||
---
|
||||
* **general**
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
# tinygo-llvm stage obtains the llvm source for TinyGo
|
||||
FROM golang:1.25 AS tinygo-llvm
|
||||
FROM golang:1.24 AS tinygo-llvm
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y apt-utils make cmake clang-17 ninja-build && \
|
||||
apt-get install -y apt-utils make cmake clang-15 ninja-build && \
|
||||
rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/log/* \
|
||||
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
|
||||
|
||||
# tinygo-compiler copies the compiler build over to a base Go container (without
|
||||
# all the build tools etc).
|
||||
FROM golang:1.25 AS tinygo-compiler
|
||||
FROM golang:1.24 AS tinygo-compiler
|
||||
|
||||
# Copy tinygo build.
|
||||
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
||||
|
||||
+11
-43
@@ -79,26 +79,6 @@ ifeq (1, $(STATIC))
|
||||
BINARYEN_OPTION += -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static"
|
||||
endif
|
||||
|
||||
# Optimize the binary size for Linux.
|
||||
# These flags may work on other platforms, but have only been tested on Linux.
|
||||
ifeq ($(uname),Linux)
|
||||
HAS_MOLD := $(shell command -v ld.mold 2> /dev/null)
|
||||
HAS_LLD := $(shell command -v ld.lld 2> /dev/null)
|
||||
LLVM_CFLAGS := -ffunction-sections -fdata-sections -fvisibility=hidden
|
||||
LLVM_LDFLAGS := -Wl,--gc-sections
|
||||
ifneq ($(HAS_MOLD),)
|
||||
# Mold might be slightly faster.
|
||||
LLVM_LDFLAGS += -fuse-ld=mold -Wl,--icf=all
|
||||
else ifneq ($(HAS_LLD),)
|
||||
# LLD is more commonly available.
|
||||
LLVM_LDFLAGS += -fuse-ld=lld -Wl,--icf=all
|
||||
endif
|
||||
LLVM_OPTION += \
|
||||
-DCMAKE_C_FLAGS="$(LLVM_CFLAGS)" \
|
||||
-DCMAKE_CXX_FLAGS="$(LLVM_CFLAGS)"
|
||||
CGO_LDFLAGS += $(LLVM_LDFLAGS)
|
||||
endif
|
||||
|
||||
# Cross compiling support.
|
||||
ifneq ($(CROSS),)
|
||||
CC = $(CROSS)-gcc
|
||||
@@ -480,15 +460,11 @@ TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS)
|
||||
TEST_IOFS := false
|
||||
endif
|
||||
|
||||
TEST_SKIP_FLAG := -skip='TestExtraMethods|TestParseAndBytesRoundTrip/P256/Generic'
|
||||
|
||||
# Test known-working standard library packages.
|
||||
# TODO: parallelize, and only show failing tests (no implied -v flag).
|
||||
.PHONY: tinygo-test
|
||||
tinygo-test:
|
||||
@# TestExtraMethods: used by many crypto packages and uses reflect.Type.Method which is not implemented.
|
||||
@# TestParseAndBytesRoundTrip/P256/Generic: relies on t.Skip() which is not implemented
|
||||
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||
$(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||
@# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also
|
||||
@# requires a large stack-size. Hence, io/fs is only run conditionally.
|
||||
@# For more details, see the comments on issue #3143.
|
||||
@@ -496,7 +472,7 @@ ifeq ($(TEST_IOFS),true)
|
||||
$(TINYGO) test -stack-size=6MB io/fs
|
||||
endif
|
||||
tinygo-test-fast:
|
||||
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST)
|
||||
$(TINYGO) test $(TEST_PACKAGES_HOST)
|
||||
tinygo-bench:
|
||||
$(TINYGO) test -bench . $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||
tinygo-bench-fast:
|
||||
@@ -504,18 +480,18 @@ tinygo-bench-fast:
|
||||
|
||||
# Same thing, except for wasi rather than the current platform.
|
||||
tinygo-test-wasm:
|
||||
$(TINYGO) test -target wasm $(TEST_SKIP_FLAG) $(TEST_PACKAGES_WASM)
|
||||
$(TINYGO) test -target wasm $(TEST_PACKAGES_WASM)
|
||||
tinygo-test-wasi:
|
||||
$(TINYGO) test -target wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
tinygo-test-wasip1:
|
||||
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
tinygo-test-wasip1-fast:
|
||||
$(TINYGO) test -target=wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target=wasip1 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
|
||||
tinygo-test-wasip2-slow:
|
||||
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_SLOW)
|
||||
$(TINYGO) test -target=wasip2 $(TEST_PACKAGES_SLOW)
|
||||
tinygo-test-wasip2-fast:
|
||||
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target=wasip2 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
|
||||
tinygo-test-wasip2-sum-slow:
|
||||
TINYGO=$(TINYGO) \
|
||||
@@ -541,7 +517,7 @@ tinygo-bench-wasip2-fast:
|
||||
|
||||
# Run tests on riscv-qemu since that one provides a large amount of memory.
|
||||
tinygo-test-baremetal:
|
||||
$(TINYGO) test -target riscv-qemu $(TEST_SKIP_FLAG) $(TEST_PACKAGES_BAREMETAL)
|
||||
$(TINYGO) test -target riscv-qemu $(TEST_PACKAGES_BAREMETAL)
|
||||
|
||||
# Test external packages in a large corpus.
|
||||
test-corpus:
|
||||
@@ -795,8 +771,6 @@ endif
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=gopher-badge examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=gopher-arcade examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=ae-rp2040 examples/echo
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=thumby examples/echo
|
||||
@@ -807,8 +781,6 @@ endif
|
||||
@$(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=metro-rp2350 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo
|
||||
@$(MD5SUM) test.hex
|
||||
# test pwm
|
||||
@@ -973,7 +945,7 @@ endif
|
||||
|
||||
|
||||
wasmtest:
|
||||
cd ./tests/wasm && $(GO) test .
|
||||
$(GO) test ./tests/wasm
|
||||
|
||||
build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binaryen)
|
||||
@mkdir -p build/release/tinygo/bin
|
||||
@@ -1120,7 +1092,6 @@ endif
|
||||
tools:
|
||||
cd internal/tools && go generate -tags tools ./
|
||||
|
||||
LINTDIRS=src/os/ src/reflect/
|
||||
.PHONY: lint
|
||||
lint: tools ## Lint source tree
|
||||
revive -version
|
||||
@@ -1128,10 +1099,7 @@ lint: tools ## Lint source tree
|
||||
# revive.toml isn't flexible enough to filter out just one kind of error from a checker, so do it with grep here.
|
||||
# Can't use grep with friendly formatter. Plain output isn't too bad, though.
|
||||
# Use 'grep .' to get rid of stray blank line
|
||||
revive -config revive.toml compiler/... $$( find $(LINTDIRS) -type f -name '*.go' ) \
|
||||
| grep -v "should have comment or be unexported" \
|
||||
| grep '.' \
|
||||
| awk '{print}; END {exit NR>0}'
|
||||
revive -config revive.toml compiler/... src/{os,reflect}/*.go | grep -v "should have comment or be unexported" | grep '.' | awk '{print}; END {exit NR>0}'
|
||||
|
||||
SPELLDIRSCMD=find . -depth 1 -type d | egrep -wv '.git|lib|llvm|src'; find src -depth 1 | egrep -wv 'device|internal|net|vendor'; find src/internal -depth 1 -type d | egrep -wv src/internal/wasi
|
||||
.PHONY: spell
|
||||
|
||||
+1
-1
@@ -1046,7 +1046,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
// Special format for the ESP family of chips (parsed by the ROM
|
||||
// bootloader).
|
||||
result.Binary = filepath.Join(tmpdir, "main"+outext)
|
||||
err := makeESPFirmwareImage(result.Executable, result.Binary, outputBinaryFormat)
|
||||
err := makeESPFirmareImage(result.Executable, result.Binary, outputBinaryFormat)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
||||
|
||||
// Version range supported by TinyGo.
|
||||
const minorMin = 19
|
||||
const minorMax = 25
|
||||
const minorMax = 24
|
||||
|
||||
// Check that we support this Go toolchain version.
|
||||
gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ type espImageSegment struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
// makeESPFirmwareImage converts an input ELF file to an image file for an ESP32 or
|
||||
// makeESPFirmareImage converts an input ELF file to an image file for an ESP32 or
|
||||
// ESP8266 chip. This is a special purpose image format just for the ESP chip
|
||||
// family, and is parsed by the on-chip mask ROM bootloader.
|
||||
//
|
||||
@@ -31,7 +31,7 @@ type espImageSegment struct {
|
||||
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format
|
||||
// https://github.com/espressif/esp-idf/blob/8fbb63c2a701c22ccf4ce249f43aded73e134a34/components/bootloader_support/include/esp_image_format.h#L58
|
||||
// https://github.com/espressif/esptool/blob/master/esptool.py
|
||||
func makeESPFirmwareImage(infile, outfile, format string) error {
|
||||
func makeESPFirmareImage(infile, outfile, format string) error {
|
||||
inf, err := elf.Open(infile)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -42,9 +42,9 @@ func TestBinarySize(t *testing.T) {
|
||||
// This is a small number of very diverse targets that we want to test.
|
||||
tests := []sizeTest{
|
||||
// microcontrollers
|
||||
{"hifive1b", "examples/echo", 3884, 280, 0, 2268},
|
||||
{"microbit", "examples/serial", 2924, 388, 8, 2272},
|
||||
{"wioterminal", "examples/pininterrupt", 7365, 1491, 116, 6912},
|
||||
{"hifive1b", "examples/echo", 3836, 280, 0, 2268},
|
||||
{"microbit", "examples/serial", 2916, 388, 8, 2272},
|
||||
{"wioterminal", "examples/pininterrupt", 7361, 1491, 116, 6912},
|
||||
|
||||
// TODO: also check wasm. Right now this is difficult, because
|
||||
// wasm binaries are run through wasm-opt and therefore the
|
||||
|
||||
@@ -21,10 +21,6 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
// Hide a warning in LLVM 21 that doesn't apply to us (appears to be a side
|
||||
// effect of how CGo processes C header files).
|
||||
#cgo CFLAGS: -Wno-deprecated-declarations
|
||||
|
||||
#include <clang-c/Index.h> // If this fails, libclang headers aren't available. Please take a look here: https://tinygo.org/docs/guides/build/
|
||||
#include <llvm/Config/llvm-config.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build !byollvm && llvm20
|
||||
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19
|
||||
|
||||
package cgo
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20
|
||||
|
||||
package cgo
|
||||
|
||||
/*
|
||||
#cgo linux CFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -I/usr/lib/llvm-21/include
|
||||
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@21/include
|
||||
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@21/include
|
||||
#cgo freebsd CFLAGS: -I/usr/local/llvm21/include
|
||||
#cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lclang
|
||||
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@21/lib -lclang
|
||||
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -lclang
|
||||
#cgo freebsd LDFLAGS: -L/usr/local/llvm21/lib -lclang
|
||||
*/
|
||||
import "C"
|
||||
@@ -84,7 +84,6 @@ type compilerContext struct {
|
||||
funcPtrType llvm.Type // pointer in function address space (1 for AVR, 0 elsewhere)
|
||||
funcPtrAddrSpace int
|
||||
uintptrType llvm.Type
|
||||
nocaptureAttr llvm.Attribute
|
||||
program *ssa.Program
|
||||
diagnostics []error
|
||||
functionInfos map[*ssa.Function]functionInfo
|
||||
@@ -136,13 +135,6 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
|
||||
c.funcPtrType = dummyFunc.Type()
|
||||
dummyFunc.EraseFromParentAsFunction()
|
||||
|
||||
// The attribute "nocapture" changed to "captures(none)" in LLVM 21.
|
||||
if llvmutil.Version() < 21 {
|
||||
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
|
||||
} else {
|
||||
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("captures"), 0)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
|
||||
@@ -121,29 +121,6 @@ func (b *builder) createKeepAliveImpl() {
|
||||
b.CreateRetVoid()
|
||||
}
|
||||
|
||||
// createAbiEscapeImpl implements the generic internal/abi.Escape function. It
|
||||
// currently only supports pointer types.
|
||||
func (b *builder) createAbiEscapeImpl() {
|
||||
b.createFunctionStart(true)
|
||||
|
||||
// The first parameter is assumed to be a pointer. This is checked at the
|
||||
// call site of createAbiEscapeImpl.
|
||||
pointerValue := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
|
||||
// Create an equivalent of the following C code, which is basically just a
|
||||
// nop but ensures the pointerValue is kept alive:
|
||||
//
|
||||
// __asm__ __volatile__("" : : "r"(pointerValue))
|
||||
//
|
||||
// It should be portable to basically everything as the "r" register type
|
||||
// exists basically everywhere.
|
||||
asmType := llvm.FunctionType(b.dataPtrType, []llvm.Type{b.dataPtrType}, false)
|
||||
asmFn := llvm.InlineAsm(asmType, "", "=r,0", true, false, 0, false)
|
||||
result := b.createCall(asmType, asmFn, []llvm.Value{pointerValue}, "")
|
||||
|
||||
b.CreateRet(result)
|
||||
}
|
||||
|
||||
var mathToLLVMMapping = map[string]string{
|
||||
"math.Ceil": "llvm.ceil.f64",
|
||||
"math.Exp": "llvm.exp.f64",
|
||||
|
||||
@@ -218,7 +218,7 @@ func Version() int {
|
||||
return major
|
||||
}
|
||||
|
||||
// ByteOrder returns the byte order for the given target triple. Most targets are little
|
||||
// Return the byte order for the given target triple. Most targets are little
|
||||
// endian, but for example MIPS can be big-endian.
|
||||
func ByteOrder(target string) binary.ByteOrder {
|
||||
if strings.HasPrefix(target, "mips-") {
|
||||
|
||||
+16
-41
@@ -139,7 +139,8 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
// not.
|
||||
// (It may be safe to add the nocapture parameter to the context
|
||||
// parameter, but I'd like to stay on the safe side here).
|
||||
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
|
||||
nocapture := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
|
||||
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
// Mark it as noreturn so LLVM can optimize away code.
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
|
||||
case "internal/abi.NoEscape":
|
||||
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
case "runtime.alloc":
|
||||
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
|
||||
// returns values that are never null and never alias to an existing value.
|
||||
@@ -174,25 +175,25 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
case "runtime.sliceAppend":
|
||||
// Appending a slice will only read the to-be-appended slice, it won't
|
||||
// be modified.
|
||||
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
case "runtime.sliceCopy":
|
||||
// Copying a slice won't capture any of the parameters.
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("writeonly"), 0))
|
||||
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
case "runtime.stringFromBytes":
|
||||
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
case "runtime.stringFromRunes":
|
||||
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
case "runtime.trackPointer":
|
||||
// This function is necessary for tracking pointers on the stack in a
|
||||
// portable way (see gc_stack_portable.go). Indicate to the optimizer
|
||||
// that the only thing we'll do is read the pointer.
|
||||
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||
case "__mulsi3", "__divmodsi4", "__udivmodsi4":
|
||||
if strings.Split(c.Triple, "-")[0] == "avr" {
|
||||
@@ -227,9 +228,11 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-name", info.wasmName))
|
||||
}
|
||||
nocaptureKind := llvm.AttributeKindID("nocapture")
|
||||
nocapture := c.ctx.CreateEnumAttribute(nocaptureKind, 0)
|
||||
for i, typ := range paramTypes {
|
||||
if typ.TypeKind() == llvm.PointerTypeKind {
|
||||
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
|
||||
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,23 +253,6 @@ func (c *compilerContext) maybeCreateSyntheticFunction(fn *ssa.Function, llvmFn
|
||||
// The exception is the package initializer, which does appear in the
|
||||
// *ssa.Package members and so shouldn't be created here.
|
||||
if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" {
|
||||
if origin := fn.Origin(); origin != nil && origin.RelString(nil) == "internal/abi.Escape" {
|
||||
// This is a special implementation or internal/abi.Escape, which
|
||||
// can only really be implemented in the compiler.
|
||||
// For simplicity we'll only implement pointer parameters for now.
|
||||
if _, ok := fn.Params[0].Type().Underlying().(*types.Pointer); ok {
|
||||
irbuilder := c.ctx.NewBuilder()
|
||||
defer irbuilder.Dispose()
|
||||
b := newBuilder(c, irbuilder, fn)
|
||||
b.createAbiEscapeImpl()
|
||||
llvmFn.SetLinkage(llvm.LinkOnceODRLinkage)
|
||||
llvmFn.SetUnnamedAddr(true)
|
||||
}
|
||||
// If the parameter is not of a pointer type, it will be left
|
||||
// unimplemented. This will result in a linker error if the function
|
||||
// is really called, making it clear it needs to be implemented.
|
||||
return
|
||||
}
|
||||
if len(fn.Blocks) == 0 {
|
||||
c.addError(fn.Pos(), "missing function body")
|
||||
return
|
||||
@@ -627,7 +613,7 @@ func (c *compilerContext) addStandardAttributes(llvmFn llvm.Value) {
|
||||
// linkName is equal to .RelString(nil) on a global and extern is false, but for
|
||||
// some symbols this is different (due to //go:extern for example).
|
||||
type globalInfo struct {
|
||||
linkName string // go:extern, go:linkname
|
||||
linkName string // go:extern
|
||||
extern bool // go:extern
|
||||
align int // go:align
|
||||
section string // go:section
|
||||
@@ -712,14 +698,14 @@ func (c *compilerContext) getGlobalInfo(g *ssa.Global) globalInfo {
|
||||
// Check for //go: pragmas, which may change the link name (among others).
|
||||
doc := c.astComments[info.linkName]
|
||||
if doc != nil {
|
||||
info.parsePragmas(doc, c, g)
|
||||
info.parsePragmas(doc)
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
// Parse //go: pragma comments from the source. In particular, it parses the
|
||||
// //go:extern and //go:linkname pragmas on globals.
|
||||
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup, c *compilerContext, g *ssa.Global) {
|
||||
// //go:extern pragma on globals.
|
||||
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
|
||||
for _, comment := range doc.List {
|
||||
if !strings.HasPrefix(comment.Text, "//go:") {
|
||||
continue
|
||||
@@ -740,17 +726,6 @@ func (info *globalInfo) parsePragmas(doc *ast.CommentGroup, c *compilerContext,
|
||||
if len(parts) == 2 {
|
||||
info.section = parts[1]
|
||||
}
|
||||
case "//go:linkname":
|
||||
if len(parts) != 3 || parts[1] != g.Name() {
|
||||
continue
|
||||
}
|
||||
// Only enable go:linkname when the package imports "unsafe".
|
||||
// This is a slightly looser requirement than what gc uses: gc
|
||||
// requires the file to import "unsafe", not the package as a
|
||||
// whole.
|
||||
if hasUnsafeImport(g.Pkg.Pkg) {
|
||||
info.linkName = parts[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+3
-3
@@ -206,7 +206,7 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+3
-3
@@ -107,8 +107,8 @@ select.body: ; preds = %select.next
|
||||
|
||||
declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #1
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
attributes #4 = { nounwind }
|
||||
|
||||
Vendored
+3
-3
@@ -93,6 +93,6 @@ entry:
|
||||
ret i8 %0
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
|
||||
Vendored
+3
-3
@@ -44,7 +44,7 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+3
-3
@@ -135,7 +135,7 @@ entry:
|
||||
ret %runtime._interface %1
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+3
-3
@@ -57,7 +57,7 @@ entry:
|
||||
ret ptr %s.data
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+3
-3
@@ -171,9 +171,9 @@ declare i32 @llvm.smax.i32(i32, i32) #4
|
||||
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
|
||||
declare i32 @llvm.umax.i32(i32, i32) #4
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||
attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
attributes #5 = { nounwind }
|
||||
|
||||
+9
-9
@@ -192,13 +192,13 @@ entry:
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.regularFunction" }
|
||||
attributes #4 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" }
|
||||
attributes #5 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" }
|
||||
attributes #6 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Print(string)" "tinygo-methods"="reflect/methods.Print(string)" }
|
||||
attributes #8 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="interface:{Print:func:{basic:string}{}}.Print$invoke" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-gowrapper"="main.regularFunction" }
|
||||
attributes #4 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" }
|
||||
attributes #5 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" }
|
||||
attributes #6 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-gowrapper" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Print(string)" "tinygo-methods"="reflect/methods.Print(string)" }
|
||||
attributes #8 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-gowrapper"="interface:{Print:func:{basic:string}{}}.Print$invoke" }
|
||||
attributes #9 = { nounwind }
|
||||
|
||||
Vendored
+7
-7
@@ -130,11 +130,11 @@ entry:
|
||||
|
||||
declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, ptr, ptr) #6
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #3 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #4 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.String() string" }
|
||||
attributes #5 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" }
|
||||
attributes #6 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #4 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.String() string" }
|
||||
attributes #5 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" }
|
||||
attributes #6 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" }
|
||||
attributes #7 = { nounwind }
|
||||
|
||||
Vendored
+3
-3
@@ -44,7 +44,7 @@ entry:
|
||||
ret ptr %x
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+10
-10
@@ -93,13 +93,13 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="extern_func" }
|
||||
attributes #4 = { inlinehint nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #6 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exportedFunctionInSection" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="modulename" "wasm-import-name"="import1" }
|
||||
attributes #8 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="foobar" "wasm-import-name"="imported" }
|
||||
attributes #9 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exported" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "wasm-export-name"="extern_func" }
|
||||
attributes #4 = { inlinehint nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #6 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "wasm-export-name"="exportedFunctionInSection" }
|
||||
attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "wasm-import-module"="modulename" "wasm-import-name"="import1" }
|
||||
attributes #8 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "wasm-import-module"="foobar" "wasm-import-name"="imported" }
|
||||
attributes #9 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" "wasm-export-name"="exported" }
|
||||
|
||||
Vendored
+3
-3
@@ -322,7 +322,7 @@ unsafe.Slice.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+3
-3
@@ -97,7 +97,7 @@ lookup.throw: ; preds = %entry
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { nounwind }
|
||||
|
||||
Vendored
+4
-4
@@ -132,9 +132,9 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #3 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #3 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+mutable-globals,+nontrapping-fptoint,+sign-ext,-call-indirect-overlong,-multivalue,-reference-types" }
|
||||
attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
attributes #5 = { nounwind }
|
||||
|
||||
@@ -5,6 +5,8 @@ go 1.22.0
|
||||
require (
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139
|
||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee
|
||||
github.com/chromedp/chromedp v0.7.6
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
||||
@@ -18,11 +20,17 @@ require (
|
||||
golang.org/x/sys v0.30.0
|
||||
golang.org/x/tools v0.30.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08
|
||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||
github.com/creack/goselect v0.1.2 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
|
||||
@@ -2,16 +2,33 @@ github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139 h1:2O/WuAt8J5id3k
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw=
|
||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI=
|
||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee h1:+SFdIVfQpG0s0DHYzou0kgfE0n0ZjKPwbiRJsXrZegU=
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
github.com/chromedp/chromedp v0.7.6 h1:2juGaktzjwULlsn+DnvIZXFUckEp5xs+GOBroaea+jA=
|
||||
github.com/chromedp/chromedp v0.7.6/go.mod h1:ayT4YU/MGAALNfOg9gNrpGSAdnU51PMx+FCeuT1iXzo=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
|
||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw=
|
||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
@@ -25,6 +42,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
|
||||
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
||||
@@ -44,6 +63,8 @@ golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
@@ -58,5 +79,5 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08 h1:vvEVYF4Qb38C25U8Ae/1QUWlCSp4pIE0PR+/BwNPvBU=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74 h1:ovavgTdIBWCH8YWlcfq9gkpoyT1+IxMKSn+Df27QwE8=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// Version of TinyGo.
|
||||
// Update this value before release of new version of software.
|
||||
const version = "0.40.0-dev"
|
||||
const version = "0.39.0-dev"
|
||||
|
||||
// Return TinyGo version, either in the form 0.30.0 or as a development version
|
||||
// (like 0.30.0-dev-abcd012).
|
||||
|
||||
@@ -291,8 +291,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
|
||||
})
|
||||
|
||||
if testConfig.CompileOnly {
|
||||
// Return the compiler error, if there is one.
|
||||
return true, err
|
||||
return true, nil
|
||||
}
|
||||
|
||||
importPath := strings.TrimSuffix(result.ImportPath, ".test")
|
||||
@@ -340,17 +339,8 @@ func dirsToModuleRootAbs(maindir, modroot string) []string {
|
||||
return dirs
|
||||
}
|
||||
|
||||
// validateOutputFormat checks if the output file extension matches the expected format
|
||||
func validateOutputFormat(outpath, expectedExt string) error {
|
||||
actualExt := filepath.Ext(outpath)
|
||||
if actualExt != expectedExt {
|
||||
return fmt.Errorf("output format %s does not match target format %s", actualExt, expectedExt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Flash builds and flashes the built binary to the given serial port.
|
||||
func Flash(pkgName, port, outpath string, options *compileopts.Options) error {
|
||||
func Flash(pkgName, port string, options *compileopts.Options) error {
|
||||
config, err := builder.NewConfig(options)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -399,24 +389,13 @@ func Flash(pkgName, port, outpath string, options *compileopts.Options) error {
|
||||
if !options.Work {
|
||||
defer os.RemoveAll(tmpdir)
|
||||
}
|
||||
// Validate output format before building
|
||||
if outpath != "" {
|
||||
if err := validateOutputFormat(outpath, fileExt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Build the binary.
|
||||
result, err := builder.Build(pkgName, fileExt, tmpdir, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save output file if specified (after build, before flashing)
|
||||
if outpath != "" {
|
||||
if err := copyFile(result.Binary, outpath); err != nil {
|
||||
return fmt.Errorf("failed to save output file: %v", err)
|
||||
}
|
||||
}
|
||||
// do we need port reset to put MCU into bootloader mode?
|
||||
if config.Target.PortReset == "true" && flashMethod != "openocd" {
|
||||
port, err := getDefaultPort(port, config.Target.SerialPort)
|
||||
@@ -1318,11 +1297,6 @@ extension at all.`
|
||||
(https://tinygo.org/docs/reference/microcontrollers/).
|
||||
Examples: "arduino-nano", "d1mini", "xiao".
|
||||
|
||||
-o={filename}:
|
||||
Save the built binary to the specified output file. The file
|
||||
format must match the target's expected format (e.g., .hex,
|
||||
.uf2). Both flashing and saving will be performed.
|
||||
|
||||
-monitor:
|
||||
Start the serial monitor (see below) immediately after
|
||||
flashing. However, some microcontrollers need a split second
|
||||
@@ -1653,7 +1627,7 @@ func main() {
|
||||
flag.BoolVar(&flagTest, "test", false, "supply -test flag to go list")
|
||||
}
|
||||
var outpath string
|
||||
if command == "help" || command == "build" || command == "test" || command == "flash" {
|
||||
if command == "help" || command == "build" || command == "test" {
|
||||
flag.StringVar(&outpath, "o", "", "output filename")
|
||||
}
|
||||
|
||||
@@ -1804,7 +1778,7 @@ func main() {
|
||||
case "flash", "gdb", "lldb":
|
||||
pkgName := filepath.ToSlash(flag.Arg(0))
|
||||
if command == "flash" {
|
||||
err := Flash(pkgName, *port, outpath, options)
|
||||
err := Flash(pkgName, *port, options)
|
||||
printBuildOutput(err, *flagJSON)
|
||||
} else {
|
||||
if !options.Debug {
|
||||
@@ -1890,7 +1864,6 @@ func main() {
|
||||
wd = ""
|
||||
}
|
||||
diagnostics.CreateDiagnostics(err).WriteTo(os.Stderr, wd)
|
||||
os.Exit(1)
|
||||
}
|
||||
if !passed {
|
||||
select {
|
||||
|
||||
+3
-3
@@ -35,8 +35,8 @@ func Monitor(executable, port string, config *compileopts.Config) error {
|
||||
// Use the RTT interface, which is documented (in part) here:
|
||||
// https://wiki.segger.com/RTT
|
||||
|
||||
// Try to find the "_SEGGER_RTT" symbol (machine.rttSerialInstance)
|
||||
// symbol, which is the RTT control block.
|
||||
// Try to find the "machine.rttSerialInstance" symbol, which is the RTT
|
||||
// control block.
|
||||
file, err := elf.Open(executable)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not open ELF file to determine RTT control block: %w", err)
|
||||
@@ -48,7 +48,7 @@ func Monitor(executable, port string, config *compileopts.Config) error {
|
||||
}
|
||||
var address uint64
|
||||
for _, symbol := range symbols {
|
||||
if symbol.Name == "_SEGGER_RTT" {
|
||||
if symbol.Name == "machine.rttSerialInstance" {
|
||||
address = symbol.Value
|
||||
break
|
||||
}
|
||||
|
||||
@@ -63,10 +63,6 @@ func SecCertificateCopyData(cert CFRef) ([]byte, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustCopyCertificateChain(trustObj CFRef) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
@@ -8,10 +8,3 @@ import "unsafe"
|
||||
func NoEscape(p unsafe.Pointer) unsafe.Pointer {
|
||||
return p
|
||||
}
|
||||
|
||||
func Escape[T any](x T) T {
|
||||
// This function is either implemented in the compiler, or left undefined
|
||||
// for some variation of T. The body of this function should not be compiled
|
||||
// as-is.
|
||||
panic("internal/abi.Escape: unreachable (implemented in the compiler)")
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ void tinygo_task_init(void *mainTask, pthread_t *thread, int *numCPU, void *cont
|
||||
// Using pthread_kill, we can still send the signal to a specific thread.
|
||||
struct sigaction act = { 0 };
|
||||
act.sa_handler = tinygo_task_gc_pause;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction(taskPauseSignal, &act, NULL);
|
||||
|
||||
// Obtain the number of CPUs available on program start (for NumCPU).
|
||||
@@ -101,7 +100,7 @@ static void* start_wrapper(void *arg) {
|
||||
};
|
||||
|
||||
// Start a new goroutine in an OS thread.
|
||||
int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, uintptr_t *stackTop, uintptr_t stackSize, void *context) {
|
||||
int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, uintptr_t *stackTop, void *context) {
|
||||
// Sanity check. Should get optimized away.
|
||||
if (sizeof(pthread_t) != sizeof(void*)) {
|
||||
__builtin_trap();
|
||||
@@ -118,11 +117,7 @@ int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, u
|
||||
#else
|
||||
sem_init(&state.startlock, 0, 0);
|
||||
#endif
|
||||
pthread_attr_t attrs;
|
||||
pthread_attr_init(&attrs);
|
||||
pthread_attr_setstacksize(&attrs, stackSize);
|
||||
int result = pthread_create(thread, &attrs, &start_wrapper, &state);
|
||||
pthread_attr_destroy(&attrs);
|
||||
int result = pthread_create(thread, NULL, &start_wrapper, &state);
|
||||
|
||||
// Wait until the thread has been created and read all state_pass variables.
|
||||
#if __APPLE__
|
||||
|
||||
@@ -109,7 +109,7 @@ func start(fn uintptr, args unsafe.Pointer, stackSize uintptr) {
|
||||
// and the stop-the-world GC won't see threads that haven't started yet or
|
||||
// are not fully started yet.
|
||||
activeTaskLock.Lock()
|
||||
errCode := tinygo_task_start(fn, args, t, &t.state.thread, &t.state.stackTop, stackSize)
|
||||
errCode := tinygo_task_start(fn, args, t, &t.state.thread, &t.state.stackTop)
|
||||
if errCode != 0 {
|
||||
runtimePanic("could not start thread")
|
||||
}
|
||||
@@ -266,7 +266,7 @@ func tinygo_task_init(t *Task, thread *threadID, numCPU *int32)
|
||||
// Here same as for tinygo_task_init.
|
||||
//
|
||||
//go:linkname tinygo_task_start tinygo_task_start
|
||||
func tinygo_task_start(fn uintptr, args unsafe.Pointer, t *Task, thread *threadID, stackTop *uintptr, stackSize uintptr) int32
|
||||
func tinygo_task_start(fn uintptr, args unsafe.Pointer, t *Task, thread *threadID, stackTop *uintptr) int32
|
||||
|
||||
// Pause the thread by sending it a signal.
|
||||
//
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
//go:build gopher_arcade
|
||||
|
||||
package machine
|
||||
|
||||
// Return the current CPU frequency in hertz.
|
||||
func CPUFrequency() uint32 {
|
||||
return 8000000
|
||||
}
|
||||
|
||||
const (
|
||||
P5 Pin = PB0
|
||||
P6 Pin = PB1
|
||||
P7 Pin = PB2
|
||||
P2 Pin = PB3
|
||||
P3 Pin = PB4
|
||||
P1 Pin = PB5
|
||||
|
||||
LED = P1
|
||||
BUTTON_LEFT = P7
|
||||
BUTTON_RIGHT = P5
|
||||
SPEAKER = P6
|
||||
)
|
||||
@@ -1,183 +0,0 @@
|
||||
//go:build metro_rp2350
|
||||
|
||||
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
|
||||
GP23 Pin = GPIO23
|
||||
GP24 Pin = GPIO24
|
||||
GP25 Pin = GPIO25
|
||||
GP26 Pin = GPIO26
|
||||
GP27 Pin = GPIO27
|
||||
GP28 Pin = GPIO28
|
||||
GP29 Pin = GPIO29
|
||||
GP30 Pin = GPIO30
|
||||
GP31 Pin = GPIO31
|
||||
GP32 Pin = GPIO32
|
||||
GP33 Pin = GPIO33
|
||||
GP34 Pin = GPIO34
|
||||
GP35 Pin = GPIO35
|
||||
GP36 Pin = GPIO36
|
||||
GP37 Pin = GPIO37
|
||||
GP38 Pin = GPIO38
|
||||
GP39 Pin = GPIO39
|
||||
GP40 Pin = GPIO40
|
||||
GP41 Pin = GPIO41
|
||||
GP42 Pin = GPIO42
|
||||
GP43 Pin = GPIO43
|
||||
GP44 Pin = GPIO44
|
||||
GP45 Pin = GPIO45
|
||||
GP46 Pin = GPIO46
|
||||
|
||||
// Boot button
|
||||
BUTTON Pin = GPIO24
|
||||
|
||||
// Onboard LED
|
||||
LED Pin = GPIO23
|
||||
|
||||
// Onboard NeoPixel
|
||||
NEOPIXEL Pin = GPIO25
|
||||
WS2812 Pin = GPIO25
|
||||
|
||||
// Onboard crystal oscillator frequency, in MHz.
|
||||
xoscFreq = 12 // MHz
|
||||
)
|
||||
|
||||
// Arduino-header digital pins
|
||||
const (
|
||||
RX Pin = GPIO1
|
||||
TX Pin = GPIO0
|
||||
D2 Pin = GPIO2
|
||||
D3 Pin = GPIO3
|
||||
D4 Pin = GPIO4
|
||||
D5 Pin = GPIO5
|
||||
D6 Pin = GPIO6
|
||||
D7 Pin = GPIO7
|
||||
D8 Pin = GPIO8
|
||||
D9 Pin = GPIO9
|
||||
D10 Pin = GPIO10
|
||||
D11 Pin = GPIO11
|
||||
D22 Pin = GPIO22
|
||||
D23 Pin = GPIO23
|
||||
)
|
||||
|
||||
// Arduino-header analog pins
|
||||
const (
|
||||
A0 Pin = GPIO41
|
||||
A1 Pin = GPIO42
|
||||
A2 Pin = GPIO43
|
||||
A3 Pin = GPIO44
|
||||
A4 Pin = GPIO45
|
||||
A5 Pin = GPIO46
|
||||
)
|
||||
|
||||
// I2C Default pins on Raspberry Pico.
|
||||
const (
|
||||
I2C0_SDA_PIN = GP20
|
||||
I2C0_SCL_PIN = GP21
|
||||
|
||||
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 = GPIO30
|
||||
// Default Serial Out Bus 1 for SPI communications
|
||||
SPI1_SDO_PIN = GPIO31 // Tx
|
||||
// Default Serial In Bus 1 for SPI communications
|
||||
SPI1_SDI_PIN = GPIO28 // Rx
|
||||
|
||||
// SPI header pins
|
||||
MOSI Pin = SPI1_SDO_PIN
|
||||
MISO Pin = SPI1_SDI_PIN
|
||||
SCK Pin = SPI1_SCK_PIN
|
||||
)
|
||||
|
||||
// SD card reader pins
|
||||
const (
|
||||
SD_SCK = GPIO34
|
||||
SD_MOSI = GPIO35
|
||||
SD_MISO = GPIO36
|
||||
SDIO_DATA1 = GPIO37
|
||||
SDIO_DATA2 = GPIO38
|
||||
SD_CS = GPIO39
|
||||
SD_CARD_DETECT = GPIO40
|
||||
)
|
||||
|
||||
// HSTX pins
|
||||
const (
|
||||
CKN Pin = GPIO15
|
||||
CKP Pin = GPIO14
|
||||
D0N Pin = GPIO19
|
||||
D0P Pin = GPIO18
|
||||
D1N Pin = GPIO17
|
||||
D1P Pin = GPIO16
|
||||
D2N Pin = GPIO13
|
||||
D2P Pin = GPIO12
|
||||
D26 Pin = GPIO26
|
||||
D27 Pin = GPIO27
|
||||
SCL Pin = GPIO21
|
||||
SDA Pin = GPIO20
|
||||
)
|
||||
|
||||
// USB host header pins
|
||||
const (
|
||||
USB_HOST_DATA_PLUS Pin = GPIO32
|
||||
USB_HOST_DATA_MINUS Pin = GPIO33
|
||||
USB_HOST_5V_POWER Pin = GPIO29
|
||||
)
|
||||
|
||||
// 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 = "Metro RP2350"
|
||||
usb_STRING_MANUFACTURER = "Adafruit"
|
||||
)
|
||||
|
||||
var (
|
||||
usb_VID uint16 = 0x239A
|
||||
usb_PID uint16 = 0x814E
|
||||
)
|
||||
@@ -78,14 +78,14 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
|
||||
// Allow scheduler to run
|
||||
gosched()
|
||||
|
||||
// Handle first occurrence of error by ensuring STOP sent on bus
|
||||
if err == nil && i2c.Bus.EVENTS_ERROR.Get() != 0 {
|
||||
err = twiCError(i2c.Bus.ERRORSRC.Get())
|
||||
// Handle errors by ensuring STOP sent on bus
|
||||
if i2c.Bus.EVENTS_ERROR.Get() != 0 {
|
||||
if i2c.Bus.EVENTS_STOPPED.Get() == 0 {
|
||||
// STOP cannot be sent during SUSPEND
|
||||
i2c.Bus.TASKS_RESUME.Set(1)
|
||||
i2c.Bus.TASKS_STOP.Set(1)
|
||||
}
|
||||
err = twiCError(i2c.Bus.ERRORSRC.Get())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,10 +58,6 @@ func machineInit() {
|
||||
|
||||
// Peripheral clocks should now all be running
|
||||
unresetBlockWait(RESETS_RESET_Msk)
|
||||
|
||||
// DBGPAUSE pauses the timer when a debugger is connected. This prevents
|
||||
// sleep functions from ever returning, so disable it.
|
||||
timer.setDbgPause(false)
|
||||
}
|
||||
|
||||
//go:linkname ticks runtime.machineTicks
|
||||
|
||||
@@ -100,8 +100,7 @@ func ReadTemperature() (millicelsius int32) {
|
||||
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
||||
|
||||
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
||||
// 1/0.001721 ≈ 581
|
||||
return int32(((int64(27000) << 16) - ((int64(thermChan.getVoltage()) - (int64(706) << 16)) * 581)) >> 16)
|
||||
return (27000<<16 - (int32(thermChan.getVoltage())-706<<16)*581) >> 16
|
||||
}
|
||||
|
||||
// waitForReady spins waiting for the ADC peripheral to become ready.
|
||||
|
||||
@@ -101,15 +101,3 @@ func (tmr *timerType) lightSleep(us uint64) {
|
||||
// Disable interrupt
|
||||
intr.Disable()
|
||||
}
|
||||
|
||||
// setDbgPause sets whether this timer is paused when a debugger is connected.
|
||||
func (tmr *timerType) setDbgPause(enable bool) {
|
||||
const bitPos = 1
|
||||
const bitMask = 0b11
|
||||
val := uint32(0b00)
|
||||
if enable {
|
||||
// Disable timer when debugger is connected to either core.
|
||||
val = 0b11
|
||||
}
|
||||
tmr.dbgPause.ReplaceBits(val, bitMask, bitPos)
|
||||
}
|
||||
|
||||
@@ -104,9 +104,7 @@ func (uart *UART) SetBaudRate(br uint32) {
|
||||
func (uart *UART) writeByte(c byte) error {
|
||||
// wait until buffer is not full
|
||||
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) {
|
||||
if !interrupt.In() {
|
||||
gosched()
|
||||
}
|
||||
gosched()
|
||||
}
|
||||
|
||||
// write data
|
||||
@@ -116,9 +114,7 @@ func (uart *UART) writeByte(c byte) error {
|
||||
|
||||
func (uart *UART) flush() {
|
||||
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_BUSY) {
|
||||
if !interrupt.In() {
|
||||
gosched()
|
||||
}
|
||||
gosched()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ import (
|
||||
)
|
||||
|
||||
// This symbol name is known by the compiler, see monitor.go.
|
||||
//
|
||||
//go:linkname rttSerialInstance _SEGGER_RTT
|
||||
var rttSerialInstance rttSerial
|
||||
|
||||
var Serial = &rttSerialInstance
|
||||
|
||||
+1
-1
Submodule src/net updated: bb43b40f19...77be3968d1
@@ -12,6 +12,7 @@ package os
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
_ "unsafe"
|
||||
)
|
||||
|
||||
const DevNull = "/dev/null"
|
||||
|
||||
@@ -127,11 +127,6 @@ type Method struct {
|
||||
Index int // index for Type.Method
|
||||
}
|
||||
|
||||
// IsExported reports whether the method is exported.
|
||||
func (m Method) IsExported() bool {
|
||||
return m.PkgPath == ""
|
||||
}
|
||||
|
||||
// The following Type type has been copied almost entirely from
|
||||
// https://github.com/golang/go/blob/go1.15/src/reflect/type.go#L27-L212.
|
||||
// Some methods have been commented out as they haven't yet been implemented.
|
||||
|
||||
@@ -81,8 +81,8 @@ func (it *MapIter) Next() bool {
|
||||
return ((*reflectlite.MapIter)(it)).Next()
|
||||
}
|
||||
|
||||
func (it *MapIter) Reset(v Value) {
|
||||
(*reflectlite.MapIter)(it).Reset(v.Value)
|
||||
func (iter *MapIter) Reset(v Value) {
|
||||
(*reflectlite.MapIter)(iter).Reset(v.Value)
|
||||
}
|
||||
|
||||
func (v Value) Set(x Value) {
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package runtime
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
// TODO: Use hardware when available
|
||||
//
|
||||
//go:linkname vgetrandom
|
||||
func vgetrandom(p []byte, flags uint32) (ret int, supported bool) { return 0, false }
|
||||
|
||||
//go:linkname fatal crypto/internal/sysrand.fatal
|
||||
func fatal(msg string) { runtimePanic(msg) }
|
||||
@@ -106,33 +106,6 @@ func UnlockOSThread() {
|
||||
// point of the call.
|
||||
func KeepAlive(x interface{})
|
||||
|
||||
// AddCleanup is a dummy cleanup implementation. It doesn't do any cleaning up.
|
||||
//
|
||||
// We base this on the following loophole in the official runtime.AddCleanup
|
||||
// documentation:
|
||||
//
|
||||
// > The cleanup(arg) call is not always guaranteed to run; in particular it is
|
||||
// > not guaranteed to run before program exit.
|
||||
//
|
||||
// So it's technically correct (the best kind of correct) to not run any
|
||||
// cleanups. But of course, this can lead to resource leaks so cleanups may need
|
||||
// to be implemented eventually.
|
||||
func AddCleanup[T, S any](ptr *T, cleanup func(S), arg S) Cleanup {
|
||||
return Cleanup{}
|
||||
}
|
||||
|
||||
type Cleanup struct{}
|
||||
|
||||
func (c Cleanup) Stop() {}
|
||||
|
||||
//go:linkname registerWeakPointer weak.runtime_registerWeakPointer
|
||||
func registerWeakPointer(ptr unsafe.Pointer) unsafe.Pointer {
|
||||
// TODO: unimplemented.
|
||||
// I hope not implementing this won't break anything, like packages that
|
||||
// expect weak pointers to be GC'd before they actually are.
|
||||
return ptr
|
||||
}
|
||||
|
||||
var godebugUpdate func(string, string)
|
||||
|
||||
//go:linkname godebug_setUpdate internal/godebug.setUpdate
|
||||
|
||||
@@ -1,380 +0,0 @@
|
||||
//go:build rp2040 || rp2350
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/rp"
|
||||
"internal/task"
|
||||
"machine"
|
||||
"machine/usb/cdc"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const numCPU = 2
|
||||
const numSpinlocks = 32
|
||||
|
||||
// machineTicks is provided by package machine.
|
||||
func machineTicks() uint64
|
||||
|
||||
// machineLightSleep is provided by package machine.
|
||||
func machineLightSleep(uint64)
|
||||
|
||||
// ticks returns the number of ticks (microseconds) elapsed since power up.
|
||||
func ticks() timeUnit {
|
||||
t := machineTicks()
|
||||
return timeUnit(t)
|
||||
}
|
||||
|
||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
||||
return int64(ticks) * 1000
|
||||
}
|
||||
|
||||
func nanosecondsToTicks(ns int64) timeUnit {
|
||||
return timeUnit(ns / 1000)
|
||||
}
|
||||
|
||||
func sleepTicks(d timeUnit) {
|
||||
if hasScheduler {
|
||||
// With scheduler, sleepTicks may return early if an interrupt or
|
||||
// event fires - so scheduler can schedule any go routines now
|
||||
// eligible to run
|
||||
machineLightSleep(uint64(d))
|
||||
return
|
||||
}
|
||||
|
||||
// Busy loop
|
||||
sleepUntil := ticks() + d
|
||||
for ticks() < sleepUntil {
|
||||
}
|
||||
}
|
||||
|
||||
// Currently sleeping core, or 0xff.
|
||||
// Must only be accessed with the scheduler lock held.
|
||||
var sleepingCore uint8 = 0xff
|
||||
|
||||
// Return whether another core is sleeping.
|
||||
// May only be called with the scheduler lock held.
|
||||
func hasSleepingCore() bool {
|
||||
return sleepingCore != 0xff
|
||||
}
|
||||
|
||||
// Almost identical to sleepTicks, except that it will unlock/lock the scheduler
|
||||
// while sleeping and is interruptible by interruptSleepTicksMulticore.
|
||||
// This may only be called with the scheduler lock held.
|
||||
func sleepTicksMulticore(d timeUnit) {
|
||||
sleepingCore = uint8(currentCPU())
|
||||
|
||||
// Note: interruptSleepTicksMulticore will be able to interrupt this, since
|
||||
// it executes the "sev" instruction which would make sleepTicks return
|
||||
// immediately without sleeping. Even if it happens while configuring the
|
||||
// sleep operation.
|
||||
|
||||
schedulerLock.Unlock()
|
||||
sleepTicks(d)
|
||||
schedulerLock.Lock()
|
||||
|
||||
sleepingCore = 0xff
|
||||
}
|
||||
|
||||
// Interrupt an ongoing call to sleepTicksMulticore on another core.
|
||||
func interruptSleepTicksMulticore(wakeup timeUnit) {
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
// Number of cores that are currently in schedulerUnlockAndWait.
|
||||
// It is possible for both cores to be sleeping, if the program is waiting for
|
||||
// an interrupt (or is deadlocked).
|
||||
var waitingCore uint8
|
||||
|
||||
// Put the scheduler to sleep, since there are no tasks to run.
|
||||
// This will unlock the scheduler lock, and must be called with the scheduler
|
||||
// lock held.
|
||||
func schedulerUnlockAndWait() {
|
||||
waitingCore++
|
||||
schedulerLock.Unlock()
|
||||
arm.Asm("wfe")
|
||||
schedulerLock.Lock()
|
||||
waitingCore--
|
||||
}
|
||||
|
||||
// Wake another core, if one is sleeping. Must be called with the scheduler lock
|
||||
// held.
|
||||
func schedulerWake() {
|
||||
if waitingCore != 0 {
|
||||
arm.Asm("sev")
|
||||
}
|
||||
}
|
||||
|
||||
// Return the current core number: 0 or 1.
|
||||
func currentCPU() uint32 {
|
||||
return rp.SIO.CPUID.Get()
|
||||
}
|
||||
|
||||
// Start the secondary cores for this chip.
|
||||
// On the RP2040/RP2350, there is only one other core to start.
|
||||
func startSecondaryCores() {
|
||||
// Start the second core of the RP2040/RP2350.
|
||||
// See sections 2.8.2 and 5.3 in the datasheets for RP2040 and RP2350 respectively.
|
||||
seq := 0
|
||||
for {
|
||||
cmd := core1StartSequence[seq]
|
||||
if cmd == 0 {
|
||||
multicore_fifo_drain()
|
||||
arm.Asm("sev")
|
||||
}
|
||||
multicore_fifo_push_blocking(cmd)
|
||||
response := multicore_fifo_pop_blocking()
|
||||
if cmd != response {
|
||||
seq = 0
|
||||
continue
|
||||
}
|
||||
seq = seq + 1
|
||||
if seq >= len(core1StartSequence) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the FIFO interrupt for the GC stop the world phase.
|
||||
// We can only do this after we don't need the FIFO anymore for starting the
|
||||
// second core.
|
||||
intr := interrupt.New(sioIrqFifoProc0, func(intr interrupt.Interrupt) {
|
||||
switch rp.SIO.FIFO_RD.Get() {
|
||||
case 1:
|
||||
gcInterruptHandler(0)
|
||||
}
|
||||
})
|
||||
intr.Enable()
|
||||
intr.SetPriority(0xff)
|
||||
}
|
||||
|
||||
var core1StartSequence = [...]uint32{
|
||||
0, 0, 1,
|
||||
uint32(uintptr(unsafe.Pointer(&__isr_vector))),
|
||||
uint32(uintptr(unsafe.Pointer(&stack1TopSymbol))),
|
||||
uint32(exportedFuncPtr(runCore1)),
|
||||
}
|
||||
|
||||
//go:extern __isr_vector
|
||||
var __isr_vector [0]uint32
|
||||
|
||||
//go:extern _stack1_top
|
||||
var stack1TopSymbol [0]uint32
|
||||
|
||||
// The function that is started on the second core.
|
||||
//
|
||||
//export tinygo_runCore1
|
||||
func runCore1() {
|
||||
// Clear sticky bit that seems to have been set while starting this core.
|
||||
rp.SIO.FIFO_ST.Set(rp.SIO_FIFO_ST_ROE)
|
||||
|
||||
// Enable the FIFO interrupt, mainly used for the stop-the-world phase of
|
||||
// the GC.
|
||||
// Use the lowest possible priority (highest priority value), so that other
|
||||
// interrupts can still happen while the GC is running.
|
||||
intr := interrupt.New(sioIrqFifoProc1, func(intr interrupt.Interrupt) {
|
||||
switch rp.SIO.FIFO_RD.Get() {
|
||||
case 1:
|
||||
gcInterruptHandler(1)
|
||||
}
|
||||
})
|
||||
intr.Enable()
|
||||
intr.SetPriority(0xff)
|
||||
|
||||
// Now start running the scheduler on this core.
|
||||
schedulerLock.Lock()
|
||||
scheduler(false)
|
||||
schedulerLock.Unlock()
|
||||
|
||||
// The main function returned.
|
||||
exit(0)
|
||||
}
|
||||
|
||||
// The below multicore_fifo_* functions have been translated from the Raspberry
|
||||
// Pi Pico SDK.
|
||||
|
||||
func multicore_fifo_rvalid() bool {
|
||||
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_VLD != 0
|
||||
}
|
||||
|
||||
func multicore_fifo_wready() bool {
|
||||
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_RDY != 0
|
||||
}
|
||||
|
||||
func multicore_fifo_drain() {
|
||||
for multicore_fifo_rvalid() {
|
||||
rp.SIO.FIFO_RD.Get()
|
||||
}
|
||||
}
|
||||
|
||||
func multicore_fifo_push_blocking(data uint32) {
|
||||
for !multicore_fifo_wready() {
|
||||
}
|
||||
rp.SIO.FIFO_WR.Set(data)
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
func multicore_fifo_pop_blocking() uint32 {
|
||||
for !multicore_fifo_rvalid() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
return rp.SIO.FIFO_RD.Get()
|
||||
}
|
||||
|
||||
// Value used to communicate between the GC core and the other (paused) cores.
|
||||
var gcSignalWait volatile.Register8
|
||||
|
||||
// The GC interrupted this core for the stop-the-world phase.
|
||||
// This function handles that, and only returns after the stop-the-world phase
|
||||
// ended.
|
||||
func gcInterruptHandler(hartID uint32) {
|
||||
// Let the GC know we're ready.
|
||||
gcScanState.Add(1)
|
||||
arm.Asm("sev")
|
||||
|
||||
// Wait until we get a signal to start scanning.
|
||||
for gcSignalWait.Get() == 0 {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
gcSignalWait.Set(0)
|
||||
|
||||
// Scan the stack(s) of this core.
|
||||
scanCurrentStack()
|
||||
if !task.OnSystemStack() {
|
||||
// Mark system stack.
|
||||
markRoots(task.SystemStack(), coreStackTop(hartID))
|
||||
}
|
||||
|
||||
// Signal we've finished scanning.
|
||||
gcScanState.Store(1)
|
||||
arm.Asm("sev")
|
||||
|
||||
// Wait until we get a signal that the stop-the-world phase has ended.
|
||||
for gcSignalWait.Get() == 0 {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
gcSignalWait.Set(0)
|
||||
|
||||
// Signal we received the signal and are going to exit the interrupt.
|
||||
gcScanState.Add(1)
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
// Pause the given core by sending it an interrupt.
|
||||
func gcPauseCore(core uint32) {
|
||||
rp.SIO.FIFO_WR.Set(1)
|
||||
}
|
||||
|
||||
// Signal the given core that it can resume one step.
|
||||
// This is called twice after gcPauseCore: the first time to scan the stack of
|
||||
// the core, and the second time to end the stop-the-world phase.
|
||||
func gcSignalCore(core uint32) {
|
||||
gcSignalWait.Set(1)
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
// Returns the stack top (highest address) of the system stack of the given
|
||||
// core.
|
||||
func coreStackTop(core uint32) uintptr {
|
||||
switch core {
|
||||
case 0:
|
||||
return uintptr(unsafe.Pointer(&stackTopSymbol))
|
||||
case 1:
|
||||
return uintptr(unsafe.Pointer(&stack1TopSymbol))
|
||||
default:
|
||||
runtimePanic("unexpected core")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// These spinlocks are needed by the runtime.
|
||||
var (
|
||||
printLock = spinLock{id: 20}
|
||||
schedulerLock = spinLock{id: 21}
|
||||
atomicsLock = spinLock{id: 22}
|
||||
futexLock = spinLock{id: 23}
|
||||
)
|
||||
|
||||
func resetSpinLocks() {
|
||||
for i := uint8(0); i < numSpinlocks; i++ {
|
||||
l := &spinLock{id: i}
|
||||
l.spinlock().Set(0)
|
||||
}
|
||||
}
|
||||
|
||||
// A hardware spinlock, one of the 32 spinlocks defined in the SIO peripheral.
|
||||
type spinLock struct {
|
||||
id uint8
|
||||
}
|
||||
|
||||
// Return the spinlock register: rp.SIO.SPINLOCKx
|
||||
func (l *spinLock) spinlock() *volatile.Register32 {
|
||||
return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&rp.SIO.SPINLOCK0), l.id*4))
|
||||
}
|
||||
|
||||
func (l *spinLock) Lock() {
|
||||
// Wait for the lock to be available.
|
||||
spinlock := l.spinlock()
|
||||
for spinlock.Get() == 0 {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
}
|
||||
|
||||
func (l *spinLock) Unlock() {
|
||||
l.spinlock().Set(0)
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
// Wait until a signal is received, indicating that it can resume from the
|
||||
// spinloop.
|
||||
func spinLoopWait() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
func waitForEvents() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
func putchar(c byte) {
|
||||
machine.Serial.WriteByte(c)
|
||||
}
|
||||
|
||||
func getchar() byte {
|
||||
for machine.Serial.Buffered() == 0 {
|
||||
Gosched()
|
||||
}
|
||||
v, _ := machine.Serial.ReadByte()
|
||||
return v
|
||||
}
|
||||
|
||||
func buffered() int {
|
||||
return machine.Serial.Buffered()
|
||||
}
|
||||
|
||||
// machineInit is provided by package machine.
|
||||
func machineInit()
|
||||
|
||||
func init() {
|
||||
machineInit()
|
||||
|
||||
cdc.EnableUSBCDC()
|
||||
machine.USBDev.Configure(machine.UARTConfig{})
|
||||
machine.InitSerial()
|
||||
}
|
||||
|
||||
func prerun() {
|
||||
// Reset spinlocks before the full machineInit() so the scheduler doesn't
|
||||
// hang waiting for schedulerLock after a soft reset.
|
||||
resetSpinLocks()
|
||||
}
|
||||
|
||||
//export Reset_Handler
|
||||
func main() {
|
||||
preinit()
|
||||
prerun()
|
||||
run()
|
||||
exit(0)
|
||||
}
|
||||
@@ -3,10 +3,365 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
"device/rp"
|
||||
"internal/task"
|
||||
"machine"
|
||||
"machine/usb/cdc"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_PROC0
|
||||
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_PROC1
|
||||
const numCPU = 2
|
||||
|
||||
// machineTicks is provided by package machine.
|
||||
func machineTicks() uint64
|
||||
|
||||
// machineLightSleep is provided by package machine.
|
||||
func machineLightSleep(uint64)
|
||||
|
||||
// ticks returns the number of ticks (microseconds) elapsed since power up.
|
||||
func ticks() timeUnit {
|
||||
t := machineTicks()
|
||||
return timeUnit(t)
|
||||
}
|
||||
|
||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
||||
return int64(ticks) * 1000
|
||||
}
|
||||
|
||||
func nanosecondsToTicks(ns int64) timeUnit {
|
||||
return timeUnit(ns / 1000)
|
||||
}
|
||||
|
||||
func sleepTicks(d timeUnit) {
|
||||
if hasScheduler {
|
||||
// With scheduler, sleepTicks may return early if an interrupt or
|
||||
// event fires - so scheduler can schedule any go routines now
|
||||
// eligible to run
|
||||
machineLightSleep(uint64(d))
|
||||
return
|
||||
}
|
||||
|
||||
// Busy loop
|
||||
sleepUntil := ticks() + d
|
||||
for ticks() < sleepUntil {
|
||||
}
|
||||
}
|
||||
|
||||
// Currently sleeping core, or 0xff.
|
||||
// Must only be accessed with the scheduler lock held.
|
||||
var sleepingCore uint8 = 0xff
|
||||
|
||||
// Return whether another core is sleeping.
|
||||
// May only be called with the scheduler lock held.
|
||||
func hasSleepingCore() bool {
|
||||
return sleepingCore != 0xff
|
||||
}
|
||||
|
||||
// Almost identical to sleepTicks, except that it will unlock/lock the scheduler
|
||||
// while sleeping and is interruptible by interruptSleepTicksMulticore.
|
||||
// This may only be called with the scheduler lock held.
|
||||
func sleepTicksMulticore(d timeUnit) {
|
||||
sleepingCore = uint8(currentCPU())
|
||||
|
||||
// Note: interruptSleepTicksMulticore will be able to interrupt this, since
|
||||
// it executes the "sev" instruction which would make sleepTicks return
|
||||
// immediately without sleeping. Even if it happens while configuring the
|
||||
// sleep operation.
|
||||
|
||||
schedulerLock.Unlock()
|
||||
sleepTicks(d)
|
||||
schedulerLock.Lock()
|
||||
|
||||
sleepingCore = 0xff
|
||||
}
|
||||
|
||||
// Interrupt an ongoing call to sleepTicksMulticore on another core.
|
||||
func interruptSleepTicksMulticore(wakeup timeUnit) {
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
// Number of cores that are currently in schedulerUnlockAndWait.
|
||||
// It is possible for both cores to be sleeping, if the program is waiting for
|
||||
// an interrupt (or is deadlocked).
|
||||
var waitingCore uint8
|
||||
|
||||
// Put the scheduler to sleep, since there are no tasks to run.
|
||||
// This will unlock the scheduler lock, and must be called with the scheduler
|
||||
// lock held.
|
||||
func schedulerUnlockAndWait() {
|
||||
waitingCore++
|
||||
schedulerLock.Unlock()
|
||||
arm.Asm("wfe")
|
||||
schedulerLock.Lock()
|
||||
waitingCore--
|
||||
}
|
||||
|
||||
// Wake another core, if one is sleeping. Must be called with the scheduler lock
|
||||
// held.
|
||||
func schedulerWake() {
|
||||
if waitingCore != 0 {
|
||||
arm.Asm("sev")
|
||||
}
|
||||
}
|
||||
|
||||
// Return the current core number: 0 or 1.
|
||||
func currentCPU() uint32 {
|
||||
return rp.SIO.CPUID.Get()
|
||||
}
|
||||
|
||||
// Start the secondary cores for this chip.
|
||||
// On the RP2040, there is only one other core to start.
|
||||
func startSecondaryCores() {
|
||||
// Start the second core of the RP2040.
|
||||
// See section 2.8.2 in the datasheet.
|
||||
seq := 0
|
||||
for {
|
||||
cmd := core1StartSequence[seq]
|
||||
if cmd == 0 {
|
||||
multicore_fifo_drain()
|
||||
arm.Asm("sev")
|
||||
}
|
||||
multicore_fifo_push_blocking(cmd)
|
||||
response := multicore_fifo_pop_blocking()
|
||||
if cmd != response {
|
||||
seq = 0
|
||||
continue
|
||||
}
|
||||
seq = seq + 1
|
||||
if seq >= len(core1StartSequence) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the FIFO interrupt for the GC stop the world phase.
|
||||
// We can only do this after we don't need the FIFO anymore for starting the
|
||||
// second core.
|
||||
intr := interrupt.New(rp.IRQ_SIO_IRQ_PROC0, func(intr interrupt.Interrupt) {
|
||||
switch rp.SIO.FIFO_RD.Get() {
|
||||
case 1:
|
||||
gcInterruptHandler(0)
|
||||
}
|
||||
})
|
||||
intr.Enable()
|
||||
intr.SetPriority(0xff)
|
||||
}
|
||||
|
||||
var core1StartSequence = [...]uint32{
|
||||
0, 0, 1,
|
||||
uint32(uintptr(unsafe.Pointer(&__isr_vector))),
|
||||
uint32(uintptr(unsafe.Pointer(&stack1TopSymbol))),
|
||||
uint32(exportedFuncPtr(runCore1)),
|
||||
}
|
||||
|
||||
//go:extern __isr_vector
|
||||
var __isr_vector [0]uint32
|
||||
|
||||
//go:extern _stack1_top
|
||||
var stack1TopSymbol [0]uint32
|
||||
|
||||
// The function that is started on the second core.
|
||||
//
|
||||
//export tinygo_runCore1
|
||||
func runCore1() {
|
||||
// Clear sticky bit that seems to have been set while starting this core.
|
||||
rp.SIO.FIFO_ST.Set(rp.SIO_FIFO_ST_ROE)
|
||||
|
||||
// Enable the FIFO interrupt, mainly used for the stop-the-world phase of
|
||||
// the GC.
|
||||
// Use the lowest possible priority (highest priority value), so that other
|
||||
// interrupts can still happen while the GC is running.
|
||||
intr := interrupt.New(rp.IRQ_SIO_IRQ_PROC1, func(intr interrupt.Interrupt) {
|
||||
switch rp.SIO.FIFO_RD.Get() {
|
||||
case 1:
|
||||
gcInterruptHandler(1)
|
||||
}
|
||||
})
|
||||
intr.Enable()
|
||||
intr.SetPriority(0xff)
|
||||
|
||||
// Now start running the scheduler on this core.
|
||||
schedulerLock.Lock()
|
||||
scheduler(false)
|
||||
schedulerLock.Unlock()
|
||||
|
||||
// The main function returned.
|
||||
exit(0)
|
||||
}
|
||||
|
||||
// The below multicore_fifo_* functions have been translated from the Raspberry
|
||||
// Pi Pico SDK.
|
||||
|
||||
func multicore_fifo_rvalid() bool {
|
||||
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_VLD != 0
|
||||
}
|
||||
|
||||
func multicore_fifo_wready() bool {
|
||||
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_RDY != 0
|
||||
}
|
||||
|
||||
func multicore_fifo_drain() {
|
||||
for multicore_fifo_rvalid() {
|
||||
rp.SIO.FIFO_RD.Get()
|
||||
}
|
||||
}
|
||||
|
||||
func multicore_fifo_push_blocking(data uint32) {
|
||||
for !multicore_fifo_wready() {
|
||||
}
|
||||
rp.SIO.FIFO_WR.Set(data)
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
func multicore_fifo_pop_blocking() uint32 {
|
||||
for !multicore_fifo_rvalid() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
return rp.SIO.FIFO_RD.Get()
|
||||
}
|
||||
|
||||
// Value used to communicate between the GC core and the other (paused) cores.
|
||||
var gcSignalWait volatile.Register8
|
||||
|
||||
// The GC interrupted this core for the stop-the-world phase.
|
||||
// This function handles that, and only returns after the stop-the-world phase
|
||||
// ended.
|
||||
func gcInterruptHandler(hartID uint32) {
|
||||
// Let the GC know we're ready.
|
||||
gcScanState.Add(1)
|
||||
arm.Asm("sev")
|
||||
|
||||
// Wait until we get a signal to start scanning.
|
||||
for gcSignalWait.Get() == 0 {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
gcSignalWait.Set(0)
|
||||
|
||||
// Scan the stack(s) of this core.
|
||||
scanCurrentStack()
|
||||
if !task.OnSystemStack() {
|
||||
// Mark system stack.
|
||||
markRoots(task.SystemStack(), coreStackTop(hartID))
|
||||
}
|
||||
|
||||
// Signal we've finished scanning.
|
||||
gcScanState.Store(1)
|
||||
arm.Asm("sev")
|
||||
|
||||
// Wait until we get a signal that the stop-the-world phase has ended.
|
||||
for gcSignalWait.Get() == 0 {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
gcSignalWait.Set(0)
|
||||
|
||||
// Signal we received the signal and are going to exit the interrupt.
|
||||
gcScanState.Add(1)
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
// Pause the given core by sending it an interrupt.
|
||||
func gcPauseCore(core uint32) {
|
||||
rp.SIO.FIFO_WR.Set(1)
|
||||
}
|
||||
|
||||
// Signal the given core that it can resume one step.
|
||||
// This is called twice after gcPauseCore: the first time to scan the stack of
|
||||
// the core, and the second time to end the stop-the-world phase.
|
||||
func gcSignalCore(core uint32) {
|
||||
gcSignalWait.Set(1)
|
||||
arm.Asm("sev")
|
||||
}
|
||||
|
||||
// Returns the stack top (highest address) of the system stack of the given
|
||||
// core.
|
||||
func coreStackTop(core uint32) uintptr {
|
||||
switch core {
|
||||
case 0:
|
||||
return uintptr(unsafe.Pointer(&stackTopSymbol))
|
||||
case 1:
|
||||
return uintptr(unsafe.Pointer(&stack1TopSymbol))
|
||||
default:
|
||||
runtimePanic("unexpected core")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// These spinlocks are needed by the runtime.
|
||||
var (
|
||||
printLock = spinLock{id: 0}
|
||||
schedulerLock = spinLock{id: 1}
|
||||
atomicsLock = spinLock{id: 2}
|
||||
futexLock = spinLock{id: 3}
|
||||
)
|
||||
|
||||
// A hardware spinlock, one of the 32 spinlocks defined in the SIO peripheral.
|
||||
type spinLock struct {
|
||||
id uint8
|
||||
}
|
||||
|
||||
// Return the spinlock register: rp.SIO.SPINLOCKx
|
||||
func (l *spinLock) spinlock() *volatile.Register32 {
|
||||
return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&rp.SIO.SPINLOCK0), l.id*4))
|
||||
}
|
||||
|
||||
func (l *spinLock) Lock() {
|
||||
// Wait for the lock to be available.
|
||||
spinlock := l.spinlock()
|
||||
for spinlock.Get() == 0 {
|
||||
// TODO: use wfe and send an event when unlocking so the CPU can go to
|
||||
// sleep while waiting for the lock.
|
||||
// Unfortunately when doing that, time.Sleep() seems to hang somewhere.
|
||||
// This needs some debugging to figure out.
|
||||
}
|
||||
}
|
||||
|
||||
func (l *spinLock) Unlock() {
|
||||
l.spinlock().Set(0)
|
||||
}
|
||||
|
||||
// Wait until a signal is received, indicating that it can resume from the
|
||||
// spinloop.
|
||||
func spinLoopWait() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
func waitForEvents() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
func putchar(c byte) {
|
||||
machine.Serial.WriteByte(c)
|
||||
}
|
||||
|
||||
func getchar() byte {
|
||||
for machine.Serial.Buffered() == 0 {
|
||||
Gosched()
|
||||
}
|
||||
v, _ := machine.Serial.ReadByte()
|
||||
return v
|
||||
}
|
||||
|
||||
func buffered() int {
|
||||
return machine.Serial.Buffered()
|
||||
}
|
||||
|
||||
// machineInit is provided by package machine.
|
||||
func machineInit()
|
||||
|
||||
func init() {
|
||||
machineInit()
|
||||
|
||||
cdc.EnableUSBCDC()
|
||||
machine.USBDev.Configure(machine.UARTConfig{})
|
||||
machine.InitSerial()
|
||||
}
|
||||
|
||||
//export Reset_Handler
|
||||
func main() {
|
||||
preinit()
|
||||
run()
|
||||
exit(0)
|
||||
}
|
||||
|
||||
@@ -3,14 +3,84 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"device/arm"
|
||||
"machine"
|
||||
"machine/usb/cdc"
|
||||
)
|
||||
|
||||
const (
|
||||
// On RP2040 each core has a different IRQ number: SIO_IRQ_PROC0 and SIO_IRQ_PROC1.
|
||||
// On RP2350 both cores share the same irq number (SIO_IRQ_PROC) just with a
|
||||
// different SIO interrupt output routed to that IRQ input on each core.
|
||||
// https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_multicore_1ga1413ebfa65114c6f408f4675897ac5ee
|
||||
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_FIFO
|
||||
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_FIFO
|
||||
)
|
||||
// machineTicks is provided by package machine.
|
||||
func machineTicks() uint64
|
||||
|
||||
// machineLightSleep is provided by package machine.
|
||||
func machineLightSleep(uint64)
|
||||
|
||||
// ticks returns the number of ticks (microseconds) elapsed since power up.
|
||||
func ticks() timeUnit {
|
||||
t := machineTicks()
|
||||
return timeUnit(t)
|
||||
}
|
||||
|
||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
||||
return int64(ticks) * 1000
|
||||
}
|
||||
|
||||
func nanosecondsToTicks(ns int64) timeUnit {
|
||||
return timeUnit(ns / 1000)
|
||||
}
|
||||
|
||||
func sleepTicks(d timeUnit) {
|
||||
if d <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if hasScheduler {
|
||||
// With scheduler, sleepTicks may return early if an interrupt or
|
||||
// event fires - so scheduler can schedule any go routines now
|
||||
// eligible to run
|
||||
machineLightSleep(uint64(d))
|
||||
return
|
||||
}
|
||||
|
||||
// Busy loop
|
||||
sleepUntil := ticks() + d
|
||||
for ticks() < sleepUntil {
|
||||
}
|
||||
}
|
||||
|
||||
func waitForEvents() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
func putchar(c byte) {
|
||||
machine.Serial.WriteByte(c)
|
||||
}
|
||||
|
||||
func getchar() byte {
|
||||
for machine.Serial.Buffered() == 0 {
|
||||
Gosched()
|
||||
}
|
||||
v, _ := machine.Serial.ReadByte()
|
||||
return v
|
||||
}
|
||||
|
||||
func buffered() int {
|
||||
return machine.Serial.Buffered()
|
||||
}
|
||||
|
||||
// machineInit is provided by package machine.
|
||||
func machineInit()
|
||||
|
||||
func init() {
|
||||
machineInit()
|
||||
|
||||
cdc.EnableUSBCDC()
|
||||
machine.USBDev.Configure(machine.UARTConfig{})
|
||||
machine.InitSerial()
|
||||
}
|
||||
|
||||
//export Reset_Handler
|
||||
func main() {
|
||||
preinit()
|
||||
run()
|
||||
exit(0)
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ func addSleepTask(t *task.Task, duration timeUnit) {
|
||||
panic("runtime: addSleepTask: expected next task to be nil")
|
||||
}
|
||||
}
|
||||
t.Data = uint64(duration)
|
||||
now := ticks()
|
||||
if sleepQueue == nil {
|
||||
scheduleLog(" -> sleep new queue")
|
||||
@@ -84,7 +85,6 @@ func addSleepTask(t *task.Task, duration timeUnit) {
|
||||
// set new base time
|
||||
sleepQueueBaseTime = now
|
||||
}
|
||||
t.Data = uint64(duration + (now - sleepQueueBaseTime))
|
||||
|
||||
// Add to sleep queue.
|
||||
q := &sleepQueue
|
||||
|
||||
@@ -46,9 +46,3 @@ func timerCallback(tn *timerNode, delta int64) {
|
||||
addTimer(tn)
|
||||
}
|
||||
}
|
||||
|
||||
//go:linkname time_runtimeIsBubbled time.runtimeIsBubbled
|
||||
func time_runtimeIsBubbled() bool {
|
||||
// We don't currently support bubbles.
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -70,15 +70,3 @@ func (m *Map) Range(f func(key, value interface{}) bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Swap replaces the value for the given key, and returns the old value if any.
|
||||
func (m *Map) Swap(key, value any) (previous any, loaded bool) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
if m.m == nil {
|
||||
m.m = make(map[interface{}]interface{})
|
||||
}
|
||||
previous, loaded = m.m[key]
|
||||
m.m[key] = value
|
||||
return
|
||||
}
|
||||
|
||||
@@ -17,22 +17,3 @@ func TestMapLoadAndDelete(t *testing.T) {
|
||||
t.Errorf("LoadAndDelete returned %v, %v, want nil, false", v, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapSwap(t *testing.T) {
|
||||
var sm sync.Map
|
||||
sm.Store("present", "value")
|
||||
|
||||
if v, ok := sm.Swap("present", "value2"); !ok || v != "value" {
|
||||
t.Errorf("Swap returned %v, %v, want value, true", v, ok)
|
||||
}
|
||||
if v, ok := sm.Load("present"); !ok || v != "value2" {
|
||||
t.Errorf("Load after Swap returned %v, %v, want value2, true", v, ok)
|
||||
}
|
||||
|
||||
if v, ok := sm.Swap("new", "foo"); ok || v != nil {
|
||||
t.Errorf("Swap returned %v, %v, want nil, false", v, ok)
|
||||
}
|
||||
if v, ok := sm.Load("present"); !ok || v != "value2" {
|
||||
t.Errorf("Load after Swap returned %v, %v, want foo, true", v, ok)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,6 @@ type RWMutex struct {
|
||||
|
||||
const rwMutexMaxReaders = 1 << 30
|
||||
|
||||
// Lock locks rw for writing.
|
||||
// If the lock is already locked for reading or writing,
|
||||
// Lock blocks until the lock is available.
|
||||
func (rw *RWMutex) Lock() {
|
||||
// Exclusive lock for writers.
|
||||
rw.writerLock.Lock()
|
||||
@@ -59,12 +56,6 @@ func (rw *RWMutex) Lock() {
|
||||
rw.writer.Store(0)
|
||||
}
|
||||
|
||||
// Unlock unlocks rw for writing. It is a run-time error if rw is
|
||||
// not locked for writing on entry to Unlock.
|
||||
//
|
||||
// As with Mutexes, a locked [RWMutex] is not associated with a particular
|
||||
// goroutine. One goroutine may [RWMutex.RLock] ([RWMutex.Lock]) a RWMutex and then
|
||||
// arrange for another goroutine to [RWMutex.RUnlock] ([RWMutex.Unlock]) it.
|
||||
func (rw *RWMutex) Unlock() {
|
||||
// Signal that new readers can lock this mutex.
|
||||
waiting := rw.readers.Add(rwMutexMaxReaders)
|
||||
@@ -77,31 +68,6 @@ func (rw *RWMutex) Unlock() {
|
||||
rw.writerLock.Unlock()
|
||||
}
|
||||
|
||||
// TryLock tries to lock m and reports whether it succeeded.
|
||||
//
|
||||
// Note that while correct uses of TryLock do exist, they are rare,
|
||||
// and use of TryLock is often a sign of a deeper problem
|
||||
// in a particular use of mutexes.
|
||||
func (rw *RWMutex) TryLock() bool {
|
||||
// Check for active writers
|
||||
if !rw.writerLock.TryLock() {
|
||||
return false
|
||||
}
|
||||
// Have write lock, now check for active readers
|
||||
n := uint32(rwMutexMaxReaders)
|
||||
if !rw.readers.CompareAndSwap(0, -n) {
|
||||
// Active readers, give up write lock
|
||||
rw.writerLock.Unlock()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// RLock locks rw for reading.
|
||||
//
|
||||
// It should not be used for recursive read locking; a blocked Lock
|
||||
// call excludes new readers from acquiring the lock. See the
|
||||
// documentation on the [RWMutex] type.
|
||||
func (rw *RWMutex) RLock() {
|
||||
// Add us as a reader.
|
||||
newVal := rw.readers.Add(1)
|
||||
@@ -113,10 +79,6 @@ func (rw *RWMutex) RLock() {
|
||||
}
|
||||
}
|
||||
|
||||
// RUnlock undoes a single [RWMutex.RLock] call;
|
||||
// it does not affect other simultaneous readers.
|
||||
// It is a run-time error if rw is not locked for reading
|
||||
// on entry to RUnlock.
|
||||
func (rw *RWMutex) RUnlock() {
|
||||
// Remove us as a reader.
|
||||
one := uint32(1)
|
||||
@@ -136,25 +98,6 @@ func (rw *RWMutex) RUnlock() {
|
||||
}
|
||||
}
|
||||
|
||||
// TryRLock tries to lock rw for reading and reports whether it succeeded.
|
||||
//
|
||||
// Note that while correct uses of TryRLock do exist, they are rare,
|
||||
// and use of TryRLock is often a sign of a deeper problem
|
||||
// in a particular use of mutexes.
|
||||
func (rw *RWMutex) TryRLock() bool {
|
||||
for {
|
||||
c := rw.readers.Load()
|
||||
if c < 0 {
|
||||
// There is a writer waiting or writing.
|
||||
return false
|
||||
}
|
||||
if rw.readers.CompareAndSwap(c, c+1) {
|
||||
// Read lock obtained.
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Locker interface {
|
||||
Lock()
|
||||
Unlock()
|
||||
|
||||
+1
-29
@@ -7,13 +7,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type mutex interface {
|
||||
Lock()
|
||||
Unlock()
|
||||
TryLock() bool
|
||||
}
|
||||
|
||||
func HammerMutex(m mutex, loops int, cdone chan bool) {
|
||||
func HammerMutex(m *sync.Mutex, loops int, cdone chan bool) {
|
||||
for i := 0; i < loops; i++ {
|
||||
if i%3 == 0 {
|
||||
if m.TryLock() {
|
||||
@@ -246,25 +240,3 @@ func TestRWMutexReadToWrite(t *testing.T) {
|
||||
t.Errorf("write lock acquired while %d readers were active", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRWMutex(t *testing.T) {
|
||||
m := new(sync.RWMutex)
|
||||
|
||||
m.Lock()
|
||||
if m.TryLock() {
|
||||
t.Fatalf("TryLock succeeded with mutex locked")
|
||||
}
|
||||
m.Unlock()
|
||||
if !m.TryLock() {
|
||||
t.Fatalf("TryLock failed with mutex unlocked")
|
||||
}
|
||||
m.Unlock()
|
||||
|
||||
c := make(chan bool)
|
||||
for i := 0; i < 10; i++ {
|
||||
go HammerMutex(m, 1000, c)
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
<-c
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,10 +500,6 @@ func (b *B) RunParallel(body func(*PB)) {
|
||||
return
|
||||
}
|
||||
|
||||
func (b *B) Loop() bool {
|
||||
panic("unimplemented: testing.B.Loop")
|
||||
}
|
||||
|
||||
// Benchmark benchmarks a single function. It is useful for creating
|
||||
// custom benchmarks that do not use the "go test" command.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["badger2040_w", "cyw43439"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["badger2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:1023"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["challenger_rp2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8M"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["239a:80f1"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["feather_rp2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8192K"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"inherits": ["attiny85"],
|
||||
"build-tags": ["gopher_arcade"],
|
||||
"ldflags": [
|
||||
"--defsym=_bootloader_size=2180",
|
||||
"--defsym=_stack_size=128"
|
||||
],
|
||||
"flash-command": "avrdude -c usbasp -p t85 -B 10 -U flash:w:{hex}:i",
|
||||
"emulator": "simavr -m attiny85 -f 16000000 {}"
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["gopher_badge"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8M"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"build-tags": ["macropad_rp2040"],
|
||||
"default-stack-size": 8192,
|
||||
"serial-port": ["239a:8107"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8M"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"inherits": [
|
||||
"rp2350b"
|
||||
],
|
||||
"build-tags": ["metro_rp2350"],
|
||||
"serial-port": ["239a:814e"],
|
||||
"default-stack-size": 8192,
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=16M"
|
||||
]
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2341:005e"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["nano_rp2040", "ninafw", "ninafw_machine_init"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=16M"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["239a:80f7"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["qtpy_rp2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8192K"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"qemu"
|
||||
],
|
||||
"scheduler": "cores",
|
||||
"default-stack-size": 16384,
|
||||
"default-stack-size": 8192,
|
||||
"cflags": [
|
||||
"-march=rv32imaczihintpause",
|
||||
"-DTINYGO_CORES=4"
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
"-march=rv32imac"
|
||||
],
|
||||
"ldflags": [
|
||||
"-melf32lriscv",
|
||||
"-mllvm", "-enable-machine-outliner=never"
|
||||
"-melf32lriscv"
|
||||
],
|
||||
"gdb": [
|
||||
"gdb-multiarch",
|
||||
|
||||
+1
-3
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"inherits": ["cortex-m33"],
|
||||
"build-tags": ["rp2350", "rp"],
|
||||
"scheduler": "cores",
|
||||
"flash-1200-bps-reset": "true",
|
||||
"flash-method": "msd",
|
||||
"serial": "usb",
|
||||
@@ -14,8 +13,7 @@
|
||||
"targets/rp2350_embedded_block.s"
|
||||
],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=2M",
|
||||
"--defsym=__num_stacks=2"
|
||||
"--defsym=__flash_size=2M"
|
||||
],
|
||||
"linkerscript": "targets/rp2350.ld",
|
||||
"openocd-interface": "picoprobe",
|
||||
|
||||
@@ -6,6 +6,5 @@
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=4M"
|
||||
],
|
||||
"serial-port": ["2e8a:000f"],
|
||||
"default-stack-size": 8192
|
||||
"serial-port": ["2e8a:000f"]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["239a:8109"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["trinkey_qt2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=8192K"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["tufty2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"llvm-target": "wasm32-unknown-unknown",
|
||||
"cpu": "mvp",
|
||||
"features": "+nontrapping-fptoint,+sign-ext,-bulk-memory,-multivalue,-reference-types",
|
||||
"cpu": "generic",
|
||||
"features": "+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-bulk-memory,-bulk-memory-opt,-multivalue,-reference-types",
|
||||
"build-tags": ["tinygo.wasm", "wasm_unknown"],
|
||||
"buildmode": "c-shared",
|
||||
"goos": "linux",
|
||||
@@ -15,6 +15,7 @@
|
||||
"cflags": [
|
||||
"-mnontrapping-fptoint",
|
||||
"-mno-bulk-memory",
|
||||
"-mno-bulk-memory-opt",
|
||||
"-mno-multivalue",
|
||||
"-mno-reference-types",
|
||||
"-msign-ext"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["waveshare_rp2040_tiny"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:0003"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["waveshare_rp2040_zero"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"rp2040"
|
||||
],
|
||||
"serial-port": ["2e8a:000a"],
|
||||
"default-stack-size": 8192,
|
||||
"build-tags": ["xiao_rp2040"],
|
||||
"ldflags": [
|
||||
"--defsym=__flash_size=1020K"
|
||||
|
||||
Vendored
+3
-3
@@ -14,9 +14,9 @@ func init() {
|
||||
func main() {
|
||||
println("main 1")
|
||||
go sub()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
println("main 2")
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
time.Sleep(2 * time.Millisecond)
|
||||
println("main 3")
|
||||
|
||||
// Await a blocking call.
|
||||
@@ -103,7 +103,7 @@ func acquire(m *sync.Mutex, wg *sync.WaitGroup) {
|
||||
|
||||
func sub() {
|
||||
println("sub 1")
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
time.Sleep(2 * time.Millisecond)
|
||||
println("sub 2")
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ package os_smoke_test
|
||||
// Intended to catch build tag mistakes affecting bare metal targets.
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
@@ -27,10 +25,3 @@ func TestFmt(t *testing.T) {
|
||||
t.Errorf("printf returned %d, expected 14", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/tinygo-org/tinygo/issues/4921
|
||||
func TestRand(t *testing.T) {
|
||||
if _, err := rsa.GenerateKey(rand.Reader, 2048); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
module github.com/tinygo-org/tinygo/tests/wasm
|
||||
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d
|
||||
github.com/chromedp/chromedp v0.14.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/chromedp/sysutil v1.1.0 // indirect
|
||||
github.com/go-json-experiment/json v0.0.0-20250725192818-e39067aee2d2 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.4.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
)
|
||||
@@ -1,21 +0,0 @@
|
||||
github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d h1:ZtA1sedVbEW7EW80Iz2GR3Ye6PwbJAJXjv7D74xG6HU=
|
||||
github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k=
|
||||
github.com/chromedp/chromedp v0.14.1 h1:0uAbnxewy/Q+Bg7oafVePE/6EXEho9hnaC38f+TTENg=
|
||||
github.com/chromedp/chromedp v0.14.1/go.mod h1:rHzAv60xDE7VNy/MYtTUrYreSc0ujt2O1/C3bzctYBo=
|
||||
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
|
||||
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
|
||||
github.com/go-json-experiment/json v0.0.0-20250725192818-e39067aee2d2 h1:iizUGZ9pEquQS5jTGkh4AqeeHCMbfbjeb0zMt0aEFzs=
|
||||
github.com/go-json-experiment/json v0.0.0-20250725192818-e39067aee2d2/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
|
||||
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
@@ -43,7 +43,6 @@ func chromectx(t *testing.T) context.Context {
|
||||
chromedp.Flag("disable-default-apps", true),
|
||||
chromedp.NoFirstRun,
|
||||
chromedp.Headless,
|
||||
chromedp.WSURLReadTimeout(45*time.Second),
|
||||
)
|
||||
|
||||
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
|
||||
@@ -82,7 +81,6 @@ func startServer(t *testing.T) (string, *httptest.Server) {
|
||||
<head>
|
||||
<title>Test</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="icon" href="data:,">
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
|
||||
Reference in New Issue
Block a user