Compare commits

..

9 Commits

Author SHA1 Message Date
Ayke van Laethem ea2f0e444d WIP stashed changes 2025-04-01 09:16:35 +02:00
Ayke van Laethem 04242fd620 WIP cores scheduler 2025-01-22 20:12:41 +01:00
Ayke van Laethem cce44b5ebb runtime: implement NumCPU for -scheduler=threads
For the threads scheduler, it makes sense to have NumCPU available.
For all other schedulers, the number of available CPUs is practically
limited to one by the scheduler (even though the system might have more
CPUs).
2025-01-21 11:11:42 +01:00
Ayke van Laethem 3767decf9e runtime: map every goroutine to a new OS thread
This is not a scheduler in the runtime, instead every goroutine is
mapped to a single OS thread - meaning 1:1 scheduling.

While this may not perform well (or at all) for large numbers of
threads, it greatly simplifies many things in the runtime. For example,
blocking syscalls can be called directly instead of having to use epoll
or similar. Also, we don't need to do anything special to call C code -
the default stack is all we need.
2025-01-21 10:48:01 +01:00
Ayke van Laethem 8d6e16019a sync: implement RWMutex using futexes
Somewhat surprisingly, this results in smaller code than the old code
with the cooperative (tasks) scheduler. Probably because the new RWMutex
is also simpler.
2025-01-21 10:48:01 +01:00
Ayke van Laethem 3cc9c44c26 runtime: refactor timerQueue
Move common functions to scheduler.go. They will be used both from the
cooperative and from the threads scheduler.
2025-01-21 10:47:56 +01:00
Ayke van Laethem c9bb33a73c runtime: make conservative and precise GC MT-safe
Using a global lock may be slow, but it is certainly simple and safe.
If this global lock becomes a bottleneck, we can of course look into
making the GC truly support multithreading.
2025-01-21 10:19:08 +01:00
Ayke van Laethem 8659b18d6f runtime: refactor GC mark phase into gcMarkReachable
This is a small refactor to prepare GC marking for multithreaded
stop-the-world.
2025-01-21 10:19:08 +01:00
Ayke van Laethem 2599db2990 internal/task: implement atomic primitives for preemptive scheduling 2025-01-21 10:19:08 +01:00
456 changed files with 8872 additions and 15317 deletions
+20 -12
View File
@@ -73,6 +73,14 @@ commands:
- go-cache-v4-{{ checksum "go.mod" }} - go-cache-v4-{{ checksum "go.mod" }}
- llvm-source-linux - llvm-source-linux
- run: go install -tags=llvm<<parameters.llvm>> . - run: go install -tags=llvm<<parameters.llvm>> .
- restore_cache:
keys:
- wasi-libc-sysroot-systemclang-v7
- run: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-systemclang-v7
paths:
- lib/wasi-libc/sysroot
- when: - when:
condition: <<parameters.fmt-check>> condition: <<parameters.fmt-check>>
steps: steps:
@@ -92,28 +100,28 @@ commands:
- /go/pkg/mod - /go/pkg/mod
jobs: jobs:
test-oldest: test-llvm15-go119:
# This tests our lowest supported versions of Go and LLVM, to make sure at
# least the smoke tests still pass.
docker: docker:
- image: golang:1.22-bullseye - image: golang:1.19-bullseye
steps: steps:
- test-linux: - test-linux:
llvm: "15" llvm: "15"
# "make lint" fails before go 1.21 because internal/tools/go.mod specifies packages that require go 1.21
fmt-check: false
resource_class: large resource_class: large
test-newest: test-llvm19-go123:
# This tests the latest supported LLVM version when linking against system
# libraries.
docker: docker:
- image: golang:1.25-bullseye - image: golang:1.23-bullseye
steps: steps:
- test-linux: - test-linux:
llvm: "20" llvm: "19"
resource_class: large resource_class: large
workflows: workflows:
test-all: test-all:
jobs: jobs:
- test-oldest # This tests our lowest supported versions of Go and LLVM, to make sure at
# disable this test, since CircleCI seems unable to download due to rate-limits on Dockerhub. # least the smoke tests still pass.
# - test-newest - test-llvm15-go119
# This tests LLVM 19 support when linking against system libraries.
- test-llvm19-go123
+22 -13
View File
@@ -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.23'
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 '{}' \;
@@ -89,10 +89,19 @@ jobs:
with: with:
key: ${{ steps.cache-llvm-build.outputs.cache-primary-key }} key: ${{ steps.cache-llvm-build.outputs.cache-primary-key }}
path: llvm-build path: llvm-build
- name: Cache wasi-libc sysroot
uses: actions/cache@v4
id: cache-wasi-libc
with:
key: wasi-libc-sysroot-${{ matrix.os }}-v1
path: lib/wasi-libc/sysroot
- name: Build wasi-libc
if: steps.cache-wasi-libc.outputs.cache-hit != 'true'
run: make wasi-libc
- name: make gen-device - name: make gen-device
run: make -j3 gen-device run: make -j3 gen-device
- name: Test TinyGo - name: Test TinyGo
run: make test GOTESTFLAGS="-only-current-os" run: make test GOTESTFLAGS="-short"
- name: Build TinyGo release tarball - name: Build TinyGo release tarball
run: make release -j3 run: make release -j3
- name: Test stdlib packages - name: Test stdlib packages
@@ -117,7 +126,7 @@ jobs:
runs-on: macos-latest runs-on: macos-latest
strategy: strategy:
matrix: matrix:
version: [16, 17, 18, 19, 20] version: [16, 17, 18, 19]
steps: steps:
- name: Set up Homebrew - name: Set up Homebrew
uses: Homebrew/actions/setup-homebrew@master uses: Homebrew/actions/setup-homebrew@master
@@ -130,19 +139,19 @@ 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.23'
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 }}
- name: Check binary - name: Check binary
run: tinygo version run: tinygo version
- name: Build TinyGo (default LLVM) - name: Build TinyGo (default LLVM)
if: matrix.version == 20 if: matrix.version == 19
run: go install run: go install
- name: Check binary - name: Check binary
if: matrix.version == 20 if: matrix.version == 19
run: tinygo version run: tinygo version
+34 -17
View File
@@ -18,7 +18,7 @@ jobs:
# statically linked binary. # statically linked binary.
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: golang:1.25-alpine image: golang:1.23-alpine
outputs: outputs:
version: ${{ steps.version.outputs.version }} version: ${{ steps.version.outputs.version }}
steps: steps:
@@ -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'
@@ -104,6 +104,15 @@ jobs:
run: | run: |
apk add cmake samurai python3 apk add cmake samurai python3
make binaryen STATIC=1 make binaryen STATIC=1
- name: Cache wasi-libc
uses: actions/cache@v4
id: cache-wasi-libc
with:
key: wasi-libc-sysroot-linux-alpine-v2
path: lib/wasi-libc/sysroot
- name: Build wasi-libc
if: steps.cache-wasi-libc.outputs.cache-hit != 'true'
run: make wasi-libc
- name: Install fpm - name: Install fpm
run: | run: |
gem install --version 4.0.7 public_suffix gem install --version 4.0.7 public_suffix
@@ -137,12 +146,12 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.25.0' go-version: '1.23'
cache: true cache: true
- name: Install wasmtime - name: Install wasmtime
uses: bytecodealliance/actions/wasmtime/setup@v1 uses: bytecodealliance/actions/wasmtime/setup@v1
with: with:
version: "29.0.1" version: "19.0.1"
- name: Install wasm-tools - name: Install wasm-tools
uses: bytecodealliance/actions/wasm-tools/setup@v1 uses: bytecodealliance/actions/wasm-tools/setup@v1
- name: Download release artifact - name: Download release artifact
@@ -156,12 +165,11 @@ jobs:
ln -s ~/lib/tinygo/bin/tinygo ~/go/bin/tinygo ln -s ~/lib/tinygo/bin/tinygo ~/go/bin/tinygo
- run: make tinygo-test-wasip1-fast - run: make tinygo-test-wasip1-fast
- run: make tinygo-test-wasip2-fast - run: make tinygo-test-wasip2-fast
- run: make tinygo-test-wasm
- run: make smoketest - run: make smoketest
assert-test-linux: assert-test-linux:
# Run all tests that can run on Linux, with LLVM assertions enabled to catch # Run all tests that can run on Linux, with LLVM assertions enabled to catch
# potential bugs. # potential bugs.
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -181,7 +189,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.25.0' go-version: '1.23'
cache: true cache: true
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
@@ -190,14 +198,14 @@ jobs:
- name: Install wasmtime - name: Install wasmtime
uses: bytecodealliance/actions/wasmtime/setup@v1 uses: bytecodealliance/actions/wasmtime/setup@v1
with: with:
version: "29.0.1" version: "19.0.1"
- name: Setup `wasm-tools` - name: Setup `wasm-tools`
uses: bytecodealliance/actions/wasm-tools/setup@v1 uses: bytecodealliance/actions/wasm-tools/setup@v1
- name: Restore LLVM source cache - name: Restore LLVM source cache
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 +230,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'
@@ -249,6 +257,15 @@ jobs:
- name: Build Binaryen - name: Build Binaryen
if: steps.cache-binaryen.outputs.cache-hit != 'true' if: steps.cache-binaryen.outputs.cache-hit != 'true'
run: make binaryen run: make binaryen
- name: Cache wasi-libc
uses: actions/cache@v4
id: cache-wasi-libc
with:
key: wasi-libc-sysroot-linux-asserts-v6
path: lib/wasi-libc/sysroot
- name: Build wasi-libc
if: steps.cache-wasi-libc.outputs.cache-hit != 'true'
run: make wasi-libc
- run: make gen-device -j4 - run: make gen-device -j4
- name: Test TinyGo - name: Test TinyGo
run: make ASSERT=1 test run: make ASSERT=1 test
@@ -260,7 +277,7 @@ jobs:
run: make tinygo-test run: make tinygo-test
- run: make smoketest - run: make smoketest
- run: make wasmtest - run: make wasmtest
- run: make tinygo-test-baremetal - run: make tinygo-baremetal
build-linux-cross: build-linux-cross:
# Build ARM Linux binaries, ready for release. # Build ARM Linux binaries, ready for release.
# This intentionally uses an older Linux image, so that we compile against # This intentionally uses an older Linux image, so that we compile against
@@ -280,7 +297,7 @@ jobs:
- goarch: arm - goarch: arm
toolchain: arm-linux-gnueabihf toolchain: arm-linux-gnueabihf
libc: armhf libc: armhf
runs-on: ubuntu-22.04 # note: use the oldest image available! (see above) runs-on: ubuntu-20.04
needs: build-linux needs: build-linux
steps: steps:
- name: Checkout - name: Checkout
@@ -298,13 +315,13 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.25.0' go-version: '1.23'
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-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 +346,7 @@ jobs:
uses: actions/cache/restore@v4 uses: actions/cache/restore@v4
id: cache-llvm-build id: cache-llvm-build
with: with:
key: llvm-build-20-linux-${{ matrix.goarch }}-v1 key: llvm-build-19-linux-${{ matrix.goarch }}-v2
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'
+2 -2
View File
@@ -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
+3 -3
View File
@@ -22,14 +22,14 @@ jobs:
run: sudo apt-get remove llvm-18 run: sudo apt-get remove llvm-18
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Pull musl, bdwgc - name: Pull musl
run: | run: |
git submodule update --init lib/musl lib/bdwgc git submodule update --init lib/musl
- 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-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
+5 -5
View File
@@ -2,11 +2,11 @@
# still works after checking out the dev branch (that is, when going from LLVM # still works after checking out the dev branch (that is, when going from LLVM
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed). # 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' | sudo tee /etc/apt/sources.list.d/llvm.list echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-19 main' | sudo tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update sudo apt-get update
sudo apt-get install --no-install-recommends -y \ sudo apt-get install --no-install-recommends -y \
llvm-20-dev \ llvm-19-dev \
clang-20 \ clang-19 \
libclang-20-dev \ libclang-19-dev \
lld-20 lld-19
+1 -1
View File
@@ -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
+21 -12
View File
@@ -23,7 +23,7 @@ jobs:
minimum-size: 8GB minimum-size: 8GB
maximum-size: 24GB maximum-size: 24GB
disk-root: "C:" disk-root: "C:"
- uses: MinoruSekine/setup-scoop@v4 - uses: brechtm/setup-scoop@v2
with: with:
scoop_update: 'false' scoop_update: 'false'
- name: Install Dependencies - name: Install Dependencies
@@ -41,13 +41,13 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.25.0' go-version: '1.23'
cache: true cache: true
- name: Restore cached LLVM source - name: Restore cached LLVM source
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 +72,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-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'
@@ -91,6 +91,15 @@ jobs:
with: with:
key: ${{ steps.cache-llvm-build.outputs.cache-primary-key }} key: ${{ steps.cache-llvm-build.outputs.cache-primary-key }}
path: llvm-build path: llvm-build
- name: Cache wasi-libc sysroot
uses: actions/cache@v4
id: cache-wasi-libc
with:
key: wasi-libc-sysroot-v5
path: lib/wasi-libc/sysroot
- name: Build wasi-libc
if: steps.cache-wasi-libc.outputs.cache-hit != 'true'
run: make wasi-libc
- name: Cache Go cache - name: Cache Go cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
@@ -100,12 +109,12 @@ jobs:
C:/Users/runneradmin/go/pkg/mod C:/Users/runneradmin/go/pkg/mod
- name: Install wasmtime - name: Install wasmtime
run: | run: |
scoop install wasmtime@29.0.1 scoop install wasmtime@14.0.4
- name: make gen-device - name: make gen-device
run: make -j3 gen-device run: make -j3 gen-device
- name: Test TinyGo - name: Test TinyGo
shell: bash shell: bash
run: make test GOTESTFLAGS="-only-current-os" run: make test GOTESTFLAGS="-short"
- name: Build TinyGo release tarball - name: Build TinyGo release tarball
shell: bash shell: bash
run: make build/release -j4 run: make build/release -j4
@@ -135,7 +144,7 @@ jobs:
minimum-size: 8GB minimum-size: 8GB
maximum-size: 24GB maximum-size: 24GB
disk-root: "C:" disk-root: "C:"
- uses: MinoruSekine/setup-scoop@v4 - uses: brechtm/setup-scoop@v2
with: with:
scoop_update: 'false' scoop_update: 'false'
- name: Install Dependencies - name: Install Dependencies
@@ -147,7 +156,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.25.0' go-version: '1.23'
cache: true cache: true
- name: Download TinyGo build - name: Download TinyGo build
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@@ -177,7 +186,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.25.0' go-version: '1.23'
cache: true cache: true
- name: Download TinyGo build - name: Download TinyGo build
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@@ -201,19 +210,19 @@ jobs:
minimum-size: 8GB minimum-size: 8GB
maximum-size: 24GB maximum-size: 24GB
disk-root: "C:" disk-root: "C:"
- uses: MinoruSekine/setup-scoop@v4 - uses: brechtm/setup-scoop@v2
with: with:
scoop_update: 'false' scoop_update: 'false'
- name: Install Dependencies - name: Install Dependencies
shell: bash shell: bash
run: | run: |
scoop install binaryen && scoop install wasmtime@29.0.1 scoop install binaryen && scoop install wasmtime@14.0.4
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.25.0' go-version: '1.23'
cache: true cache: true
- name: Download TinyGo build - name: Download TinyGo build
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
+2 -4
View File
@@ -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
@@ -35,9 +35,7 @@
[submodule "src/net"] [submodule "src/net"]
path = src/net path = src/net
url = https://github.com/tinygo-org/net.git url = https://github.com/tinygo-org/net.git
branch = dev
[submodule "lib/wasi-cli"] [submodule "lib/wasi-cli"]
path = lib/wasi-cli path = lib/wasi-cli
url = https://github.com/WebAssembly/wasi-cli url = https://github.com/WebAssembly/wasi-cli
[submodule "lib/bdwgc"]
path = lib/bdwgc
url = https://github.com/ivmai/bdwgc.git
+2 -8
View File
@@ -85,17 +85,11 @@ Try running TinyGo:
./build/tinygo help ./build/tinygo help
Also, make sure the `tinygo` binary really is statically linked. The command to check for Also, make sure the `tinygo` binary really is statically linked. Check this
dynamic dependencies differs depending on your operating system. using `ldd` (not to be confused with `lld`):
On Linux, use `ldd` (not to be confused with `lld`):
ldd ./build/tinygo ldd ./build/tinygo
On macOS, use otool -L:
otool -L ./build/tinygo
The result should not contain libclang or libLLVM. The result should not contain libclang or libLLVM.
## Make a release tarball ## Make a release tarball
-269
View File
@@ -1,272 +1,3 @@
0.39.0
---
* **general**
- all: add Go 1.25 support
- net: update to latest tinygo net package
- docs: clarify build verification step for macOS users
- Add flag to skip Renesas SVD builds
* **build**
- Makefile: install missing dlmalloc files
- flash: add -o flag support to save built binary (Fixes #4937) (#4942)
- fix: update version of clang to 17 to accommodate latest Go 1.25 docker base image
* **ci**
- chore: update all CI builds to test Go 1.25 release
- fix: disable test-newest since CircleCI seems unable to download due to rate-limits on Dockerhub
- ci: rename some jobs to avoid churn on every Go/LLVM version bump
- ci: make the goroutines test less racy
- tests: de-flake goroutines test
* **compiler**
- compiler: implement internal/abi.Escape
* **main**
- main: show the compiler error (if any) for `tinygo test -c`
- chore: correct GOOS=js name in error messages for WASM
* **machine**
- machine: add international keys
- machine: remove some unnecessary "// peripherals:" comments
- machine: add I2C pin comments
- machine: standardize I2C errors with "i2c:" prefix
- machine: make I2C usable in the simulator
- fix: add SPI and I2C to teensy 4.1 (#4943)
- `rp2`: use the correct channel mask for rp2350 ADC; hold lock during read (#4938)
- `rp2`: disable digital input for analog inputs
* **runtime**
- runtime: ensure time.Sleep(d) sleeps at least d
- runtime: stub out weak pointer support
- runtime: implement dummy AddCleanup
- runtime: enable multi-core scheduler for rp2350
- `internal/task`: use -stack-size flag when starting a new thread
- `internal/task`: add SA_RESTART flag to GC interrupts
- `internal/task`: a few small correctness fixes
- `internal/gclayout`: make gclayout values constants
- darwin: add threading support and use it by default
* **standard library**
- `sync`: implement sync.Swap
- `reflect`: implement Method.IsExported
* **testing**
- testing: stub out testing.B.Loop
* **targets**
- `stm32`: add support for the STM32L031G6U6
- add metro-rp2350 board definition (#4989)
- `rp2040/rp2350`: set the default stack size to 8k for rp2040/rp2350 based boards where this was not already the case
0.38.0
---
* **general**
- `go.*`: upgrade `golang.org/x/tools` to v0.30.0
- `all`: add support for LLVM 20
* **build**
- go back to using MinoruSekine/setup-scoop for Windows CI builds
- `flake.*`: upgrade to nixpkgs 25.05, LLVM 20
- `Makefile`: only detect ccache command when needed
- `Makefile`: create random filename inside rule
- `Makefile`: don't set GOROOT
- `Makefile`: call uname at most once
- `Makefile`: only read NodeJS version when it is needed
* **compiler**
- add support for `GODEBUG=gotypesalias=1`
- `interp`: fix `copy()` from/to external buffers
- add `-nobounds` (similar to `-gcflags=-B`)
- `compileopts`: add library version to cached library path
- `builder`: build wasi-libc inside TinyGo
- `builder`: simplify bdwgc libc dependency
- `builder`: don't use precompiled libraries
- `compileopts`: enable support for `GOARCH=wasm` in `tinygo test`
* **fixes**
- `rp2350`: Fix DMA to SPI transmits on RP2350 (#4903)
- `microbit v2`: use OpenOCD flash method on microbit v2 when using Nordic Semi SoftDevice
- `main`: display all of the current GC options for the `-gc` flag
- Remove duplicated error handling
- `sync`: fix `TestMutexConcurrent` test
- fix race condition in `testdata/goroutines.go`
- fix build warnings on Windows ARM
* **machine**
- `usb`: add USB mass storage class support
- implement usb receive message throttling
- declare usb endpoints per-platform
- `samd21`: implement watchdog
- `samd51`: write to flash memory in 512 byte long chunks
- `samd21`: write to flash memory in 64 byte long chunks
- don't inline RTT `WriteByte` everywhere
- `rp2`: unexport machine-specific errors
- `rp2`: discount scheduling delays in I2C timeouts (#4876)
- use pointer receiver in simulated PWM peripherals
- add simulated PWM/timer peripherals
- `rp2`: expose usb endpoint stall handling
- `arm`: clear pending interrupts before enabling them
- `rp2`: merge common usb code (#4856)
* **main**
- add "cores" and "threads" schedulers to help text
- add `StartPos` and `EndPos` to `-json` build output
- change `-json` flag to match upstream Go
* **runtime**
- don't lock the print output inside interrupts
- don't try to interrupt other cores before they are started
- implement `NumCPU` for the multicore scheduler
- add support for multicore scheduler
- refactor obtaining the system stack
- `interrupt`: add `Checkpoint` type
- add `exportedFuncPtr`
- avoid an allocation in `(*time.Timer).Reset`
- stub runtime signal functions for `os/signal` on wasip1
- move `timeUnit` to a single place
- implement `NumCPU` for `-scheduler=threads`
- move `mainExited` boolean
- `internal/task`: rename `tinygo_pause` to `tinygo_task_exit`
- map every goroutine to a new OS thread
- refactor `timerQueue`
- make conservative and precise GC MT-safe
- `internal/task`: implement atomic primitives for preemptive scheduling
- Use diskutil on macOS to extract volume name and path for FAT mounts #4928
* **standard library**
- `net`: update submodule to latest commits
- `runtime/debug`: add GC related stubs
- `metrics`: flesh out some of the metric types
- `reflect`: Chan related stubs
- `os`: handle relative and abs paths in `Executable()`
- `os`: add `os.Executable()` for Darwin
- `sync`: implement `RWMutex` using futexes
- `reflect`: Add `SliceOf`, `ArrayOf`, `StructOf`, `MapOf`, `FuncOf`
* **targets**
- `rp2040`: add multicore support
- `riscv32`: use `gdb` binary as a fallback
- add target for Microbit v2 with SoftDevice S140 support for both peripheral and central
- `windows`: use MSVCRT.DLL instead of UCRT on i386
- `windows`: add windows/386 support
- `arm64`: remove unnecessary `.section` directive
- `riscv-qemu`: actually sleep in `time.Sleep()`
- `riscv`: define CSR constants and use them where possible
- `darwin`: support Boehm GC (and use by default)
- `windows`: add support for the Boehm-Demers-Weiser GC
- `windows`: fix wrong register for first parameter
* **wasm**
- add Boehm GC support
- refactor/modify stub signal handling
- don't block `//go:wasmexport` because of running goroutines
- use `int64` instead of `float64` for the `timeUnit`
* **boards**
- Add board support for BigTreeTech SKR Pico (#4842)
0.37.0
---
* **general**
- add the Boehm-Demers-Weiser GC on Linux
* **ci**
- add more tests for wasm and baremetal
* **compiler**
- crypto/internal/sysrand is allowed to use unsafe signatures
* **examples**
- add goroutine benchmark to examples
* **fixes**
- ensure use of pointers for SPI interface on atsam21/atsam51 and other machines/boards that were missing implementation (#4798)
- replace loop counter with hw timer for USB SetAddressReq on rp2040 (#4796)
* **internal**
- update to go.bytecodealliance.org@v0.6.2 in GNUmakefile and internal/wasm-tools
- exclude certain files when copying package in internal/cm
- update to go.bytecodealliance.org/cm@v0.2.2 in internal/cm
- remove old reflect.go in internal/reflectlite
* **loader**
- use build tags for package iter and iter methods on reflect.Value in loader, iter, reflect
- add shim for go1.22 and earlier in loader, iter
* **machine**
- bump rp2040 to 200MHz (#4768)
- correct register address for Pin.SetInterrupt for rp2350 (#4782)
- don't block the rp2xxx UART interrupt handler
- fix RP2040 Pico board on the playground
- add flash support for rp2350 (#4803)
* **os**
- add stub Symlink for wasm
* **refactor**
- use *SPI everywhere to make consistent for implementations. Fixes #4663 "in reverse" by making SPI a pointer everywhere, as discussed in the comments.
* **reflect**
- add Value.SetIter{Key,Value} and MapIter.Reset in reflect, internal/reflectlite
- embed reflectlite types into reflect types in reflect, internal/reflectlite
- add Go 1.24 iter.Seq[2] methods
- copy reflect iter tests from upstream Go
- panic on Type.CanSeq[2] instead of returning false
- remove strconv.go
- remove unused go:linkname functions
* **riscv-qemu**
- add VirtIO RNG device
- increase stack size
* **runtime**
- only allocate heap memory when needed
- remove unused file func.go
- use package reflectlite
* **transform**
- cherry-pick from #4774
0.36.0
---
* **general**
- add initial Go 1.24 support
- add support for LLVM 19
- update license for 2025
- make small corrections for README regarding wasm
- use GOOS and GOARCH for building wasm simulated boards
- only infer target for wasm when GOOS and GOARCH are set correctly, not just based on file extension
- add test-corpus-wasip2
- use older image for cross-compiling builds
- update Linux builds to run on ubuntu-latest since 20.04 is being retired
- ensure build output directory is created
- add NoSandbox flag to chrome headless that is run during WASM tests, since this is now required for Ubuntu 23+ and we are using Ubuntu 24+ when running Github Actions
- update wasmtime used for CI to 29.0.1 to fix issue with install during CI tests
- update to use `Get-CimInstance` as `wmic` is being deprecated on WIndows
- remove unnecessary executable permissions
- `goenv`: update to new v0.36.0 development version
* **compiler**
- `builder`: fix parsing of external ld.lld error messages
- `cgo`: mangle identifier names
- `interp`: correctly mark functions as modifying memory
- add buildmode=wasi-legacy to support existing base of users who expected the older behavior for wasi modules to not return an exit code as if they were reactors
* **standard library**
- `crypto/tls`: add Dialer.DialContext() to fix websocket client
- `crypto/tls`: add VersionTLS constants and VersionName(version uint16) method that turns it into a string, copied from big go
- `internal/syscall/unix`: use our own version of this package
- `machine`: replace hard-coded cpu frequencies on rp2xxx
- `machine`: bump rp2350 CPUFrequency to 150 MHz
- `machine`: compute rp2 clock dividers from crystal and target frequency
- `machine`: remove bytes package dependency in flash code
- `machine/usb/descriptor`: avoid bytes package
- `net`: update to latest submodule with httptest subpackage and ResolveIPAddress implementation
- `os`: add File.Chdir support
- `os`: implement stub Chdir for non-OS systems
- `os/file`: add file.Chmod
- `reflect`: implement Value.Equal
- `runtime`: add FIPS helper functions
- `runtime`: manually initialize xorshift state
- `sync`: move Mutex to internal/task
- `syscall`: add wasip1 RandomGet
- `testing`: add Chdir
- `wasip2`: add stubs to get internal/syscall/unix to work
* **fixes**
- correctly handle calls for GetRNG() when being made from nrf devices with SoftDevice enabled
- fix stm32f103 ADC
- `wasm`: correctly handle id lookup for finalizeRef call
- `wasm`: avoid total failure on wasm finalizer call
- `wasm`: convert offset as signed int into unsigned int in syscall/js.stringVal in wasm_exec.js
* **targets**
- rp2350: add pll generalized solution; fix ADC handles; pwm period fix
- rp2350: extending support to include the rp2350b
- rp2350: cleanup: unexport internal USB and clock package variable, consts and types
- nrf: make ADC resolution changeable
- turn on GC for TKey1 device, since it does in fact work
- match Pico2 stack size to Pico
* **boards**
- add support for Pimoroni Pico Plus2
- add target for pico2-w board
- add comboat_fw tag for elecrow W5 boards with Combo-AT Wifi firmware
- add support for Elecrow Pico rp2350 W5 boards
- add support for Elecrow Pico rp2040 W5 boards
- add support for NRF51 HW-651
- add support for esp32c3-supermini
- add support for waveshare-rp2040-tiny
* **examples**
- add naive debouncing for pininterrupt example
0.35.0 0.35.0
--- ---
* **general** * **general**
+3 -3
View File
@@ -1,8 +1,8 @@
# tinygo-llvm stage obtains the llvm source for TinyGo # tinygo-llvm stage obtains the llvm source for TinyGo
FROM golang:1.25 AS tinygo-llvm FROM golang:1.23 AS tinygo-llvm
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y apt-utils make cmake clang-17 ninja-build && \ apt-get install -y apt-utils make cmake clang-15 ninja-build && \
rm -rf \ rm -rf \
/var/lib/apt/lists/* \ /var/lib/apt/lists/* \
/var/log/* \ /var/log/* \
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
# tinygo-compiler copies the compiler build over to a base Go container (without # tinygo-compiler copies the compiler build over to a base Go container (without
# all the build tools etc). # all the build tools etc).
FROM golang:1.25 AS tinygo-compiler FROM golang:1.23 AS tinygo-compiler
# Copy tinygo build. # Copy tinygo build.
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
+72 -188
View File
@@ -8,20 +8,13 @@ LLVM_PROJECTDIR ?= llvm-project
CLANG_SRC ?= $(LLVM_PROJECTDIR)/clang CLANG_SRC ?= $(LLVM_PROJECTDIR)/clang
LLD_SRC ?= $(LLVM_PROJECTDIR)/lld LLD_SRC ?= $(LLVM_PROJECTDIR)/lld
ifeq ($(OS),Windows_NT)
# avoid calling uname on Windows
uname := Windows_NT
else
uname := $(shell uname -s)
endif
# Try to autodetect LLVM build tools. # Try to autodetect LLVM build tools.
# Versions are listed here in descending priority order. # Versions are listed here in descending priority order.
LLVM_VERSIONS = 19 18 17 16 15 LLVM_VERSIONS = 19 18 17 16 15
errifempty = $(if $(1),$(1),$(error $(2))) errifempty = $(if $(1),$(1),$(error $(2)))
detect = $(shell which $(call errifempty,$(firstword $(foreach p,$(2),$(shell command -v $(p) 2> /dev/null && echo $(p)))),failed to locate $(1) at any of: $(2))) detect = $(shell which $(call errifempty,$(firstword $(foreach p,$(2),$(shell command -v $(p) 2> /dev/null && echo $(p)))),failed to locate $(1) at any of: $(2)))
toolSearchPathsVersion = $(1)-$(2) toolSearchPathsVersion = $(1)-$(2)
ifeq ($(uname),Darwin) ifeq ($(shell uname -s),Darwin)
# Also explicitly search Brew's copy, which is not in PATH by default. # Also explicitly search Brew's copy, which is not in PATH by default.
BREW_PREFIX := $(shell brew --prefix) BREW_PREFIX := $(shell brew --prefix)
toolSearchPathsVersion += $(BREW_PREFIX)/opt/llvm@$(2)/bin/$(1)-$(2) $(BREW_PREFIX)/opt/llvm@$(2)/bin/$(1) toolSearchPathsVersion += $(BREW_PREFIX)/opt/llvm@$(2)/bin/$(1)-$(2) $(BREW_PREFIX)/opt/llvm@$(2)/bin/$(1)
@@ -34,6 +27,7 @@ LLVM_NM ?= $(call findLLVMTool,llvm-nm)
# Go binary and GOROOT to select # Go binary and GOROOT to select
GO ?= go GO ?= go
export GOROOT = $(shell $(GO) env GOROOT)
# Flags to pass to go test. # Flags to pass to go test.
GOTESTFLAGS ?= GOTESTFLAGS ?=
@@ -44,10 +38,14 @@ TINYGO ?= $(call detect,tinygo,tinygo $(CURDIR)/build/tinygo)
# Check for ccache if the user hasn't set it to on or off. # Check for ccache if the user hasn't set it to on or off.
ifeq (, $(CCACHE)) ifeq (, $(CCACHE))
LLVM_OPTION += '-DLLVM_CCACHE_BUILD=$(if $(shell command -v ccache 2> /dev/null),ON,OFF)' # Use CCACHE for LLVM if possible
else ifneq (, $(shell command -v ccache 2> /dev/null))
LLVM_OPTION += '-DLLVM_CCACHE_BUILD=$(CCACHE)' CCACHE := ON
else
CCACHE := OFF
endif
endif endif
LLVM_OPTION += '-DLLVM_CCACHE_BUILD=$(CCACHE)'
# Allow enabling LLVM assertions # Allow enabling LLVM assertions
ifeq (1, $(ASSERT)) ifeq (1, $(ASSERT))
@@ -79,26 +77,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
@@ -149,14 +127,14 @@ ifeq ($(OS),Windows_NT)
USE_SYSTEM_BINARYEN ?= 1 USE_SYSTEM_BINARYEN ?= 1
else ifeq ($(uname),Darwin) else ifeq ($(shell uname -s),Darwin)
MD5SUM ?= md5 MD5SUM ?= md5
CGO_LDFLAGS += -lxar CGO_LDFLAGS += -lxar
USE_SYSTEM_BINARYEN ?= 1 USE_SYSTEM_BINARYEN ?= 1
else ifeq ($(uname),FreeBSD) else ifeq ($(shell uname -s),FreeBSD)
MD5SUM ?= md5 MD5SUM ?= md5
START_GROUP = -Wl,--start-group START_GROUP = -Wl,--start-group
END_GROUP = -Wl,--end-group END_GROUP = -Wl,--end-group
@@ -207,10 +185,7 @@ fmt-check: ## Warn if any source needs reformatting
@unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1 @unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1
gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp ## Generate microcontroller-specific sources gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp gen-device-renesas ## Generate microcontroller-specific sources
ifneq ($(RENESAS), 0)
gen-device: gen-device-renesas
endif
ifneq ($(STM32), 0) ifneq ($(STM32), 0)
gen-device: gen-device-stm32 gen-device: gen-device-stm32
endif endif
@@ -263,7 +238,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.
@@ -284,34 +259,40 @@ build/wasm-opt$(EXE):
cp lib/binaryen/bin/wasm-opt$(EXE) build/wasm-opt$(EXE) cp lib/binaryen/bin/wasm-opt$(EXE) build/wasm-opt$(EXE)
endif endif
# Build wasi-libc sysroot
.PHONY: wasi-libc
wasi-libc: lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a
lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a:
@if [ ! -e lib/wasi-libc/Makefile ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init"; exit 1; fi
cd lib/wasi-libc && $(MAKE) -j4 EXTRA_CFLAGS="-O2 -g -DNDEBUG -mnontrapping-fptoint -msign-ext" MALLOC_IMPL=none CC="$(CLANG)" AR=$(LLVM_AR) NM=$(LLVM_NM)
# Generate WASI syscall bindings # Generate WASI syscall bindings
WASM_TOOLS_MODULE=go.bytecodealliance.org WASM_TOOLS_MODULE=github.com/bytecodealliance/wasm-tools-go
.PHONY: wasi-syscall .PHONY: wasi-syscall
wasi-syscall: wasi-cm wasi-syscall: wasi-cm
rm -rf ./src/internal/wasi/*
go run -modfile ./internal/wasm-tools/go.mod $(WASM_TOOLS_MODULE)/cmd/wit-bindgen-go generate --versioned -o ./src/internal -p internal --cm internal/cm ./lib/wasi-cli/wit go run -modfile ./internal/wasm-tools/go.mod $(WASM_TOOLS_MODULE)/cmd/wit-bindgen-go generate --versioned -o ./src/internal -p internal --cm internal/cm ./lib/wasi-cli/wit
# Copy package cm into src/internal/cm # Copy package cm into src/internal/cm
.PHONY: wasi-cm .PHONY: wasi-cm
wasi-cm: wasi-cm:
rm -rf ./src/internal/cm/* # rm -rf ./src/internal/cm
rsync -rv --delete --exclude go.mod --exclude '*_test.go' --exclude '*_json.go' --exclude '*.md' --exclude LICENSE $(shell go list -modfile ./internal/wasm-tools/go.mod -m -f {{.Dir}} $(WASM_TOOLS_MODULE)/cm)/ ./src/internal/cm rsync -rv --delete --exclude '*_test.go' $(shell go list -modfile ./internal/wasm-tools/go.mod -m -f {{.Dir}} $(WASM_TOOLS_MODULE))/cm ./src/internal/
# Check for Node.js used during WASM tests. # Check for Node.js used during WASM tests.
NODEJS_VERSION := $(word 1,$(subst ., ,$(shell node -v | cut -c 2-)))
MIN_NODEJS_VERSION=18 MIN_NODEJS_VERSION=18
.PHONY: check-nodejs-version .PHONY: check-nodejs-version
check-nodejs-version: check-nodejs-version:
@# Check whether NodeJS is available. ifeq (, $(shell which node))
@if ! command -v node 2>&1 >/dev/null; then echo "Install NodeJS version ${MIN_NODEJS_VERSION}+ to run tests."; exit 1; fi @echo "Install NodeJS version 18+ to run tests."; exit 1;
endif
@# Check whether the version is high enough. @if [ $(NODEJS_VERSION) -lt $(MIN_NODEJS_VERSION) ]; then echo "Install NodeJS version 18+ to run tests."; exit 1; fi
@if [ "`node -v | sed 's/v\([0-9]\+\).*/\\1/g'`" -lt $(MIN_NODEJS_VERSION) ]; then echo "Install NodeJS version $(MIN_NODEJS_VERSION)+ to run tests."; exit 1; fi
tinygo: ## Build the TinyGo compiler tinygo: ## Build the TinyGo compiler
@if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " $(MAKE) llvm-source"; echo " $(MAKE) $(LLVM_BUILDDIR)"; exit 1; fi @if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " $(MAKE) llvm-source"; echo " $(MAKE) $(LLVM_BUILDDIR)"; exit 1; fi
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOENVFLAGS) $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags "byollvm osusergo" . CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOENVFLAGS) $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags "byollvm osusergo" .
test: check-nodejs-version test: wasi-libc check-nodejs-version
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags "byollvm osusergo" $(GOTESTPKGS) CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags "byollvm osusergo" $(GOTESTPKGS)
# Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi # Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi
@@ -328,9 +309,11 @@ TEST_PACKAGES_FAST = \
container/heap \ container/heap \
container/list \ container/list \
container/ring \ container/ring \
crypto/des \
crypto/ecdsa \ crypto/ecdsa \
crypto/elliptic \ crypto/elliptic \
crypto/md5 \ crypto/md5 \
crypto/rc4 \
crypto/sha1 \ crypto/sha1 \
crypto/sha256 \ crypto/sha256 \
crypto/sha512 \ crypto/sha512 \
@@ -372,11 +355,17 @@ TEST_PACKAGES_FAST = \
unique \ unique \
$(nil) $(nil)
# Assume this will go away before Go2, so only check minor version.
ifeq ($(filter $(shell $(GO) env GOVERSION | cut -f 2 -d.), 16 17 18), )
TEST_PACKAGES_FAST += crypto/internal/nistec/fiat
else
TEST_PACKAGES_FAST += crypto/elliptic/internal/fiat
endif
# archive/zip requires os.ReadAt, which is not yet supported on windows # archive/zip requires os.ReadAt, which is not yet supported on windows
# bytes requires mmap # bytes requires mmap
# compress/flate appears to hang on wasi # compress/flate appears to hang on wasi
# crypto/aes fails on wasi, needs panic()/recover() # crypto/aes fails on wasi, needs panic()/recover()
# crypto/des fails on wasi, needs panic()/recover()
# crypto/hmac fails on wasi, it exits with a "slice out of range" panic # crypto/hmac fails on wasi, it exits with a "slice out of range" panic
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows # debug/plan9obj requires os.ReadAt, which is not yet supported on windows
# image requires recover(), which is not yet supported on wasi # image requires recover(), which is not yet supported on wasi
@@ -397,7 +386,6 @@ TEST_PACKAGES_LINUX := \
archive/zip \ archive/zip \
compress/flate \ compress/flate \
crypto/aes \ crypto/aes \
crypto/des \
crypto/hmac \ crypto/hmac \
debug/dwarf \ debug/dwarf \
debug/plan9obj \ debug/plan9obj \
@@ -417,48 +405,17 @@ TEST_PACKAGES_LINUX := \
TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX) TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
# os/user requires t.Skip() support
TEST_PACKAGES_WINDOWS := \ TEST_PACKAGES_WINDOWS := \
compress/flate \ compress/flate \
crypto/des \
crypto/hmac \ crypto/hmac \
os/user \
strconv \ strconv \
text/template/parse \ text/template/parse \
$(nil) $(nil)
# These packages cannot be tested on wasm, mostly because these tests assume a
# working filesystem. This could perhaps be fixed, by supporting filesystem
# access when running inside Node.js.
TEST_PACKAGES_WASM = $(filter-out $(TEST_PACKAGES_NONWASM), $(TEST_PACKAGES_FAST))
TEST_PACKAGES_NONWASM = \
compress/lzw \
compress/zlib \
crypto/ecdsa \
debug/macho \
embed/internal/embedtest \
go/format \
os \
testing \
$(nil)
# These packages cannot be tested on baremetal.
#
# Some reasons why the tests don't pass on baremetal:
#
# * No filesystem is available, so packages like compress/zlib can't be tested
# (just like wasm).
# * picolibc math functions apparently are less precise, the math package
# fails on baremetal.
TEST_PACKAGES_BAREMETAL = $(filter-out $(TEST_PACKAGES_NONBAREMETAL), $(TEST_PACKAGES_FAST))
TEST_PACKAGES_NONBAREMETAL = \
$(TEST_PACKAGES_NONWASM) \
math \
$(nil)
# Report platforms on which each standard library package is known to pass tests # Report platforms on which each standard library package is known to pass tests
jointmp := $(shell echo /tmp/join.$$$$)
report-stdlib-tests-pass: report-stdlib-tests-pass:
$(eval jointmp := $(shell echo /tmp/join.$$$$))
@for t in $(TEST_PACKAGES_DARWIN); do echo "$$t darwin"; done | sort > $(jointmp).darwin @for t in $(TEST_PACKAGES_DARWIN); do echo "$$t darwin"; done | sort > $(jointmp).darwin
@for t in $(TEST_PACKAGES_LINUX); do echo "$$t linux"; done | sort > $(jointmp).linux @for t in $(TEST_PACKAGES_LINUX); do echo "$$t linux"; done | sort > $(jointmp).linux
@for t in $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW); do echo "$$t darwin linux wasi windows"; done | sort > $(jointmp).portable @for t in $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW); do echo "$$t darwin linux wasi windows"; done | sort > $(jointmp).portable
@@ -467,11 +424,11 @@ report-stdlib-tests-pass:
@rm $(jointmp).* @rm $(jointmp).*
# Standard library packages that pass tests quickly on the current platform # Standard library packages that pass tests quickly on the current platform
ifeq ($(uname),Darwin) ifeq ($(shell uname),Darwin)
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_DARWIN) TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_DARWIN)
TEST_IOFS := true TEST_IOFS := true
endif endif
ifeq ($(uname),Linux) ifeq ($(shell uname),Linux)
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_LINUX) TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_LINUX)
TEST_IOFS := true TEST_IOFS := true
endif endif
@@ -480,15 +437,11 @@ 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'
# 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).
.PHONY: tinygo-test .PHONY: tinygo-test
tinygo-test: tinygo-test:
@# TestExtraMethods: used by many crypto packages and uses reflect.Type.Method which is not implemented. $(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
@# TestParseAndBytesRoundTrip/P256/Generic: relies on t.Skip() which is not implemented
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
@# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also @# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also
@# requires a large stack-size. Hence, io/fs is only run conditionally. @# requires a large stack-size. Hence, io/fs is only run conditionally.
@# For more details, see the comments on issue #3143. @# For more details, see the comments on issue #3143.
@@ -496,26 +449,24 @@ ifeq ($(TEST_IOFS),true)
$(TINYGO) test -stack-size=6MB io/fs $(TINYGO) test -stack-size=6MB io/fs
endif endif
tinygo-test-fast: tinygo-test-fast:
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST) $(TINYGO) test $(TEST_PACKAGES_HOST)
tinygo-bench: tinygo-bench:
$(TINYGO) test -bench . $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW) $(TINYGO) test -bench . $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
tinygo-bench-fast: tinygo-bench-fast:
$(TINYGO) test -bench . $(TEST_PACKAGES_HOST) $(TINYGO) test -bench . $(TEST_PACKAGES_HOST)
# Same thing, except for wasi rather than the current platform. # Same thing, except for wasi rather than the current platform.
tinygo-test-wasm:
$(TINYGO) test -target wasm $(TEST_SKIP_FLAG) $(TEST_PACKAGES_WASM)
tinygo-test-wasi: tinygo-test-wasi:
$(TINYGO) test -target wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi $(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
tinygo-test-wasip1: tinygo-test-wasip1:
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
tinygo-test-wasip1-fast: tinygo-test-wasip1-fast:
$(TINYGO) test -target=wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi $(TINYGO) test -target=wasip1 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
tinygo-test-wasip2-slow: tinygo-test-wasip2-slow:
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_SLOW) $(TINYGO) test -target=wasip2 $(TEST_PACKAGES_SLOW)
tinygo-test-wasip2-fast: tinygo-test-wasip2-fast:
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi $(TINYGO) test -target=wasip2 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
tinygo-test-wasip2-sum-slow: tinygo-test-wasip2-sum-slow:
TINYGO=$(TINYGO) \ TINYGO=$(TINYGO) \
@@ -539,19 +490,18 @@ tinygo-bench-wasip2:
tinygo-bench-wasip2-fast: tinygo-bench-wasip2-fast:
$(TINYGO) test -target wasip2 -bench . $(TEST_PACKAGES_FAST) $(TINYGO) test -target wasip2 -bench . $(TEST_PACKAGES_FAST)
# Run tests on riscv-qemu since that one provides a large amount of memory.
tinygo-test-baremetal:
$(TINYGO) test -target riscv-qemu $(TEST_SKIP_FLAG) $(TEST_PACKAGES_BAREMETAL)
# Test external packages in a large corpus. # Test external packages in a large corpus.
test-corpus: test-corpus:
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml
test-corpus-fast: test-corpus-fast:
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus -short . -corpus=testdata/corpus.yaml CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus -short . -corpus=testdata/corpus.yaml
test-corpus-wasi: test-corpus-wasi: wasi-libc
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml -target=wasip1 CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml -target=wasip1
test-corpus-wasip2:
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml -target=wasip2 tinygo-baremetal:
# Regression tests that run on a baremetal target and don't fit in either main_test.go or smoketest.
# regression test for #2666: e.g. encoding/hex must pass on baremetal
$(TINYGO) test -target cortex-m-qemu encoding/hex
.PHONY: testchdir .PHONY: testchdir
testchdir: testchdir:
@@ -573,8 +523,6 @@ smoketest: testchdir
# regression test for #2563 # regression test for #2563
cd tests/os/smoke && $(TINYGO) test -c -target=pybadge && rm smoke.test cd tests/os/smoke && $(TINYGO) test -c -target=pybadge && rm smoke.test
# test all examples (except pwm) # test all examples (except pwm)
$(TINYGO) build -size short -o test.hex -target=pga2350 examples/echo
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pca10040 examples/blinky1 $(TINYGO) build -size short -o test.hex -target=pca10040 examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pca10040 examples/adc $(TINYGO) build -size short -o test.hex -target=pca10040 examples/adc
@@ -623,23 +571,21 @@ smoketest: testchdir
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
# test simulated boards on play.tinygo.org # test simulated boards on play.tinygo.org
ifneq ($(WASM), 0) ifneq ($(WASM), 0)
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=arduino examples/blinky1 $(TINYGO) build -size short -o test.wasm -tags=arduino examples/blinky1
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=hifive1b examples/blinky1 $(TINYGO) build -size short -o test.wasm -tags=hifive1b examples/blinky1
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=reelboard examples/blinky1 $(TINYGO) build -size short -o test.wasm -tags=reelboard examples/blinky1
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=microbit examples/microbit-blink $(TINYGO) build -size short -o test.wasm -tags=microbit examples/microbit-blink
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=circuitplay_express examples/blinky1 $(TINYGO) build -size short -o test.wasm -tags=circuitplay_express examples/blinky1
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=circuitplay_bluefruit examples/blinky1 $(TINYGO) build -size short -o test.wasm -tags=circuitplay_bluefruit examples/blinky1
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=mch2022 examples/machinetest $(TINYGO) build -size short -o test.wasm -tags=mch2022 examples/machinetest
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=gopher_badge examples/blinky1 $(TINYGO) build -size short -o test.wasm -tags=gopher_badge examples/blinky1
@$(MD5SUM) test.wasm
GOOS=js GOARCH=wasm $(TINYGO) build -size short -o test.wasm -tags=pico examples/blinky1
@$(MD5SUM) test.wasm @$(MD5SUM) test.wasm
endif endif
# test all targets/boards # test all targets/boards
@@ -653,12 +599,8 @@ endif
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=microbit-v2-s113v7 examples/microbit-blink $(TINYGO) build -size short -o test.hex -target=microbit-v2-s113v7 examples/microbit-blink
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=microbit-v2-s140v7 examples/microbit-blink
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=nrf52840-mdk examples/blinky1 $(TINYGO) build -size short -o test.hex -target=nrf52840-mdk examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=btt-skr-pico examples/uart
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pca10031 examples/blinky1 $(TINYGO) build -size short -o test.hex -target=pca10031 examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=reelboard examples/blinky1 $(TINYGO) build -size short -o test.hex -target=reelboard examples/blinky1
@@ -795,8 +737,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
@@ -805,10 +745,6 @@ endif
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=tiny2350 examples/blinky1 $(TINYGO) build -size short -o test.hex -target=tiny2350 examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pico-plus2 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=metro-rp2350 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo $(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
# test pwm # test pwm
@@ -825,10 +761,6 @@ endif
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=feather-nrf52840 examples/usb-midi $(TINYGO) build -size short -o test.hex -target=feather-nrf52840 examples/usb-midi
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pico examples/usb-storage
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pico2 examples/usb-storage
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=nrf52840-s140v6-uf2-generic examples/machinetest $(TINYGO) build -size short -o test.hex -target=nrf52840-s140v6-uf2-generic examples/machinetest
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
ifneq ($(STM32), 0) ifneq ($(STM32), 0)
@@ -868,8 +800,6 @@ ifneq ($(STM32), 0)
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=mksnanov3 examples/blinky1 $(TINYGO) build -size short -o test.hex -target=mksnanov3 examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=stm32l0x1 examples/serial
@$(MD5SUM) test.hex
endif endif
$(TINYGO) build -size short -o test.hex -target=atmega328pb examples/blinkm $(TINYGO) build -size short -o test.hex -target=atmega328pb examples/blinkm
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
@@ -937,10 +867,6 @@ endif
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=elecrow-rp2350 examples/blinky1 $(TINYGO) build -size short -o test.hex -target=elecrow-rp2350 examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=hw-651 examples/machinetest
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=hw-651-s110v8 examples/machinetest
@$(MD5SUM) test.hex
ifneq ($(WASM), 0) ifneq ($(WASM), 0)
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/export $(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/export
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/main $(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/main
@@ -973,17 +899,15 @@ 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 wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binaryen)
@mkdir -p build/release/tinygo/bin @mkdir -p build/release/tinygo/bin
@mkdir -p build/release/tinygo/lib/bdwgc
@mkdir -p build/release/tinygo/lib/clang/include @mkdir -p build/release/tinygo/lib/clang/include
@mkdir -p build/release/tinygo/lib/CMSIS/CMSIS @mkdir -p build/release/tinygo/lib/CMSIS/CMSIS
@mkdir -p build/release/tinygo/lib/macos-minimal-sdk @mkdir -p build/release/tinygo/lib/macos-minimal-sdk
@mkdir -p build/release/tinygo/lib/mingw-w64/mingw-w64-crt/crt
@mkdir -p build/release/tinygo/lib/mingw-w64/mingw-w64-crt/math
@mkdir -p build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common @mkdir -p build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common
@mkdir -p build/release/tinygo/lib/mingw-w64/mingw-w64-crt/stdio
@mkdir -p build/release/tinygo/lib/mingw-w64/mingw-w64-headers/defaults @mkdir -p build/release/tinygo/lib/mingw-w64/mingw-w64-headers/defaults
@mkdir -p build/release/tinygo/lib/musl/arch @mkdir -p build/release/tinygo/lib/musl/arch
@mkdir -p build/release/tinygo/lib/musl/crt @mkdir -p build/release/tinygo/lib/musl/crt
@@ -991,8 +915,7 @@ build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binary
@mkdir -p build/release/tinygo/lib/nrfx @mkdir -p build/release/tinygo/lib/nrfx
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libc @mkdir -p build/release/tinygo/lib/picolibc/newlib/libc
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libm @mkdir -p build/release/tinygo/lib/picolibc/newlib/libm
@mkdir -p build/release/tinygo/lib/wasi-libc/dlmalloc @mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch @mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src @mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@mkdir -p build/release/tinygo/lib/wasi-cli/ @mkdir -p build/release/tinygo/lib/wasi-cli/
@@ -1001,7 +924,6 @@ build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binary
ifneq ($(USE_SYSTEM_BINARYEN),1) ifneq ($(USE_SYSTEM_BINARYEN),1)
@cp -p build/wasm-opt$(EXE) build/release/tinygo/bin @cp -p build/wasm-opt$(EXE) build/release/tinygo/bin
endif endif
@cp -rp lib/bdwgc/* build/release/tinygo/lib/bdwgc
@cp -p $(abspath $(CLANG_SRC))/lib/Headers/*.h build/release/tinygo/lib/clang/include @cp -p $(abspath $(CLANG_SRC))/lib/Headers/*.h build/release/tinygo/lib/clang/include
@cp -rp lib/CMSIS/CMSIS/Include build/release/tinygo/lib/CMSIS/CMSIS @cp -rp lib/CMSIS/CMSIS/Include build/release/tinygo/lib/CMSIS/CMSIS
@cp -rp lib/CMSIS/README.md build/release/tinygo/lib/CMSIS @cp -rp lib/CMSIS/README.md build/release/tinygo/lib/CMSIS
@@ -1015,8 +937,6 @@ endif
@cp -rp lib/musl/crt/crt1.c build/release/tinygo/lib/musl/crt @cp -rp lib/musl/crt/crt1.c build/release/tinygo/lib/musl/crt
@cp -rp lib/musl/COPYRIGHT build/release/tinygo/lib/musl @cp -rp lib/musl/COPYRIGHT build/release/tinygo/lib/musl
@cp -rp lib/musl/include build/release/tinygo/lib/musl @cp -rp lib/musl/include build/release/tinygo/lib/musl
@cp -rp lib/musl/src/conf build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/ctype build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/env build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/env build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/errno build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/errno build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/exit build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/exit build/release/tinygo/lib/musl/src
@@ -1031,29 +951,19 @@ endif
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/misc build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/misc build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/multibyte build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/multibyte build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/sched build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/stdlib build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/thread build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/thread build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/time build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/time build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/unistd build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/unistd build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/process build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/process build/release/tinygo/lib/musl/src
@cp -rp lib/mingw-w64/mingw-w64-crt/crt/pseudo-reloc.c build/release/tinygo/lib/mingw-w64/mingw-w64-crt/crt
@cp -rp lib/mingw-w64/mingw-w64-crt/def-include build/release/tinygo/lib/mingw-w64/mingw-w64-crt @cp -rp lib/mingw-w64/mingw-w64-crt/def-include build/release/tinygo/lib/mingw-w64/mingw-w64-crt
@cp -rp lib/mingw-w64/mingw-w64-crt/gdtoa build/release/tinygo/lib/mingw-w64/mingw-w64-crt
@cp -rp lib/mingw-w64/mingw-w64-crt/include build/release/tinygo/lib/mingw-w64/mingw-w64-crt
@cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/api-ms-win-crt-* build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common @cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/api-ms-win-crt-* build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common
@cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/advapi32.def.in build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common
@cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/kernel32.def.in build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common @cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/kernel32.def.in build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common
@cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/msvcrt.def.in build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common @cp -rp lib/mingw-w64/mingw-w64-crt/stdio/ucrt_* build/release/tinygo/lib/mingw-w64/mingw-w64-crt/stdio
@cp -rp lib/mingw-w64/mingw-w64-crt/math/x86 build/release/tinygo/lib/mingw-w64/mingw-w64-crt/math
@cp -rp lib/mingw-w64/mingw-w64-crt/misc build/release/tinygo/lib/mingw-w64/mingw-w64-crt
@cp -rp lib/mingw-w64/mingw-w64-crt/stdio build/release/tinygo/lib/mingw-w64/mingw-w64-crt
@cp -rp lib/mingw-w64/mingw-w64-headers/crt/ build/release/tinygo/lib/mingw-w64/mingw-w64-headers @cp -rp lib/mingw-w64/mingw-w64-headers/crt/ build/release/tinygo/lib/mingw-w64/mingw-w64-headers
@cp -rp lib/mingw-w64/mingw-w64-headers/defaults/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers/defaults @cp -rp lib/mingw-w64/mingw-w64-headers/defaults/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers/defaults
@cp -rp lib/mingw-w64/mingw-w64-headers/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers
@cp -rp lib/nrfx/* build/release/tinygo/lib/nrfx @cp -rp lib/nrfx/* build/release/tinygo/lib/nrfx
@cp -rp lib/picolibc/newlib/libc/ctype build/release/tinygo/lib/picolibc/newlib/libc @cp -rp lib/picolibc/newlib/libc/ctype build/release/tinygo/lib/picolibc/newlib/libc
@cp -rp lib/picolibc/newlib/libc/include build/release/tinygo/lib/picolibc/newlib/libc @cp -rp lib/picolibc/newlib/libc/include build/release/tinygo/lib/picolibc/newlib/libc
@@ -1063,37 +973,15 @@ endif
@cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm @cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm @cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib @cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
@cp -rp lib/wasi-libc/dlmalloc/src build/release/tinygo/lib/wasi-libc/dlmalloc @cp -rp lib/wasi-libc/libc-bottom-half/headers/public build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
@cp -rp lib/wasi-libc/libc-bottom-half/cloudlibc build/release/tinygo/lib/wasi-libc/libc-bottom-half
@cp -rp lib/wasi-libc/libc-bottom-half/headers build/release/tinygo/lib/wasi-libc/libc-bottom-half
@cp -rp lib/wasi-libc/libc-bottom-half/sources build/release/tinygo/lib/wasi-libc/libc-bottom-half
@cp -rp lib/wasi-libc/libc-top-half/headers build/release/tinygo/lib/wasi-libc/libc-top-half
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch @cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch @cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
@cp -rp lib/wasi-libc/libc-top-half/musl/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl
@cp -rp lib/wasi-libc/libc-top-half/musl/src/conf build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/dirent build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/env build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/errno build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/exit build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/fcntl build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/fenv build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src @cp -rp lib/wasi-libc/libc-top-half/musl/src/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/internal build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src @cp -rp lib/wasi-libc/libc-top-half/musl/src/internal build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/legacy build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/locale build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/math build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src @cp -rp lib/wasi-libc/libc-top-half/musl/src/math build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/misc build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/multibyte build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/network build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/stat build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/stdio build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/stdlib build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/string build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src @cp -rp lib/wasi-libc/libc-top-half/musl/src/string build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/thread build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src @cp -rp lib/wasi-libc/libc-top-half/musl/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl
@cp -rp lib/wasi-libc/libc-top-half/musl/src/time build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src @cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
@cp -rp lib/wasi-libc/libc-top-half/musl/src/unistd build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/sources build/release/tinygo/lib/wasi-libc/libc-top-half
@cp -rp lib/wasi-cli/wit build/release/tinygo/lib/wasi-cli/wit @cp -rp lib/wasi-cli/wit build/release/tinygo/lib/wasi-cli/wit
@cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins @cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
@cp -rp llvm-project/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins @cp -rp llvm-project/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
@@ -1120,7 +1008,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
@@ -1128,10 +1015,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
+2 -2
View File
@@ -1,7 +1,7 @@
Copyright (c) 2018-2025 The TinyGo Authors. All rights reserved. Copyright (c) 2018-2023 The TinyGo Authors. All rights reserved.
TinyGo includes portions of the Go standard library. TinyGo includes portions of the Go standard library.
Copyright (c) 2009-2024 The Go Authors. All rights reserved. Copyright (c) 2009-2023 The Go Authors. All rights reserved.
TinyGo includes portions of LLVM, which is under the Apache License v2.0 with TinyGo includes portions of LLVM, which is under the Apache License v2.0 with
LLVM Exceptions. See https://llvm.org/LICENSE.txt for license information. LLVM Exceptions. See https://llvm.org/LICENSE.txt for license information.
+7 -9
View File
@@ -48,22 +48,20 @@ Here is a small TinyGo program for use by a WASI host application:
```go ```go
package main package main
//go:wasmexport add //go:wasm-module yourmodulename
//export add
func add(x, y uint32) uint32 { func add(x, y uint32) uint32 {
return x + y return x + y
} }
// main is required for the `wasip1` target, even if it isn't used.
func main() {}
``` ```
This compiles the above TinyGo program for use on any WASI Preview 1 runtime: This compiles the above TinyGo program for use on any WASI runtime:
```shell ```shell
tinygo build -buildmode=c-shared -o add.wasm -target=wasip1 add.go tinygo build -o main.wasm -target=wasip1 main.go
```
You can also use the same syntax as Go 1.24+:
```shell
GOARCH=wasip1 GOOS=wasm tinygo build -buildmode=c-shared -o add.wasm add.go
``` ```
## Installation ## Installation
-15
View File
@@ -3,7 +3,6 @@ package builder
import ( import (
"bytes" "bytes"
"debug/elf" "debug/elf"
"debug/macho"
"debug/pe" "debug/pe"
"encoding/binary" "encoding/binary"
"errors" "errors"
@@ -63,20 +62,6 @@ func makeArchive(arfile *os.File, objs []string) error {
fileIndex int fileIndex int
}{symbol.Name, i}) }{symbol.Name, i})
} }
} else if dbg, err := macho.NewFile(objfile); err == nil {
for _, symbol := range dbg.Symtab.Syms {
// See mach-o/nlist.h
if symbol.Type&0x0e != 0xe { // (symbol.Type & N_TYPE) != N_SECT
continue // undefined symbol
}
if symbol.Type&0x01 == 0 { // (symbol.Type & N_EXT) == 0
continue // internal symbol (static, etc)
}
symbolTable = append(symbolTable, struct {
name string
fileIndex int
}{symbol.Name, i})
}
} else if dbg, err := pe.NewFile(objfile); err == nil { } else if dbg, err := pe.NewFile(objfile); err == nil {
for _, symbol := range dbg.Symbols { for _, symbol := range dbg.Symbols {
if symbol.StorageClass != 2 { if symbol.StorageClass != 2 {
-88
View File
@@ -1,88 +0,0 @@
package builder
// The well-known conservative Boehm-Demers-Weiser GC.
// This file provides a way to compile this GC for use with TinyGo.
import (
"path/filepath"
"strings"
"github.com/tinygo-org/tinygo/goenv"
)
var BoehmGC = Library{
name: "bdwgc",
cflags: func(target, headerPath string) []string {
libdir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/bdwgc")
flags := []string{
// use a modern environment
"-DUSE_MMAP", // mmap is available
"-DUSE_MUNMAP", // return memory to the OS using munmap
"-DGC_BUILTIN_ATOMIC", // use compiler intrinsics for atomic operations
"-DNO_EXECUTE_PERMISSION", // don't make the heap executable
// specific flags for TinyGo
"-DALL_INTERIOR_POINTERS", // scan interior pointers (needed for Go)
"-DIGNORE_DYNAMIC_LOADING", // we don't support dynamic loading at the moment
"-DNO_GETCONTEXT", // musl doesn't support getcontext()
"-DGC_DISABLE_INCREMENTAL", // don't mess with SIGSEGV and such
// Use a minimal environment.
"-DNO_MSGBOX_ON_ERROR", // don't call MessageBoxA on Windows
"-DDONT_USE_ATEXIT",
"-DNO_GETENV",
// Special flag to work around the lack of __data_start in ld.lld.
// TODO: try to fix this in LLVM/lld directly so we don't have to
// work around it anymore.
"-DGC_DONT_REGISTER_MAIN_STATIC_DATA",
// Do not scan the stack. We have our own mechanism to do this.
"-DSTACK_NOT_SCANNED",
// Assertions can be enabled while debugging GC issues.
//"-DGC_ASSERTIONS",
// We use our own way of dealing with threads (that is a bit hacky).
// See src/runtime/gc_boehm.go.
//"-DGC_THREADS",
//"-DTHREAD_LOCAL_ALLOC",
"-I" + libdir + "/include",
}
return flags
},
needsLibc: true,
sourceDir: func() string {
return filepath.Join(goenv.Get("TINYGOROOT"), "lib/bdwgc")
},
librarySources: func(target string, _ bool) ([]string, error) {
sources := []string{
"allchblk.c",
"alloc.c",
"blacklst.c",
"dbg_mlc.c",
"dyn_load.c",
"finalize.c",
"headers.c",
"mach_dep.c",
"malloc.c",
"mark.c",
"mark_rts.c",
"misc.c",
"new_hblk.c",
"obj_map.c",
"os_dep.c",
"reclaim.c",
}
if strings.Split(target, "-")[2] == "windows" {
// Due to how the linker on Windows works (that doesn't allow
// undefined functions), we need to include these extra files.
sources = append(sources,
"mallocx.c",
"ptr_chck.c",
)
}
return sources, nil
},
}
+54 -80
View File
@@ -14,6 +14,7 @@ import (
"fmt" "fmt"
"go/types" "go/types"
"hash/crc32" "hash/crc32"
"io/fs"
"math/bits" "math/bits"
"os" "os"
"os/exec" "os/exec"
@@ -148,17 +149,16 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
var libcDependencies []*compileJob var libcDependencies []*compileJob
switch config.Target.Libc { switch config.Target.Libc {
case "darwin-libSystem": case "darwin-libSystem":
libcJob := makeDarwinLibSystemJob(config, tmpdir) job := makeDarwinLibSystemJob(config, tmpdir)
libcDependencies = append(libcDependencies, libcJob) libcDependencies = append(libcDependencies, job)
case "musl": case "musl":
var unlock func() job, unlock, err := libMusl.load(config, tmpdir)
libcJob, unlock, err := libMusl.load(config, tmpdir)
if err != nil { if err != nil {
return BuildResult{}, err return BuildResult{}, err
} }
defer unlock() defer unlock()
libcDependencies = append(libcDependencies, dummyCompileJob(filepath.Join(filepath.Dir(libcJob.result), "crt1.o"))) libcDependencies = append(libcDependencies, dummyCompileJob(filepath.Join(filepath.Dir(job.result), "crt1.o")))
libcDependencies = append(libcDependencies, libcJob) libcDependencies = append(libcDependencies, job)
case "picolibc": case "picolibc":
libcJob, unlock, err := libPicolibc.load(config, tmpdir) libcJob, unlock, err := libPicolibc.load(config, tmpdir)
if err != nil { if err != nil {
@@ -167,12 +167,11 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
defer unlock() defer unlock()
libcDependencies = append(libcDependencies, libcJob) libcDependencies = append(libcDependencies, libcJob)
case "wasi-libc": case "wasi-libc":
libcJob, unlock, err := libWasiLibc.load(config, tmpdir) path := filepath.Join(root, "lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a")
if err != nil { if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) {
return BuildResult{}, err return BuildResult{}, errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?")
} }
defer unlock() libcDependencies = append(libcDependencies, dummyCompileJob(path))
libcDependencies = append(libcDependencies, libcJob)
case "wasmbuiltins": case "wasmbuiltins":
libcJob, unlock, err := libWasmBuiltins.load(config, tmpdir) libcJob, unlock, err := libWasmBuiltins.load(config, tmpdir)
if err != nil { if err != nil {
@@ -181,12 +180,12 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
defer unlock() defer unlock()
libcDependencies = append(libcDependencies, libcJob) libcDependencies = append(libcDependencies, libcJob)
case "mingw-w64": case "mingw-w64":
libcJob, unlock, err := libMinGW.load(config, tmpdir) job, unlock, err := libMinGW.load(config, tmpdir)
if err != nil { if err != nil {
return BuildResult{}, err return BuildResult{}, err
} }
defer unlock() defer unlock()
libcDependencies = append(libcDependencies, libcJob) libcDependencies = append(libcDependencies, job)
libcDependencies = append(libcDependencies, makeMinGWExtraLibs(tmpdir, config.GOARCH())...) libcDependencies = append(libcDependencies, makeMinGWExtraLibs(tmpdir, config.GOARCH())...)
case "": case "":
// no library specified, so nothing to do // no library specified, so nothing to do
@@ -214,7 +213,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
MaxStackAlloc: config.MaxStackAlloc(), MaxStackAlloc: config.MaxStackAlloc(),
NeedsStackObjects: config.NeedsStackObjects(), NeedsStackObjects: config.NeedsStackObjects(),
Debug: !config.Options.SkipDWARF, // emit DWARF except when -internal-nodwarf is passed Debug: !config.Options.SkipDWARF, // emit DWARF except when -internal-nodwarf is passed
Nobounds: config.Options.Nobounds,
PanicStrategy: config.PanicStrategy(), PanicStrategy: config.PanicStrategy(),
} }
@@ -451,15 +449,8 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
if global.IsNil() { if global.IsNil() {
return errors.New("global not found: " + globalName) return errors.New("global not found: " + globalName)
} }
globalType := global.GlobalValueType()
if globalType.TypeKind() != llvm.StructTypeKind || globalType.StructName() != "runtime._string" {
// Verify this is indeed a string. This is needed so
// that makeGlobalsModule can just create the right
// globals of string type without checking.
return fmt.Errorf("%s: not a string", globalName)
}
name := global.Name() name := global.Name()
newGlobal := llvm.AddGlobal(mod, globalType, name+".tmp") newGlobal := llvm.AddGlobal(mod, global.GlobalValueType(), name+".tmp")
global.ReplaceAllUsesWith(newGlobal) global.ReplaceAllUsesWith(newGlobal)
global.EraseFromParentAsGlobal() global.EraseFromParentAsGlobal()
newGlobal.SetName(name) newGlobal.SetName(name)
@@ -547,15 +538,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
} }
} }
// Insert values from -ldflags="-X ..." into the IR.
// This is a separate module, so that the "runtime._string" type
// doesn't need to match precisely. LLVM tends to rename that type
// sometimes, leading to errors. But linking in a separate module
// works fine. See:
// https://github.com/tinygo-org/tinygo/issues/4810
globalsMod := makeGlobalsModule(ctx, globalValues, machine)
llvm.LinkModules(mod, globalsMod)
// Create runtime.initAll function that calls the runtime // Create runtime.initAll function that calls the runtime
// initializer of each package. // initializer of each package.
llvmInitFn := mod.NamedFunction("runtime.initAll") llvmInitFn := mod.NamedFunction("runtime.initAll")
@@ -608,7 +590,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
// Run all optimization passes, which are much more effective now // Run all optimization passes, which are much more effective now
// that the optimizer can see the whole program at once. // that the optimizer can see the whole program at once.
err := optimizeProgram(mod, config) err := optimizeProgram(mod, config, globalValues)
if err != nil { if err != nil {
return err return err
} }
@@ -622,11 +604,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
}, },
} }
// Create the output directory, if needed
if err := os.MkdirAll(filepath.Dir(outpath), 0777); err != nil {
return result, err
}
// Check whether we only need to create an object file. // Check whether we only need to create an object file.
// If so, we don't need to link anything and will be finished quickly. // If so, we don't need to link anything and will be finished quickly.
outext := filepath.Ext(outpath) outext := filepath.Ext(outpath)
@@ -690,16 +667,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
ldflags = append(ldflags, "--no-entry") ldflags = append(ldflags, "--no-entry")
} }
if config.Options.BuildMode == "wasi-legacy" {
if !strings.HasPrefix(config.Triple(), "wasm32-") {
return result, fmt.Errorf("buildmode wasi-legacy is only supported on wasm")
}
if config.Options.Scheduler != "none" {
return result, fmt.Errorf("buildmode wasi-legacy only supports scheduler=none")
}
}
// Add compiler-rt dependency if needed. Usually this is a simple load from // Add compiler-rt dependency if needed. Usually this is a simple load from
// a cache. // a cache.
if config.Target.RTLib == "compiler-rt" { if config.Target.RTLib == "compiler-rt" {
@@ -711,16 +678,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
linkerDependencies = append(linkerDependencies, job) linkerDependencies = append(linkerDependencies, job)
} }
// The Boehm collector is stored in a separate C library.
if config.GC() == "boehm" {
job, unlock, err := BoehmGC.load(config, tmpdir)
if err != nil {
return BuildResult{}, err
}
defer unlock()
linkerDependencies = append(linkerDependencies, job)
}
// Add jobs to compile extra files. These files are in C or assembly and // Add jobs to compile extra files. These files are in C or assembly and
// contain things like the interrupt vector table and low level operations // contain things like the interrupt vector table and low level operations
// such as stack switching. // such as stack switching.
@@ -1046,7 +1003,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
} }
@@ -1173,7 +1130,7 @@ func createEmbedObjectFile(data, hexSum, sourceFile, sourceDir, tmpdir string, c
// optimizeProgram runs a series of optimizations and transformations that are // optimizeProgram runs a series of optimizations and transformations that are
// needed to convert a program to its final form. Some transformations are not // needed to convert a program to its final form. Some transformations are not
// optional and must be run as the compiler expects them to run. // optional and must be run as the compiler expects them to run.
func optimizeProgram(mod llvm.Module, config *compileopts.Config) error { func optimizeProgram(mod llvm.Module, config *compileopts.Config, globalValues map[string]map[string]string) error {
err := interp.Run(mod, config.Options.InterpTimeout, config.DumpSSA()) err := interp.Run(mod, config.Options.InterpTimeout, config.DumpSSA())
if err != nil { if err != nil {
return err return err
@@ -1191,6 +1148,12 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config) error {
} }
} }
// Insert values from -ldflags="-X ..." into the IR.
err = setGlobalValues(mod, globalValues)
if err != nil {
return err
}
// Run most of the whole-program optimizations (including the whole // Run most of the whole-program optimizations (including the whole
// O0/O1/O2/Os/Oz optimization pipeline). // O0/O1/O2/Os/Oz optimization pipeline).
errs := transform.Optimize(mod, config) errs := transform.Optimize(mod, config)
@@ -1204,19 +1167,10 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config) error {
return nil return nil
} }
func makeGlobalsModule(ctx llvm.Context, globals map[string]map[string]string, machine llvm.TargetMachine) llvm.Module { // setGlobalValues sets the global values from the -ldflags="-X ..." compiler
mod := ctx.NewModule("cmdline-globals") // option in the given module. An error may be returned if the global is not of
targetData := machine.CreateTargetData() // the expected type.
defer targetData.Dispose() func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) error {
mod.SetDataLayout(targetData.String())
stringType := ctx.StructCreateNamed("runtime._string")
uintptrType := ctx.IntType(targetData.PointerSize() * 8)
stringType.StructSetBody([]llvm.Type{
llvm.PointerType(ctx.Int8Type(), 0),
uintptrType,
}, false)
var pkgPaths []string var pkgPaths []string
for pkgPath := range globals { for pkgPath := range globals {
pkgPaths = append(pkgPaths, pkgPath) pkgPaths = append(pkgPaths, pkgPath)
@@ -1232,6 +1186,24 @@ func makeGlobalsModule(ctx llvm.Context, globals map[string]map[string]string, m
for _, name := range names { for _, name := range names {
value := pkg[name] value := pkg[name]
globalName := pkgPath + "." + name globalName := pkgPath + "." + name
global := mod.NamedGlobal(globalName)
if global.IsNil() || !global.Initializer().IsNil() {
// The global either does not exist (optimized away?) or has
// some value, in which case it has already been initialized at
// package init time.
continue
}
// A strin is a {ptr, len} pair. We need these types to build the
// initializer.
initializerType := global.GlobalValueType()
if initializerType.TypeKind() != llvm.StructTypeKind || initializerType.StructName() == "" {
return fmt.Errorf("%s: not a string", globalName)
}
elementTypes := initializerType.StructElementTypes()
if len(elementTypes) != 2 {
return fmt.Errorf("%s: not a string", globalName)
}
// Create a buffer for the string contents. // Create a buffer for the string contents.
bufInitializer := mod.Context().ConstString(value, false) bufInitializer := mod.Context().ConstString(value, false)
@@ -1242,20 +1214,22 @@ func makeGlobalsModule(ctx llvm.Context, globals map[string]map[string]string, m
buf.SetLinkage(llvm.PrivateLinkage) buf.SetLinkage(llvm.PrivateLinkage)
// Create the string value, which is a {ptr, len} pair. // Create the string value, which is a {ptr, len} pair.
length := llvm.ConstInt(uintptrType, uint64(len(value)), false) zero := llvm.ConstInt(mod.Context().Int32Type(), 0, false)
initializer := llvm.ConstNamedStruct(stringType, []llvm.Value{ ptr := llvm.ConstGEP(bufInitializer.Type(), buf, []llvm.Value{zero, zero})
buf, if ptr.Type() != elementTypes[0] {
return fmt.Errorf("%s: not a string", globalName)
}
length := llvm.ConstInt(elementTypes[1], uint64(len(value)), false)
initializer := llvm.ConstNamedStruct(initializerType, []llvm.Value{
ptr,
length, length,
}) })
// Create the string global. // Set the initializer. No initializer should be set at this point.
global := llvm.AddGlobal(mod, stringType, globalName)
global.SetInitializer(initializer) global.SetInitializer(initializer)
global.SetAlignment(targetData.PrefTypeAlignment(stringType))
} }
} }
return nil
return mod
} }
// functionStackSizes keeps stack size information about a single function // functionStackSizes keeps stack size information about a single function
+1 -1
View File
@@ -67,9 +67,9 @@ func TestClangAttributes(t *testing.T) {
{GOOS: "linux", GOARCH: "mipsle", GOMIPS: "softfloat"}, {GOOS: "linux", GOARCH: "mipsle", GOMIPS: "softfloat"},
{GOOS: "darwin", GOARCH: "amd64"}, {GOOS: "darwin", GOARCH: "amd64"},
{GOOS: "darwin", GOARCH: "arm64"}, {GOOS: "darwin", GOARCH: "arm64"},
{GOOS: "windows", GOARCH: "386"},
{GOOS: "windows", GOARCH: "amd64"}, {GOOS: "windows", GOARCH: "amd64"},
{GOOS: "windows", GOARCH: "arm64"}, {GOOS: "windows", GOARCH: "arm64"},
{GOOS: "wasip1", GOARCH: "wasm"},
} { } {
name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH
if options.GOARCH == "arm" { if options.GOARCH == "arm" {
+1 -11
View File
@@ -3,7 +3,6 @@ package builder
import ( import (
"os" "os"
"path/filepath" "path/filepath"
"strings"
"github.com/tinygo-org/tinygo/compileopts" "github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/goenv" "github.com/tinygo-org/tinygo/goenv"
@@ -202,11 +201,6 @@ var avrBuiltins = []string{
"avr/udivmodqi4.S", "avr/udivmodqi4.S",
} }
// Builtins needed specifically for windows/386.
var windowsI386Builtins = []string{
"i386/chkstk.S", // also _alloca
}
// libCompilerRT is a library with symbols required by programs compiled with // libCompilerRT is a library with symbols required by programs compiled with
// LLVM. These symbols are for operations that cannot be emitted with a single // LLVM. These symbols are for operations that cannot be emitted with a single
// instruction or a short sequence of instructions for that target. // instruction or a short sequence of instructions for that target.
@@ -226,7 +220,7 @@ var libCompilerRT = Library{
// Development build. // Development build.
return filepath.Join(goenv.Get("TINYGOROOT"), "lib/compiler-rt-builtins") return filepath.Join(goenv.Get("TINYGOROOT"), "lib/compiler-rt-builtins")
}, },
librarySources: func(target string, _ bool) ([]string, error) { librarySources: func(target string) ([]string, error) {
builtins := append([]string{}, genericBuiltins...) // copy genericBuiltins builtins := append([]string{}, genericBuiltins...) // copy genericBuiltins
switch compileopts.CanonicalArchName(target) { switch compileopts.CanonicalArchName(target) {
case "arm": case "arm":
@@ -235,10 +229,6 @@ var libCompilerRT = Library{
builtins = append(builtins, avrBuiltins...) builtins = append(builtins, avrBuiltins...)
case "x86_64", "aarch64", "riscv64": // any 64-bit arch case "x86_64", "aarch64", "riscv64": // any 64-bit arch
builtins = append(builtins, genericBuiltins128...) builtins = append(builtins, genericBuiltins128...)
case "i386":
if strings.Split(target, "-")[2] == "windows" {
builtins = append(builtins, windowsI386Builtins...)
}
} }
return builtins, nil return builtins, nil
}, },
+8 -13
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -26,7 +26,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
// Version range supported by TinyGo. // Version range supported by TinyGo.
const minorMin = 19 const minorMin = 19
const minorMax = 25 const minorMax = 23
// Check that we support this Go toolchain version. // Check that we support this Go toolchain version.
gorootMajor, gorootMinor, err := goenv.GetGorootVersion() gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
@@ -36,7 +36,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
if gorootMajor != 1 || gorootMinor < minorMin || gorootMinor > minorMax { if gorootMajor != 1 || gorootMinor < minorMin || gorootMinor > minorMax {
// Note: when this gets updated, also update the Go compatibility matrix: // Note: when this gets updated, also update the Go compatibility matrix:
// https://github.com/tinygo-org/tinygo-site/blob/dev/content/docs/reference/go-compat-matrix.md // https://github.com/tinygo-org/tinygo-site/blob/dev/content/docs/reference/go-compat-matrix.md
return nil, fmt.Errorf("requires go version 1.%d through 1.%d, got go%d.%d", minorMin, minorMax, gorootMajor, gorootMinor) return nil, fmt.Errorf("requires go version 1.19 through 1.23, got go%d.%d", gorootMajor, gorootMinor)
} }
// Check that the Go toolchain version isn't too new, if we haven't been // Check that the Go toolchain version isn't too new, if we haven't been
+2 -2
View File
@@ -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
+12 -25
View File
@@ -15,9 +15,6 @@ import (
// Library is a container for information about a single C library, such as a // Library is a container for information about a single C library, such as a
// compiler runtime or libc. // compiler runtime or libc.
//
// Note: whenever a library gets changed, the version in compileopts/config.go
// probably also needs to be incremented.
type Library struct { type Library struct {
// The library name, such as compiler-rt or picolibc. // The library name, such as compiler-rt or picolibc.
name string name string
@@ -28,17 +25,11 @@ type Library struct {
// cflags returns the C flags specific to this library // cflags returns the C flags specific to this library
cflags func(target, headerPath string) []string cflags func(target, headerPath string) []string
// cflagsForFile returns additional C flags for a particular source file.
cflagsForFile func(path string) []string
// needsLibc is set to true if this library needs libc headers.
needsLibc bool
// The source directory. // The source directory.
sourceDir func() string sourceDir func() string
// The source files, relative to sourceDir. // The source files, relative to sourceDir.
librarySources func(target string, libcNeedsMalloc bool) ([]string, error) librarySources func(target string) ([]string, error)
// The source code for the crt1.o file, relative to sourceDir. // The source code for the crt1.o file, relative to sourceDir.
crt1Source string crt1Source string
@@ -53,8 +44,13 @@ type Library struct {
// As a side effect, this call creates the library header files if they didn't // As a side effect, this call creates the library header files if they didn't
// exist yet. // exist yet.
func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJob, abortLock func(), err error) { func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJob, abortLock func(), err error) {
outdir := config.LibraryPath(l.name) outdir, precompiled := config.LibcPath(l.name)
archiveFilePath := filepath.Join(outdir, "lib.a") archiveFilePath := filepath.Join(outdir, "lib.a")
if precompiled {
// Found a precompiled library for this OS/architecture. Return the path
// directly.
return dummyCompileJob(archiveFilePath), func() {}, nil
}
// Create a lock on the output (if supported). // Create a lock on the output (if supported).
// This is a bit messy, but avoids a deadlock because it is ordered consistently with other library loads within a build. // This is a bit messy, but avoids a deadlock because it is ordered consistently with other library loads within a build.
@@ -185,9 +181,6 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
args = append(args, "-mfpu=vfpv2") args = append(args, "-mfpu=vfpv2")
} }
} }
if l.needsLibc {
args = append(args, config.LibcCFlags()...)
}
var once sync.Once var once sync.Once
@@ -226,13 +219,12 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
// Create jobs to compile all sources. These jobs are depended upon by the // Create jobs to compile all sources. These jobs are depended upon by the
// archive job above, so must be run first. // archive job above, so must be run first.
paths, err := l.librarySources(target, config.LibcNeedsMalloc()) paths, err := l.librarySources(target)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
for _, path := range paths { for _, path := range paths {
// Strip leading "../" parts off the path. // Strip leading "../" parts off the path.
path := path
cleanpath := path cleanpath := path
for strings.HasPrefix(cleanpath, "../") { for strings.HasPrefix(cleanpath, "../") {
cleanpath = cleanpath[3:] cleanpath = cleanpath[3:]
@@ -241,14 +233,11 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
objpath := filepath.Join(dir, cleanpath+".o") objpath := filepath.Join(dir, cleanpath+".o")
os.MkdirAll(filepath.Dir(objpath), 0o777) os.MkdirAll(filepath.Dir(objpath), 0o777)
objs = append(objs, objpath) objs = append(objs, objpath)
objfile := &compileJob{ job.dependencies = append(job.dependencies, &compileJob{
description: "compile " + srcpath, description: "compile " + srcpath,
run: func(*compileJob) error { run: func(*compileJob) error {
var compileArgs []string var compileArgs []string
compileArgs = append(compileArgs, args...) compileArgs = append(compileArgs, args...)
if l.cflagsForFile != nil {
compileArgs = append(compileArgs, l.cflagsForFile(path)...)
}
compileArgs = append(compileArgs, "-o", objpath, srcpath) compileArgs = append(compileArgs, "-o", objpath, srcpath)
if config.Options.PrintCommands != nil { if config.Options.PrintCommands != nil {
config.Options.PrintCommands("clang", compileArgs...) config.Options.PrintCommands("clang", compileArgs...)
@@ -259,8 +248,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
} }
return nil return nil
}, },
} })
job.dependencies = append(job.dependencies, objfile)
} }
// Create crt1.o job, if needed. // Create crt1.o job, if needed.
@@ -269,7 +257,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
// won't make much of a difference in speed). // won't make much of a difference in speed).
if l.crt1Source != "" { if l.crt1Source != "" {
srcpath := filepath.Join(sourceDir, l.crt1Source) srcpath := filepath.Join(sourceDir, l.crt1Source)
crt1Job := &compileJob{ job.dependencies = append(job.dependencies, &compileJob{
description: "compile " + srcpath, description: "compile " + srcpath,
run: func(*compileJob) error { run: func(*compileJob) error {
var compileArgs []string var compileArgs []string
@@ -289,8 +277,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
} }
return os.Rename(tmpfile.Name(), filepath.Join(outdir, "crt1.o")) return os.Rename(tmpfile.Name(), filepath.Join(outdir, "crt1.o"))
}, },
} })
job.dependencies = append(job.dependencies, crt1Job)
} }
ok = true ok = true
+33 -87
View File
@@ -30,62 +30,25 @@ var libMinGW = Library{
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64") }, sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64") },
cflags: func(target, headerPath string) []string { cflags: func(target, headerPath string) []string {
mingwDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64") mingwDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64")
flags := []string{ return []string{
"-nostdlibinc", "-nostdlibinc",
"-isystem", mingwDir + "/mingw-w64-crt/include",
"-isystem", mingwDir + "/mingw-w64-headers/crt", "-isystem", mingwDir + "/mingw-w64-headers/crt",
"-isystem", mingwDir + "/mingw-w64-headers/include",
"-I", mingwDir + "/mingw-w64-headers/defaults/include", "-I", mingwDir + "/mingw-w64-headers/defaults/include",
"-I" + headerPath, "-I" + headerPath,
} }
if strings.Split(target, "-")[0] == "i386" {
flags = append(flags,
"-D__MSVCRT_VERSION__=0x700", // Microsoft Visual C++ .NET 2002
"-D_WIN32_WINNT=0x0501", // target Windows XP
"-D_CRTBLD",
"-Wno-pragma-pack",
)
}
return flags
}, },
librarySources: func(target string, _ bool) ([]string, error) { librarySources: func(target string) ([]string, error) {
// These files are needed so that printf and the like are supported. // These files are needed so that printf and the like are supported.
var sources []string sources := []string{
if strings.Split(target, "-")[0] == "i386" { "mingw-w64-crt/stdio/ucrt_fprintf.c",
// Old 32-bit x86 systems use msvcrt.dll. "mingw-w64-crt/stdio/ucrt_fwprintf.c",
sources = []string{ "mingw-w64-crt/stdio/ucrt_printf.c",
"mingw-w64-crt/crt/pseudo-reloc.c", "mingw-w64-crt/stdio/ucrt_snprintf.c",
"mingw-w64-crt/gdtoa/dmisc.c", "mingw-w64-crt/stdio/ucrt_sprintf.c",
"mingw-w64-crt/gdtoa/gdtoa.c", "mingw-w64-crt/stdio/ucrt_vfprintf.c",
"mingw-w64-crt/gdtoa/gmisc.c", "mingw-w64-crt/stdio/ucrt_vprintf.c",
"mingw-w64-crt/gdtoa/misc.c", "mingw-w64-crt/stdio/ucrt_vsnprintf.c",
"mingw-w64-crt/math/x86/exp2.S", "mingw-w64-crt/stdio/ucrt_vsprintf.c",
"mingw-w64-crt/math/x86/trunc.S",
"mingw-w64-crt/misc/___mb_cur_max_func.c",
"mingw-w64-crt/misc/lc_locale_func.c",
"mingw-w64-crt/misc/mbrtowc.c",
"mingw-w64-crt/misc/strnlen.c",
"mingw-w64-crt/misc/wcrtomb.c",
"mingw-w64-crt/misc/wcsnlen.c",
"mingw-w64-crt/stdio/acrt_iob_func.c",
"mingw-w64-crt/stdio/mingw_lock.c",
"mingw-w64-crt/stdio/mingw_pformat.c",
"mingw-w64-crt/stdio/mingw_vfprintf.c",
"mingw-w64-crt/stdio/mingw_vsnprintf.c",
}
} else {
// Anything somewhat modern (amd64, arm64) uses UCRT.
sources = []string{
"mingw-w64-crt/stdio/ucrt_fprintf.c",
"mingw-w64-crt/stdio/ucrt_fwprintf.c",
"mingw-w64-crt/stdio/ucrt_printf.c",
"mingw-w64-crt/stdio/ucrt_snprintf.c",
"mingw-w64-crt/stdio/ucrt_sprintf.c",
"mingw-w64-crt/stdio/ucrt_vfprintf.c",
"mingw-w64-crt/stdio/ucrt_vprintf.c",
"mingw-w64-crt/stdio/ucrt_vsnprintf.c",
"mingw-w64-crt/stdio/ucrt_vsprintf.c",
}
} }
return sources, nil return sources, nil
}, },
@@ -100,41 +63,27 @@ var libMinGW = Library{
func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob { func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob {
var jobs []*compileJob var jobs []*compileJob
root := goenv.Get("TINYGOROOT") root := goenv.Get("TINYGOROOT")
var libs []string // Normally all the api-ms-win-crt-*.def files are all compiled to a single
if goarch == "386" { // .lib file. But to simplify things, we're going to leave them as separate
libs = []string{ // files.
// x86 uses msvcrt.dll instead of UCRT for compatibility with old for _, name := range []string{
// Windows versions. "kernel32.def.in",
"advapi32.def.in", "api-ms-win-crt-conio-l1-1-0.def",
"kernel32.def.in", "api-ms-win-crt-convert-l1-1-0.def.in",
"msvcrt.def.in", "api-ms-win-crt-environment-l1-1-0.def",
} "api-ms-win-crt-filesystem-l1-1-0.def",
} else { "api-ms-win-crt-heap-l1-1-0.def",
// Use the modernized UCRT on new systems. "api-ms-win-crt-locale-l1-1-0.def",
// Normally all the api-ms-win-crt-*.def files are all compiled to a "api-ms-win-crt-math-l1-1-0.def.in",
// single .lib file. But to simplify things, we're going to leave them "api-ms-win-crt-multibyte-l1-1-0.def",
// as separate files. "api-ms-win-crt-private-l1-1-0.def.in",
libs = []string{ "api-ms-win-crt-process-l1-1-0.def",
"advapi32.def.in", "api-ms-win-crt-runtime-l1-1-0.def.in",
"kernel32.def.in", "api-ms-win-crt-stdio-l1-1-0.def",
"api-ms-win-crt-conio-l1-1-0.def", "api-ms-win-crt-string-l1-1-0.def",
"api-ms-win-crt-convert-l1-1-0.def.in", "api-ms-win-crt-time-l1-1-0.def",
"api-ms-win-crt-environment-l1-1-0.def", "api-ms-win-crt-utility-l1-1-0.def",
"api-ms-win-crt-filesystem-l1-1-0.def", } {
"api-ms-win-crt-heap-l1-1-0.def",
"api-ms-win-crt-locale-l1-1-0.def",
"api-ms-win-crt-math-l1-1-0.def.in",
"api-ms-win-crt-multibyte-l1-1-0.def",
"api-ms-win-crt-private-l1-1-0.def.in",
"api-ms-win-crt-process-l1-1-0.def",
"api-ms-win-crt-runtime-l1-1-0.def.in",
"api-ms-win-crt-stdio-l1-1-0.def",
"api-ms-win-crt-string-l1-1-0.def",
"api-ms-win-crt-time-l1-1-0.def",
"api-ms-win-crt-utility-l1-1-0.def",
}
}
for _, name := range libs {
outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib") outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib")
inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name) inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name)
job := &compileJob{ job := &compileJob{
@@ -144,9 +93,6 @@ func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob {
defpath := inpath defpath := inpath
var archDef, emulation string var archDef, emulation string
switch goarch { switch goarch {
case "386":
archDef = "-DDEF_I386"
emulation = "i386pe"
case "amd64": case "amd64":
archDef = "-DDEF_X64" archDef = "-DDEF_X64"
emulation = "i386pep" emulation = "i386pep"
+31 -48
View File
@@ -12,45 +12,6 @@ import (
"github.com/tinygo-org/tinygo/goenv" "github.com/tinygo-org/tinygo/goenv"
) )
// Create the alltypes.h file from the appropriate alltypes.h.in files.
func buildMuslAllTypes(arch, muslDir, outputBitsDir string) error {
// Create the file alltypes.h.
f, err := os.Create(filepath.Join(outputBitsDir, "alltypes.h"))
if err != nil {
return err
}
infiles := []string{
filepath.Join(muslDir, "arch", arch, "bits", "alltypes.h.in"),
filepath.Join(muslDir, "include", "alltypes.h.in"),
}
for _, infile := range infiles {
data, err := os.ReadFile(infile)
if err != nil {
return err
}
lines := strings.Split(string(data), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "TYPEDEF ") {
matches := regexp.MustCompile(`TYPEDEF (.*) ([^ ]*);`).FindStringSubmatch(line)
value := matches[1]
name := matches[2]
line = fmt.Sprintf("#if defined(__NEED_%s) && !defined(__DEFINED_%s)\ntypedef %s %s;\n#define __DEFINED_%s\n#endif\n", name, name, value, name, name)
}
if strings.HasPrefix(line, "STRUCT ") {
matches := regexp.MustCompile(`STRUCT * ([^ ]*) (.*);`).FindStringSubmatch(line)
name := matches[1]
value := matches[2]
line = fmt.Sprintf("#if defined(__NEED_struct_%s) && !defined(__DEFINED_struct_%s)\nstruct %s %s;\n#define __DEFINED_struct_%s\n#endif\n", name, name, name, value, name)
}
_, err := f.WriteString(line + "\n")
if err != nil {
return err
}
}
}
return f.Close()
}
var libMusl = Library{ var libMusl = Library{
name: "musl", name: "musl",
makeHeaders: func(target, includeDir string) error { makeHeaders: func(target, includeDir string) error {
@@ -63,13 +24,41 @@ var libMusl = Library{
arch := compileopts.MuslArchitecture(target) arch := compileopts.MuslArchitecture(target)
muslDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "musl") muslDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "musl")
err = buildMuslAllTypes(arch, muslDir, bits) // Create the file alltypes.h.
f, err := os.Create(filepath.Join(bits, "alltypes.h"))
if err != nil { if err != nil {
return err return err
} }
infiles := []string{
filepath.Join(muslDir, "arch", arch, "bits", "alltypes.h.in"),
filepath.Join(muslDir, "include", "alltypes.h.in"),
}
for _, infile := range infiles {
data, err := os.ReadFile(infile)
if err != nil {
return err
}
lines := strings.Split(string(data), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "TYPEDEF ") {
matches := regexp.MustCompile(`TYPEDEF (.*) ([^ ]*);`).FindStringSubmatch(line)
value := matches[1]
name := matches[2]
line = fmt.Sprintf("#if defined(__NEED_%s) && !defined(__DEFINED_%s)\ntypedef %s %s;\n#define __DEFINED_%s\n#endif\n", name, name, value, name, name)
}
if strings.HasPrefix(line, "STRUCT ") {
matches := regexp.MustCompile(`STRUCT * ([^ ]*) (.*);`).FindStringSubmatch(line)
name := matches[1]
value := matches[2]
line = fmt.Sprintf("#if defined(__NEED_struct_%s) && !defined(__DEFINED_struct_%s)\nstruct %s %s;\n#define __DEFINED_struct_%s\n#endif\n", name, name, name, value, name)
}
f.WriteString(line + "\n")
}
}
f.Close()
// Create the file syscall.h. // Create the file syscall.h.
f, err := os.Create(filepath.Join(bits, "syscall.h")) f, err = os.Create(filepath.Join(bits, "syscall.h"))
if err != nil { if err != nil {
return err return err
} }
@@ -121,36 +110,30 @@ var libMusl = Library{
return cflags return cflags
}, },
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/musl/src") }, sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/musl/src") },
librarySources: func(target string, _ bool) ([]string, error) { librarySources: func(target string) ([]string, error) {
arch := compileopts.MuslArchitecture(target) arch := compileopts.MuslArchitecture(target)
globs := []string{ globs := []string{
"conf/*.c", "conf/*.c",
"ctype/*.c",
"env/*.c", "env/*.c",
"errno/*.c", "errno/*.c",
"exit/*.c", "exit/*.c",
"fcntl/*.c", "fcntl/*.c",
"internal/defsysinfo.c", "internal/defsysinfo.c",
"internal/intscan.c",
"internal/libc.c", "internal/libc.c",
"internal/shgetc.c",
"internal/syscall_ret.c", "internal/syscall_ret.c",
"internal/vdso.c", "internal/vdso.c",
"legacy/*.c", "legacy/*.c",
"locale/*.c", "locale/*.c",
"linux/*.c", "linux/*.c",
"locale/*.c",
"malloc/*.c", "malloc/*.c",
"malloc/mallocng/*.c", "malloc/mallocng/*.c",
"mman/*.c", "mman/*.c",
"math/*.c", "math/*.c",
"misc/*.c", "misc/*.c",
"multibyte/*.c", "multibyte/*.c",
"sched/*.c",
"signal/" + arch + "/*.s", "signal/" + arch + "/*.s",
"signal/*.c", "signal/*.c",
"stdio/*.c", "stdio/*.c",
"stdlib/*.c",
"string/*.c", "string/*.c",
"thread/" + arch + "/*.s", "thread/" + arch + "/*.s",
"thread/*.c", "thread/*.c",
+1 -1
View File
@@ -43,7 +43,7 @@ var libPicolibc = Library{
} }
}, },
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib") }, sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib") },
librarySources: func(target string, _ bool) ([]string, error) { librarySources: func(target string) ([]string, error) {
sources := append([]string(nil), picolibcSources...) sources := append([]string(nil), picolibcSources...)
if !strings.HasPrefix(target, "avr") { if !strings.HasPrefix(target, "avr") {
// Small chips without long jumps can't compile many files (printf, // Small chips without long jumps can't compile many files (printf,
+2 -2
View File
@@ -490,9 +490,9 @@ func loadProgramSize(path string, packagePathMap map[string]string) (*programSiz
continue continue
} }
if section.Type == elf.SHT_NOBITS { if section.Type == elf.SHT_NOBITS {
if strings.HasPrefix(section.Name, ".stack") { if section.Name == ".stack" || section.Name == ".stack1" {
// TinyGo emits stack sections on microcontroller using the // TinyGo emits stack sections on microcontroller using the
// ".stack" name. // ".stack" (or ".stack1") name.
// This is a bit ugly, but I don't think there is a way to // This is a bit ugly, but I don't think there is a way to
// mark the stack section in a linker script. // mark the stack section in a linker script.
sections = append(sections, memorySection{ sections = append(sections, memorySection{
+3 -3
View File
@@ -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", 4560, 280, 0, 2268},
{"microbit", "examples/serial", 2924, 388, 8, 2272}, {"microbit", "examples/serial", 2908, 388, 8, 2272},
{"wioterminal", "examples/pininterrupt", 7365, 1491, 116, 6912}, {"wioterminal", "examples/pininterrupt", 7293, 1487, 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
-284
View File
@@ -1,284 +0,0 @@
package builder
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/tinygo-org/tinygo/goenv"
)
var libWasiLibc = Library{
name: "wasi-libc",
makeHeaders: func(target, includeDir string) error {
bits := filepath.Join(includeDir, "bits")
err := os.Mkdir(bits, 0777)
if err != nil {
return err
}
muslDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "wasi-libc/libc-top-half/musl")
err = buildMuslAllTypes("wasm32", muslDir, bits)
if err != nil {
return err
}
// See MUSL_OMIT_HEADERS in the Makefile.
omitHeaders := map[string]struct{}{
"syslog.h": {},
"wait.h": {},
"ucontext.h": {},
"paths.h": {},
"utmp.h": {},
"utmpx.h": {},
"lastlog.h": {},
"elf.h": {},
"link.h": {},
"pwd.h": {},
"shadow.h": {},
"grp.h": {},
"mntent.h": {},
"netdb.h": {},
"resolv.h": {},
"pty.h": {},
"dlfcn.h": {},
"setjmp.h": {},
"ulimit.h": {},
"wordexp.h": {},
"spawn.h": {},
"termios.h": {},
"libintl.h": {},
"aio.h": {},
"stdarg.h": {},
"stddef.h": {},
"pthread.h": {},
}
for _, glob := range [][2]string{
{"libc-bottom-half/headers/public/*.h", ""},
{"libc-bottom-half/headers/public/wasi/*.h", "wasi"},
{"libc-top-half/musl/arch/wasm32/bits/*.h", "bits"},
{"libc-top-half/musl/include/*.h", ""},
{"libc-top-half/musl/include/netinet/*.h", "netinet"},
{"libc-top-half/musl/include/sys/*.h", "sys"},
} {
matches, _ := filepath.Glob(filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc", glob[0]))
outDir := filepath.Join(includeDir, glob[1])
os.MkdirAll(outDir, 0o777)
for _, match := range matches {
name := filepath.Base(match)
if _, ok := omitHeaders[name]; ok {
continue
}
data, err := os.ReadFile(match)
if err != nil {
return err
}
err = os.WriteFile(filepath.Join(outDir, name), data, 0o666)
if err != nil {
return err
}
}
}
return nil
},
cflags: func(target, headerPath string) []string {
libcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc")
return []string{
"-Werror",
"-Wall",
"-std=gnu11",
"-nostdlibinc",
"-mnontrapping-fptoint", "-msign-ext", "-mbulk-memory",
"-Wno-null-pointer-arithmetic", "-Wno-unused-parameter", "-Wno-sign-compare", "-Wno-unused-variable", "-Wno-unused-function", "-Wno-ignored-attributes", "-Wno-missing-braces", "-Wno-ignored-pragmas", "-Wno-unused-but-set-variable", "-Wno-unknown-warning-option",
"-Wno-parentheses", "-Wno-shift-op-parentheses", "-Wno-bitwise-op-parentheses", "-Wno-logical-op-parentheses", "-Wno-string-plus-int", "-Wno-dangling-else", "-Wno-unknown-pragmas",
"-DNDEBUG",
"-D__wasilibc_printscan_no_long_double",
"-D__wasilibc_printscan_full_support_option=\"long double support is disabled\"",
"-DBULK_MEMORY_THRESHOLD=32", // default threshold in wasi-libc
"-isystem", headerPath,
"-I" + libcDir + "/libc-top-half/musl/src/include",
"-I" + libcDir + "/libc-top-half/musl/src/internal",
"-I" + libcDir + "/libc-top-half/musl/arch/wasm32",
"-I" + libcDir + "/libc-top-half/musl/arch/generic",
"-I" + libcDir + "/libc-top-half/headers/private",
}
},
cflagsForFile: func(path string) []string {
if strings.HasPrefix(path, "libc-bottom-half"+string(os.PathSeparator)) {
libcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc")
return []string{
"-I" + libcDir + "/libc-bottom-half/headers/private",
"-I" + libcDir + "/libc-bottom-half/cloudlibc/src/include",
"-I" + libcDir + "/libc-bottom-half/cloudlibc/src",
}
}
return nil
},
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc") },
librarySources: func(target string, libcNeedsMalloc bool) ([]string, error) {
type filePattern struct {
glob string
exclude []string
}
// See: LIBC_TOP_HALF_MUSL_SOURCES in the Makefile
globs := []filePattern{
// Top half: mostly musl sources.
{glob: "libc-top-half/sources/*.c"},
{glob: "libc-top-half/musl/src/conf/*.c"},
{glob: "libc-top-half/musl/src/internal/*.c", exclude: []string{
"procfdname.c", "syscall.c", "syscall_ret.c", "vdso.c", "version.c",
}},
{glob: "libc-top-half/musl/src/locale/*.c", exclude: []string{
"dcngettext.c", "textdomain.c", "bind_textdomain_codeset.c"}},
{glob: "libc-top-half/musl/src/math/*.c", exclude: []string{
"__signbit.c", "__signbitf.c", "__signbitl.c",
"__fpclassify.c", "__fpclassifyf.c", "__fpclassifyl.c",
"ceilf.c", "ceil.c",
"floorf.c", "floor.c",
"truncf.c", "trunc.c",
"rintf.c", "rint.c",
"nearbyintf.c", "nearbyint.c",
"sqrtf.c", "sqrt.c",
"fabsf.c", "fabs.c",
"copysignf.c", "copysign.c",
"fminf.c", "fmaxf.c",
"fmin.c", "fmax.c,",
}},
{glob: "libc-top-half/musl/src/multibyte/*.c"},
{glob: "libc-top-half/musl/src/stdio/*.c", exclude: []string{
"vfwscanf.c", "vfwprintf.c", // long double is unsupported
"__lockfile.c", "flockfile.c", "funlockfile.c", "ftrylockfile.c",
"rename.c",
"tmpnam.c", "tmpfile.c", "tempnam.c",
"popen.c", "pclose.c",
"remove.c",
"gets.c"}},
{glob: "libc-top-half/musl/src/stdlib/*.c"},
{glob: "libc-top-half/musl/src/string/*.c", exclude: []string{
"strsignal.c"}},
// Bottom half: connect top half to WASI equivalents.
{glob: "libc-bottom-half/cloudlibc/src/libc/*/*.c"},
{glob: "libc-bottom-half/cloudlibc/src/libc/sys/*/*.c"},
{glob: "libc-bottom-half/sources/*.c"},
}
// We're using the Boehm GC, so we need a heap implementation in the libc.
if libcNeedsMalloc {
globs = append(globs, filePattern{glob: "dlmalloc/src/dlmalloc.c"})
}
// See: LIBC_TOP_HALF_MUSL_SOURCES in the Makefile
sources := []string{
"libc-top-half/musl/src/misc/a64l.c",
"libc-top-half/musl/src/misc/basename.c",
"libc-top-half/musl/src/misc/dirname.c",
"libc-top-half/musl/src/misc/ffs.c",
"libc-top-half/musl/src/misc/ffsl.c",
"libc-top-half/musl/src/misc/ffsll.c",
"libc-top-half/musl/src/misc/fmtmsg.c",
"libc-top-half/musl/src/misc/getdomainname.c",
"libc-top-half/musl/src/misc/gethostid.c",
"libc-top-half/musl/src/misc/getopt.c",
"libc-top-half/musl/src/misc/getopt_long.c",
"libc-top-half/musl/src/misc/getsubopt.c",
"libc-top-half/musl/src/misc/uname.c",
"libc-top-half/musl/src/misc/nftw.c",
"libc-top-half/musl/src/errno/strerror.c",
"libc-top-half/musl/src/network/htonl.c",
"libc-top-half/musl/src/network/htons.c",
"libc-top-half/musl/src/network/ntohl.c",
"libc-top-half/musl/src/network/ntohs.c",
"libc-top-half/musl/src/network/inet_ntop.c",
"libc-top-half/musl/src/network/inet_pton.c",
"libc-top-half/musl/src/network/inet_aton.c",
"libc-top-half/musl/src/network/in6addr_any.c",
"libc-top-half/musl/src/network/in6addr_loopback.c",
"libc-top-half/musl/src/fenv/fenv.c",
"libc-top-half/musl/src/fenv/fesetround.c",
"libc-top-half/musl/src/fenv/feupdateenv.c",
"libc-top-half/musl/src/fenv/fesetexceptflag.c",
"libc-top-half/musl/src/fenv/fegetexceptflag.c",
"libc-top-half/musl/src/fenv/feholdexcept.c",
"libc-top-half/musl/src/exit/exit.c",
"libc-top-half/musl/src/exit/atexit.c",
"libc-top-half/musl/src/exit/assert.c",
"libc-top-half/musl/src/exit/quick_exit.c",
"libc-top-half/musl/src/exit/at_quick_exit.c",
"libc-top-half/musl/src/time/strftime.c",
"libc-top-half/musl/src/time/asctime.c",
"libc-top-half/musl/src/time/asctime_r.c",
"libc-top-half/musl/src/time/ctime.c",
"libc-top-half/musl/src/time/ctime_r.c",
"libc-top-half/musl/src/time/wcsftime.c",
"libc-top-half/musl/src/time/strptime.c",
"libc-top-half/musl/src/time/difftime.c",
"libc-top-half/musl/src/time/timegm.c",
"libc-top-half/musl/src/time/ftime.c",
"libc-top-half/musl/src/time/gmtime.c",
"libc-top-half/musl/src/time/gmtime_r.c",
"libc-top-half/musl/src/time/timespec_get.c",
"libc-top-half/musl/src/time/getdate.c",
"libc-top-half/musl/src/time/localtime.c",
"libc-top-half/musl/src/time/localtime_r.c",
"libc-top-half/musl/src/time/mktime.c",
"libc-top-half/musl/src/time/__tm_to_secs.c",
"libc-top-half/musl/src/time/__month_to_secs.c",
"libc-top-half/musl/src/time/__secs_to_tm.c",
"libc-top-half/musl/src/time/__year_to_secs.c",
"libc-top-half/musl/src/time/__tz.c",
"libc-top-half/musl/src/fcntl/creat.c",
"libc-top-half/musl/src/dirent/alphasort.c",
"libc-top-half/musl/src/dirent/versionsort.c",
"libc-top-half/musl/src/env/__stack_chk_fail.c",
"libc-top-half/musl/src/env/clearenv.c",
"libc-top-half/musl/src/env/getenv.c",
"libc-top-half/musl/src/env/putenv.c",
"libc-top-half/musl/src/env/setenv.c",
"libc-top-half/musl/src/env/unsetenv.c",
"libc-top-half/musl/src/unistd/posix_close.c",
"libc-top-half/musl/src/stat/futimesat.c",
"libc-top-half/musl/src/legacy/getpagesize.c",
"libc-top-half/musl/src/thread/thrd_sleep.c",
}
basepath := goenv.Get("TINYGOROOT") + "/lib/wasi-libc/"
for _, pattern := range globs {
matches, err := filepath.Glob(basepath + pattern.glob)
if err != nil {
// From the documentation:
// > Glob ignores file system errors such as I/O errors reading
// > directories. The only possible returned error is
// > ErrBadPattern, when pattern is malformed.
// So the only possible error is when the (statically defined)
// pattern is wrong. In other words, a programming bug.
return nil, fmt.Errorf("wasi-libc: could not glob source dirs: %w", err)
}
if len(matches) == 0 {
return nil, fmt.Errorf("wasi-libc: did not find any files for pattern %#v", pattern)
}
excludeSet := map[string]struct{}{}
for _, exclude := range pattern.exclude {
excludeSet[exclude] = struct{}{}
}
for _, match := range matches {
if _, ok := excludeSet[filepath.Base(match)]; ok {
continue
}
relpath, err := filepath.Rel(basepath, match)
if err != nil {
// Not sure if this is even possible.
return nil, err
}
sources = append(sources, relpath)
}
}
return sources, nil
},
}
+1 -3
View File
@@ -29,8 +29,6 @@ var libWasmBuiltins = Library{
"-Wall", "-Wall",
"-std=gnu11", "-std=gnu11",
"-nostdlibinc", "-nostdlibinc",
"-mnontrapping-fptoint", // match wasm-unknown (default on in LLVM 20)
"-mno-bulk-memory", // same here
"-isystem", libcDir + "/libc-top-half/musl/arch/wasm32", "-isystem", libcDir + "/libc-top-half/musl/arch/wasm32",
"-isystem", libcDir + "/libc-top-half/musl/arch/generic", "-isystem", libcDir + "/libc-top-half/musl/arch/generic",
"-isystem", libcDir + "/libc-top-half/musl/src/internal", "-isystem", libcDir + "/libc-top-half/musl/src/internal",
@@ -41,7 +39,7 @@ var libWasmBuiltins = Library{
} }
}, },
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc") }, sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc") },
librarySources: func(target string, _ bool) ([]string, error) { librarySources: func(target string) ([]string, error) {
return []string{ return []string{
// memory builtins needed for llvm.memcpy.*, llvm.memmove.*, and // memory builtins needed for llvm.memcpy.*, llvm.memmove.*, and
// llvm.memset.* LLVM intrinsics. // llvm.memset.* LLVM intrinsics.
+64 -45
View File
@@ -92,18 +92,18 @@ type noescapingFunc struct {
// cgoAliases list type aliases between Go and C, for types that are equivalent // cgoAliases list type aliases between Go and C, for types that are equivalent
// in both languages. See addTypeAliases. // in both languages. See addTypeAliases.
var cgoAliases = map[string]string{ var cgoAliases = map[string]string{
"_Cgo_int8_t": "int8", "C.int8_t": "int8",
"_Cgo_int16_t": "int16", "C.int16_t": "int16",
"_Cgo_int32_t": "int32", "C.int32_t": "int32",
"_Cgo_int64_t": "int64", "C.int64_t": "int64",
"_Cgo_uint8_t": "uint8", "C.uint8_t": "uint8",
"_Cgo_uint16_t": "uint16", "C.uint16_t": "uint16",
"_Cgo_uint32_t": "uint32", "C.uint32_t": "uint32",
"_Cgo_uint64_t": "uint64", "C.uint64_t": "uint64",
"_Cgo_uintptr_t": "uintptr", "C.uintptr_t": "uintptr",
"_Cgo_float": "float32", "C.float": "float32",
"_Cgo_double": "float64", "C.double": "float64",
"_Cgo__Bool": "bool", "C._Bool": "bool",
} }
// builtinAliases are handled specially because they only exist on the Go side // builtinAliases are handled specially because they only exist on the Go side
@@ -145,46 +145,48 @@ typedef unsigned long long _Cgo_ulonglong;
// The string/bytes functions below implement C.CString etc. To make sure the // The string/bytes functions below implement C.CString etc. To make sure the
// runtime doesn't need to know the C int type, lengths are converted to uintptr // runtime doesn't need to know the C int type, lengths are converted to uintptr
// first. // first.
// These functions will be modified to get a "C." prefix, so the source below
// doesn't reflect the final AST.
const generatedGoFilePrefixBase = ` const generatedGoFilePrefixBase = `
import "syscall" import "syscall"
import "unsafe" import "unsafe"
var _ unsafe.Pointer var _ unsafe.Pointer
//go:linkname _Cgo_CString runtime.cgo_CString //go:linkname C.CString runtime.cgo_CString
func _Cgo_CString(string) *_Cgo_char func CString(string) *C.char
//go:linkname _Cgo_GoString runtime.cgo_GoString //go:linkname C.GoString runtime.cgo_GoString
func _Cgo_GoString(*_Cgo_char) string func GoString(*C.char) string
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN //go:linkname C.__GoStringN runtime.cgo_GoStringN
func _Cgo___GoStringN(*_Cgo_char, uintptr) string func __GoStringN(*C.char, uintptr) string
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { func GoStringN(cstr *C.char, length C.int) string {
return _Cgo___GoStringN(cstr, uintptr(length)) return C.__GoStringN(cstr, uintptr(length))
} }
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes //go:linkname C.__GoBytes runtime.cgo_GoBytes
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte func __GoBytes(unsafe.Pointer, uintptr) []byte
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { func GoBytes(ptr unsafe.Pointer, length C.int) []byte {
return _Cgo___GoBytes(ptr, uintptr(length)) return C.__GoBytes(ptr, uintptr(length))
} }
//go:linkname _Cgo___CBytes runtime.cgo_CBytes //go:linkname C.__CBytes runtime.cgo_CBytes
func _Cgo___CBytes([]byte) unsafe.Pointer func __CBytes([]byte) unsafe.Pointer
func _Cgo_CBytes(b []byte) unsafe.Pointer { func CBytes(b []byte) unsafe.Pointer {
return _Cgo___CBytes(b) return C.__CBytes(b)
} }
//go:linkname _Cgo___get_errno_num runtime.cgo_errno //go:linkname C.__get_errno_num runtime.cgo_errno
func _Cgo___get_errno_num() uintptr func __get_errno_num() uintptr
` `
const generatedGoFilePrefixOther = generatedGoFilePrefixBase + ` const generatedGoFilePrefixOther = generatedGoFilePrefixBase + `
func _Cgo___get_errno() error { func __get_errno() error {
return syscall.Errno(_Cgo___get_errno_num()) return syscall.Errno(C.__get_errno_num())
} }
` `
@@ -195,7 +197,7 @@ func _Cgo___get_errno() error {
// map the errno values to match the values in the syscall package. // map the errno values to match the values in the syscall package.
// Source of the errno values: lib/mingw-w64/mingw-w64-headers/crt/errno.h // Source of the errno values: lib/mingw-w64/mingw-w64-headers/crt/errno.h
const generatedGoFilePrefixWindows = generatedGoFilePrefixBase + ` const generatedGoFilePrefixWindows = generatedGoFilePrefixBase + `
var _Cgo___errno_mapping = [...]syscall.Errno{ var __errno_mapping = [...]syscall.Errno{
1: syscall.EPERM, 1: syscall.EPERM,
2: syscall.ENOENT, 2: syscall.ENOENT,
3: syscall.ESRCH, 3: syscall.ESRCH,
@@ -236,10 +238,10 @@ var _Cgo___errno_mapping = [...]syscall.Errno{
42: syscall.EILSEQ, 42: syscall.EILSEQ,
} }
func _Cgo___get_errno() error { func __get_errno() error {
num := _Cgo___get_errno_num() num := C.__get_errno_num()
if num < uintptr(len(_Cgo___errno_mapping)) { if num < uintptr(len(__errno_mapping)) {
if mapped := _Cgo___errno_mapping[num]; mapped != 0 { if mapped := __errno_mapping[num]; mapped != 0 {
return mapped return mapped
} }
} }
@@ -302,6 +304,23 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
// If the Comments field is not set to nil, the go/format package will get // If the Comments field is not set to nil, the go/format package will get
// confused about where comments should go. // confused about where comments should go.
p.generated.Comments = nil p.generated.Comments = nil
// Adjust some of the functions in there.
for _, decl := range p.generated.Decls {
switch decl := decl.(type) {
case *ast.FuncDecl:
switch decl.Name.Name {
case "CString", "GoString", "GoStringN", "__GoStringN", "GoBytes", "__GoBytes", "CBytes", "__CBytes", "__get_errno_num", "__get_errno", "__errno_mapping":
// Adjust the name to have a "C." prefix so it is correctly
// resolved.
decl.Name.Name = "C." + decl.Name.Name
}
}
}
// Patch some types, for example *C.char in C.CString.
cf := p.newCGoFile(nil, -1) // dummy *cgoFile for the walker
astutil.Apply(p.generated, func(cursor *astutil.Cursor) bool {
return cf.walker(cursor, nil)
}, nil)
// Find `import "C"` C fragments in the file. // Find `import "C"` C fragments in the file.
p.cgoHeaders = make([]string, len(files)) // combined CGo header fragment for each file p.cgoHeaders = make([]string, len(files)) // combined CGo header fragment for each file
@@ -380,7 +399,7 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
Tok: token.TYPE, Tok: token.TYPE,
} }
for _, name := range builtinAliases { for _, name := range builtinAliases {
typeSpec := p.getIntegerType("_Cgo_"+name, names["_Cgo_"+name]) typeSpec := p.getIntegerType("C."+name, names["_Cgo_"+name])
gen.Specs = append(gen.Specs, typeSpec) gen.Specs = append(gen.Specs, typeSpec)
} }
p.generated.Decls = append(p.generated.Decls, gen) p.generated.Decls = append(p.generated.Decls, gen)
@@ -1253,7 +1272,7 @@ func (p *cgoPackage) getUnnamedDeclName(prefix string, itf interface{}) string {
func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) string { func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) string {
// Some types are defined in stdint.h and map directly to a particular Go // Some types are defined in stdint.h and map directly to a particular Go
// type. // type.
if alias := cgoAliases["_Cgo_"+name]; alias != "" { if alias := cgoAliases["C."+name]; alias != "" {
return alias return alias
} }
node := f.getASTDeclNode(name, found) node := f.getASTDeclNode(name, found)
@@ -1263,7 +1282,7 @@ func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) st
} }
return node.Name.Name return node.Name.Name
} }
return "_Cgo_" + name return "C." + name
} }
// getASTDeclNode will declare the given C AST node (if not already defined) and // getASTDeclNode will declare the given C AST node (if not already defined) and
@@ -1363,8 +1382,8 @@ extern __typeof(%s) %s __attribute__((alias(%#v)));
case *elaboratedTypeInfo: case *elaboratedTypeInfo:
// Add struct bitfields. // Add struct bitfields.
for _, bitfield := range elaboratedType.bitfields { for _, bitfield := range elaboratedType.bitfields {
f.createBitfieldGetter(bitfield, "_Cgo_"+name) f.createBitfieldGetter(bitfield, "C."+name)
f.createBitfieldSetter(bitfield, "_Cgo_"+name) f.createBitfieldSetter(bitfield, "C."+name)
} }
if elaboratedType.unionSize != 0 { if elaboratedType.unionSize != 0 {
// Create union getters/setters. // Create union getters/setters.
@@ -1373,7 +1392,7 @@ extern __typeof(%s) %s __attribute__((alias(%#v)));
f.addError(elaboratedType.pos, fmt.Sprintf("union must have field with a single name, it has %d names", len(field.Names))) f.addError(elaboratedType.pos, fmt.Sprintf("union must have field with a single name, it has %d names", len(field.Names)))
continue continue
} }
f.createUnionAccessor(field, "_Cgo_"+name) f.createUnionAccessor(field, "C."+name)
} }
} }
} }
@@ -1422,7 +1441,7 @@ func (f *cgoFile) walker(cursor *astutil.Cursor, names map[string]clangCursor) b
node.Rhs = append(node.Rhs, &ast.CallExpr{ node.Rhs = append(node.Rhs, &ast.CallExpr{
Fun: &ast.Ident{ Fun: &ast.Ident{
NamePos: node.Lhs[1].End(), NamePos: node.Lhs[1].End(),
Name: "_Cgo___get_errno", Name: "C.__get_errno",
}, },
}) })
} }
@@ -1447,7 +1466,7 @@ func (f *cgoFile) walker(cursor *astutil.Cursor, names map[string]clangCursor) b
return true return true
} }
if x.Name == "C" { if x.Name == "C" {
name := "_Cgo_" + node.Sel.Name name := "C." + node.Sel.Name
if found, ok := names[node.Sel.Name]; ok { if found, ok := names[node.Sel.Name]; ok {
name = f.getASTDeclName(node.Sel.Name, found, false) name = f.getASTDeclName(node.Sel.Name, found, false)
} }
+28 -28
View File
@@ -71,7 +71,7 @@ unsigned tinygo_clang_Cursor_isMacroFunctionLike(GoCXCursor c);
// libclang.go:68:5: note: previous declaration is here // libclang.go:68:5: note: previous declaration is here
// See: https://github.com/golang/go/issues/49721 // See: https://github.com/golang/go/issues/49721
#if defined(_WIN32) #if defined(_WIN32)
#define CGO_DECL __declspec(dllexport) #define CGO_DECL // __declspec(dllexport)
#else #else
#define CGO_DECL #define CGO_DECL
#endif #endif
@@ -219,7 +219,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
numArgs := int(C.tinygo_clang_Cursor_getNumArguments(c)) numArgs := int(C.tinygo_clang_Cursor_getNumArguments(c))
obj := &ast.Object{ obj := &ast.Object{
Kind: ast.Fun, Kind: ast.Fun,
Name: "_Cgo_" + name, Name: "C." + name,
} }
exportName := name exportName := name
localName := name localName := name
@@ -257,7 +257,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
}, },
Name: &ast.Ident{ Name: &ast.Ident{
NamePos: pos, NamePos: pos,
Name: "_Cgo_" + localName, Name: "C." + localName,
Obj: obj, Obj: obj,
}, },
Type: &ast.FuncType{ Type: &ast.FuncType{
@@ -319,7 +319,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
return decl, stringSignature return decl, stringSignature
case C.CXCursor_StructDecl, C.CXCursor_UnionDecl: case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
typ := f.makeASTRecordType(c, pos) typ := f.makeASTRecordType(c, pos)
typeName := "_Cgo_" + name typeName := "C." + name
typeExpr := typ.typeExpr typeExpr := typ.typeExpr
if typ.unionSize != 0 { if typ.unionSize != 0 {
// Convert to a single-field struct type. // Convert to a single-field struct type.
@@ -340,7 +340,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
obj.Decl = typeSpec obj.Decl = typeSpec
return typeSpec, typ return typeSpec, typ
case C.CXCursor_TypedefDecl: case C.CXCursor_TypedefDecl:
typeName := "_Cgo_" + name typeName := "C." + name
underlyingType := C.tinygo_clang_getTypedefDeclUnderlyingType(c) underlyingType := C.tinygo_clang_getTypedefDeclUnderlyingType(c)
obj := &ast.Object{ obj := &ast.Object{
Kind: ast.Typ, Kind: ast.Typ,
@@ -378,12 +378,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
} }
obj := &ast.Object{ obj := &ast.Object{
Kind: ast.Var, Kind: ast.Var,
Name: "_Cgo_" + name, Name: "C." + name,
} }
valueSpec := &ast.ValueSpec{ valueSpec := &ast.ValueSpec{
Names: []*ast.Ident{{ Names: []*ast.Ident{{
NamePos: pos, NamePos: pos,
Name: "_Cgo_" + name, Name: "C." + name,
Obj: obj, Obj: obj,
}}, }},
Type: typeExpr, Type: typeExpr,
@@ -407,12 +407,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
} }
obj := &ast.Object{ obj := &ast.Object{
Kind: ast.Con, Kind: ast.Con,
Name: "_Cgo_" + name, Name: "C." + name,
} }
valueSpec := &ast.ValueSpec{ valueSpec := &ast.ValueSpec{
Names: []*ast.Ident{{ Names: []*ast.Ident{{
NamePos: pos, NamePos: pos,
Name: "_Cgo_" + name, Name: "C." + name,
Obj: obj, Obj: obj,
}}, }},
Values: []ast.Expr{expr}, Values: []ast.Expr{expr},
@@ -423,7 +423,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
case C.CXCursor_EnumDecl: case C.CXCursor_EnumDecl:
obj := &ast.Object{ obj := &ast.Object{
Kind: ast.Typ, Kind: ast.Typ,
Name: "_Cgo_" + name, Name: "C." + name,
} }
underlying := C.tinygo_clang_getEnumDeclIntegerType(c) underlying := C.tinygo_clang_getEnumDeclIntegerType(c)
// TODO: gc's CGo implementation uses types such as `uint32` for enums // TODO: gc's CGo implementation uses types such as `uint32` for enums
@@ -431,7 +431,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
typeSpec := &ast.TypeSpec{ typeSpec := &ast.TypeSpec{
Name: &ast.Ident{ Name: &ast.Ident{
NamePos: pos, NamePos: pos,
Name: "_Cgo_" + name, Name: "C." + name,
Obj: obj, Obj: obj,
}, },
Assign: pos, Assign: pos,
@@ -454,12 +454,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
} }
obj := &ast.Object{ obj := &ast.Object{
Kind: ast.Con, Kind: ast.Con,
Name: "_Cgo_" + name, Name: "C." + name,
} }
valueSpec := &ast.ValueSpec{ valueSpec := &ast.ValueSpec{
Names: []*ast.Ident{{ Names: []*ast.Ident{{
NamePos: pos, NamePos: pos,
Name: "_Cgo_" + name, Name: "C." + name,
Obj: obj, Obj: obj,
}}, }},
Values: []ast.Expr{expr}, Values: []ast.Expr{expr},
@@ -745,27 +745,27 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr {
var typeName string var typeName string
switch typ.kind { switch typ.kind {
case C.CXType_Char_S, C.CXType_Char_U: case C.CXType_Char_S, C.CXType_Char_U:
typeName = "_Cgo_char" typeName = "C.char"
case C.CXType_SChar: case C.CXType_SChar:
typeName = "_Cgo_schar" typeName = "C.schar"
case C.CXType_UChar: case C.CXType_UChar:
typeName = "_Cgo_uchar" typeName = "C.uchar"
case C.CXType_Short: case C.CXType_Short:
typeName = "_Cgo_short" typeName = "C.short"
case C.CXType_UShort: case C.CXType_UShort:
typeName = "_Cgo_ushort" typeName = "C.ushort"
case C.CXType_Int: case C.CXType_Int:
typeName = "_Cgo_int" typeName = "C.int"
case C.CXType_UInt: case C.CXType_UInt:
typeName = "_Cgo_uint" typeName = "C.uint"
case C.CXType_Long: case C.CXType_Long:
typeName = "_Cgo_long" typeName = "C.long"
case C.CXType_ULong: case C.CXType_ULong:
typeName = "_Cgo_ulong" typeName = "C.ulong"
case C.CXType_LongLong: case C.CXType_LongLong:
typeName = "_Cgo_longlong" typeName = "C.longlong"
case C.CXType_ULongLong: case C.CXType_ULongLong:
typeName = "_Cgo_ulonglong" typeName = "C.ulonglong"
case C.CXType_Bool: case C.CXType_Bool:
typeName = "bool" typeName = "bool"
case C.CXType_Float, C.CXType_Double, C.CXType_LongDouble: case C.CXType_Float, C.CXType_Double, C.CXType_LongDouble:
@@ -896,7 +896,7 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr {
typeSpelling := getString(C.clang_getTypeSpelling(typ)) typeSpelling := getString(C.clang_getTypeSpelling(typ))
typeKindSpelling := getString(C.clang_getTypeKindSpelling(typ.kind)) typeKindSpelling := getString(C.clang_getTypeKindSpelling(typ.kind))
f.addError(pos, fmt.Sprintf("unknown C type: %v (libclang type kind %s)", typeSpelling, typeKindSpelling)) f.addError(pos, fmt.Sprintf("unknown C type: %v (libclang type kind %s)", typeSpelling, typeKindSpelling))
typeName = "_Cgo_<unknown>" typeName = "C.<unknown>"
} }
return &ast.Ident{ return &ast.Ident{
NamePos: pos, NamePos: pos,
@@ -913,7 +913,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
var goName string var goName string
typeSize := C.clang_Type_getSizeOf(underlyingType) typeSize := C.clang_Type_getSizeOf(underlyingType)
switch name { switch name {
case "_Cgo_char": case "C.char":
if typeSize != 1 { if typeSize != 1 {
// This happens for some very special purpose architectures // This happens for some very special purpose architectures
// (DSPs etc.) that are not currently targeted. // (DSPs etc.) that are not currently targeted.
@@ -926,7 +926,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
case C.CXType_Char_U: case C.CXType_Char_U:
goName = "uint8" goName = "uint8"
} }
case "_Cgo_schar", "_Cgo_short", "_Cgo_int", "_Cgo_long", "_Cgo_longlong": case "C.schar", "C.short", "C.int", "C.long", "C.longlong":
switch typeSize { switch typeSize {
case 1: case 1:
goName = "int8" goName = "int8"
@@ -937,7 +937,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
case 8: case 8:
goName = "int64" goName = "int64"
} }
case "_Cgo_uchar", "_Cgo_ushort", "_Cgo_uint", "_Cgo_ulong", "_Cgo_ulonglong": case "C.uchar", "C.ushort", "C.uint", "C.ulong", "C.ulonglong":
switch typeSize { switch typeSize {
case 1: case 1:
goName = "uint8" goName = "uint8"
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build !byollvm && llvm19 //go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18
package cgo package cgo
-15
View File
@@ -1,15 +0,0 @@
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19
package cgo
/*
#cgo linux CFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -I/usr/lib/llvm-20/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@20/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@20/include
#cgo freebsd CFLAGS: -I/usr/local/llvm20/include
#cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@20/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm20/lib -lclang
*/
import "C"
+31 -31
View File
@@ -5,50 +5,50 @@ import "unsafe"
var _ unsafe.Pointer var _ unsafe.Pointer
//go:linkname _Cgo_CString runtime.cgo_CString //go:linkname C.CString runtime.cgo_CString
func _Cgo_CString(string) *_Cgo_char func C.CString(string) *C.char
//go:linkname _Cgo_GoString runtime.cgo_GoString //go:linkname C.GoString runtime.cgo_GoString
func _Cgo_GoString(*_Cgo_char) string func C.GoString(*C.char) string
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN //go:linkname C.__GoStringN runtime.cgo_GoStringN
func _Cgo___GoStringN(*_Cgo_char, uintptr) string func C.__GoStringN(*C.char, uintptr) string
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { func C.GoStringN(cstr *C.char, length C.int) string {
return _Cgo___GoStringN(cstr, uintptr(length)) return C.__GoStringN(cstr, uintptr(length))
} }
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes //go:linkname C.__GoBytes runtime.cgo_GoBytes
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte func C.__GoBytes(unsafe.Pointer, uintptr) []byte
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
return _Cgo___GoBytes(ptr, uintptr(length)) return C.__GoBytes(ptr, uintptr(length))
} }
//go:linkname _Cgo___CBytes runtime.cgo_CBytes //go:linkname C.__CBytes runtime.cgo_CBytes
func _Cgo___CBytes([]byte) unsafe.Pointer func C.__CBytes([]byte) unsafe.Pointer
func _Cgo_CBytes(b []byte) unsafe.Pointer { func C.CBytes(b []byte) unsafe.Pointer {
return _Cgo___CBytes(b) return C.__CBytes(b)
} }
//go:linkname _Cgo___get_errno_num runtime.cgo_errno //go:linkname C.__get_errno_num runtime.cgo_errno
func _Cgo___get_errno_num() uintptr func C.__get_errno_num() uintptr
func _Cgo___get_errno() error { func C.__get_errno() error {
return syscall.Errno(_Cgo___get_errno_num()) return syscall.Errno(C.__get_errno_num())
} }
type ( type (
_Cgo_char uint8 C.char uint8
_Cgo_schar int8 C.schar int8
_Cgo_uchar uint8 C.uchar uint8
_Cgo_short int16 C.short int16
_Cgo_ushort uint16 C.ushort uint16
_Cgo_int int32 C.int int32
_Cgo_uint uint32 C.uint uint32
_Cgo_long int32 C.long int32
_Cgo_ulong uint32 C.ulong uint32
_Cgo_longlong int64 C.longlong int64
_Cgo_ulonglong uint64 C.ulonglong uint64
) )
+38 -38
View File
@@ -5,58 +5,58 @@ import "unsafe"
var _ unsafe.Pointer var _ unsafe.Pointer
//go:linkname _Cgo_CString runtime.cgo_CString //go:linkname C.CString runtime.cgo_CString
func _Cgo_CString(string) *_Cgo_char func C.CString(string) *C.char
//go:linkname _Cgo_GoString runtime.cgo_GoString //go:linkname C.GoString runtime.cgo_GoString
func _Cgo_GoString(*_Cgo_char) string func C.GoString(*C.char) string
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN //go:linkname C.__GoStringN runtime.cgo_GoStringN
func _Cgo___GoStringN(*_Cgo_char, uintptr) string func C.__GoStringN(*C.char, uintptr) string
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { func C.GoStringN(cstr *C.char, length C.int) string {
return _Cgo___GoStringN(cstr, uintptr(length)) return C.__GoStringN(cstr, uintptr(length))
} }
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes //go:linkname C.__GoBytes runtime.cgo_GoBytes
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte func C.__GoBytes(unsafe.Pointer, uintptr) []byte
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
return _Cgo___GoBytes(ptr, uintptr(length)) return C.__GoBytes(ptr, uintptr(length))
} }
//go:linkname _Cgo___CBytes runtime.cgo_CBytes //go:linkname C.__CBytes runtime.cgo_CBytes
func _Cgo___CBytes([]byte) unsafe.Pointer func C.__CBytes([]byte) unsafe.Pointer
func _Cgo_CBytes(b []byte) unsafe.Pointer { func C.CBytes(b []byte) unsafe.Pointer {
return _Cgo___CBytes(b) return C.__CBytes(b)
} }
//go:linkname _Cgo___get_errno_num runtime.cgo_errno //go:linkname C.__get_errno_num runtime.cgo_errno
func _Cgo___get_errno_num() uintptr func C.__get_errno_num() uintptr
func _Cgo___get_errno() error { func C.__get_errno() error {
return syscall.Errno(_Cgo___get_errno_num()) return syscall.Errno(C.__get_errno_num())
} }
type ( type (
_Cgo_char uint8 C.char uint8
_Cgo_schar int8 C.schar int8
_Cgo_uchar uint8 C.uchar uint8
_Cgo_short int16 C.short int16
_Cgo_ushort uint16 C.ushort uint16
_Cgo_int int32 C.int int32
_Cgo_uint uint32 C.uint uint32
_Cgo_long int32 C.long int32
_Cgo_ulong uint32 C.ulong uint32
_Cgo_longlong int64 C.longlong int64
_Cgo_ulonglong uint64 C.ulonglong uint64
) )
const _Cgo_foo = 3 const C.foo = 3
const _Cgo_bar = _Cgo_foo const C.bar = C.foo
const _Cgo_unreferenced = 4 const C.unreferenced = 4
const _Cgo_referenced = _Cgo_unreferenced const C.referenced = C.unreferenced
const _Cgo_fnlike_val = 5 const C.fnlike_val = 5
const _Cgo_square_val = (20 * 20) const C.square_val = (20 * 20)
const _Cgo_add_val = (3 + 5) const C.add_val = (3 + 5)
+46 -46
View File
@@ -14,16 +14,16 @@
// testdata/errors.go:3:1: function "unusedFunction" in #cgo noescape line is not used // testdata/errors.go:3:1: function "unusedFunction" in #cgo noescape line is not used
// Type checking errors after CGo processing: // Type checking errors after CGo processing:
// testdata/errors.go:102: cannot use 2 << 10 (untyped int constant 2048) as _Cgo_char value in variable declaration (overflows) // testdata/errors.go:102: cannot use 2 << 10 (untyped int constant 2048) as C.char value in variable declaration (overflows)
// testdata/errors.go:105: unknown field z in struct literal // testdata/errors.go:105: unknown field z in struct literal
// testdata/errors.go:108: undefined: _Cgo_SOME_CONST_1 // testdata/errors.go:108: undefined: C.SOME_CONST_1
// testdata/errors.go:110: cannot use _Cgo_SOME_CONST_3 (untyped int constant 1234) as byte value in variable declaration (overflows) // testdata/errors.go:110: cannot use C.SOME_CONST_3 (untyped int constant 1234) as byte value in variable declaration (overflows)
// testdata/errors.go:112: undefined: _Cgo_SOME_CONST_4 // testdata/errors.go:112: undefined: C.SOME_CONST_4
// testdata/errors.go:114: undefined: _Cgo_SOME_CONST_b // testdata/errors.go:114: undefined: C.SOME_CONST_b
// testdata/errors.go:116: undefined: _Cgo_SOME_CONST_startspace // testdata/errors.go:116: undefined: C.SOME_CONST_startspace
// testdata/errors.go:119: undefined: _Cgo_SOME_PARAM_CONST_invalid // testdata/errors.go:119: undefined: C.SOME_PARAM_CONST_invalid
// testdata/errors.go:122: undefined: _Cgo_add_toomuch // testdata/errors.go:122: undefined: C.add_toomuch
// testdata/errors.go:123: undefined: _Cgo_add_toolittle // testdata/errors.go:123: undefined: C.add_toolittle
package main package main
@@ -32,58 +32,58 @@ import "unsafe"
var _ unsafe.Pointer var _ unsafe.Pointer
//go:linkname _Cgo_CString runtime.cgo_CString //go:linkname C.CString runtime.cgo_CString
func _Cgo_CString(string) *_Cgo_char func C.CString(string) *C.char
//go:linkname _Cgo_GoString runtime.cgo_GoString //go:linkname C.GoString runtime.cgo_GoString
func _Cgo_GoString(*_Cgo_char) string func C.GoString(*C.char) string
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN //go:linkname C.__GoStringN runtime.cgo_GoStringN
func _Cgo___GoStringN(*_Cgo_char, uintptr) string func C.__GoStringN(*C.char, uintptr) string
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { func C.GoStringN(cstr *C.char, length C.int) string {
return _Cgo___GoStringN(cstr, uintptr(length)) return C.__GoStringN(cstr, uintptr(length))
} }
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes //go:linkname C.__GoBytes runtime.cgo_GoBytes
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte func C.__GoBytes(unsafe.Pointer, uintptr) []byte
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
return _Cgo___GoBytes(ptr, uintptr(length)) return C.__GoBytes(ptr, uintptr(length))
} }
//go:linkname _Cgo___CBytes runtime.cgo_CBytes //go:linkname C.__CBytes runtime.cgo_CBytes
func _Cgo___CBytes([]byte) unsafe.Pointer func C.__CBytes([]byte) unsafe.Pointer
func _Cgo_CBytes(b []byte) unsafe.Pointer { func C.CBytes(b []byte) unsafe.Pointer {
return _Cgo___CBytes(b) return C.__CBytes(b)
} }
//go:linkname _Cgo___get_errno_num runtime.cgo_errno //go:linkname C.__get_errno_num runtime.cgo_errno
func _Cgo___get_errno_num() uintptr func C.__get_errno_num() uintptr
func _Cgo___get_errno() error { func C.__get_errno() error {
return syscall.Errno(_Cgo___get_errno_num()) return syscall.Errno(C.__get_errno_num())
} }
type ( type (
_Cgo_char uint8 C.char uint8
_Cgo_schar int8 C.schar int8
_Cgo_uchar uint8 C.uchar uint8
_Cgo_short int16 C.short int16
_Cgo_ushort uint16 C.ushort uint16
_Cgo_int int32 C.int int32
_Cgo_uint uint32 C.uint uint32
_Cgo_long int32 C.long int32
_Cgo_ulong uint32 C.ulong uint32
_Cgo_longlong int64 C.longlong int64
_Cgo_ulonglong uint64 C.ulonglong uint64
) )
type _Cgo_struct_point_t struct { type C.struct_point_t struct {
x _Cgo_int x C.int
y _Cgo_int y C.int
} }
type _Cgo_point_t = _Cgo_struct_point_t type C.point_t = C.struct_point_t
const _Cgo_SOME_CONST_3 = 1234 const C.SOME_CONST_3 = 1234
const _Cgo_SOME_PARAM_CONST_valid = 3 + 4 const C.SOME_PARAM_CONST_valid = 3 + 4
+33 -33
View File
@@ -10,53 +10,53 @@ import "unsafe"
var _ unsafe.Pointer var _ unsafe.Pointer
//go:linkname _Cgo_CString runtime.cgo_CString //go:linkname C.CString runtime.cgo_CString
func _Cgo_CString(string) *_Cgo_char func C.CString(string) *C.char
//go:linkname _Cgo_GoString runtime.cgo_GoString //go:linkname C.GoString runtime.cgo_GoString
func _Cgo_GoString(*_Cgo_char) string func C.GoString(*C.char) string
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN //go:linkname C.__GoStringN runtime.cgo_GoStringN
func _Cgo___GoStringN(*_Cgo_char, uintptr) string func C.__GoStringN(*C.char, uintptr) string
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { func C.GoStringN(cstr *C.char, length C.int) string {
return _Cgo___GoStringN(cstr, uintptr(length)) return C.__GoStringN(cstr, uintptr(length))
} }
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes //go:linkname C.__GoBytes runtime.cgo_GoBytes
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte func C.__GoBytes(unsafe.Pointer, uintptr) []byte
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
return _Cgo___GoBytes(ptr, uintptr(length)) return C.__GoBytes(ptr, uintptr(length))
} }
//go:linkname _Cgo___CBytes runtime.cgo_CBytes //go:linkname C.__CBytes runtime.cgo_CBytes
func _Cgo___CBytes([]byte) unsafe.Pointer func C.__CBytes([]byte) unsafe.Pointer
func _Cgo_CBytes(b []byte) unsafe.Pointer { func C.CBytes(b []byte) unsafe.Pointer {
return _Cgo___CBytes(b) return C.__CBytes(b)
} }
//go:linkname _Cgo___get_errno_num runtime.cgo_errno //go:linkname C.__get_errno_num runtime.cgo_errno
func _Cgo___get_errno_num() uintptr func C.__get_errno_num() uintptr
func _Cgo___get_errno() error { func C.__get_errno() error {
return syscall.Errno(_Cgo___get_errno_num()) return syscall.Errno(C.__get_errno_num())
} }
type ( type (
_Cgo_char uint8 C.char uint8
_Cgo_schar int8 C.schar int8
_Cgo_uchar uint8 C.uchar uint8
_Cgo_short int16 C.short int16
_Cgo_ushort uint16 C.ushort uint16
_Cgo_int int32 C.int int32
_Cgo_uint uint32 C.uint uint32
_Cgo_long int32 C.long int32
_Cgo_ulong uint32 C.ulong uint32
_Cgo_longlong int64 C.longlong int64
_Cgo_ulonglong uint64 C.ulonglong uint64
) )
const _Cgo_BAR = 3 const C.BAR = 3
const _Cgo_FOO_H = 1 const C.FOO_H = 1
+42 -42
View File
@@ -5,80 +5,80 @@ import "unsafe"
var _ unsafe.Pointer var _ unsafe.Pointer
//go:linkname _Cgo_CString runtime.cgo_CString //go:linkname C.CString runtime.cgo_CString
func _Cgo_CString(string) *_Cgo_char func C.CString(string) *C.char
//go:linkname _Cgo_GoString runtime.cgo_GoString //go:linkname C.GoString runtime.cgo_GoString
func _Cgo_GoString(*_Cgo_char) string func C.GoString(*C.char) string
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN //go:linkname C.__GoStringN runtime.cgo_GoStringN
func _Cgo___GoStringN(*_Cgo_char, uintptr) string func C.__GoStringN(*C.char, uintptr) string
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { func C.GoStringN(cstr *C.char, length C.int) string {
return _Cgo___GoStringN(cstr, uintptr(length)) return C.__GoStringN(cstr, uintptr(length))
} }
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes //go:linkname C.__GoBytes runtime.cgo_GoBytes
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte func C.__GoBytes(unsafe.Pointer, uintptr) []byte
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
return _Cgo___GoBytes(ptr, uintptr(length)) return C.__GoBytes(ptr, uintptr(length))
} }
//go:linkname _Cgo___CBytes runtime.cgo_CBytes //go:linkname C.__CBytes runtime.cgo_CBytes
func _Cgo___CBytes([]byte) unsafe.Pointer func C.__CBytes([]byte) unsafe.Pointer
func _Cgo_CBytes(b []byte) unsafe.Pointer { func C.CBytes(b []byte) unsafe.Pointer {
return _Cgo___CBytes(b) return C.__CBytes(b)
} }
//go:linkname _Cgo___get_errno_num runtime.cgo_errno //go:linkname C.__get_errno_num runtime.cgo_errno
func _Cgo___get_errno_num() uintptr func C.__get_errno_num() uintptr
func _Cgo___get_errno() error { func C.__get_errno() error {
return syscall.Errno(_Cgo___get_errno_num()) return syscall.Errno(C.__get_errno_num())
} }
type ( type (
_Cgo_char uint8 C.char uint8
_Cgo_schar int8 C.schar int8
_Cgo_uchar uint8 C.uchar uint8
_Cgo_short int16 C.short int16
_Cgo_ushort uint16 C.ushort uint16
_Cgo_int int32 C.int int32
_Cgo_uint uint32 C.uint uint32
_Cgo_long int32 C.long int32
_Cgo_ulong uint32 C.ulong uint32
_Cgo_longlong int64 C.longlong int64
_Cgo_ulonglong uint64 C.ulonglong uint64
) )
//export foo //export foo
func _Cgo_foo(a _Cgo_int, b _Cgo_int) _Cgo_int func C.foo(a C.int, b C.int) C.int
var _Cgo_foo$funcaddr unsafe.Pointer var C.foo$funcaddr unsafe.Pointer
//export variadic0 //export variadic0
//go:variadic //go:variadic
func _Cgo_variadic0() func C.variadic0()
var _Cgo_variadic0$funcaddr unsafe.Pointer var C.variadic0$funcaddr unsafe.Pointer
//export variadic2 //export variadic2
//go:variadic //go:variadic
func _Cgo_variadic2(x _Cgo_int, y _Cgo_int) func C.variadic2(x C.int, y C.int)
var _Cgo_variadic2$funcaddr unsafe.Pointer var C.variadic2$funcaddr unsafe.Pointer
//export _Cgo_static_173c95a79b6df1980521_staticfunc //export _Cgo_static_173c95a79b6df1980521_staticfunc
func _Cgo_staticfunc!symbols.go(x _Cgo_int) func C.staticfunc!symbols.go(x C.int)
var _Cgo_staticfunc!symbols.go$funcaddr unsafe.Pointer var C.staticfunc!symbols.go$funcaddr unsafe.Pointer
//export notEscapingFunction //export notEscapingFunction
//go:noescape //go:noescape
func _Cgo_notEscapingFunction(a *_Cgo_int) func C.notEscapingFunction(a *C.int)
var _Cgo_notEscapingFunction$funcaddr unsafe.Pointer var C.notEscapingFunction$funcaddr unsafe.Pointer
//go:extern someValue //go:extern someValue
var _Cgo_someValue _Cgo_int var C.someValue C.int
+99 -103
View File
@@ -5,162 +5,158 @@ import "unsafe"
var _ unsafe.Pointer var _ unsafe.Pointer
//go:linkname _Cgo_CString runtime.cgo_CString //go:linkname C.CString runtime.cgo_CString
func _Cgo_CString(string) *_Cgo_char func C.CString(string) *C.char
//go:linkname _Cgo_GoString runtime.cgo_GoString //go:linkname C.GoString runtime.cgo_GoString
func _Cgo_GoString(*_Cgo_char) string func C.GoString(*C.char) string
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN //go:linkname C.__GoStringN runtime.cgo_GoStringN
func _Cgo___GoStringN(*_Cgo_char, uintptr) string func C.__GoStringN(*C.char, uintptr) string
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { func C.GoStringN(cstr *C.char, length C.int) string {
return _Cgo___GoStringN(cstr, uintptr(length)) return C.__GoStringN(cstr, uintptr(length))
} }
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes //go:linkname C.__GoBytes runtime.cgo_GoBytes
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte func C.__GoBytes(unsafe.Pointer, uintptr) []byte
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
return _Cgo___GoBytes(ptr, uintptr(length)) return C.__GoBytes(ptr, uintptr(length))
} }
//go:linkname _Cgo___CBytes runtime.cgo_CBytes //go:linkname C.__CBytes runtime.cgo_CBytes
func _Cgo___CBytes([]byte) unsafe.Pointer func C.__CBytes([]byte) unsafe.Pointer
func _Cgo_CBytes(b []byte) unsafe.Pointer { func C.CBytes(b []byte) unsafe.Pointer {
return _Cgo___CBytes(b) return C.__CBytes(b)
} }
//go:linkname _Cgo___get_errno_num runtime.cgo_errno //go:linkname C.__get_errno_num runtime.cgo_errno
func _Cgo___get_errno_num() uintptr func C.__get_errno_num() uintptr
func _Cgo___get_errno() error { func C.__get_errno() error {
return syscall.Errno(_Cgo___get_errno_num()) return syscall.Errno(C.__get_errno_num())
} }
type ( type (
_Cgo_char uint8 C.char uint8
_Cgo_schar int8 C.schar int8
_Cgo_uchar uint8 C.uchar uint8
_Cgo_short int16 C.short int16
_Cgo_ushort uint16 C.ushort uint16
_Cgo_int int32 C.int int32
_Cgo_uint uint32 C.uint uint32
_Cgo_long int32 C.long int32
_Cgo_ulong uint32 C.ulong uint32
_Cgo_longlong int64 C.longlong int64
_Cgo_ulonglong uint64 C.ulonglong uint64
) )
type _Cgo_myint = _Cgo_int type C.myint = C.int
type _Cgo_struct_point2d_t struct { type C.struct_point2d_t struct {
x _Cgo_int x C.int
y _Cgo_int y C.int
} }
type _Cgo_point2d_t = _Cgo_struct_point2d_t type C.point2d_t = C.struct_point2d_t
type _Cgo_struct_point3d struct { type C.struct_point3d struct {
x _Cgo_int x C.int
y _Cgo_int y C.int
z _Cgo_int z C.int
} }
type _Cgo_point3d_t = _Cgo_struct_point3d type C.point3d_t = C.struct_point3d
type _Cgo_struct_type1 struct { type C.struct_type1 struct {
_type _Cgo_int _type C.int
__type _Cgo_int __type C.int
___type _Cgo_int ___type C.int
} }
type _Cgo_struct_type2 struct{ _type _Cgo_int } type C.struct_type2 struct{ _type C.int }
type _Cgo_union_union1_t struct{ i _Cgo_int } type C.union_union1_t struct{ i C.int }
type _Cgo_union1_t = _Cgo_union_union1_t type C.union1_t = C.union_union1_t
type _Cgo_union_union3_t struct{ $union uint64 } type C.union_union3_t struct{ $union uint64 }
func (union *_Cgo_union_union3_t) unionfield_i() *_Cgo_int { func (union *C.union_union3_t) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) }
return (*_Cgo_int)(unsafe.Pointer(&union.$union)) func (union *C.union_union3_t) unionfield_d() *float64 {
}
func (union *_Cgo_union_union3_t) unionfield_d() *float64 {
return (*float64)(unsafe.Pointer(&union.$union)) return (*float64)(unsafe.Pointer(&union.$union))
} }
func (union *_Cgo_union_union3_t) unionfield_s() *_Cgo_short { func (union *C.union_union3_t) unionfield_s() *C.short {
return (*_Cgo_short)(unsafe.Pointer(&union.$union)) return (*C.short)(unsafe.Pointer(&union.$union))
} }
type _Cgo_union3_t = _Cgo_union_union3_t type C.union3_t = C.union_union3_t
type _Cgo_union_union2d struct{ $union [2]uint64 } type C.union_union2d struct{ $union [2]uint64 }
func (union *_Cgo_union_union2d) unionfield_i() *_Cgo_int { func (union *C.union_union2d) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) }
return (*_Cgo_int)(unsafe.Pointer(&union.$union)) func (union *C.union_union2d) unionfield_d() *[2]float64 {
}
func (union *_Cgo_union_union2d) unionfield_d() *[2]float64 {
return (*[2]float64)(unsafe.Pointer(&union.$union)) return (*[2]float64)(unsafe.Pointer(&union.$union))
} }
type _Cgo_union2d_t = _Cgo_union_union2d type C.union2d_t = C.union_union2d
type _Cgo_union_unionarray_t struct{ arr [10]_Cgo_uchar } type C.union_unionarray_t struct{ arr [10]C.uchar }
type _Cgo_unionarray_t = _Cgo_union_unionarray_t type C.unionarray_t = C.union_unionarray_t
type _Cgo__Ctype_union___0 struct{ $union [3]uint32 } type C._Ctype_union___0 struct{ $union [3]uint32 }
func (union *_Cgo__Ctype_union___0) unionfield_area() *_Cgo_point2d_t { func (union *C._Ctype_union___0) unionfield_area() *C.point2d_t {
return (*_Cgo_point2d_t)(unsafe.Pointer(&union.$union)) return (*C.point2d_t)(unsafe.Pointer(&union.$union))
} }
func (union *_Cgo__Ctype_union___0) unionfield_solid() *_Cgo_point3d_t { func (union *C._Ctype_union___0) unionfield_solid() *C.point3d_t {
return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union)) return (*C.point3d_t)(unsafe.Pointer(&union.$union))
} }
type _Cgo_struct_struct_nested_t struct { type C.struct_struct_nested_t struct {
begin _Cgo_point2d_t begin C.point2d_t
end _Cgo_point2d_t end C.point2d_t
tag _Cgo_int tag C.int
coord _Cgo__Ctype_union___0 coord C._Ctype_union___0
} }
type _Cgo_struct_nested_t = _Cgo_struct_struct_nested_t type C.struct_nested_t = C.struct_struct_nested_t
type _Cgo_union_union_nested_t struct{ $union [2]uint64 } type C.union_union_nested_t struct{ $union [2]uint64 }
func (union *_Cgo_union_union_nested_t) unionfield_point() *_Cgo_point3d_t { func (union *C.union_union_nested_t) unionfield_point() *C.point3d_t {
return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union)) return (*C.point3d_t)(unsafe.Pointer(&union.$union))
} }
func (union *_Cgo_union_union_nested_t) unionfield_array() *_Cgo_unionarray_t { func (union *C.union_union_nested_t) unionfield_array() *C.unionarray_t {
return (*_Cgo_unionarray_t)(unsafe.Pointer(&union.$union)) return (*C.unionarray_t)(unsafe.Pointer(&union.$union))
} }
func (union *_Cgo_union_union_nested_t) unionfield_thing() *_Cgo_union3_t { func (union *C.union_union_nested_t) unionfield_thing() *C.union3_t {
return (*_Cgo_union3_t)(unsafe.Pointer(&union.$union)) return (*C.union3_t)(unsafe.Pointer(&union.$union))
} }
type _Cgo_union_nested_t = _Cgo_union_union_nested_t type C.union_nested_t = C.union_union_nested_t
type _Cgo_enum_option = _Cgo_int type C.enum_option = C.int
type _Cgo_option_t = _Cgo_enum_option type C.option_t = C.enum_option
type _Cgo_enum_option2_t = _Cgo_uint type C.enum_option2_t = C.uint
type _Cgo_option2_t = _Cgo_enum_option2_t type C.option2_t = C.enum_option2_t
type _Cgo_struct_types_t struct { type C.struct_types_t struct {
f float32 f float32
d float64 d float64
ptr *_Cgo_int ptr *C.int
} }
type _Cgo_types_t = _Cgo_struct_types_t type C.types_t = C.struct_types_t
type _Cgo_myIntArray = [10]_Cgo_int type C.myIntArray = [10]C.int
type _Cgo_struct_bitfield_t struct { type C.struct_bitfield_t struct {
start _Cgo_uchar start C.uchar
__bitfield_1 _Cgo_uchar __bitfield_1 C.uchar
d _Cgo_uchar d C.uchar
e _Cgo_uchar e C.uchar
} }
func (s *_Cgo_struct_bitfield_t) bitfield_a() _Cgo_uchar { return s.__bitfield_1 & 0x1f } func (s *C.struct_bitfield_t) bitfield_a() C.uchar { return s.__bitfield_1 & 0x1f }
func (s *_Cgo_struct_bitfield_t) set_bitfield_a(value _Cgo_uchar) { func (s *C.struct_bitfield_t) set_bitfield_a(value C.uchar) {
s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0 s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0
} }
func (s *_Cgo_struct_bitfield_t) bitfield_b() _Cgo_uchar { func (s *C.struct_bitfield_t) bitfield_b() C.uchar {
return s.__bitfield_1 >> 5 & 0x1 return s.__bitfield_1 >> 5 & 0x1
} }
func (s *_Cgo_struct_bitfield_t) set_bitfield_b(value _Cgo_uchar) { func (s *C.struct_bitfield_t) set_bitfield_b(value C.uchar) {
s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5 s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5
} }
func (s *_Cgo_struct_bitfield_t) bitfield_c() _Cgo_uchar { func (s *C.struct_bitfield_t) bitfield_c() C.uchar {
return s.__bitfield_1 >> 6 return s.__bitfield_1 >> 6
} }
func (s *_Cgo_struct_bitfield_t) set_bitfield_c(value _Cgo_uchar, func (s *C.struct_bitfield_t) set_bitfield_c(value C.uchar,
) { s.__bitfield_1 = s.__bitfield_1&0x3f | value<<6 } ) { s.__bitfield_1 = s.__bitfield_1&0x3f | value<<6 }
type _Cgo_bitfield_t = _Cgo_struct_bitfield_t type C.bitfield_t = C.struct_bitfield_t
+65 -113
View File
@@ -8,24 +8,12 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv"
"strings" "strings"
"github.com/google/shlex" "github.com/google/shlex"
"github.com/tinygo-org/tinygo/goenv" "github.com/tinygo-org/tinygo/goenv"
) )
// Library versions. Whenever an existing library is changed, this number should
// be added/increased so that existing caches are invalidated.
//
// (This is a bit of a layering violation, this should really be part of the
// builder.Library struct but that's hard to do since we want to know the
// library path in advance in several places).
var libVersions = map[string]int{
"musl": 3,
"bdwgc": 2,
}
// Config keeps all configuration affecting the build in a single struct. // Config keeps all configuration affecting the build in a single struct.
type Config struct { type Config struct {
Options *Options Options *Options
@@ -139,7 +127,7 @@ func (c *Config) GC() string {
// that can be traced by the garbage collector. // that can be traced by the garbage collector.
func (c *Config) NeedsStackObjects() bool { func (c *Config) NeedsStackObjects() bool {
switch c.GC() { switch c.GC() {
case "conservative", "custom", "precise", "boehm": case "conservative", "custom", "precise":
for _, tag := range c.BuildTags() { for _, tag := range c.BuildTags() {
if tag == "tinygo.wasm" { if tag == "tinygo.wasm" {
return true return true
@@ -264,18 +252,10 @@ func MuslArchitecture(triple string) string {
return CanonicalArchName(triple) return CanonicalArchName(triple)
} }
// Returns true if the libc needs to include malloc, for the libcs where this // LibcPath returns the path to the libc directory. The libc path will be either
// matters. // a precompiled libc shipped with a TinyGo build, or a libc path in the cache
func (c *Config) LibcNeedsMalloc() bool { // directory (which might not yet be built).
if c.GC() == "boehm" && c.Target.Libc == "wasi-libc" { func (c *Config) LibcPath(name string) (path string, precompiled bool) {
return true
}
return false
}
// LibraryPath returns the path to the library build directory. The path will be
// a library path in the cache directory (which might not yet be built).
func (c *Config) LibraryPath(name string) string {
archname := c.Triple() archname := c.Triple()
if c.CPU() != "" { if c.CPU() != "" {
archname += "-" + c.CPU() archname += "-" + c.CPU()
@@ -286,24 +266,18 @@ func (c *Config) LibraryPath(name string) string {
if c.Target.SoftFloat { if c.Target.SoftFloat {
archname += "-softfloat" archname += "-softfloat"
} }
if name == "bdwgc" {
// Boehm GC is compiled against a particular libc.
archname += "-" + c.Target.Libc
}
// Append a version string, if this library has a version. // Try to load a precompiled library.
if v, ok := libVersions[name]; ok { precompiledDir := filepath.Join(goenv.Get("TINYGOROOT"), "pkg", archname, name)
archname += "-v" + strconv.Itoa(v) if _, err := os.Stat(precompiledDir); err == nil {
} // Found a precompiled library for this OS/architecture. Return the path
// directly.
options := "" return precompiledDir, true
if c.LibcNeedsMalloc() {
options += "+malloc"
} }
// No precompiled library found. Determine the path name that will be used // No precompiled library found. Determine the path name that will be used
// in the build cache. // in the build cache.
return filepath.Join(goenv.Get("GOCACHE"), name+options+"-"+archname) return filepath.Join(goenv.Get("GOCACHE"), name+"-"+archname), false
} }
// DefaultBinaryExtension returns the default extension for binaries, such as // DefaultBinaryExtension returns the default extension for binaries, such as
@@ -346,7 +320,59 @@ func (c *Config) CFlags(libclang bool) []string {
"-resource-dir="+resourceDir, "-resource-dir="+resourceDir,
) )
} }
cflags = append(cflags, c.LibcCFlags()...) switch c.Target.Libc {
case "darwin-libSystem":
root := goenv.Get("TINYGOROOT")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(root, "lib/macos-minimal-sdk/src/usr/include"),
)
case "picolibc":
root := goenv.Get("TINYGOROOT")
picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc")
path, _ := c.LibcPath("picolibc")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(picolibcDir, "include"),
"-isystem", filepath.Join(picolibcDir, "tinystdio"),
"-D__PICOLIBC_ERRNO_FUNCTION=__errno_location",
)
case "musl":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("musl")
arch := MuslArchitecture(c.Triple())
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "musl", "arch", arch),
"-isystem", filepath.Join(root, "lib", "musl", "arch", "generic"),
"-isystem", filepath.Join(root, "lib", "musl", "include"),
)
case "wasi-libc":
root := goenv.Get("TINYGOROOT")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", root+"/lib/wasi-libc/sysroot/include")
case "wasmbuiltins":
// nothing to add (library is purely for builtins)
case "mingw-w64":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("mingw-w64")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"),
"-D_UCRT",
)
case "":
// No libc specified, nothing to add.
default:
// Incorrect configuration. This could be handled in a better way, but
// usually this will be found by developers (not by TinyGo users).
panic("unknown libc: " + c.Target.Libc)
}
// Always emit debug information. It is optionally stripped at link time. // Always emit debug information. It is optionally stripped at link time.
cflags = append(cflags, "-gdwarf-4") cflags = append(cflags, "-gdwarf-4")
// Use the same optimization level as TinyGo. // Use the same optimization level as TinyGo.
@@ -373,80 +399,6 @@ func (c *Config) CFlags(libclang bool) []string {
return cflags return cflags
} }
// LibcCFlags returns the C compiler flags for the configured libc.
// It only uses flags that are part of the libc path (triple, cpu, abi, libc
// name) so it can safely be used to compile another C library.
func (c *Config) LibcCFlags() []string {
switch c.Target.Libc {
case "darwin-libSystem":
root := goenv.Get("TINYGOROOT")
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(root, "lib/macos-minimal-sdk/src/usr/include"),
}
case "picolibc":
root := goenv.Get("TINYGOROOT")
picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc")
path := c.LibraryPath("picolibc")
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(picolibcDir, "include"),
"-isystem", filepath.Join(picolibcDir, "tinystdio"),
"-D__PICOLIBC_ERRNO_FUNCTION=__errno_location",
}
case "musl":
root := goenv.Get("TINYGOROOT")
path := c.LibraryPath("musl")
arch := MuslArchitecture(c.Triple())
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "musl", "arch", arch),
"-isystem", filepath.Join(root, "lib", "musl", "arch", "generic"),
"-isystem", filepath.Join(root, "lib", "musl", "include"),
}
case "wasi-libc":
path := c.LibraryPath("wasi-libc")
return []string{
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
}
case "wasmbuiltins":
// nothing to add (library is purely for builtins)
return nil
case "mingw-w64":
root := goenv.Get("TINYGOROOT")
path := c.LibraryPath("mingw-w64")
cflags := []string{
"-nostdlibinc",
"-isystem", filepath.Join(path, "include"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "include"),
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"),
}
if c.GOARCH() == "386" {
cflags = append(cflags,
"-D__MSVCRT_VERSION__=0x700", // Microsoft Visual C++ .NET 2002
"-D_WIN32_WINNT=0x0501", // target Windows XP
)
} else {
cflags = append(cflags,
"-D_UCRT",
"-D_WIN32_WINNT=0x0a00", // target Windows 10
)
}
return cflags
case "":
// No libc specified, nothing to add.
return nil
default:
// Incorrect configuration. This could be handled in a better way, but
// usually this will be found by developers (not by TinyGo users).
panic("unknown libc: " + c.Target.Libc)
}
}
// LDFlags returns the flags to pass to the linker. A few more flags are needed // LDFlags returns the flags to pass to the linker. A few more flags are needed
// (like the one for the compiler runtime), but this represents the majority of // (like the one for the compiler runtime), but this represents the majority of
// the flags. // the flags.
+3 -3
View File
@@ -8,8 +8,8 @@ import (
) )
var ( var (
validBuildModeOptions = []string{"default", "c-shared", "wasi-legacy"} validBuildModeOptions = []string{"default", "c-shared"}
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise", "boehm"} validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
validSchedulerOptions = []string{"none", "tasks", "asyncify", "threads", "cores"} validSchedulerOptions = []string{"none", "tasks", "asyncify", "threads", "cores"}
validSerialOptions = []string{"none", "uart", "usb", "rtt"} validSerialOptions = []string{"none", "uart", "usb", "rtt"}
validPrintSizeOptions = []string{"none", "short", "full", "html"} validPrintSizeOptions = []string{"none", "short", "full", "html"}
@@ -43,7 +43,6 @@ type Options struct {
PrintCommands func(cmd string, args ...string) `json:"-"` PrintCommands func(cmd string, args ...string) `json:"-"`
Semaphore chan struct{} `json:"-"` // -p flag controls cap Semaphore chan struct{} `json:"-"` // -p flag controls cap
Debug bool Debug bool
Nobounds bool
PrintSizes string PrintSizes string
PrintAllocs *regexp.Regexp // regexp string PrintAllocs *regexp.Regexp // regexp string
PrintStacks bool PrintStacks bool
@@ -53,6 +52,7 @@ type Options struct {
Programmer string Programmer string
OpenOCDCommands []string OpenOCDCommands []string
LLVMFeatures string LLVMFeatures string
PrintJSON bool
Monitor bool Monitor bool
BaudRate int BaudRate int
Timeout time.Duration Timeout time.Duration
+2 -2
View File
@@ -9,8 +9,8 @@ import (
func TestVerifyOptions(t *testing.T) { func TestVerifyOptions(t *testing.T) {
expectedGCError := errors.New(`invalid gc option 'incorrect': valid values are none, leaking, conservative, custom, precise, boehm`) expectedGCError := errors.New(`invalid gc option 'incorrect': valid values are none, leaking, conservative, custom, precise`)
expectedSchedulerError := errors.New(`invalid scheduler option 'incorrect': valid values are none, tasks, asyncify, threads, cores`) expectedSchedulerError := errors.New(`invalid scheduler option 'incorrect': valid values are none, tasks, asyncify, threads`)
expectedPrintSizeError := errors.New(`invalid size option 'incorrect': valid values are none, short, full, html`) expectedPrintSizeError := errors.New(`invalid size option 'incorrect': valid values are none, short, full, html`)
expectedPanicStrategyError := errors.New(`invalid panic option 'incorrect': valid values are print, trap`) expectedPanicStrategyError := errors.New(`invalid panic option 'incorrect': valid values are print, trap`)
+37 -43
View File
@@ -178,21 +178,6 @@ func (spec *TargetSpec) resolveInherits() error {
// Load a target specification. // Load a target specification.
func LoadTarget(options *Options) (*TargetSpec, error) { func LoadTarget(options *Options) (*TargetSpec, error) {
if options.Target == "" && options.GOARCH == "wasm" {
// Set a specific target if we're building from a known GOOS/GOARCH
// combination that is defined in a target JSON file.
switch options.GOOS {
case "js":
options.Target = "wasm"
case "wasip1":
options.Target = "wasip1"
case "wasip2":
options.Target = "wasip2"
default:
return nil, errors.New("GOARCH=wasm but GOOS is not set correctly. Please set GOOS to js, wasip1, or wasip2.")
}
}
if options.Target == "" { if options.Target == "" {
return defaultTarget(options) return defaultTarget(options)
} }
@@ -262,6 +247,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
GOOS: options.GOOS, GOOS: options.GOOS,
GOARCH: options.GOARCH, GOARCH: options.GOARCH,
BuildTags: []string{options.GOOS, options.GOARCH}, BuildTags: []string{options.GOOS, options.GOARCH},
GC: "precise",
Linker: "cc", Linker: "cc",
DefaultStackSize: 1024 * 64, // 64kB DefaultStackSize: 1024 * 64, // 64kB
GDB: []string{"gdb"}, GDB: []string{"gdb"},
@@ -369,7 +355,17 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS) return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS)
} }
case "wasm": case "wasm":
return nil, fmt.Errorf("GOARCH=wasm but GOOS is unset. Please set GOOS to js, wasip1, or wasip2.") llvmarch = "wasm32"
spec.CPU = "generic"
spec.Features = "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types"
spec.BuildTags = append(spec.BuildTags, "tinygo.wasm")
spec.CFlags = append(spec.CFlags,
"-mbulk-memory",
"-mnontrapping-fptoint",
"-mno-multivalue",
"-mno-reference-types",
"-msign-ext",
)
default: default:
return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH) return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH)
} }
@@ -379,13 +375,12 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
llvmvendor := "unknown" llvmvendor := "unknown"
switch options.GOOS { switch options.GOOS {
case "darwin": case "darwin":
spec.GC = "boehm"
platformVersion := "10.12.0" platformVersion := "10.12.0"
if options.GOARCH == "arm64" { if options.GOARCH == "arm64" {
platformVersion = "11.0.0" // first macosx platform with arm64 support platformVersion = "11.0.0" // first macosx platform with arm64 support
} }
llvmvendor = "apple" llvmvendor = "apple"
spec.Scheduler = "threads" spec.Scheduler = "tasks"
spec.Linker = "ld.lld" spec.Linker = "ld.lld"
spec.Libc = "darwin-libSystem" spec.Libc = "darwin-libSystem"
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to // Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
@@ -399,12 +394,10 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
) )
spec.ExtraFiles = append(spec.ExtraFiles, spec.ExtraFiles = append(spec.ExtraFiles,
"src/internal/futex/futex_darwin.c", "src/internal/futex/futex_darwin.c",
"src/internal/task/task_threads.c",
"src/runtime/os_darwin.c", "src/runtime/os_darwin.c",
"src/runtime/runtime_unix.c", "src/runtime/runtime_unix.c",
"src/runtime/signal.c") "src/runtime/signal.c")
case "linux": case "linux":
spec.GC = "boehm"
spec.Scheduler = "threads" spec.Scheduler = "threads"
spec.Linker = "ld.lld" spec.Linker = "ld.lld"
spec.RTLib = "compiler-rt" spec.RTLib = "compiler-rt"
@@ -430,26 +423,17 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
"src/runtime/runtime_unix.c", "src/runtime/runtime_unix.c",
"src/runtime/signal.c") "src/runtime/signal.c")
case "windows": case "windows":
spec.GC = "boehm"
spec.Scheduler = "tasks" spec.Scheduler = "tasks"
spec.Linker = "ld.lld" spec.Linker = "ld.lld"
spec.Libc = "mingw-w64" spec.Libc = "mingw-w64"
// Note: using a medium code model, low image base and no ASLR
// because Go doesn't really need those features. ASLR patches
// around issues for unsafe languages like C/C++ that are not
// normally present in Go (without explicitly opting in).
// For more discussion:
// https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1
switch options.GOARCH { switch options.GOARCH {
case "386":
spec.LDFlags = append(spec.LDFlags,
"-m", "i386pe",
"--major-os-version", "4",
"--major-subsystem-version", "4",
)
// __udivdi3 is not present in ucrt it seems.
spec.RTLib = "compiler-rt"
case "amd64": case "amd64":
// Note: using a medium code model, low image base and no ASLR
// because Go doesn't really need those features. ASLR patches
// around issues for unsafe languages like C/C++ that are not
// normally present in Go (without explicitly opting in).
// For more discussion:
// https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1
spec.LDFlags = append(spec.LDFlags, spec.LDFlags = append(spec.LDFlags,
"-m", "i386pep", "-m", "i386pep",
"--image-base", "0x400000", "--image-base", "0x400000",
@@ -465,18 +449,27 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
"--no-insert-timestamp", "--no-insert-timestamp",
"--no-dynamicbase", "--no-dynamicbase",
) )
case "wasm", "wasip1", "wasip2": case "wasip1":
return nil, fmt.Errorf("GOOS=%s but GOARCH is unset. Please set GOARCH to wasm", options.GOOS) spec.GC = "" // use default GC
spec.Scheduler = "asyncify"
spec.Linker = "wasm-ld"
spec.RTLib = "compiler-rt"
spec.Libc = "wasi-libc"
spec.DefaultStackSize = 1024 * 64 // 64kB
spec.LDFlags = append(spec.LDFlags,
"--stack-first",
"--no-demangle",
)
spec.Emulator = "wasmtime run --dir={tmpDir}::/tmp {}"
spec.ExtraFiles = append(spec.ExtraFiles,
"src/runtime/asm_tinygowasm.S",
"src/internal/task/task_asyncify_wasm.S",
)
llvmos = "wasi"
default: default:
return nil, fmt.Errorf("unknown GOOS=%s", options.GOOS) return nil, fmt.Errorf("unknown GOOS=%s", options.GOOS)
} }
if spec.GC == "boehm" {
// Add this file only when needed. This fixes a build failure on
// Windows.
spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/gc_boehm.c")
}
// Target triples (which actually have four components, but are called // Target triples (which actually have four components, but are called
// triples for historical reasons) have the form: // triples for historical reasons) have the form:
// arch-vendor-os-environment // arch-vendor-os-environment
@@ -508,6 +501,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
} }
spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/asm_"+asmGoarch+suffix+".S") spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/asm_"+asmGoarch+suffix+".S")
spec.ExtraFiles = append(spec.ExtraFiles, "src/internal/task/task_stack_"+asmGoarch+suffix+".S") spec.ExtraFiles = append(spec.ExtraFiles, "src/internal/task/task_stack_"+asmGoarch+suffix+".S")
spec.ExtraFiles = append(spec.ExtraFiles, "src/internal/task/task_cores.c")
} }
// Configure the emulator. // Configure the emulator.
+5 -6
View File
@@ -18,12 +18,11 @@ var stdlibAliases = map[string]string{
// crypto packages // crypto packages
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric", "crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
"crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric", "crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
"crypto/md5.block": "crypto/md5.blockGeneric", "crypto/md5.block": "crypto/md5.blockGeneric",
"crypto/sha1.block": "crypto/sha1.blockGeneric", "crypto/sha1.block": "crypto/sha1.blockGeneric",
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric", "crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
"crypto/sha256.block": "crypto/sha256.blockGeneric", "crypto/sha256.block": "crypto/sha256.blockGeneric",
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric", "crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
"internal/chacha8rand.block": "internal/chacha8rand.block_generic",
// AES // AES
"crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock", "crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock",
+1 -9
View File
@@ -76,15 +76,7 @@ func (b *builder) createCall(fnType llvm.Type, fn llvm.Value, args []llvm.Value,
fragments := b.expandFormalParam(arg) fragments := b.expandFormalParam(arg)
expanded = append(expanded, fragments...) expanded = append(expanded, fragments...)
} }
call := b.CreateCall(fnType, fn, expanded, name) return b.CreateCall(fnType, fn, expanded, name)
if !fn.IsAFunction().IsNil() {
if cc := fn.FunctionCallConv(); cc != llvm.CCallConv {
// Set a different calling convention if needed.
// This is needed for GetModuleHandleExA on Windows, for example.
call.SetInstructionCallConv(cc)
}
}
return call
} }
// createInvoke is like createCall but continues execution at the landing pad if // createInvoke is like createCall but continues execution at the landing pad if
+10 -39
View File
@@ -58,7 +58,6 @@ type Config struct {
MaxStackAlloc uint64 MaxStackAlloc uint64
NeedsStackObjects bool NeedsStackObjects bool
Debug bool // Whether to emit debug information in the LLVM module. Debug bool // Whether to emit debug information in the LLVM module.
Nobounds bool // Whether to skip bounds checks
PanicStrategy string PanicStrategy string
} }
@@ -389,7 +388,7 @@ func (c *compilerContext) getLLVMType(goType types.Type) llvm.Type {
// makeLLVMType creates a LLVM type for a Go type. Don't call this, use // makeLLVMType creates a LLVM type for a Go type. Don't call this, use
// getLLVMType instead. // getLLVMType instead.
func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type { func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
switch typ := types.Unalias(goType).(type) { switch typ := goType.(type) {
case *types.Array: case *types.Array:
elemType := c.getLLVMType(typ.Elem()) elemType := c.getLLVMType(typ.Elem())
return llvm.ArrayType(elemType, int(typ.Len())) return llvm.ArrayType(elemType, int(typ.Len()))
@@ -497,21 +496,6 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
llvmType := c.getLLVMType(typ) llvmType := c.getLLVMType(typ)
sizeInBytes := c.targetData.TypeAllocSize(llvmType) sizeInBytes := c.targetData.TypeAllocSize(llvmType)
switch typ := typ.(type) { switch typ := typ.(type) {
case *types.Alias:
// Implement types.Alias just like types.Named: by treating them like a
// C typedef.
temporaryMDNode := c.dibuilder.CreateReplaceableCompositeType(llvm.Metadata{}, llvm.DIReplaceableCompositeType{
Tag: dwarf.TagTypedef,
SizeInBits: sizeInBytes * 8,
AlignInBits: uint32(c.targetData.ABITypeAlignment(llvmType)) * 8,
})
c.ditypes[typ] = temporaryMDNode
md := c.dibuilder.CreateTypedef(llvm.DITypedef{
Type: c.getDIType(types.Unalias(typ)), // TODO: use typ.Rhs in Go 1.23
Name: typ.String(),
})
temporaryMDNode.ReplaceAllUsesWith(md)
return md
case *types.Array: case *types.Array:
return c.dibuilder.CreateArrayType(llvm.DIArrayType{ return c.dibuilder.CreateArrayType(llvm.DIArrayType{
SizeInBits: sizeInBytes * 8, SizeInBits: sizeInBytes * 8,
@@ -874,11 +858,6 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package
// Interfaces don't have concrete methods. // Interfaces don't have concrete methods.
continue continue
} }
if _, isalias := member.Type().(*types.Alias); isalias {
// Aliases don't need to be redefined, since they just refer to
// an already existing type whose methods will be defined.
continue
}
// Named type. We should make sure all methods are created. // Named type. We should make sure all methods are created.
// This includes both functions with pointer receivers and those // This includes both functions with pointer receivers and those
@@ -1856,7 +1835,15 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
// //
// This is also where compiler intrinsics are implemented. // This is also where compiler intrinsics are implemented.
func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) { func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) {
// See if this is an intrinsic function that is handled specially. var params []llvm.Value
for _, param := range instr.Args {
params = append(params, b.getValue(param, getPos(instr)))
}
// Try to call the function directly for trivially static calls.
var callee, context llvm.Value
var calleeType llvm.Type
exported := false
if fn := instr.StaticCallee(); fn != nil { if fn := instr.StaticCallee(); fn != nil {
// Direct function call, either to a named or anonymous (directly // Direct function call, either to a named or anonymous (directly
// applied) function call. If it is anonymous, it may be a closure. // applied) function call. If it is anonymous, it may be a closure.
@@ -1892,29 +1879,13 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil
case name == "runtime/interrupt.New": case name == "runtime/interrupt.New":
return b.createInterruptGlobal(instr) return b.createInterruptGlobal(instr)
case name == "runtime.exportedFuncPtr":
_, ptr := b.getFunction(instr.Args[0].(*ssa.Function))
return b.CreatePtrToInt(ptr, b.uintptrType, ""), nil
case name == "(*runtime/interrupt.Checkpoint).Save":
return b.createInterruptCheckpoint(instr.Args[0]), nil
case name == "internal/abi.FuncPCABI0": case name == "internal/abi.FuncPCABI0":
retval := b.createDarwinFuncPCABI0Call(instr) retval := b.createDarwinFuncPCABI0Call(instr)
if !retval.IsNil() { if !retval.IsNil() {
return retval, nil return retval, nil
} }
} }
}
var params []llvm.Value
for _, param := range instr.Args {
params = append(params, b.getValue(param, getPos(instr)))
}
// Try to call the function directly for trivially static calls.
var callee, context llvm.Value
var calleeType llvm.Type
exported := false
if fn := instr.StaticCallee(); fn != nil {
calleeType, callee = b.getFunction(fn) calleeType, callee = b.getFunction(fn)
info := b.getFunctionInfo(fn) info := b.getFunctionInfo(fn)
if callee.IsNil() { if callee.IsNil() {
+6 -15
View File
@@ -103,11 +103,10 @@ func (b *builder) createLandingPad() {
b.CreateBr(b.blockEntries[b.fn.Recover]) b.CreateBr(b.blockEntries[b.fn.Recover])
} }
// Create a checkpoint (similar to setjmp). This emits inline assembly that // createInvokeCheckpoint saves the function state at the given point, to
// stores the current program counter inside the ptr address (actually // continue at the landing pad if a panic happened. This is implemented using a
// ptr+sizeof(ptr)) and then returns a boolean indicating whether this is the // setjmp-like construct.
// normal flow (false) or we jumped here from somewhere else (true). func (b *builder) createInvokeCheckpoint() {
func (b *builder) createCheckpoint(ptr llvm.Value) llvm.Value {
// Construct inline assembly equivalents of setjmp. // Construct inline assembly equivalents of setjmp.
// The assembly works as follows: // The assembly works as follows:
// * All registers (both callee-saved and caller saved) are clobbered // * All registers (both callee-saved and caller saved) are clobbered
@@ -218,19 +217,11 @@ li a0, 0
// This case should have been handled by b.supportsRecover(). // This case should have been handled by b.supportsRecover().
b.addError(b.fn.Pos(), "unknown architecture for defer: "+b.archFamily()) b.addError(b.fn.Pos(), "unknown architecture for defer: "+b.archFamily())
} }
asmType := llvm.FunctionType(resultType, []llvm.Type{b.dataPtrType}, false) asmType := llvm.FunctionType(resultType, []llvm.Type{b.deferFrame.Type()}, false)
asm := llvm.InlineAsm(asmType, asmString, constraints, false, false, 0, false) asm := llvm.InlineAsm(asmType, asmString, constraints, false, false, 0, false)
result := b.CreateCall(asmType, asm, []llvm.Value{ptr}, "setjmp") result := b.CreateCall(asmType, asm, []llvm.Value{b.deferFrame}, "setjmp")
result.AddCallSiteAttribute(-1, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("returns_twice"), 0)) result.AddCallSiteAttribute(-1, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("returns_twice"), 0))
isZero := b.CreateICmp(llvm.IntEQ, result, llvm.ConstInt(resultType, 0, false), "setjmp.result") isZero := b.CreateICmp(llvm.IntEQ, result, llvm.ConstInt(resultType, 0, false), "setjmp.result")
return isZero
}
// createInvokeCheckpoint saves the function state at the given point, to
// continue at the landing pad if a panic happened. This is implemented using a
// setjmp-like construct.
func (b *builder) createInvokeCheckpoint() {
isZero := b.createCheckpoint(b.deferFrame)
continueBB := b.insertBasicBlock("") continueBB := b.insertBasicBlock("")
b.CreateCondBr(isZero, continueBB, b.landingpad) b.CreateCondBr(isZero, continueBB, b.landingpad)
b.SetInsertPointAtEnd(continueBB) b.SetInsertPointAtEnd(continueBB)
-12
View File
@@ -249,15 +249,3 @@ func (b *builder) emitCSROperation(call *ssa.CallCommon) (llvm.Value, error) {
return llvm.Value{}, b.makeError(call.Pos(), "unknown CSR operation: "+name) return llvm.Value{}, b.makeError(call.Pos(), "unknown CSR operation: "+name)
} }
} }
// Implement runtime/interrupt.Checkpoint.Save. It needs to be implemented
// directly at the call site. If it isn't implemented directly at the call site
// (but instead through a function call), it might result in an overwritten
// stack in the non-jump return case.
func (b *builder) createInterruptCheckpoint(ptr ssa.Value) llvm.Value {
addr := b.getValue(ptr, ptr.Pos())
b.createNilCheck(ptr, addr, "deref")
stackPointer := b.readStackPointer()
b.CreateStore(stackPointer, addr)
return b.createCheckpoint(addr)
}
+2 -5
View File
@@ -122,9 +122,6 @@ func (c *compilerContext) pkgPathPtr(pkgpath string) llvm.Value {
// This function returns a pointer to the 'kind' field (which might not be the // This function returns a pointer to the 'kind' field (which might not be the
// first field in the struct). // first field in the struct).
func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value { func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
// Resolve alias types: alias types are resolved at compile time.
typ = types.Unalias(typ)
ms := c.program.MethodSets.MethodSet(typ) ms := c.program.MethodSets.MethodSet(typ)
hasMethodSet := ms.Len() != 0 hasMethodSet := ms.Len() != 0
_, isInterface := typ.Underlying().(*types.Interface) _, isInterface := typ.Underlying().(*types.Interface)
@@ -515,7 +512,7 @@ var basicTypeNames = [...]string{
// interface lowering pass to assign type codes as expected by the reflect // interface lowering pass to assign type codes as expected by the reflect
// package. See getTypeCodeNum. // package. See getTypeCodeNum.
func getTypeCodeName(t types.Type) (string, bool) { func getTypeCodeName(t types.Type) (string, bool) {
switch t := types.Unalias(t).(type) { switch t := t.(type) {
case *types.Named: case *types.Named:
if t.Obj().Parent() != t.Obj().Pkg().Scope() { if t.Obj().Parent() != t.Obj().Pkg().Scope() {
return "named:" + t.String() + "$local", true return "named:" + t.String() + "$local", true
@@ -945,7 +942,7 @@ func signature(sig *types.Signature) string {
// normalization around `byte` vs `uint8` for example. // normalization around `byte` vs `uint8` for example.
func typestring(t types.Type) string { func typestring(t types.Type) string {
// See: https://github.com/golang/go/blob/master/src/go/types/typestring.go // See: https://github.com/golang/go/blob/master/src/go/types/typestring.go
switch t := types.Unalias(t).(type) { switch t := t.(type) {
case *types.Array: case *types.Array:
return "[" + strconv.FormatInt(t.Len(), 10) + "]" + typestring(t.Elem()) return "[" + strconv.FormatInt(t.Len(), 10) + "]" + typestring(t.Elem())
case *types.Basic: case *types.Basic:
-23
View File
@@ -121,29 +121,6 @@ func (b *builder) createKeepAliveImpl() {
b.CreateRetVoid() b.CreateRetVoid()
} }
// createAbiEscapeImpl implements the generic internal/abi.Escape function. It
// currently only supports pointer types.
func (b *builder) createAbiEscapeImpl() {
b.createFunctionStart(true)
// The first parameter is assumed to be a pointer. This is checked at the
// call site of createAbiEscapeImpl.
pointerValue := b.getValue(b.fn.Params[0], getPos(b.fn))
// Create an equivalent of the following C code, which is basically just a
// nop but ensures the pointerValue is kept alive:
//
// __asm__ __volatile__("" : : "r"(pointerValue))
//
// It should be portable to basically everything as the "r" register type
// exists basically everywhere.
asmType := llvm.FunctionType(b.dataPtrType, []llvm.Type{b.dataPtrType}, false)
asmFn := llvm.InlineAsm(asmType, "", "=r,0", true, false, 0, false)
result := b.createCall(asmType, asmFn, []llvm.Value{pointerValue}, "")
b.CreateRet(result)
}
var mathToLLVMMapping = map[string]string{ var mathToLLVMMapping = map[string]string{
"math.Ceil": "llvm.ceil.f64", "math.Ceil": "llvm.ceil.f64",
"math.Exp": "llvm.exp.f64", "math.Exp": "llvm.exp.f64",
+7 -15
View File
@@ -371,6 +371,13 @@ func (c *compilerContext) getPointerBitmap(typ llvm.Type, pos token.Pos) *big.In
return big.NewInt(1) return big.NewInt(1)
case llvm.StructTypeKind: case llvm.StructTypeKind:
ptrs := big.NewInt(0) ptrs := big.NewInt(0)
if typ.StructName() == "runtime.funcValue" {
// Hack: the type runtime.funcValue contains an 'id' field which is
// of type uintptr, but before the LowerFuncValues pass it actually
// contains a pointer (ptrtoint) to a global. This trips up the
// interp package. Therefore, make the id field a pointer for now.
typ = c.ctx.StructType([]llvm.Type{c.dataPtrType, c.dataPtrType}, false)
}
for i, subtyp := range typ.StructElementTypes() { for i, subtyp := range typ.StructElementTypes() {
subptrs := c.getPointerBitmap(subtyp, pos) subptrs := c.getPointerBitmap(subtyp, pos)
if subptrs.BitLen() == 0 { if subptrs.BitLen() == 0 {
@@ -452,21 +459,6 @@ func (b *builder) readStackPointer() llvm.Value {
return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "") return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "")
} }
// writeStackPointer emits a LLVM intrinsic call that updates the current stack
// pointer.
func (b *builder) writeStackPointer(sp llvm.Value) {
name := "llvm.stackrestore.p0"
if llvmutil.Version() < 18 {
name = "llvm.stackrestore" // backwards compatibility with LLVM 17 and below
}
stackrestore := b.mod.NamedFunction(name)
if stackrestore.IsNil() {
fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.dataPtrType}, false)
stackrestore = llvm.AddFunction(b.mod, name, fnType)
}
b.CreateCall(stackrestore.GlobalValueType(), stackrestore, []llvm.Value{sp}, "")
}
// createZExtOrTrunc lets the input value fit in the output type bits, by zero // createZExtOrTrunc lets the input value fit in the output type bits, by zero
// extending or truncating the integer. // extending or truncating the integer.
func (b *builder) createZExtOrTrunc(value llvm.Value, t llvm.Type) llvm.Value { func (b *builder) createZExtOrTrunc(value llvm.Value, t llvm.Type) llvm.Value {
+1 -1
View File
@@ -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-") {
+3 -1
View File
@@ -248,7 +248,7 @@ func (b *builder) createMapIteratorNext(rangeVal ssa.Value, llvmRangeVal, it llv
// can be compared with runtime.memequal. Note that padding bytes are undef // can be compared with runtime.memequal. Note that padding bytes are undef
// and can alter two "equal" structs being equal when compared with memequal. // and can alter two "equal" structs being equal when compared with memequal.
func hashmapIsBinaryKey(keyType types.Type) bool { func hashmapIsBinaryKey(keyType types.Type) bool {
switch keyType := keyType.Underlying().(type) { switch keyType := keyType.(type) {
case *types.Basic: case *types.Basic:
return keyType.Info()&(types.IsBoolean|types.IsInteger) != 0 return keyType.Info()&(types.IsBoolean|types.IsInteger) != 0
case *types.Pointer: case *types.Pointer:
@@ -263,6 +263,8 @@ func hashmapIsBinaryKey(keyType types.Type) bool {
return true return true
case *types.Array: case *types.Array:
return hashmapIsBinaryKey(keyType.Elem()) return hashmapIsBinaryKey(keyType.Elem())
case *types.Named:
return hashmapIsBinaryKey(keyType.Underlying())
default: default:
return false return false
} }
+10 -50
View File
@@ -208,12 +208,8 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
// > circumstances, and should not be exposed to source languages. // > circumstances, and should not be exposed to source languages.
llvmutil.AppendToGlobal(c.mod, "llvm.compiler.used", llvmFn) llvmutil.AppendToGlobal(c.mod, "llvm.compiler.used", llvmFn)
} }
case "GetModuleHandleExA", "GetProcAddress", "GetSystemInfo", "GetSystemTimeAsFileTime", "LoadLibraryExW", "QueryPerformanceCounter", "QueryPerformanceFrequency", "QueryUnbiasedInterruptTime", "SetEnvironmentVariableA", "Sleep", "SystemFunction036", "VirtualAlloc": case "tinygo_exitTask", "tinygo_schedulerUnlock":
// On Windows we need to use a special calling convention for some llvmutil.AppendToGlobal(c.mod, "llvm.used", llvmFn)
// external calls.
if c.GOOS == "windows" && c.GOARCH == "386" {
llvmFn.SetFunctionCallConv(llvm.X86StdcallCallConv)
}
} }
// External/exported functions may not retain pointer values. // External/exported functions may not retain pointer values.
@@ -253,23 +249,6 @@ func (c *compilerContext) maybeCreateSyntheticFunction(fn *ssa.Function, llvmFn
// The exception is the package initializer, which does appear in the // The exception is the package initializer, which does appear in the
// *ssa.Package members and so shouldn't be created here. // *ssa.Package members and so shouldn't be created here.
if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" { if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" {
if origin := fn.Origin(); origin != nil && origin.RelString(nil) == "internal/abi.Escape" {
// This is a special implementation or internal/abi.Escape, which
// can only really be implemented in the compiler.
// For simplicity we'll only implement pointer parameters for now.
if _, ok := fn.Params[0].Type().Underlying().(*types.Pointer); ok {
irbuilder := c.ctx.NewBuilder()
defer irbuilder.Dispose()
b := newBuilder(c, irbuilder, fn)
b.createAbiEscapeImpl()
llvmFn.SetLinkage(llvm.LinkOnceODRLinkage)
llvmFn.SetUnnamedAddr(true)
}
// If the parameter is not of a pointer type, it will be left
// unimplemented. This will result in a linker error if the function
// is really called, making it clear it needs to be implemented.
return
}
if len(fn.Blocks) == 0 { if len(fn.Blocks) == 0 {
c.addError(fn.Pos(), "missing function body") c.addError(fn.Pos(), "missing function body")
return return
@@ -306,11 +285,6 @@ func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo {
info.wasmName = "_start" info.wasmName = "_start"
info.exported = true info.exported = true
} }
if info.linkName == "runtime.wasmEntryLegacy" && c.BuildMode == "wasi-legacy" {
info.linkName = "_start"
info.wasmName = "_start"
info.exported = true
}
// Check for //go: pragmas, which may change the link name (among others). // Check for //go: pragmas, which may change the link name (among others).
c.parsePragmas(&info, f) c.parsePragmas(&info, f)
@@ -455,16 +429,13 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
// pass for C variadic functions. This includes both explicit // pass for C variadic functions. This includes both explicit
// (with ...) and implicit (no parameters in signature) // (with ...) and implicit (no parameters in signature)
// functions. // functions.
if strings.HasPrefix(f.Name(), "_Cgo_") { if strings.HasPrefix(f.Name(), "C.") {
// This prefix was created as a result of CGo preprocessing. // This prefix cannot naturally be created, it must have
// been created as a result of CGo preprocessing.
info.variadic = true info.variadic = true
} }
} }
} }
if c.Nobounds {
info.nobounds = true
}
} }
// Check whether this function can be used in //go:wasmimport or // Check whether this function can be used in //go:wasmimport or
@@ -473,7 +444,7 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
// The list of allowed types is based on this proposal: // The list of allowed types is based on this proposal:
// https://github.com/golang/go/issues/59149 // https://github.com/golang/go/issues/59149
func (c *compilerContext) checkWasmImportExport(f *ssa.Function, pragma string) { func (c *compilerContext) checkWasmImportExport(f *ssa.Function, pragma string) {
if c.pkg.Path() == "runtime" || c.pkg.Path() == "syscall/js" || c.pkg.Path() == "syscall" || c.pkg.Path() == "crypto/internal/sysrand" { if c.pkg.Path() == "runtime" || c.pkg.Path() == "syscall/js" || c.pkg.Path() == "syscall" {
// The runtime is a special case. Allow all kinds of parameters // The runtime is a special case. Allow all kinds of parameters
// (importantly, including pointers). // (importantly, including pointers).
return return
@@ -630,7 +601,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 +686,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 +714,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]
}
} }
} }
} }
+1 -24
View File
@@ -268,8 +268,6 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) {
// The signature looks like this: // The signature looks like this:
// func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) // func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
isI386 := strings.HasPrefix(b.Triple, "i386-")
// Prepare input values. // Prepare input values.
var paramTypes []llvm.Type var paramTypes []llvm.Type
var params []llvm.Value var params []llvm.Value
@@ -287,17 +285,11 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) {
if setLastError.IsNil() { if setLastError.IsNil() {
llvmType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.ctx.Int32Type()}, false) llvmType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.ctx.Int32Type()}, false)
setLastError = llvm.AddFunction(b.mod, "SetLastError", llvmType) setLastError = llvm.AddFunction(b.mod, "SetLastError", llvmType)
if isI386 {
setLastError.SetFunctionCallConv(llvm.X86StdcallCallConv)
}
} }
getLastError := b.mod.NamedFunction("GetLastError") getLastError := b.mod.NamedFunction("GetLastError")
if getLastError.IsNil() { if getLastError.IsNil() {
llvmType := llvm.FunctionType(b.ctx.Int32Type(), nil, false) llvmType := llvm.FunctionType(b.ctx.Int32Type(), nil, false)
getLastError = llvm.AddFunction(b.mod, "GetLastError", llvmType) getLastError = llvm.AddFunction(b.mod, "GetLastError", llvmType)
if isI386 {
getLastError.SetFunctionCallConv(llvm.X86StdcallCallConv)
}
} }
// Now do the actual call. Pseudocode: // Now do the actual call. Pseudocode:
@@ -308,24 +300,9 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) {
// Note that SetLastError/GetLastError could be replaced with direct // Note that SetLastError/GetLastError could be replaced with direct
// access to the thread control block, which is probably smaller and // access to the thread control block, which is probably smaller and
// faster. The Go runtime does this in assembly. // faster. The Go runtime does this in assembly.
// On windows/386, we also need to save/restore the stack pointer. I'm b.CreateCall(setLastError.GlobalValueType(), setLastError, []llvm.Value{llvm.ConstNull(b.ctx.Int32Type())}, "")
// not entirely sure why this is needed, but without it these calls
// change the stack pointer leading to a crash soon after.
setLastErrorCall := b.CreateCall(setLastError.GlobalValueType(), setLastError, []llvm.Value{llvm.ConstNull(b.ctx.Int32Type())}, "")
var sp llvm.Value
if isI386 {
setLastErrorCall.SetInstructionCallConv(llvm.X86StdcallCallConv)
sp = b.readStackPointer()
}
syscallResult := b.CreateCall(llvmType, fnPtr, params, "") syscallResult := b.CreateCall(llvmType, fnPtr, params, "")
if isI386 {
syscallResult.SetInstructionCallConv(llvm.X86StdcallCallConv)
b.writeStackPointer(sp)
}
errResult := b.CreateCall(getLastError.GlobalValueType(), getLastError, nil, "err") errResult := b.CreateCall(getLastError.GlobalValueType(), getLastError, nil, "err")
if isI386 {
errResult.SetInstructionCallConv(llvm.X86StdcallCallConv)
}
if b.uintptrType != b.ctx.Int32Type() { if b.uintptrType != b.ctx.Int32Type() {
errResult = b.CreateZExt(errResult, b.uintptrType, "err.uintptr") errResult = b.CreateZExt(errResult, b.uintptrType, "err.uintptr")
} }
+4 -4
View File
@@ -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 }
+7 -7
View File
@@ -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
View File
@@ -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
+4 -4
View File
@@ -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" }
+4 -4
View File
@@ -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 }
+11 -11
View File
@@ -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 }
+4 -4
View File
@@ -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 }
+6 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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 }
+8 -8
View File
@@ -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 }
+4 -4
View File
@@ -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 }
+11 -11
View File
@@ -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" }
+6 -6
View File
@@ -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 }
+6 -6
View File
@@ -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 }
+19 -19
View File
@@ -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 }
+20 -40
View File
@@ -10,7 +10,6 @@ import (
"go/types" "go/types"
"io" "io"
"path/filepath" "path/filepath"
"reflect"
"sort" "sort"
"strings" "strings"
@@ -24,11 +23,6 @@ import (
type Diagnostic struct { type Diagnostic struct {
Pos token.Position Pos token.Position
Msg string Msg string
// Start and end position, if available. For many errors these positions are
// not available, but for some they are.
StartPos token.Position
EndPos token.Position
} }
// One or multiple errors of a particular package. // One or multiple errors of a particular package.
@@ -120,22 +114,12 @@ func createPackageDiagnostic(err error) PackageDiagnostic {
func createDiagnostics(err error) []Diagnostic { func createDiagnostics(err error) []Diagnostic {
switch err := err.(type) { switch err := err.(type) {
case types.Error: case types.Error:
diag := Diagnostic{ return []Diagnostic{
Pos: err.Fset.Position(err.Pos), {
Msg: err.Msg, Pos: err.Fset.Position(err.Pos),
Msg: err.Msg,
},
} }
// There is a special unexported API since Go 1.16 that provides the
// range (start and end position) where the type error exists.
// There is no promise of backwards compatibility in future Go versions
// so we have to be extra careful here to be resilient.
v := reflect.ValueOf(err)
start := v.FieldByName("go116start")
end := v.FieldByName("go116end")
if start.IsValid() && end.IsValid() && start.Int() != end.Int() {
diag.StartPos = err.Fset.Position(token.Pos(start.Int()))
diag.EndPos = err.Fset.Position(token.Pos(end.Int()))
}
return []Diagnostic{diag}
case scanner.Error: case scanner.Error:
return []Diagnostic{ return []Diagnostic{
{ {
@@ -204,29 +188,25 @@ func (diag Diagnostic) WriteTo(w io.Writer, wd string) {
fmt.Fprintln(w, diag.Msg) fmt.Fprintln(w, diag.Msg)
return return
} }
pos := RelativePosition(diag.Pos, wd) pos := diag.Pos // make a copy
if !strings.HasPrefix(pos.Filename, filepath.Join(goenv.Get("GOROOT"), "src")) && !strings.HasPrefix(pos.Filename, filepath.Join(goenv.Get("TINYGOROOT"), "src")) {
// This file is not from the standard library (either the GOROOT or the
// TINYGOROOT). Make the path relative, for easier reading. Ignore any
// errors in the process (falling back to the absolute path).
pos.Filename = tryToMakePathRelative(pos.Filename, wd)
}
fmt.Fprintf(w, "%s: %s\n", pos, diag.Msg) fmt.Fprintf(w, "%s: %s\n", pos, diag.Msg)
} }
// Convert the position in pos (assumed to have an absolute path) into a // try to make the path relative to the current working directory. If any error
// relative path if possible. Paths inside GOROOT/TINYGOROOT will remain // occurs, this error is ignored and the absolute path is returned instead.
// absolute. func tryToMakePathRelative(dir, wd string) string {
func RelativePosition(pos token.Position, wd string) token.Position {
// Check whether we even have a working directory.
if wd == "" { if wd == "" {
return pos return dir // working directory not found
} }
relpath, err := filepath.Rel(wd, dir)
// Paths inside GOROOT should be printed in full. if err != nil {
if strings.HasPrefix(pos.Filename, filepath.Join(goenv.Get("GOROOT"), "src")) || strings.HasPrefix(pos.Filename, filepath.Join(goenv.Get("TINYGOROOT"), "src")) { return dir
return pos
} }
return relpath
// Make the path relative, for easier reading. Ignore any errors in the
// process (falling back to the absolute path).
relpath, err := filepath.Rel(wd, pos.Filename)
if err == nil {
pos.Filename = relpath
}
return pos
} }
+1 -6
View File
@@ -8,7 +8,6 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/tinygo-org/tinygo/builder"
"github.com/tinygo-org/tinygo/compileopts" "github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/diagnostics" "github.com/tinygo-org/tinygo/diagnostics"
) )
@@ -65,11 +64,7 @@ func testErrorMessages(t *testing.T, filename string, options *compileopts.Optio
// Try to build a binary (this should fail with an error). // Try to build a binary (this should fail with an error).
tmpdir := t.TempDir() tmpdir := t.TempDir()
config, err := builder.NewConfig(options) err := Build(filename, tmpdir+"/out", options)
if err != nil {
t.Fatal("expected to get a compiler error")
}
err = Build(filename, tmpdir+"/out", config)
if err == nil { if err == nil {
t.Fatal("expected to get a compiler error") t.Fatal("expected to get a compiler error")
} }
Generated
+4 -4
View File
@@ -20,16 +20,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1747953325, "lastModified": 1728500571,
"narHash": "sha256-y2ZtlIlNTuVJUZCqzZAhIw5rrKP4DOSklev6c8PyCkQ=", "narHash": "sha256-dOymOQ3AfNI4Z337yEwHGohrVQb4yPODCW9MDUyAc4w=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "55d1f923c480dadce40f5231feb472e81b0bab48", "rev": "d51c28603def282a24fa034bcb007e2bcb5b5dd0",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "nixos-25.05", "ref": "nixos-24.05",
"type": "indirect" "type": "indirect"
} }
}, },
+14 -5
View File
@@ -21,6 +21,7 @@
# make llvm-source # fetch compiler-rt # make llvm-source # fetch compiler-rt
# git submodule update --init # fetch lots of other libraries and SVD files # git submodule update --init # fetch lots of other libraries and SVD files
# make gen-device -j4 # build src/device/*/*.go files # make gen-device -j4 # build src/device/*/*.go files
# make wasi-libc # build support for wasi/wasm
# #
# With this, you should have an environment that can compile anything - except # With this, you should have an environment that can compile anything - except
# for the Xtensa architecture (ESP8266/ESP32) because support for that lives in # for the Xtensa architecture (ESP8266/ESP32) because support for that lives in
@@ -34,7 +35,7 @@
inputs = { inputs = {
# Use a recent stable release, but fix the version to make it reproducible. # Use a recent stable release, but fix the version to make it reproducible.
# This version should be updated from time to time. # This version should be updated from time to time.
nixpkgs.url = "nixpkgs/nixos-25.05"; nixpkgs.url = "nixpkgs/nixos-24.05";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { self, nixpkgs, flake-utils }: outputs = { self, nixpkgs, flake-utils }:
@@ -48,11 +49,11 @@
buildInputs = [ buildInputs = [
# These dependencies are required for building tinygo (go install). # These dependencies are required for building tinygo (go install).
go go
llvmPackages_20.llvm llvmPackages_18.llvm
llvmPackages_20.libclang llvmPackages_18.libclang
# Additional dependencies needed at runtime, for building and/or # Additional dependencies needed at runtime, for building and/or
# flashing. # flashing.
llvmPackages_20.lld llvmPackages_18.lld
avrdude avrdude
binaryen binaryen
# Additional dependencies needed for on-chip debugging. # Additional dependencies needed for on-chip debugging.
@@ -63,12 +64,20 @@
#openocd #openocd
]; ];
shellHook= '' shellHook= ''
# Configure CLANG, LLVM_AR, and LLVM_NM for `make wasi-libc`.
# Without setting these explicitly, Homebrew versions might be used
# or the default `ar` and `nm` tools might be used (which don't
# support wasi).
export CLANG="clang-18 -resource-dir ${llvmPackages_18.clang.cc.lib}/lib/clang/18"
export LLVM_AR=llvm-ar
export LLVM_NM=llvm-nm
# Make `make smoketest` work (the default is `md5`, while Nix only # Make `make smoketest` work (the default is `md5`, while Nix only
# has `md5sum`). # has `md5sum`).
export MD5SUM=md5sum export MD5SUM=md5sum
# Ugly hack to make the Clang resources directory available. # Ugly hack to make the Clang resources directory available.
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_20.clang.cc.lib}/lib/clang/20\" -tags=llvm20" export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_18.clang.cc.lib}/lib/clang/18\" -tags=llvm18"
''; '';
}; };
} }
+15 -7
View File
@@ -1,10 +1,12 @@
module github.com/tinygo-org/tinygo module github.com/tinygo-org/tinygo
go 1.22.0 go 1.19
require ( require (
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139 github.com/aykevl/go-wasm v0.0.2-0.20240825160117-b76c3f9f0982
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
@@ -14,16 +16,22 @@ require (
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
github.com/tetratelabs/wazero v1.6.0 github.com/tetratelabs/wazero v1.6.0
go.bug.st/serial v1.6.0 go.bug.st/serial v1.6.0
golang.org/x/net v0.35.0 golang.org/x/net v0.26.0
golang.org/x/sys v0.30.0 golang.org/x/sys v0.21.0
golang.org/x/tools v0.30.0 golang.org/x/tools v0.22.1-0.20240621165957-db513b091504
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74 tinygo.org/x/go-llvm v0.0.0-20250119132755-9dca92dfb4f9
) )
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.16.0 // indirect
) )
+35 -19
View File
@@ -1,17 +1,33 @@
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139 h1:2O/WuAt8J5id3khcAtVB90czG80m+v0sfkLE07GrCVg= github.com/aykevl/go-wasm v0.0.2-0.20240825160117-b76c3f9f0982 h1:cD7QfvrJdYmBw2tFP/VyKPT8ZESlcrwSwo7SvH9Y4dc=
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw= github.com/aykevl/go-wasm v0.0.2-0.20240825160117-b76c3f9f0982/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/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,8 +41,9 @@ 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/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs= github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA= github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
@@ -35,28 +52,27 @@ github.com/tetratelabs/wazero v1.6.0 h1:z0H1iikCdP8t+q341xqepY4EWvHEw8Es7tlqiVzl
github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A= github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
go.bug.st/serial v1.6.0 h1:mAbRGN4cKE2J5gMwsMHC2KQisdLRQssO9WSM+rbZJ8A= go.bug.st/serial v1.6.0 h1:mAbRGN4cKE2J5gMwsMHC2KQisdLRQssO9WSM+rbZJ8A=
go.bug.st/serial v1.6.0/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE= go.bug.st/serial v1.6.0/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-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.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= golang.org/x/tools v0.22.1-0.20240621165957-db513b091504 h1:MMsD8mMfluf/578+3wrTn22pjI/Xkzm+gPW47SYfspY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/tools v0.22.1-0.20240621165957-db513b091504/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= tinygo.org/x/go-llvm v0.0.0-20250119132755-9dca92dfb4f9 h1:rMvEzuCYjyiR+pmdiCVWTQw3L6VqiSIXoL19I3lYufE=
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74 h1:ovavgTdIBWCH8YWlcfq9gkpoyT1+IxMKSn+Df27QwE8= tinygo.org/x/go-llvm v0.0.0-20250119132755-9dca92dfb4f9/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+1 -1
View File
@@ -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.36.0-dev"
// 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).
+8 -12
View File
@@ -1,22 +1,18 @@
module github.com/tinygo-org/tinygo/internal/wasm-tools module github.com/tinygo-org/tinygo/internal/tools
go 1.23.0 go 1.22.4
require ( require github.com/bytecodealliance/wasm-tools-go v0.3.1
go.bytecodealliance.org v0.6.2
go.bytecodealliance.org/cm v0.2.2
)
require ( require (
github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/compress v1.17.9 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/regclient/regclient v0.8.2 // indirect github.com/regclient/regclient v0.7.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tetratelabs/wazero v1.9.0 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect github.com/ulikunitz/xz v0.5.12 // indirect
github.com/urfave/cli/v3 v3.0.0-beta1 // indirect github.com/urfave/cli/v3 v3.0.0-alpha9.2 // indirect
golang.org/x/mod v0.24.0 // indirect golang.org/x/mod v0.21.0 // indirect
golang.org/x/sys v0.31.0 // indirect golang.org/x/sys v0.26.0 // indirect
) )
+18 -22
View File
@@ -1,3 +1,5 @@
github.com/bytecodealliance/wasm-tools-go v0.3.1 h1:9Q9PjSzkbiVmkUvZ7nYCfJ02mcQDBalxycA3s8g7kR4=
github.com/bytecodealliance/wasm-tools-go v0.3.1/go.mod h1:vNAQ8DAEp6xvvk+TUHah5DslLEa76f4H6e737OeaxuY=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -5,16 +7,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/olareg/olareg v0.1.1 h1:Ui7q93zjcoF+U9U71sgqgZWByDoZOpqHitUXEu2xV+g= github.com/olareg/olareg v0.1.0 h1:1dXBOgPrig5N7zoXyIZVQqU0QBo6sD9pbL6UYjY75CA=
github.com/olareg/olareg v0.1.1/go.mod h1:w8NP4SWrHHtxsFaUiv1lnCnYPm4sN1seCd2h7FK/dc0= github.com/olareg/olareg v0.1.0/go.mod h1:RBuU7JW7SoIIxZKzLRhq8sVtQeAHzCAtRrXEBx2KlM4=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 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/regclient/regclient v0.8.2 h1:23BQ3jWgKYHHIXUhp/S9laVJDHDoOQaQCzXMJ4undVE= github.com/regclient/regclient v0.7.1 h1:qEsJrTmZd98fZKjueAbrZCSNGU+ifnr6xjlSAs3WOPs=
github.com/regclient/regclient v0.8.2/go.mod h1:uGyetv0o6VLyRDjtfeBqp/QBwRLJ3Hcn07/+8QbhNcM= github.com/regclient/regclient v0.7.1/go.mod h1:+w/BFtJuw0h0nzIw/z2+1FuA2/dVXBzDq4rYmziJpMc=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
@@ -23,25 +25,19 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg= github.com/urfave/cli/v3 v3.0.0-alpha9.2 h1:CL8llQj3dGRLVQQzHxS+ZYRLanOuhyK1fXgLKD+qV+Y=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y= github.com/urfave/cli/v3 v3.0.0-alpha9.2/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
go.bytecodealliance.org v0.6.2 h1:Jy4u5DVmSkXgsnwojBhJ+AD/YsJsR3VzVnxF0xRCqTQ= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
go.bytecodealliance.org v0.6.2/go.mod h1:gqjTJm0y9NSksG4py/lSjIQ/SNuIlOQ+hCIEPQwtJgA= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+2 -3
View File
@@ -5,8 +5,7 @@
package tools package tools
import ( import (
_ "go.bytecodealliance.org/cm" _ "github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go"
_ "go.bytecodealliance.org/cmd/wit-bindgen-go"
) )
//go:generate go install go.bytecodealliance.org/cmd/wit-bindgen-go //go:generate go install github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go
+5 -18
View File
@@ -364,22 +364,9 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
continue continue
} }
nBytes := uint32(n * elemSize) nBytes := uint32(n * elemSize)
srcObj := mem.get(src.index())
dstObj := mem.getWritable(dst.index()) dstObj := mem.getWritable(dst.index())
if srcObj.buffer == nil || dstObj.buffer == nil {
// If the buffer is nil, it means the slice is external.
// This can happen for example when copying data out of
// a //go:embed slice, which is not available at interp
// time.
// See: https://github.com/tinygo-org/tinygo/issues/4895
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
if err != nil {
return nil, mem, err
}
continue
}
dstBuf := dstObj.buffer.asRawValue(r) dstBuf := dstObj.buffer.asRawValue(r)
srcBuf := srcObj.buffer.asRawValue(r) srcBuf := mem.get(src.index()).buffer.asRawValue(r)
copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():]) copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():])
dstObj.buffer = dstBuf dstObj.buffer = dstBuf
mem.put(dst.index(), dstObj) mem.put(dst.index(), dstObj)
@@ -577,7 +564,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)
@@ -983,9 +970,9 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me
case llvm.Call: case llvm.Call:
llvmFn := operands[len(operands)-1] llvmFn := operands[len(operands)-1]
args := operands[:len(operands)-1] args := operands[:len(operands)-1]
for _, op := range operands { for _, arg := range args {
if op.Type().TypeKind() == llvm.PointerTypeKind { if arg.Type().TypeKind() == llvm.PointerTypeKind {
err := mem.markExternalStore(op) err := mem.markExternalStore(arg)
if err != nil { if err != nil {
return r.errorAt(inst, err) return r.errorAt(inst, err)
} }
+13
View File
@@ -824,6 +824,19 @@ func (v rawValue) rawLLVMValue(mem *memoryView) (llvm.Value, error) {
if err != nil { if err != nil {
return llvm.Value{}, err return llvm.Value{}, err
} }
if !field.IsAGlobalVariable().IsNil() {
elementType := field.GlobalValueType()
if elementType.TypeKind() == llvm.StructTypeKind {
// There are some special pointer types that should be used
// as a ptrtoint, so that they can be used in certain
// optimizations.
name := elementType.StructName()
if name == "runtime.funcValueWithSignature" {
uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8)
field = llvm.ConstPtrToInt(field, uintptrType)
}
}
}
structFields = append(structFields, field) structFields = append(structFields, field)
i += mem.r.pointerSize i += mem.r.pointerSize
continue continue
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
-18
View File
@@ -11,10 +11,6 @@ target triple = "x86_64--linux"
@main.sliceDstUntaint.buf = internal global [2 x i8] zeroinitializer @main.sliceDstUntaint.buf = internal global [2 x i8] zeroinitializer
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd" @main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
@main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer @main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer
@main.sliceSrcExternal1.buf = external global [2 x i8]
@main.sliceDstExternal1.buf = internal global [2 x i8] zeroinitializer
@main.sliceSrcExternal2.buf = internal global [2 x i8] zeroinitializer
@main.sliceDstExternal2.buf = external global [2 x i8]
declare i64 @runtime.sliceCopy(ptr %dst, ptr %src, i64 %dstLen, i64 %srcLen, i64 %elemSize) unnamed_addr declare i64 @runtime.sliceCopy(ptr %dst, ptr %src, i64 %dstLen, i64 %srcLen, i64 %elemSize) unnamed_addr
@@ -62,14 +58,6 @@ entry:
%sliceDstTaint.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstTaint.buf, i32 0) %sliceDstTaint.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstTaint.buf, i32 0)
call void @runtime.printuint8(i8 %sliceDstTaint.val) call void @runtime.printuint8(i8 %sliceDstTaint.val)
; print(sliceDstExternal1[0])
%sliceDstExternal1.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstExternal1.buf, i32 0)
call void @runtime.printuint8(i8 %sliceDstExternal1.val)
; print(sliceDstExternal2[0])
%sliceDstExternal2.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstExternal2.buf, i32 0)
call void @runtime.printuint8(i8 %sliceDstExternal2.val)
ret void ret void
} }
@@ -114,11 +102,5 @@ entry:
call void @use(ptr @main.sliceSrcTaint.buf) call void @use(ptr @main.sliceSrcTaint.buf)
%copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1) %copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1)
; Test that copying from or into external buffers works correctly.
; These copy operations must be done at runtime.
; https://github.com/tinygo-org/tinygo/issues/4895
%copy.n5 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal1.buf, ptr @main.sliceSrcExternal1.buf, i64 2, i64 2, i64 1)
%copy.n6 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal2.buf, ptr @main.sliceSrcExternal2.buf, i64 2, i64 2, i64 1)
ret void ret void
} }
-10
View File
@@ -3,10 +3,6 @@ target triple = "x86_64--linux"
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd" @main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
@main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer @main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer
@main.sliceSrcExternal1.buf = external global [2 x i8]
@main.sliceDstExternal1.buf = internal global [2 x i8] zeroinitializer
@main.sliceSrcExternal2.buf = internal global [2 x i8] zeroinitializer
@main.sliceDstExternal2.buf = external global [2 x i8]
declare i64 @runtime.sliceCopy(ptr, ptr, i64, i64, i64) unnamed_addr declare i64 @runtime.sliceCopy(ptr, ptr, i64, i64, i64) unnamed_addr
@@ -20,8 +16,6 @@ define void @runtime.initAll() unnamed_addr {
entry: entry:
call void @use(ptr @main.sliceSrcTaint.buf) call void @use(ptr @main.sliceSrcTaint.buf)
%copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1) %copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1)
%copy.n5 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal1.buf, ptr @main.sliceSrcExternal1.buf, i64 2, i64 2, i64 1)
%copy.n6 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal2.buf, ptr @main.sliceSrcExternal2.buf, i64 2, i64 2, i64 1)
ret void ret void
} }
@@ -34,9 +28,5 @@ entry:
call void @runtime.printuint8(i8 97) call void @runtime.printuint8(i8 97)
%sliceDstTaint.val = load i8, ptr @main.sliceDstTaint.buf, align 1 %sliceDstTaint.val = load i8, ptr @main.sliceDstTaint.buf, align 1
call void @runtime.printuint8(i8 %sliceDstTaint.val) call void @runtime.printuint8(i8 %sliceDstTaint.val)
%sliceDstExternal1.val = load i8, ptr @main.sliceDstExternal1.buf, align 1
call void @runtime.printuint8(i8 %sliceDstExternal1.val)
%sliceDstExternal2.val = load i8, ptr @main.sliceDstExternal2.buf, align 1
call void @runtime.printuint8(i8 %sliceDstExternal2.val)
ret void ret void
} }
Submodule lib/bdwgc deleted from 1166f11f7d
-2
View File
@@ -269,8 +269,6 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
if needsSyscallPackage { if needsSyscallPackage {
paths["syscall/"] = true // include syscall/js paths["syscall/"] = true // include syscall/js
paths["internal/syscall/"] = true
paths["internal/syscall/unix/"] = false
} }
return paths return paths
} }
+1 -3
View File
@@ -8,9 +8,7 @@ import (
// //
// The program must already be parsed and type-checked with the .Parse() method. // The program must already be parsed and type-checked with the .Parse() method.
func (p *Program) LoadSSA() *ssa.Program { func (p *Program) LoadSSA() *ssa.Program {
// TODO: re-enable SanityCheckFunctions when x/tools is upgraded to prog := ssa.NewProgram(p.fset, ssa.SanityCheckFunctions|ssa.BareInits|ssa.GlobalDebug|ssa.InstantiateGenerics)
// a version with a fix for https://golang.org/issues/73594.
prog := ssa.NewProgram(p.fset /*ssa.SanityCheckFunctions|*/, ssa.BareInits|ssa.GlobalDebug|ssa.InstantiateGenerics)
for _, pkg := range p.sorted { for _, pkg := range p.sorted {
prog.CreatePackage(pkg.Pkg, pkg.Files, &pkg.info, true) prog.CreatePackage(pkg.Pkg, pkg.Files, &pkg.info, true)
+48 -157
View File
@@ -138,13 +138,27 @@ func printCommand(cmd string, args ...string) {
} }
// Build compiles and links the given package and writes it to outpath. // Build compiles and links the given package and writes it to outpath.
func Build(pkgName, outpath string, config *compileopts.Config) error { func Build(pkgName, outpath string, options *compileopts.Options) error {
config, err := builder.NewConfig(options)
if err != nil {
return err
}
if options.PrintJSON {
b, err := json.MarshalIndent(config, "", " ")
if err != nil {
handleCompilerError(err)
}
fmt.Printf("%s\n", string(b))
return nil
}
// Create a temporary directory for intermediary files. // Create a temporary directory for intermediary files.
tmpdir, err := os.MkdirTemp("", "tinygo") tmpdir, err := os.MkdirTemp("", "tinygo")
if err != nil { if err != nil {
return err return err
} }
if !config.Options.Work { if !options.Work {
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
} }
@@ -291,8 +305,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
}) })
if testConfig.CompileOnly { if testConfig.CompileOnly {
// Return the compiler error, if there is one. return true, nil
return true, err
} }
importPath := strings.TrimSuffix(result.ImportPath, ".test") importPath := strings.TrimSuffix(result.ImportPath, ".test")
@@ -340,17 +353,8 @@ func dirsToModuleRootAbs(maindir, modroot string) []string {
return dirs return dirs
} }
// validateOutputFormat checks if the output file extension matches the expected format
func validateOutputFormat(outpath, expectedExt string) error {
actualExt := filepath.Ext(outpath)
if actualExt != expectedExt {
return fmt.Errorf("output format %s does not match target format %s", actualExt, expectedExt)
}
return nil
}
// Flash builds and flashes the built binary to the given serial port. // Flash builds and flashes the built binary to the given serial port.
func Flash(pkgName, port, outpath string, options *compileopts.Options) error { func Flash(pkgName, port string, options *compileopts.Options) error {
config, err := builder.NewConfig(options) config, err := builder.NewConfig(options)
if err != nil { if err != nil {
return err return err
@@ -399,24 +403,13 @@ func Flash(pkgName, port, outpath string, options *compileopts.Options) error {
if !options.Work { if !options.Work {
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
} }
// Validate output format before building
if outpath != "" {
if err := validateOutputFormat(outpath, fileExt); err != nil {
return err
}
}
// Build the binary. // Build the binary.
result, err := builder.Build(pkgName, fileExt, tmpdir, config) result, err := builder.Build(pkgName, fileExt, tmpdir, config)
if err != nil { if err != nil {
return err return err
} }
// Save output file if specified (after build, before flashing)
if outpath != "" {
if err := copyFile(result.Binary, outpath); err != nil {
return fmt.Errorf("failed to save output file: %v", err)
}
}
// do we need port reset to put MCU into bootloader mode? // do we need port reset to put MCU into bootloader mode?
if config.Target.PortReset == "true" && flashMethod != "openocd" { if config.Target.PortReset == "true" && flashMethod != "openocd" {
port, err := getDefaultPort(port, config.Target.SerialPort) port, err := getDefaultPort(port, config.Target.SerialPort)
@@ -1034,50 +1027,15 @@ func findFATMounts(options *compileopts.Options) ([]mountPoint, error) {
return nil, fmt.Errorf("could not list mount points: %w", err) return nil, fmt.Errorf("could not list mount points: %w", err)
} }
for _, elem := range list { for _, elem := range list {
volumePath := filepath.Join("/Volumes", elem.Name()) // TODO: find a way to check for the filesystem type.
if _, err := os.Stat(volumePath); err != nil { // (Only return FAT filesystems).
continue points = append(points, mountPoint{
} name: elem.Name(),
path: filepath.Join("/Volumes", elem.Name()),
cmd := exec.Command("diskutil", "info", volumePath) })
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
continue // skip if diskutil failed
}
diskInfo := map[string]string{}
scanner := bufio.NewScanner(&out)
for scanner.Scan() {
line := scanner.Text()
parts := strings.SplitN(line, ":", 2)
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
diskInfo[key] = value
}
if err := scanner.Err(); err != nil {
continue
}
volName, okv := diskInfo["Volume Name"]
fsType, okf := diskInfo["File System Personality"]
if !okv || !okf {
continue
}
// Check if a filesystem type is FAT-based
if strings.Contains(strings.ToUpper(fsType), "FAT") {
points = append(points, mountPoint{
name: volName,
path: volumePath,
})
}
} }
sort.Slice(points, func(i, j int) bool { sort.Slice(points, func(i, j int) bool {
return points[i].path < points[j].path return points[i].path < points[j].name
}) })
return points, nil return points, nil
case "linux": case "linux":
@@ -1318,11 +1276,6 @@ extension at all.`
(https://tinygo.org/docs/reference/microcontrollers/). (https://tinygo.org/docs/reference/microcontrollers/).
Examples: "arduino-nano", "d1mini", "xiao". Examples: "arduino-nano", "d1mini", "xiao".
-o={filename}:
Save the built binary to the specified output file. The file
format must match the target's expected format (e.g., .hex,
.uf2). Both flashing and saving will be performed.
-monitor: -monitor:
Start the serial monitor (see below) immediately after Start the serial monitor (see below) immediately after
flashing. However, some microcontrollers need a split second flashing. However, some microcontrollers need a split second
@@ -1443,68 +1396,6 @@ func usage(command string) {
} }
// Print diagnostics very similar to the -json flag in Go.
func printBuildOutput(err error, jsonDiagnostics bool) {
if err == nil {
return // nothing to report
}
if jsonDiagnostics {
workingDir, getwdErr := os.Getwd()
if getwdErr != nil {
workingDir = ""
}
type jsonDiagnosticOutput struct {
ImportPath string
Action string
Output string `json:",omitempty"`
StartPos string `json:",omitempty"` // non-standard
EndPos string `json:",omitempty"` // non-standard
}
for _, diags := range diagnostics.CreateDiagnostics(err) {
if diags.ImportPath != "" {
output, _ := json.Marshal(jsonDiagnosticOutput{
ImportPath: diags.ImportPath,
Action: "build-output",
Output: "# " + diags.ImportPath + "\n",
})
os.Stdout.Write(append(output, '\n'))
}
for _, diag := range diags.Diagnostics {
w := &bytes.Buffer{}
diag.WriteTo(w, workingDir)
data := jsonDiagnosticOutput{
ImportPath: diags.ImportPath,
Action: "build-output",
Output: w.String(),
}
if diag.StartPos.IsValid() && diag.EndPos.IsValid() {
// Include the non-standard StartPos/EndPos values. These
// are useful for the TinyGo Playground to show better error
// messages.
data.StartPos = diagnostics.RelativePosition(diag.StartPos, workingDir).String()
data.EndPos = diagnostics.RelativePosition(diag.EndPos, workingDir).String()
}
output, _ := json.Marshal(data)
os.Stdout.Write(append(output, '\n'))
}
// Emit the "Action":"build-fail" JSON.
output, _ := json.Marshal(jsonDiagnosticOutput{
ImportPath: diags.ImportPath,
Action: "build-fail",
})
os.Stdout.Write(append(output, '\n'))
}
os.Exit(1)
}
// Regular diagnostic handling.
handleCompilerError(err)
}
func handleCompilerError(err error) { func handleCompilerError(err error) {
if err != nil { if err != nil {
wd, getwdErr := os.Getwd() wd, getwdErr := os.Getwd()
@@ -1601,16 +1492,16 @@ func main() {
command := os.Args[1] command := os.Args[1]
opt := flag.String("opt", "z", "optimization level: 0, 1, 2, s, z") opt := flag.String("opt", "z", "optimization level: 0, 1, 2, s, z")
gc := flag.String("gc", "", "garbage collector to use (none, leaking, conservative, custom, precise, boehm)") gc := flag.String("gc", "", "garbage collector to use (none, leaking, conservative)")
panicStrategy := flag.String("panic", "print", "panic strategy (print, trap)") panicStrategy := flag.String("panic", "print", "panic strategy (print, trap)")
scheduler := flag.String("scheduler", "", "which scheduler to use (none, tasks, cores, threads, asyncify)") scheduler := flag.String("scheduler", "", "which scheduler to use (none, tasks, asyncify)")
serial := flag.String("serial", "", "which serial output to use (none, uart, usb, rtt)") serial := flag.String("serial", "", "which serial output to use (none, uart, usb, rtt)")
work := flag.Bool("work", false, "print the name of the temporary build directory and do not delete this directory on exit") work := flag.Bool("work", false, "print the name of the temporary build directory and do not delete this directory on exit")
interpTimeout := flag.Duration("interp-timeout", 180*time.Second, "interp optimization pass timeout") interpTimeout := flag.Duration("interp-timeout", 180*time.Second, "interp optimization pass timeout")
var tags buildutil.TagsFlag var tags buildutil.TagsFlag
flag.Var(&tags, "tags", "a space-separated list of extra build tags") flag.Var(&tags, "tags", "a space-separated list of extra build tags")
target := flag.String("target", "", "chip/board name or JSON target specification file") target := flag.String("target", "", "chip/board name or JSON target specification file")
buildMode := flag.String("buildmode", "", "build mode to use (default, c-shared, wasi-legacy)") buildMode := flag.String("buildmode", "", "build mode to use (default, c-shared)")
var stackSize uint64 var stackSize uint64
flag.Func("stack-size", "goroutine stack size (if unknown at compile time)", func(s string) error { flag.Func("stack-size", "goroutine stack size (if unknown at compile time)", func(s string) error {
size, err := bytesize.Parse(s) size, err := bytesize.Parse(s)
@@ -1621,10 +1512,8 @@ func main() {
printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines") printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines")
printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed") printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed")
printCommands := flag.Bool("x", false, "Print commands") printCommands := flag.Bool("x", false, "Print commands")
flagJSON := flag.Bool("json", false, "print output in JSON format")
parallelism := flag.Int("p", runtime.GOMAXPROCS(0), "the number of build jobs that can run in parallel") parallelism := flag.Int("p", runtime.GOMAXPROCS(0), "the number of build jobs that can run in parallel")
nodebug := flag.Bool("no-debug", false, "strip debug information") nodebug := flag.Bool("no-debug", false, "strip debug information")
nobounds := flag.Bool("nobounds", false, "do not emit bounds checks")
ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)") ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)")
ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug") ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug")
port := flag.String("port", "", "flash port (can specify multiple candidates separated by commas)") port := flag.String("port", "", "flash port (can specify multiple candidates separated by commas)")
@@ -1647,13 +1536,16 @@ func main() {
// development it can be useful to not emit debug information at all. // development it can be useful to not emit debug information at all.
skipDwarf := flag.Bool("internal-nodwarf", false, "internal flag, use -no-debug instead") skipDwarf := flag.Bool("internal-nodwarf", false, "internal flag, use -no-debug instead")
var flagDeps, flagTest bool var flagJSON, flagDeps, flagTest bool
if command == "help" || command == "list" || command == "info" || command == "build" {
flag.BoolVar(&flagJSON, "json", false, "print data in JSON format")
}
if command == "help" || command == "list" { if command == "help" || command == "list" {
flag.BoolVar(&flagDeps, "deps", false, "supply -deps flag to go list") flag.BoolVar(&flagDeps, "deps", false, "supply -deps flag to go list")
flag.BoolVar(&flagTest, "test", false, "supply -test flag to go list") flag.BoolVar(&flagTest, "test", false, "supply -test flag to go list")
} }
var outpath string var outpath string
if command == "help" || command == "build" || command == "test" || command == "flash" { if command == "help" || command == "build" || command == "test" {
flag.StringVar(&outpath, "o", "", "output filename") flag.StringVar(&outpath, "o", "", "output filename")
} }
@@ -1733,7 +1625,6 @@ func main() {
SkipDWARF: *skipDwarf, SkipDWARF: *skipDwarf,
Semaphore: make(chan struct{}, *parallelism), Semaphore: make(chan struct{}, *parallelism),
Debug: !*nodebug, Debug: !*nodebug,
Nobounds: *nobounds,
PrintSizes: *printSize, PrintSizes: *printSize,
PrintStacks: *printStacks, PrintStacks: *printStacks,
PrintAllocs: printAllocs, PrintAllocs: printAllocs,
@@ -1743,6 +1634,7 @@ func main() {
Programmer: *programmer, Programmer: *programmer,
OpenOCDCommands: ocdCommands, OpenOCDCommands: ocdCommands,
LLVMFeatures: *llvmFeatures, LLVMFeatures: *llvmFeatures,
PrintJSON: flagJSON,
Monitor: *monitor, Monitor: *monitor,
BaudRate: *baudrate, BaudRate: *baudrate,
Timeout: *timeout, Timeout: *timeout,
@@ -1792,20 +1684,17 @@ func main() {
usage(command) usage(command)
os.Exit(1) os.Exit(1)
} }
if filepath.Ext(outpath) == ".wasm" && options.GOARCH != "wasm" && options.Target == "" { if options.Target == "" && filepath.Ext(outpath) == ".wasm" {
fmt.Fprintln(os.Stderr, "you appear to want to build a wasm file, but have not specified either a target flag, or the GOARCH/GOOS to use.") options.Target = "wasm"
os.Exit(1)
} }
config, err := builder.NewConfig(options) err := Build(pkgName, outpath, options)
handleCompilerError(err) handleCompilerError(err)
err = Build(pkgName, outpath, config)
printBuildOutput(err, *flagJSON)
case "flash", "gdb", "lldb": case "flash", "gdb", "lldb":
pkgName := filepath.ToSlash(flag.Arg(0)) pkgName := filepath.ToSlash(flag.Arg(0))
if command == "flash" { if command == "flash" {
err := Flash(pkgName, *port, outpath, options) err := Flash(pkgName, *port, options)
printBuildOutput(err, *flagJSON) handleCompilerError(err)
} else { } else {
if !options.Debug { if !options.Debug {
fmt.Fprintln(os.Stderr, "Debug disabled while running debugger?") fmt.Fprintln(os.Stderr, "Debug disabled while running debugger?")
@@ -1813,7 +1702,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
err := Debug(command, pkgName, *ocdOutput, options) err := Debug(command, pkgName, *ocdOutput, options)
printBuildOutput(err, *flagJSON) handleCompilerError(err)
} }
case "run": case "run":
if flag.NArg() < 1 { if flag.NArg() < 1 {
@@ -1823,7 +1712,7 @@ func main() {
} }
pkgName := filepath.ToSlash(flag.Arg(0)) pkgName := filepath.ToSlash(flag.Arg(0))
err := Run(pkgName, options, flag.Args()[1:]) err := Run(pkgName, options, flag.Args()[1:])
printBuildOutput(err, *flagJSON) handleCompilerError(err)
case "test": case "test":
var pkgNames []string var pkgNames []string
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
@@ -1890,7 +1779,6 @@ func main() {
wd = "" wd = ""
} }
diagnostics.CreateDiagnostics(err).WriteTo(os.Stderr, wd) diagnostics.CreateDiagnostics(err).WriteTo(os.Stderr, wd)
os.Exit(1)
} }
if !passed { if !passed {
select { select {
@@ -1952,13 +1840,16 @@ func main() {
os.Exit(1) os.Exit(1)
} }
config.GoMinorVersion = 0 // this avoids creating the list of Go1.x build tags. config.GoMinorVersion = 0 // this avoids creating the list of Go1.x build tags.
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
cachedGOROOT, err := loader.GetCachedGoroot(config) cachedGOROOT, err := loader.GetCachedGoroot(config)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
os.Exit(1) os.Exit(1)
} }
if *flagJSON { if flagJSON {
json, _ := json.MarshalIndent(struct { json, _ := json.MarshalIndent(struct {
Target *compileopts.TargetSpec `json:"target"` Target *compileopts.TargetSpec `json:"target"`
GOROOT string `json:"goroot"` GOROOT string `json:"goroot"`
@@ -2000,7 +1891,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
var extraArgs []string var extraArgs []string
if *flagJSON { if flagJSON {
extraArgs = append(extraArgs, "-json") extraArgs = append(extraArgs, "-json")
} }
if flagDeps { if flagDeps {
+24 -69
View File
@@ -35,8 +35,6 @@ const TESTDATA = "testdata"
var testTarget = flag.String("target", "", "override test target") var testTarget = flag.String("target", "", "override test target")
var testOnlyCurrentOS = flag.Bool("only-current-os", false, "")
var supportedLinuxArches = map[string]string{ var supportedLinuxArches = map[string]string{
"AMD64Linux": "linux/amd64", "AMD64Linux": "linux/amd64",
"X86Linux": "linux/386", "X86Linux": "linux/386",
@@ -160,51 +158,20 @@ func TestBuild(t *testing.T) {
return return
} }
if !*testOnlyCurrentOS { t.Run("EmulatedCortexM3", func(t *testing.T) {
t.Run("EmulatedCortexM3", func(t *testing.T) { t.Parallel()
t.Parallel() runPlatTests(optionsFromTarget("cortex-m-qemu", sema), tests, t)
runPlatTests(optionsFromTarget("cortex-m-qemu", sema), tests, t) })
})
t.Run("EmulatedRISCV", func(t *testing.T) { t.Run("EmulatedRISCV", func(t *testing.T) {
t.Parallel() t.Parallel()
runPlatTests(optionsFromTarget("riscv-qemu", sema), tests, t) runPlatTests(optionsFromTarget("riscv-qemu", sema), tests, t)
}) })
t.Run("AVR", func(t *testing.T) { t.Run("AVR", func(t *testing.T) {
t.Parallel() t.Parallel()
runPlatTests(optionsFromTarget("simavr", sema), tests, t) runPlatTests(optionsFromTarget("simavr", sema), tests, t)
}) })
t.Run("WebAssembly", func(t *testing.T) {
t.Parallel()
runPlatTests(optionsFromTarget("wasm", sema), tests, t)
// Test with -gc=boehm.
t.Run("gc.go-boehm", func(t *testing.T) {
t.Parallel()
optionsBoehm := optionsFromTarget("wasm", sema)
optionsBoehm.GC = "boehm"
runTest("gc.go", optionsBoehm, t, nil, nil)
})
})
t.Run("WASIp1", func(t *testing.T) {
t.Parallel()
runPlatTests(optionsFromTarget("wasip1", sema), tests, t)
// Test with -gc=boehm.
t.Run("gc.go-boehm", func(t *testing.T) {
t.Parallel()
optionsBoehm := optionsFromTarget("wasip1", sema)
optionsBoehm.GC = "boehm"
runTest("gc.go", optionsBoehm, t, nil, nil)
})
})
t.Run("WASIp2", func(t *testing.T) {
t.Parallel()
runPlatTests(optionsFromTarget("wasip2", sema), tests, t)
})
}
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
for name, osArch := range supportedLinuxArches { for name, osArch := range supportedLinuxArches {
@@ -224,13 +191,18 @@ func TestBuild(t *testing.T) {
options := optionsFromOSARCH("linux/mipsle/softfloat", sema) options := optionsFromOSARCH("linux/mipsle/softfloat", sema)
runTest("cgo/", options, t, nil, nil) runTest("cgo/", options, t, nil, nil)
}) })
} else if runtime.GOOS == "windows" { t.Run("WebAssembly", func(t *testing.T) {
if runtime.GOARCH != "386" { t.Parallel()
t.Run("Windows386", func(t *testing.T) { runPlatTests(optionsFromTarget("wasm", sema), tests, t)
t.Parallel() })
runPlatTests(optionsFromOSARCH("windows/386", sema), tests, t) t.Run("WASI", func(t *testing.T) {
}) t.Parallel()
} runPlatTests(optionsFromTarget("wasip1", sema), tests, t)
})
t.Run("WASIp2", func(t *testing.T) {
t.Parallel()
runPlatTests(optionsFromTarget("wasip2", sema), tests, t)
})
} }
} }
@@ -424,12 +396,10 @@ func optionsFromOSARCH(osarch string, sema chan struct{}) compileopts.Options {
} }
func runTest(name string, options compileopts.Options, t *testing.T, cmdArgs, environmentVars []string) { func runTest(name string, options compileopts.Options, t *testing.T, cmdArgs, environmentVars []string) {
t.Helper()
runTestWithConfig(name, t, options, cmdArgs, environmentVars) runTestWithConfig(name, t, options, cmdArgs, environmentVars)
} }
func runTestWithConfig(name string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) { func runTestWithConfig(name string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) {
t.Helper()
// Get the expected output for this test. // Get the expected output for this test.
// Note: not using filepath.Join as it strips the path separator at the end // Note: not using filepath.Join as it strips the path separator at the end
// of the path. // of the path.
@@ -624,15 +594,6 @@ func TestWasmExport(t *testing.T) {
noOutput: true, // wasm-unknown cannot produce output noOutput: true, // wasm-unknown cannot produce output
command: true, command: true,
}, },
// Test buildmode=wasi-legacy with WASI.
{
name: "WASIp1-legacy",
target: "wasip1",
buildMode: "wasi-legacy",
scheduler: "none",
file: "wasmexport-noscheduler.go",
command: true,
},
} }
for _, tc := range tests { for _, tc := range tests {
@@ -705,10 +666,6 @@ func TestWasmExport(t *testing.T) {
// again. // again.
checkResult("reentrantCall(2, 3)", mustCall(mod.ExportedFunction("reentrantCall").Call(ctx, 2, 3)), []uint64{5}) checkResult("reentrantCall(2, 3)", mustCall(mod.ExportedFunction("reentrantCall").Call(ctx, 2, 3)), []uint64{5})
checkResult("reentrantCall(1, 8)", mustCall(mod.ExportedFunction("reentrantCall").Call(ctx, 1, 8)), []uint64{9}) checkResult("reentrantCall(1, 8)", mustCall(mod.ExportedFunction("reentrantCall").Call(ctx, 1, 8)), []uint64{9})
// Check that goroutines started inside //go:wasmexport don't
// block the called function from returning.
checkResult("goroutineExit()", mustCall(mod.ExportedFunction("goroutineExit").Call(ctx)), nil)
} }
// Add wasip1 module. // Add wasip1 module.
@@ -878,7 +835,6 @@ func TestWasmExit(t *testing.T) {
// Check whether the output of a test equals the expected output. // Check whether the output of a test equals the expected output.
func checkOutput(t *testing.T, filename string, actual []byte) { func checkOutput(t *testing.T, filename string, actual []byte) {
t.Helper()
expectedOutput, err := os.ReadFile(filename) expectedOutput, err := os.ReadFile(filename)
if err != nil { if err != nil {
t.Fatal("could not read output file:", err) t.Fatal("could not read output file:", err)
@@ -887,7 +843,6 @@ func checkOutput(t *testing.T, filename string, actual []byte) {
} }
func checkOutputData(t *testing.T, expectedOutput, actual []byte) { func checkOutputData(t *testing.T, expectedOutput, actual []byte) {
t.Helper()
expectedOutput = bytes.ReplaceAll(expectedOutput, []byte("\r\n"), []byte("\n")) expectedOutput = bytes.ReplaceAll(expectedOutput, []byte("\r\n"), []byte("\n"))
actual = bytes.ReplaceAll(actual, []byte("\r\n"), []byte("\n")) actual = bytes.ReplaceAll(actual, []byte("\r\n"), []byte("\n"))
+3 -3
View File
@@ -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
} }
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt) //go:build nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey
// If you update the above build constraint, you'll probably also need to update // If you update the above build constraint, you'll probably also need to update
// src/runtime/rand_hwrng.go. // src/runtime/rand_hwrng.go.
+21 -18
View File
@@ -1,9 +1,6 @@
package rand package rand
import ( import "errors"
"errors"
"unsafe"
)
func init() { func init() {
Reader = &reader{} Reader = &reader{}
@@ -19,22 +16,28 @@ func (r *reader) Read(b []byte) (n int, err error) {
return return
} }
// Use the old RtlGenRandom, introduced in Windows XP. var randomByte uint32
// Even though the documentation says it is deprecated, it is widely used for i := range b {
// and probably won't go away anytime soon. // Call rand_s every four bytes because it's a C int (always 32-bit in
// See for example: https://github.com/golang/go/issues/33542 // Windows).
// For Windows 7 and newer, we might switch to ProcessPrng in the future if i%4 == 0 {
// (which is a documented function and might be a tiny bit faster). errCode := libc_rand_s(&randomByte)
ok := libc_RtlGenRandom(unsafe.Pointer(&b[0]), len(b)) if errCode != 0 {
if !ok { // According to the documentation, it can return an error.
return 0, errRandom return n, errRandom
}
} else {
randomByte >>= 8
}
b[i] = byte(randomByte)
} }
return len(b), nil return len(b), nil
} }
// This function is part of advapi32.dll, and is called SystemFunction036 for // Cryptographically secure random number generator.
// some reason. It's available on Windows XP and newer. // https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170
// See: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom // errno_t rand_s(unsigned int* randomValue);
// //
//export SystemFunction036 //export rand_s
func libc_RtlGenRandom(buf unsafe.Pointer, len int) bool func libc_rand_s(randomValue *uint32) int32

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