mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 19:17:47 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1762476f3f |
@@ -30,22 +30,22 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu binaryen
|
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu binaryen
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Extract TinyGo version
|
- name: Extract TinyGo version
|
||||||
id: version
|
id: version
|
||||||
run: ./.github/workflows/tinygo-extract-version.sh | tee -a "$GITHUB_OUTPUT"
|
run: ./.github/workflows/tinygo-extract-version.sh | tee -a "$GITHUB_OUTPUT"
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.1'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Restore LLVM source cache
|
- name: Restore LLVM source cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-20-${{ matrix.os }}-v1
|
key: llvm-source-19-${{ matrix.os }}-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-20-${{ matrix.os }}-v2
|
key: llvm-build-19-${{ matrix.os }}-v1
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
rm -rf llvm-project
|
rm -rf llvm-project
|
||||||
make llvm-source
|
make llvm-source
|
||||||
# install dependencies
|
# install dependencies
|
||||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install ninja
|
HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake ninja
|
||||||
# build!
|
# build!
|
||||||
make llvm-build
|
make llvm-build
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
@@ -130,11 +130,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
brew install llvm@${{ matrix.version }}
|
brew install llvm@${{ matrix.version }}
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.1'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
||||||
run: go install -tags=llvm${{ matrix.version }}
|
run: go install -tags=llvm${{ matrix.version }}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
# tar: needed for actions/cache@v4
|
# tar: needed for actions/cache@v4
|
||||||
# git+openssh: needed for checkout (I think?)
|
# git+openssh: needed for checkout (I think?)
|
||||||
# ruby: needed to install fpm
|
# 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
|
- name: Work around CVE-2022-24765
|
||||||
# We're not on a multi-user machine, so this is safe.
|
# We're not on a multi-user machine, so this is safe.
|
||||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-20-linux-alpine-v1
|
key: llvm-source-19-linux-alpine-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -73,7 +73,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-20-linux-alpine-v1
|
key: llvm-build-19-linux-alpine-v1
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -197,7 +197,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-20-linux-asserts-v1
|
key: llvm-source-19-linux-asserts-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -222,7 +222,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-20-linux-asserts-v1
|
key: llvm-build-19-linux-asserts-v1
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -304,7 +304,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-20-linux-v1
|
key: llvm-source-19-linux-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -329,7 +329,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-20-linux-${{ matrix.goarch }}-v1
|
key: llvm-build-19-linux-${{ matrix.goarch }}-v3
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ jobs:
|
|||||||
uses: docker/metadata-action@v5
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
tinygo/llvm-20
|
tinygo/llvm-19
|
||||||
ghcr.io/${{ github.repository_owner }}/llvm-20
|
ghcr.io/${{ github.repository_owner }}/llvm-19
|
||||||
tags: |
|
tags: |
|
||||||
type=sha,format=long
|
type=sha,format=long
|
||||||
type=raw,value=latest
|
type=raw,value=latest
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-20-linux-nix-v1
|
key: llvm-source-19-linux-nix-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/compiler-rt
|
llvm-project/compiler-rt
|
||||||
- name: Download LLVM source
|
- name: Download LLVM source
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-20-sizediff-v1
|
key: llvm-source-19-sizediff-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/compiler-rt
|
llvm-project/compiler-rt
|
||||||
- name: Download LLVM source
|
- name: Download LLVM source
|
||||||
|
|||||||
@@ -13,9 +13,17 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-windows:
|
build-windows:
|
||||||
runs-on: windows-2022
|
runs-on: ${{ matrix.image }}
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.version.outputs.version }}
|
version: ${{ steps.version.outputs.version }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
goarch: [ amd64, arm64 ]
|
||||||
|
include:
|
||||||
|
- goarch: amd64
|
||||||
|
image: windows-2022
|
||||||
|
- goarch: arm64
|
||||||
|
image: windows-11-arm
|
||||||
steps:
|
steps:
|
||||||
- name: Configure pagefile
|
- name: Configure pagefile
|
||||||
uses: al-cheb/configure-pagefile-action@v1.4
|
uses: al-cheb/configure-pagefile-action@v1.4
|
||||||
@@ -47,7 +55,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-20-windows-v1
|
key: llvm-source-19-windows-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -72,7 +80,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-20-windows-v2
|
key: llvm-build-19-windows-${{ matrix.goarch }}-v1
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -94,7 +102,7 @@ jobs:
|
|||||||
- name: Cache Go cache
|
- name: Cache Go cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
key: go-cache-windows-v1-${{ hashFiles('go.mod') }}
|
key: go-cache-windows-${{ matrix.goarch }}-v1-${{ hashFiles('go.mod') }}
|
||||||
path: |
|
path: |
|
||||||
C:/Users/runneradmin/AppData/Local/go-build
|
C:/Users/runneradmin/AppData/Local/go-build
|
||||||
C:/Users/runneradmin/go/pkg/mod
|
C:/Users/runneradmin/go/pkg/mod
|
||||||
@@ -105,6 +113,7 @@ jobs:
|
|||||||
run: make -j3 gen-device
|
run: make -j3 gen-device
|
||||||
- name: Test TinyGo
|
- name: Test TinyGo
|
||||||
shell: bash
|
shell: bash
|
||||||
|
if: matrix.goarch == 'amd64' # skip on ARM64 to speed up build
|
||||||
run: make test GOTESTFLAGS="-only-current-os"
|
run: make test GOTESTFLAGS="-only-current-os"
|
||||||
- name: Build TinyGo release tarball
|
- name: Build TinyGo release tarball
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -112,7 +121,7 @@ jobs:
|
|||||||
- name: Make release artifact
|
- name: Make release artifact
|
||||||
shell: bash
|
shell: bash
|
||||||
working-directory: build/release
|
working-directory: build/release
|
||||||
run: 7z -tzip a tinygo${{ steps.version.outputs.version }}.windows-amd64.zip tinygo
|
run: 7z -tzip a tinygo${{ steps.version.outputs.version }}.windows-${{ matrix.goarch }}.zip tinygo
|
||||||
- name: Publish release artifact
|
- name: Publish release artifact
|
||||||
# Note: this release artifact is double-zipped, see:
|
# Note: this release artifact is double-zipped, see:
|
||||||
# https://github.com/actions/upload-artifact/issues/39
|
# https://github.com/actions/upload-artifact/issues/39
|
||||||
@@ -122,8 +131,8 @@ jobs:
|
|||||||
# We're doing the former here, to keep artifact uploads fast.
|
# We're doing the former here, to keep artifact uploads fast.
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: windows-amd64-double-zipped-${{ steps.version.outputs.version }}
|
name: windows-${{ matrix.goarch }}-double-zipped-${{ steps.version.outputs.version }}
|
||||||
path: build/release/tinygo${{ steps.version.outputs.version }}.windows-amd64.zip
|
path: build/release/tinygo${{ steps.version.outputs.version }}.windows-${{ matrix.goarch }}.zip
|
||||||
|
|
||||||
smoke-test-windows:
|
smoke-test-windows:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@
|
|||||||
url = https://github.com/tinygo-org/stm32-svd
|
url = https://github.com/tinygo-org/stm32-svd
|
||||||
[submodule "lib/musl"]
|
[submodule "lib/musl"]
|
||||||
path = lib/musl
|
path = lib/musl
|
||||||
url = https://github.com/tinygo-org/musl-libc.git
|
url = git://git.musl-libc.org/musl
|
||||||
[submodule "lib/binaryen"]
|
[submodule "lib/binaryen"]
|
||||||
path = lib/binaryen
|
path = lib/binaryen
|
||||||
url = https://github.com/WebAssembly/binaryen.git
|
url = https://github.com/WebAssembly/binaryen.git
|
||||||
|
|||||||
+5
-30
@@ -79,26 +79,6 @@ ifeq (1, $(STATIC))
|
|||||||
BINARYEN_OPTION += -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static"
|
BINARYEN_OPTION += -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static"
|
||||||
endif
|
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.
|
# Cross compiling support.
|
||||||
ifneq ($(CROSS),)
|
ifneq ($(CROSS),)
|
||||||
CC = $(CROSS)-gcc
|
CC = $(CROSS)-gcc
|
||||||
@@ -263,7 +243,7 @@ gen-device-renesas: build/gen-device-svd
|
|||||||
GO111MODULE=off $(GO) fmt ./src/device/renesas
|
GO111MODULE=off $(GO) fmt ./src/device/renesas
|
||||||
|
|
||||||
$(LLVM_PROJECTDIR)/llvm:
|
$(LLVM_PROJECTDIR)/llvm:
|
||||||
git clone -b tinygo_20.x --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
|
git clone -b xtensa_release_19.1.2 --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR)
|
||||||
llvm-source: $(LLVM_PROJECTDIR)/llvm ## Get LLVM sources
|
llvm-source: $(LLVM_PROJECTDIR)/llvm ## Get LLVM sources
|
||||||
|
|
||||||
# Configure LLVM.
|
# Configure LLVM.
|
||||||
@@ -363,6 +343,7 @@ TEST_PACKAGES_FAST = \
|
|||||||
path \
|
path \
|
||||||
reflect \
|
reflect \
|
||||||
sync \
|
sync \
|
||||||
|
testing \
|
||||||
testing/iotest \
|
testing/iotest \
|
||||||
text/scanner \
|
text/scanner \
|
||||||
unicode \
|
unicode \
|
||||||
@@ -479,7 +460,7 @@ TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS)
|
|||||||
TEST_IOFS := false
|
TEST_IOFS := false
|
||||||
endif
|
endif
|
||||||
|
|
||||||
TEST_SKIP_FLAG := -skip='TestExtraMethods|TestParseAndBytesRoundTrip/P256/Generic|^Fuzz'
|
TEST_SKIP_FLAG := -skip='TestExtraMethods|TestParseAndBytesRoundTrip/P256/Generic'
|
||||||
|
|
||||||
# Test known-working standard library packages.
|
# Test known-working standard library packages.
|
||||||
# TODO: parallelize, and only show failing tests (no implied -v flag).
|
# TODO: parallelize, and only show failing tests (no implied -v flag).
|
||||||
@@ -794,8 +775,6 @@ endif
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=gopher-badge examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=gopher-badge examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(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
|
$(TINYGO) build -size short -o test.hex -target=ae-rp2040 examples/echo
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=thumby examples/echo
|
$(TINYGO) build -size short -o test.hex -target=thumby examples/echo
|
||||||
@@ -972,7 +951,7 @@ endif
|
|||||||
|
|
||||||
|
|
||||||
wasmtest:
|
wasmtest:
|
||||||
cd ./tests/wasm && $(GO) test .
|
$(GO) test ./tests/wasm
|
||||||
|
|
||||||
build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binaryen)
|
build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binaryen)
|
||||||
@mkdir -p build/release/tinygo/bin
|
@mkdir -p build/release/tinygo/bin
|
||||||
@@ -1119,7 +1098,6 @@ endif
|
|||||||
tools:
|
tools:
|
||||||
cd internal/tools && go generate -tags tools ./
|
cd internal/tools && go generate -tags tools ./
|
||||||
|
|
||||||
LINTDIRS=src/os/ src/reflect/
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: tools ## Lint source tree
|
lint: tools ## Lint source tree
|
||||||
revive -version
|
revive -version
|
||||||
@@ -1127,10 +1105,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.
|
# 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.
|
# Can't use grep with friendly formatter. Plain output isn't too bad, though.
|
||||||
# Use 'grep .' to get rid of stray blank line
|
# Use 'grep .' to get rid of stray blank line
|
||||||
revive -config revive.toml compiler/... $$( find $(LINTDIRS) -type f -name '*.go' ) \
|
revive -config revive.toml compiler/... src/{os,reflect}/*.go | grep -v "should have comment or be unexported" | grep '.' | awk '{print}; END {exit NR>0}'
|
||||||
| 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
|
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
|
.PHONY: spell
|
||||||
|
|||||||
+3
-6
@@ -30,10 +30,7 @@ var BoehmGC = Library{
|
|||||||
// Use a minimal environment.
|
// Use a minimal environment.
|
||||||
"-DNO_MSGBOX_ON_ERROR", // don't call MessageBoxA on Windows
|
"-DNO_MSGBOX_ON_ERROR", // don't call MessageBoxA on Windows
|
||||||
"-DDONT_USE_ATEXIT",
|
"-DDONT_USE_ATEXIT",
|
||||||
"-DNO_GETENV", // smaller binary, more predictable configuration
|
"-DNO_GETENV",
|
||||||
"-DNO_CLOCK", // don't use system clock
|
|
||||||
"-DNO_DEBUGGING", // reduce code size
|
|
||||||
"-DGC_NO_FINALIZATION", // finalization is not used at the moment
|
|
||||||
|
|
||||||
// Special flag to work around the lack of __data_start in ld.lld.
|
// Special flag to work around the lack of __data_start in ld.lld.
|
||||||
// TODO: try to fix this in LLVM/lld directly so we don't have to
|
// TODO: try to fix this in LLVM/lld directly so we don't have to
|
||||||
@@ -42,8 +39,6 @@ var BoehmGC = Library{
|
|||||||
|
|
||||||
// Do not scan the stack. We have our own mechanism to do this.
|
// Do not scan the stack. We have our own mechanism to do this.
|
||||||
"-DSTACK_NOT_SCANNED",
|
"-DSTACK_NOT_SCANNED",
|
||||||
"-DNO_PROC_STAT", // we scan the stack manually (don't read /proc/self/stat on Linux)
|
|
||||||
"-DSTACKBOTTOM=0", // dummy value, we scan the stack manually
|
|
||||||
|
|
||||||
// Assertions can be enabled while debugging GC issues.
|
// Assertions can be enabled while debugging GC issues.
|
||||||
//"-DGC_ASSERTIONS",
|
//"-DGC_ASSERTIONS",
|
||||||
@@ -68,6 +63,7 @@ var BoehmGC = Library{
|
|||||||
"blacklst.c",
|
"blacklst.c",
|
||||||
"dbg_mlc.c",
|
"dbg_mlc.c",
|
||||||
"dyn_load.c",
|
"dyn_load.c",
|
||||||
|
"finalize.c",
|
||||||
"headers.c",
|
"headers.c",
|
||||||
"mach_dep.c",
|
"mach_dep.c",
|
||||||
"malloc.c",
|
"malloc.c",
|
||||||
@@ -75,6 +71,7 @@ var BoehmGC = Library{
|
|||||||
"mark_rts.c",
|
"mark_rts.c",
|
||||||
"misc.c",
|
"misc.c",
|
||||||
"new_hblk.c",
|
"new_hblk.c",
|
||||||
|
"obj_map.c",
|
||||||
"os_dep.c",
|
"os_dep.c",
|
||||||
"reclaim.c",
|
"reclaim.c",
|
||||||
}
|
}
|
||||||
|
|||||||
+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
|
// Special format for the ESP family of chips (parsed by the ROM
|
||||||
// bootloader).
|
// bootloader).
|
||||||
result.Binary = filepath.Join(tmpdir, "main"+outext)
|
result.Binary = filepath.Join(tmpdir, "main"+outext)
|
||||||
err := makeESPFirmwareImage(result.Executable, result.Binary, outputBinaryFormat)
|
err := makeESPFirmareImage(result.Executable, result.Binary, outputBinaryFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-13
@@ -144,6 +144,8 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
|||||||
.Default(llvm::DebugCompressionType::None);
|
.Default(llvm::DebugCompressionType::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Opts.RelaxELFRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
|
||||||
|
Opts.SSE2AVX = Args.hasArg(OPT_msse2avx);
|
||||||
if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32))
|
if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32))
|
||||||
Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64);
|
Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64);
|
||||||
Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
|
Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
|
||||||
@@ -234,9 +236,6 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
|||||||
Opts.EmitCompactUnwindNonCanonical =
|
Opts.EmitCompactUnwindNonCanonical =
|
||||||
Args.hasArg(OPT_femit_compact_unwind_non_canonical);
|
Args.hasArg(OPT_femit_compact_unwind_non_canonical);
|
||||||
Opts.Crel = Args.hasArg(OPT_crel);
|
Opts.Crel = Args.hasArg(OPT_crel);
|
||||||
Opts.ImplicitMapsyms = Args.hasArg(OPT_mmapsyms_implicit);
|
|
||||||
Opts.X86RelaxRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
|
|
||||||
Opts.X86Sse2Avx = Args.hasArg(OPT_msse2avx);
|
|
||||||
|
|
||||||
Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);
|
Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);
|
||||||
|
|
||||||
@@ -295,9 +294,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||||||
MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
|
MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
|
||||||
MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
|
MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
|
||||||
MCOptions.Crel = Opts.Crel;
|
MCOptions.Crel = Opts.Crel;
|
||||||
MCOptions.ImplicitMapSyms = Opts.ImplicitMapsyms;
|
MCOptions.X86RelaxRelocations = Opts.RelaxELFRelocations;
|
||||||
MCOptions.X86RelaxRelocations = Opts.X86RelaxRelocations;
|
MCOptions.X86Sse2Avx = Opts.SSE2AVX;
|
||||||
MCOptions.X86Sse2Avx = Opts.X86Sse2Avx;
|
|
||||||
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
|
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
|
||||||
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;
|
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;
|
||||||
|
|
||||||
@@ -345,6 +343,10 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||||||
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
|
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
|
||||||
std::unique_ptr<MCObjectFileInfo> MOFI(
|
std::unique_ptr<MCObjectFileInfo> MOFI(
|
||||||
TheTarget->createMCObjectFileInfo(Ctx, PIC));
|
TheTarget->createMCObjectFileInfo(Ctx, PIC));
|
||||||
|
if (Opts.DarwinTargetVariantTriple)
|
||||||
|
MOFI->setDarwinTargetVariantTriple(*Opts.DarwinTargetVariantTriple);
|
||||||
|
if (!Opts.DarwinTargetVariantSDKVersion.empty())
|
||||||
|
MOFI->setDarwinTargetVariantSDKVersion(Opts.DarwinTargetVariantSDKVersion);
|
||||||
Ctx.setObjectFileInfo(MOFI.get());
|
Ctx.setObjectFileInfo(MOFI.get());
|
||||||
|
|
||||||
if (Opts.GenDwarfForAssembly)
|
if (Opts.GenDwarfForAssembly)
|
||||||
@@ -426,13 +428,6 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||||||
Str.reset(TheTarget->createMCObjectStreamer(
|
Str.reset(TheTarget->createMCObjectStreamer(
|
||||||
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
|
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
|
||||||
Str.get()->initSections(Opts.NoExecStack, *STI);
|
Str.get()->initSections(Opts.NoExecStack, *STI);
|
||||||
if (T.isOSBinFormatMachO() && T.isOSDarwin()) {
|
|
||||||
Triple *TVT = Opts.DarwinTargetVariantTriple
|
|
||||||
? &*Opts.DarwinTargetVariantTriple
|
|
||||||
: nullptr;
|
|
||||||
Str->emitVersionForTarget(T, VersionTuple(), TVT,
|
|
||||||
Opts.DarwinTargetVariantSDKVersion);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When -fembed-bitcode is passed to clang_as, a 1-byte marker
|
// When -fembed-bitcode is passed to clang_as, a 1-byte marker
|
||||||
|
|||||||
+5
-10
@@ -45,6 +45,10 @@ struct AssemblerInvocation {
|
|||||||
LLVM_PREFERRED_TYPE(bool)
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
unsigned GenDwarfForAssembly : 1;
|
unsigned GenDwarfForAssembly : 1;
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
|
unsigned RelaxELFRelocations : 1;
|
||||||
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
|
unsigned SSE2AVX : 1;
|
||||||
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
unsigned Dwarf64 : 1;
|
unsigned Dwarf64 : 1;
|
||||||
unsigned DwarfVersion;
|
unsigned DwarfVersion;
|
||||||
std::string DwarfDebugFlags;
|
std::string DwarfDebugFlags;
|
||||||
@@ -113,13 +117,6 @@ struct AssemblerInvocation {
|
|||||||
|
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
unsigned Crel : 1;
|
unsigned Crel : 1;
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
|
||||||
unsigned ImplicitMapsyms : 1;
|
|
||||||
|
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
|
||||||
unsigned X86RelaxRelocations : 1;
|
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
|
||||||
unsigned X86Sse2Avx : 1;
|
|
||||||
|
|
||||||
/// The name of the relocation model to use.
|
/// The name of the relocation model to use.
|
||||||
std::string RelocationModel;
|
std::string RelocationModel;
|
||||||
@@ -151,6 +148,7 @@ public:
|
|||||||
ShowInst = 0;
|
ShowInst = 0;
|
||||||
ShowEncoding = 0;
|
ShowEncoding = 0;
|
||||||
RelaxAll = 0;
|
RelaxAll = 0;
|
||||||
|
SSE2AVX = 0;
|
||||||
NoExecStack = 0;
|
NoExecStack = 0;
|
||||||
FatalWarnings = 0;
|
FatalWarnings = 0;
|
||||||
NoWarn = 0;
|
NoWarn = 0;
|
||||||
@@ -162,9 +160,6 @@ public:
|
|||||||
EmitDwarfUnwind = EmitDwarfUnwindType::Default;
|
EmitDwarfUnwind = EmitDwarfUnwindType::Default;
|
||||||
EmitCompactUnwindNonCanonical = false;
|
EmitCompactUnwindNonCanonical = false;
|
||||||
Crel = false;
|
Crel = false;
|
||||||
ImplicitMapsyms = 0;
|
|
||||||
X86RelaxRelocations = 0;
|
|
||||||
X86Sse2Avx = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CreateFromArgs(AssemblerInvocation &Res,
|
static bool CreateFromArgs(AssemblerInvocation &Res,
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ bool tinygo_clang_driver(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the actual diagnostics engine.
|
// Create the actual diagnostics engine.
|
||||||
Clang->createDiagnostics(*llvm::vfs::getRealFileSystem());
|
Clang->createDiagnostics();
|
||||||
if (!Clang->hasDiagnostics()) {
|
if (!Clang->hasDiagnostics()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -23,7 +23,7 @@ type espImageSegment struct {
|
|||||||
data []byte
|
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
|
// 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.
|
// 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/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/esp-idf/blob/8fbb63c2a701c22ccf4ce249f43aded73e134a34/components/bootloader_support/include/esp_image_format.h#L58
|
||||||
// https://github.com/espressif/esptool/blob/master/esptool.py
|
// 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)
|
inf, err := elf.Open(infile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.
|
// This is a small number of very diverse targets that we want to test.
|
||||||
tests := []sizeTest{
|
tests := []sizeTest{
|
||||||
// microcontrollers
|
// microcontrollers
|
||||||
{"hifive1b", "examples/echo", 3884, 280, 0, 2268},
|
{"hifive1b", "examples/echo", 4580, 280, 0, 2264},
|
||||||
{"microbit", "examples/serial", 2852, 360, 8, 2272},
|
{"microbit", "examples/serial", 2928, 388, 8, 2272},
|
||||||
{"wioterminal", "examples/pininterrupt", 7337, 1491, 116, 6912},
|
{"wioterminal", "examples/pininterrupt", 7387, 1489, 116, 6912},
|
||||||
|
|
||||||
// TODO: also check wasm. Right now this is difficult, because
|
// TODO: also check wasm. Right now this is difficult, because
|
||||||
// wasm binaries are run through wasm-opt and therefore the
|
// wasm binaries are run through wasm-opt and therefore the
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
|
|||||||
// provided immediately. For example:
|
// provided immediately. For example:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, [{result}]",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1,
|
// "value": 1
|
||||||
// "result": uintptr(unsafe.Pointer(&dest)),
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) {
|
func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) {
|
||||||
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
|
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ func Version() int {
|
|||||||
return major
|
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.
|
// endian, but for example MIPS can be big-endian.
|
||||||
func ByteOrder(target string) binary.ByteOrder {
|
func ByteOrder(target string) binary.ByteOrder {
|
||||||
if strings.HasPrefix(target, "mips-") {
|
if strings.HasPrefix(target, "mips-") {
|
||||||
|
|||||||
+4
-15
@@ -630,7 +630,7 @@ func (c *compilerContext) addStandardAttributes(llvmFn llvm.Value) {
|
|||||||
// linkName is equal to .RelString(nil) on a global and extern is false, but for
|
// 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).
|
// some symbols this is different (due to //go:extern for example).
|
||||||
type globalInfo struct {
|
type globalInfo struct {
|
||||||
linkName string // go:extern, go:linkname
|
linkName string // go:extern
|
||||||
extern bool // go:extern
|
extern bool // go:extern
|
||||||
align int // go:align
|
align int // go:align
|
||||||
section string // go:section
|
section string // go:section
|
||||||
@@ -715,14 +715,14 @@ func (c *compilerContext) getGlobalInfo(g *ssa.Global) globalInfo {
|
|||||||
// Check for //go: pragmas, which may change the link name (among others).
|
// Check for //go: pragmas, which may change the link name (among others).
|
||||||
doc := c.astComments[info.linkName]
|
doc := c.astComments[info.linkName]
|
||||||
if doc != nil {
|
if doc != nil {
|
||||||
info.parsePragmas(doc, c, g)
|
info.parsePragmas(doc)
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse //go: pragma comments from the source. In particular, it parses the
|
// Parse //go: pragma comments from the source. In particular, it parses the
|
||||||
// //go:extern and //go:linkname pragmas on globals.
|
// //go:extern pragma on globals.
|
||||||
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup, c *compilerContext, g *ssa.Global) {
|
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
|
||||||
for _, comment := range doc.List {
|
for _, comment := range doc.List {
|
||||||
if !strings.HasPrefix(comment.Text, "//go:") {
|
if !strings.HasPrefix(comment.Text, "//go:") {
|
||||||
continue
|
continue
|
||||||
@@ -743,17 +743,6 @@ func (info *globalInfo) parsePragmas(doc *ast.CommentGroup, c *compilerContext,
|
|||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
info.section = parts[1]
|
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
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'basic.go'
|
; ModuleID = 'basic.go'
|
||||||
source_filename = "basic.go"
|
source_filename = "basic.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%main.kv = type { float, i32, i32, i32 }
|
%main.kv = type { float, i32, i32, i32 }
|
||||||
@@ -206,7 +206,7 @@ entry:
|
|||||||
ret void
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+7
-7
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'channel.go'
|
; ModuleID = 'channel.go'
|
||||||
source_filename = "channel.go"
|
source_filename = "channel.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime.channelOp = type { ptr, ptr, i32, ptr }
|
%runtime.channelOp = type { ptr, ptr, i32, ptr }
|
||||||
@@ -82,11 +82,11 @@ entry:
|
|||||||
store i32 1, ptr %select.send.value, align 4
|
store i32 1, ptr %select.send.value, align 4
|
||||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
|
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||||
store ptr %ch1, ptr %select.states.alloca, align 4
|
store ptr %ch1, ptr %select.states.alloca, align 4
|
||||||
%select.states.alloca.repack1 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 4
|
%select.states.alloca.repack1 = getelementptr inbounds i8, ptr %select.states.alloca, i32 4
|
||||||
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
|
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
|
||||||
%0 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 8
|
%0 = getelementptr inbounds i8, ptr %select.states.alloca, i32 8
|
||||||
store ptr %ch2, ptr %0, align 4
|
store ptr %ch2, ptr %0, align 4
|
||||||
%.repack3 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 12
|
%.repack3 = getelementptr inbounds i8, ptr %select.states.alloca, i32 12
|
||||||
store ptr null, ptr %.repack3, align 4
|
store ptr null, ptr %.repack3, align 4
|
||||||
%select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #4
|
%select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #4
|
||||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca)
|
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||||
@@ -107,8 +107,8 @@ select.body: ; preds = %select.next
|
|||||||
|
|
||||||
declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #1
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||||
attributes #4 = { nounwind }
|
attributes #4 = { nounwind }
|
||||||
|
|||||||
+7
-7
@@ -27,7 +27,7 @@ entry:
|
|||||||
%0 = call ptr @llvm.stacksave.p0()
|
%0 = call ptr @llvm.stacksave.p0()
|
||||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||||
store i32 0, ptr %defer.alloca, align 4
|
store i32 0, ptr %defer.alloca, align 4
|
||||||
%defer.alloca.repack15 = getelementptr inbounds nuw i8, ptr %defer.alloca, i32 4
|
%defer.alloca.repack15 = getelementptr inbounds i8, ptr %defer.alloca, i32 4
|
||||||
store ptr null, ptr %defer.alloca.repack15, align 4
|
store ptr null, ptr %defer.alloca.repack15, align 4
|
||||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
||||||
@@ -51,7 +51,7 @@ rundefers.loophead: ; preds = %3, %rundefers.block
|
|||||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||||
|
|
||||||
rundefers.loop: ; preds = %rundefers.loophead
|
rundefers.loop: ; preds = %rundefers.loophead
|
||||||
%stack.next.gep = getelementptr inbounds nuw i8, ptr %2, i32 4
|
%stack.next.gep = getelementptr inbounds i8, ptr %2, i32 4
|
||||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||||
store ptr %stack.next, ptr %deferPtr, align 4
|
store ptr %stack.next, ptr %deferPtr, align 4
|
||||||
%callback = load i32, ptr %2, align 4
|
%callback = load i32, ptr %2, align 4
|
||||||
@@ -87,7 +87,7 @@ rundefers.loophead6: ; preds = %5, %lpad
|
|||||||
br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5
|
br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5
|
||||||
|
|
||||||
rundefers.loop5: ; preds = %rundefers.loophead6
|
rundefers.loop5: ; preds = %rundefers.loophead6
|
||||||
%stack.next.gep8 = getelementptr inbounds nuw i8, ptr %4, i32 4
|
%stack.next.gep8 = getelementptr inbounds i8, ptr %4, i32 4
|
||||||
%stack.next9 = load ptr, ptr %stack.next.gep8, align 4
|
%stack.next9 = load ptr, ptr %stack.next.gep8, align 4
|
||||||
store ptr %stack.next9, ptr %deferPtr, align 4
|
store ptr %stack.next9, ptr %deferPtr, align 4
|
||||||
%callback11 = load i32, ptr %4, align 4
|
%callback11 = load i32, ptr %4, align 4
|
||||||
@@ -144,11 +144,11 @@ entry:
|
|||||||
%0 = call ptr @llvm.stacksave.p0()
|
%0 = call ptr @llvm.stacksave.p0()
|
||||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||||
store i32 0, ptr %defer.alloca, align 4
|
store i32 0, ptr %defer.alloca, align 4
|
||||||
%defer.alloca.repack22 = getelementptr inbounds nuw i8, ptr %defer.alloca, i32 4
|
%defer.alloca.repack22 = getelementptr inbounds i8, ptr %defer.alloca, i32 4
|
||||||
store ptr null, ptr %defer.alloca.repack22, align 4
|
store ptr null, ptr %defer.alloca.repack22, align 4
|
||||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||||
store i32 1, ptr %defer.alloca2, align 4
|
store i32 1, ptr %defer.alloca2, align 4
|
||||||
%defer.alloca2.repack23 = getelementptr inbounds nuw i8, ptr %defer.alloca2, i32 4
|
%defer.alloca2.repack23 = getelementptr inbounds i8, ptr %defer.alloca2, i32 4
|
||||||
store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4
|
store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4
|
||||||
store ptr %defer.alloca2, ptr %deferPtr, align 4
|
store ptr %defer.alloca2, ptr %deferPtr, align 4
|
||||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
||||||
@@ -172,7 +172,7 @@ rundefers.loophead: ; preds = %4, %3, %rundefers.b
|
|||||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||||
|
|
||||||
rundefers.loop: ; preds = %rundefers.loophead
|
rundefers.loop: ; preds = %rundefers.loophead
|
||||||
%stack.next.gep = getelementptr inbounds nuw i8, ptr %2, i32 4
|
%stack.next.gep = getelementptr inbounds i8, ptr %2, i32 4
|
||||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||||
store ptr %stack.next, ptr %deferPtr, align 4
|
store ptr %stack.next, ptr %deferPtr, align 4
|
||||||
%callback = load i32, ptr %2, align 4
|
%callback = load i32, ptr %2, align 4
|
||||||
@@ -218,7 +218,7 @@ rundefers.loophead10: ; preds = %7, %6, %lpad
|
|||||||
br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9
|
br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9
|
||||||
|
|
||||||
rundefers.loop9: ; preds = %rundefers.loophead10
|
rundefers.loop9: ; preds = %rundefers.loophead10
|
||||||
%stack.next.gep12 = getelementptr inbounds nuw i8, ptr %5, i32 4
|
%stack.next.gep12 = getelementptr inbounds i8, ptr %5, i32 4
|
||||||
%stack.next13 = load ptr, ptr %stack.next.gep12, align 4
|
%stack.next13 = load ptr, ptr %stack.next.gep12, align 4
|
||||||
store ptr %stack.next13, ptr %deferPtr, align 4
|
store ptr %stack.next13, ptr %deferPtr, align 4
|
||||||
%callback15 = load i32, ptr %5, align 4
|
%callback15 = load i32, ptr %5, align 4
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'float.go'
|
; ModuleID = 'float.go'
|
||||||
source_filename = "float.go"
|
source_filename = "float.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -93,6 +93,6 @@ entry:
|
|||||||
ret i8 %0
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'func.go'
|
; ModuleID = 'func.go'
|
||||||
source_filename = "func.go"
|
source_filename = "func.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -44,7 +44,7 @@ entry:
|
|||||||
ret void
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+11
-11
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'gc.go'
|
; ModuleID = 'gc.go'
|
||||||
source_filename = "gc.go"
|
source_filename = "gc.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._interface = type { ptr, ptr }
|
%runtime._interface = type { ptr, ptr }
|
||||||
@@ -105,18 +105,18 @@ entry:
|
|||||||
%makeslice = call align 1 dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
%makeslice = call align 1 dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store ptr %makeslice, ptr @main.slice1, align 4
|
store ptr %makeslice, ptr @main.slice1, align 4
|
||||||
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice1, i32 4), align 4
|
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice1, i32 4), align 4
|
||||||
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice1, i32 8), align 4
|
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice1, i32 8), align 4
|
||||||
%makeslice1 = call align 4 dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
|
%makeslice1 = call align 4 dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store ptr %makeslice1, ptr @main.slice2, align 4
|
store ptr %makeslice1, ptr @main.slice2, align 4
|
||||||
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice2, i32 4), align 4
|
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice2, i32 4), align 4
|
||||||
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice2, i32 8), align 4
|
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice2, i32 8), align 4
|
||||||
%makeslice3 = call align 4 dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #3
|
%makeslice3 = call align 4 dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #3
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store ptr %makeslice3, ptr @main.slice3, align 4
|
store ptr %makeslice3, ptr @main.slice3, align 4
|
||||||
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice3, i32 4), align 4
|
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice3, i32 4), align 4
|
||||||
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice3, i32 8), align 4
|
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice3, i32 8), align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ entry:
|
|||||||
%0 = call align 8 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #3
|
%0 = call align 8 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #3
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store double %v.r, ptr %0, align 8
|
store double %v.r, ptr %0, align 8
|
||||||
%.repack1 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%.repack1 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
store double %v.i, ptr %.repack1, align 8
|
store double %v.i, ptr %.repack1, align 8
|
||||||
%1 = insertvalue %runtime._interface { ptr @"reflect/types.type:basic:complex128", ptr undef }, ptr %0, 1
|
%1 = insertvalue %runtime._interface { ptr @"reflect/types.type:basic:complex128", ptr undef }, ptr %0, 1
|
||||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:complex128", ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:complex128", ptr nonnull %stackalloc, ptr undef) #3
|
||||||
@@ -135,7 +135,7 @@ entry:
|
|||||||
ret %runtime._interface %1
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'go1.20.go'
|
; ModuleID = 'go1.20.go'
|
||||||
source_filename = "go1.20.go"
|
source_filename = "go1.20.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._string = type { ptr, i32 }
|
%runtime._string = type { ptr, i32 }
|
||||||
@@ -57,7 +57,7 @@ entry:
|
|||||||
ret ptr %s.data
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'go1.21.go'
|
; ModuleID = 'go1.21.go'
|
||||||
source_filename = "go1.21.go"
|
source_filename = "go1.21.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._string = type { ptr, i32 }
|
%runtime._string = type { ptr, i32 }
|
||||||
@@ -86,7 +86,7 @@ entry:
|
|||||||
%stackalloc = alloca i8, align 1
|
%stackalloc = alloca i8, align 1
|
||||||
%4 = call i1 @runtime.stringLess(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr undef) #5
|
%4 = call i1 @runtime.stringLess(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr undef) #5
|
||||||
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
||||||
%6 = select i1 %4, ptr %a.data, ptr %b.data
|
%6 = extractvalue %runtime._string %5, 0
|
||||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
||||||
ret %runtime._string %5
|
ret %runtime._string %5
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ entry:
|
|||||||
%stackalloc = alloca i8, align 1
|
%stackalloc = alloca i8, align 1
|
||||||
%4 = call i1 @runtime.stringLess(ptr %b.data, i32 %b.len, ptr %a.data, i32 %a.len, ptr undef) #5
|
%4 = call i1 @runtime.stringLess(ptr %b.data, i32 %b.len, ptr %a.data, i32 %a.len, ptr undef) #5
|
||||||
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
||||||
%6 = select i1 %4, ptr %a.data, ptr %b.data
|
%6 = extractvalue %runtime._string %5, 0
|
||||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
||||||
ret %runtime._string %5
|
ret %runtime._string %5
|
||||||
}
|
}
|
||||||
@@ -171,9 +171,9 @@ declare i32 @llvm.smax.i32(i32, i32) #4
|
|||||||
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
|
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
|
||||||
declare i32 @llvm.umax.i32(i32, i32) #4
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||||
attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
||||||
attributes #5 = { nounwind }
|
attributes #5 = { nounwind }
|
||||||
|
|||||||
+12
-12
@@ -65,7 +65,7 @@ entry:
|
|||||||
store i32 3, ptr %n, align 4
|
store i32 3, ptr %n, align 4
|
||||||
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
store ptr %n, ptr %1, align 4
|
store ptr %n, ptr %1, align 4
|
||||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr undef) #9
|
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr undef) #9
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
||||||
@@ -87,7 +87,7 @@ entry:
|
|||||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
||||||
ret void
|
ret void
|
||||||
@@ -104,9 +104,9 @@ define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %co
|
|||||||
entry:
|
entry:
|
||||||
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
store ptr %fn.context, ptr %1, align 4
|
store ptr %fn.context, ptr %1, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
store ptr %fn.funcptr, ptr %2, align 4
|
store ptr %fn.funcptr, ptr %2, align 4
|
||||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr undef) #9
|
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr undef) #9
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
||||||
@@ -117,9 +117,9 @@ entry:
|
|||||||
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
%5 = load ptr, ptr %4, align 4
|
%5 = load ptr, ptr %4, align 4
|
||||||
call void %5(i32 %1, ptr %3) #9
|
call void %5(i32 %1, ptr %3) #9
|
||||||
ret void
|
ret void
|
||||||
@@ -154,11 +154,11 @@ define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value,
|
|||||||
entry:
|
entry:
|
||||||
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
||||||
store ptr %itf.value, ptr %0, align 4
|
store ptr %itf.value, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
store ptr @"main$string", ptr %1, align 4
|
store ptr @"main$string", ptr %1, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
store i32 4, ptr %2, align 4
|
store i32 4, ptr %2, align 4
|
||||||
%3 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
%3 = getelementptr inbounds i8, ptr %0, i32 12
|
||||||
store ptr %itf.typecode, ptr %3, align 4
|
store ptr %itf.typecode, ptr %3, align 4
|
||||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr undef) #9
|
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr undef) #9
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
||||||
@@ -171,11 +171,11 @@ declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i
|
|||||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load ptr, ptr %0, align 4
|
%1 = load ptr, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
%5 = load i32, ptr %4, align 4
|
%5 = load i32, ptr %4, align 4
|
||||||
%6 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
%6 = getelementptr inbounds i8, ptr %0, i32 12
|
||||||
%7 = load ptr, ptr %6, align 4
|
%7 = load ptr, ptr %6, align 4
|
||||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
||||||
ret void
|
ret void
|
||||||
|
|||||||
+22
-22
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'goroutine.go'
|
; ModuleID = 'goroutine.go'
|
||||||
source_filename = "goroutine.go"
|
source_filename = "goroutine.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
||||||
@@ -72,7 +72,7 @@ entry:
|
|||||||
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
store ptr %n, ptr %1, align 4
|
store ptr %n, ptr %1, align 4
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
||||||
%2 = load i32, ptr %n, align 4
|
%2 = load i32, ptr %n, align 4
|
||||||
@@ -93,7 +93,7 @@ entry:
|
|||||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
||||||
call void @runtime.deadlock(ptr undef) #9
|
call void @runtime.deadlock(ptr undef) #9
|
||||||
@@ -113,9 +113,9 @@ entry:
|
|||||||
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
store ptr %fn.context, ptr %1, align 4
|
store ptr %fn.context, ptr %1, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
store ptr %fn.funcptr, ptr %2, align 4
|
store ptr %fn.funcptr, ptr %2, align 4
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
||||||
ret void
|
ret void
|
||||||
@@ -125,9 +125,9 @@ entry:
|
|||||||
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
%5 = load ptr, ptr %4, align 4
|
%5 = load ptr, ptr %4, align 4
|
||||||
call void %5(i32 %1, ptr %3) #9
|
call void %5(i32 %1, ptr %3) #9
|
||||||
call void @runtime.deadlock(ptr undef) #9
|
call void @runtime.deadlock(ptr undef) #9
|
||||||
@@ -165,11 +165,11 @@ entry:
|
|||||||
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||||
store ptr %itf.value, ptr %0, align 4
|
store ptr %itf.value, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
store ptr @"main$string", ptr %1, align 4
|
store ptr @"main$string", ptr %1, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
store i32 4, ptr %2, align 4
|
store i32 4, ptr %2, align 4
|
||||||
%3 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
%3 = getelementptr inbounds i8, ptr %0, i32 12
|
||||||
store ptr %itf.typecode, ptr %3, align 4
|
store ptr %itf.typecode, ptr %3, align 4
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
||||||
ret void
|
ret void
|
||||||
@@ -181,24 +181,24 @@ declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i
|
|||||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load ptr, ptr %0, align 4
|
%1 = load ptr, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
||||||
%5 = load i32, ptr %4, align 4
|
%5 = load i32, ptr %4, align 4
|
||||||
%6 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
%6 = getelementptr inbounds i8, ptr %0, i32 12
|
||||||
%7 = load ptr, ptr %6, align 4
|
%7 = load ptr, ptr %6, align 4
|
||||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
||||||
call void @runtime.deadlock(ptr undef) #9
|
call void @runtime.deadlock(ptr undef) #9
|
||||||
unreachable
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+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 #3 = { nounwind "target-features"="+bulk-memory,+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 #4 = { nounwind "target-features"="+bulk-memory,+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 #5 = { nounwind "target-features"="+bulk-memory,+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 #6 = { nounwind "target-features"="+bulk-memory,+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 #7 = { "target-features"="+bulk-memory,+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 #8 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="interface:{Print:func:{basic:string}{}}.Print$invoke" }
|
||||||
attributes #9 = { nounwind }
|
attributes #9 = { nounwind }
|
||||||
|
|||||||
Vendored
+8
-8
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'interface.go'
|
; ModuleID = 'interface.go'
|
||||||
source_filename = "interface.go"
|
source_filename = "interface.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._interface = type { ptr, ptr }
|
%runtime._interface = type { ptr, ptr }
|
||||||
@@ -130,11 +130,11 @@ entry:
|
|||||||
|
|
||||||
declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, ptr, ptr) #6
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+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 #3 = { "target-features"="+bulk-memory,+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 #4 = { "target-features"="+bulk-memory,+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 #5 = { "target-features"="+bulk-memory,+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 #6 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" }
|
||||||
attributes #7 = { nounwind }
|
attributes #7 = { nounwind }
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'pointer.go'
|
; ModuleID = 'pointer.go'
|
||||||
source_filename = "pointer.go"
|
source_filename = "pointer.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -44,7 +44,7 @@ entry:
|
|||||||
ret ptr %x
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+11
-11
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'pragma.go'
|
; ModuleID = 'pragma.go'
|
||||||
source_filename = "pragma.go"
|
source_filename = "pragma.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
@extern_global = external global [0 x i8], align 1
|
@extern_global = external global [0 x i8], align 1
|
||||||
@@ -93,13 +93,13 @@ entry:
|
|||||||
ret void
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+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 #3 = { nounwind "target-features"="+bulk-memory,+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 #4 = { inlinehint nounwind "target-features"="+bulk-memory,+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 #5 = { noinline nounwind "target-features"="+bulk-memory,+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 #6 = { noinline nounwind "target-features"="+bulk-memory,+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 #7 = { "target-features"="+bulk-memory,+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 #8 = { "target-features"="+bulk-memory,+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 #9 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exported" }
|
||||||
|
|||||||
Vendored
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'slice.go'
|
; ModuleID = 'slice.go'
|
||||||
source_filename = "slice.go"
|
source_filename = "slice.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -51,9 +51,9 @@ entry:
|
|||||||
%varargs = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
%varargs = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||||
call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store i32 1, ptr %varargs, align 4
|
store i32 1, ptr %varargs, align 4
|
||||||
%0 = getelementptr inbounds nuw i8, ptr %varargs, i32 4
|
%0 = getelementptr inbounds i8, ptr %varargs, i32 4
|
||||||
store i32 2, ptr %0, align 4
|
store i32 2, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %varargs, i32 8
|
%1 = getelementptr inbounds i8, ptr %varargs, i32 8
|
||||||
store i32 3, ptr %1, align 4
|
store i32 3, ptr %1, align 4
|
||||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr undef) #3
|
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr undef) #3
|
||||||
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
||||||
@@ -322,7 +322,7 @@ unsafe.Slice.throw: ; preds = %entry
|
|||||||
unreachable
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'string.go'
|
; ModuleID = 'string.go'
|
||||||
source_filename = "string.go"
|
source_filename = "string.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._string = type { ptr, i32 }
|
%runtime._string = type { ptr, i32 }
|
||||||
@@ -84,11 +84,11 @@ declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #1
|
|||||||
define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #2 {
|
define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #2 {
|
||||||
entry:
|
entry:
|
||||||
%0 = zext i8 %x to i32
|
%0 = zext i8 %x to i32
|
||||||
%.not = icmp ugt i32 %s.len, %0
|
%.not = icmp ult i32 %0, %s.len
|
||||||
br i1 %.not, label %lookup.next, label %lookup.throw
|
br i1 %.not, label %lookup.next, label %lookup.throw
|
||||||
|
|
||||||
lookup.next: ; preds = %entry
|
lookup.next: ; preds = %entry
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %s.data, i32 %0
|
%1 = getelementptr inbounds i8, ptr %s.data, i32 %0
|
||||||
%2 = load i8, ptr %1, align 1
|
%2 = load i8, ptr %1, align 1
|
||||||
ret i8 %2
|
ret i8 %2
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ lookup.throw: ; preds = %entry
|
|||||||
unreachable
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+19
-19
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'zeromap.go'
|
; ModuleID = 'zeromap.go'
|
||||||
source_filename = "zeromap.go"
|
source_filename = "zeromap.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%main.hasPadding = type { i1, i32, i1 }
|
%main.hasPadding = type { i1, i32, i1 }
|
||||||
@@ -27,9 +27,9 @@ entry:
|
|||||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||||
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
%4 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
||||||
%5 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
%5 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
@@ -60,9 +60,9 @@ entry:
|
|||||||
store i32 5, ptr %hashmap.value, align 4
|
store i32 5, ptr %hashmap.value, align 4
|
||||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||||
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
%4 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
||||||
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
@@ -81,16 +81,16 @@ entry:
|
|||||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||||
%hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12
|
%hashmap.key.repack1 = getelementptr inbounds i8, ptr %hashmap.key, i32 12
|
||||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||||
%0 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
%0 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
%1 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 13
|
%2 = getelementptr inbounds i8, ptr %hashmap.key, i32 13
|
||||||
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
||||||
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 21
|
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 21
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
%4 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
%4 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
@@ -109,16 +109,16 @@ entry:
|
|||||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||||
%hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12
|
%hashmap.key.repack1 = getelementptr inbounds i8, ptr %hashmap.key, i32 12
|
||||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||||
%0 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
%0 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
||||||
%1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
%1 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
||||||
%2 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 13
|
%2 = getelementptr inbounds i8, ptr %hashmap.key, i32 13
|
||||||
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
||||||
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 21
|
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 21
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
@@ -132,9 +132,9 @@ entry:
|
|||||||
ret void
|
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 #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+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 #1 = { "target-features"="+bulk-memory,+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 #2 = { nounwind "target-features"="+bulk-memory,+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 #3 = { noinline nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||||
attributes #5 = { nounwind }
|
attributes #5 = { nounwind }
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ go 1.22.0
|
|||||||
require (
|
require (
|
||||||
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139
|
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139
|
||||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
|
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/gofrs/flock v0.8.1
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
||||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
||||||
@@ -22,7 +24,13 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||||
github.com/creack/goselect v0.1.2 // 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/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/stretchr/testify v1.8.4 // indirect
|
github.com/stretchr/testify v1.8.4 // indirect
|
||||||
golang.org/x/text v0.22.0 // 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/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 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI=
|
||||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
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 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
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 h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
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 h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
|
||||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
|
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 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw=
|
||||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M=
|
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=
|
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-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 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
|
||||||
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
|
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 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-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-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-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.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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// Version of TinyGo.
|
// Version of TinyGo.
|
||||||
// Update this value before release of new version of software.
|
// Update this value before release of new version of software.
|
||||||
const version = "0.40.0-dev"
|
const version = "0.39.0"
|
||||||
|
|
||||||
// Return TinyGo version, either in the form 0.30.0 or as a development version
|
// Return TinyGo version, either in the form 0.30.0 or as a development version
|
||||||
// (like 0.30.0-dev-abcd012).
|
// (like 0.30.0-dev-abcd012).
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||||||
// runtime instead of at compile time. But we need to
|
// runtime instead of at compile time. But we need to
|
||||||
// revert any changes made by the call first.
|
// revert any changes made by the call first.
|
||||||
if r.debug {
|
if r.debug {
|
||||||
fmt.Fprintln(os.Stderr, indent+"!! revert because of error:", callErr.Error())
|
fmt.Fprintln(os.Stderr, indent+"!! revert because of error:", callErr.Err)
|
||||||
}
|
}
|
||||||
callMem.revert()
|
callMem.revert()
|
||||||
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
|
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
|
||||||
|
|||||||
Vendored
+1
-1
@@ -10,7 +10,7 @@ target triple = "x86_64--linux"
|
|||||||
@main.exposedValue2 = local_unnamed_addr global i16 0
|
@main.exposedValue2 = local_unnamed_addr global i16 0
|
||||||
@main.insertedValue = local_unnamed_addr global { i8, i32, { float, { i64, i16 } } } zeroinitializer
|
@main.insertedValue = local_unnamed_addr global { i8, i32, { float, { i64, i16 } } } zeroinitializer
|
||||||
@main.gepArray = local_unnamed_addr global [8 x i8] zeroinitializer
|
@main.gepArray = local_unnamed_addr global [8 x i8] zeroinitializer
|
||||||
@main.negativeGEP = global ptr getelementptr inbounds nuw (i8, ptr @main.negativeGEP, i64 2)
|
@main.negativeGEP = global ptr getelementptr inbounds (i8, ptr @main.negativeGEP, i64 2)
|
||||||
|
|
||||||
declare void @runtime.printint64(i64) unnamed_addr
|
declare void @runtime.printint64(i64) unnamed_addr
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ target triple = "x86_64--linux"
|
|||||||
@ptrToIntResult = local_unnamed_addr global i8 2
|
@ptrToIntResult = local_unnamed_addr global i8 2
|
||||||
@pointerTagResult = local_unnamed_addr global i64 2
|
@pointerTagResult = local_unnamed_addr global i64 2
|
||||||
@someArray = internal global { i16, i8, i8 } zeroinitializer
|
@someArray = internal global { i16, i8, i8 } zeroinitializer
|
||||||
@someArrayPointer = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @someArray, i64 2)
|
@someArrayPointer = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @someArray, i64 2)
|
||||||
|
|
||||||
define void @runtime.initAll() local_unnamed_addr {
|
define void @runtime.initAll() local_unnamed_addr {
|
||||||
ret void
|
ret void
|
||||||
|
|||||||
+1
-1
Submodule lib/bdwgc updated: 7577ca7c2d...1166f11f7d
@@ -256,6 +256,7 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
|
|||||||
"reflect/": false,
|
"reflect/": false,
|
||||||
"runtime/": false,
|
"runtime/": false,
|
||||||
"sync/": true,
|
"sync/": true,
|
||||||
|
"testing/": true,
|
||||||
"tinygo/": false,
|
"tinygo/": false,
|
||||||
"unique/": false,
|
"unique/": false,
|
||||||
}
|
}
|
||||||
|
|||||||
+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:
|
// Use the RTT interface, which is documented (in part) here:
|
||||||
// https://wiki.segger.com/RTT
|
// https://wiki.segger.com/RTT
|
||||||
|
|
||||||
// Try to find the "_SEGGER_RTT" symbol (machine.rttSerialInstance)
|
// Try to find the "machine.rttSerialInstance" symbol, which is the RTT
|
||||||
// symbol, which is the RTT control block.
|
// control block.
|
||||||
file, err := elf.Open(executable)
|
file, err := elf.Open(executable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not open ELF file to determine RTT control block: %w", err)
|
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
|
var address uint64
|
||||||
for _, symbol := range symbols {
|
for _, symbol := range symbols {
|
||||||
if symbol.Name == "_SEGGER_RTT" {
|
if symbol.Name == "machine.rttSerialInstance" {
|
||||||
address = symbol.Value
|
address = symbol.Value
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ func Asm(asm string)
|
|||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, [{result}]",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1,
|
// "value": 1
|
||||||
// "result": uintptr(unsafe.Pointer(&dest)),
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
|
|||||||
@@ -1,6 +1,29 @@
|
|||||||
.syntax unified
|
.syntax unified
|
||||||
.cfi_sections .debug_frame
|
.cfi_sections .debug_frame
|
||||||
|
|
||||||
|
.section .text.HardFault_Handler
|
||||||
|
.global HardFault_Handler
|
||||||
|
.type HardFault_Handler, %function
|
||||||
|
HardFault_Handler:
|
||||||
|
.cfi_startproc
|
||||||
|
// Put the old stack pointer in the first argument, for easy debugging. This
|
||||||
|
// is especially useful on Cortex-M0, which supports far fewer debug
|
||||||
|
// facilities.
|
||||||
|
mov r0, sp
|
||||||
|
|
||||||
|
// Load the default stack pointer from address 0 so that we can call normal
|
||||||
|
// functions again that expect a working stack. However, it will corrupt the
|
||||||
|
// old stack so the function below must not attempt to recover from this
|
||||||
|
// fault.
|
||||||
|
movs r3, #0
|
||||||
|
ldr r3, [r3]
|
||||||
|
mov sp, r3
|
||||||
|
|
||||||
|
// Continue handling this error in Go.
|
||||||
|
bl handleHardFault
|
||||||
|
.cfi_endproc
|
||||||
|
.size HardFault_Handler, .-HardFault_Handler
|
||||||
|
|
||||||
// This is a convenience function for semihosting support.
|
// This is a convenience function for semihosting support.
|
||||||
// At some point, this should be replaced by inline assembly.
|
// At some point, this should be replaced by inline assembly.
|
||||||
.section .text.SemihostingCall
|
.section .text.SemihostingCall
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ func Asm(asm string)
|
|||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, [{result}]",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1,
|
// "value": 1
|
||||||
// "result": uintptr(unsafe.Pointer(&dest)),
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
|
|||||||
+3
-3
@@ -10,10 +10,10 @@ func Asm(asm string)
|
|||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, [{result}]",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1,
|
// "value": 1
|
||||||
// "result": uintptr(unsafe.Pointer(&dest)),
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ func Asm(asm string)
|
|||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "st {value}, [{result}]",
|
// "st {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1,
|
// "value": 1
|
||||||
// "result": uintptr(unsafe.Pointer(&dest)),
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ const (
|
|||||||
P09 Pin = 9
|
P09 Pin = 9
|
||||||
P10 Pin = 10
|
P10 Pin = 10
|
||||||
P11 Pin = 11
|
P11 Pin = 11
|
||||||
P12 Pin = 12 // peripherals: I2C0 SDA
|
P12 Pin = 12
|
||||||
P13 Pin = 13 // peripherals: I2C0 SCL
|
P13 Pin = 13
|
||||||
P14 Pin = 14
|
P14 Pin = 14
|
||||||
P15 Pin = 15
|
P15 Pin = 15
|
||||||
P16 Pin = 16
|
P16 Pin = 16
|
||||||
|
|||||||
@@ -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
|
|
||||||
)
|
|
||||||
@@ -78,14 +78,14 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
|
|||||||
// Allow scheduler to run
|
// Allow scheduler to run
|
||||||
gosched()
|
gosched()
|
||||||
|
|
||||||
// Handle first occurrence of error by ensuring STOP sent on bus
|
// Handle errors by ensuring STOP sent on bus
|
||||||
if err == nil && i2c.Bus.EVENTS_ERROR.Get() != 0 {
|
if i2c.Bus.EVENTS_ERROR.Get() != 0 {
|
||||||
err = twiCError(i2c.Bus.ERRORSRC.Get())
|
|
||||||
if i2c.Bus.EVENTS_STOPPED.Get() == 0 {
|
if i2c.Bus.EVENTS_STOPPED.Get() == 0 {
|
||||||
// STOP cannot be sent during SUSPEND
|
// STOP cannot be sent during SUSPEND
|
||||||
i2c.Bus.TASKS_RESUME.Set(1)
|
i2c.Bus.TASKS_RESUME.Set(1)
|
||||||
i2c.Bus.TASKS_STOP.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
|
// Peripheral clocks should now all be running
|
||||||
unresetBlockWait(RESETS_RESET_Msk)
|
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
|
//go:linkname ticks runtime.machineTicks
|
||||||
|
|||||||
@@ -100,8 +100,7 @@ func ReadTemperature() (millicelsius int32) {
|
|||||||
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
||||||
|
|
||||||
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
||||||
// 1/0.001721 ≈ 581
|
return (27000<<16 - (int32(thermChan.getVoltage())-706<<16)*581) >> 16
|
||||||
return int32(((int64(27000) << 16) - ((int64(thermChan.getVoltage()) - (int64(706) << 16)) * 581)) >> 16)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForReady spins waiting for the ADC peripheral to become ready.
|
// waitForReady spins waiting for the ADC peripheral to become ready.
|
||||||
|
|||||||
@@ -101,15 +101,3 @@ func (tmr *timerType) lightSleep(us uint64) {
|
|||||||
// Disable interrupt
|
// Disable interrupt
|
||||||
intr.Disable()
|
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 {
|
func (uart *UART) writeByte(c byte) error {
|
||||||
// wait until buffer is not full
|
// wait until buffer is not full
|
||||||
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) {
|
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) {
|
||||||
if !interrupt.In() {
|
gosched()
|
||||||
gosched()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
@@ -116,9 +114,7 @@ func (uart *UART) writeByte(c byte) error {
|
|||||||
|
|
||||||
func (uart *UART) flush() {
|
func (uart *UART) flush() {
|
||||||
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_BUSY) {
|
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.
|
// This symbol name is known by the compiler, see monitor.go.
|
||||||
//
|
|
||||||
//go:linkname rttSerialInstance _SEGGER_RTT
|
|
||||||
var rttSerialInstance rttSerial
|
var rttSerialInstance rttSerial
|
||||||
|
|
||||||
var Serial = &rttSerialInstance
|
var Serial = &rttSerialInstance
|
||||||
|
|||||||
+1
-1
Submodule src/net updated: bb43b40f19...983d88dd7a
@@ -12,6 +12,7 @@ package os
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
_ "unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DevNull = "/dev/null"
|
const DevNull = "/dev/null"
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ func (it *MapIter) Next() bool {
|
|||||||
return ((*reflectlite.MapIter)(it)).Next()
|
return ((*reflectlite.MapIter)(it)).Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *MapIter) Reset(v Value) {
|
func (iter *MapIter) Reset(v Value) {
|
||||||
(*reflectlite.MapIter)(it).Reset(v.Value)
|
(*reflectlite.MapIter)(iter).Reset(v.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) Set(x Value) {
|
func (v Value) Set(x Value) {
|
||||||
|
|||||||
@@ -30,9 +30,7 @@ func SetPanicOnFault(enabled bool) bool {
|
|||||||
|
|
||||||
func WriteHeapDump(fd uintptr)
|
func WriteHeapDump(fd uintptr)
|
||||||
|
|
||||||
// Unimplemented.
|
func SetTraceback(level string)
|
||||||
func SetTraceback(level string) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetMemoryLimit(limit int64) int64 {
|
func SetMemoryLimit(limit int64) int64 {
|
||||||
return limit
|
return limit
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
func Callers(skip int, pc []uintptr) int {
|
func Callers(skip int, pc []uintptr) int {
|
||||||
if len(pc) > 0 {
|
|
||||||
// The testing package expects at least one caller in all cases.
|
|
||||||
pc[0] = 0
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,9 +93,6 @@ func runtimePanicAt(addr unsafe.Pointer, msg string) {
|
|||||||
trap()
|
trap()
|
||||||
}
|
}
|
||||||
if hasReturnAddr {
|
if hasReturnAddr {
|
||||||
// Note: the string "panic: runtime error at " is also used in
|
|
||||||
// runtime_cortexm_hardfault.go. It is kept the same so that the string
|
|
||||||
// can be deduplicated by the compiler.
|
|
||||||
printstring("panic: runtime error at ")
|
printstring("panic: runtime error at ")
|
||||||
printptr(uintptr(addr) - callInstSize)
|
printptr(uintptr(addr) - callInstSize)
|
||||||
printstring(": ")
|
printstring(": ")
|
||||||
|
|||||||
@@ -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) }
|
|
||||||
@@ -57,12 +57,6 @@ func memzero(ptr unsafe.Pointer, size uintptr)
|
|||||||
// the current stack pointer in a platform-independent way.
|
// the current stack pointer in a platform-independent way.
|
||||||
func stacksave() unsafe.Pointer
|
func stacksave() unsafe.Pointer
|
||||||
|
|
||||||
// Special LLVM intrinsic that returns the SP register on entry to the calling
|
|
||||||
// function.
|
|
||||||
//
|
|
||||||
//export llvm.sponentry.p0
|
|
||||||
func llvm_sponentry() unsafe.Pointer
|
|
||||||
|
|
||||||
//export strlen
|
//export strlen
|
||||||
func strlen(ptr unsafe.Pointer) uintptr
|
func strlen(ptr unsafe.Pointer) uintptr
|
||||||
|
|
||||||
@@ -181,19 +175,3 @@ func getAuxv() []uintptr {
|
|||||||
func cgo_errno() uintptr {
|
func cgo_errno() uintptr {
|
||||||
return uintptr(*libc_errno_location())
|
return uintptr(*libc_errno_location())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unimplemented.
|
|
||||||
var MemProfileRate int = 0
|
|
||||||
|
|
||||||
// Unimplemented.
|
|
||||||
func SetBlockProfileRate(rate int) {
|
|
||||||
}
|
|
||||||
|
|
||||||
var mutexProfileFraction int
|
|
||||||
|
|
||||||
// Unimplemented.
|
|
||||||
func SetMutexProfileFraction(rate int) int {
|
|
||||||
previous := mutexProfileFraction
|
|
||||||
mutexProfileFraction = rate
|
|
||||||
return previous
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,25 +2,39 @@
|
|||||||
|
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
// This function is called at HardFault.
|
// This function is called at HardFault.
|
||||||
|
// Before this function is called, the stack pointer is reset to the initial
|
||||||
|
// stack pointer (loaded from address 0x0) and the previous stack pointer is
|
||||||
|
// passed as an argument to this function. This allows for easy inspection of
|
||||||
|
// the stack the moment a HardFault occurs, but it means that the stack will be
|
||||||
|
// corrupted by this function and thus this handler must not attempt to recover.
|
||||||
//
|
//
|
||||||
// For details, see:
|
// For details, see:
|
||||||
// https://community.arm.com/developer/ip-products/system/f/embedded-forum/3257/debugging-a-cortex-m0-hard-fault
|
// https://community.arm.com/developer/ip-products/system/f/embedded-forum/3257/debugging-a-cortex-m0-hard-fault
|
||||||
// https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/
|
// https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/
|
||||||
//
|
//
|
||||||
//export HardFault_Handler
|
//export handleHardFault
|
||||||
func HardFault_Handler() {
|
func handleHardFault(sp *interruptStack) {
|
||||||
// Obtain the stack pointer as it was on entry to the HardFault. It contains
|
print("fatal error: ")
|
||||||
// the registers that were pushed by the NVIC and that we can now read back
|
if uintptr(unsafe.Pointer(sp)) < 0x20000000 {
|
||||||
// to print the PC value at the time of the hard fault, for example.
|
print("stack overflow")
|
||||||
sp := (*interruptStack)(llvm_sponentry())
|
} else {
|
||||||
|
// TODO: try to find the cause of the hard fault. Especially on
|
||||||
// Note: by reusing the string "panic: runtime error at " we save a little
|
// Cortex-M3 and higher it is possible to find more detailed information
|
||||||
// bit in terms of code size as the string can be deduplicated.
|
// in special status registers.
|
||||||
print("panic: runtime error at ", sp.PC, ": HardFault with sp=", sp)
|
print("HardFault")
|
||||||
// TODO: try to find the cause of the hard fault. Especially on Cortex-M3
|
}
|
||||||
// and higher it is possible to find more detailed information in special
|
print(" with sp=", sp)
|
||||||
// status registers.
|
if uintptr(unsafe.Pointer(&sp.PC)) >= 0x20000000 {
|
||||||
|
// Only print the PC if it points into memory.
|
||||||
|
// It may not point into memory during a stack overflow, so check that
|
||||||
|
// first before accessing the stack.
|
||||||
|
print(" pc=", sp.PC)
|
||||||
|
}
|
||||||
println()
|
println()
|
||||||
abort()
|
abort()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,8 @@ const (
|
|||||||
|
|
||||||
// See runtime_cortexm_hardfault.go
|
// See runtime_cortexm_hardfault.go
|
||||||
//
|
//
|
||||||
//export HardFault_Handler
|
//go:export handleHardFault
|
||||||
func HardFault_Handler() {
|
func handleHardFault(sp *interruptStack) {
|
||||||
// Obtain the stack pointer as it was on entry to the HardFault. It contains
|
|
||||||
// the registers that were pushed by the NVIC and that we can now read back
|
|
||||||
// to print the PC value at the time of the hard fault, for example.
|
|
||||||
sp := (*interruptStack)(llvm_sponentry())
|
|
||||||
|
|
||||||
fault := GetFaultStatus()
|
fault := GetFaultStatus()
|
||||||
spValid := !fault.Bus().ImpreciseDataBusError()
|
spValid := !fault.Bus().ImpreciseDataBusError()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const numCPU = 2
|
const numCPU = 2
|
||||||
const numSpinlocks = 32
|
|
||||||
|
|
||||||
// machineTicks is provided by package machine.
|
// machineTicks is provided by package machine.
|
||||||
func machineTicks() uint64
|
func machineTicks() uint64
|
||||||
@@ -292,19 +291,12 @@ func coreStackTop(core uint32) uintptr {
|
|||||||
|
|
||||||
// These spinlocks are needed by the runtime.
|
// These spinlocks are needed by the runtime.
|
||||||
var (
|
var (
|
||||||
printLock = spinLock{id: 20}
|
printLock = spinLock{id: 0}
|
||||||
schedulerLock = spinLock{id: 21}
|
schedulerLock = spinLock{id: 1}
|
||||||
atomicsLock = spinLock{id: 22}
|
atomicsLock = spinLock{id: 2}
|
||||||
futexLock = spinLock{id: 23}
|
futexLock = spinLock{id: 3}
|
||||||
)
|
)
|
||||||
|
|
||||||
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.
|
// A hardware spinlock, one of the 32 spinlocks defined in the SIO peripheral.
|
||||||
type spinLock struct {
|
type spinLock struct {
|
||||||
id uint8
|
id uint8
|
||||||
@@ -319,13 +311,15 @@ func (l *spinLock) Lock() {
|
|||||||
// Wait for the lock to be available.
|
// Wait for the lock to be available.
|
||||||
spinlock := l.spinlock()
|
spinlock := l.spinlock()
|
||||||
for spinlock.Get() == 0 {
|
for spinlock.Get() == 0 {
|
||||||
arm.Asm("wfe")
|
// 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() {
|
func (l *spinLock) Unlock() {
|
||||||
l.spinlock().Set(0)
|
l.spinlock().Set(0)
|
||||||
arm.Asm("sev")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until a signal is received, indicating that it can resume from the
|
// Wait until a signal is received, indicating that it can resume from the
|
||||||
@@ -365,16 +359,9 @@ func init() {
|
|||||||
machine.InitSerial()
|
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
|
//export Reset_Handler
|
||||||
func main() {
|
func main() {
|
||||||
preinit()
|
preinit()
|
||||||
prerun()
|
|
||||||
run()
|
run()
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ type RWMutex struct {
|
|||||||
|
|
||||||
const rwMutexMaxReaders = 1 << 30
|
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() {
|
func (rw *RWMutex) Lock() {
|
||||||
// Exclusive lock for writers.
|
// Exclusive lock for writers.
|
||||||
rw.writerLock.Lock()
|
rw.writerLock.Lock()
|
||||||
@@ -59,12 +56,6 @@ func (rw *RWMutex) Lock() {
|
|||||||
rw.writer.Store(0)
|
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() {
|
func (rw *RWMutex) Unlock() {
|
||||||
// Signal that new readers can lock this mutex.
|
// Signal that new readers can lock this mutex.
|
||||||
waiting := rw.readers.Add(rwMutexMaxReaders)
|
waiting := rw.readers.Add(rwMutexMaxReaders)
|
||||||
@@ -77,31 +68,6 @@ func (rw *RWMutex) Unlock() {
|
|||||||
rw.writerLock.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() {
|
func (rw *RWMutex) RLock() {
|
||||||
// Add us as a reader.
|
// Add us as a reader.
|
||||||
newVal := rw.readers.Add(1)
|
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() {
|
func (rw *RWMutex) RUnlock() {
|
||||||
// Remove us as a reader.
|
// Remove us as a reader.
|
||||||
one := uint32(1)
|
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 {
|
type Locker interface {
|
||||||
Lock()
|
Lock()
|
||||||
Unlock()
|
Unlock()
|
||||||
|
|||||||
+1
-29
@@ -7,13 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mutex interface {
|
func HammerMutex(m *sync.Mutex, loops int, cdone chan bool) {
|
||||||
Lock()
|
|
||||||
Unlock()
|
|
||||||
TryLock() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func HammerMutex(m mutex, loops int, cdone chan bool) {
|
|
||||||
for i := 0; i < loops; i++ {
|
for i := 0; i < loops; i++ {
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
if m.TryLock() {
|
if m.TryLock() {
|
||||||
@@ -246,25 +240,3 @@ func TestRWMutexReadToWrite(t *testing.T) {
|
|||||||
t.Errorf("write lock acquired while %d readers were active", res)
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,521 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
// This file has been modified for use by the TinyGo compiler.
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initBenchmarkFlags() {
|
||||||
|
matchBenchmarks = flag.String("test.bench", "", "run only benchmarks matching `regexp`")
|
||||||
|
benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks")
|
||||||
|
flag.Var(&benchTime, "test.benchtime", "run each benchmark for duration `d`")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
matchBenchmarks *string
|
||||||
|
benchmarkMemory *bool
|
||||||
|
benchTime = benchTimeFlag{d: 1 * time.Second} // changed during test of testing package
|
||||||
|
)
|
||||||
|
|
||||||
|
type benchTimeFlag struct {
|
||||||
|
d time.Duration
|
||||||
|
n int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *benchTimeFlag) String() string {
|
||||||
|
if f.n > 0 {
|
||||||
|
return fmt.Sprintf("%dx", f.n)
|
||||||
|
}
|
||||||
|
return time.Duration(f.d).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *benchTimeFlag) Set(s string) error {
|
||||||
|
if strings.HasSuffix(s, "x") {
|
||||||
|
n, err := strconv.ParseInt(s[:len(s)-1], 10, 0)
|
||||||
|
if err != nil || n <= 0 {
|
||||||
|
return fmt.Errorf("invalid count")
|
||||||
|
}
|
||||||
|
*f = benchTimeFlag{n: int(n)}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
d, err := time.ParseDuration(s)
|
||||||
|
if err != nil || d <= 0 {
|
||||||
|
return fmt.Errorf("invalid duration")
|
||||||
|
}
|
||||||
|
*f = benchTimeFlag{d: d}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InternalBenchmark is an internal type but exported because it is cross-package;
|
||||||
|
// it is part of the implementation of the "go test" command.
|
||||||
|
type InternalBenchmark struct {
|
||||||
|
Name string
|
||||||
|
F func(b *B)
|
||||||
|
}
|
||||||
|
|
||||||
|
// B is a type passed to Benchmark functions to manage benchmark
|
||||||
|
// timing and to specify the number of iterations to run.
|
||||||
|
//
|
||||||
|
// A benchmark ends when its Benchmark function returns or calls any of the methods
|
||||||
|
// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods must be called
|
||||||
|
// only from the goroutine running the Benchmark function.
|
||||||
|
// The other reporting methods, such as the variations of Log and Error,
|
||||||
|
// may be called simultaneously from multiple goroutines.
|
||||||
|
//
|
||||||
|
// Like in tests, benchmark logs are accumulated during execution
|
||||||
|
// and dumped to standard output when done. Unlike in tests, benchmark logs
|
||||||
|
// are always printed, so as not to hide output whose existence may be
|
||||||
|
// affecting benchmark results.
|
||||||
|
type B struct {
|
||||||
|
common
|
||||||
|
context *benchContext
|
||||||
|
N int
|
||||||
|
benchFunc func(b *B)
|
||||||
|
bytes int64
|
||||||
|
missingBytes bool // one of the subbenchmarks does not have bytes set.
|
||||||
|
benchTime benchTimeFlag
|
||||||
|
timerOn bool
|
||||||
|
result BenchmarkResult
|
||||||
|
|
||||||
|
// report memory statistics
|
||||||
|
showAllocResult bool
|
||||||
|
// initial state of MemStats.Mallocs and MemStats.TotalAlloc
|
||||||
|
startAllocs uint64
|
||||||
|
startBytes uint64
|
||||||
|
// net total after running benchmar
|
||||||
|
netAllocs uint64
|
||||||
|
netBytes uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartTimer starts timing a test. This function is called automatically
|
||||||
|
// before a benchmark starts, but it can also be used to resume timing after
|
||||||
|
// a call to StopTimer.
|
||||||
|
func (b *B) StartTimer() {
|
||||||
|
if !b.timerOn {
|
||||||
|
b.start = time.Now()
|
||||||
|
b.timerOn = true
|
||||||
|
|
||||||
|
var mstats runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&mstats)
|
||||||
|
b.startAllocs = mstats.Mallocs
|
||||||
|
b.startBytes = mstats.TotalAlloc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopTimer stops timing a test. This can be used to pause the timer
|
||||||
|
// while performing complex initialization that you don't
|
||||||
|
// want to measure.
|
||||||
|
func (b *B) StopTimer() {
|
||||||
|
if b.timerOn {
|
||||||
|
b.duration += time.Since(b.start)
|
||||||
|
b.timerOn = false
|
||||||
|
|
||||||
|
var mstats runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&mstats)
|
||||||
|
b.netAllocs += mstats.Mallocs - b.startAllocs
|
||||||
|
b.netBytes += mstats.TotalAlloc - b.startBytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetTimer zeroes the elapsed benchmark time and memory allocation counters
|
||||||
|
// and deletes user-reported metrics.
|
||||||
|
func (b *B) ResetTimer() {
|
||||||
|
if b.timerOn {
|
||||||
|
b.start = time.Now()
|
||||||
|
|
||||||
|
var mstats runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&mstats)
|
||||||
|
b.startAllocs = mstats.Mallocs
|
||||||
|
b.startBytes = mstats.TotalAlloc
|
||||||
|
}
|
||||||
|
b.duration = 0
|
||||||
|
b.netAllocs = 0
|
||||||
|
b.netBytes = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBytes records the number of bytes processed in a single operation.
|
||||||
|
// If this is called, the benchmark will report ns/op and MB/s.
|
||||||
|
func (b *B) SetBytes(n int64) { b.bytes = n }
|
||||||
|
|
||||||
|
// ReportAllocs enables malloc statistics for this benchmark.
|
||||||
|
// It is equivalent to setting -test.benchmem, but it only affects the
|
||||||
|
// benchmark function that calls ReportAllocs.
|
||||||
|
func (b *B) ReportAllocs() {
|
||||||
|
b.showAllocResult = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// runN runs a single benchmark for the specified number of iterations.
|
||||||
|
func (b *B) runN(n int) {
|
||||||
|
b.N = n
|
||||||
|
runtime.GC()
|
||||||
|
b.ResetTimer()
|
||||||
|
b.StartTimer()
|
||||||
|
b.benchFunc(b)
|
||||||
|
b.StopTimer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func min(x, y int64) int64 {
|
||||||
|
if x > y {
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func max(x, y int64) int64 {
|
||||||
|
if x < y {
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
// run1 runs the first iteration of benchFunc. It reports whether more
|
||||||
|
// iterations of this benchmarks should be run.
|
||||||
|
func (b *B) run1() bool {
|
||||||
|
if ctx := b.context; ctx != nil {
|
||||||
|
// Extend maxLen, if needed.
|
||||||
|
if n := len(b.name); n > ctx.maxLen {
|
||||||
|
ctx.maxLen = n + 8 // Add additional slack to avoid too many jumps in size.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.runN(1)
|
||||||
|
return !b.hasSub
|
||||||
|
}
|
||||||
|
|
||||||
|
// run executes the benchmark.
|
||||||
|
func (b *B) run() {
|
||||||
|
if b.context != nil {
|
||||||
|
// Running go test --test.bench
|
||||||
|
b.processBench(b.context) // calls doBench and prints results
|
||||||
|
} else {
|
||||||
|
// Running func Benchmark.
|
||||||
|
b.doBench()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *B) doBench() BenchmarkResult {
|
||||||
|
// in upstream, this uses a goroutine
|
||||||
|
b.launch()
|
||||||
|
return b.result
|
||||||
|
}
|
||||||
|
|
||||||
|
// launch launches the benchmark function. It gradually increases the number
|
||||||
|
// of benchmark iterations until the benchmark runs for the requested benchtime.
|
||||||
|
// run1 must have been called on b.
|
||||||
|
func (b *B) launch() {
|
||||||
|
// Run the benchmark for at least the specified amount of time.
|
||||||
|
if b.benchTime.n > 0 {
|
||||||
|
b.runN(b.benchTime.n)
|
||||||
|
} else {
|
||||||
|
d := b.benchTime.d
|
||||||
|
b.failed = false
|
||||||
|
b.duration = 0
|
||||||
|
for n := int64(1); !b.failed && b.duration < d && n < 1e9; {
|
||||||
|
last := n
|
||||||
|
// Predict required iterations.
|
||||||
|
goalns := d.Nanoseconds()
|
||||||
|
prevIters := int64(b.N)
|
||||||
|
prevns := b.duration.Nanoseconds()
|
||||||
|
if prevns <= 0 {
|
||||||
|
// Round up, to avoid div by zero.
|
||||||
|
prevns = 1
|
||||||
|
}
|
||||||
|
// Order of operations matters.
|
||||||
|
// For very fast benchmarks, prevIters ~= prevns.
|
||||||
|
// If you divide first, you get 0 or 1,
|
||||||
|
// which can hide an order of magnitude in execution time.
|
||||||
|
// So multiply first, then divide.
|
||||||
|
n = goalns * prevIters / prevns
|
||||||
|
// Run more iterations than we think we'll need (1.2x).
|
||||||
|
n += n / 5
|
||||||
|
// Don't grow too fast in case we had timing errors previously.
|
||||||
|
n = min(n, 100*last)
|
||||||
|
// Be sure to run at least one more than last time.
|
||||||
|
n = max(n, last+1)
|
||||||
|
// Don't run more than 1e9 times. (This also keeps n in int range on 32 bit platforms.)
|
||||||
|
n = min(n, 1e9)
|
||||||
|
b.runN(int(n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.result = BenchmarkResult{b.N, b.duration, b.bytes, b.netAllocs, b.netBytes}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BenchmarkResult contains the results of a benchmark run.
|
||||||
|
type BenchmarkResult struct {
|
||||||
|
N int // The number of iterations.
|
||||||
|
T time.Duration // The total time taken.
|
||||||
|
Bytes int64 // Bytes processed in one iteration.
|
||||||
|
|
||||||
|
MemAllocs uint64 // The total number of memory allocations.
|
||||||
|
MemBytes uint64 // The total number of bytes allocated.
|
||||||
|
}
|
||||||
|
|
||||||
|
// NsPerOp returns the "ns/op" metric.
|
||||||
|
func (r BenchmarkResult) NsPerOp() int64 {
|
||||||
|
if r.N <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return r.T.Nanoseconds() / int64(r.N)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mbPerSec returns the "MB/s" metric.
|
||||||
|
func (r BenchmarkResult) mbPerSec() float64 {
|
||||||
|
if r.Bytes <= 0 || r.T <= 0 || r.N <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllocsPerOp returns the "allocs/op" metric,
|
||||||
|
// which is calculated as r.MemAllocs / r.N.
|
||||||
|
func (r BenchmarkResult) AllocsPerOp() int64 {
|
||||||
|
if r.N <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int64(r.MemAllocs) / int64(r.N)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllocedBytesPerOp returns the "B/op" metric,
|
||||||
|
// which is calculated as r.MemBytes / r.N.
|
||||||
|
func (r BenchmarkResult) AllocedBytesPerOp() int64 {
|
||||||
|
if r.N <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int64(r.MemBytes) / int64(r.N)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a summary of the benchmark results.
|
||||||
|
// It follows the benchmark result line format from
|
||||||
|
// https://golang.org/design/14313-benchmark-format, not including the
|
||||||
|
// benchmark name.
|
||||||
|
// Extra metrics override built-in metrics of the same name.
|
||||||
|
// String does not include allocs/op or B/op, since those are reported
|
||||||
|
// by MemString.
|
||||||
|
func (r BenchmarkResult) String() string {
|
||||||
|
buf := new(strings.Builder)
|
||||||
|
fmt.Fprintf(buf, "%8d", r.N)
|
||||||
|
|
||||||
|
// Get ns/op as a float.
|
||||||
|
ns := float64(r.T.Nanoseconds()) / float64(r.N)
|
||||||
|
if ns != 0 {
|
||||||
|
buf.WriteByte('\t')
|
||||||
|
prettyPrint(buf, ns, "ns/op")
|
||||||
|
}
|
||||||
|
|
||||||
|
if mbs := r.mbPerSec(); mbs != 0 {
|
||||||
|
fmt.Fprintf(buf, "\t%7.2f MB/s", mbs)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemString returns r.AllocedBytesPerOp and r.AllocsPerOp in the same format as 'go test'.
|
||||||
|
func (r BenchmarkResult) MemString() string {
|
||||||
|
return fmt.Sprintf("%8d B/op\t%8d allocs/op",
|
||||||
|
r.AllocedBytesPerOp(), r.AllocsPerOp())
|
||||||
|
}
|
||||||
|
|
||||||
|
func prettyPrint(w io.Writer, x float64, unit string) {
|
||||||
|
// Print all numbers with 10 places before the decimal point
|
||||||
|
// and small numbers with four sig figs. Field widths are
|
||||||
|
// chosen to fit the whole part in 10 places while aligning
|
||||||
|
// the decimal point of all fractional formats.
|
||||||
|
var format string
|
||||||
|
switch y := math.Abs(x); {
|
||||||
|
case y == 0 || y >= 999.95:
|
||||||
|
format = "%10.0f %s"
|
||||||
|
case y >= 99.995:
|
||||||
|
format = "%12.1f %s"
|
||||||
|
case y >= 9.9995:
|
||||||
|
format = "%13.2f %s"
|
||||||
|
case y >= 0.99995:
|
||||||
|
format = "%14.3f %s"
|
||||||
|
case y >= 0.099995:
|
||||||
|
format = "%15.4f %s"
|
||||||
|
case y >= 0.0099995:
|
||||||
|
format = "%16.5f %s"
|
||||||
|
case y >= 0.00099995:
|
||||||
|
format = "%17.6f %s"
|
||||||
|
default:
|
||||||
|
format = "%18.7f %s"
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, format, x, unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
type benchContext struct {
|
||||||
|
match *matcher
|
||||||
|
|
||||||
|
maxLen int // The largest recorded benchmark name.
|
||||||
|
}
|
||||||
|
|
||||||
|
func runBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) bool {
|
||||||
|
// If no flag was specified, don't run benchmarks.
|
||||||
|
if len(*matchBenchmarks) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
ctx := &benchContext{
|
||||||
|
match: newMatcher(matchString, *matchBenchmarks, "-test.bench", flagSkipRegexp),
|
||||||
|
}
|
||||||
|
var bs []InternalBenchmark
|
||||||
|
for _, Benchmark := range benchmarks {
|
||||||
|
if _, matched, _ := ctx.match.fullName(nil, Benchmark.Name); matched {
|
||||||
|
bs = append(bs, Benchmark)
|
||||||
|
benchName := Benchmark.Name
|
||||||
|
if l := len(benchName); l > ctx.maxLen {
|
||||||
|
ctx.maxLen = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main := &B{
|
||||||
|
common: common{
|
||||||
|
output: &logger{},
|
||||||
|
name: "Main",
|
||||||
|
},
|
||||||
|
benchTime: benchTime,
|
||||||
|
benchFunc: func(b *B) {
|
||||||
|
for _, Benchmark := range bs {
|
||||||
|
b.Run(Benchmark.Name, Benchmark.F)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
context: ctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
main.runN(1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// processBench runs bench b and prints the results.
|
||||||
|
func (b *B) processBench(ctx *benchContext) {
|
||||||
|
benchName := b.name
|
||||||
|
|
||||||
|
for i := 0; i < flagCount; i++ {
|
||||||
|
if ctx != nil {
|
||||||
|
fmt.Printf("%-*s\t", ctx.maxLen, benchName)
|
||||||
|
}
|
||||||
|
r := b.doBench()
|
||||||
|
if b.failed {
|
||||||
|
// The output could be very long here, but probably isn't.
|
||||||
|
// We print it all, regardless, because we don't want to trim the reason
|
||||||
|
// the benchmark failed.
|
||||||
|
fmt.Printf("--- FAIL: %s\n%s", benchName, "") // b.output)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ctx != nil {
|
||||||
|
results := r.String()
|
||||||
|
|
||||||
|
if *benchmarkMemory || b.showAllocResult {
|
||||||
|
results += "\t" + r.MemString()
|
||||||
|
}
|
||||||
|
fmt.Println(results)
|
||||||
|
|
||||||
|
// Print any benchmark output
|
||||||
|
if b.output.Len() > 0 {
|
||||||
|
fmt.Printf("--- BENCH: %s\n", benchName)
|
||||||
|
b.output.WriteTo(os.Stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run benchmarks f as a subbenchmark with the given name. It reports
|
||||||
|
// true if the subbenchmark succeeded.
|
||||||
|
//
|
||||||
|
// A subbenchmark is like any other benchmark. A benchmark that calls Run at
|
||||||
|
// least once will not be measured itself and will be called once with N=1.
|
||||||
|
func (b *B) Run(name string, f func(b *B)) bool {
|
||||||
|
benchName, ok, partial := b.name, true, false
|
||||||
|
if b.context != nil {
|
||||||
|
benchName, ok, partial = b.context.match.fullName(&b.common, name)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
b.hasSub = true
|
||||||
|
sub := &B{
|
||||||
|
common: common{
|
||||||
|
output: &logger{},
|
||||||
|
name: benchName,
|
||||||
|
level: b.level + 1,
|
||||||
|
},
|
||||||
|
benchFunc: f,
|
||||||
|
benchTime: b.benchTime,
|
||||||
|
context: b.context,
|
||||||
|
}
|
||||||
|
if partial {
|
||||||
|
// Partial name match, like -bench=X/Y matching BenchmarkX.
|
||||||
|
// Only process sub-benchmarks, if any.
|
||||||
|
sub.hasSub = true
|
||||||
|
}
|
||||||
|
if sub.run1() {
|
||||||
|
sub.run()
|
||||||
|
}
|
||||||
|
b.add(sub.result)
|
||||||
|
return !sub.failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// add simulates running benchmarks in sequence in a single iteration. It is
|
||||||
|
// used to give some meaningful results in case func Benchmark is used in
|
||||||
|
// combination with Run.
|
||||||
|
func (b *B) add(other BenchmarkResult) {
|
||||||
|
r := &b.result
|
||||||
|
// The aggregated BenchmarkResults resemble running all subbenchmarks as
|
||||||
|
// in sequence in a single benchmark.
|
||||||
|
r.N = 1
|
||||||
|
r.T += time.Duration(other.NsPerOp())
|
||||||
|
if other.Bytes == 0 {
|
||||||
|
// Summing Bytes is meaningless in aggregate if not all subbenchmarks
|
||||||
|
// set it.
|
||||||
|
b.missingBytes = true
|
||||||
|
r.Bytes = 0
|
||||||
|
}
|
||||||
|
if !b.missingBytes {
|
||||||
|
r.Bytes += other.Bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A PB is used by RunParallel for running parallel benchmarks.
|
||||||
|
type PB struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next reports whether there are more iterations to execute.
|
||||||
|
func (pb *PB) Next() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunParallel runs a benchmark in parallel.
|
||||||
|
//
|
||||||
|
// Not implemented
|
||||||
|
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.
|
||||||
|
//
|
||||||
|
// If f calls Run, the result will be an estimate of running all its
|
||||||
|
// subbenchmarks that don't call Run in sequence in a single benchmark.
|
||||||
|
func Benchmark(f func(b *B)) BenchmarkResult {
|
||||||
|
b := &B{
|
||||||
|
benchFunc: f,
|
||||||
|
benchTime: benchTime,
|
||||||
|
}
|
||||||
|
if b.run1() {
|
||||||
|
b.run()
|
||||||
|
}
|
||||||
|
return b.result
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package testing_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var buf = make([]byte, 13579)
|
||||||
|
|
||||||
|
func NonASCII(b []byte, i int, offset int) int {
|
||||||
|
for i = offset; i < len(b)+offset; i++ {
|
||||||
|
if b[i%len(b)] >= 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkFastNonASCII(b *testing.B) {
|
||||||
|
var val int
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
val += NonASCII(buf, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSlowNonASCII(b *testing.B) {
|
||||||
|
var val int
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
val += NonASCII(buf, 0, 0)
|
||||||
|
val += NonASCII(buf, 0, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestBenchmark simply uses Benchmark twice and makes sure it does not crash.
|
||||||
|
func TestBenchmark(t *testing.T) {
|
||||||
|
// FIXME: reduce runtime from the current 3 seconds.
|
||||||
|
rslow := testing.Benchmark(BenchmarkSlowNonASCII)
|
||||||
|
rfast := testing.Benchmark(BenchmarkFastNonASCII)
|
||||||
|
tslow := rslow.NsPerOp()
|
||||||
|
tfast := rfast.NsPerOp()
|
||||||
|
|
||||||
|
// Be exceedingly forgiving; do not fail even if system gets busy.
|
||||||
|
speedup := float64(tslow) / float64(tfast)
|
||||||
|
if speedup < 0.3 {
|
||||||
|
t.Errorf("Expected speedup >= 0.3, got %f", speedup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSub(b *testing.B) {
|
||||||
|
b.Run("Fast", func(b *testing.B) { BenchmarkFastNonASCII(b) })
|
||||||
|
b.Run("Slow", func(b *testing.B) { BenchmarkSlowNonASCII(b) })
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is a sad stub of the upstream testing package because it doesn't compile
|
||||||
|
with tinygo right now.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InternalFuzzTarget is an internal type but exported because it is
|
||||||
|
// cross-package; it is part of the implementation of the "go test" command.
|
||||||
|
type InternalFuzzTarget struct {
|
||||||
|
Name string
|
||||||
|
Fn func(f *F)
|
||||||
|
}
|
||||||
|
|
||||||
|
// F is a type passed to fuzz tests.
|
||||||
|
//
|
||||||
|
// Fuzz tests run generated inputs against a provided fuzz target, which can
|
||||||
|
// find and report potential bugs in the code being tested.
|
||||||
|
//
|
||||||
|
// A fuzz test runs the seed corpus by default, which includes entries provided
|
||||||
|
// by (*F).Add and entries in the testdata/fuzz/<FuzzTestName> directory. After
|
||||||
|
// any necessary setup and calls to (*F).Add, the fuzz test must then call
|
||||||
|
// (*F).Fuzz to provide the fuzz target. See the testing package documentation
|
||||||
|
// for an example, and see the F.Fuzz and F.Add method documentation for
|
||||||
|
// details.
|
||||||
|
//
|
||||||
|
// *F methods can only be called before (*F).Fuzz. Once the test is
|
||||||
|
// executing the fuzz target, only (*T) methods can be used. The only *F methods
|
||||||
|
// that are allowed in the (*F).Fuzz function are (*F).Failed and (*F).Name.
|
||||||
|
type F struct {
|
||||||
|
common
|
||||||
|
fuzzContext *fuzzContext
|
||||||
|
testContext *testContext
|
||||||
|
|
||||||
|
// inFuzzFn is true when the fuzz function is running. Most F methods cannot
|
||||||
|
// be called when inFuzzFn is true.
|
||||||
|
inFuzzFn bool
|
||||||
|
|
||||||
|
// corpus is a set of seed corpus entries, added with F.Add and loaded
|
||||||
|
// from testdata.
|
||||||
|
corpus []corpusEntry
|
||||||
|
|
||||||
|
result fuzzResult
|
||||||
|
fuzzCalled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// corpusEntry is an alias to the same type as internal/fuzz.CorpusEntry.
|
||||||
|
// We use a type alias because we don't want to export this type, and we can't
|
||||||
|
// import internal/fuzz from testing.
|
||||||
|
type corpusEntry = struct {
|
||||||
|
Parent string
|
||||||
|
Path string
|
||||||
|
Data []byte
|
||||||
|
Values []interface{}
|
||||||
|
Generation int
|
||||||
|
IsSeed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add will add the arguments to the seed corpus for the fuzz test. This will be
|
||||||
|
// a no-op if called after or within the fuzz target, and args must match the
|
||||||
|
// arguments for the fuzz target.
|
||||||
|
func (f *F) Add(args ...interface{}) {
|
||||||
|
var values []interface{}
|
||||||
|
for i := range args {
|
||||||
|
if t := reflect.TypeOf(args[i]); !supportedTypes[t] {
|
||||||
|
panic(fmt.Sprintf("testing: unsupported type to Add %v", t))
|
||||||
|
}
|
||||||
|
values = append(values, args[i])
|
||||||
|
}
|
||||||
|
f.corpus = append(f.corpus, corpusEntry{Values: values, IsSeed: true, Path: fmt.Sprintf("seed#%d", len(f.corpus))})
|
||||||
|
}
|
||||||
|
|
||||||
|
// supportedTypes represents all of the supported types which can be fuzzed.
|
||||||
|
var supportedTypes = map[reflect.Type]bool{
|
||||||
|
reflect.TypeOf(([]byte)("")): true,
|
||||||
|
reflect.TypeOf((string)("")): true,
|
||||||
|
reflect.TypeOf((bool)(false)): true,
|
||||||
|
reflect.TypeOf((byte)(0)): true,
|
||||||
|
reflect.TypeOf((rune)(0)): true,
|
||||||
|
reflect.TypeOf((float32)(0)): true,
|
||||||
|
reflect.TypeOf((float64)(0)): true,
|
||||||
|
reflect.TypeOf((int)(0)): true,
|
||||||
|
reflect.TypeOf((int8)(0)): true,
|
||||||
|
reflect.TypeOf((int16)(0)): true,
|
||||||
|
reflect.TypeOf((int32)(0)): true,
|
||||||
|
reflect.TypeOf((int64)(0)): true,
|
||||||
|
reflect.TypeOf((uint)(0)): true,
|
||||||
|
reflect.TypeOf((uint8)(0)): true,
|
||||||
|
reflect.TypeOf((uint16)(0)): true,
|
||||||
|
reflect.TypeOf((uint32)(0)): true,
|
||||||
|
reflect.TypeOf((uint64)(0)): true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fuzz runs the fuzz function, ff, for fuzz testing. If ff fails for a set of
|
||||||
|
// arguments, those arguments will be added to the seed corpus.
|
||||||
|
//
|
||||||
|
// ff must be a function with no return value whose first argument is *T and
|
||||||
|
// whose remaining arguments are the types to be fuzzed.
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// f.Fuzz(func(t *testing.T, b []byte, i int) { ... })
|
||||||
|
//
|
||||||
|
// The following types are allowed: []byte, string, bool, byte, rune, float32,
|
||||||
|
// float64, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64.
|
||||||
|
// More types may be supported in the future.
|
||||||
|
//
|
||||||
|
// ff must not call any *F methods, e.g. (*F).Log, (*F).Error, (*F).Skip. Use
|
||||||
|
// the corresponding *T method instead. The only *F methods that are allowed in
|
||||||
|
// the (*F).Fuzz function are (*F).Failed and (*F).Name.
|
||||||
|
//
|
||||||
|
// This function should be fast and deterministic, and its behavior should not
|
||||||
|
// depend on shared state. No mutatable input arguments, or pointers to them,
|
||||||
|
// should be retained between executions of the fuzz function, as the memory
|
||||||
|
// backing them may be mutated during a subsequent invocation. ff must not
|
||||||
|
// modify the underlying data of the arguments provided by the fuzzing engine.
|
||||||
|
//
|
||||||
|
// When fuzzing, F.Fuzz does not return until a problem is found, time runs out
|
||||||
|
// (set with -fuzztime), or the test process is interrupted by a signal. F.Fuzz
|
||||||
|
// should be called exactly once, unless F.Skip or F.Fail is called beforehand.
|
||||||
|
func (f *F) Fuzz(ff interface{}) {
|
||||||
|
f.failed = true
|
||||||
|
f.result.N = 0
|
||||||
|
f.result.T = 0
|
||||||
|
f.result.Error = errors.New("operation not implemented")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// fuzzContext holds fields common to all fuzz tests.
|
||||||
|
type fuzzContext struct {
|
||||||
|
deps testDeps
|
||||||
|
mode fuzzMode
|
||||||
|
}
|
||||||
|
|
||||||
|
type fuzzMode uint8
|
||||||
|
|
||||||
|
// fuzzResult contains the results of a fuzz run.
|
||||||
|
type fuzzResult struct {
|
||||||
|
N int // The number of iterations.
|
||||||
|
T time.Duration // The total time taken.
|
||||||
|
Error error // Error is the error from the failing input
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
//go:build baremetal
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
const isBaremetal = true
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
//go:build !baremetal
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
const isBaremetal = false
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// matcher sanitizes, uniques, and filters names of subtests and subbenchmarks.
|
||||||
|
type matcher struct {
|
||||||
|
filter filterMatch
|
||||||
|
skip filterMatch
|
||||||
|
matchFunc func(pat, str string) (bool, error)
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
|
||||||
|
// subNames is used to deduplicate subtest names.
|
||||||
|
// Each key is the subtest name joined to the deduplicated name of the parent test.
|
||||||
|
// Each value is the count of the number of occurrences of the given subtest name
|
||||||
|
// already seen.
|
||||||
|
subNames map[string]int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type filterMatch interface {
|
||||||
|
// matches checks the name against the receiver's pattern strings using the
|
||||||
|
// given match function.
|
||||||
|
matches(name []string, matchString func(pat, str string) (bool, error)) (ok, partial bool)
|
||||||
|
|
||||||
|
// verify checks that the receiver's pattern strings are valid filters by
|
||||||
|
// calling the given match function.
|
||||||
|
verify(name string, matchString func(pat, str string) (bool, error)) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// simpleMatch matches a test name if all of the pattern strings match in
|
||||||
|
// sequence.
|
||||||
|
type simpleMatch []string
|
||||||
|
|
||||||
|
// alternationMatch matches a test name if one of the alternations match.
|
||||||
|
type alternationMatch []filterMatch
|
||||||
|
|
||||||
|
// TODO: fix test_main to avoid race and improve caching, also allowing to
|
||||||
|
// eliminate this Mutex.
|
||||||
|
var matchMutex sync.Mutex
|
||||||
|
|
||||||
|
func allMatcher() *matcher {
|
||||||
|
return newMatcher(nil, "", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMatcher(matchString func(pat, str string) (bool, error), patterns, name, skips string) *matcher {
|
||||||
|
if isBaremetal {
|
||||||
|
matchString = fakeMatchString
|
||||||
|
}
|
||||||
|
|
||||||
|
var filter, skip filterMatch
|
||||||
|
if patterns == "" {
|
||||||
|
filter = simpleMatch{} // always partial true
|
||||||
|
} else {
|
||||||
|
filter = splitRegexp(patterns)
|
||||||
|
if err := filter.verify(name, matchString); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "testing: invalid regexp for %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if skips == "" {
|
||||||
|
skip = alternationMatch{} // always false
|
||||||
|
} else {
|
||||||
|
skip = splitRegexp(skips)
|
||||||
|
if err := skip.verify("-test.skip", matchString); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "testing: invalid regexp for %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &matcher{
|
||||||
|
filter: filter,
|
||||||
|
skip: skip,
|
||||||
|
matchFunc: matchString,
|
||||||
|
subNames: map[string]int32{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *matcher) fullName(c *common, subname string) (name string, ok, partial bool) {
|
||||||
|
name = subname
|
||||||
|
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
|
if c != nil && c.level > 0 {
|
||||||
|
name = m.unique(c.name, rewrite(subname))
|
||||||
|
}
|
||||||
|
|
||||||
|
matchMutex.Lock()
|
||||||
|
defer matchMutex.Unlock()
|
||||||
|
|
||||||
|
// We check the full array of paths each time to allow for the case that a pattern contains a '/'.
|
||||||
|
elem := strings.Split(name, "/")
|
||||||
|
|
||||||
|
// filter must match.
|
||||||
|
// accept partial match that may produce full match later.
|
||||||
|
ok, partial = m.filter.matches(elem, m.matchFunc)
|
||||||
|
if !ok {
|
||||||
|
return name, false, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip must not match.
|
||||||
|
// ignore partial match so we can get to more precise match later.
|
||||||
|
skip, partialSkip := m.skip.matches(elem, m.matchFunc)
|
||||||
|
if skip && !partialSkip {
|
||||||
|
return name, false, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return name, ok, partial
|
||||||
|
}
|
||||||
|
|
||||||
|
// clearSubNames clears the matcher's internal state, potentially freeing
|
||||||
|
// memory. After this is called, T.Name may return the same strings as it did
|
||||||
|
// for earlier subtests.
|
||||||
|
func (m *matcher) clearSubNames() {
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
for key := range m.subNames {
|
||||||
|
delete(m.subNames, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m simpleMatch) matches(name []string, matchString func(pat, str string) (bool, error)) (ok, partial bool) {
|
||||||
|
for i, s := range name {
|
||||||
|
if i >= len(m) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ok, _ := matchString(m[i], s); !ok {
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, len(name) < len(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m simpleMatch) verify(name string, matchString func(pat, str string) (bool, error)) error {
|
||||||
|
for i, s := range m {
|
||||||
|
m[i] = rewrite(s)
|
||||||
|
}
|
||||||
|
// Verify filters before doing any processing.
|
||||||
|
for i, s := range m {
|
||||||
|
if _, err := matchString(s, "non-empty"); err != nil {
|
||||||
|
return fmt.Errorf("element %d of %s (%q): %s", i, name, s, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m alternationMatch) matches(name []string, matchString func(pat, str string) (bool, error)) (ok, partial bool) {
|
||||||
|
for _, m := range m {
|
||||||
|
if ok, partial = m.matches(name, matchString); ok {
|
||||||
|
return ok, partial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m alternationMatch) verify(name string, matchString func(pat, str string) (bool, error)) error {
|
||||||
|
for i, m := range m {
|
||||||
|
if err := m.verify(name, matchString); err != nil {
|
||||||
|
return fmt.Errorf("alternation %d of %s", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitRegexp(s string) filterMatch {
|
||||||
|
a := make(simpleMatch, 0, strings.Count(s, "/"))
|
||||||
|
b := make(alternationMatch, 0, strings.Count(s, "|"))
|
||||||
|
cs := 0
|
||||||
|
cp := 0
|
||||||
|
for i := 0; i < len(s); {
|
||||||
|
switch s[i] {
|
||||||
|
case '[':
|
||||||
|
cs++
|
||||||
|
case ']':
|
||||||
|
if cs--; cs < 0 { // An unmatched ']' is legal.
|
||||||
|
cs = 0
|
||||||
|
}
|
||||||
|
case '(':
|
||||||
|
if cs == 0 {
|
||||||
|
cp++
|
||||||
|
}
|
||||||
|
case ')':
|
||||||
|
if cs == 0 {
|
||||||
|
cp--
|
||||||
|
}
|
||||||
|
case '\\':
|
||||||
|
i++
|
||||||
|
case '/':
|
||||||
|
if cs == 0 && cp == 0 {
|
||||||
|
a = append(a, s[:i])
|
||||||
|
s = s[i+1:]
|
||||||
|
i = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case '|':
|
||||||
|
if cs == 0 && cp == 0 {
|
||||||
|
a = append(a, s[:i])
|
||||||
|
s = s[i+1:]
|
||||||
|
i = 0
|
||||||
|
b = append(b, a)
|
||||||
|
a = make(simpleMatch, 0, len(a))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
a = append(a, s)
|
||||||
|
if len(b) == 0 {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return append(b, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// unique creates a unique name for the given parent and subname by affixing it
|
||||||
|
// with one or more counts, if necessary.
|
||||||
|
func (m *matcher) unique(parent, subname string) string {
|
||||||
|
base := parent + "/" + subname
|
||||||
|
|
||||||
|
for {
|
||||||
|
n := m.subNames[base]
|
||||||
|
if n < 0 {
|
||||||
|
panic("subtest count overflow")
|
||||||
|
}
|
||||||
|
m.subNames[base] = n + 1
|
||||||
|
|
||||||
|
if n == 0 && subname != "" {
|
||||||
|
prefix, nn := parseSubtestNumber(base)
|
||||||
|
if len(prefix) < len(base) && nn < m.subNames[prefix] {
|
||||||
|
// This test is explicitly named like "parent/subname#NN",
|
||||||
|
// and #NN was already used for the NNth occurrence of "parent/subname".
|
||||||
|
// Loop to add a disambiguating suffix.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return base
|
||||||
|
}
|
||||||
|
|
||||||
|
name := fmt.Sprintf("%s#%02d", base, n)
|
||||||
|
if m.subNames[name] != 0 {
|
||||||
|
// This is the nth occurrence of base, but the name "parent/subname#NN"
|
||||||
|
// collides with the first occurrence of a subtest *explicitly* named
|
||||||
|
// "parent/subname#NN". Try the next number.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseSubtestNumber splits a subtest name into a "#%02d"-formatted int32
|
||||||
|
// suffix (if present), and a prefix preceding that suffix (always).
|
||||||
|
func parseSubtestNumber(s string) (prefix string, nn int32) {
|
||||||
|
i := strings.LastIndex(s, "#")
|
||||||
|
if i < 0 {
|
||||||
|
return s, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix, suffix := s[:i], s[i+1:]
|
||||||
|
if len(suffix) < 2 || (len(suffix) > 2 && suffix[0] == '0') {
|
||||||
|
// Even if suffix is numeric, it is not a possible output of a "%02" format
|
||||||
|
// string: it has either too few digits or too many leading zeroes.
|
||||||
|
return s, 0
|
||||||
|
}
|
||||||
|
if suffix == "00" {
|
||||||
|
if !strings.HasSuffix(prefix, "/") {
|
||||||
|
// We only use "#00" as a suffix for subtests named with the empty
|
||||||
|
// string — it isn't a valid suffix if the subtest name is non-empty.
|
||||||
|
return s, 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := strconv.ParseInt(suffix, 10, 32)
|
||||||
|
if err != nil || n < 0 {
|
||||||
|
return s, 0
|
||||||
|
}
|
||||||
|
return prefix, int32(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewrite rewrites a subname to having only printable characters and no white
|
||||||
|
// space.
|
||||||
|
func rewrite(s string) string {
|
||||||
|
b := []byte{}
|
||||||
|
for _, r := range s {
|
||||||
|
switch {
|
||||||
|
case isSpace(r):
|
||||||
|
b = append(b, '_')
|
||||||
|
case !strconv.IsPrint(r):
|
||||||
|
s := strconv.QuoteRune(r)
|
||||||
|
b = append(b, s[1:len(s)-1]...)
|
||||||
|
default:
|
||||||
|
b = append(b, string(r)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSpace(r rune) bool {
|
||||||
|
if r < 0x2000 {
|
||||||
|
switch r {
|
||||||
|
// Note: not the same as Unicode Z class.
|
||||||
|
case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0, 0x1680:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if r <= 0x200a {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case 0x2028, 0x2029, 0x202f, 0x205f, 0x3000:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verify that our IsSpace agrees with unicode.IsSpace.
|
||||||
|
func TestIsSpace(t *T) {
|
||||||
|
n := 0
|
||||||
|
for r := rune(0); r <= unicode.MaxRune; r++ {
|
||||||
|
if isSpace(r) != unicode.IsSpace(r) {
|
||||||
|
t.Errorf("IsSpace(%U)=%t incorrect", r, isSpace(r))
|
||||||
|
n++
|
||||||
|
if n > 10 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitRegexp(t *T) {
|
||||||
|
res := func(s ...string) filterMatch { return simpleMatch(s) }
|
||||||
|
alt := func(m ...filterMatch) filterMatch { return alternationMatch(m) }
|
||||||
|
testCases := []struct {
|
||||||
|
pattern string
|
||||||
|
result filterMatch
|
||||||
|
}{
|
||||||
|
// Correct patterns
|
||||||
|
// If a regexp pattern is correct, all split regexps need to be correct
|
||||||
|
// as well.
|
||||||
|
{"", res("")},
|
||||||
|
{"/", res("", "")},
|
||||||
|
{"//", res("", "", "")},
|
||||||
|
{"A", res("A")},
|
||||||
|
{"A/B", res("A", "B")},
|
||||||
|
{"A/B/", res("A", "B", "")},
|
||||||
|
{"/A/B/", res("", "A", "B", "")},
|
||||||
|
{"[A]/(B)", res("[A]", "(B)")},
|
||||||
|
{"[/]/[/]", res("[/]", "[/]")},
|
||||||
|
{"[/]/[:/]", res("[/]", "[:/]")},
|
||||||
|
{"/]", res("", "]")},
|
||||||
|
{"]/", res("]", "")},
|
||||||
|
{"]/[/]", res("]", "[/]")},
|
||||||
|
{`([)/][(])`, res(`([)/][(])`)},
|
||||||
|
{"[(]/[)]", res("[(]", "[)]")},
|
||||||
|
|
||||||
|
{"A/B|C/D", alt(res("A", "B"), res("C", "D"))},
|
||||||
|
|
||||||
|
// Faulty patterns
|
||||||
|
// Errors in original should produce at least one faulty regexp in results.
|
||||||
|
{")/", res(")/")},
|
||||||
|
{")/(/)", res(")/(", ")")},
|
||||||
|
{"a[/)b", res("a[/)b")},
|
||||||
|
{"(/]", res("(/]")},
|
||||||
|
{"(/", res("(/")},
|
||||||
|
{"[/]/[/", res("[/]", "[/")},
|
||||||
|
{`\p{/}`, res(`\p{`, "}")},
|
||||||
|
{`\p/`, res(`\p`, "")},
|
||||||
|
{`[[:/:]]`, res(`[[:/:]]`)},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
a := splitRegexp(tc.pattern)
|
||||||
|
if !reflect.DeepEqual(a, tc.result) {
|
||||||
|
t.Errorf("splitRegexp(%q) = %#v; want %#v", tc.pattern, a, tc.result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is any error in the pattern, one of the returned subpatterns
|
||||||
|
// needs to have an error as well.
|
||||||
|
if _, err := regexp.Compile(tc.pattern); err != nil {
|
||||||
|
ok := true
|
||||||
|
if err := a.verify("", regexp.MatchString); err != nil {
|
||||||
|
ok = false
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
t.Errorf("%s: expected error in any of %q", tc.pattern, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatcher(t *T) {
|
||||||
|
testCases := []struct {
|
||||||
|
pattern string
|
||||||
|
skip string
|
||||||
|
parent, sub string
|
||||||
|
ok bool
|
||||||
|
partial bool
|
||||||
|
}{
|
||||||
|
// Behavior without subtests.
|
||||||
|
{"", "", "", "TestFoo", true, false},
|
||||||
|
{"TestFoo", "", "", "TestFoo", true, false},
|
||||||
|
{"TestFoo/", "", "", "TestFoo", true, true},
|
||||||
|
{"TestFoo/bar/baz", "", "", "TestFoo", true, true},
|
||||||
|
{"TestFoo", "", "", "TestBar", false, false},
|
||||||
|
{"TestFoo/", "", "", "TestBar", false, false},
|
||||||
|
{"TestFoo/bar/baz", "", "", "TestBar/bar/baz", false, false},
|
||||||
|
{"", "TestBar", "", "TestFoo", true, false},
|
||||||
|
{"", "TestBar", "", "TestBar", false, false},
|
||||||
|
|
||||||
|
// Skipping a non-existent test doesn't change anything.
|
||||||
|
{"", "TestFoo/skipped", "", "TestFoo", true, false},
|
||||||
|
{"TestFoo", "TestFoo/skipped", "", "TestFoo", true, false},
|
||||||
|
{"TestFoo/", "TestFoo/skipped", "", "TestFoo", true, true},
|
||||||
|
{"TestFoo/bar/baz", "TestFoo/skipped", "", "TestFoo", true, true},
|
||||||
|
{"TestFoo", "TestFoo/skipped", "", "TestBar", false, false},
|
||||||
|
{"TestFoo/", "TestFoo/skipped", "", "TestBar", false, false},
|
||||||
|
{"TestFoo/bar/baz", "TestFoo/skipped", "", "TestBar/bar/baz", false, false},
|
||||||
|
|
||||||
|
// with subtests
|
||||||
|
{"", "", "TestFoo", "x", true, false},
|
||||||
|
{"TestFoo", "", "TestFoo", "x", true, false},
|
||||||
|
{"TestFoo/", "", "TestFoo", "x", true, false},
|
||||||
|
{"TestFoo/bar/baz", "", "TestFoo", "bar", true, true},
|
||||||
|
|
||||||
|
{"", "TestFoo/skipped", "TestFoo", "x", true, false},
|
||||||
|
{"TestFoo", "TestFoo/skipped", "TestFoo", "x", true, false},
|
||||||
|
{"TestFoo", "TestFoo/skipped", "TestFoo", "skipped", false, false},
|
||||||
|
{"TestFoo/", "TestFoo/skipped", "TestFoo", "x", true, false},
|
||||||
|
{"TestFoo/bar/baz", "TestFoo/skipped", "TestFoo", "bar", true, true},
|
||||||
|
|
||||||
|
// Subtest with a '/' in its name still allows for copy and pasted names
|
||||||
|
// to match.
|
||||||
|
{"TestFoo/bar/baz", "", "TestFoo", "bar/baz", true, false},
|
||||||
|
{"TestFoo/bar/baz", "TestFoo/bar/baz", "TestFoo", "bar/baz", false, false},
|
||||||
|
{"TestFoo/bar/baz", "TestFoo/bar/baz/skip", "TestFoo", "bar/baz", true, false},
|
||||||
|
{"TestFoo/bar/baz", "", "TestFoo/bar", "baz", true, false},
|
||||||
|
{"TestFoo/bar/baz", "", "TestFoo", "x", false, false},
|
||||||
|
{"TestFoo", "", "TestBar", "x", false, false},
|
||||||
|
{"TestFoo/", "", "TestBar", "x", false, false},
|
||||||
|
{"TestFoo/bar/baz", "", "TestBar", "x/bar/baz", false, false},
|
||||||
|
|
||||||
|
{"A/B|C/D", "", "TestA", "B", true, false},
|
||||||
|
{"A/B|C/D", "", "TestC", "D", true, false},
|
||||||
|
{"A/B|C/D", "", "TestA", "C", false, false},
|
||||||
|
|
||||||
|
// subtests only
|
||||||
|
{"", "", "TestFoo", "x", true, false},
|
||||||
|
{"/", "", "TestFoo", "x", true, false},
|
||||||
|
{"./", "", "TestFoo", "x", true, false},
|
||||||
|
{"./.", "", "TestFoo", "x", true, false},
|
||||||
|
{"/bar/baz", "", "TestFoo", "bar", true, true},
|
||||||
|
{"/bar/baz", "", "TestFoo", "bar/baz", true, false},
|
||||||
|
{"//baz", "", "TestFoo", "bar/baz", true, false},
|
||||||
|
{"//", "", "TestFoo", "bar/baz", true, false},
|
||||||
|
{"/bar/baz", "", "TestFoo/bar", "baz", true, false},
|
||||||
|
{"//foo", "", "TestFoo", "bar/baz", false, false},
|
||||||
|
{"/bar/baz", "", "TestFoo", "x", false, false},
|
||||||
|
{"/bar/baz", "", "TestBar", "x/bar/baz", false, false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
m := newMatcher(regexp.MatchString, tc.pattern, "-test.run", tc.skip)
|
||||||
|
|
||||||
|
parent := &common{name: tc.parent}
|
||||||
|
if tc.parent != "" {
|
||||||
|
parent.level = 1
|
||||||
|
}
|
||||||
|
if n, ok, partial := m.fullName(parent, tc.sub); ok != tc.ok || partial != tc.partial {
|
||||||
|
t.Errorf("for pattern %q, fullName(parent=%q, sub=%q) = %q, ok %v partial %v; want ok %v partial %v",
|
||||||
|
tc.pattern, tc.parent, tc.sub, n, ok, partial, tc.ok, tc.partial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var namingTestCases = []struct{ name, want string }{
|
||||||
|
// Uniqueness
|
||||||
|
{"", "x/#00"},
|
||||||
|
{"", "x/#01"},
|
||||||
|
{"#0", "x/#0"}, // Doesn't conflict with #00 because the number of digits differs.
|
||||||
|
{"#00", "x/#00#01"}, // Conflicts with implicit #00 (used above), so add a suffix.
|
||||||
|
{"#", "x/#"},
|
||||||
|
{"#", "x/##01"},
|
||||||
|
|
||||||
|
{"t", "x/t"},
|
||||||
|
{"t", "x/t#01"},
|
||||||
|
{"t", "x/t#02"},
|
||||||
|
{"t#00", "x/t#00"}, // Explicit "#00" doesn't conflict with the unsuffixed first subtest.
|
||||||
|
|
||||||
|
{"a#01", "x/a#01"}, // user has subtest with this name.
|
||||||
|
{"a", "x/a"}, // doesn't conflict with this name.
|
||||||
|
{"a", "x/a#02"}, // This string is claimed now, so resume
|
||||||
|
{"a", "x/a#03"}, // with counting.
|
||||||
|
{"a#02", "x/a#02#01"}, // We already used a#02 once, so add a suffix.
|
||||||
|
|
||||||
|
{"b#00", "x/b#00"},
|
||||||
|
{"b", "x/b"}, // Implicit 0 doesn't conflict with explicit "#00".
|
||||||
|
{"b", "x/b#01"},
|
||||||
|
{"b#9223372036854775807", "x/b#9223372036854775807"}, // MaxInt64
|
||||||
|
{"b", "x/b#02"},
|
||||||
|
{"b", "x/b#03"},
|
||||||
|
|
||||||
|
// Sanitizing
|
||||||
|
{"A:1 B:2", "x/A:1_B:2"},
|
||||||
|
{"s\t\r\u00a0", "x/s___"},
|
||||||
|
{"\x01", `x/\x01`},
|
||||||
|
{"\U0010ffff", `x/\U0010ffff`},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNaming(t *T) {
|
||||||
|
m := newMatcher(regexp.MatchString, "", "", "")
|
||||||
|
parent := &common{name: "x", level: 1} // top-level test.
|
||||||
|
|
||||||
|
for i, tc := range namingTestCases {
|
||||||
|
if got, _, _ := m.fullName(parent, tc.name); got != tc.want {
|
||||||
|
t.Errorf("%d:%s: got %q; want %q", i, tc.name, got, tc.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FuzzNaming(f *F) {
|
||||||
|
for _, tc := range namingTestCases {
|
||||||
|
f.Add(tc.name)
|
||||||
|
}
|
||||||
|
parent := &common{name: "x", level: 1}
|
||||||
|
var m *matcher
|
||||||
|
var seen map[string]string
|
||||||
|
reset := func() {
|
||||||
|
m = allMatcher()
|
||||||
|
seen = make(map[string]string)
|
||||||
|
}
|
||||||
|
reset()
|
||||||
|
|
||||||
|
f.Fuzz(func(t *T, subname string) {
|
||||||
|
if len(subname) > 10 {
|
||||||
|
// Long names attract the OOM killer.
|
||||||
|
t.Skip()
|
||||||
|
}
|
||||||
|
name := m.unique(parent.name, subname)
|
||||||
|
if !strings.Contains(name, "/"+subname) {
|
||||||
|
t.Errorf("name %q does not contain subname %q", name, subname)
|
||||||
|
}
|
||||||
|
if prev, ok := seen[name]; ok {
|
||||||
|
t.Errorf("name %q generated by both %q and %q", name, prev, subname)
|
||||||
|
}
|
||||||
|
if len(seen) > 1e6 {
|
||||||
|
// Free up memory.
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
seen[name] = subname
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoString returns a string that is more readable than the default, which makes
|
||||||
|
// it easier to read test errors.
|
||||||
|
func (m alternationMatch) GoString() string {
|
||||||
|
s := make([]string, len(m))
|
||||||
|
for i, m := range m {
|
||||||
|
s[i] = fmt.Sprintf("%#v", m)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("(%s)", strings.Join(s, " | "))
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCleanup(t *T) {
|
||||||
|
var cleanups []int
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() { cleanups = append(cleanups, 1) })
|
||||||
|
t.Cleanup(func() { cleanups = append(cleanups, 2) })
|
||||||
|
})
|
||||||
|
if got, want := cleanups, []int{2, 1}; !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("unexpected cleanup record; got %v want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunCleanup(t *T) {
|
||||||
|
outerCleanup := 0
|
||||||
|
innerCleanup := 0
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() { outerCleanup++ })
|
||||||
|
t.Run("x", func(t *T) {
|
||||||
|
t.Cleanup(func() { innerCleanup++ })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if innerCleanup != 1 {
|
||||||
|
t.Errorf("unexpected inner cleanup count; got %d want 1", innerCleanup)
|
||||||
|
}
|
||||||
|
if outerCleanup != 1 {
|
||||||
|
t.Errorf("unexpected outer cleanup count; got %d want 1", outerCleanup) // wrong upstream!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCleanupParallelSubtests(t *T) {
|
||||||
|
ranCleanup := 0
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() { ranCleanup++ })
|
||||||
|
t.Run("x", func(t *T) {
|
||||||
|
t.Parallel()
|
||||||
|
if ranCleanup > 0 {
|
||||||
|
t.Error("outer cleanup ran before parallel subtest")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if ranCleanup != 1 {
|
||||||
|
t.Errorf("unexpected cleanup count; got %d want 1", ranCleanup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNestedCleanup(t *T) {
|
||||||
|
ranCleanup := 0
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if ranCleanup != 2 {
|
||||||
|
t.Errorf("unexpected cleanup count in first cleanup: got %d want 2", ranCleanup)
|
||||||
|
}
|
||||||
|
ranCleanup++
|
||||||
|
})
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if ranCleanup != 0 {
|
||||||
|
t.Errorf("unexpected cleanup count in second cleanup: got %d want 0", ranCleanup)
|
||||||
|
}
|
||||||
|
ranCleanup++
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if ranCleanup != 1 {
|
||||||
|
t.Errorf("unexpected cleanup count in nested cleanup: got %d want 1", ranCleanup)
|
||||||
|
}
|
||||||
|
ranCleanup++
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if ranCleanup != 3 {
|
||||||
|
t.Errorf("unexpected cleanup count: got %d want 3", ranCleanup)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,686 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
// This file has been modified for use by the TinyGo compiler.
|
||||||
|
// src: https://github.com/golang/go/blob/61bb56ad/src/testing/testing.go
|
||||||
|
|
||||||
|
// Package testing provides support for automated testing of Go packages.
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Testing flags.
|
||||||
|
var (
|
||||||
|
flagVerbose bool
|
||||||
|
flagShort bool
|
||||||
|
flagRunRegexp string
|
||||||
|
flagSkipRegexp string
|
||||||
|
flagShuffle string
|
||||||
|
flagCount int
|
||||||
|
)
|
||||||
|
|
||||||
|
var initRan bool
|
||||||
|
|
||||||
|
// Init registers testing flags. It has no effect if it has already run.
|
||||||
|
func Init() {
|
||||||
|
if initRan {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
initRan = true
|
||||||
|
|
||||||
|
flag.BoolVar(&flagVerbose, "test.v", false, "verbose: print additional output")
|
||||||
|
flag.BoolVar(&flagShort, "test.short", false, "short: run smaller test suite to save time")
|
||||||
|
flag.StringVar(&flagRunRegexp, "test.run", "", "run: regexp of tests to run")
|
||||||
|
flag.StringVar(&flagSkipRegexp, "test.skip", "", "skip: regexp of tests to run")
|
||||||
|
flag.StringVar(&flagShuffle, "test.shuffle", "off", "shuffle: off, on, <numeric-seed>")
|
||||||
|
|
||||||
|
flag.IntVar(&flagCount, "test.count", 1, "run each test or benchmark `count` times")
|
||||||
|
|
||||||
|
initBenchmarkFlags()
|
||||||
|
}
|
||||||
|
|
||||||
|
// common holds the elements common between T and B and
|
||||||
|
// captures common methods such as Errorf.
|
||||||
|
type common struct {
|
||||||
|
output *logger
|
||||||
|
indent string
|
||||||
|
ran bool // Test or benchmark (or one of its subtests) was executed.
|
||||||
|
failed bool // Test or benchmark has failed.
|
||||||
|
skipped bool // Test of benchmark has been skipped.
|
||||||
|
cleanups []func() // optional functions to be called at the end of the test
|
||||||
|
finished bool // Test function has completed.
|
||||||
|
|
||||||
|
hasSub bool // TODO: should be atomic
|
||||||
|
|
||||||
|
parent *common
|
||||||
|
level int // Nesting depth of test or benchmark.
|
||||||
|
name string // Name of test or benchmark.
|
||||||
|
start time.Time // Time test or benchmark started
|
||||||
|
duration time.Duration
|
||||||
|
|
||||||
|
tempDir string
|
||||||
|
tempDirErr error
|
||||||
|
tempDirSeq int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type logger struct {
|
||||||
|
logToStdout bool
|
||||||
|
b bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Write(p []byte) (int, error) {
|
||||||
|
if l.logToStdout {
|
||||||
|
return os.Stdout.Write(p)
|
||||||
|
}
|
||||||
|
return l.b.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
if l.logToStdout {
|
||||||
|
// We've already been logging to stdout; nothing to do.
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return l.b.WriteTo(w)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Len() int {
|
||||||
|
return l.b.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Short reports whether the -test.short flag is set.
|
||||||
|
func Short() bool {
|
||||||
|
return flagShort
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoverMode reports what the test coverage mode is set to.
|
||||||
|
//
|
||||||
|
// Test coverage is not supported; this returns the empty string.
|
||||||
|
func CoverMode() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verbose reports whether the -test.v flag is set.
|
||||||
|
func Verbose() bool {
|
||||||
|
return flagVerbose
|
||||||
|
}
|
||||||
|
|
||||||
|
// String constant that is being set when running a test.
|
||||||
|
var testBinary string
|
||||||
|
|
||||||
|
// Testing returns whether the program was compiled as a test, using "tinygo
|
||||||
|
// test". It returns false when built using "tinygo build", "tinygo flash", etc.
|
||||||
|
func Testing() bool {
|
||||||
|
return testBinary == "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// flushToParent writes c.output to the parent after first writing the header
|
||||||
|
// with the given format and arguments.
|
||||||
|
func (c *common) flushToParent(testName, format string, args ...interface{}) {
|
||||||
|
if c.parent == nil {
|
||||||
|
// The fake top-level test doesn't want a FAIL or PASS banner.
|
||||||
|
// Not quite sure how this works upstream.
|
||||||
|
c.output.WriteTo(os.Stdout)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(c.parent.output, format, args...)
|
||||||
|
c.output.WriteTo(c.parent.output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmtDuration returns a string representing d in the form "87.00s".
|
||||||
|
func fmtDuration(d time.Duration) string {
|
||||||
|
return fmt.Sprintf("%.2fs", d.Seconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
// TB is the interface common to T and B.
|
||||||
|
type TB interface {
|
||||||
|
Cleanup(func())
|
||||||
|
Error(args ...interface{})
|
||||||
|
Errorf(format string, args ...interface{})
|
||||||
|
Fail()
|
||||||
|
FailNow()
|
||||||
|
Failed() bool
|
||||||
|
Fatal(args ...interface{})
|
||||||
|
Fatalf(format string, args ...interface{})
|
||||||
|
Helper()
|
||||||
|
Log(args ...interface{})
|
||||||
|
Logf(format string, args ...interface{})
|
||||||
|
Name() string
|
||||||
|
Setenv(key, value string)
|
||||||
|
Skip(args ...interface{})
|
||||||
|
SkipNow()
|
||||||
|
Skipf(format string, args ...interface{})
|
||||||
|
Skipped() bool
|
||||||
|
TempDir() string
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ TB = (*T)(nil)
|
||||||
|
var _ TB = (*B)(nil)
|
||||||
|
|
||||||
|
// T is a type passed to Test functions to manage test state and support formatted test logs.
|
||||||
|
// Logs are accumulated during execution and dumped to standard output when done.
|
||||||
|
type T struct {
|
||||||
|
common
|
||||||
|
context *testContext // For running tests and subtests.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the running test or benchmark.
|
||||||
|
func (c *common) Name() string {
|
||||||
|
return c.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *common) setRan() {
|
||||||
|
if c.parent != nil {
|
||||||
|
c.parent.setRan()
|
||||||
|
}
|
||||||
|
c.ran = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail marks the function as having failed but continues execution.
|
||||||
|
func (c *common) Fail() {
|
||||||
|
c.failed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed reports whether the function has failed.
|
||||||
|
func (c *common) Failed() bool {
|
||||||
|
failed := c.failed
|
||||||
|
return failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// FailNow marks the function as having failed and stops its execution
|
||||||
|
// by calling runtime.Goexit (which then runs all deferred calls in the
|
||||||
|
// current goroutine).
|
||||||
|
func (c *common) FailNow() {
|
||||||
|
c.Fail()
|
||||||
|
|
||||||
|
c.finished = true
|
||||||
|
c.Error("FailNow is incomplete, requires runtime.Goexit()")
|
||||||
|
}
|
||||||
|
|
||||||
|
// log generates the output.
|
||||||
|
func (c *common) log(s string) {
|
||||||
|
// This doesn't print the same as in upstream go, but works for now.
|
||||||
|
if len(s) != 0 && s[len(s)-1] == '\n' {
|
||||||
|
s = s[:len(s)-1]
|
||||||
|
}
|
||||||
|
lines := strings.Split(s, "\n")
|
||||||
|
// First line.
|
||||||
|
fmt.Fprintf(c.output, "%s %s\n", c.indent, lines[0])
|
||||||
|
// More lines.
|
||||||
|
for _, line := range lines[1:] {
|
||||||
|
fmt.Fprintf(c.output, "%s %s\n", c.indent, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log formats its arguments using default formatting, analogous to Println,
|
||||||
|
// and records the text in the error log. For tests, the text will be printed only if
|
||||||
|
// the test fails or the -test.v flag is set. For benchmarks, the text is always
|
||||||
|
// printed to avoid having performance depend on the value of the -test.v flag.
|
||||||
|
func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) }
|
||||||
|
|
||||||
|
// Logf formats its arguments according to the format, analogous to Printf, and
|
||||||
|
// records the text in the error log. A final newline is added if not provided. For
|
||||||
|
// tests, the text will be printed only if the test fails or the -test.v flag is
|
||||||
|
// set. For benchmarks, the text is always printed to avoid having performance
|
||||||
|
// depend on the value of the -test.v flag.
|
||||||
|
func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) }
|
||||||
|
|
||||||
|
// Error is equivalent to Log followed by Fail.
|
||||||
|
func (c *common) Error(args ...interface{}) {
|
||||||
|
c.log(fmt.Sprintln(args...))
|
||||||
|
c.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errorf is equivalent to Logf followed by Fail.
|
||||||
|
func (c *common) Errorf(format string, args ...interface{}) {
|
||||||
|
c.log(fmt.Sprintf(format, args...))
|
||||||
|
c.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatal is equivalent to Log followed by FailNow.
|
||||||
|
func (c *common) Fatal(args ...interface{}) {
|
||||||
|
c.log(fmt.Sprintln(args...))
|
||||||
|
c.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatalf is equivalent to Logf followed by FailNow.
|
||||||
|
func (c *common) Fatalf(format string, args ...interface{}) {
|
||||||
|
c.log(fmt.Sprintf(format, args...))
|
||||||
|
c.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip is equivalent to Log followed by SkipNow.
|
||||||
|
func (c *common) Skip(args ...interface{}) {
|
||||||
|
c.log(fmt.Sprintln(args...))
|
||||||
|
c.SkipNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skipf is equivalent to Logf followed by SkipNow.
|
||||||
|
func (c *common) Skipf(format string, args ...interface{}) {
|
||||||
|
c.log(fmt.Sprintf(format, args...))
|
||||||
|
c.SkipNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkipNow marks the test as having been skipped and stops its execution
|
||||||
|
// by calling runtime.Goexit.
|
||||||
|
func (c *common) SkipNow() {
|
||||||
|
c.skip()
|
||||||
|
c.finished = true
|
||||||
|
c.Error("SkipNow is incomplete, requires runtime.Goexit()")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *common) skip() {
|
||||||
|
c.skipped = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skipped reports whether the test was skipped.
|
||||||
|
func (c *common) Skipped() bool {
|
||||||
|
return c.skipped
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper is not implemented, it is only provided for compatibility.
|
||||||
|
func (c *common) Helper() {
|
||||||
|
// Unimplemented.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup registers a function to be called when the test (or subtest) and all its
|
||||||
|
// subtests complete. Cleanup functions will be called in last added,
|
||||||
|
// first called order.
|
||||||
|
func (c *common) Cleanup(f func()) {
|
||||||
|
c.cleanups = append(c.cleanups, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TempDir returns a temporary directory for the test to use.
|
||||||
|
// The directory is automatically removed by Cleanup when the test and
|
||||||
|
// all its subtests complete.
|
||||||
|
// Each subsequent call to t.TempDir returns a unique directory;
|
||||||
|
// if the directory creation fails, TempDir terminates the test by calling Fatal.
|
||||||
|
func (c *common) TempDir() string {
|
||||||
|
// Use a single parent directory for all the temporary directories
|
||||||
|
// created by a test, each numbered sequentially.
|
||||||
|
var nonExistent bool
|
||||||
|
if c.tempDir == "" { // Usually the case with js/wasm
|
||||||
|
nonExistent = true
|
||||||
|
} else {
|
||||||
|
_, err := os.Stat(c.tempDir)
|
||||||
|
nonExistent = errors.Is(err, fs.ErrNotExist)
|
||||||
|
if err != nil && !nonExistent {
|
||||||
|
c.Fatalf("TempDir: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nonExistent {
|
||||||
|
c.Helper()
|
||||||
|
|
||||||
|
// Drop unusual characters (such as path separators or
|
||||||
|
// characters interacting with globs) from the directory name to
|
||||||
|
// avoid surprising os.MkdirTemp behavior.
|
||||||
|
mapper := func(r rune) rune {
|
||||||
|
if r < utf8.RuneSelf {
|
||||||
|
const allowed = "!#$%&()+,-.=@^_{}~ "
|
||||||
|
if '0' <= r && r <= '9' ||
|
||||||
|
'a' <= r && r <= 'z' ||
|
||||||
|
'A' <= r && r <= 'Z' {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
if strings.ContainsRune(allowed, r) {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
} else if unicode.IsLetter(r) || unicode.IsNumber(r) {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
pattern := strings.Map(mapper, c.Name())
|
||||||
|
c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
|
||||||
|
if c.tempDirErr == nil {
|
||||||
|
c.Cleanup(func() {
|
||||||
|
if err := os.RemoveAll(c.tempDir); err != nil {
|
||||||
|
c.Errorf("TempDir RemoveAll cleanup: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.tempDirErr != nil {
|
||||||
|
c.Fatalf("TempDir: %v", c.tempDirErr)
|
||||||
|
}
|
||||||
|
seq := c.tempDirSeq
|
||||||
|
c.tempDirSeq++
|
||||||
|
dir := fmt.Sprintf("%s%c%03d", c.tempDir, os.PathSeparator, seq)
|
||||||
|
if err := os.Mkdir(dir, 0777); err != nil {
|
||||||
|
c.Fatalf("TempDir: %v", err)
|
||||||
|
}
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setenv calls os.Setenv(key, value) and uses Cleanup to
|
||||||
|
// restore the environment variable to its original value
|
||||||
|
// after the test.
|
||||||
|
func (c *common) Setenv(key, value string) {
|
||||||
|
prevValue, ok := os.LookupEnv(key)
|
||||||
|
|
||||||
|
if err := os.Setenv(key, value); err != nil {
|
||||||
|
c.Fatalf("cannot set environment variable: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
c.Cleanup(func() {
|
||||||
|
os.Setenv(key, prevValue)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
c.Cleanup(func() {
|
||||||
|
os.Unsetenv(key)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chdir calls os.Chdir(dir) and uses Cleanup to restore the current
|
||||||
|
// working directory to its original value after the test. On Unix, it
|
||||||
|
// also sets PWD environment variable for the duration of the test.
|
||||||
|
//
|
||||||
|
// Because Chdir affects the whole process, it cannot be used
|
||||||
|
// in parallel tests or tests with parallel ancestors.
|
||||||
|
func (c *common) Chdir(dir string) {
|
||||||
|
// Note: function copied from the Go 1.24.0 source tree.
|
||||||
|
|
||||||
|
oldwd, err := os.Open(".")
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.Chdir(dir); err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
// On POSIX platforms, PWD represents “an absolute pathname of the
|
||||||
|
// current working directory.” Since we are changing the working
|
||||||
|
// directory, we should also set or update PWD to reflect that.
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows", "plan9":
|
||||||
|
// Windows and Plan 9 do not use the PWD variable.
|
||||||
|
default:
|
||||||
|
if !filepath.IsAbs(dir) {
|
||||||
|
dir, err = os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Setenv("PWD", dir)
|
||||||
|
}
|
||||||
|
c.Cleanup(func() {
|
||||||
|
err := oldwd.Chdir()
|
||||||
|
oldwd.Close()
|
||||||
|
if err != nil {
|
||||||
|
// It's not safe to continue with tests if we can't
|
||||||
|
// get back to the original working directory. Since
|
||||||
|
// we are holding a dirfd, this is highly unlikely.
|
||||||
|
panic("testing.Chdir: " + err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// runCleanup is called at the end of the test.
|
||||||
|
func (c *common) runCleanup() {
|
||||||
|
for {
|
||||||
|
var cleanup func()
|
||||||
|
if len(c.cleanups) > 0 {
|
||||||
|
last := len(c.cleanups) - 1
|
||||||
|
cleanup = c.cleanups[last]
|
||||||
|
c.cleanups = c.cleanups[:last]
|
||||||
|
}
|
||||||
|
if cleanup == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cleanup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parallel is not implemented, it is only provided for compatibility.
|
||||||
|
func (t *T) Parallel() {
|
||||||
|
// Unimplemented.
|
||||||
|
}
|
||||||
|
|
||||||
|
// InternalTest is a reference to a test that should be called during a test suite run.
|
||||||
|
type InternalTest struct {
|
||||||
|
Name string
|
||||||
|
F func(*T)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tRunner(t *T, fn func(t *T)) {
|
||||||
|
defer func() {
|
||||||
|
t.runCleanup()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Run the test.
|
||||||
|
t.start = time.Now()
|
||||||
|
fn(t)
|
||||||
|
t.duration += time.Since(t.start) // TODO: capture cleanup time, too.
|
||||||
|
|
||||||
|
t.report() // Report after all subtests have finished.
|
||||||
|
if t.parent != nil && !t.hasSub {
|
||||||
|
t.setRan()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs f as a subtest of t called name. It waits until the subtest is finished
|
||||||
|
// and returns whether the subtest succeeded.
|
||||||
|
func (t *T) Run(name string, f func(t *T)) bool {
|
||||||
|
t.hasSub = true
|
||||||
|
testName, ok, _ := t.context.match.fullName(&t.common, name)
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a subtest.
|
||||||
|
sub := T{
|
||||||
|
common: common{
|
||||||
|
output: &logger{logToStdout: flagVerbose},
|
||||||
|
name: testName,
|
||||||
|
parent: &t.common,
|
||||||
|
level: t.level + 1,
|
||||||
|
},
|
||||||
|
context: t.context,
|
||||||
|
}
|
||||||
|
if t.level > 0 {
|
||||||
|
sub.indent = sub.indent + " "
|
||||||
|
}
|
||||||
|
if flagVerbose {
|
||||||
|
fmt.Fprintf(t.output, "=== RUN %s\n", sub.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
tRunner(&sub, f)
|
||||||
|
return !sub.failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deadline reports the time at which the test binary will have
|
||||||
|
// exceeded the timeout specified by the -timeout flag.
|
||||||
|
//
|
||||||
|
// The ok result is false if the -timeout flag indicates “no timeout” (0).
|
||||||
|
// For now tinygo always return 0, false.
|
||||||
|
//
|
||||||
|
// Not Implemented.
|
||||||
|
func (t *T) Deadline() (deadline time.Time, ok bool) {
|
||||||
|
deadline = t.context.deadline
|
||||||
|
return deadline, !deadline.IsZero()
|
||||||
|
}
|
||||||
|
|
||||||
|
// testContext holds all fields that are common to all tests. This includes
|
||||||
|
// synchronization primitives to run at most *parallel tests.
|
||||||
|
type testContext struct {
|
||||||
|
match *matcher
|
||||||
|
deadline time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTestContext(m *matcher) *testContext {
|
||||||
|
return &testContext{
|
||||||
|
match: m,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// M is a test suite.
|
||||||
|
type M struct {
|
||||||
|
// tests is a list of the test names to execute
|
||||||
|
Tests []InternalTest
|
||||||
|
Benchmarks []InternalBenchmark
|
||||||
|
|
||||||
|
deps testDeps
|
||||||
|
|
||||||
|
// value to pass to os.Exit, the outer test func main
|
||||||
|
// harness calls os.Exit with this code. See #34129.
|
||||||
|
exitCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
type testDeps interface {
|
||||||
|
MatchString(pat, str string) (bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *M) shuffle() error {
|
||||||
|
var n int64
|
||||||
|
|
||||||
|
if flagShuffle == "on" {
|
||||||
|
n = time.Now().UnixNano()
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
n, err = strconv.ParseInt(flagShuffle, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
m.exitCode = 2
|
||||||
|
return fmt.Errorf(`testing: -shuffle should be "off", "on", or a valid integer: %v`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("-test.shuffle", n)
|
||||||
|
rng := rand.New(rand.NewSource(n))
|
||||||
|
rng.Shuffle(len(m.Tests), func(i, j int) { m.Tests[i], m.Tests[j] = m.Tests[j], m.Tests[i] })
|
||||||
|
rng.Shuffle(len(m.Benchmarks), func(i, j int) { m.Benchmarks[i], m.Benchmarks[j] = m.Benchmarks[j], m.Benchmarks[i] })
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs the tests. It returns an exit code to pass to os.Exit.
|
||||||
|
func (m *M) Run() (code int) {
|
||||||
|
defer func() {
|
||||||
|
code = m.exitCode
|
||||||
|
}()
|
||||||
|
|
||||||
|
if !flag.Parsed() {
|
||||||
|
flag.Parse()
|
||||||
|
}
|
||||||
|
|
||||||
|
if flagShuffle != "off" {
|
||||||
|
if err := m.shuffle(); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testRan, testOk := runTests(m.deps.MatchString, m.Tests)
|
||||||
|
if !testRan && *matchBenchmarks == "" {
|
||||||
|
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
|
||||||
|
}
|
||||||
|
if !testOk || !runBenchmarks(m.deps.MatchString, m.Benchmarks) {
|
||||||
|
fmt.Println("FAIL")
|
||||||
|
m.exitCode = 1
|
||||||
|
} else {
|
||||||
|
fmt.Println("PASS")
|
||||||
|
m.exitCode = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ran, ok bool) {
|
||||||
|
ok = true
|
||||||
|
|
||||||
|
ctx := newTestContext(newMatcher(matchString, flagRunRegexp, "-test.run", flagSkipRegexp))
|
||||||
|
t := &T{
|
||||||
|
common: common{
|
||||||
|
output: &logger{logToStdout: flagVerbose},
|
||||||
|
},
|
||||||
|
context: ctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < flagCount; i++ {
|
||||||
|
tRunner(t, func(t *T) {
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.Name, test.F)
|
||||||
|
ok = ok && !t.Failed()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.ran, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) report() {
|
||||||
|
dstr := fmtDuration(t.duration)
|
||||||
|
format := t.indent + "--- %s: %s (%s)\n"
|
||||||
|
if t.Failed() {
|
||||||
|
if t.parent != nil {
|
||||||
|
t.parent.failed = true
|
||||||
|
}
|
||||||
|
t.flushToParent(t.name, format, "FAIL", t.name, dstr)
|
||||||
|
} else if flagVerbose {
|
||||||
|
if t.Skipped() {
|
||||||
|
t.flushToParent(t.name, format, "SKIP", t.name, dstr)
|
||||||
|
} else {
|
||||||
|
t.flushToParent(t.name, format, "PASS", t.name, dstr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllocsPerRun returns the average number of allocations during calls to f.
|
||||||
|
// Although the return value has type float64, it will always be an integral
|
||||||
|
// value.
|
||||||
|
//
|
||||||
|
// Not implemented.
|
||||||
|
func AllocsPerRun(runs int, f func()) (avg float64) {
|
||||||
|
f()
|
||||||
|
for i := 0; i < runs; i++ {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type InternalExample struct {
|
||||||
|
Name string
|
||||||
|
F func()
|
||||||
|
Output string
|
||||||
|
Unordered bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// MainStart is meant for use by tests generated by 'go test'.
|
||||||
|
// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
|
||||||
|
// It may change signature from release to release.
|
||||||
|
func MainStart(deps interface{}, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M {
|
||||||
|
Init()
|
||||||
|
return &M{
|
||||||
|
Tests: tests,
|
||||||
|
Benchmarks: benchmarks,
|
||||||
|
deps: deps.(testDeps),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A fake regexp matcher.
|
||||||
|
// Inflexible, but saves 50KB of flash and 50KB of RAM per -size full,
|
||||||
|
// and lets tests pass on cortex-m.
|
||||||
|
func fakeMatchString(pat, str string) (bool, error) {
|
||||||
|
if pat == ".*" {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
matched := strings.Contains(str, pat)
|
||||||
|
return matched, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
// TODO: implement readdir for windows, then enable this file
|
||||||
|
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package testing_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is exactly what a test would do without a TestMain.
|
||||||
|
// It's here only so that there is at least one package in the
|
||||||
|
// standard library with a TestMain, so that code is executed.
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
os.Exit(m.Run())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTempDirInCleanup(t *testing.T) {
|
||||||
|
if runtime.GOOS == "wasip1" || runtime.GOOS == "wasip2" {
|
||||||
|
t.Log("Skipping. TODO: implement RemoveAll for wasi")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var dir string
|
||||||
|
|
||||||
|
t.Run("test", func(t *testing.T) {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
dir = t.TempDir()
|
||||||
|
})
|
||||||
|
_ = t.TempDir()
|
||||||
|
})
|
||||||
|
|
||||||
|
fi, err := os.Stat(dir)
|
||||||
|
if fi != nil {
|
||||||
|
t.Fatalf("Directory %q from user Cleanup still exists", dir)
|
||||||
|
}
|
||||||
|
if !errors.Is(err, fs.ErrNotExist) {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTempDirInBenchmark(t *testing.T) {
|
||||||
|
testing.Benchmark(func(b *testing.B) {
|
||||||
|
if !b.Run("test", func(b *testing.B) {
|
||||||
|
// Add a loop so that the test won't fail. See issue 38677.
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = b.TempDir()
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
t.Fatal("Sub test failure in a benchmark")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTempDir(t *testing.T) {
|
||||||
|
if runtime.GOOS == "wasip1" || runtime.GOOS == "wasip2" {
|
||||||
|
t.Log("Skipping. TODO: implement RemoveAll for wasi")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
testTempDir(t)
|
||||||
|
t.Run("InSubtest", testTempDir)
|
||||||
|
t.Run("test/subtest", testTempDir)
|
||||||
|
t.Run("test\\subtest", testTempDir)
|
||||||
|
t.Run("test:subtest", testTempDir)
|
||||||
|
t.Run("test/..", testTempDir)
|
||||||
|
t.Run("../test", testTempDir)
|
||||||
|
t.Run("test[]", testTempDir)
|
||||||
|
t.Run("test*", testTempDir)
|
||||||
|
t.Run("äöüéè", testTempDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTempDir(t *testing.T) {
|
||||||
|
dirCh := make(chan string, 1)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
// Verify directory has been removed.
|
||||||
|
select {
|
||||||
|
case dir := <-dirCh:
|
||||||
|
fi, err := os.Stat(dir)
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
// All good
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Errorf("directory %q still exists: %v, isDir=%v", dir, fi, fi.IsDir())
|
||||||
|
default:
|
||||||
|
if !t.Failed() {
|
||||||
|
t.Fatal("never received dir channel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
dir := t.TempDir()
|
||||||
|
if dir == "" {
|
||||||
|
t.Fatal("expected dir")
|
||||||
|
}
|
||||||
|
dir2 := t.TempDir()
|
||||||
|
if dir == dir2 {
|
||||||
|
t.Fatal("subsequent calls to TempDir returned the same directory")
|
||||||
|
}
|
||||||
|
if filepath.Dir(dir) != filepath.Dir(dir2) {
|
||||||
|
t.Fatalf("calls to TempDir do not share a parent; got %q, %q", dir, dir2)
|
||||||
|
}
|
||||||
|
dirCh <- dir
|
||||||
|
fi, err := os.Stat(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !fi.IsDir() {
|
||||||
|
t.Errorf("dir %q is not a dir", dir)
|
||||||
|
}
|
||||||
|
files, err := os.ReadDir(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(files) > 0 {
|
||||||
|
t.Errorf("unexpected %d files in TempDir: %v", len(files), files)
|
||||||
|
}
|
||||||
|
|
||||||
|
glob := filepath.Join(dir, "*.txt")
|
||||||
|
if _, err := filepath.Glob(glob); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Remove(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected files in TempDir")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetenv(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
key string
|
||||||
|
initialValueExists bool
|
||||||
|
initialValue string
|
||||||
|
newValue string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "initial value exists",
|
||||||
|
key: "GO_TEST_KEY_1",
|
||||||
|
initialValueExists: true,
|
||||||
|
initialValue: "111",
|
||||||
|
newValue: "222",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "initial value exists but empty",
|
||||||
|
key: "GO_TEST_KEY_2",
|
||||||
|
initialValueExists: true,
|
||||||
|
initialValue: "",
|
||||||
|
newValue: "222",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "initial value is not exists",
|
||||||
|
key: "GO_TEST_KEY_3",
|
||||||
|
initialValueExists: false,
|
||||||
|
initialValue: "",
|
||||||
|
newValue: "222",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
if test.initialValueExists {
|
||||||
|
if err := os.Setenv(test.key, test.initialValue); err != nil {
|
||||||
|
t.Fatalf("unable to set env: got %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
os.Unsetenv(test.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Setenv(test.key, test.newValue)
|
||||||
|
if os.Getenv(test.key) != test.newValue {
|
||||||
|
t.Fatalf("unexpected value after t.Setenv: got %s, want %s", os.Getenv(test.key), test.newValue)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
got, exists := os.LookupEnv(test.key)
|
||||||
|
if got != test.initialValue {
|
||||||
|
t.Fatalf("unexpected value after t.Setenv cleanup: got %s, want %s", got, test.initialValue)
|
||||||
|
}
|
||||||
|
if exists != test.initialValueExists {
|
||||||
|
t.Fatalf("unexpected value after t.Setenv cleanup: got %t, want %t", exists, test.initialValueExists)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTesting(t *testing.T) {
|
||||||
|
if !testing.Testing() {
|
||||||
|
t.Error("Expected testing.Testing() to return true while in a test")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["riscv32"],
|
"inherits": ["riscv32"],
|
||||||
"features": "+32bit,+c,+m,+zmmul,-a,-b,-d,-e,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-f,-h,-relax,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zacas,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
"features": "+32bit,+c,+m,+zmmul,-a,-b,-d,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-f,-h,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||||
"build-tags": ["esp32c3", "esp"],
|
"build-tags": ["esp32c3", "esp"],
|
||||||
"serial": "usb",
|
"serial": "usb",
|
||||||
"rtlib": "compiler-rt",
|
"rtlib": "compiler-rt",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["riscv32"],
|
"inherits": ["riscv32"],
|
||||||
"cpu": "sifive-e31",
|
"cpu": "sifive-e31",
|
||||||
"features": "+32bit,+a,+c,+m,+zaamo,+zalrsc,+zmmul,-b,-d,-e,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-f,-h,-relax,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zabha,-zacas,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
"features": "+32bit,+a,+c,+m,+zmmul,-b,-d,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-f,-h,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||||
"build-tags": ["fe310", "sifive"]
|
"build-tags": ["fe310", "sifive"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {}"
|
|
||||||
}
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["riscv64"],
|
"inherits": ["riscv64"],
|
||||||
"features": "+64bit,+a,+c,+d,+f,+m,+zaamo,+zalrsc,+zicsr,+zifencei,+zmmul,-b,-e,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-h,-relax,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zabha,-zacas,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
"features": "+64bit,+a,+c,+d,+f,+m,+zicsr,+zifencei,+zmmul,-b,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-h,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||||
"build-tags": ["k210", "kendryte"],
|
"build-tags": ["k210", "kendryte"],
|
||||||
"code-model": "medium"
|
"code-model": "medium"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
"inherits": [
|
"inherits": [
|
||||||
"riscv32"
|
"riscv32"
|
||||||
],
|
],
|
||||||
"features": "+32bit,+a,+c,+m,+zaamo,+zalrsc,+zihintpause,+zmmul,-b,-d,-e,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-f,-h,-relax,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zabha,-zacas,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
"features": "+32bit,+a,+c,+m,+zihintpause,+zmmul,-b,-d,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-f,-h,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||||
"build-tags": [
|
"build-tags": [
|
||||||
"virt",
|
"virt",
|
||||||
"qemu"
|
"qemu"
|
||||||
],
|
],
|
||||||
"scheduler": "cores",
|
"scheduler": "cores",
|
||||||
"default-stack-size": 16384,
|
"default-stack-size": 8192,
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-march=rv32imaczihintpause",
|
"-march=rv32imaczihintpause",
|
||||||
"-DTINYGO_CORES=4"
|
"-DTINYGO_CORES=4"
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
"-march=rv32imac"
|
"-march=rv32imac"
|
||||||
],
|
],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-melf32lriscv",
|
"-melf32lriscv"
|
||||||
"-mllvm", "-enable-machine-outliner=never"
|
|
||||||
],
|
],
|
||||||
"gdb": [
|
"gdb": [
|
||||||
"gdb-multiarch",
|
"gdb-multiarch",
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["riscv32"],
|
"inherits": ["riscv32"],
|
||||||
"build-tags": ["tkey"],
|
"build-tags": ["tkey"],
|
||||||
"features": "+32bit,+c,+zmmul,-a,-b,-d,-e,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-f,-h,-m,-relax,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zacas,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
"features": "+32bit,+c,+zmmul,-a,-b,-d,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-f,-h,-m,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-march=rv32iczmmul"
|
"-march=rv32iczmmul"
|
||||||
],
|
],
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"llvm-target": "wasm32-unknown-wasi",
|
"llvm-target": "wasm32-unknown-wasi",
|
||||||
"cpu": "generic",
|
"cpu": "generic",
|
||||||
"features": "+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types",
|
"features": "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types",
|
||||||
"build-tags": ["tinygo.wasm"],
|
"build-tags": ["tinygo.wasm"],
|
||||||
"goos": "wasip1",
|
"goos": "wasip1",
|
||||||
"goarch": "wasm",
|
"goarch": "wasm",
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"llvm-target": "wasm32-unknown-wasi",
|
"llvm-target": "wasm32-unknown-wasi",
|
||||||
"cpu": "generic",
|
"cpu": "generic",
|
||||||
"features": "+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types",
|
"features": "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types",
|
||||||
"build-tags": ["tinygo.wasm", "wasip2"],
|
"build-tags": ["tinygo.wasm", "wasip2"],
|
||||||
"buildmode": "c-shared",
|
"buildmode": "c-shared",
|
||||||
"goos": "linux",
|
"goos": "linux",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"llvm-target": "wasm32-unknown-unknown",
|
"llvm-target": "wasm32-unknown-unknown",
|
||||||
"cpu": "mvp",
|
"cpu": "generic",
|
||||||
"features": "+nontrapping-fptoint,+sign-ext,-bulk-memory,-multivalue,-reference-types",
|
"features": "+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types",
|
||||||
"build-tags": ["tinygo.wasm", "wasm_unknown"],
|
"build-tags": ["tinygo.wasm", "wasm_unknown"],
|
||||||
"buildmode": "c-shared",
|
"buildmode": "c-shared",
|
||||||
"goos": "linux",
|
"goos": "linux",
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
"default-stack-size": 4096,
|
"default-stack-size": 4096,
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-mnontrapping-fptoint",
|
"-mnontrapping-fptoint",
|
||||||
"-mno-bulk-memory",
|
|
||||||
"-mno-multivalue",
|
"-mno-multivalue",
|
||||||
"-mno-reference-types",
|
"-mno-reference-types",
|
||||||
"-msign-ext"
|
"-msign-ext"
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"llvm-target": "wasm32-unknown-wasi",
|
"llvm-target": "wasm32-unknown-wasi",
|
||||||
"cpu": "generic",
|
"cpu": "generic",
|
||||||
"features": "+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types",
|
"features": "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types",
|
||||||
"build-tags": ["tinygo.wasm"],
|
"build-tags": ["tinygo.wasm"],
|
||||||
"goos": "js",
|
"goos": "js",
|
||||||
"goarch": "wasm",
|
"goarch": "wasm",
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ package os_smoke_test
|
|||||||
// Intended to catch build tag mistakes affecting bare metal targets.
|
// Intended to catch build tag mistakes affecting bare metal targets.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -27,10 +25,3 @@ func TestFmt(t *testing.T) {
|
|||||||
t.Errorf("printf returned %d, expected 14", n)
|
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.Flag("disable-default-apps", true),
|
||||||
chromedp.NoFirstRun,
|
chromedp.NoFirstRun,
|
||||||
chromedp.Headless,
|
chromedp.Headless,
|
||||||
chromedp.WSURLReadTimeout(45*time.Second),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
|
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
|
||||||
@@ -82,7 +81,6 @@ func startServer(t *testing.T) (string, *httptest.Server) {
|
|||||||
<head>
|
<head>
|
||||||
<title>Test</title>
|
<title>Test</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<link rel="icon" href="data:,">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="main"></div>
|
<div id="main"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user