mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5caa99b9c |
+20
-12
@@ -73,6 +73,14 @@ commands:
|
||||
- go-cache-v4-{{ checksum "go.mod" }}
|
||||
- llvm-source-linux
|
||||
- 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:
|
||||
condition: <<parameters.fmt-check>>
|
||||
steps:
|
||||
@@ -92,28 +100,28 @@ commands:
|
||||
- /go/pkg/mod
|
||||
|
||||
jobs:
|
||||
test-oldest:
|
||||
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
||||
# least the smoke tests still pass.
|
||||
test-llvm15-go119:
|
||||
docker:
|
||||
- image: golang:1.22-bullseye
|
||||
- image: golang:1.19-bullseye
|
||||
steps:
|
||||
- test-linux:
|
||||
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
|
||||
test-newest:
|
||||
# This tests the latest supported LLVM version when linking against system
|
||||
# libraries.
|
||||
test-llvm19-go123:
|
||||
docker:
|
||||
- image: golang:1.25-bullseye
|
||||
- image: golang:1.23-bullseye
|
||||
steps:
|
||||
- test-linux:
|
||||
llvm: "20"
|
||||
llvm: "19"
|
||||
resource_class: large
|
||||
|
||||
workflows:
|
||||
test-all:
|
||||
jobs:
|
||||
- test-oldest
|
||||
# disable this test, since CircleCI seems unable to download due to rate-limits on Dockerhub.
|
||||
# - test-newest
|
||||
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
||||
# least the smoke tests still pass.
|
||||
- test-llvm15-go119
|
||||
# This tests LLVM 19 support when linking against system libraries.
|
||||
- test-llvm19-go123
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -89,10 +89,19 @@ jobs:
|
||||
with:
|
||||
key: ${{ steps.cache-llvm-build.outputs.cache-primary-key }}
|
||||
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
|
||||
run: make -j3 gen-device
|
||||
- name: Test TinyGo
|
||||
run: make test GOTESTFLAGS="-only-current-os"
|
||||
run: make test GOTESTFLAGS="-short"
|
||||
- name: Build TinyGo release tarball
|
||||
run: make release -j3
|
||||
- name: Test stdlib packages
|
||||
@@ -117,7 +126,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
version: [16, 17, 18, 19, 20]
|
||||
version: [16, 17, 18, 19]
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
@@ -134,15 +143,15 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
||||
run: go install -tags=llvm${{ matrix.version }}
|
||||
- name: Check binary
|
||||
run: tinygo version
|
||||
- name: Build TinyGo (default LLVM)
|
||||
if: matrix.version == 20
|
||||
if: matrix.version == 19
|
||||
run: go install
|
||||
- name: Check binary
|
||||
if: matrix.version == 20
|
||||
if: matrix.version == 19
|
||||
run: tinygo version
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
# statically linked binary.
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: golang:1.25-alpine
|
||||
image: golang:1.23-alpine
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
@@ -104,6 +104,15 @@ jobs:
|
||||
run: |
|
||||
apk add cmake samurai python3
|
||||
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
|
||||
run: |
|
||||
gem install --version 4.0.7 public_suffix
|
||||
@@ -137,7 +146,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Install wasmtime
|
||||
uses: bytecodealliance/actions/wasmtime/setup@v1
|
||||
@@ -156,7 +165,6 @@ jobs:
|
||||
ln -s ~/lib/tinygo/bin/tinygo ~/go/bin/tinygo
|
||||
- run: make tinygo-test-wasip1-fast
|
||||
- run: make tinygo-test-wasip2-fast
|
||||
- run: make tinygo-test-wasm
|
||||
- run: make smoketest
|
||||
assert-test-linux:
|
||||
# Run all tests that can run on Linux, with LLVM assertions enabled to catch
|
||||
@@ -181,7 +189,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
@@ -249,6 +257,15 @@ jobs:
|
||||
- name: Build Binaryen
|
||||
if: steps.cache-binaryen.outputs.cache-hit != 'true'
|
||||
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
|
||||
- name: Test TinyGo
|
||||
run: make ASSERT=1 test
|
||||
@@ -260,7 +277,7 @@ jobs:
|
||||
run: make tinygo-test
|
||||
- run: make smoketest
|
||||
- run: make wasmtest
|
||||
- run: make tinygo-test-baremetal
|
||||
- run: make tinygo-baremetal
|
||||
build-linux-cross:
|
||||
# Build ARM Linux binaries, ready for release.
|
||||
# This intentionally uses an older Linux image, so that we compile against
|
||||
@@ -280,7 +297,7 @@ jobs:
|
||||
- goarch: arm
|
||||
toolchain: arm-linux-gnueabihf
|
||||
libc: armhf
|
||||
runs-on: ubuntu-22.04 # note: use the oldest image available! (see above)
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-linux
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -298,7 +315,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -329,7 +346,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-19-linux-${{ matrix.goarch }}-v3
|
||||
key: llvm-build-19-linux-${{ matrix.goarch }}-v2
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
||||
@@ -22,9 +22,9 @@ jobs:
|
||||
run: sudo apt-get remove llvm-18
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Pull musl, bdwgc
|
||||
- name: Pull musl
|
||||
run: |
|
||||
git submodule update --init lib/musl lib/bdwgc
|
||||
git submodule update --init lib/musl
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-source
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
# still works after checking out the dev branch (that is, when going from LLVM
|
||||
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
|
||||
|
||||
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-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 -
|
||||
sudo apt-get update
|
||||
sudo apt-get install --no-install-recommends -y \
|
||||
llvm-20-dev \
|
||||
clang-20 \
|
||||
libclang-20-dev \
|
||||
lld-20
|
||||
llvm-19-dev \
|
||||
clang-19 \
|
||||
libclang-19-dev \
|
||||
lld-19
|
||||
|
||||
@@ -13,17 +13,9 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: ${{ matrix.image }}
|
||||
runs-on: windows-2022
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
strategy:
|
||||
matrix:
|
||||
goarch: [ amd64, arm64 ]
|
||||
include:
|
||||
- goarch: amd64
|
||||
image: windows-2022
|
||||
- goarch: arm64
|
||||
image: windows-11-arm
|
||||
steps:
|
||||
- name: Configure pagefile
|
||||
uses: al-cheb/configure-pagefile-action@v1.4
|
||||
@@ -31,7 +23,7 @@ jobs:
|
||||
minimum-size: 8GB
|
||||
maximum-size: 24GB
|
||||
disk-root: "C:"
|
||||
- uses: MinoruSekine/setup-scoop@v4
|
||||
- uses: brechtm/setup-scoop@v2
|
||||
with:
|
||||
scoop_update: 'false'
|
||||
- name: Install Dependencies
|
||||
@@ -49,7 +41,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Restore cached LLVM source
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -80,7 +72,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-19-windows-${{ matrix.goarch }}-v1
|
||||
key: llvm-build-19-windows-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
@@ -99,10 +91,19 @@ jobs:
|
||||
with:
|
||||
key: ${{ steps.cache-llvm-build.outputs.cache-primary-key }}
|
||||
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
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: go-cache-windows-${{ matrix.goarch }}-v1-${{ hashFiles('go.mod') }}
|
||||
key: go-cache-windows-v1-${{ hashFiles('go.mod') }}
|
||||
path: |
|
||||
C:/Users/runneradmin/AppData/Local/go-build
|
||||
C:/Users/runneradmin/go/pkg/mod
|
||||
@@ -113,15 +114,14 @@ jobs:
|
||||
run: make -j3 gen-device
|
||||
- name: Test TinyGo
|
||||
shell: bash
|
||||
if: matrix.goarch == 'amd64' # skip on ARM64 to speed up build
|
||||
run: make test GOTESTFLAGS="-only-current-os"
|
||||
run: make test GOTESTFLAGS="-short"
|
||||
- name: Build TinyGo release tarball
|
||||
shell: bash
|
||||
run: make build/release -j4
|
||||
- name: Make release artifact
|
||||
shell: bash
|
||||
working-directory: build/release
|
||||
run: 7z -tzip a tinygo${{ steps.version.outputs.version }}.windows-${{ matrix.goarch }}.zip tinygo
|
||||
run: 7z -tzip a tinygo${{ steps.version.outputs.version }}.windows-amd64.zip tinygo
|
||||
- name: Publish release artifact
|
||||
# Note: this release artifact is double-zipped, see:
|
||||
# https://github.com/actions/upload-artifact/issues/39
|
||||
@@ -131,8 +131,8 @@ jobs:
|
||||
# We're doing the former here, to keep artifact uploads fast.
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-${{ matrix.goarch }}-double-zipped-${{ steps.version.outputs.version }}
|
||||
path: build/release/tinygo${{ steps.version.outputs.version }}.windows-${{ matrix.goarch }}.zip
|
||||
name: windows-amd64-double-zipped-${{ steps.version.outputs.version }}
|
||||
path: build/release/tinygo${{ steps.version.outputs.version }}.windows-amd64.zip
|
||||
|
||||
smoke-test-windows:
|
||||
runs-on: windows-2022
|
||||
@@ -144,7 +144,7 @@ jobs:
|
||||
minimum-size: 8GB
|
||||
maximum-size: 24GB
|
||||
disk-root: "C:"
|
||||
- uses: MinoruSekine/setup-scoop@v4
|
||||
- uses: brechtm/setup-scoop@v2
|
||||
with:
|
||||
scoop_update: 'false'
|
||||
- name: Install Dependencies
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -186,7 +186,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -210,7 +210,7 @@ jobs:
|
||||
minimum-size: 8GB
|
||||
maximum-size: 24GB
|
||||
disk-root: "C:"
|
||||
- uses: MinoruSekine/setup-scoop@v4
|
||||
- uses: brechtm/setup-scoop@v2
|
||||
with:
|
||||
scoop_update: 'false'
|
||||
- name: Install Dependencies
|
||||
@@ -222,7 +222,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25.0'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
+1
-3
@@ -35,9 +35,7 @@
|
||||
[submodule "src/net"]
|
||||
path = src/net
|
||||
url = https://github.com/tinygo-org/net.git
|
||||
branch = dev
|
||||
[submodule "lib/wasi-cli"]
|
||||
path = lib/wasi-cli
|
||||
url = https://github.com/WebAssembly/wasi-cli
|
||||
[submodule "lib/bdwgc"]
|
||||
path = lib/bdwgc
|
||||
url = https://github.com/ivmai/bdwgc.git
|
||||
|
||||
+2
-8
@@ -85,17 +85,11 @@ Try running TinyGo:
|
||||
|
||||
./build/tinygo help
|
||||
|
||||
Also, make sure the `tinygo` binary really is statically linked. The command to check for
|
||||
dynamic dependencies differs depending on your operating system.
|
||||
|
||||
On Linux, use `ldd` (not to be confused with `lld`):
|
||||
Also, make sure the `tinygo` binary really is statically linked. Check this
|
||||
using `ldd` (not to be confused with `lld`):
|
||||
|
||||
ldd ./build/tinygo
|
||||
|
||||
On macOS, use otool -L:
|
||||
|
||||
otool -L ./build/tinygo
|
||||
|
||||
The result should not contain libclang or libLLVM.
|
||||
|
||||
## Make a release tarball
|
||||
|
||||
-269
@@ -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
|
||||
---
|
||||
* **general**
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
# tinygo-llvm stage obtains the llvm source for TinyGo
|
||||
FROM golang:1.25 AS tinygo-llvm
|
||||
FROM golang:1.23 AS tinygo-llvm
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y apt-utils make cmake clang-17 ninja-build && \
|
||||
apt-get install -y apt-utils make cmake clang-15 ninja-build && \
|
||||
rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/log/* \
|
||||
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
|
||||
|
||||
# tinygo-compiler copies the compiler build over to a base Go container (without
|
||||
# all the build tools etc).
|
||||
FROM golang:1.25 AS tinygo-compiler
|
||||
FROM golang:1.23 AS tinygo-compiler
|
||||
|
||||
# Copy tinygo build.
|
||||
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
||||
|
||||
+70
-152
@@ -8,20 +8,13 @@ LLVM_PROJECTDIR ?= llvm-project
|
||||
CLANG_SRC ?= $(LLVM_PROJECTDIR)/clang
|
||||
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.
|
||||
# Versions are listed here in descending priority order.
|
||||
LLVM_VERSIONS = 19 18 17 16 15
|
||||
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)))
|
||||
toolSearchPathsVersion = $(1)-$(2)
|
||||
ifeq ($(uname),Darwin)
|
||||
ifeq ($(shell uname -s),Darwin)
|
||||
# Also explicitly search Brew's copy, which is not in PATH by default.
|
||||
BREW_PREFIX := $(shell brew --prefix)
|
||||
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 ?= go
|
||||
export GOROOT = $(shell $(GO) env GOROOT)
|
||||
|
||||
# Flags to pass to go test.
|
||||
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.
|
||||
ifeq (, $(CCACHE))
|
||||
LLVM_OPTION += '-DLLVM_CCACHE_BUILD=$(if $(shell command -v ccache 2> /dev/null),ON,OFF)'
|
||||
else
|
||||
LLVM_OPTION += '-DLLVM_CCACHE_BUILD=$(CCACHE)'
|
||||
# Use CCACHE for LLVM if possible
|
||||
ifneq (, $(shell command -v ccache 2> /dev/null))
|
||||
CCACHE := ON
|
||||
else
|
||||
CCACHE := OFF
|
||||
endif
|
||||
endif
|
||||
LLVM_OPTION += '-DLLVM_CCACHE_BUILD=$(CCACHE)'
|
||||
|
||||
# Allow enabling LLVM assertions
|
||||
ifeq (1, $(ASSERT))
|
||||
@@ -129,14 +127,14 @@ ifeq ($(OS),Windows_NT)
|
||||
|
||||
USE_SYSTEM_BINARYEN ?= 1
|
||||
|
||||
else ifeq ($(uname),Darwin)
|
||||
else ifeq ($(shell uname -s),Darwin)
|
||||
MD5SUM ?= md5
|
||||
|
||||
CGO_LDFLAGS += -lxar
|
||||
|
||||
USE_SYSTEM_BINARYEN ?= 1
|
||||
|
||||
else ifeq ($(uname),FreeBSD)
|
||||
else ifeq ($(shell uname -s),FreeBSD)
|
||||
MD5SUM ?= md5
|
||||
START_GROUP = -Wl,--start-group
|
||||
END_GROUP = -Wl,--end-group
|
||||
@@ -187,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
|
||||
|
||||
|
||||
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
|
||||
ifneq ($(RENESAS), 0)
|
||||
gen-device: gen-device-renesas
|
||||
endif
|
||||
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 ($(STM32), 0)
|
||||
gen-device: gen-device-stm32
|
||||
endif
|
||||
@@ -264,34 +259,40 @@ build/wasm-opt$(EXE):
|
||||
cp lib/binaryen/bin/wasm-opt$(EXE) build/wasm-opt$(EXE)
|
||||
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
|
||||
WASM_TOOLS_MODULE=go.bytecodealliance.org
|
||||
WASM_TOOLS_MODULE=github.com/bytecodealliance/wasm-tools-go
|
||||
.PHONY: wasi-syscall
|
||||
wasi-syscall: wasi-cm
|
||||
rm -rf ./src/internal/wasi/*
|
||||
go run -modfile ./internal/wasm-tools/go.mod $(WASM_TOOLS_MODULE)/cmd/wit-bindgen-go generate --versioned -o ./src/internal -p internal --cm internal/cm ./lib/wasi-cli/wit
|
||||
|
||||
# Copy package cm into src/internal/cm
|
||||
.PHONY: wasi-cm
|
||||
wasi-cm:
|
||||
rm -rf ./src/internal/cm/*
|
||||
rsync -rv --delete --exclude 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
|
||||
# rm -rf ./src/internal/cm
|
||||
rsync -rv --delete --exclude '*_test.go' $(shell go list -modfile ./internal/wasm-tools/go.mod -m -f {{.Dir}} $(WASM_TOOLS_MODULE))/cm ./src/internal/
|
||||
|
||||
# Check for Node.js used during WASM tests.
|
||||
NODEJS_VERSION := $(word 1,$(subst ., ,$(shell node -v | cut -c 2-)))
|
||||
MIN_NODEJS_VERSION=18
|
||||
|
||||
.PHONY: check-nodejs-version
|
||||
check-nodejs-version:
|
||||
@# Check whether NodeJS is available.
|
||||
@if ! command -v node 2>&1 >/dev/null; then echo "Install NodeJS version ${MIN_NODEJS_VERSION}+ to run tests."; exit 1; fi
|
||||
|
||||
@# Check whether the version is high enough.
|
||||
@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
|
||||
ifeq (, $(shell which node))
|
||||
@echo "Install NodeJS version 18+ to run tests."; exit 1;
|
||||
endif
|
||||
@if [ $(NODEJS_VERSION) -lt $(MIN_NODEJS_VERSION) ]; then echo "Install NodeJS version 18+ to run tests."; exit 1; fi
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
# Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi
|
||||
@@ -308,9 +309,11 @@ TEST_PACKAGES_FAST = \
|
||||
container/heap \
|
||||
container/list \
|
||||
container/ring \
|
||||
crypto/des \
|
||||
crypto/ecdsa \
|
||||
crypto/elliptic \
|
||||
crypto/md5 \
|
||||
crypto/rc4 \
|
||||
crypto/sha1 \
|
||||
crypto/sha256 \
|
||||
crypto/sha512 \
|
||||
@@ -352,11 +355,17 @@ TEST_PACKAGES_FAST = \
|
||||
unique \
|
||||
$(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
|
||||
# bytes requires mmap
|
||||
# compress/flate appears to hang on wasi
|
||||
# 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
|
||||
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows
|
||||
# image requires recover(), which is not yet supported on wasi
|
||||
@@ -377,7 +386,6 @@ TEST_PACKAGES_LINUX := \
|
||||
archive/zip \
|
||||
compress/flate \
|
||||
crypto/aes \
|
||||
crypto/des \
|
||||
crypto/hmac \
|
||||
debug/dwarf \
|
||||
debug/plan9obj \
|
||||
@@ -397,48 +405,17 @@ TEST_PACKAGES_LINUX := \
|
||||
|
||||
TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
|
||||
|
||||
# os/user requires t.Skip() support
|
||||
TEST_PACKAGES_WINDOWS := \
|
||||
compress/flate \
|
||||
crypto/des \
|
||||
crypto/hmac \
|
||||
os/user \
|
||||
strconv \
|
||||
text/template/parse \
|
||||
$(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
|
||||
jointmp := $(shell echo /tmp/join.$$$$)
|
||||
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_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
|
||||
@@ -447,11 +424,11 @@ report-stdlib-tests-pass:
|
||||
@rm $(jointmp).*
|
||||
|
||||
# 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_IOFS := true
|
||||
endif
|
||||
ifeq ($(uname),Linux)
|
||||
ifeq ($(shell uname),Linux)
|
||||
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_LINUX)
|
||||
TEST_IOFS := true
|
||||
endif
|
||||
@@ -460,15 +437,11 @@ TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS)
|
||||
TEST_IOFS := false
|
||||
endif
|
||||
|
||||
TEST_SKIP_FLAG := -skip='TestExtraMethods|TestParseAndBytesRoundTrip/P256/Generic'
|
||||
|
||||
# Test known-working standard library packages.
|
||||
# TODO: parallelize, and only show failing tests (no implied -v flag).
|
||||
.PHONY: tinygo-test
|
||||
tinygo-test:
|
||||
@# TestExtraMethods: used by many crypto packages and uses reflect.Type.Method which is not implemented.
|
||||
@# TestParseAndBytesRoundTrip/P256/Generic: relies on t.Skip() which is not implemented
|
||||
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||
$(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||
@# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also
|
||||
@# requires a large stack-size. Hence, io/fs is only run conditionally.
|
||||
@# For more details, see the comments on issue #3143.
|
||||
@@ -476,26 +449,24 @@ ifeq ($(TEST_IOFS),true)
|
||||
$(TINYGO) test -stack-size=6MB io/fs
|
||||
endif
|
||||
tinygo-test-fast:
|
||||
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST)
|
||||
$(TINYGO) test $(TEST_PACKAGES_HOST)
|
||||
tinygo-bench:
|
||||
$(TINYGO) test -bench . $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||
tinygo-bench-fast:
|
||||
$(TINYGO) test -bench . $(TEST_PACKAGES_HOST)
|
||||
|
||||
# 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 -target wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
tinygo-test-wasip1:
|
||||
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
tinygo-test-wasip1-fast:
|
||||
$(TINYGO) test -target=wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target=wasip1 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
|
||||
tinygo-test-wasip2-slow:
|
||||
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_SLOW)
|
||||
$(TINYGO) test -target=wasip2 $(TEST_PACKAGES_SLOW)
|
||||
tinygo-test-wasip2-fast:
|
||||
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target=wasip2 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
|
||||
tinygo-test-wasip2-sum-slow:
|
||||
TINYGO=$(TINYGO) \
|
||||
@@ -519,19 +490,18 @@ tinygo-bench-wasip2:
|
||||
tinygo-bench-wasip2-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-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
|
||||
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
|
||||
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
|
||||
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
|
||||
testchdir:
|
||||
@@ -603,23 +573,21 @@ smoketest: testchdir
|
||||
@$(MD5SUM) test.hex
|
||||
# test simulated boards on play.tinygo.org
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
GOOS=js GOARCH=wasm $(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
|
||||
$(TINYGO) build -size short -o test.wasm -tags=gopher_badge examples/blinky1
|
||||
@$(MD5SUM) test.wasm
|
||||
endif
|
||||
# test all targets/boards
|
||||
@@ -633,12 +601,8 @@ endif
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=microbit-v2-s113v7 examples/microbit-blink
|
||||
@$(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
|
||||
@$(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
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=reelboard examples/blinky1
|
||||
@@ -785,8 +749,6 @@ endif
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=pico-plus2 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=metro-rp2350 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo
|
||||
@$(MD5SUM) test.hex
|
||||
# test pwm
|
||||
@@ -803,10 +765,6 @@ endif
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=feather-nrf52840 examples/usb-midi
|
||||
@$(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
|
||||
@$(MD5SUM) test.hex
|
||||
ifneq ($(STM32), 0)
|
||||
@@ -846,8 +804,6 @@ ifneq ($(STM32), 0)
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=mksnanov3 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=stm32l0x1 examples/serial
|
||||
@$(MD5SUM) test.hex
|
||||
endif
|
||||
$(TINYGO) build -size short -o test.hex -target=atmega328pb examples/blinkm
|
||||
@$(MD5SUM) test.hex
|
||||
@@ -918,7 +874,7 @@ endif
|
||||
$(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
|
||||
@$(MD5SUM) test.hex
|
||||
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/main
|
||||
@@ -953,15 +909,13 @@ endif
|
||||
wasmtest:
|
||||
$(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/lib/bdwgc
|
||||
@mkdir -p build/release/tinygo/lib/clang/include
|
||||
@mkdir -p build/release/tinygo/lib/CMSIS/CMSIS
|
||||
@mkdir -p build/release/tinygo/lib/macos-minimal-sdk
|
||||
@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/stdio
|
||||
@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/crt
|
||||
@@ -969,8 +923,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/picolibc/newlib/libc
|
||||
@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
|
||||
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
|
||||
@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-cli/
|
||||
@@ -979,7 +932,6 @@ build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binary
|
||||
ifneq ($(USE_SYSTEM_BINARYEN),1)
|
||||
@cp -p build/wasm-opt$(EXE) build/release/tinygo/bin
|
||||
endif
|
||||
@cp -rp lib/bdwgc/* build/release/tinygo/lib/bdwgc
|
||||
@cp -p $(abspath $(CLANG_SRC))/lib/Headers/*.h build/release/tinygo/lib/clang/include
|
||||
@cp -rp lib/CMSIS/CMSIS/Include build/release/tinygo/lib/CMSIS/CMSIS
|
||||
@cp -rp lib/CMSIS/README.md build/release/tinygo/lib/CMSIS
|
||||
@@ -993,8 +945,6 @@ endif
|
||||
@cp -rp lib/musl/crt/crt1.c build/release/tinygo/lib/musl/crt
|
||||
@cp -rp lib/musl/COPYRIGHT build/release/tinygo/lib/musl
|
||||
@cp -rp lib/musl/include build/release/tinygo/lib/musl
|
||||
@cp -rp lib/musl/src/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/errno build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/exit build/release/tinygo/lib/musl/src
|
||||
@@ -1009,29 +959,19 @@ endif
|
||||
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/misc build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/multibyte build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/sched build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/stdlib build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/thread build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/time build/release/tinygo/lib/musl/src
|
||||
@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/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/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/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/msvcrt.def.in build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common
|
||||
@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-crt/stdio/ucrt_* build/release/tinygo/lib/mingw-w64/mingw-w64-crt/stdio
|
||||
@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/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers
|
||||
@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/include build/release/tinygo/lib/picolibc/newlib/libc
|
||||
@@ -1041,37 +981,15 @@ endif
|
||||
@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-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/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-bottom-half/headers/public build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
|
||||
@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/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/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/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/thread build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
||||
@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/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-libc/libc-top-half/musl/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl
|
||||
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
|
||||
@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/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
|
||||
|
||||
@@ -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.
|
||||
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
|
||||
LLVM Exceptions. See https://llvm.org/LICENSE.txt for license information.
|
||||
|
||||
@@ -48,22 +48,20 @@ Here is a small TinyGo program for use by a WASI host application:
|
||||
```go
|
||||
package main
|
||||
|
||||
//go:wasmexport add
|
||||
//go:wasm-module yourmodulename
|
||||
//export add
|
||||
func add(x, y uint32) uint32 {
|
||||
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
|
||||
tinygo build -buildmode=c-shared -o add.wasm -target=wasip1 add.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
|
||||
tinygo build -o main.wasm -target=wasip1 main.go
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -3,7 +3,6 @@ package builder
|
||||
import (
|
||||
"bytes"
|
||||
"debug/elf"
|
||||
"debug/macho"
|
||||
"debug/pe"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
@@ -63,20 +62,6 @@ func makeArchive(arfile *os.File, objs []string) error {
|
||||
fileIndex int
|
||||
}{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 {
|
||||
for _, symbol := range dbg.Symbols {
|
||||
if symbol.StorageClass != 2 {
|
||||
|
||||
@@ -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
|
||||
},
|
||||
}
|
||||
+53
-64
@@ -14,6 +14,7 @@ import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"hash/crc32"
|
||||
"io/fs"
|
||||
"math/bits"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -148,17 +149,16 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
var libcDependencies []*compileJob
|
||||
switch config.Target.Libc {
|
||||
case "darwin-libSystem":
|
||||
libcJob := makeDarwinLibSystemJob(config, tmpdir)
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
job := makeDarwinLibSystemJob(config, tmpdir)
|
||||
libcDependencies = append(libcDependencies, job)
|
||||
case "musl":
|
||||
var unlock func()
|
||||
libcJob, unlock, err := libMusl.load(config, tmpdir)
|
||||
job, unlock, err := libMusl.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, dummyCompileJob(filepath.Join(filepath.Dir(libcJob.result), "crt1.o")))
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
libcDependencies = append(libcDependencies, dummyCompileJob(filepath.Join(filepath.Dir(job.result), "crt1.o")))
|
||||
libcDependencies = append(libcDependencies, job)
|
||||
case "picolibc":
|
||||
libcJob, unlock, err := libPicolibc.load(config, tmpdir)
|
||||
if err != nil {
|
||||
@@ -167,12 +167,11 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
case "wasi-libc":
|
||||
libcJob, unlock, err := libWasiLibc.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
path := filepath.Join(root, "lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a")
|
||||
if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) {
|
||||
return BuildResult{}, errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?")
|
||||
}
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
libcDependencies = append(libcDependencies, dummyCompileJob(path))
|
||||
case "wasmbuiltins":
|
||||
libcJob, unlock, err := libWasmBuiltins.load(config, tmpdir)
|
||||
if err != nil {
|
||||
@@ -181,12 +180,12 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
case "mingw-w64":
|
||||
libcJob, unlock, err := libMinGW.load(config, tmpdir)
|
||||
job, unlock, err := libMinGW.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
libcDependencies = append(libcDependencies, job)
|
||||
libcDependencies = append(libcDependencies, makeMinGWExtraLibs(tmpdir, config.GOARCH())...)
|
||||
case "":
|
||||
// no library specified, so nothing to do
|
||||
@@ -214,7 +213,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
MaxStackAlloc: config.MaxStackAlloc(),
|
||||
NeedsStackObjects: config.NeedsStackObjects(),
|
||||
Debug: !config.Options.SkipDWARF, // emit DWARF except when -internal-nodwarf is passed
|
||||
Nobounds: config.Options.Nobounds,
|
||||
PanicStrategy: config.PanicStrategy(),
|
||||
}
|
||||
|
||||
@@ -451,15 +449,8 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
if global.IsNil() {
|
||||
return errors.New("global not found: " + globalName)
|
||||
}
|
||||
globalType := global.GlobalValueType()
|
||||
if globalType.TypeKind() != llvm.StructTypeKind || globalType.StructName() != "runtime._string" {
|
||||
// Verify this is indeed a string. This is needed so
|
||||
// that makeGlobalsModule can just create the right
|
||||
// globals of string type without checking.
|
||||
return fmt.Errorf("%s: not a string", globalName)
|
||||
}
|
||||
name := global.Name()
|
||||
newGlobal := llvm.AddGlobal(mod, globalType, name+".tmp")
|
||||
newGlobal := llvm.AddGlobal(mod, global.GlobalValueType(), name+".tmp")
|
||||
global.ReplaceAllUsesWith(newGlobal)
|
||||
global.EraseFromParentAsGlobal()
|
||||
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
|
||||
// initializer of each package.
|
||||
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
|
||||
// that the optimizer can see the whole program at once.
|
||||
err := optimizeProgram(mod, config)
|
||||
err := optimizeProgram(mod, config, globalValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -711,16 +693,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
linkerDependencies = append(linkerDependencies, job)
|
||||
}
|
||||
|
||||
// The Boehm collector is stored in a separate C library.
|
||||
if config.GC() == "boehm" {
|
||||
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
|
||||
// contain things like the interrupt vector table and low level operations
|
||||
// such as stack switching.
|
||||
@@ -1173,7 +1145,7 @@ func createEmbedObjectFile(data, hexSum, sourceFile, sourceDir, tmpdir string, c
|
||||
// optimizeProgram runs a series of optimizations and transformations that are
|
||||
// needed to convert a program to its final form. Some transformations are not
|
||||
// optional and must be run as the compiler expects them to run.
|
||||
func optimizeProgram(mod llvm.Module, config *compileopts.Config) 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())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1191,6 +1163,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
|
||||
// O0/O1/O2/Os/Oz optimization pipeline).
|
||||
errs := transform.Optimize(mod, config)
|
||||
@@ -1204,19 +1182,10 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeGlobalsModule(ctx llvm.Context, globals map[string]map[string]string, machine llvm.TargetMachine) llvm.Module {
|
||||
mod := ctx.NewModule("cmdline-globals")
|
||||
targetData := machine.CreateTargetData()
|
||||
defer targetData.Dispose()
|
||||
mod.SetDataLayout(targetData.String())
|
||||
|
||||
stringType := ctx.StructCreateNamed("runtime._string")
|
||||
uintptrType := ctx.IntType(targetData.PointerSize() * 8)
|
||||
stringType.StructSetBody([]llvm.Type{
|
||||
llvm.PointerType(ctx.Int8Type(), 0),
|
||||
uintptrType,
|
||||
}, false)
|
||||
|
||||
// setGlobalValues sets the global values from the -ldflags="-X ..." compiler
|
||||
// option in the given module. An error may be returned if the global is not of
|
||||
// the expected type.
|
||||
func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) error {
|
||||
var pkgPaths []string
|
||||
for pkgPath := range globals {
|
||||
pkgPaths = append(pkgPaths, pkgPath)
|
||||
@@ -1232,6 +1201,24 @@ func makeGlobalsModule(ctx llvm.Context, globals map[string]map[string]string, m
|
||||
for _, name := range names {
|
||||
value := pkg[name]
|
||||
globalName := pkgPath + "." + name
|
||||
global := mod.NamedGlobal(globalName)
|
||||
if global.IsNil() || !global.Initializer().IsNil() {
|
||||
// The global either does not exist (optimized away?) or has
|
||||
// some value, in which case it has already been initialized at
|
||||
// package init time.
|
||||
continue
|
||||
}
|
||||
|
||||
// A strin is a {ptr, len} pair. We need these types to build the
|
||||
// initializer.
|
||||
initializerType := global.GlobalValueType()
|
||||
if initializerType.TypeKind() != llvm.StructTypeKind || initializerType.StructName() == "" {
|
||||
return fmt.Errorf("%s: not a string", globalName)
|
||||
}
|
||||
elementTypes := initializerType.StructElementTypes()
|
||||
if len(elementTypes) != 2 {
|
||||
return fmt.Errorf("%s: not a string", globalName)
|
||||
}
|
||||
|
||||
// Create a buffer for the string contents.
|
||||
bufInitializer := mod.Context().ConstString(value, false)
|
||||
@@ -1242,20 +1229,22 @@ func makeGlobalsModule(ctx llvm.Context, globals map[string]map[string]string, m
|
||||
buf.SetLinkage(llvm.PrivateLinkage)
|
||||
|
||||
// Create the string value, which is a {ptr, len} pair.
|
||||
length := llvm.ConstInt(uintptrType, uint64(len(value)), false)
|
||||
initializer := llvm.ConstNamedStruct(stringType, []llvm.Value{
|
||||
buf,
|
||||
zero := llvm.ConstInt(mod.Context().Int32Type(), 0, false)
|
||||
ptr := llvm.ConstGEP(bufInitializer.Type(), buf, []llvm.Value{zero, zero})
|
||||
if ptr.Type() != elementTypes[0] {
|
||||
return fmt.Errorf("%s: not a string", globalName)
|
||||
}
|
||||
length := llvm.ConstInt(elementTypes[1], uint64(len(value)), false)
|
||||
initializer := llvm.ConstNamedStruct(initializerType, []llvm.Value{
|
||||
ptr,
|
||||
length,
|
||||
})
|
||||
|
||||
// Create the string global.
|
||||
global := llvm.AddGlobal(mod, stringType, globalName)
|
||||
// Set the initializer. No initializer should be set at this point.
|
||||
global.SetInitializer(initializer)
|
||||
global.SetAlignment(targetData.PrefTypeAlignment(stringType))
|
||||
}
|
||||
}
|
||||
|
||||
return mod
|
||||
return nil
|
||||
}
|
||||
|
||||
// functionStackSizes keeps stack size information about a single function
|
||||
|
||||
@@ -67,9 +67,9 @@ func TestClangAttributes(t *testing.T) {
|
||||
{GOOS: "linux", GOARCH: "mipsle", GOMIPS: "softfloat"},
|
||||
{GOOS: "darwin", GOARCH: "amd64"},
|
||||
{GOOS: "darwin", GOARCH: "arm64"},
|
||||
{GOOS: "windows", GOARCH: "386"},
|
||||
{GOOS: "windows", GOARCH: "amd64"},
|
||||
{GOOS: "windows", GOARCH: "arm64"},
|
||||
{GOOS: "wasip1", GOARCH: "wasm"},
|
||||
} {
|
||||
name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH
|
||||
if options.GOARCH == "arm" {
|
||||
|
||||
+1
-11
@@ -3,7 +3,6 @@ package builder
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
@@ -202,11 +201,6 @@ var avrBuiltins = []string{
|
||||
"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
|
||||
// LLVM. These symbols are for operations that cannot be emitted with a single
|
||||
// instruction or a short sequence of instructions for that target.
|
||||
@@ -226,7 +220,7 @@ var libCompilerRT = Library{
|
||||
// Development build.
|
||||
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
|
||||
switch compileopts.CanonicalArchName(target) {
|
||||
case "arm":
|
||||
@@ -235,10 +229,6 @@ var libCompilerRT = Library{
|
||||
builtins = append(builtins, avrBuiltins...)
|
||||
case "x86_64", "aarch64", "riscv64": // any 64-bit arch
|
||||
builtins = append(builtins, genericBuiltins128...)
|
||||
case "i386":
|
||||
if strings.Split(target, "-")[2] == "windows" {
|
||||
builtins = append(builtins, windowsI386Builtins...)
|
||||
}
|
||||
}
|
||||
return builtins, nil
|
||||
},
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
||||
|
||||
// Version range supported by TinyGo.
|
||||
const minorMin = 19
|
||||
const minorMax = 25
|
||||
const minorMax = 23
|
||||
|
||||
// Check that we support this Go toolchain version.
|
||||
gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
|
||||
@@ -36,7 +36,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
||||
if gorootMajor != 1 || gorootMinor < minorMin || gorootMinor > minorMax {
|
||||
// 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
|
||||
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
|
||||
|
||||
+12
-25
@@ -15,9 +15,6 @@ import (
|
||||
|
||||
// Library is a container for information about a single C library, such as a
|
||||
// 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 {
|
||||
// The library name, such as compiler-rt or picolibc.
|
||||
name string
|
||||
@@ -28,17 +25,11 @@ type Library struct {
|
||||
// cflags returns the C flags specific to this library
|
||||
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.
|
||||
sourceDir func() string
|
||||
|
||||
// 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.
|
||||
crt1Source string
|
||||
@@ -53,8 +44,13 @@ type Library struct {
|
||||
// As a side effect, this call creates the library header files if they didn't
|
||||
// exist yet.
|
||||
func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJob, abortLock func(), err error) {
|
||||
outdir := config.LibraryPath(l.name)
|
||||
outdir, precompiled := config.LibcPath(l.name)
|
||||
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).
|
||||
// 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")
|
||||
}
|
||||
}
|
||||
if l.needsLibc {
|
||||
args = append(args, config.LibcCFlags()...)
|
||||
}
|
||||
|
||||
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
|
||||
// archive job above, so must be run first.
|
||||
paths, err := l.librarySources(target, config.LibcNeedsMalloc())
|
||||
paths, err := l.librarySources(target)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, path := range paths {
|
||||
// Strip leading "../" parts off the path.
|
||||
path := path
|
||||
cleanpath := path
|
||||
for strings.HasPrefix(cleanpath, "../") {
|
||||
cleanpath = cleanpath[3:]
|
||||
@@ -241,14 +233,11 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
|
||||
objpath := filepath.Join(dir, cleanpath+".o")
|
||||
os.MkdirAll(filepath.Dir(objpath), 0o777)
|
||||
objs = append(objs, objpath)
|
||||
objfile := &compileJob{
|
||||
job.dependencies = append(job.dependencies, &compileJob{
|
||||
description: "compile " + srcpath,
|
||||
run: func(*compileJob) error {
|
||||
var compileArgs []string
|
||||
compileArgs = append(compileArgs, args...)
|
||||
if l.cflagsForFile != nil {
|
||||
compileArgs = append(compileArgs, l.cflagsForFile(path)...)
|
||||
}
|
||||
compileArgs = append(compileArgs, "-o", objpath, srcpath)
|
||||
if config.Options.PrintCommands != nil {
|
||||
config.Options.PrintCommands("clang", compileArgs...)
|
||||
@@ -259,8 +248,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
job.dependencies = append(job.dependencies, objfile)
|
||||
})
|
||||
}
|
||||
|
||||
// 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).
|
||||
if l.crt1Source != "" {
|
||||
srcpath := filepath.Join(sourceDir, l.crt1Source)
|
||||
crt1Job := &compileJob{
|
||||
job.dependencies = append(job.dependencies, &compileJob{
|
||||
description: "compile " + srcpath,
|
||||
run: func(*compileJob) error {
|
||||
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"))
|
||||
},
|
||||
}
|
||||
job.dependencies = append(job.dependencies, crt1Job)
|
||||
})
|
||||
}
|
||||
|
||||
ok = true
|
||||
|
||||
+33
-87
@@ -30,62 +30,25 @@ var libMinGW = Library{
|
||||
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64") },
|
||||
cflags: func(target, headerPath string) []string {
|
||||
mingwDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64")
|
||||
flags := []string{
|
||||
return []string{
|
||||
"-nostdlibinc",
|
||||
"-isystem", mingwDir + "/mingw-w64-crt/include",
|
||||
"-isystem", mingwDir + "/mingw-w64-headers/crt",
|
||||
"-isystem", mingwDir + "/mingw-w64-headers/include",
|
||||
"-I", mingwDir + "/mingw-w64-headers/defaults/include",
|
||||
"-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.
|
||||
var sources []string
|
||||
if strings.Split(target, "-")[0] == "i386" {
|
||||
// Old 32-bit x86 systems use msvcrt.dll.
|
||||
sources = []string{
|
||||
"mingw-w64-crt/crt/pseudo-reloc.c",
|
||||
"mingw-w64-crt/gdtoa/dmisc.c",
|
||||
"mingw-w64-crt/gdtoa/gdtoa.c",
|
||||
"mingw-w64-crt/gdtoa/gmisc.c",
|
||||
"mingw-w64-crt/gdtoa/misc.c",
|
||||
"mingw-w64-crt/math/x86/exp2.S",
|
||||
"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",
|
||||
}
|
||||
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
|
||||
},
|
||||
@@ -100,41 +63,27 @@ var libMinGW = Library{
|
||||
func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob {
|
||||
var jobs []*compileJob
|
||||
root := goenv.Get("TINYGOROOT")
|
||||
var libs []string
|
||||
if goarch == "386" {
|
||||
libs = []string{
|
||||
// x86 uses msvcrt.dll instead of UCRT for compatibility with old
|
||||
// Windows versions.
|
||||
"advapi32.def.in",
|
||||
"kernel32.def.in",
|
||||
"msvcrt.def.in",
|
||||
}
|
||||
} else {
|
||||
// Use the modernized UCRT on new systems.
|
||||
// Normally all the api-ms-win-crt-*.def files are all compiled to a
|
||||
// single .lib file. But to simplify things, we're going to leave them
|
||||
// as separate files.
|
||||
libs = []string{
|
||||
"advapi32.def.in",
|
||||
"kernel32.def.in",
|
||||
"api-ms-win-crt-conio-l1-1-0.def",
|
||||
"api-ms-win-crt-convert-l1-1-0.def.in",
|
||||
"api-ms-win-crt-environment-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 {
|
||||
// Normally all the api-ms-win-crt-*.def files are all compiled to a single
|
||||
// .lib file. But to simplify things, we're going to leave them as separate
|
||||
// files.
|
||||
for _, name := range []string{
|
||||
"kernel32.def.in",
|
||||
"api-ms-win-crt-conio-l1-1-0.def",
|
||||
"api-ms-win-crt-convert-l1-1-0.def.in",
|
||||
"api-ms-win-crt-environment-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",
|
||||
} {
|
||||
outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib")
|
||||
inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name)
|
||||
job := &compileJob{
|
||||
@@ -144,9 +93,6 @@ func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob {
|
||||
defpath := inpath
|
||||
var archDef, emulation string
|
||||
switch goarch {
|
||||
case "386":
|
||||
archDef = "-DDEF_I386"
|
||||
emulation = "i386pe"
|
||||
case "amd64":
|
||||
archDef = "-DDEF_X64"
|
||||
emulation = "i386pep"
|
||||
|
||||
+31
-49
@@ -12,45 +12,6 @@ import (
|
||||
"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{
|
||||
name: "musl",
|
||||
makeHeaders: func(target, includeDir string) error {
|
||||
@@ -63,13 +24,41 @@ var libMusl = Library{
|
||||
arch := compileopts.MuslArchitecture(target)
|
||||
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 {
|
||||
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.
|
||||
f, err := os.Create(filepath.Join(bits, "syscall.h"))
|
||||
f, err = os.Create(filepath.Join(bits, "syscall.h"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -121,36 +110,29 @@ var libMusl = Library{
|
||||
return cflags
|
||||
},
|
||||
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)
|
||||
globs := []string{
|
||||
"conf/*.c",
|
||||
"ctype/*.c",
|
||||
"env/*.c",
|
||||
"errno/*.c",
|
||||
"exit/*.c",
|
||||
"fcntl/*.c",
|
||||
"internal/defsysinfo.c",
|
||||
"internal/intscan.c",
|
||||
"internal/libc.c",
|
||||
"internal/shgetc.c",
|
||||
"internal/syscall_ret.c",
|
||||
"internal/vdso.c",
|
||||
"legacy/*.c",
|
||||
"locale/*.c",
|
||||
"linux/*.c",
|
||||
"locale/*.c",
|
||||
"malloc/*.c",
|
||||
"malloc/mallocng/*.c",
|
||||
"mman/*.c",
|
||||
"math/*.c",
|
||||
"misc/*.c",
|
||||
"multibyte/*.c",
|
||||
"sched/*.c",
|
||||
"signal/" + arch + "/*.s",
|
||||
"signal/*.c",
|
||||
"stdio/*.c",
|
||||
"stdlib/*.c",
|
||||
"string/*.c",
|
||||
"thread/" + arch + "/*.s",
|
||||
"thread/*.c",
|
||||
|
||||
+14
-2
@@ -19,7 +19,7 @@ type jsonManifest struct {
|
||||
DataFile string `json:"dat_file"`
|
||||
InitPacketData nrfInitPacket `json:"init_packet_data"`
|
||||
} `json:"application"`
|
||||
DFUVersion float64 `json:"dfu_version"` // yes, this is a JSON number, not a string
|
||||
DFUVersion float64 `json:"dfu_version,omitempty"` // yes, this is a JSON number, not a string
|
||||
} `json:"manifest"`
|
||||
}
|
||||
|
||||
@@ -93,7 +93,19 @@ func makeDFUFirmwareImage(options *compileopts.Options, infile, outfile string)
|
||||
manifest.Manifest.Application.BinaryFile = "application.bin"
|
||||
manifest.Manifest.Application.DataFile = "application.dat"
|
||||
manifest.Manifest.Application.InitPacketData = initPacket
|
||||
manifest.Manifest.DFUVersion = 0.5
|
||||
|
||||
// use build tag "nrf_open_dfu" to indicate open DFU format, otherwise defaults to secure DFU
|
||||
openDFU := false
|
||||
for _, tag := range options.Tags {
|
||||
if tag == "nrf_open_dfu" {
|
||||
openDFU = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !openDFU {
|
||||
manifest.Manifest.DFUVersion = 0.5
|
||||
}
|
||||
|
||||
// Write the JSON manifest to the file.
|
||||
jsonw, err := w.Create("manifest.json")
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ var libPicolibc = Library{
|
||||
}
|
||||
},
|
||||
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...)
|
||||
if !strings.HasPrefix(target, "avr") {
|
||||
// Small chips without long jumps can't compile many files (printf,
|
||||
|
||||
+1
-1
@@ -490,7 +490,7 @@ func loadProgramSize(path string, packagePathMap map[string]string) (*programSiz
|
||||
continue
|
||||
}
|
||||
if section.Type == elf.SHT_NOBITS {
|
||||
if strings.HasPrefix(section.Name, ".stack") {
|
||||
if section.Name == ".stack" {
|
||||
// TinyGo emits stack sections on microcontroller using the
|
||||
// ".stack" name.
|
||||
// This is a bit ugly, but I don't think there is a way to
|
||||
|
||||
@@ -42,9 +42,9 @@ func TestBinarySize(t *testing.T) {
|
||||
// This is a small number of very diverse targets that we want to test.
|
||||
tests := []sizeTest{
|
||||
// microcontrollers
|
||||
{"hifive1b", "examples/echo", 4580, 280, 0, 2264},
|
||||
{"microbit", "examples/serial", 2928, 388, 8, 2272},
|
||||
{"wioterminal", "examples/pininterrupt", 7387, 1489, 116, 6912},
|
||||
{"hifive1b", "examples/echo", 4560, 280, 0, 2268},
|
||||
{"microbit", "examples/serial", 2916, 388, 8, 2272},
|
||||
{"wioterminal", "examples/pininterrupt", 7315, 1489, 116, 6912},
|
||||
|
||||
// TODO: also check wasm. Right now this is difficult, because
|
||||
// wasm binaries are run through wasm-opt and therefore the
|
||||
|
||||
@@ -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
|
||||
},
|
||||
}
|
||||
@@ -29,8 +29,6 @@ var libWasmBuiltins = Library{
|
||||
"-Wall",
|
||||
"-std=gnu11",
|
||||
"-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/generic",
|
||||
"-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") },
|
||||
librarySources: func(target string, _ bool) ([]string, error) {
|
||||
librarySources: func(target string) ([]string, error) {
|
||||
return []string{
|
||||
// memory builtins needed for llvm.memcpy.*, llvm.memmove.*, and
|
||||
// llvm.memset.* LLVM intrinsics.
|
||||
|
||||
+64
-45
@@ -92,18 +92,18 @@ type noescapingFunc struct {
|
||||
// cgoAliases list type aliases between Go and C, for types that are equivalent
|
||||
// in both languages. See addTypeAliases.
|
||||
var cgoAliases = map[string]string{
|
||||
"_Cgo_int8_t": "int8",
|
||||
"_Cgo_int16_t": "int16",
|
||||
"_Cgo_int32_t": "int32",
|
||||
"_Cgo_int64_t": "int64",
|
||||
"_Cgo_uint8_t": "uint8",
|
||||
"_Cgo_uint16_t": "uint16",
|
||||
"_Cgo_uint32_t": "uint32",
|
||||
"_Cgo_uint64_t": "uint64",
|
||||
"_Cgo_uintptr_t": "uintptr",
|
||||
"_Cgo_float": "float32",
|
||||
"_Cgo_double": "float64",
|
||||
"_Cgo__Bool": "bool",
|
||||
"C.int8_t": "int8",
|
||||
"C.int16_t": "int16",
|
||||
"C.int32_t": "int32",
|
||||
"C.int64_t": "int64",
|
||||
"C.uint8_t": "uint8",
|
||||
"C.uint16_t": "uint16",
|
||||
"C.uint32_t": "uint32",
|
||||
"C.uint64_t": "uint64",
|
||||
"C.uintptr_t": "uintptr",
|
||||
"C.float": "float32",
|
||||
"C.double": "float64",
|
||||
"C._Bool": "bool",
|
||||
}
|
||||
|
||||
// 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
|
||||
// runtime doesn't need to know the C int type, lengths are converted to uintptr
|
||||
// first.
|
||||
// These functions will be modified to get a "C." prefix, so the source below
|
||||
// doesn't reflect the final AST.
|
||||
const generatedGoFilePrefixBase = `
|
||||
import "syscall"
|
||||
import "unsafe"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||
func _Cgo_CString(string) *_Cgo_char
|
||||
//go:linkname C.CString runtime.cgo_CString
|
||||
func CString(string) *C.char
|
||||
|
||||
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||
func _Cgo_GoString(*_Cgo_char) string
|
||||
//go:linkname C.GoString runtime.cgo_GoString
|
||||
func GoString(*C.char) string
|
||||
|
||||
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
||||
func __GoStringN(*C.char, uintptr) string
|
||||
|
||||
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||
func GoStringN(cstr *C.char, length C.int) string {
|
||||
return C.__GoStringN(cstr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
||||
func __GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
|
||||
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||
func GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func __CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||
return _Cgo___CBytes(b)
|
||||
func CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||
func _Cgo___get_errno_num() uintptr
|
||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
||||
func __get_errno_num() uintptr
|
||||
`
|
||||
|
||||
const generatedGoFilePrefixOther = generatedGoFilePrefixBase + `
|
||||
func _Cgo___get_errno() error {
|
||||
return syscall.Errno(_Cgo___get_errno_num())
|
||||
func __get_errno() error {
|
||||
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.
|
||||
// Source of the errno values: lib/mingw-w64/mingw-w64-headers/crt/errno.h
|
||||
const generatedGoFilePrefixWindows = generatedGoFilePrefixBase + `
|
||||
var _Cgo___errno_mapping = [...]syscall.Errno{
|
||||
var __errno_mapping = [...]syscall.Errno{
|
||||
1: syscall.EPERM,
|
||||
2: syscall.ENOENT,
|
||||
3: syscall.ESRCH,
|
||||
@@ -236,10 +238,10 @@ var _Cgo___errno_mapping = [...]syscall.Errno{
|
||||
42: syscall.EILSEQ,
|
||||
}
|
||||
|
||||
func _Cgo___get_errno() error {
|
||||
num := _Cgo___get_errno_num()
|
||||
if num < uintptr(len(_Cgo___errno_mapping)) {
|
||||
if mapped := _Cgo___errno_mapping[num]; mapped != 0 {
|
||||
func __get_errno() error {
|
||||
num := C.__get_errno_num()
|
||||
if num < uintptr(len(__errno_mapping)) {
|
||||
if mapped := __errno_mapping[num]; mapped != 0 {
|
||||
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
|
||||
// confused about where comments should go.
|
||||
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.
|
||||
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,
|
||||
}
|
||||
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)
|
||||
}
|
||||
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 {
|
||||
// Some types are defined in stdint.h and map directly to a particular Go
|
||||
// type.
|
||||
if alias := cgoAliases["_Cgo_"+name]; alias != "" {
|
||||
if alias := cgoAliases["C."+name]; alias != "" {
|
||||
return alias
|
||||
}
|
||||
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 "_Cgo_" + name
|
||||
return "C." + name
|
||||
}
|
||||
|
||||
// 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:
|
||||
// Add struct bitfields.
|
||||
for _, bitfield := range elaboratedType.bitfields {
|
||||
f.createBitfieldGetter(bitfield, "_Cgo_"+name)
|
||||
f.createBitfieldSetter(bitfield, "_Cgo_"+name)
|
||||
f.createBitfieldGetter(bitfield, "C."+name)
|
||||
f.createBitfieldSetter(bitfield, "C."+name)
|
||||
}
|
||||
if elaboratedType.unionSize != 0 {
|
||||
// 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)))
|
||||
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{
|
||||
Fun: &ast.Ident{
|
||||
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
|
||||
}
|
||||
if x.Name == "C" {
|
||||
name := "_Cgo_" + node.Sel.Name
|
||||
name := "C." + node.Sel.Name
|
||||
if found, ok := names[node.Sel.Name]; ok {
|
||||
name = f.getASTDeclName(node.Sel.Name, found, false)
|
||||
}
|
||||
|
||||
+28
-28
@@ -71,7 +71,7 @@ unsigned tinygo_clang_Cursor_isMacroFunctionLike(GoCXCursor c);
|
||||
// libclang.go:68:5: note: previous declaration is here
|
||||
// See: https://github.com/golang/go/issues/49721
|
||||
#if defined(_WIN32)
|
||||
#define CGO_DECL __declspec(dllexport)
|
||||
#define CGO_DECL // __declspec(dllexport)
|
||||
#else
|
||||
#define CGO_DECL
|
||||
#endif
|
||||
@@ -219,7 +219,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||
numArgs := int(C.tinygo_clang_Cursor_getNumArguments(c))
|
||||
obj := &ast.Object{
|
||||
Kind: ast.Fun,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
}
|
||||
exportName := name
|
||||
localName := name
|
||||
@@ -257,7 +257,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||
},
|
||||
Name: &ast.Ident{
|
||||
NamePos: pos,
|
||||
Name: "_Cgo_" + localName,
|
||||
Name: "C." + localName,
|
||||
Obj: obj,
|
||||
},
|
||||
Type: &ast.FuncType{
|
||||
@@ -319,7 +319,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||
return decl, stringSignature
|
||||
case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
|
||||
typ := f.makeASTRecordType(c, pos)
|
||||
typeName := "_Cgo_" + name
|
||||
typeName := "C." + name
|
||||
typeExpr := typ.typeExpr
|
||||
if typ.unionSize != 0 {
|
||||
// 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
|
||||
return typeSpec, typ
|
||||
case C.CXCursor_TypedefDecl:
|
||||
typeName := "_Cgo_" + name
|
||||
typeName := "C." + name
|
||||
underlyingType := C.tinygo_clang_getTypedefDeclUnderlyingType(c)
|
||||
obj := &ast.Object{
|
||||
Kind: ast.Typ,
|
||||
@@ -378,12 +378,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||
}
|
||||
obj := &ast.Object{
|
||||
Kind: ast.Var,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
}
|
||||
valueSpec := &ast.ValueSpec{
|
||||
Names: []*ast.Ident{{
|
||||
NamePos: pos,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
Obj: obj,
|
||||
}},
|
||||
Type: typeExpr,
|
||||
@@ -407,12 +407,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||
}
|
||||
obj := &ast.Object{
|
||||
Kind: ast.Con,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
}
|
||||
valueSpec := &ast.ValueSpec{
|
||||
Names: []*ast.Ident{{
|
||||
NamePos: pos,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
Obj: obj,
|
||||
}},
|
||||
Values: []ast.Expr{expr},
|
||||
@@ -423,7 +423,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||
case C.CXCursor_EnumDecl:
|
||||
obj := &ast.Object{
|
||||
Kind: ast.Typ,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
}
|
||||
underlying := C.tinygo_clang_getEnumDeclIntegerType(c)
|
||||
// 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{
|
||||
Name: &ast.Ident{
|
||||
NamePos: pos,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
Obj: obj,
|
||||
},
|
||||
Assign: pos,
|
||||
@@ -454,12 +454,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||
}
|
||||
obj := &ast.Object{
|
||||
Kind: ast.Con,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
}
|
||||
valueSpec := &ast.ValueSpec{
|
||||
Names: []*ast.Ident{{
|
||||
NamePos: pos,
|
||||
Name: "_Cgo_" + name,
|
||||
Name: "C." + name,
|
||||
Obj: obj,
|
||||
}},
|
||||
Values: []ast.Expr{expr},
|
||||
@@ -745,27 +745,27 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr {
|
||||
var typeName string
|
||||
switch typ.kind {
|
||||
case C.CXType_Char_S, C.CXType_Char_U:
|
||||
typeName = "_Cgo_char"
|
||||
typeName = "C.char"
|
||||
case C.CXType_SChar:
|
||||
typeName = "_Cgo_schar"
|
||||
typeName = "C.schar"
|
||||
case C.CXType_UChar:
|
||||
typeName = "_Cgo_uchar"
|
||||
typeName = "C.uchar"
|
||||
case C.CXType_Short:
|
||||
typeName = "_Cgo_short"
|
||||
typeName = "C.short"
|
||||
case C.CXType_UShort:
|
||||
typeName = "_Cgo_ushort"
|
||||
typeName = "C.ushort"
|
||||
case C.CXType_Int:
|
||||
typeName = "_Cgo_int"
|
||||
typeName = "C.int"
|
||||
case C.CXType_UInt:
|
||||
typeName = "_Cgo_uint"
|
||||
typeName = "C.uint"
|
||||
case C.CXType_Long:
|
||||
typeName = "_Cgo_long"
|
||||
typeName = "C.long"
|
||||
case C.CXType_ULong:
|
||||
typeName = "_Cgo_ulong"
|
||||
typeName = "C.ulong"
|
||||
case C.CXType_LongLong:
|
||||
typeName = "_Cgo_longlong"
|
||||
typeName = "C.longlong"
|
||||
case C.CXType_ULongLong:
|
||||
typeName = "_Cgo_ulonglong"
|
||||
typeName = "C.ulonglong"
|
||||
case C.CXType_Bool:
|
||||
typeName = "bool"
|
||||
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))
|
||||
typeKindSpelling := getString(C.clang_getTypeKindSpelling(typ.kind))
|
||||
f.addError(pos, fmt.Sprintf("unknown C type: %v (libclang type kind %s)", typeSpelling, typeKindSpelling))
|
||||
typeName = "_Cgo_<unknown>"
|
||||
typeName = "C.<unknown>"
|
||||
}
|
||||
return &ast.Ident{
|
||||
NamePos: pos,
|
||||
@@ -913,7 +913,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
|
||||
var goName string
|
||||
typeSize := C.clang_Type_getSizeOf(underlyingType)
|
||||
switch name {
|
||||
case "_Cgo_char":
|
||||
case "C.char":
|
||||
if typeSize != 1 {
|
||||
// This happens for some very special purpose architectures
|
||||
// (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:
|
||||
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 {
|
||||
case 1:
|
||||
goName = "int8"
|
||||
@@ -937,7 +937,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp
|
||||
case 8:
|
||||
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 {
|
||||
case 1:
|
||||
goName = "uint8"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build !byollvm && llvm19
|
||||
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18
|
||||
|
||||
package cgo
|
||||
|
||||
|
||||
@@ -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"
|
||||
Vendored
+31
-31
@@ -5,50 +5,50 @@ import "unsafe"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||
func _Cgo_CString(string) *_Cgo_char
|
||||
//go:linkname C.CString runtime.cgo_CString
|
||||
func C.CString(string) *C.char
|
||||
|
||||
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||
func _Cgo_GoString(*_Cgo_char) string
|
||||
//go:linkname C.GoString runtime.cgo_GoString
|
||||
func C.GoString(*C.char) string
|
||||
|
||||
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
||||
func C.__GoStringN(*C.char, uintptr) string
|
||||
|
||||
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
||||
return C.__GoStringN(cstr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
|
||||
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||
return _Cgo___CBytes(b)
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||
func _Cgo___get_errno_num() uintptr
|
||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
||||
func C.__get_errno_num() uintptr
|
||||
|
||||
func _Cgo___get_errno() error {
|
||||
return syscall.Errno(_Cgo___get_errno_num())
|
||||
func C.__get_errno() error {
|
||||
return syscall.Errno(C.__get_errno_num())
|
||||
}
|
||||
|
||||
type (
|
||||
_Cgo_char uint8
|
||||
_Cgo_schar int8
|
||||
_Cgo_uchar uint8
|
||||
_Cgo_short int16
|
||||
_Cgo_ushort uint16
|
||||
_Cgo_int int32
|
||||
_Cgo_uint uint32
|
||||
_Cgo_long int32
|
||||
_Cgo_ulong uint32
|
||||
_Cgo_longlong int64
|
||||
_Cgo_ulonglong uint64
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
C.uchar uint8
|
||||
C.short int16
|
||||
C.ushort uint16
|
||||
C.int int32
|
||||
C.uint uint32
|
||||
C.long int32
|
||||
C.ulong uint32
|
||||
C.longlong int64
|
||||
C.ulonglong uint64
|
||||
)
|
||||
|
||||
Vendored
+38
-38
@@ -5,58 +5,58 @@ import "unsafe"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||
func _Cgo_CString(string) *_Cgo_char
|
||||
//go:linkname C.CString runtime.cgo_CString
|
||||
func C.CString(string) *C.char
|
||||
|
||||
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||
func _Cgo_GoString(*_Cgo_char) string
|
||||
//go:linkname C.GoString runtime.cgo_GoString
|
||||
func C.GoString(*C.char) string
|
||||
|
||||
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
||||
func C.__GoStringN(*C.char, uintptr) string
|
||||
|
||||
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
||||
return C.__GoStringN(cstr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
|
||||
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||
return _Cgo___CBytes(b)
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||
func _Cgo___get_errno_num() uintptr
|
||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
||||
func C.__get_errno_num() uintptr
|
||||
|
||||
func _Cgo___get_errno() error {
|
||||
return syscall.Errno(_Cgo___get_errno_num())
|
||||
func C.__get_errno() error {
|
||||
return syscall.Errno(C.__get_errno_num())
|
||||
}
|
||||
|
||||
type (
|
||||
_Cgo_char uint8
|
||||
_Cgo_schar int8
|
||||
_Cgo_uchar uint8
|
||||
_Cgo_short int16
|
||||
_Cgo_ushort uint16
|
||||
_Cgo_int int32
|
||||
_Cgo_uint uint32
|
||||
_Cgo_long int32
|
||||
_Cgo_ulong uint32
|
||||
_Cgo_longlong int64
|
||||
_Cgo_ulonglong uint64
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
C.uchar uint8
|
||||
C.short int16
|
||||
C.ushort uint16
|
||||
C.int int32
|
||||
C.uint uint32
|
||||
C.long int32
|
||||
C.ulong uint32
|
||||
C.longlong int64
|
||||
C.ulonglong uint64
|
||||
)
|
||||
|
||||
const _Cgo_foo = 3
|
||||
const _Cgo_bar = _Cgo_foo
|
||||
const _Cgo_unreferenced = 4
|
||||
const _Cgo_referenced = _Cgo_unreferenced
|
||||
const _Cgo_fnlike_val = 5
|
||||
const _Cgo_square_val = (20 * 20)
|
||||
const _Cgo_add_val = (3 + 5)
|
||||
const C.foo = 3
|
||||
const C.bar = C.foo
|
||||
const C.unreferenced = 4
|
||||
const C.referenced = C.unreferenced
|
||||
const C.fnlike_val = 5
|
||||
const C.square_val = (20 * 20)
|
||||
const C.add_val = (3 + 5)
|
||||
|
||||
Vendored
+46
-46
@@ -14,16 +14,16 @@
|
||||
// testdata/errors.go:3:1: function "unusedFunction" in #cgo noescape line is not used
|
||||
|
||||
// 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:108: undefined: _Cgo_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:112: undefined: _Cgo_SOME_CONST_4
|
||||
// testdata/errors.go:114: undefined: _Cgo_SOME_CONST_b
|
||||
// testdata/errors.go:116: undefined: _Cgo_SOME_CONST_startspace
|
||||
// testdata/errors.go:119: undefined: _Cgo_SOME_PARAM_CONST_invalid
|
||||
// testdata/errors.go:122: undefined: _Cgo_add_toomuch
|
||||
// testdata/errors.go:123: undefined: _Cgo_add_toolittle
|
||||
// testdata/errors.go:108: undefined: C.SOME_CONST_1
|
||||
// testdata/errors.go:110: cannot use C.SOME_CONST_3 (untyped int constant 1234) as byte value in variable declaration (overflows)
|
||||
// testdata/errors.go:112: undefined: C.SOME_CONST_4
|
||||
// testdata/errors.go:114: undefined: C.SOME_CONST_b
|
||||
// testdata/errors.go:116: undefined: C.SOME_CONST_startspace
|
||||
// testdata/errors.go:119: undefined: C.SOME_PARAM_CONST_invalid
|
||||
// testdata/errors.go:122: undefined: C.add_toomuch
|
||||
// testdata/errors.go:123: undefined: C.add_toolittle
|
||||
|
||||
package main
|
||||
|
||||
@@ -32,58 +32,58 @@ import "unsafe"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||
func _Cgo_CString(string) *_Cgo_char
|
||||
//go:linkname C.CString runtime.cgo_CString
|
||||
func C.CString(string) *C.char
|
||||
|
||||
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||
func _Cgo_GoString(*_Cgo_char) string
|
||||
//go:linkname C.GoString runtime.cgo_GoString
|
||||
func C.GoString(*C.char) string
|
||||
|
||||
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
||||
func C.__GoStringN(*C.char, uintptr) string
|
||||
|
||||
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
||||
return C.__GoStringN(cstr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
|
||||
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||
return _Cgo___CBytes(b)
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||
func _Cgo___get_errno_num() uintptr
|
||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
||||
func C.__get_errno_num() uintptr
|
||||
|
||||
func _Cgo___get_errno() error {
|
||||
return syscall.Errno(_Cgo___get_errno_num())
|
||||
func C.__get_errno() error {
|
||||
return syscall.Errno(C.__get_errno_num())
|
||||
}
|
||||
|
||||
type (
|
||||
_Cgo_char uint8
|
||||
_Cgo_schar int8
|
||||
_Cgo_uchar uint8
|
||||
_Cgo_short int16
|
||||
_Cgo_ushort uint16
|
||||
_Cgo_int int32
|
||||
_Cgo_uint uint32
|
||||
_Cgo_long int32
|
||||
_Cgo_ulong uint32
|
||||
_Cgo_longlong int64
|
||||
_Cgo_ulonglong uint64
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
C.uchar uint8
|
||||
C.short int16
|
||||
C.ushort uint16
|
||||
C.int int32
|
||||
C.uint uint32
|
||||
C.long int32
|
||||
C.ulong uint32
|
||||
C.longlong int64
|
||||
C.ulonglong uint64
|
||||
)
|
||||
type _Cgo_struct_point_t struct {
|
||||
x _Cgo_int
|
||||
y _Cgo_int
|
||||
type C.struct_point_t struct {
|
||||
x C.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 _Cgo_SOME_PARAM_CONST_valid = 3 + 4
|
||||
const C.SOME_CONST_3 = 1234
|
||||
const C.SOME_PARAM_CONST_valid = 3 + 4
|
||||
|
||||
Vendored
+33
-33
@@ -10,53 +10,53 @@ import "unsafe"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||
func _Cgo_CString(string) *_Cgo_char
|
||||
//go:linkname C.CString runtime.cgo_CString
|
||||
func C.CString(string) *C.char
|
||||
|
||||
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||
func _Cgo_GoString(*_Cgo_char) string
|
||||
//go:linkname C.GoString runtime.cgo_GoString
|
||||
func C.GoString(*C.char) string
|
||||
|
||||
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
||||
func C.__GoStringN(*C.char, uintptr) string
|
||||
|
||||
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
||||
return C.__GoStringN(cstr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
|
||||
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||
return _Cgo___CBytes(b)
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||
func _Cgo___get_errno_num() uintptr
|
||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
||||
func C.__get_errno_num() uintptr
|
||||
|
||||
func _Cgo___get_errno() error {
|
||||
return syscall.Errno(_Cgo___get_errno_num())
|
||||
func C.__get_errno() error {
|
||||
return syscall.Errno(C.__get_errno_num())
|
||||
}
|
||||
|
||||
type (
|
||||
_Cgo_char uint8
|
||||
_Cgo_schar int8
|
||||
_Cgo_uchar uint8
|
||||
_Cgo_short int16
|
||||
_Cgo_ushort uint16
|
||||
_Cgo_int int32
|
||||
_Cgo_uint uint32
|
||||
_Cgo_long int32
|
||||
_Cgo_ulong uint32
|
||||
_Cgo_longlong int64
|
||||
_Cgo_ulonglong uint64
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
C.uchar uint8
|
||||
C.short int16
|
||||
C.ushort uint16
|
||||
C.int int32
|
||||
C.uint uint32
|
||||
C.long int32
|
||||
C.ulong uint32
|
||||
C.longlong int64
|
||||
C.ulonglong uint64
|
||||
)
|
||||
|
||||
const _Cgo_BAR = 3
|
||||
const _Cgo_FOO_H = 1
|
||||
const C.BAR = 3
|
||||
const C.FOO_H = 1
|
||||
|
||||
Vendored
+42
-42
@@ -5,80 +5,80 @@ import "unsafe"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||
func _Cgo_CString(string) *_Cgo_char
|
||||
//go:linkname C.CString runtime.cgo_CString
|
||||
func C.CString(string) *C.char
|
||||
|
||||
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||
func _Cgo_GoString(*_Cgo_char) string
|
||||
//go:linkname C.GoString runtime.cgo_GoString
|
||||
func C.GoString(*C.char) string
|
||||
|
||||
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
||||
func C.__GoStringN(*C.char, uintptr) string
|
||||
|
||||
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
||||
return C.__GoStringN(cstr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
|
||||
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||
return _Cgo___CBytes(b)
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||
func _Cgo___get_errno_num() uintptr
|
||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
||||
func C.__get_errno_num() uintptr
|
||||
|
||||
func _Cgo___get_errno() error {
|
||||
return syscall.Errno(_Cgo___get_errno_num())
|
||||
func C.__get_errno() error {
|
||||
return syscall.Errno(C.__get_errno_num())
|
||||
}
|
||||
|
||||
type (
|
||||
_Cgo_char uint8
|
||||
_Cgo_schar int8
|
||||
_Cgo_uchar uint8
|
||||
_Cgo_short int16
|
||||
_Cgo_ushort uint16
|
||||
_Cgo_int int32
|
||||
_Cgo_uint uint32
|
||||
_Cgo_long int32
|
||||
_Cgo_ulong uint32
|
||||
_Cgo_longlong int64
|
||||
_Cgo_ulonglong uint64
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
C.uchar uint8
|
||||
C.short int16
|
||||
C.ushort uint16
|
||||
C.int int32
|
||||
C.uint uint32
|
||||
C.long int32
|
||||
C.ulong uint32
|
||||
C.longlong int64
|
||||
C.ulonglong uint64
|
||||
)
|
||||
|
||||
//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
|
||||
//go:variadic
|
||||
func _Cgo_variadic0()
|
||||
func C.variadic0()
|
||||
|
||||
var _Cgo_variadic0$funcaddr unsafe.Pointer
|
||||
var C.variadic0$funcaddr unsafe.Pointer
|
||||
|
||||
//export variadic2
|
||||
//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
|
||||
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
|
||||
//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
|
||||
var _Cgo_someValue _Cgo_int
|
||||
var C.someValue C.int
|
||||
|
||||
Vendored
+99
-103
@@ -5,162 +5,158 @@ import "unsafe"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
//go:linkname _Cgo_CString runtime.cgo_CString
|
||||
func _Cgo_CString(string) *_Cgo_char
|
||||
//go:linkname C.CString runtime.cgo_CString
|
||||
func C.CString(string) *C.char
|
||||
|
||||
//go:linkname _Cgo_GoString runtime.cgo_GoString
|
||||
func _Cgo_GoString(*_Cgo_char) string
|
||||
//go:linkname C.GoString runtime.cgo_GoString
|
||||
func C.GoString(*C.char) string
|
||||
|
||||
//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN
|
||||
func _Cgo___GoStringN(*_Cgo_char, uintptr) string
|
||||
//go:linkname C.__GoStringN runtime.cgo_GoStringN
|
||||
func C.__GoStringN(*C.char, uintptr) string
|
||||
|
||||
func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string {
|
||||
return _Cgo___GoStringN(cstr, uintptr(length))
|
||||
func C.GoStringN(cstr *C.char, length C.int) string {
|
||||
return C.__GoStringN(cstr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes
|
||||
func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
//go:linkname C.__GoBytes runtime.cgo_GoBytes
|
||||
func C.__GoBytes(unsafe.Pointer, uintptr) []byte
|
||||
|
||||
func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte {
|
||||
return _Cgo___GoBytes(ptr, uintptr(length))
|
||||
func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
||||
return C.__GoBytes(ptr, uintptr(length))
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___CBytes runtime.cgo_CBytes
|
||||
func _Cgo___CBytes([]byte) unsafe.Pointer
|
||||
//go:linkname C.__CBytes runtime.cgo_CBytes
|
||||
func C.__CBytes([]byte) unsafe.Pointer
|
||||
|
||||
func _Cgo_CBytes(b []byte) unsafe.Pointer {
|
||||
return _Cgo___CBytes(b)
|
||||
func C.CBytes(b []byte) unsafe.Pointer {
|
||||
return C.__CBytes(b)
|
||||
}
|
||||
|
||||
//go:linkname _Cgo___get_errno_num runtime.cgo_errno
|
||||
func _Cgo___get_errno_num() uintptr
|
||||
//go:linkname C.__get_errno_num runtime.cgo_errno
|
||||
func C.__get_errno_num() uintptr
|
||||
|
||||
func _Cgo___get_errno() error {
|
||||
return syscall.Errno(_Cgo___get_errno_num())
|
||||
func C.__get_errno() error {
|
||||
return syscall.Errno(C.__get_errno_num())
|
||||
}
|
||||
|
||||
type (
|
||||
_Cgo_char uint8
|
||||
_Cgo_schar int8
|
||||
_Cgo_uchar uint8
|
||||
_Cgo_short int16
|
||||
_Cgo_ushort uint16
|
||||
_Cgo_int int32
|
||||
_Cgo_uint uint32
|
||||
_Cgo_long int32
|
||||
_Cgo_ulong uint32
|
||||
_Cgo_longlong int64
|
||||
_Cgo_ulonglong uint64
|
||||
C.char uint8
|
||||
C.schar int8
|
||||
C.uchar uint8
|
||||
C.short int16
|
||||
C.ushort uint16
|
||||
C.int int32
|
||||
C.uint uint32
|
||||
C.long int32
|
||||
C.ulong uint32
|
||||
C.longlong int64
|
||||
C.ulonglong uint64
|
||||
)
|
||||
type _Cgo_myint = _Cgo_int
|
||||
type _Cgo_struct_point2d_t struct {
|
||||
x _Cgo_int
|
||||
y _Cgo_int
|
||||
type C.myint = C.int
|
||||
type C.struct_point2d_t struct {
|
||||
x C.int
|
||||
y C.int
|
||||
}
|
||||
type _Cgo_point2d_t = _Cgo_struct_point2d_t
|
||||
type _Cgo_struct_point3d struct {
|
||||
x _Cgo_int
|
||||
y _Cgo_int
|
||||
z _Cgo_int
|
||||
type C.point2d_t = C.struct_point2d_t
|
||||
type C.struct_point3d struct {
|
||||
x C.int
|
||||
y C.int
|
||||
z C.int
|
||||
}
|
||||
type _Cgo_point3d_t = _Cgo_struct_point3d
|
||||
type _Cgo_struct_type1 struct {
|
||||
_type _Cgo_int
|
||||
__type _Cgo_int
|
||||
___type _Cgo_int
|
||||
type C.point3d_t = C.struct_point3d
|
||||
type C.struct_type1 struct {
|
||||
_type C.int
|
||||
__type C.int
|
||||
___type C.int
|
||||
}
|
||||
type _Cgo_struct_type2 struct{ _type _Cgo_int }
|
||||
type _Cgo_union_union1_t struct{ i _Cgo_int }
|
||||
type _Cgo_union1_t = _Cgo_union_union1_t
|
||||
type _Cgo_union_union3_t struct{ $union uint64 }
|
||||
type C.struct_type2 struct{ _type C.int }
|
||||
type C.union_union1_t struct{ i C.int }
|
||||
type C.union1_t = C.union_union1_t
|
||||
type C.union_union3_t struct{ $union uint64 }
|
||||
|
||||
func (union *_Cgo_union_union3_t) unionfield_i() *_Cgo_int {
|
||||
return (*_Cgo_int)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
func (union *_Cgo_union_union3_t) unionfield_d() *float64 {
|
||||
func (union *C.union_union3_t) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) }
|
||||
func (union *C.union_union3_t) unionfield_d() *float64 {
|
||||
return (*float64)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
func (union *_Cgo_union_union3_t) unionfield_s() *_Cgo_short {
|
||||
return (*_Cgo_short)(unsafe.Pointer(&union.$union))
|
||||
func (union *C.union_union3_t) unionfield_s() *C.short {
|
||||
return (*C.short)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
|
||||
type _Cgo_union3_t = _Cgo_union_union3_t
|
||||
type _Cgo_union_union2d struct{ $union [2]uint64 }
|
||||
type C.union3_t = C.union_union3_t
|
||||
type C.union_union2d struct{ $union [2]uint64 }
|
||||
|
||||
func (union *_Cgo_union_union2d) unionfield_i() *_Cgo_int {
|
||||
return (*_Cgo_int)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
func (union *_Cgo_union_union2d) unionfield_d() *[2]float64 {
|
||||
func (union *C.union_union2d) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) }
|
||||
func (union *C.union_union2d) unionfield_d() *[2]float64 {
|
||||
return (*[2]float64)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
|
||||
type _Cgo_union2d_t = _Cgo_union_union2d
|
||||
type _Cgo_union_unionarray_t struct{ arr [10]_Cgo_uchar }
|
||||
type _Cgo_unionarray_t = _Cgo_union_unionarray_t
|
||||
type _Cgo__Ctype_union___0 struct{ $union [3]uint32 }
|
||||
type C.union2d_t = C.union_union2d
|
||||
type C.union_unionarray_t struct{ arr [10]C.uchar }
|
||||
type C.unionarray_t = C.union_unionarray_t
|
||||
type C._Ctype_union___0 struct{ $union [3]uint32 }
|
||||
|
||||
func (union *_Cgo__Ctype_union___0) unionfield_area() *_Cgo_point2d_t {
|
||||
return (*_Cgo_point2d_t)(unsafe.Pointer(&union.$union))
|
||||
func (union *C._Ctype_union___0) unionfield_area() *C.point2d_t {
|
||||
return (*C.point2d_t)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
func (union *_Cgo__Ctype_union___0) unionfield_solid() *_Cgo_point3d_t {
|
||||
return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union))
|
||||
func (union *C._Ctype_union___0) unionfield_solid() *C.point3d_t {
|
||||
return (*C.point3d_t)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
|
||||
type _Cgo_struct_struct_nested_t struct {
|
||||
begin _Cgo_point2d_t
|
||||
end _Cgo_point2d_t
|
||||
tag _Cgo_int
|
||||
type C.struct_struct_nested_t struct {
|
||||
begin C.point2d_t
|
||||
end C.point2d_t
|
||||
tag C.int
|
||||
|
||||
coord _Cgo__Ctype_union___0
|
||||
coord C._Ctype_union___0
|
||||
}
|
||||
type _Cgo_struct_nested_t = _Cgo_struct_struct_nested_t
|
||||
type _Cgo_union_union_nested_t struct{ $union [2]uint64 }
|
||||
type C.struct_nested_t = C.struct_struct_nested_t
|
||||
type C.union_union_nested_t struct{ $union [2]uint64 }
|
||||
|
||||
func (union *_Cgo_union_union_nested_t) unionfield_point() *_Cgo_point3d_t {
|
||||
return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union))
|
||||
func (union *C.union_union_nested_t) unionfield_point() *C.point3d_t {
|
||||
return (*C.point3d_t)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
func (union *_Cgo_union_union_nested_t) unionfield_array() *_Cgo_unionarray_t {
|
||||
return (*_Cgo_unionarray_t)(unsafe.Pointer(&union.$union))
|
||||
func (union *C.union_union_nested_t) unionfield_array() *C.unionarray_t {
|
||||
return (*C.unionarray_t)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
func (union *_Cgo_union_union_nested_t) unionfield_thing() *_Cgo_union3_t {
|
||||
return (*_Cgo_union3_t)(unsafe.Pointer(&union.$union))
|
||||
func (union *C.union_union_nested_t) unionfield_thing() *C.union3_t {
|
||||
return (*C.union3_t)(unsafe.Pointer(&union.$union))
|
||||
}
|
||||
|
||||
type _Cgo_union_nested_t = _Cgo_union_union_nested_t
|
||||
type _Cgo_enum_option = _Cgo_int
|
||||
type _Cgo_option_t = _Cgo_enum_option
|
||||
type _Cgo_enum_option2_t = _Cgo_uint
|
||||
type _Cgo_option2_t = _Cgo_enum_option2_t
|
||||
type _Cgo_struct_types_t struct {
|
||||
type C.union_nested_t = C.union_union_nested_t
|
||||
type C.enum_option = C.int
|
||||
type C.option_t = C.enum_option
|
||||
type C.enum_option2_t = C.uint
|
||||
type C.option2_t = C.enum_option2_t
|
||||
type C.struct_types_t struct {
|
||||
f float32
|
||||
d float64
|
||||
ptr *_Cgo_int
|
||||
ptr *C.int
|
||||
}
|
||||
type _Cgo_types_t = _Cgo_struct_types_t
|
||||
type _Cgo_myIntArray = [10]_Cgo_int
|
||||
type _Cgo_struct_bitfield_t struct {
|
||||
start _Cgo_uchar
|
||||
__bitfield_1 _Cgo_uchar
|
||||
type C.types_t = C.struct_types_t
|
||||
type C.myIntArray = [10]C.int
|
||||
type C.struct_bitfield_t struct {
|
||||
start C.uchar
|
||||
__bitfield_1 C.uchar
|
||||
|
||||
d _Cgo_uchar
|
||||
e _Cgo_uchar
|
||||
d C.uchar
|
||||
e C.uchar
|
||||
}
|
||||
|
||||
func (s *_Cgo_struct_bitfield_t) bitfield_a() _Cgo_uchar { return s.__bitfield_1 & 0x1f }
|
||||
func (s *_Cgo_struct_bitfield_t) set_bitfield_a(value _Cgo_uchar) {
|
||||
func (s *C.struct_bitfield_t) bitfield_a() C.uchar { return s.__bitfield_1 & 0x1f }
|
||||
func (s *C.struct_bitfield_t) set_bitfield_a(value C.uchar) {
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
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 }
|
||||
|
||||
type _Cgo_bitfield_t = _Cgo_struct_bitfield_t
|
||||
type C.bitfield_t = C.struct_bitfield_t
|
||||
|
||||
+65
-118
@@ -8,24 +8,12 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/shlex"
|
||||
"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.
|
||||
type Config struct {
|
||||
Options *Options
|
||||
@@ -111,11 +99,6 @@ func (c *Config) BuildTags() []string {
|
||||
"math_big_pure_go", // to get math/big to work
|
||||
"gc." + c.GC(), "scheduler." + c.Scheduler(), // used inside the runtime package
|
||||
"serial." + c.Serial()}...) // used inside the machine package
|
||||
switch c.Scheduler() {
|
||||
case "threads", "cores":
|
||||
default:
|
||||
tags = append(tags, "tinygo.unicore")
|
||||
}
|
||||
for i := 1; i <= c.GoMinorVersion; i++ {
|
||||
tags = append(tags, fmt.Sprintf("go1.%d", i))
|
||||
}
|
||||
@@ -139,7 +122,7 @@ func (c *Config) GC() string {
|
||||
// that can be traced by the garbage collector.
|
||||
func (c *Config) NeedsStackObjects() bool {
|
||||
switch c.GC() {
|
||||
case "conservative", "custom", "precise", "boehm":
|
||||
case "conservative", "custom", "precise":
|
||||
for _, tag := range c.BuildTags() {
|
||||
if tag == "tinygo.wasm" {
|
||||
return true
|
||||
@@ -264,18 +247,10 @@ func MuslArchitecture(triple string) string {
|
||||
return CanonicalArchName(triple)
|
||||
}
|
||||
|
||||
// Returns true if the libc needs to include malloc, for the libcs where this
|
||||
// matters.
|
||||
func (c *Config) LibcNeedsMalloc() bool {
|
||||
if c.GC() == "boehm" && c.Target.Libc == "wasi-libc" {
|
||||
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 {
|
||||
// LibcPath returns the path to the libc directory. The libc path will be either
|
||||
// a precompiled libc shipped with a TinyGo build, or a libc path in the cache
|
||||
// directory (which might not yet be built).
|
||||
func (c *Config) LibcPath(name string) (path string, precompiled bool) {
|
||||
archname := c.Triple()
|
||||
if c.CPU() != "" {
|
||||
archname += "-" + c.CPU()
|
||||
@@ -286,24 +261,18 @@ func (c *Config) LibraryPath(name string) string {
|
||||
if c.Target.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.
|
||||
if v, ok := libVersions[name]; ok {
|
||||
archname += "-v" + strconv.Itoa(v)
|
||||
}
|
||||
|
||||
options := ""
|
||||
if c.LibcNeedsMalloc() {
|
||||
options += "+malloc"
|
||||
// Try to load a precompiled library.
|
||||
precompiledDir := filepath.Join(goenv.Get("TINYGOROOT"), "pkg", archname, name)
|
||||
if _, err := os.Stat(precompiledDir); err == nil {
|
||||
// Found a precompiled library for this OS/architecture. Return the path
|
||||
// directly.
|
||||
return precompiledDir, true
|
||||
}
|
||||
|
||||
// No precompiled library found. Determine the path name that will be used
|
||||
// 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
|
||||
@@ -346,7 +315,59 @@ func (c *Config) CFlags(libclang bool) []string {
|
||||
"-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.
|
||||
cflags = append(cflags, "-gdwarf-4")
|
||||
// Use the same optimization level as TinyGo.
|
||||
@@ -373,80 +394,6 @@ func (c *Config) CFlags(libclang bool) []string {
|
||||
return cflags
|
||||
}
|
||||
|
||||
// LibcCFlags returns the C compiler flags for the configured libc.
|
||||
// It only uses flags that are part of the libc path (triple, cpu, abi, libc
|
||||
// name) so it can safely be used to compile another C library.
|
||||
func (c *Config) LibcCFlags() []string {
|
||||
switch c.Target.Libc {
|
||||
case "darwin-libSystem":
|
||||
root := goenv.Get("TINYGOROOT")
|
||||
return []string{
|
||||
"-nostdlibinc",
|
||||
"-isystem", filepath.Join(root, "lib/macos-minimal-sdk/src/usr/include"),
|
||||
}
|
||||
case "picolibc":
|
||||
root := goenv.Get("TINYGOROOT")
|
||||
picolibcDir := filepath.Join(root, "lib", "picolibc", "newlib", "libc")
|
||||
path := c.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
|
||||
// (like the one for the compiler runtime), but this represents the majority of
|
||||
// the flags.
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
var (
|
||||
validBuildModeOptions = []string{"default", "c-shared", "wasi-legacy"}
|
||||
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise", "boehm"}
|
||||
validSchedulerOptions = []string{"none", "tasks", "asyncify", "threads", "cores"}
|
||||
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
|
||||
validSchedulerOptions = []string{"none", "tasks", "asyncify"}
|
||||
validSerialOptions = []string{"none", "uart", "usb", "rtt"}
|
||||
validPrintSizeOptions = []string{"none", "short", "full", "html"}
|
||||
validPanicStrategyOptions = []string{"print", "trap"}
|
||||
@@ -43,7 +43,6 @@ type Options struct {
|
||||
PrintCommands func(cmd string, args ...string) `json:"-"`
|
||||
Semaphore chan struct{} `json:"-"` // -p flag controls cap
|
||||
Debug bool
|
||||
Nobounds bool
|
||||
PrintSizes string
|
||||
PrintAllocs *regexp.Regexp // regexp string
|
||||
PrintStacks bool
|
||||
@@ -53,6 +52,7 @@ type Options struct {
|
||||
Programmer string
|
||||
OpenOCDCommands []string
|
||||
LLVMFeatures string
|
||||
PrintJSON bool
|
||||
Monitor bool
|
||||
BaudRate int
|
||||
Timeout time.Duration
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
func TestVerifyOptions(t *testing.T) {
|
||||
|
||||
expectedGCError := errors.New(`invalid gc option 'incorrect': valid values are none, leaking, conservative, custom, precise, boehm`)
|
||||
expectedSchedulerError := errors.New(`invalid scheduler option 'incorrect': valid values are none, tasks, asyncify, threads, cores`)
|
||||
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`)
|
||||
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`)
|
||||
|
||||
|
||||
+36
-46
@@ -178,21 +178,6 @@ func (spec *TargetSpec) resolveInherits() error {
|
||||
|
||||
// Load a target specification.
|
||||
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 == "" {
|
||||
return defaultTarget(options)
|
||||
}
|
||||
@@ -262,6 +247,8 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
GOOS: options.GOOS,
|
||||
GOARCH: options.GOARCH,
|
||||
BuildTags: []string{options.GOOS, options.GOARCH},
|
||||
GC: "precise",
|
||||
Scheduler: "tasks",
|
||||
Linker: "cc",
|
||||
DefaultStackSize: 1024 * 64, // 64kB
|
||||
GDB: []string{"gdb"},
|
||||
@@ -369,7 +356,17 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS)
|
||||
}
|
||||
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:
|
||||
return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH)
|
||||
}
|
||||
@@ -379,13 +376,11 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
llvmvendor := "unknown"
|
||||
switch options.GOOS {
|
||||
case "darwin":
|
||||
spec.GC = "boehm"
|
||||
platformVersion := "10.12.0"
|
||||
if options.GOARCH == "arm64" {
|
||||
platformVersion = "11.0.0" // first macosx platform with arm64 support
|
||||
}
|
||||
llvmvendor = "apple"
|
||||
spec.Scheduler = "threads"
|
||||
spec.Linker = "ld.lld"
|
||||
spec.Libc = "darwin-libSystem"
|
||||
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
|
||||
@@ -399,13 +394,10 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
)
|
||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||
"src/internal/futex/futex_darwin.c",
|
||||
"src/internal/task/task_threads.c",
|
||||
"src/runtime/os_darwin.c",
|
||||
"src/runtime/runtime_unix.c",
|
||||
"src/runtime/signal.c")
|
||||
case "linux":
|
||||
spec.GC = "boehm"
|
||||
spec.Scheduler = "threads"
|
||||
spec.Linker = "ld.lld"
|
||||
spec.RTLib = "compiler-rt"
|
||||
spec.Libc = "musl"
|
||||
@@ -426,30 +418,19 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
}
|
||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||
"src/internal/futex/futex_linux.c",
|
||||
"src/internal/task/task_threads.c",
|
||||
"src/runtime/runtime_unix.c",
|
||||
"src/runtime/signal.c")
|
||||
case "windows":
|
||||
spec.GC = "boehm"
|
||||
spec.Scheduler = "tasks"
|
||||
spec.Linker = "ld.lld"
|
||||
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 {
|
||||
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":
|
||||
// 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,
|
||||
"-m", "i386pep",
|
||||
"--image-base", "0x400000",
|
||||
@@ -465,18 +446,27 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
"--no-insert-timestamp",
|
||||
"--no-dynamicbase",
|
||||
)
|
||||
case "wasm", "wasip1", "wasip2":
|
||||
return nil, fmt.Errorf("GOOS=%s but GOARCH is unset. Please set GOARCH to wasm", options.GOOS)
|
||||
case "wasip1":
|
||||
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:
|
||||
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
|
||||
// triples for historical reasons) have the form:
|
||||
// arch-vendor-os-environment
|
||||
|
||||
+5
-6
@@ -18,12 +18,11 @@ var stdlibAliases = map[string]string{
|
||||
// crypto packages
|
||||
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
|
||||
"crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
|
||||
"crypto/md5.block": "crypto/md5.blockGeneric",
|
||||
"crypto/sha1.block": "crypto/sha1.blockGeneric",
|
||||
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
|
||||
"crypto/sha256.block": "crypto/sha256.blockGeneric",
|
||||
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
|
||||
"internal/chacha8rand.block": "internal/chacha8rand.block_generic",
|
||||
"crypto/md5.block": "crypto/md5.blockGeneric",
|
||||
"crypto/sha1.block": "crypto/sha1.blockGeneric",
|
||||
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
|
||||
"crypto/sha256.block": "crypto/sha256.blockGeneric",
|
||||
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
|
||||
|
||||
// AES
|
||||
"crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock",
|
||||
|
||||
+1
-9
@@ -76,15 +76,7 @@ func (b *builder) createCall(fnType llvm.Type, fn llvm.Value, args []llvm.Value,
|
||||
fragments := b.expandFormalParam(arg)
|
||||
expanded = append(expanded, fragments...)
|
||||
}
|
||||
call := 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
|
||||
return b.CreateCall(fnType, fn, expanded, name)
|
||||
}
|
||||
|
||||
// createInvoke is like createCall but continues execution at the landing pad if
|
||||
|
||||
+10
-39
@@ -58,7 +58,6 @@ type Config struct {
|
||||
MaxStackAlloc uint64
|
||||
NeedsStackObjects bool
|
||||
Debug bool // Whether to emit debug information in the LLVM module.
|
||||
Nobounds bool // Whether to skip bounds checks
|
||||
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
|
||||
// getLLVMType instead.
|
||||
func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
|
||||
switch typ := types.Unalias(goType).(type) {
|
||||
switch typ := goType.(type) {
|
||||
case *types.Array:
|
||||
elemType := c.getLLVMType(typ.Elem())
|
||||
return llvm.ArrayType(elemType, int(typ.Len()))
|
||||
@@ -497,21 +496,6 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
|
||||
llvmType := c.getLLVMType(typ)
|
||||
sizeInBytes := c.targetData.TypeAllocSize(llvmType)
|
||||
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:
|
||||
return c.dibuilder.CreateArrayType(llvm.DIArrayType{
|
||||
SizeInBits: sizeInBytes * 8,
|
||||
@@ -874,11 +858,6 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package
|
||||
// Interfaces don't have concrete methods.
|
||||
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.
|
||||
// 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.
|
||||
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 {
|
||||
// Direct function call, either to a named or anonymous (directly
|
||||
// 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
|
||||
case name == "runtime/interrupt.New":
|
||||
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":
|
||||
retval := b.createDarwinFuncPCABI0Call(instr)
|
||||
if !retval.IsNil() {
|
||||
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)
|
||||
info := b.getFunctionInfo(fn)
|
||||
if callee.IsNil() {
|
||||
|
||||
+6
-15
@@ -103,11 +103,10 @@ func (b *builder) createLandingPad() {
|
||||
b.CreateBr(b.blockEntries[b.fn.Recover])
|
||||
}
|
||||
|
||||
// Create a checkpoint (similar to setjmp). This emits inline assembly that
|
||||
// stores the current program counter inside the ptr address (actually
|
||||
// ptr+sizeof(ptr)) and then returns a boolean indicating whether this is the
|
||||
// normal flow (false) or we jumped here from somewhere else (true).
|
||||
func (b *builder) createCheckpoint(ptr llvm.Value) llvm.Value {
|
||||
// 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() {
|
||||
// Construct inline assembly equivalents of setjmp.
|
||||
// The assembly works as follows:
|
||||
// * 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().
|
||||
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)
|
||||
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))
|
||||
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("")
|
||||
b.CreateCondBr(isZero, continueBB, b.landingpad)
|
||||
b.SetInsertPointAtEnd(continueBB)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
// first field in the struct).
|
||||
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)
|
||||
hasMethodSet := ms.Len() != 0
|
||||
_, isInterface := typ.Underlying().(*types.Interface)
|
||||
@@ -515,7 +512,7 @@ var basicTypeNames = [...]string{
|
||||
// interface lowering pass to assign type codes as expected by the reflect
|
||||
// package. See getTypeCodeNum.
|
||||
func getTypeCodeName(t types.Type) (string, bool) {
|
||||
switch t := types.Unalias(t).(type) {
|
||||
switch t := t.(type) {
|
||||
case *types.Named:
|
||||
if t.Obj().Parent() != t.Obj().Pkg().Scope() {
|
||||
return "named:" + t.String() + "$local", true
|
||||
@@ -945,7 +942,7 @@ func signature(sig *types.Signature) string {
|
||||
// normalization around `byte` vs `uint8` for example.
|
||||
func typestring(t types.Type) string {
|
||||
// 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:
|
||||
return "[" + strconv.FormatInt(t.Len(), 10) + "]" + typestring(t.Elem())
|
||||
case *types.Basic:
|
||||
|
||||
@@ -121,29 +121,6 @@ func (b *builder) createKeepAliveImpl() {
|
||||
b.CreateRetVoid()
|
||||
}
|
||||
|
||||
// createAbiEscapeImpl implements the generic internal/abi.Escape function. It
|
||||
// currently only supports pointer types.
|
||||
func (b *builder) createAbiEscapeImpl() {
|
||||
b.createFunctionStart(true)
|
||||
|
||||
// The first parameter is assumed to be a pointer. This is checked at the
|
||||
// call site of createAbiEscapeImpl.
|
||||
pointerValue := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
|
||||
// Create an equivalent of the following C code, which is basically just a
|
||||
// nop but ensures the pointerValue is kept alive:
|
||||
//
|
||||
// __asm__ __volatile__("" : : "r"(pointerValue))
|
||||
//
|
||||
// It should be portable to basically everything as the "r" register type
|
||||
// exists basically everywhere.
|
||||
asmType := llvm.FunctionType(b.dataPtrType, []llvm.Type{b.dataPtrType}, false)
|
||||
asmFn := llvm.InlineAsm(asmType, "", "=r,0", true, false, 0, false)
|
||||
result := b.createCall(asmType, asmFn, []llvm.Value{pointerValue}, "")
|
||||
|
||||
b.CreateRet(result)
|
||||
}
|
||||
|
||||
var mathToLLVMMapping = map[string]string{
|
||||
"math.Ceil": "llvm.ceil.f64",
|
||||
"math.Exp": "llvm.exp.f64",
|
||||
|
||||
+7
-15
@@ -371,6 +371,13 @@ func (c *compilerContext) getPointerBitmap(typ llvm.Type, pos token.Pos) *big.In
|
||||
return big.NewInt(1)
|
||||
case llvm.StructTypeKind:
|
||||
ptrs := big.NewInt(0)
|
||||
if typ.StructName() == "runtime.funcValue" {
|
||||
// Hack: the type runtime.funcValue contains an 'id' field which is
|
||||
// of type uintptr, but before the LowerFuncValues pass it actually
|
||||
// contains a pointer (ptrtoint) to a global. This trips up the
|
||||
// interp package. Therefore, make the id field a pointer for now.
|
||||
typ = c.ctx.StructType([]llvm.Type{c.dataPtrType, c.dataPtrType}, false)
|
||||
}
|
||||
for i, subtyp := range typ.StructElementTypes() {
|
||||
subptrs := c.getPointerBitmap(subtyp, pos)
|
||||
if subptrs.BitLen() == 0 {
|
||||
@@ -452,21 +459,6 @@ func (b *builder) readStackPointer() llvm.Value {
|
||||
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
|
||||
// extending or truncating the integer.
|
||||
func (b *builder) createZExtOrTrunc(value llvm.Value, t llvm.Type) llvm.Value {
|
||||
|
||||
+3
-1
@@ -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
|
||||
// and can alter two "equal" structs being equal when compared with memequal.
|
||||
func hashmapIsBinaryKey(keyType types.Type) bool {
|
||||
switch keyType := keyType.Underlying().(type) {
|
||||
switch keyType := keyType.(type) {
|
||||
case *types.Basic:
|
||||
return keyType.Info()&(types.IsBoolean|types.IsInteger) != 0
|
||||
case *types.Pointer:
|
||||
@@ -263,6 +263,8 @@ func hashmapIsBinaryKey(keyType types.Type) bool {
|
||||
return true
|
||||
case *types.Array:
|
||||
return hashmapIsBinaryKey(keyType.Elem())
|
||||
case *types.Named:
|
||||
return hashmapIsBinaryKey(keyType.Underlying())
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
+4
-30
@@ -208,12 +208,6 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
// > circumstances, and should not be exposed to source languages.
|
||||
llvmutil.AppendToGlobal(c.mod, "llvm.compiler.used", llvmFn)
|
||||
}
|
||||
case "GetModuleHandleExA", "GetProcAddress", "GetSystemInfo", "GetSystemTimeAsFileTime", "LoadLibraryExW", "QueryPerformanceCounter", "QueryPerformanceFrequency", "QueryUnbiasedInterruptTime", "SetEnvironmentVariableA", "Sleep", "SystemFunction036", "VirtualAlloc":
|
||||
// On Windows we need to use a special calling convention for some
|
||||
// external calls.
|
||||
if c.GOOS == "windows" && c.GOARCH == "386" {
|
||||
llvmFn.SetFunctionCallConv(llvm.X86StdcallCallConv)
|
||||
}
|
||||
}
|
||||
|
||||
// External/exported functions may not retain pointer values.
|
||||
@@ -253,23 +247,6 @@ func (c *compilerContext) maybeCreateSyntheticFunction(fn *ssa.Function, llvmFn
|
||||
// The exception is the package initializer, which does appear in the
|
||||
// *ssa.Package members and so shouldn't be created here.
|
||||
if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" {
|
||||
if origin := fn.Origin(); origin != nil && origin.RelString(nil) == "internal/abi.Escape" {
|
||||
// This is a special implementation or internal/abi.Escape, which
|
||||
// can only really be implemented in the compiler.
|
||||
// For simplicity we'll only implement pointer parameters for now.
|
||||
if _, ok := fn.Params[0].Type().Underlying().(*types.Pointer); ok {
|
||||
irbuilder := c.ctx.NewBuilder()
|
||||
defer irbuilder.Dispose()
|
||||
b := newBuilder(c, irbuilder, fn)
|
||||
b.createAbiEscapeImpl()
|
||||
llvmFn.SetLinkage(llvm.LinkOnceODRLinkage)
|
||||
llvmFn.SetUnnamedAddr(true)
|
||||
}
|
||||
// If the parameter is not of a pointer type, it will be left
|
||||
// unimplemented. This will result in a linker error if the function
|
||||
// is really called, making it clear it needs to be implemented.
|
||||
return
|
||||
}
|
||||
if len(fn.Blocks) == 0 {
|
||||
c.addError(fn.Pos(), "missing function body")
|
||||
return
|
||||
@@ -455,16 +432,13 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
|
||||
// pass for C variadic functions. This includes both explicit
|
||||
// (with ...) and implicit (no parameters in signature)
|
||||
// functions.
|
||||
if strings.HasPrefix(f.Name(), "_Cgo_") {
|
||||
// This prefix was created as a result of CGo preprocessing.
|
||||
if strings.HasPrefix(f.Name(), "C.") {
|
||||
// This prefix cannot naturally be created, it must have
|
||||
// been created as a result of CGo preprocessing.
|
||||
info.variadic = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c.Nobounds {
|
||||
info.nobounds = true
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether this function can be used in //go:wasmimport or
|
||||
@@ -473,7 +447,7 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
|
||||
// The list of allowed types is based on this proposal:
|
||||
// https://github.com/golang/go/issues/59149
|
||||
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
|
||||
// (importantly, including pointers).
|
||||
return
|
||||
|
||||
+1
-24
@@ -268,8 +268,6 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
||||
// The signature looks like this:
|
||||
// func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
isI386 := strings.HasPrefix(b.Triple, "i386-")
|
||||
|
||||
// Prepare input values.
|
||||
var paramTypes []llvm.Type
|
||||
var params []llvm.Value
|
||||
@@ -287,17 +285,11 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
||||
if setLastError.IsNil() {
|
||||
llvmType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.ctx.Int32Type()}, false)
|
||||
setLastError = llvm.AddFunction(b.mod, "SetLastError", llvmType)
|
||||
if isI386 {
|
||||
setLastError.SetFunctionCallConv(llvm.X86StdcallCallConv)
|
||||
}
|
||||
}
|
||||
getLastError := b.mod.NamedFunction("GetLastError")
|
||||
if getLastError.IsNil() {
|
||||
llvmType := llvm.FunctionType(b.ctx.Int32Type(), nil, false)
|
||||
getLastError = llvm.AddFunction(b.mod, "GetLastError", llvmType)
|
||||
if isI386 {
|
||||
getLastError.SetFunctionCallConv(llvm.X86StdcallCallConv)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// access to the thread control block, which is probably smaller and
|
||||
// faster. The Go runtime does this in assembly.
|
||||
// On windows/386, we also need to save/restore the stack pointer. I'm
|
||||
// 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()
|
||||
}
|
||||
b.CreateCall(setLastError.GlobalValueType(), setLastError, []llvm.Value{llvm.ConstNull(b.ctx.Int32Type())}, "")
|
||||
syscallResult := b.CreateCall(llvmType, fnPtr, params, "")
|
||||
if isI386 {
|
||||
syscallResult.SetInstructionCallConv(llvm.X86StdcallCallConv)
|
||||
b.writeStackPointer(sp)
|
||||
}
|
||||
errResult := b.CreateCall(getLastError.GlobalValueType(), getLastError, nil, "err")
|
||||
if isI386 {
|
||||
errResult.SetInstructionCallConv(llvm.X86StdcallCallConv)
|
||||
}
|
||||
if b.uintptrType != b.ctx.Int32Type() {
|
||||
errResult = b.CreateZExt(errResult, b.uintptrType, "err.uintptr")
|
||||
}
|
||||
|
||||
+20
-40
@@ -10,7 +10,6 @@ import (
|
||||
"go/types"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -24,11 +23,6 @@ import (
|
||||
type Diagnostic struct {
|
||||
Pos token.Position
|
||||
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.
|
||||
@@ -120,22 +114,12 @@ func createPackageDiagnostic(err error) PackageDiagnostic {
|
||||
func createDiagnostics(err error) []Diagnostic {
|
||||
switch err := err.(type) {
|
||||
case types.Error:
|
||||
diag := Diagnostic{
|
||||
Pos: err.Fset.Position(err.Pos),
|
||||
Msg: err.Msg,
|
||||
return []Diagnostic{
|
||||
{
|
||||
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:
|
||||
return []Diagnostic{
|
||||
{
|
||||
@@ -204,29 +188,25 @@ func (diag Diagnostic) WriteTo(w io.Writer, wd string) {
|
||||
fmt.Fprintln(w, diag.Msg)
|
||||
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)
|
||||
}
|
||||
|
||||
// Convert the position in pos (assumed to have an absolute path) into a
|
||||
// relative path if possible. Paths inside GOROOT/TINYGOROOT will remain
|
||||
// absolute.
|
||||
func RelativePosition(pos token.Position, wd string) token.Position {
|
||||
// Check whether we even have a working directory.
|
||||
// try to make the path relative to the current working directory. If any error
|
||||
// occurs, this error is ignored and the absolute path is returned instead.
|
||||
func tryToMakePathRelative(dir, wd string) string {
|
||||
if wd == "" {
|
||||
return pos
|
||||
return dir // working directory not found
|
||||
}
|
||||
|
||||
// Paths inside GOROOT should be printed in full.
|
||||
if strings.HasPrefix(pos.Filename, filepath.Join(goenv.Get("GOROOT"), "src")) || strings.HasPrefix(pos.Filename, filepath.Join(goenv.Get("TINYGOROOT"), "src")) {
|
||||
return pos
|
||||
relpath, err := filepath.Rel(wd, dir)
|
||||
if err != nil {
|
||||
return dir
|
||||
}
|
||||
|
||||
// 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
|
||||
return relpath
|
||||
}
|
||||
|
||||
+1
-6
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/tinygo-org/tinygo/builder"
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"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).
|
||||
tmpdir := t.TempDir()
|
||||
config, err := builder.NewConfig(options)
|
||||
if err != nil {
|
||||
t.Fatal("expected to get a compiler error")
|
||||
}
|
||||
err = Build(filename, tmpdir+"/out", config)
|
||||
err := Build(filename, tmpdir+"/out", options)
|
||||
if err == nil {
|
||||
t.Fatal("expected to get a compiler error")
|
||||
}
|
||||
|
||||
Generated
+4
-4
@@ -20,16 +20,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1747953325,
|
||||
"narHash": "sha256-y2ZtlIlNTuVJUZCqzZAhIw5rrKP4DOSklev6c8PyCkQ=",
|
||||
"lastModified": 1728500571,
|
||||
"narHash": "sha256-dOymOQ3AfNI4Z337yEwHGohrVQb4yPODCW9MDUyAc4w=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "55d1f923c480dadce40f5231feb472e81b0bab48",
|
||||
"rev": "d51c28603def282a24fa034bcb007e2bcb5b5dd0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-25.05",
|
||||
"ref": "nixos-24.05",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
# make llvm-source # fetch compiler-rt
|
||||
# git submodule update --init # fetch lots of other libraries and SVD 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
|
||||
# for the Xtensa architecture (ESP8266/ESP32) because support for that lives in
|
||||
@@ -34,7 +35,7 @@
|
||||
inputs = {
|
||||
# Use a recent stable release, but fix the version to make it reproducible.
|
||||
# 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";
|
||||
};
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
@@ -48,11 +49,11 @@
|
||||
buildInputs = [
|
||||
# These dependencies are required for building tinygo (go install).
|
||||
go
|
||||
llvmPackages_20.llvm
|
||||
llvmPackages_20.libclang
|
||||
llvmPackages_18.llvm
|
||||
llvmPackages_18.libclang
|
||||
# Additional dependencies needed at runtime, for building and/or
|
||||
# flashing.
|
||||
llvmPackages_20.lld
|
||||
llvmPackages_18.lld
|
||||
avrdude
|
||||
binaryen
|
||||
# Additional dependencies needed for on-chip debugging.
|
||||
@@ -63,12 +64,20 @@
|
||||
#openocd
|
||||
];
|
||||
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
|
||||
# has `md5sum`).
|
||||
export MD5SUM=md5sum
|
||||
|
||||
# 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"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
module github.com/tinygo-org/tinygo
|
||||
|
||||
go 1.22.0
|
||||
go 1.19
|
||||
|
||||
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/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee
|
||||
github.com/chromedp/chromedp v0.7.6
|
||||
@@ -16,11 +16,11 @@ require (
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
|
||||
github.com/tetratelabs/wazero v1.6.0
|
||||
go.bug.st/serial v1.6.0
|
||||
golang.org/x/net v0.35.0
|
||||
golang.org/x/sys v0.30.0
|
||||
golang.org/x/tools v0.30.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/sys v0.21.0
|
||||
golang.org/x/tools v0.22.1-0.20240621165957-db513b091504
|
||||
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 (
|
||||
@@ -33,5 +33,5 @@ require (
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139 h1:2O/WuAt8J5id3khcAtVB90czG80m+v0sfkLE07GrCVg=
|
||||
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 h1:cD7QfvrJdYmBw2tFP/VyKPT8ZESlcrwSwo7SvH9Y4dc=
|
||||
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/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
@@ -12,7 +12,6 @@ github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moA
|
||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
@@ -45,7 +44,6 @@ github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3px
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
@@ -54,12 +52,10 @@ github.com/tetratelabs/wazero v1.6.0 h1:z0H1iikCdP8t+q341xqepY4EWvHEw8Es7tlqiVzl
|
||||
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/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
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/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -67,17 +63,16 @@ golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.22.1-0.20240621165957-db513b091504 h1:MMsD8mMfluf/578+3wrTn22pjI/Xkzm+gPW47SYfspY=
|
||||
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74 h1:ovavgTdIBWCH8YWlcfq9gkpoyT1+IxMKSn+Df27QwE8=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250119132755-9dca92dfb4f9 h1:rMvEzuCYjyiR+pmdiCVWTQw3L6VqiSIXoL19I3lYufE=
|
||||
tinygo.org/x/go-llvm v0.0.0-20250119132755-9dca92dfb4f9/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// Version of TinyGo.
|
||||
// Update this value before release of new version of software.
|
||||
const version = "0.39.0"
|
||||
const version = "0.36.0-dev"
|
||||
|
||||
// Return TinyGo version, either in the form 0.30.0 or as a development version
|
||||
// (like 0.30.0-dev-abcd012).
|
||||
|
||||
@@ -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 (
|
||||
go.bytecodealliance.org v0.6.2
|
||||
go.bytecodealliance.org/cm v0.2.2
|
||||
)
|
||||
require github.com/bytecodealliance/wasm-tools-go v0.3.1
|
||||
|
||||
require (
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // 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/tetratelabs/wazero v1.9.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||
github.com/urfave/cli/v3 v3.0.0-beta1 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.2 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
)
|
||||
|
||||
+18
-22
@@ -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/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
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/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/olareg/olareg v0.1.1 h1:Ui7q93zjcoF+U9U71sgqgZWByDoZOpqHitUXEu2xV+g=
|
||||
github.com/olareg/olareg v0.1.1/go.mod h1:w8NP4SWrHHtxsFaUiv1lnCnYPm4sN1seCd2h7FK/dc0=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/olareg/olareg v0.1.0 h1:1dXBOgPrig5N7zoXyIZVQqU0QBo6sD9pbL6UYjY75CA=
|
||||
github.com/olareg/olareg v0.1.0/go.mod h1:RBuU7JW7SoIIxZKzLRhq8sVtQeAHzCAtRrXEBx2KlM4=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/regclient/regclient v0.8.2 h1:23BQ3jWgKYHHIXUhp/S9laVJDHDoOQaQCzXMJ4undVE=
|
||||
github.com/regclient/regclient v0.8.2/go.mod h1:uGyetv0o6VLyRDjtfeBqp/QBwRLJ3Hcn07/+8QbhNcM=
|
||||
github.com/regclient/regclient v0.7.1 h1:qEsJrTmZd98fZKjueAbrZCSNGU+ifnr6xjlSAs3WOPs=
|
||||
github.com/regclient/regclient v0.7.1/go.mod h1:+w/BFtJuw0h0nzIw/z2+1FuA2/dVXBzDq4rYmziJpMc=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
@@ -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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
|
||||
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
|
||||
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
|
||||
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
|
||||
go.bytecodealliance.org v0.6.2 h1:Jy4u5DVmSkXgsnwojBhJ+AD/YsJsR3VzVnxF0xRCqTQ=
|
||||
go.bytecodealliance.org v0.6.2/go.mod h1:gqjTJm0y9NSksG4py/lSjIQ/SNuIlOQ+hCIEPQwtJgA=
|
||||
go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA=
|
||||
go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.2 h1:CL8llQj3dGRLVQQzHxS+ZYRLanOuhyK1fXgLKD+qV+Y=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.2/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
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.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
_ "go.bytecodealliance.org/cm"
|
||||
_ "go.bytecodealliance.org/cmd/wit-bindgen-go"
|
||||
_ "github.com/bytecodealliance/wasm-tools-go/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
|
||||
|
||||
+1
-14
@@ -364,22 +364,9 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
||||
continue
|
||||
}
|
||||
nBytes := uint32(n * elemSize)
|
||||
srcObj := mem.get(src.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)
|
||||
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():])
|
||||
dstObj.buffer = dstBuf
|
||||
mem.put(dst.index(), dstObj)
|
||||
|
||||
@@ -824,6 +824,19 @@ func (v rawValue) rawLLVMValue(mem *memoryView) (llvm.Value, error) {
|
||||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
if !field.IsAGlobalVariable().IsNil() {
|
||||
elementType := field.GlobalValueType()
|
||||
if elementType.TypeKind() == llvm.StructTypeKind {
|
||||
// There are some special pointer types that should be used
|
||||
// as a ptrtoint, so that they can be used in certain
|
||||
// optimizations.
|
||||
name := elementType.StructName()
|
||||
if name == "runtime.funcValueWithSignature" {
|
||||
uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8)
|
||||
field = llvm.ConstPtrToInt(field, uintptrType)
|
||||
}
|
||||
}
|
||||
}
|
||||
structFields = append(structFields, field)
|
||||
i += mem.r.pointerSize
|
||||
continue
|
||||
|
||||
Vendored
-18
@@ -11,10 +11,6 @@ target triple = "x86_64--linux"
|
||||
@main.sliceDstUntaint.buf = internal global [2 x i8] zeroinitializer
|
||||
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
|
||||
@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
|
||||
|
||||
@@ -62,14 +58,6 @@ entry:
|
||||
%sliceDstTaint.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstTaint.buf, i32 0)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -114,11 +102,5 @@ entry:
|
||||
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)
|
||||
|
||||
; 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
|
||||
}
|
||||
|
||||
Vendored
-10
@@ -3,10 +3,6 @@ target triple = "x86_64--linux"
|
||||
|
||||
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
|
||||
@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
|
||||
|
||||
@@ -20,8 +16,6 @@ define void @runtime.initAll() unnamed_addr {
|
||||
entry:
|
||||
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.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
|
||||
}
|
||||
|
||||
@@ -34,9 +28,5 @@ entry:
|
||||
call void @runtime.printuint8(i8 97)
|
||||
%sliceDstTaint.val = load i8, ptr @main.sliceDstTaint.buf, align 1
|
||||
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
|
||||
}
|
||||
|
||||
-1
Submodule lib/bdwgc deleted from 1166f11f7d
+1
-1
Submodule lib/macos-minimal-sdk updated: e7c72156ea...9b69407cb5
@@ -269,8 +269,6 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
|
||||
|
||||
if needsSyscallPackage {
|
||||
paths["syscall/"] = true // include syscall/js
|
||||
paths["internal/syscall/"] = true
|
||||
paths["internal/syscall/unix/"] = false
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
+1
-3
@@ -8,9 +8,7 @@ import (
|
||||
//
|
||||
// The program must already be parsed and type-checked with the .Parse() method.
|
||||
func (p *Program) LoadSSA() *ssa.Program {
|
||||
// TODO: re-enable SanityCheckFunctions when x/tools is upgraded to
|
||||
// a version with a fix for https://golang.org/issues/73594.
|
||||
prog := ssa.NewProgram(p.fset /*ssa.SanityCheckFunctions|*/, ssa.BareInits|ssa.GlobalDebug|ssa.InstantiateGenerics)
|
||||
prog := ssa.NewProgram(p.fset, ssa.SanityCheckFunctions|ssa.BareInits|ssa.GlobalDebug|ssa.InstantiateGenerics)
|
||||
|
||||
for _, pkg := range p.sorted {
|
||||
prog.CreatePackage(pkg.Pkg, pkg.Files, &pkg.info, true)
|
||||
|
||||
@@ -138,13 +138,27 @@ func printCommand(cmd string, args ...string) {
|
||||
}
|
||||
|
||||
// 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.
|
||||
tmpdir, err := os.MkdirTemp("", "tinygo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !config.Options.Work {
|
||||
if !options.Work {
|
||||
defer os.RemoveAll(tmpdir)
|
||||
}
|
||||
|
||||
@@ -291,8 +305,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
|
||||
})
|
||||
|
||||
if testConfig.CompileOnly {
|
||||
// Return the compiler error, if there is one.
|
||||
return true, err
|
||||
return true, nil
|
||||
}
|
||||
|
||||
importPath := strings.TrimSuffix(result.ImportPath, ".test")
|
||||
@@ -340,17 +353,8 @@ func dirsToModuleRootAbs(maindir, modroot string) []string {
|
||||
return dirs
|
||||
}
|
||||
|
||||
// validateOutputFormat checks if the output file extension matches the expected format
|
||||
func validateOutputFormat(outpath, expectedExt string) error {
|
||||
actualExt := filepath.Ext(outpath)
|
||||
if actualExt != expectedExt {
|
||||
return fmt.Errorf("output format %s does not match target format %s", actualExt, expectedExt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Flash builds and flashes the built binary to the given serial port.
|
||||
func Flash(pkgName, port, outpath string, options *compileopts.Options) error {
|
||||
func Flash(pkgName, port string, options *compileopts.Options) error {
|
||||
config, err := builder.NewConfig(options)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -399,24 +403,13 @@ func Flash(pkgName, port, outpath string, options *compileopts.Options) error {
|
||||
if !options.Work {
|
||||
defer os.RemoveAll(tmpdir)
|
||||
}
|
||||
// Validate output format before building
|
||||
if outpath != "" {
|
||||
if err := validateOutputFormat(outpath, fileExt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Build the binary.
|
||||
result, err := builder.Build(pkgName, fileExt, tmpdir, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save output file if specified (after build, before flashing)
|
||||
if outpath != "" {
|
||||
if err := copyFile(result.Binary, outpath); err != nil {
|
||||
return fmt.Errorf("failed to save output file: %v", err)
|
||||
}
|
||||
}
|
||||
// do we need port reset to put MCU into bootloader mode?
|
||||
if config.Target.PortReset == "true" && flashMethod != "openocd" {
|
||||
port, err := getDefaultPort(port, config.Target.SerialPort)
|
||||
@@ -1034,50 +1027,15 @@ func findFATMounts(options *compileopts.Options) ([]mountPoint, error) {
|
||||
return nil, fmt.Errorf("could not list mount points: %w", err)
|
||||
}
|
||||
for _, elem := range list {
|
||||
volumePath := filepath.Join("/Volumes", elem.Name())
|
||||
if _, err := os.Stat(volumePath); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
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,
|
||||
})
|
||||
}
|
||||
// TODO: find a way to check for the filesystem type.
|
||||
// (Only return FAT filesystems).
|
||||
points = append(points, mountPoint{
|
||||
name: elem.Name(),
|
||||
path: filepath.Join("/Volumes", elem.Name()),
|
||||
})
|
||||
}
|
||||
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
|
||||
case "linux":
|
||||
@@ -1318,11 +1276,6 @@ extension at all.`
|
||||
(https://tinygo.org/docs/reference/microcontrollers/).
|
||||
Examples: "arduino-nano", "d1mini", "xiao".
|
||||
|
||||
-o={filename}:
|
||||
Save the built binary to the specified output file. The file
|
||||
format must match the target's expected format (e.g., .hex,
|
||||
.uf2). Both flashing and saving will be performed.
|
||||
|
||||
-monitor:
|
||||
Start the serial monitor (see below) immediately after
|
||||
flashing. However, some microcontrollers need a split second
|
||||
@@ -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) {
|
||||
if err != nil {
|
||||
wd, getwdErr := os.Getwd()
|
||||
@@ -1601,9 +1492,9 @@ func main() {
|
||||
command := os.Args[1]
|
||||
|
||||
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)")
|
||||
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)")
|
||||
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")
|
||||
@@ -1621,10 +1512,8 @@ func main() {
|
||||
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")
|
||||
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")
|
||||
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)")
|
||||
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)")
|
||||
@@ -1647,13 +1536,16 @@ func main() {
|
||||
// development it can be useful to not emit debug information at all.
|
||||
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" {
|
||||
flag.BoolVar(&flagDeps, "deps", false, "supply -deps flag to go list")
|
||||
flag.BoolVar(&flagTest, "test", false, "supply -test flag to go list")
|
||||
}
|
||||
var outpath string
|
||||
if command == "help" || command == "build" || command == "test" || command == "flash" {
|
||||
if command == "help" || command == "build" || command == "test" {
|
||||
flag.StringVar(&outpath, "o", "", "output filename")
|
||||
}
|
||||
|
||||
@@ -1733,7 +1625,6 @@ func main() {
|
||||
SkipDWARF: *skipDwarf,
|
||||
Semaphore: make(chan struct{}, *parallelism),
|
||||
Debug: !*nodebug,
|
||||
Nobounds: *nobounds,
|
||||
PrintSizes: *printSize,
|
||||
PrintStacks: *printStacks,
|
||||
PrintAllocs: printAllocs,
|
||||
@@ -1743,6 +1634,7 @@ func main() {
|
||||
Programmer: *programmer,
|
||||
OpenOCDCommands: ocdCommands,
|
||||
LLVMFeatures: *llvmFeatures,
|
||||
PrintJSON: flagJSON,
|
||||
Monitor: *monitor,
|
||||
BaudRate: *baudrate,
|
||||
Timeout: *timeout,
|
||||
@@ -1792,20 +1684,17 @@ func main() {
|
||||
usage(command)
|
||||
os.Exit(1)
|
||||
}
|
||||
if filepath.Ext(outpath) == ".wasm" && options.GOARCH != "wasm" && options.Target == "" {
|
||||
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.")
|
||||
os.Exit(1)
|
||||
if options.Target == "" && filepath.Ext(outpath) == ".wasm" {
|
||||
options.Target = "wasm"
|
||||
}
|
||||
|
||||
config, err := builder.NewConfig(options)
|
||||
err := Build(pkgName, outpath, options)
|
||||
handleCompilerError(err)
|
||||
err = Build(pkgName, outpath, config)
|
||||
printBuildOutput(err, *flagJSON)
|
||||
case "flash", "gdb", "lldb":
|
||||
pkgName := filepath.ToSlash(flag.Arg(0))
|
||||
if command == "flash" {
|
||||
err := Flash(pkgName, *port, outpath, options)
|
||||
printBuildOutput(err, *flagJSON)
|
||||
err := Flash(pkgName, *port, options)
|
||||
handleCompilerError(err)
|
||||
} else {
|
||||
if !options.Debug {
|
||||
fmt.Fprintln(os.Stderr, "Debug disabled while running debugger?")
|
||||
@@ -1813,7 +1702,7 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
err := Debug(command, pkgName, *ocdOutput, options)
|
||||
printBuildOutput(err, *flagJSON)
|
||||
handleCompilerError(err)
|
||||
}
|
||||
case "run":
|
||||
if flag.NArg() < 1 {
|
||||
@@ -1823,7 +1712,7 @@ func main() {
|
||||
}
|
||||
pkgName := filepath.ToSlash(flag.Arg(0))
|
||||
err := Run(pkgName, options, flag.Args()[1:])
|
||||
printBuildOutput(err, *flagJSON)
|
||||
handleCompilerError(err)
|
||||
case "test":
|
||||
var pkgNames []string
|
||||
for i := 0; i < flag.NArg(); i++ {
|
||||
@@ -1890,7 +1779,6 @@ func main() {
|
||||
wd = ""
|
||||
}
|
||||
diagnostics.CreateDiagnostics(err).WriteTo(os.Stderr, wd)
|
||||
os.Exit(1)
|
||||
}
|
||||
if !passed {
|
||||
select {
|
||||
@@ -1952,13 +1840,16 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if *flagJSON {
|
||||
if flagJSON {
|
||||
json, _ := json.MarshalIndent(struct {
|
||||
Target *compileopts.TargetSpec `json:"target"`
|
||||
GOROOT string `json:"goroot"`
|
||||
@@ -2000,7 +1891,7 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
var extraArgs []string
|
||||
if *flagJSON {
|
||||
if flagJSON {
|
||||
extraArgs = append(extraArgs, "-json")
|
||||
}
|
||||
if flagDeps {
|
||||
|
||||
+24
-60
@@ -35,8 +35,6 @@ const TESTDATA = "testdata"
|
||||
|
||||
var testTarget = flag.String("target", "", "override test target")
|
||||
|
||||
var testOnlyCurrentOS = flag.Bool("only-current-os", false, "")
|
||||
|
||||
var supportedLinuxArches = map[string]string{
|
||||
"AMD64Linux": "linux/amd64",
|
||||
"X86Linux": "linux/386",
|
||||
@@ -160,51 +158,20 @@ func TestBuild(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
if !*testOnlyCurrentOS {
|
||||
t.Run("EmulatedCortexM3", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromTarget("cortex-m-qemu", sema), tests, t)
|
||||
})
|
||||
t.Run("EmulatedCortexM3", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromTarget("cortex-m-qemu", sema), tests, t)
|
||||
})
|
||||
|
||||
t.Run("EmulatedRISCV", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromTarget("riscv-qemu", sema), tests, t)
|
||||
})
|
||||
t.Run("EmulatedRISCV", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromTarget("riscv-qemu", sema), tests, t)
|
||||
})
|
||||
|
||||
t.Run("AVR", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
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)
|
||||
})
|
||||
}
|
||||
t.Run("AVR", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromTarget("simavr", sema), tests, t)
|
||||
})
|
||||
|
||||
if runtime.GOOS == "linux" {
|
||||
for name, osArch := range supportedLinuxArches {
|
||||
@@ -224,13 +191,18 @@ func TestBuild(t *testing.T) {
|
||||
options := optionsFromOSARCH("linux/mipsle/softfloat", sema)
|
||||
runTest("cgo/", options, t, nil, nil)
|
||||
})
|
||||
} else if runtime.GOOS == "windows" {
|
||||
if runtime.GOARCH != "386" {
|
||||
t.Run("Windows386", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromOSARCH("windows/386", sema), tests, t)
|
||||
})
|
||||
}
|
||||
t.Run("WebAssembly", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromTarget("wasm", 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) {
|
||||
t.Helper()
|
||||
runTestWithConfig(name, t, options, cmdArgs, environmentVars)
|
||||
}
|
||||
|
||||
func runTestWithConfig(name string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) {
|
||||
t.Helper()
|
||||
// Get the expected output for this test.
|
||||
// Note: not using filepath.Join as it strips the path separator at the end
|
||||
// of the path.
|
||||
@@ -705,10 +675,6 @@ func TestWasmExport(t *testing.T) {
|
||||
// again.
|
||||
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})
|
||||
|
||||
// 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.
|
||||
@@ -878,7 +844,6 @@ func TestWasmExit(t *testing.T) {
|
||||
|
||||
// Check whether the output of a test equals the expected output.
|
||||
func checkOutput(t *testing.T, filename string, actual []byte) {
|
||||
t.Helper()
|
||||
expectedOutput, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatal("could not read output file:", err)
|
||||
@@ -887,7 +852,6 @@ func checkOutput(t *testing.T, filename string, actual []byte) {
|
||||
}
|
||||
|
||||
func checkOutputData(t *testing.T, expectedOutput, actual []byte) {
|
||||
t.Helper()
|
||||
expectedOutput = bytes.ReplaceAll(expectedOutput, []byte("\r\n"), []byte("\n"))
|
||||
actual = bytes.ReplaceAll(actual, []byte("\r\n"), []byte("\n"))
|
||||
|
||||
|
||||
@@ -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
|
||||
// src/runtime/rand_hwrng.go.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package rand
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
import "errors"
|
||||
|
||||
func init() {
|
||||
Reader = &reader{}
|
||||
@@ -19,22 +16,28 @@ func (r *reader) Read(b []byte) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Use the old RtlGenRandom, introduced in Windows XP.
|
||||
// Even though the documentation says it is deprecated, it is widely used
|
||||
// and probably won't go away anytime soon.
|
||||
// See for example: https://github.com/golang/go/issues/33542
|
||||
// For Windows 7 and newer, we might switch to ProcessPrng in the future
|
||||
// (which is a documented function and might be a tiny bit faster).
|
||||
ok := libc_RtlGenRandom(unsafe.Pointer(&b[0]), len(b))
|
||||
if !ok {
|
||||
return 0, errRandom
|
||||
var randomByte uint32
|
||||
for i := range b {
|
||||
// Call rand_s every four bytes because it's a C int (always 32-bit in
|
||||
// Windows).
|
||||
if i%4 == 0 {
|
||||
errCode := libc_rand_s(&randomByte)
|
||||
if errCode != 0 {
|
||||
// According to the documentation, it can return an error.
|
||||
return n, errRandom
|
||||
}
|
||||
} else {
|
||||
randomByte >>= 8
|
||||
}
|
||||
b[i] = byte(randomByte)
|
||||
}
|
||||
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// This function is part of advapi32.dll, and is called SystemFunction036 for
|
||||
// some reason. It's available on Windows XP and newer.
|
||||
// See: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
|
||||
// Cryptographically secure random number generator.
|
||||
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170
|
||||
// errno_t rand_s(unsigned int* randomValue);
|
||||
//
|
||||
//export SystemFunction036
|
||||
func libc_RtlGenRandom(buf unsafe.Pointer, len int) bool
|
||||
//export rand_s
|
||||
func libc_rand_s(randomValue *uint32) int32
|
||||
|
||||
@@ -63,10 +63,6 @@ func SecCertificateCopyData(cert CFRef) ([]byte, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustCopyCertificateChain(trustObj CFRef) (CFRef, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
@@ -146,11 +146,6 @@ const (
|
||||
SYST_CALIB_NOREF = 0x80000000 // Bit NOREF.
|
||||
)
|
||||
|
||||
// ClearPendingIRQ clears the pending status of the interrupt.
|
||||
func ClearPendingIRQ(irq uint32) {
|
||||
NVIC.ICPR[irq>>5].Set(1 << (irq & 0x1F))
|
||||
}
|
||||
|
||||
// Enable the given interrupt number.
|
||||
func EnableIRQ(irq uint32) {
|
||||
NVIC.ISER[irq>>5].Set(1 << (irq & 0x1F))
|
||||
|
||||
@@ -275,61 +275,3 @@ const (
|
||||
DPC CSR = 0x7B1 // Debug PC.
|
||||
DSCRATCH CSR = 0x7B2 // Debug scratch register.
|
||||
)
|
||||
|
||||
// Bitfields for the CSR registers above.
|
||||
const (
|
||||
// MSTATUS (common bits between RV32 and RV64)
|
||||
MSTATUS_SIE = 1 << 1
|
||||
MSTATUS_MIE = 1 << 3
|
||||
MSTATUS_SPIE = 1 << 5
|
||||
MSTATUS_UBE = 1 << 6
|
||||
MSTATUS_MPIE = 1 << 7
|
||||
MSTATUS_SPP = 1 << 8
|
||||
MSTATUS_MPRV = 1 << 17
|
||||
MSTATUS_SUM = 1 << 18
|
||||
MSTATUS_MXR = 1 << 19
|
||||
MSTATUS_TVM = 1 << 20
|
||||
MSTATUS_TW = 1 << 21
|
||||
MSTATUS_TSR = 1 << 22
|
||||
|
||||
MIE_SSIE = 1 << 1
|
||||
MIE_MSIE = 1 << 3
|
||||
MIE_STIE = 1 << 5
|
||||
MIE_MTIE = 1 << 7
|
||||
MIE_SEIE = 1 << 9
|
||||
MIE_MEIE = 1 << 11
|
||||
|
||||
MIP_SSIP = 1 << 1
|
||||
MIP_MSIP = 1 << 3
|
||||
MIP_STIP = 1 << 5
|
||||
MIP_MTIP = 1 << 7
|
||||
MIP_SEIP = 1 << 9
|
||||
MIP_MEIP = 1 << 11
|
||||
)
|
||||
|
||||
// Interrupt constants
|
||||
const (
|
||||
// MCAUSE values with the topmost bit (interrupt bit) set.
|
||||
SupervisorSoftwareInterrupt = 1
|
||||
MachineSoftwareInterrupt = 3
|
||||
SupervisorTimerInterrupt = 5
|
||||
MachineTimerInterrupt = 7
|
||||
SupervisorExternalInterrupt = 9
|
||||
MachineExternalInterrupt = 11
|
||||
|
||||
// MCAUSE values with the topmost bit (interrupt bit) clear.
|
||||
InstructionAddressMisaligned = 0
|
||||
InstructionAccessFault = 1
|
||||
IllegalInstruction = 2
|
||||
Breakpoint = 3
|
||||
LoadAddressMisaligned = 4
|
||||
LoadAccessFault = 5
|
||||
StoreOrAMOAddressMisaligned = 6
|
||||
StoreOrAMOAccessFault = 7
|
||||
EnvironmentCallFromUMode = 8
|
||||
EnvironmentCallFromSMode = 9
|
||||
EnvironmentCallFromMMode = 11
|
||||
InstructionPageFault = 12
|
||||
LoadPageFault = 13
|
||||
StoreOrAMOPageFault = 15
|
||||
)
|
||||
|
||||
@@ -3,47 +3,8 @@
|
||||
.type _start,@function
|
||||
|
||||
_start:
|
||||
// If we're on a multicore system, we need to wait for hart 0 to wake us up.
|
||||
#if TINYGO_CORES > 1
|
||||
csrr a0, mhartid
|
||||
|
||||
// Hart 0 stack
|
||||
bnez a0, 1f
|
||||
la sp, _stack_top
|
||||
|
||||
1:
|
||||
// Hart 1 stack
|
||||
li a1, 1
|
||||
bne a0, a1, 2f
|
||||
la sp, _stack1_top
|
||||
|
||||
2:
|
||||
// Hart 2 stack
|
||||
#if TINYGO_CORES >= 3
|
||||
li a1, 2
|
||||
bne a0, a1, 3f
|
||||
la sp, _stack2_top
|
||||
#endif
|
||||
|
||||
3:
|
||||
// Hart 3 stack
|
||||
#if TINYGO_CORES >= 4
|
||||
li a1, 3
|
||||
bne a0, a1, 4f
|
||||
la sp, _stack3_top
|
||||
#endif
|
||||
|
||||
4:
|
||||
// done
|
||||
|
||||
#if TINYGO_CORES > 4
|
||||
#error only up to 4 cores are supported at the moment!
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Load the stack pointer.
|
||||
la sp, _stack_top
|
||||
#endif
|
||||
|
||||
// Load the globals pointer. The program will load pointers relative to this
|
||||
// register, so it must be set to the right value on startup.
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// Hand created file. DO NOT DELETE.
|
||||
// Definitions that are missing in src/device/rp/rp2040.go generated from SVDs
|
||||
|
||||
//go:build rp && rp2040
|
||||
|
||||
package rp
|
||||
|
||||
// DMA: 2.5.3.1. System DREQ Table from RP2040 Datasheet
|
||||
// https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf
|
||||
const (
|
||||
DREQ_PIO0_TX0 = 0
|
||||
DREQ_PIO0_TX1 = 1
|
||||
DREQ_PIO0_TX2 = 2
|
||||
DREQ_PIO0_TX3 = 3
|
||||
DREQ_PIO0_RX0 = 4
|
||||
DREQ_PIO0_RX1 = 5
|
||||
DREQ_PIO0_RX2 = 6
|
||||
DREQ_PIO0_RX3 = 7
|
||||
DREQ_PIO1_TX0 = 8
|
||||
DREQ_PIO1_TX1 = 9
|
||||
DREQ_PIO1_TX2 = 10
|
||||
DREQ_PIO1_TX3 = 11
|
||||
DREQ_PIO1_RX0 = 12
|
||||
DREQ_PIO1_RX1 = 13
|
||||
DREQ_PIO1_RX2 = 14
|
||||
DREQ_PIO1_RX3 = 15
|
||||
DREQ_SPI0_TX = 16
|
||||
DREQ_SPI0_RX = 17
|
||||
DREQ_SPI1_TX = 18
|
||||
DREQ_SPI1_RX = 19
|
||||
DREQ_UART0_TX = 20
|
||||
DREQ_UART0_RX = 21
|
||||
DREQ_UART1_TX = 22
|
||||
DREQ_UART1_RX = 23
|
||||
DREQ_PWM_WRAP0 = 24
|
||||
DREQ_PWM_WRAP1 = 25
|
||||
DREQ_PWM_WRAP2 = 26
|
||||
DREQ_PWM_WRAP3 = 27
|
||||
DREQ_PWM_WRAP4 = 28
|
||||
DREQ_PWM_WRAP5 = 29
|
||||
DREQ_PWM_WRAP6 = 30
|
||||
DREQ_PWM_WRAP7 = 31
|
||||
DREQ_I2C0_TX = 32
|
||||
DREQ_I2C0_RX = 33
|
||||
DREQ_I2C1_TX = 34
|
||||
DREQ_I2C1_RX = 35
|
||||
DREQ_ADC = 36
|
||||
DREQ_XIP_STREAM = 37
|
||||
DREQ_XIP_SSITX = 38
|
||||
DREQ_XIP_SSIRX = 39
|
||||
)
|
||||
@@ -1,66 +0,0 @@
|
||||
// Hand created file. DO NOT DELETE.
|
||||
// Definitions that are missing in src/device/rp/rp2350.go generated from SVDs
|
||||
|
||||
//go:build rp && rp2350
|
||||
|
||||
package rp
|
||||
|
||||
// DMA: 12.6.4.1. System DREQ Table from RP2350 Datasheet
|
||||
// https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf
|
||||
const (
|
||||
DREQ_PIO0_TX0 = 0
|
||||
DREQ_PIO0_TX1 = 1
|
||||
DREQ_PIO0_TX2 = 2
|
||||
DREQ_PIO0_TX3 = 3
|
||||
DREQ_PIO0_RX0 = 4
|
||||
DREQ_PIO0_RX1 = 5
|
||||
DREQ_PIO0_RX2 = 6
|
||||
DREQ_PIO0_RX3 = 7
|
||||
DREQ_PIO1_TX0 = 8
|
||||
DREQ_PIO1_TX1 = 9
|
||||
DREQ_PIO1_TX2 = 10
|
||||
DREQ_PIO1_TX3 = 11
|
||||
DREQ_PIO1_RX0 = 12
|
||||
DREQ_PIO1_RX1 = 13
|
||||
DREQ_PIO1_RX2 = 14
|
||||
DREQ_PIO1_RX3 = 15
|
||||
DREQ_PIO2_TX0 = 16
|
||||
DREQ_PIO2_TX1 = 17
|
||||
DREQ_PIO2_TX2 = 18
|
||||
DREQ_PIO2_TX3 = 19
|
||||
DREQ_PIO2_RX0 = 20
|
||||
DREQ_PIO2_RX1 = 21
|
||||
DREQ_PIO2_RX2 = 22
|
||||
DREQ_PIO2_RX3 = 23
|
||||
DREQ_SPI0_TX = 24
|
||||
DREQ_SPI0_RX = 25
|
||||
DREQ_SPI1_TX = 26
|
||||
DREQ_SPI1_RX = 27
|
||||
DREQ_UART0_TX = 28
|
||||
DREQ_UART0_RX = 29
|
||||
DREQ_UART1_TX = 30
|
||||
DREQ_UART1_RX = 31
|
||||
DREQ_PWM_WRAP0 = 32
|
||||
DREQ_PWM_WRAP1 = 33
|
||||
DREQ_PWM_WRAP2 = 34
|
||||
DREQ_PWM_WRAP3 = 35
|
||||
DREQ_PWM_WRAP4 = 36
|
||||
DREQ_PWM_WRAP5 = 37
|
||||
DREQ_PWM_WRAP6 = 38
|
||||
DREQ_PWM_WRAP7 = 39
|
||||
DREQ_PWM_WRAP8 = 40
|
||||
DREQ_PWM_WRAP9 = 41
|
||||
DREQ_PWM_WRAP10 = 42
|
||||
DREQ_PWM_WRAP11 = 43
|
||||
DREQ_I2C0_TX = 44
|
||||
DREQ_I2C0_RX = 45
|
||||
DREQ_I2C1_TX = 46
|
||||
DREQ_I2C1_RX = 47
|
||||
DREQ_ADC = 48
|
||||
DREQ_XIP_STREAM = 49
|
||||
DREQ_XIP_QMITX = 50
|
||||
DREQ_XIP_QMIRX = 51
|
||||
DREQ_HSTX = 52
|
||||
DREQ_CORESIGHT = 53
|
||||
DREQ_SHA256 = 54
|
||||
)
|
||||
@@ -1,40 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"machine"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const N = 500000
|
||||
const Ngoro = 4
|
||||
|
||||
func main() {
|
||||
start := time.Now()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(Ngoro)
|
||||
for i := 0; i < Ngoro; i++ {
|
||||
go adder(&wg, N)
|
||||
}
|
||||
wg.Wait()
|
||||
elapsed := time.Since(start)
|
||||
goroutineCtxSwitchOverhead := (elapsed / (Ngoro * N)).String()
|
||||
|
||||
elapsedstr := elapsed.String()
|
||||
machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
for {
|
||||
println("bench:", elapsedstr, "goroutine ctx switch:", goroutineCtxSwitchOverhead)
|
||||
machine.LED.High()
|
||||
time.Sleep(elapsed)
|
||||
machine.LED.Low()
|
||||
time.Sleep(elapsed)
|
||||
}
|
||||
}
|
||||
|
||||
func adder(wg *sync.WaitGroup, num int) {
|
||||
for i := 0; i < num; i++ {
|
||||
runtime.Gosched()
|
||||
}
|
||||
wg.Done()
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"machine"
|
||||
"machine/usb/msc"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
msc.Port(machine.Flash)
|
||||
|
||||
for {
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,3 @@ import "unsafe"
|
||||
func NoEscape(p unsafe.Pointer) unsafe.Pointer {
|
||||
return p
|
||||
}
|
||||
|
||||
func Escape[T any](x T) T {
|
||||
// This function is either implemented in the compiler, or left undefined
|
||||
// for some variation of T. The body of this function should not be compiled
|
||||
// as-is.
|
||||
panic("internal/abi.Escape: unreachable (implemented in the compiler)")
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package abi
|
||||
|
||||
type Type struct {
|
||||
// Intentionally left empty. TinyGo uses a different way to represent types,
|
||||
// so this is unimplementable. The type definition here is purely for
|
||||
// compatibility.
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package cm
|
||||
|
||||
// CaseUnmarshaler returns an function that can unmarshal text into
|
||||
// [variant] or [enum] case T.
|
||||
//
|
||||
// [enum]: https://component-model.bytecodealliance.org/design/wit.html#enums
|
||||
// [variant]: https://component-model.bytecodealliance.org/design/wit.html#variants
|
||||
func CaseUnmarshaler[T ~uint8 | ~uint16 | ~uint32](cases []string) func(v *T, text []byte) error {
|
||||
if len(cases) <= linearScanThreshold {
|
||||
return func(v *T, text []byte) error {
|
||||
if len(text) == 0 {
|
||||
return &emptyTextError{}
|
||||
}
|
||||
s := string(text)
|
||||
for i := 0; i < len(cases); i++ {
|
||||
if cases[i] == s {
|
||||
*v = T(i)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return &noMatchingCaseError{}
|
||||
}
|
||||
}
|
||||
|
||||
m := make(map[string]T, len(cases))
|
||||
for i, v := range cases {
|
||||
m[v] = T(i)
|
||||
}
|
||||
|
||||
return func(v *T, text []byte) error {
|
||||
if len(text) == 0 {
|
||||
return &emptyTextError{}
|
||||
}
|
||||
c, ok := m[string(text)]
|
||||
if !ok {
|
||||
return &noMatchingCaseError{}
|
||||
}
|
||||
*v = c
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const linearScanThreshold = 16
|
||||
|
||||
type emptyTextError struct{}
|
||||
|
||||
func (*emptyTextError) Error() string { return "empty text" }
|
||||
|
||||
type noMatchingCaseError struct{}
|
||||
|
||||
func (*noMatchingCaseError) Error() string { return "no matching case" }
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package cm provides types and functions for interfacing with the WebAssembly Component Model.
|
||||
// Package cm contains types and functions for interfacing with the WebAssembly Component Model.
|
||||
//
|
||||
// The types in this package (such as [List], [Option], [Result], and [Variant]) are designed to match the memory layout
|
||||
// of [Component Model] types as specified in the [Canonical ABI].
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
// This file exists for testing this package without WebAssembly,
|
||||
// allowing empty function bodies with a //go:wasmimport directive.
|
||||
// See https://pkg.go.dev/cmd/compile for more information.
|
||||
@@ -1,40 +0,0 @@
|
||||
package cm
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// ErrorContext represents the Component Model [error-context] type,
|
||||
// an immutable, non-deterministic, host-defined value meant to aid in debugging.
|
||||
//
|
||||
// [error-context]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-context-type
|
||||
type ErrorContext struct {
|
||||
_ HostLayout
|
||||
errorContext
|
||||
}
|
||||
|
||||
type errorContext uint32
|
||||
|
||||
// Error implements the [error] interface. It returns the debug message associated with err.
|
||||
func (err errorContext) Error() string {
|
||||
return err.DebugMessage()
|
||||
}
|
||||
|
||||
// String implements [fmt.Stringer].
|
||||
func (err errorContext) String() string {
|
||||
return err.DebugMessage()
|
||||
}
|
||||
|
||||
// DebugMessage represents the Canonical ABI [error-context.debug-message] function.
|
||||
//
|
||||
// [error-context.debug-message]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-contextdebug-message
|
||||
func (err errorContext) DebugMessage() string {
|
||||
var s string
|
||||
wasmimport_errorContextDebugMessage(err, unsafe.Pointer(&s))
|
||||
return s
|
||||
}
|
||||
|
||||
// Drop represents the Canonical ABI [error-context.drop] function.
|
||||
//
|
||||
// [error-context.drop]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#error-contextdrop
|
||||
func (err errorContext) Drop() {
|
||||
wasmimport_errorContextDrop(err)
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package cm
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// msg uses unsafe.Pointer for compatibility with go1.23 and lower.
|
||||
//
|
||||
//go:wasmimport canon error-context.debug-message
|
||||
//go:noescape
|
||||
func wasmimport_errorContextDebugMessage(err errorContext, msg unsafe.Pointer)
|
||||
|
||||
//go:wasmimport canon error-context.drop
|
||||
//go:noescape
|
||||
func wasmimport_errorContextDrop(err errorContext)
|
||||
@@ -1,15 +0,0 @@
|
||||
package cm
|
||||
|
||||
// Future represents the Component Model [future] type.
|
||||
// A future is a special case of stream. In non-error cases,
|
||||
// a future delivers exactly one value before being automatically closed.
|
||||
//
|
||||
// [future]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#asynchronous-value-types
|
||||
type Future[T any] struct {
|
||||
_ HostLayout
|
||||
future[T]
|
||||
}
|
||||
|
||||
type future[T any] uint32
|
||||
|
||||
// TODO: implement methods on type future
|
||||
@@ -1,8 +1,6 @@
|
||||
package cm
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
import "unsafe"
|
||||
|
||||
// List represents a Component Model list.
|
||||
// The binary representation of list<T> is similar to a Go slice minus the cap field.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package cm
|
||||
|
||||
// Stream represents the Component Model [stream] type.
|
||||
// A stream is a special case of stream. In non-error cases,
|
||||
// a stream delivers exactly one value before being automatically closed.
|
||||
//
|
||||
// [stream]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#asynchronous-value-types
|
||||
type Stream[T any] struct {
|
||||
_ HostLayout
|
||||
stream[T]
|
||||
}
|
||||
|
||||
type stream[T any] uint32
|
||||
|
||||
// TODO: implement methods on type stream
|
||||
@@ -3,9 +3,10 @@ package cm
|
||||
import "unsafe"
|
||||
|
||||
// Discriminant is the set of types that can represent the tag or discriminator of a variant.
|
||||
// Use uint8 where there are 256 or fewer cases, uint16 for up to 65,536 cases, or uint32 for anything greater.
|
||||
// Use bool for 2-case variant types, result<T>, or option<T> types, uint8 where there are 256 or
|
||||
// fewer cases, uint16 for up to 65,536 cases, or uint32 for anything greater.
|
||||
type Discriminant interface {
|
||||
uint8 | uint16 | uint32
|
||||
bool | uint8 | uint16 | uint32
|
||||
}
|
||||
|
||||
// Variant represents a loosely-typed Component Model variant.
|
||||
|
||||
@@ -5,20 +5,29 @@ import "unsafe"
|
||||
// Internal constants for gc layout
|
||||
// See runtime/gc_precise.go
|
||||
|
||||
type Layout uintptr
|
||||
|
||||
const (
|
||||
// 16-bit int => bits = 4
|
||||
// 32-bit int => bits = 5
|
||||
// 64-bit int => bits = 6
|
||||
sizeBits = 4 + unsafe.Sizeof(uintptr(0))/4
|
||||
|
||||
sizeShift = sizeBits + 1
|
||||
|
||||
NoPtrs = Layout(uintptr(0b0<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||
Pointer = Layout(uintptr(0b1<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||
String = Layout(uintptr(0b01<<sizeShift) | uintptr(0b10<<1) | uintptr(1))
|
||||
Slice = Layout(uintptr(0b001<<sizeShift) | uintptr(0b11<<1) | uintptr(1))
|
||||
var (
|
||||
NoPtrs unsafe.Pointer
|
||||
Pointer unsafe.Pointer
|
||||
String unsafe.Pointer
|
||||
Slice unsafe.Pointer
|
||||
)
|
||||
|
||||
func (l Layout) AsPtr() unsafe.Pointer { return unsafe.Pointer(l) }
|
||||
func init() {
|
||||
var sizeBits uintptr
|
||||
|
||||
switch unsafe.Sizeof(uintptr(0)) {
|
||||
case 8:
|
||||
sizeBits = 6
|
||||
case 4:
|
||||
sizeBits = 5
|
||||
case 2:
|
||||
sizeBits = 4
|
||||
}
|
||||
|
||||
var sizeShift = sizeBits + 1
|
||||
|
||||
NoPtrs = unsafe.Pointer(uintptr(0b0<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||
Pointer = unsafe.Pointer(uintptr(0b1<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||
String = unsafe.Pointer(uintptr(0b01<<sizeShift) | uintptr(0b10<<1) | uintptr(1))
|
||||
Slice = unsafe.Pointer(uintptr(0b001<<sizeShift) | uintptr(0b11<<1) | uintptr(1))
|
||||
}
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Deep equality test via reflection
|
||||
|
||||
package reflectlite
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// During deepValueEqual, must keep track of checks that are
|
||||
// in progress. The comparison algorithm assumes that all
|
||||
// checks in progress are true when it reencounters them.
|
||||
// Visited comparisons are stored in a map indexed by visit.
|
||||
type visit struct {
|
||||
a1 unsafe.Pointer
|
||||
a2 unsafe.Pointer
|
||||
typ *RawType
|
||||
}
|
||||
|
||||
// Tests for deep equality using reflected types. The map argument tracks
|
||||
// comparisons that have already been seen, which allows short circuiting on
|
||||
// recursive types.
|
||||
func deepValueEqual(v1, v2 Value, visited map[visit]struct{}) bool {
|
||||
if !v1.IsValid() || !v2.IsValid() {
|
||||
return v1.IsValid() == v2.IsValid()
|
||||
}
|
||||
if v1.typecode != v2.typecode {
|
||||
return false
|
||||
}
|
||||
|
||||
// We want to avoid putting more in the visited map than we need to.
|
||||
// For any possible reference cycle that might be encountered,
|
||||
// hard(v1, v2) needs to return true for at least one of the types in the cycle,
|
||||
// and it's safe and valid to get Value's internal pointer.
|
||||
hard := func(v1, v2 Value) bool {
|
||||
switch v1.Kind() {
|
||||
case Map, Slice, Ptr, Interface:
|
||||
// Nil pointers cannot be cyclic. Avoid putting them in the visited map.
|
||||
return !v1.IsNil() && !v2.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if hard(v1, v2) {
|
||||
addr1 := v1.pointer()
|
||||
addr2 := v2.pointer()
|
||||
if uintptr(addr1) > uintptr(addr2) {
|
||||
// Canonicalize order to reduce number of entries in visited.
|
||||
// Assumes non-moving garbage collector.
|
||||
addr1, addr2 = addr2, addr1
|
||||
}
|
||||
|
||||
// Short circuit if references are already seen.
|
||||
v := visit{addr1, addr2, v1.typecode}
|
||||
if _, ok := visited[v]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
// Remember for later.
|
||||
visited[v] = struct{}{}
|
||||
}
|
||||
|
||||
switch v1.Kind() {
|
||||
case Array:
|
||||
for i := 0; i < v1.Len(); i++ {
|
||||
if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case Slice:
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
if v1.UnsafePointer() == v2.UnsafePointer() {
|
||||
return true
|
||||
}
|
||||
for i := 0; i < v1.Len(); i++ {
|
||||
if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case Interface:
|
||||
if v1.IsNil() || v2.IsNil() {
|
||||
return v1.IsNil() == v2.IsNil()
|
||||
}
|
||||
return deepValueEqual(v1.Elem(), v2.Elem(), visited)
|
||||
case Ptr:
|
||||
if v1.UnsafePointer() == v2.UnsafePointer() {
|
||||
return true
|
||||
}
|
||||
return deepValueEqual(v1.Elem(), v2.Elem(), visited)
|
||||
case Struct:
|
||||
for i, n := 0, v1.NumField(); i < n; i++ {
|
||||
if !deepValueEqual(v1.Field(i), v2.Field(i), visited) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case Map:
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
if v1.UnsafePointer() == v2.UnsafePointer() {
|
||||
return true
|
||||
}
|
||||
for _, k := range v1.MapKeys() {
|
||||
val1 := v1.MapIndex(k)
|
||||
val2 := v2.MapIndex(k)
|
||||
if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case Func:
|
||||
if v1.IsNil() && v2.IsNil() {
|
||||
return true
|
||||
}
|
||||
// Can't do better than this:
|
||||
return false
|
||||
default:
|
||||
// Normal equality suffices
|
||||
return valueInterfaceUnsafe(v1) == valueInterfaceUnsafe(v2)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepEqual reports whether x and y are “deeply equal”, defined as follows.
|
||||
// Two values of identical type are deeply equal if one of the following cases applies.
|
||||
// Values of distinct types are never deeply equal.
|
||||
//
|
||||
// Array values are deeply equal when their corresponding elements are deeply equal.
|
||||
//
|
||||
// Struct values are deeply equal if their corresponding fields,
|
||||
// both exported and unexported, are deeply equal.
|
||||
//
|
||||
// Func values are deeply equal if both are nil; otherwise they are not deeply equal.
|
||||
//
|
||||
// Interface values are deeply equal if they hold deeply equal concrete values.
|
||||
//
|
||||
// Map values are deeply equal when all of the following are true:
|
||||
// they are both nil or both non-nil, they have the same length,
|
||||
// and either they are the same map object or their corresponding keys
|
||||
// (matched using Go equality) map to deeply equal values.
|
||||
//
|
||||
// Pointer values are deeply equal if they are equal using Go's == operator
|
||||
// or if they point to deeply equal values.
|
||||
//
|
||||
// Slice values are deeply equal when all of the following are true:
|
||||
// they are both nil or both non-nil, they have the same length,
|
||||
// and either they point to the same initial entry of the same underlying array
|
||||
// (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal.
|
||||
// Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil))
|
||||
// are not deeply equal.
|
||||
//
|
||||
// Other values - numbers, bools, strings, and channels - are deeply equal
|
||||
// if they are equal using Go's == operator.
|
||||
//
|
||||
// In general DeepEqual is a recursive relaxation of Go's == operator.
|
||||
// However, this idea is impossible to implement without some inconsistency.
|
||||
// Specifically, it is possible for a value to be unequal to itself,
|
||||
// either because it is of func type (uncomparable in general)
|
||||
// or because it is a floating-point NaN value (not equal to itself in floating-point comparison),
|
||||
// or because it is an array, struct, or interface containing
|
||||
// such a value.
|
||||
// On the other hand, pointer values are always equal to themselves,
|
||||
// even if they point at or contain such problematic values,
|
||||
// because they compare equal using Go's == operator, and that
|
||||
// is a sufficient condition to be deeply equal, regardless of content.
|
||||
// DeepEqual has been defined so that the same short-cut applies
|
||||
// to slices and maps: if x and y are the same slice or the same map,
|
||||
// they are deeply equal regardless of content.
|
||||
//
|
||||
// As DeepEqual traverses the data values it may find a cycle. The
|
||||
// second and subsequent times that DeepEqual compares two pointer
|
||||
// values that have been compared before, it treats the values as
|
||||
// equal rather than examining the values to which they point.
|
||||
// This ensures that DeepEqual terminates.
|
||||
func DeepEqual(x, y interface{}) bool {
|
||||
if x == nil || y == nil {
|
||||
return x == y
|
||||
}
|
||||
v1 := ValueOf(x)
|
||||
v2 := ValueOf(y)
|
||||
if v1.typecode != v2.typecode {
|
||||
return false
|
||||
}
|
||||
return deepValueEqual(v1, v2, make(map[visit]struct{}))
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package reflectlite
|
||||
|
||||
import "reflect"
|
||||
|
||||
func Swapper(slice interface{}) func(i, j int) {
|
||||
return reflect.Swapper(slice)
|
||||
}
|
||||
|
||||
type Kind = reflect.Kind
|
||||
type Type = reflect.Type
|
||||
type Value = reflect.Value
|
||||
|
||||
const (
|
||||
Invalid Kind = reflect.Invalid
|
||||
Bool Kind = reflect.Bool
|
||||
Int Kind = reflect.Int
|
||||
Int8 Kind = reflect.Int8
|
||||
Int16 Kind = reflect.Int16
|
||||
Int32 Kind = reflect.Int32
|
||||
Int64 Kind = reflect.Int64
|
||||
Uint Kind = reflect.Uint
|
||||
Uint8 Kind = reflect.Uint8
|
||||
Uint16 Kind = reflect.Uint16
|
||||
Uint32 Kind = reflect.Uint32
|
||||
Uint64 Kind = reflect.Uint64
|
||||
Uintptr Kind = reflect.Uintptr
|
||||
Float32 Kind = reflect.Float32
|
||||
Float64 Kind = reflect.Float64
|
||||
Complex64 Kind = reflect.Complex64
|
||||
Complex128 Kind = reflect.Complex128
|
||||
Array Kind = reflect.Array
|
||||
Chan Kind = reflect.Chan
|
||||
Func Kind = reflect.Func
|
||||
Interface Kind = reflect.Interface
|
||||
Map Kind = reflect.Map
|
||||
Ptr Kind = reflect.Ptr
|
||||
Slice Kind = reflect.Slice
|
||||
String Kind = reflect.String
|
||||
Struct Kind = reflect.Struct
|
||||
UnsafePointer Kind = reflect.UnsafePointer
|
||||
)
|
||||
|
||||
func ValueOf(i interface{}) reflect.Value {
|
||||
return reflect.ValueOf(i)
|
||||
}
|
||||
|
||||
func TypeOf(i interface{}) reflect.Type {
|
||||
return reflect.TypeOf(i)
|
||||
}
|
||||
|
||||
type ValueError = reflect.ValueError
|
||||
@@ -1,40 +0,0 @@
|
||||
package reflectlite
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Some of code here has been copied from the Go sources:
|
||||
// https://github.com/golang/go/blob/go1.15.2/src/reflect/swapper.go
|
||||
// It has the following copyright note:
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
func Swapper(slice interface{}) func(i, j int) {
|
||||
v := ValueOf(slice)
|
||||
if v.Kind() != Slice {
|
||||
panic(&ValueError{Method: "Swapper"})
|
||||
}
|
||||
|
||||
// Just return Nop func if nothing to swap.
|
||||
if v.Len() < 2 {
|
||||
return func(i, j int) {}
|
||||
}
|
||||
|
||||
typ := v.typecode.Elem()
|
||||
size := typ.Size()
|
||||
|
||||
header := (*sliceHeader)(v.value)
|
||||
tmp := unsafe.Pointer(&make([]byte, size)[0])
|
||||
|
||||
return func(i, j int) {
|
||||
if uint(i) >= uint(header.len) || uint(j) >= uint(header.len) {
|
||||
panic("reflect: slice index out of range")
|
||||
}
|
||||
val1 := unsafe.Add(header.data, uintptr(i)*size)
|
||||
val2 := unsafe.Add(header.data, uintptr(j)*size)
|
||||
memcpy(tmp, val1, size)
|
||||
memcpy(val1, val2, size)
|
||||
memcpy(val2, tmp, size)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user