mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 14:48:40 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ef4f46f1d1 | |||
| 16cd500000 | |||
| 16950780d3 | |||
| 7e284a37fc | |||
| b6c53a6f0e | |||
| 8b626e6ea7 | |||
| 1d1f4fc401 | |||
| 250426c1e5 | |||
| e300e90a63 | |||
| e865db232b | |||
| db2a06a9bb | |||
| 560fd0a558 | |||
| b8048112df | |||
| b51cda9721 | |||
| 4d60d679d3 | |||
| 9932f2e126 | |||
| bf8d6460da | |||
| d3e67cf18c | |||
| 5d82a7eee6 | |||
| c82ff057f5 | |||
| 5368dd22c5 | |||
| 194396d715 | |||
| 815784bd96 | |||
| 7fc64a27b4 | |||
| c38bf27091 | |||
| 9a2fab8874 | |||
| f1516ad3ee | |||
| 4dc07d6cc3 | |||
| a35b983a5d | |||
| a47ff02c82 | |||
| e27b2c4ad6 | |||
| 8135be4e90 | |||
| 835e73237e | |||
| eab1a5d7ec | |||
| f188eaf5f9 | |||
| 6efc6d2bb6 | |||
| d6e73b4c68 | |||
| 2e76cd3687 | |||
| 2eb39785fe | |||
| 3021e16bbf | |||
| 55f7d21ff5 | |||
| 841abb0903 | |||
| fb3d98ce6e | |||
| 020664591a | |||
| 2d6d9eb76d | |||
| a8a532f9d6 | |||
| 417a26d20c | |||
| 88f9fc3ce2 | |||
| 84c376160f | |||
| 6184a6cd35 |
@@ -104,10 +104,12 @@ jobs:
|
||||
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-llvm18-go122:
|
||||
test-llvm18-go123:
|
||||
docker:
|
||||
- image: golang:1.22-bullseye
|
||||
- image: golang:1.23-bullseye
|
||||
steps:
|
||||
- test-linux:
|
||||
llvm: "18"
|
||||
@@ -120,4 +122,4 @@ workflows:
|
||||
# least the smoke tests still pass.
|
||||
- test-llvm15-go119
|
||||
# This tests LLVM 18 support when linking against system libraries.
|
||||
- test-llvm18-go122
|
||||
- test-llvm18-go123
|
||||
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -145,7 +145,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
||||
run: go install -tags=llvm${{ matrix.version }}
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
# statically linked binary.
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: golang:1.22-alpine
|
||||
image: golang:1.23-alpine
|
||||
steps:
|
||||
- name: Install apk dependencies
|
||||
# tar: needed for actions/cache@v4
|
||||
@@ -115,6 +115,8 @@ jobs:
|
||||
gem install --no-document fpm
|
||||
- name: Run linter
|
||||
run: make lint
|
||||
- name: Run spellcheck
|
||||
run: make spell
|
||||
- name: Build TinyGo release
|
||||
run: |
|
||||
make release deb -j3 STATIC=1
|
||||
@@ -139,7 +141,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Install wasmtime
|
||||
uses: bytecodealliance/actions/wasmtime/setup@v1
|
||||
@@ -182,7 +184,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
@@ -305,7 +307,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v4
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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/jammy/ llvm-toolchain-jammy-18 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-18 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 \
|
||||
|
||||
@@ -9,6 +9,8 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
sizediff:
|
||||
# Note: when updating the Ubuntu version, also update the Ubuntu version in
|
||||
# sizediff-install-pkgs.sh
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Restore cached LLVM source
|
||||
uses: actions/cache/restore@v4
|
||||
@@ -143,7 +143,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -173,7 +173,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -209,7 +209,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
go-version: '1.23'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
+15
@@ -28,6 +28,21 @@ build tools to be built. Go is of course necessary to build TinyGo itself.
|
||||
The rest of this guide assumes you're running Linux, but it should be equivalent
|
||||
on a different system like Mac.
|
||||
|
||||
## Using GNU Make
|
||||
|
||||
The static build of TinyGo is driven by GNUmakefile, which provides a help target for quick reference:
|
||||
|
||||
% make help
|
||||
clean Remove build directory
|
||||
fmt Reformat source
|
||||
fmt-check Warn if any source needs reformatting
|
||||
gen-device Generate microcontroller-specific sources
|
||||
llvm-source Get LLVM sources
|
||||
llvm-build Build LLVM
|
||||
tinygo Build the TinyGo compiler
|
||||
lint Lint source tree
|
||||
spell Spellcheck source tree
|
||||
|
||||
## Download the source
|
||||
|
||||
The first step is to download the TinyGo sources (use `--recursive` if you clone
|
||||
|
||||
+63
-3
@@ -1,3 +1,63 @@
|
||||
0.33.0
|
||||
---
|
||||
|
||||
* **general**
|
||||
- use latest version of x/tools
|
||||
- add chromeos 9p support for flashing
|
||||
- sort compiler error messages by source position in a package
|
||||
- don't include prebuilt libraries in the release to simplify packaging and reduce the release tarball size
|
||||
- show runtime panic addresses for `tinygo run`
|
||||
- support Go 1.23 (including all new language features)
|
||||
- `test`: support GOOS/GOARCH pairs in the `-target` flag
|
||||
- `test`: remove message after test binary built
|
||||
* **compiler**
|
||||
- remove unused registers for x86_64 linux syscalls
|
||||
- remove old atomics workaround for AVR (not necessary in modern LLVM versions)
|
||||
- support `golang.org/x/sys/unix` syscalls
|
||||
- `builder`: remove workaround for generics race condition
|
||||
- `builder`: add package ID to compiler and optimization error messages
|
||||
- `builder`: show better error messages for some common linker errors
|
||||
- `cgo`: support preprocessor macros passed on the command line
|
||||
- `cgo`: use absolute paths for error messages
|
||||
- `cgo`: add support for printf
|
||||
- `loader`: handle `go list` errors inside TinyGo (for better error messages)
|
||||
- `transform`: fix incorrect alignment of heap-to-stack transform
|
||||
- `transform`: use thinlto-pre-link passes (instead of the full pipeline) to speed up compilation speed slightly
|
||||
* **standard library**
|
||||
- `crypto/tls`: add CipherSuiteName and some extra fields to ConnectionSTate
|
||||
- `internal/abi`: implement initial version of this package
|
||||
- `machine`: use new `internal/binary` package
|
||||
- `machine`: rewrite Reply() to fix sending long replies in I2C Target Mode
|
||||
- `machine/usb/descriptor`: Reset joystick physical
|
||||
- `machine/usb/descriptor`: Drop second joystick hat
|
||||
- `machine/usb/descriptor`: Add more HID... functions
|
||||
- `machine/usb/descriptor`: Fix encoding of values
|
||||
- `machine/usb/hid/joystick`: Allow more hat switches
|
||||
- `os`: add `Chown`, `Truncate`
|
||||
- `os/user`: use stdlib version of this package
|
||||
- `reflect`: return correct name for the `unsafe.Pointer` type
|
||||
- `reflect`: implement `Type.Overflow*` functions
|
||||
- `runtime`: implement dummy `getAuxv` to satisfy golang.org/x/sys/
|
||||
- `runtime`: don't zero out new allocations for `-gc=leaking` when they are already zeroed
|
||||
- `runtime`: simplify slice growing/appending code
|
||||
- `runtime`: print a message when a fatal signal like SIGSEGV happens
|
||||
- `runtime/debug`: add `GoVersion` to `debug.BuildInfo`
|
||||
- `sync`: add `Map.Clear()`
|
||||
- `sync/atomic`: add And* and Or* compiler intrinsics needed for Go 1.23
|
||||
- `syscall`: add `Fork` and `Execve`
|
||||
- `syscall`: add all MacOS errno values
|
||||
- `testing`: stub out `T.Deadline`
|
||||
- `unique`: implement custom (naive) version of the unique package
|
||||
* **targets**
|
||||
- `arm`: support `GOARM=*,softfloat` (softfloat support for ARM v5, v6, and v7)
|
||||
- `mips`: add linux/mipsle (and experimental linux/mips) support
|
||||
- `mips`: add `GOMIPS=softfloat` support
|
||||
- `wasip2`: add WASI preview 2 support
|
||||
- `wasm/js`: add `node:` prefix in `require()` call of wasm_exec.js
|
||||
- `wasm-unknown`: make sure the `os` package can be imported
|
||||
- `wasm-unknown`: remove import-memory flag
|
||||
|
||||
|
||||
0.32.0
|
||||
---
|
||||
|
||||
@@ -18,7 +78,7 @@
|
||||
- `builder`: keep un-wasm-opt'd .wasm if -work was passed
|
||||
- `builder`: make sure wasm-opt command line is printed if asked
|
||||
- `cgo`: implement shift operations in preprocessor macros
|
||||
- `interp`: checking for methodset existance
|
||||
- `interp`: checking for methodset existence
|
||||
|
||||
* **standard library**
|
||||
- `machine`: add `__tinygo_spi_tx` function to simulator
|
||||
@@ -217,7 +277,7 @@
|
||||
- `reflect`: add SetZero
|
||||
- `reflect`: fix iterating over maps with interface{} keys
|
||||
- `reflect`: implement Value.Grow
|
||||
- `reflect`: remove unecessary heap allocations
|
||||
- `reflect`: remove unnecessary heap allocations
|
||||
- `reflect`: use .key() instead of a type assert
|
||||
- `sync`: add implementation from upstream Go for OnceFunc, OnceValue, and OnceValues
|
||||
* **targets**
|
||||
@@ -1896,7 +1956,7 @@
|
||||
- allow packages like github.com/tinygo-org/tinygo/src/\* by aliasing it
|
||||
- remove `//go:volatile` support
|
||||
It has been replaced with the runtime/volatile package.
|
||||
- allow poiners in map keys
|
||||
- allow pointers in map keys
|
||||
- support non-constant syscall numbers
|
||||
- implement non-blocking selects
|
||||
- add support for the `-tags` flag
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
# tinygo-llvm stage obtains the llvm source for TinyGo
|
||||
FROM golang:1.22 AS tinygo-llvm
|
||||
FROM golang:1.23 AS tinygo-llvm
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y apt-utils make cmake clang-15 ninja-build && \
|
||||
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
|
||||
|
||||
# tinygo-compiler copies the compiler build over to a base Go container (without
|
||||
# all the build tools etc).
|
||||
FROM golang:1.22 AS tinygo-compiler
|
||||
FROM golang:1.23 AS tinygo-compiler
|
||||
|
||||
# Copy tinygo build.
|
||||
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
||||
|
||||
+36
-30
@@ -175,17 +175,17 @@ ifneq ("$(wildcard $(LLVM_BUILDDIR)/bin/llvm-config*)","")
|
||||
CGO_LDFLAGS+=-L$(abspath $(LLVM_BUILDDIR)/lib) -lclang $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_CONFIG_PREFIX) $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA)
|
||||
endif
|
||||
|
||||
clean:
|
||||
clean: ## Remove build directory
|
||||
@rm -rf build
|
||||
|
||||
FMT_PATHS = ./*.go builder cgo/*.go compiler interp loader src transform
|
||||
fmt:
|
||||
fmt: ## Reformat source
|
||||
@gofmt -l -w $(FMT_PATHS)
|
||||
fmt-check:
|
||||
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
|
||||
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 ($(STM32), 0)
|
||||
gen-device: gen-device-stm32
|
||||
endif
|
||||
@@ -237,18 +237,16 @@ gen-device-renesas: build/gen-device-svd
|
||||
./build/gen-device-svd -source=https://github.com/tinygo-org/renesas-svd lib/renesas-svd/ src/device/renesas/
|
||||
GO111MODULE=off $(GO) fmt ./src/device/renesas
|
||||
|
||||
# Get LLVM sources.
|
||||
$(LLVM_PROJECTDIR)/llvm:
|
||||
git clone -b tinygo_xtensa_release_18.1.2 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
|
||||
llvm-source: $(LLVM_PROJECTDIR)/llvm
|
||||
llvm-source: $(LLVM_PROJECTDIR)/llvm ## Get LLVM sources
|
||||
|
||||
# Configure LLVM.
|
||||
TINYGO_SOURCE_DIR=$(shell pwd)
|
||||
$(LLVM_BUILDDIR)/build.ninja:
|
||||
mkdir -p $(LLVM_BUILDDIR) && cd $(LLVM_BUILDDIR) && cmake -G Ninja $(TINYGO_SOURCE_DIR)/$(LLVM_PROJECTDIR)/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;AVR;Mips;RISCV;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=Xtensa" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_ZSTD=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=OFF $(LLVM_OPTION)
|
||||
|
||||
# Build LLVM.
|
||||
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
|
||||
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja ## Build LLVM
|
||||
cd $(LLVM_BUILDDIR) && ninja $(NINJA_BUILD_TARGETS)
|
||||
|
||||
ifneq ($(USE_SYSTEM_BINARYEN),1)
|
||||
@@ -291,8 +289,7 @@ ifeq (, $(shell which node))
|
||||
endif
|
||||
@if [ $(NODEJS_VERSION) -lt $(MIN_NODEJS_VERSION) ]; then echo "Install NodeJS version 18+ to run tests."; exit 1; fi
|
||||
|
||||
# Build the Go compiler.
|
||||
tinygo:
|
||||
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" -ldflags="-X github.com/tinygo-org/tinygo/goenv.GitSha1=`git rev-parse --short HEAD`" .
|
||||
test: wasi-libc check-nodejs-version
|
||||
@@ -347,6 +344,7 @@ TEST_PACKAGES_FAST = \
|
||||
unicode \
|
||||
unicode/utf16 \
|
||||
unicode/utf8 \
|
||||
unique \
|
||||
$(nil)
|
||||
|
||||
# Assume this will go away before Go2, so only check minor version.
|
||||
@@ -361,18 +359,17 @@ endif
|
||||
# compress/flate appears to hang on wasi
|
||||
# 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
|
||||
# image requires recover(), which is not yet supported on wasi
|
||||
# io/ioutil requires os.ReadDir, which is not yet supported on windows or wasi
|
||||
# mime/quotedprintable requires syscall.Faccessat
|
||||
# strconv requires recover() which is not yet supported on wasi
|
||||
# text/tabwriter requries recover(), which is not yet supported on wasi
|
||||
# text/tabwriter requires recover(), which is not yet supported on wasi
|
||||
# text/template/parse requires recover(), which is not yet supported on wasi
|
||||
# testing/fstest requires os.ReadDir, which is not yet supported on windows or wasi
|
||||
|
||||
# Additional standard library packages that pass tests on individual platforms
|
||||
TEST_PACKAGES_LINUX := \
|
||||
archive/zip \
|
||||
bytes \
|
||||
compress/flate \
|
||||
crypto/hmac \
|
||||
debug/dwarf \
|
||||
@@ -381,8 +378,8 @@ TEST_PACKAGES_LINUX := \
|
||||
io/ioutil \
|
||||
mime/quotedprintable \
|
||||
net \
|
||||
os/user \
|
||||
strconv \
|
||||
testing/fstest \
|
||||
text/tabwriter \
|
||||
text/template/parse
|
||||
|
||||
@@ -391,6 +388,7 @@ TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
|
||||
TEST_PACKAGES_WINDOWS := \
|
||||
compress/flate \
|
||||
crypto/hmac \
|
||||
os/user \
|
||||
strconv \
|
||||
text/template/parse \
|
||||
$(nil)
|
||||
@@ -856,6 +854,7 @@ build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN
|
||||
@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/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
|
||||
@@ -867,9 +866,6 @@ build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN
|
||||
@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/
|
||||
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0
|
||||
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0plus
|
||||
@mkdir -p build/release/tinygo/pkg/thumbv7em-unknown-unknown-eabi-cortex-m4
|
||||
@echo copying source files
|
||||
@cp -p build/tinygo$(EXE) build/release/tinygo/bin
|
||||
ifneq ($(USE_SYSTEM_BINARYEN),1)
|
||||
@@ -894,10 +890,12 @@ endif
|
||||
@cp -rp lib/musl/src/include build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/legacy build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/locale build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/linux build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/malloc build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/mman build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
|
||||
@cp -rp lib/musl/src/multibyte 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/string build/release/tinygo/lib/musl/src
|
||||
@@ -907,6 +905,7 @@ endif
|
||||
@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/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/kernel32.def.in build/release/tinygo/lib/mingw-w64/mingw-w64-crt/lib-common
|
||||
@cp -rp lib/mingw-w64/mingw-w64-crt/stdio/ucrt_* build/release/tinygo/lib/mingw-w64/mingw-w64-crt/stdio
|
||||
@cp -rp lib/mingw-w64/mingw-w64-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/nrfx/* build/release/tinygo/lib/nrfx
|
||||
@@ -932,12 +931,6 @@ endif
|
||||
@cp -rp llvm-project/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
|
||||
@cp -rp src build/release/tinygo/src
|
||||
@cp -rp targets build/release/tinygo/targets
|
||||
./build/release/tinygo/bin/tinygo build-library -target=cortex-m0 -o build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0/compiler-rt compiler-rt
|
||||
./build/release/tinygo/bin/tinygo build-library -target=cortex-m0plus -o build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0plus/compiler-rt compiler-rt
|
||||
./build/release/tinygo/bin/tinygo build-library -target=cortex-m4 -o build/release/tinygo/pkg/thumbv7em-unknown-unknown-eabi-cortex-m4/compiler-rt compiler-rt
|
||||
./build/release/tinygo/bin/tinygo build-library -target=cortex-m0 -o build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0/picolibc picolibc
|
||||
./build/release/tinygo/bin/tinygo build-library -target=cortex-m0plus -o build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0plus/picolibc picolibc
|
||||
./build/release/tinygo/bin/tinygo build-library -target=cortex-m4 -o build/release/tinygo/pkg/thumbv7em-unknown-unknown-eabi-cortex-m4/picolibc picolibc
|
||||
|
||||
release:
|
||||
tar -czf build/release.tar.gz -C build/release tinygo
|
||||
@@ -957,18 +950,31 @@ endif
|
||||
|
||||
.PHONY: tools
|
||||
tools:
|
||||
go generate -C ./internal/tools -tags tools ./
|
||||
cd internal/tools && go generate -tags tools ./
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
go run github.com/mgechev/revive -version
|
||||
lint: tools ## Lint source tree
|
||||
revive -version
|
||||
# TODO: lint more directories!
|
||||
# revive.toml isn't flexible enough to filter out just one kind of error from a checker, so do it with grep here.
|
||||
# Can't use grep with friendly formatter. Plain output isn't too bad, though.
|
||||
# Use 'grep .' to get rid of stray blank line
|
||||
go run github.com/mgechev/revive -config revive.toml compiler/... src/{os,reflect}/*.go | grep -v "should have comment or be unexported" | grep '.' | awk '{print}; END {exit NR>0}'
|
||||
revive -config revive.toml compiler/... src/{os,reflect}/*.go | grep -v "should have comment or be unexported" | grep '.' | awk '{print}; END {exit NR>0}'
|
||||
|
||||
SPELLDIRSCMD=find . -depth 1 -type d | egrep -wv '.git|lib|llvm|src'; find src -depth 1 | egrep -wv 'device|internal|net|vendor'; find src/internal -depth 1 -type d | egrep -wv src/internal/wasi
|
||||
.PHONY: spell
|
||||
spell:
|
||||
# Check for typos in comments. Skip git submodules etc.
|
||||
go run github.com/client9/misspell/cmd/misspell -i 'ackward,devided,extint,inbetween,programmmer,rela' $$( find . -depth 1 -type d | egrep -w -v 'lib|llvm|src/net' )
|
||||
spell: tools ## Spellcheck source tree
|
||||
misspell -error --dict misspell.csv -i 'ackward,devided,extint,rela' $$( $(SPELLDIRSCMD) ) *.go *.md
|
||||
|
||||
.PHONY: spellfix
|
||||
spellfix: tools ## Same as spell, but fixes what it finds
|
||||
misspell -w --dict misspell.csv -i 'ackward,devided,extint,rela' $$( $(SPELLDIRSCMD) ) *.go *.md
|
||||
|
||||
# https://www.client9.com/self-documenting-makefiles/
|
||||
.PHONY: help
|
||||
help:
|
||||
@awk -F ':|##' '/^[^\t].+?:.*?##/ {\
|
||||
gsub(/\$$\(LLVM_BUILDDIR\)/, "$(LLVM_BUILDDIR)"); \
|
||||
printf "\033[36m%-30s\033[0m %s\n", $$1, $$NF \
|
||||
}' $(MAKEFILE_LIST)
|
||||
#.DEFAULT_GOAL=help
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/blakesmith/ar"
|
||||
)
|
||||
|
||||
// makeArchive creates an arcive for static linking from a list of object files
|
||||
// makeArchive creates an archive for static linking from a list of object files
|
||||
// given as a parameter. It is equivalent to the following command:
|
||||
//
|
||||
// ar -rcs <archivePath> <objs...>
|
||||
@@ -150,7 +150,7 @@ func makeArchive(arfile *os.File, objs []string) error {
|
||||
}
|
||||
|
||||
// Keep track of the start of the symbol table.
|
||||
symbolTableStart, err := arfile.Seek(0, os.SEEK_CUR)
|
||||
symbolTableStart, err := arfile.Seek(0, io.SeekCurrent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -172,7 +172,7 @@ func makeArchive(arfile *os.File, objs []string) error {
|
||||
|
||||
// Store the start index, for when we'll update the symbol table with
|
||||
// the correct file start indices.
|
||||
offset, err := arfile.Seek(0, os.SEEK_CUR)
|
||||
offset, err := arfile.Seek(0, io.SeekCurrent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+10
-8
@@ -148,7 +148,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
job := makeDarwinLibSystemJob(config, tmpdir)
|
||||
libcDependencies = append(libcDependencies, job)
|
||||
case "musl":
|
||||
job, unlock, err := Musl.load(config, tmpdir)
|
||||
job, unlock, err := libMusl.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
@@ -156,7 +156,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
libcDependencies = append(libcDependencies, dummyCompileJob(filepath.Join(filepath.Dir(job.result), "crt1.o")))
|
||||
libcDependencies = append(libcDependencies, job)
|
||||
case "picolibc":
|
||||
libcJob, unlock, err := Picolibc.load(config, tmpdir)
|
||||
libcJob, unlock, err := libPicolibc.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
@@ -169,18 +169,19 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
}
|
||||
libcDependencies = append(libcDependencies, dummyCompileJob(path))
|
||||
case "wasmbuiltins":
|
||||
libcJob, unlock, err := WasmBuiltins.load(config, tmpdir)
|
||||
libcJob, unlock, err := libWasmBuiltins.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
case "mingw-w64":
|
||||
_, unlock, err := MinGW.load(config, tmpdir)
|
||||
job, unlock, err := libMinGW.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
unlock()
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, job)
|
||||
libcDependencies = append(libcDependencies, makeMinGWExtraLibs(tmpdir, config.GOARCH())...)
|
||||
case "":
|
||||
// no library specified, so nothing to do
|
||||
@@ -651,7 +652,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
// Add compiler-rt dependency if needed. Usually this is a simple load from
|
||||
// a cache.
|
||||
if config.Target.RTLib == "compiler-rt" {
|
||||
job, unlock, err := CompilerRT.load(config, tmpdir)
|
||||
job, unlock, err := libCompilerRT.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -745,6 +746,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
ldflags = append(ldflags, dependency.result)
|
||||
}
|
||||
ldflags = append(ldflags, "-mllvm", "-mcpu="+config.CPU())
|
||||
ldflags = append(ldflags, "-mllvm", "-mattr="+config.Features()) // needed for MIPS softfloat
|
||||
if config.GOOS() == "windows" {
|
||||
// Options for the MinGW wrapper for the lld COFF linker.
|
||||
ldflags = append(ldflags,
|
||||
@@ -778,7 +780,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
}
|
||||
err = link(config.Target.Linker, ldflags...)
|
||||
if err != nil {
|
||||
return &commandError{"failed to link", result.Executable, err}
|
||||
return err
|
||||
}
|
||||
|
||||
var calculatedStacks []string
|
||||
@@ -1257,7 +1259,7 @@ func determineStackSizes(mod llvm.Module, executable string) ([]string, map[stri
|
||||
}
|
||||
|
||||
// Goroutines need to be started and finished and take up some stack space
|
||||
// that way. This can be measured by measuing the stack size of
|
||||
// that way. This can be measured by measuring the stack size of
|
||||
// tinygo_startTask.
|
||||
if numFuncs := len(functions["tinygo_startTask"]); numFuncs != 1 {
|
||||
return nil, nil, fmt.Errorf("expected exactly one definition of tinygo_startTask, got %d", numFuncs)
|
||||
|
||||
+13
-6
@@ -53,23 +53,30 @@ func TestClangAttributes(t *testing.T) {
|
||||
for _, options := range []*compileopts.Options{
|
||||
{GOOS: "linux", GOARCH: "386"},
|
||||
{GOOS: "linux", GOARCH: "amd64"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "5"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "6"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "7"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "5,softfloat"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "6,softfloat"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "7,softfloat"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "5,hardfloat"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "6,hardfloat"},
|
||||
{GOOS: "linux", GOARCH: "arm", GOARM: "7,hardfloat"},
|
||||
{GOOS: "linux", GOARCH: "arm64"},
|
||||
{GOOS: "linux", GOARCH: "mips"},
|
||||
{GOOS: "linux", GOARCH: "mipsle"},
|
||||
{GOOS: "linux", GOARCH: "mips", GOMIPS: "hardfloat"},
|
||||
{GOOS: "linux", GOARCH: "mipsle", GOMIPS: "hardfloat"},
|
||||
{GOOS: "linux", GOARCH: "mips", GOMIPS: "softfloat"},
|
||||
{GOOS: "linux", GOARCH: "mipsle", GOMIPS: "softfloat"},
|
||||
{GOOS: "darwin", GOARCH: "amd64"},
|
||||
{GOOS: "darwin", GOARCH: "arm64"},
|
||||
{GOOS: "windows", GOARCH: "amd64"},
|
||||
{GOOS: "windows", GOARCH: "arm64"},
|
||||
{GOOS: "wasip1", GOARCH: "wasm"},
|
||||
{GOOS: "wasip2", GOARCH: "wasm"},
|
||||
} {
|
||||
name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH
|
||||
if options.GOARCH == "arm" {
|
||||
name += ",GOARM=" + options.GOARM
|
||||
}
|
||||
if options.GOARCH == "mips" || options.GOARCH == "mipsle" {
|
||||
name += ",GOMIPS=" + options.GOMIPS
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
testClangAttributes(t, options)
|
||||
})
|
||||
|
||||
+41
-7
@@ -3,8 +3,8 @@ package builder
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
)
|
||||
|
||||
@@ -132,6 +132,38 @@ var genericBuiltins = []string{
|
||||
"umodti3.c",
|
||||
}
|
||||
|
||||
// These are the GENERIC_TF_SOURCES as of LLVM 18.
|
||||
// They are not needed on all platforms (32-bit platforms usually don't need
|
||||
// these) but they seem to compile fine so it's easier to include them.
|
||||
var genericBuiltins128 = []string{
|
||||
"addtf3.c",
|
||||
"comparetf2.c",
|
||||
"divtc3.c",
|
||||
"divtf3.c",
|
||||
"extenddftf2.c",
|
||||
"extendhftf2.c",
|
||||
"extendsftf2.c",
|
||||
"fixtfdi.c",
|
||||
"fixtfsi.c",
|
||||
"fixtfti.c",
|
||||
"fixunstfdi.c",
|
||||
"fixunstfsi.c",
|
||||
"fixunstfti.c",
|
||||
"floatditf.c",
|
||||
"floatsitf.c",
|
||||
"floattitf.c",
|
||||
"floatunditf.c",
|
||||
"floatunsitf.c",
|
||||
"floatuntitf.c",
|
||||
"multc3.c",
|
||||
"multf3.c",
|
||||
"powitf2.c",
|
||||
"subtf3.c",
|
||||
"trunctfdf2.c",
|
||||
"trunctfhf2.c",
|
||||
"trunctfsf2.c",
|
||||
}
|
||||
|
||||
var aeabiBuiltins = []string{
|
||||
"arm/aeabi_cdcmp.S",
|
||||
"arm/aeabi_cdcmpeq_check_nan.c",
|
||||
@@ -169,12 +201,12 @@ var avrBuiltins = []string{
|
||||
"avr/udivmodqi4.S",
|
||||
}
|
||||
|
||||
// CompilerRT is a library with symbols required by programs compiled with LLVM.
|
||||
// These symbols are for operations that cannot be emitted with a single
|
||||
// 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.
|
||||
//
|
||||
// For more information, see: https://compiler-rt.llvm.org/
|
||||
var CompilerRT = Library{
|
||||
var libCompilerRT = Library{
|
||||
name: "compiler-rt",
|
||||
cflags: func(target, headerPath string) []string {
|
||||
return []string{"-Werror", "-Wall", "-std=c11", "-nostdlibinc"}
|
||||
@@ -190,11 +222,13 @@ var CompilerRT = Library{
|
||||
},
|
||||
librarySources: func(target string) ([]string, error) {
|
||||
builtins := append([]string{}, genericBuiltins...) // copy genericBuiltins
|
||||
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
|
||||
switch compileopts.CanonicalArchName(target) {
|
||||
case "arm":
|
||||
builtins = append(builtins, aeabiBuiltins...)
|
||||
}
|
||||
if strings.HasPrefix(target, "avr") {
|
||||
case "avr":
|
||||
builtins = append(builtins, avrBuiltins...)
|
||||
case "x86_64", "aarch64", "riscv64": // any 64-bit arch
|
||||
builtins = append(builtins, genericBuiltins128...)
|
||||
}
|
||||
return builtins, nil
|
||||
},
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ struct AssemblerInvocation {
|
||||
EmitDwarfUnwindType EmitDwarfUnwind;
|
||||
|
||||
// Whether to emit compact-unwind for non-canonical entries.
|
||||
// Note: maybe overriden by other constraints.
|
||||
// Note: maybe overridden by other constraints.
|
||||
unsigned EmitCompactUnwindNonCanonical : 1;
|
||||
|
||||
/// The name of the relocation model to use.
|
||||
|
||||
+2
-2
@@ -27,10 +27,10 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if major != 1 || minor < 19 || minor > 22 {
|
||||
if major != 1 || minor < 19 || minor > 23 {
|
||||
// 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.19 through 1.22, got go%d.%d", major, minor)
|
||||
return nil, fmt.Errorf("requires go version 1.19 through 1.23, got go%d.%d", major, minor)
|
||||
}
|
||||
|
||||
return &compileopts.Config{
|
||||
|
||||
+2
-2
@@ -15,12 +15,12 @@ func (e *MultiError) Error() string {
|
||||
|
||||
// newMultiError returns a *MultiError if there is more than one error, or
|
||||
// returns that error directly when there is only one. Passing an empty slice
|
||||
// will lead to a panic.
|
||||
// will return nil (because there is no error).
|
||||
// The importPath may be passed if this error is for a single package.
|
||||
func newMultiError(errs []error, importPath string) error {
|
||||
switch len(errs) {
|
||||
case 0:
|
||||
panic("attempted to create empty MultiError")
|
||||
return nil
|
||||
case 1:
|
||||
return errs[0]
|
||||
default:
|
||||
|
||||
+18
-22
@@ -35,19 +35,6 @@ type Library struct {
|
||||
crt1Source string
|
||||
}
|
||||
|
||||
// Load the library archive, possibly generating and caching it if needed.
|
||||
// The resulting directory may be stored in the provided tmpdir, which is
|
||||
// expected to be removed after the Load call.
|
||||
func (l *Library) Load(config *compileopts.Config, tmpdir string) (dir string, err error) {
|
||||
job, unlock, err := l.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer unlock()
|
||||
err = runJobs(job, config.Options.Semaphore)
|
||||
return filepath.Dir(job.result), err
|
||||
}
|
||||
|
||||
// load returns a compile job to build this library file for the given target
|
||||
// and CPU. It may return a dummy compileJob if the library build is already
|
||||
// cached. The path is stored as job.result but is only valid after the job has
|
||||
@@ -162,29 +149,38 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
|
||||
if config.ABI() != "" {
|
||||
args = append(args, "-mabi="+config.ABI())
|
||||
}
|
||||
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
|
||||
switch compileopts.CanonicalArchName(target) {
|
||||
case "arm":
|
||||
if strings.Split(target, "-")[2] == "linux" {
|
||||
args = append(args, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||
} else {
|
||||
args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(target, "avr") {
|
||||
case "avr":
|
||||
// AVR defaults to C float and double both being 32-bit. This deviates
|
||||
// from what most code (and certainly compiler-rt) expects. So we need
|
||||
// to force the compiler to use 64-bit floating point numbers for
|
||||
// double.
|
||||
args = append(args, "-mdouble=64")
|
||||
}
|
||||
if strings.HasPrefix(target, "riscv32-") {
|
||||
case "riscv32":
|
||||
args = append(args, "-march=rv32imac", "-fforce-enable-int128")
|
||||
}
|
||||
if strings.HasPrefix(target, "riscv64-") {
|
||||
case "riscv64":
|
||||
args = append(args, "-march=rv64gc")
|
||||
}
|
||||
if strings.HasPrefix(target, "mips") {
|
||||
case "mips":
|
||||
args = append(args, "-fno-pic")
|
||||
}
|
||||
if config.Target.SoftFloat {
|
||||
// Use softfloat instead of floating point instructions. This is
|
||||
// supported on many architectures.
|
||||
args = append(args, "-msoft-float")
|
||||
} else {
|
||||
if strings.HasPrefix(target, "armv5") {
|
||||
// On ARMv5 we need to explicitly enable hardware floating point
|
||||
// instructions: Clang appears to assume the hardware doesn't have a
|
||||
// FPU otherwise.
|
||||
args = append(args, "-mfpu=vfpv2")
|
||||
}
|
||||
}
|
||||
|
||||
var once sync.Once
|
||||
|
||||
|
||||
+22
-6
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
)
|
||||
|
||||
var MinGW = Library{
|
||||
var libMinGW = Library{
|
||||
name: "mingw-w64",
|
||||
makeHeaders: func(target, includeDir string) error {
|
||||
// copy _mingw.h
|
||||
@@ -27,14 +27,30 @@ var MinGW = Library{
|
||||
_, err = io.Copy(outf, inf)
|
||||
return err
|
||||
},
|
||||
sourceDir: func() string { return "" }, // unused
|
||||
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64") },
|
||||
cflags: func(target, headerPath string) []string {
|
||||
// No flags necessary because there are no files to compile.
|
||||
return nil
|
||||
mingwDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64")
|
||||
return []string{
|
||||
"-nostdlibinc",
|
||||
"-isystem", mingwDir + "/mingw-w64-headers/crt",
|
||||
"-I", mingwDir + "/mingw-w64-headers/defaults/include",
|
||||
"-I" + headerPath,
|
||||
}
|
||||
},
|
||||
librarySources: func(target string) ([]string, error) {
|
||||
// We only use the UCRT DLL file. No source files necessary.
|
||||
return nil, nil
|
||||
// These files are needed so that printf and the like are supported.
|
||||
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
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
)
|
||||
|
||||
var Musl = Library{
|
||||
var libMusl = Library{
|
||||
name: "musl",
|
||||
makeHeaders: func(target, includeDir string) error {
|
||||
bits := filepath.Join(includeDir, "bits")
|
||||
@@ -92,6 +92,8 @@ var Musl = Library{
|
||||
"-Wno-ignored-pragmas",
|
||||
"-Wno-tautological-constant-out-of-range-compare",
|
||||
"-Wno-deprecated-non-prototype",
|
||||
"-Wno-format",
|
||||
"-Wno-parentheses",
|
||||
"-Qunused-arguments",
|
||||
// Select include dirs. Don't include standard library includes
|
||||
// (that would introduce host dependencies and other complications),
|
||||
@@ -119,11 +121,13 @@ var Musl = Library{
|
||||
"internal/syscall_ret.c",
|
||||
"internal/vdso.c",
|
||||
"legacy/*.c",
|
||||
"locale/*.c",
|
||||
"linux/*.c",
|
||||
"malloc/*.c",
|
||||
"malloc/mallocng/*.c",
|
||||
"mman/*.c",
|
||||
"math/*.c",
|
||||
"multibyte/*.c",
|
||||
"signal/*.c",
|
||||
"stdio/*.c",
|
||||
"string/*.c",
|
||||
|
||||
+3
-2
@@ -8,9 +8,9 @@ import (
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
)
|
||||
|
||||
// Picolibc is a C library for bare metal embedded devices. It was originally
|
||||
// libPicolibc is a C library for bare metal embedded devices. It was originally
|
||||
// based on newlib.
|
||||
var Picolibc = Library{
|
||||
var libPicolibc = Library{
|
||||
name: "picolibc",
|
||||
makeHeaders: func(target, includeDir string) error {
|
||||
f, err := os.Create(filepath.Join(includeDir, "picolibc.h"))
|
||||
@@ -29,6 +29,7 @@ var Picolibc = Library{
|
||||
"-D_HAVE_ALIAS_ATTRIBUTE",
|
||||
"-DTINY_STDIO",
|
||||
"-DPOSIX_IO",
|
||||
"-DFORMAT_DEFAULT_INTEGER", // use __i_vfprintf and __i_vfscanf by default
|
||||
"-D_IEEE_LIBM",
|
||||
"-D__OBSOLETE_MATH_FLOAT=1", // use old math code that doesn't expect a FPU
|
||||
"-D__OBSOLETE_MATH_DOUBLE=0",
|
||||
|
||||
+134
-16
@@ -1,10 +1,15 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/scanner"
|
||||
"go/token"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// runCCompiler invokes a C compiler with the given arguments.
|
||||
@@ -23,22 +28,135 @@ func runCCompiler(flags ...string) error {
|
||||
|
||||
// link invokes a linker with the given name and flags.
|
||||
func link(linker string, flags ...string) error {
|
||||
if hasBuiltinTools && (linker == "ld.lld" || linker == "wasm-ld") {
|
||||
// Run command with internal linker.
|
||||
cmd := exec.Command(os.Args[0], append([]string{linker}, flags...)...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
// We only support LLD.
|
||||
if linker != "ld.lld" && linker != "wasm-ld" {
|
||||
return fmt.Errorf("unexpected: linker %s should be ld.lld or wasm-ld", linker)
|
||||
}
|
||||
|
||||
// Fall back to external command.
|
||||
if _, ok := commands[linker]; ok {
|
||||
return execCommand(linker, flags...)
|
||||
var cmd *exec.Cmd
|
||||
if hasBuiltinTools {
|
||||
cmd = exec.Command(os.Args[0], append([]string{linker}, flags...)...)
|
||||
} else {
|
||||
name, err := LookupCommand(linker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd = exec.Command(name, flags...)
|
||||
}
|
||||
|
||||
cmd := exec.Command(linker, flags...)
|
||||
var buf bytes.Buffer
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Dir = goenv.Get("TINYGOROOT")
|
||||
return cmd.Run()
|
||||
cmd.Stderr = &buf
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
if buf.Len() == 0 {
|
||||
// The linker failed but there was no output.
|
||||
// Therefore, show some output anyway.
|
||||
return fmt.Errorf("failed to run linker: %w", err)
|
||||
}
|
||||
return parseLLDErrors(buf.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Split LLD errors into individual erros (including errors that continue on the
|
||||
// next line, using a ">>>" prefix). If possible, replace the raw errors with a
|
||||
// more user-friendly version (and one that's more in a Go style).
|
||||
func parseLLDErrors(text string) error {
|
||||
// Split linker output in separate error messages.
|
||||
lines := strings.Split(text, "\n")
|
||||
var errorLines []string // one or more line (belonging to a single error) per line
|
||||
for _, line := range lines {
|
||||
line = strings.TrimRight(line, "\r") // needed for Windows
|
||||
if len(errorLines) != 0 && strings.HasPrefix(line, ">>> ") {
|
||||
errorLines[len(errorLines)-1] += "\n" + line
|
||||
continue
|
||||
}
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
errorLines = append(errorLines, line)
|
||||
}
|
||||
|
||||
// Parse error messages.
|
||||
var linkErrors []error
|
||||
var flashOverflow, ramOverflow uint64
|
||||
for _, message := range errorLines {
|
||||
parsedError := false
|
||||
|
||||
// Check for undefined symbols.
|
||||
// This can happen in some cases like with CGo and //go:linkname tricker.
|
||||
if matches := regexp.MustCompile(`^ld.lld: error: undefined symbol: (.*)\n`).FindStringSubmatch(message); matches != nil {
|
||||
symbolName := matches[1]
|
||||
for _, line := range strings.Split(message, "\n") {
|
||||
matches := regexp.MustCompile(`referenced by .* \(((.*):([0-9]+))\)`).FindStringSubmatch(line)
|
||||
if matches != nil {
|
||||
parsedError = true
|
||||
line, _ := strconv.Atoi(matches[3])
|
||||
// TODO: detect common mistakes like -gc=none?
|
||||
linkErrors = append(linkErrors, scanner.Error{
|
||||
Pos: token.Position{
|
||||
Filename: matches[2],
|
||||
Line: line,
|
||||
},
|
||||
Msg: "linker could not find symbol " + symbolName,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for flash/RAM overflow.
|
||||
if matches := regexp.MustCompile(`^ld.lld: error: section '(.*?)' will not fit in region '(.*?)': overflowed by ([0-9]+) bytes$`).FindStringSubmatch(message); matches != nil {
|
||||
region := matches[2]
|
||||
n, err := strconv.ParseUint(matches[3], 10, 64)
|
||||
if err != nil {
|
||||
// Should not happen at all (unless it overflows an uint64 for some reason).
|
||||
continue
|
||||
}
|
||||
|
||||
// Check which area overflowed.
|
||||
// Some chips use differently named memory areas, but these are by
|
||||
// far the most common.
|
||||
switch region {
|
||||
case "FLASH_TEXT":
|
||||
if n > flashOverflow {
|
||||
flashOverflow = n
|
||||
}
|
||||
parsedError = true
|
||||
case "RAM":
|
||||
if n > ramOverflow {
|
||||
ramOverflow = n
|
||||
}
|
||||
parsedError = true
|
||||
}
|
||||
}
|
||||
|
||||
// If we couldn't parse the linker error: show the error as-is to
|
||||
// the user.
|
||||
if !parsedError {
|
||||
linkErrors = append(linkErrors, LinkerError{message})
|
||||
}
|
||||
}
|
||||
|
||||
if flashOverflow > 0 {
|
||||
linkErrors = append(linkErrors, LinkerError{
|
||||
Msg: fmt.Sprintf("program too large for this chip (flash overflowed by %d bytes)\n\toptimization guide: https://tinygo.org/docs/guides/optimizing-binaries/", flashOverflow),
|
||||
})
|
||||
}
|
||||
if ramOverflow > 0 {
|
||||
linkErrors = append(linkErrors, LinkerError{
|
||||
Msg: fmt.Sprintf("program uses too much static RAM on this chip (RAM overflowed by %d bytes)", ramOverflow),
|
||||
})
|
||||
}
|
||||
|
||||
return newMultiError(linkErrors, "")
|
||||
}
|
||||
|
||||
// LLD linker error that could not be parsed or doesn't refer to a source
|
||||
// location.
|
||||
type LinkerError struct {
|
||||
Msg string
|
||||
}
|
||||
|
||||
func (e LinkerError) Error() string {
|
||||
return e.Msg
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
)
|
||||
|
||||
var WasmBuiltins = Library{
|
||||
var libWasmBuiltins = Library{
|
||||
name: "wasmbuiltins",
|
||||
makeHeaders: func(target, includeDir string) error {
|
||||
if err := os.Mkdir(includeDir+"/bits", 0o777); err != nil {
|
||||
|
||||
+24
-5
@@ -60,7 +60,7 @@ func (c *Config) GOOS() string {
|
||||
}
|
||||
|
||||
// GOARCH returns the GOARCH of the target. This might not always be the actual
|
||||
// archtecture: for example, the AVR target is not supported by the Go standard
|
||||
// architecture: for example, the AVR target is not supported by the Go standard
|
||||
// library so such targets will usually pretend to be linux/arm.
|
||||
func (c *Config) GOARCH() string {
|
||||
return c.Target.GOARCH
|
||||
@@ -72,12 +72,19 @@ func (c *Config) GOARM() string {
|
||||
return c.Options.GOARM
|
||||
}
|
||||
|
||||
// GOMIPS will return the GOMIPS environment variable given to the compiler when
|
||||
// building a program.
|
||||
func (c *Config) GOMIPS() string {
|
||||
return c.Options.GOMIPS
|
||||
}
|
||||
|
||||
// BuildTags returns the complete list of build tags used during this build.
|
||||
func (c *Config) BuildTags() []string {
|
||||
tags := append([]string(nil), c.Target.BuildTags...) // copy slice (avoid a race)
|
||||
tags = append(tags, []string{
|
||||
"tinygo", // that's the compiler
|
||||
"purego", // to get various crypto packages to work
|
||||
"osusergo", // to get os/user to work
|
||||
"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
|
||||
@@ -207,10 +214,13 @@ func (c *Config) RP2040BootPatch() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// MuslArchitecture returns the architecture name as used in musl libc. It is
|
||||
// usually the same as the first part of the LLVM triple, but not always.
|
||||
func MuslArchitecture(triple string) string {
|
||||
// Return a canonicalized architecture name, so we don't have to deal with arm*
|
||||
// vs thumb* vs arm64.
|
||||
func CanonicalArchName(triple string) string {
|
||||
arch := strings.Split(triple, "-")[0]
|
||||
if arch == "arm64" {
|
||||
return "aarch64"
|
||||
}
|
||||
if strings.HasPrefix(arch, "arm") || strings.HasPrefix(arch, "thumb") {
|
||||
return "arm"
|
||||
}
|
||||
@@ -220,6 +230,12 @@ func MuslArchitecture(triple string) string {
|
||||
return arch
|
||||
}
|
||||
|
||||
// MuslArchitecture returns the architecture name as used in musl libc. It is
|
||||
// usually the same as the first part of the LLVM triple, but not always.
|
||||
func MuslArchitecture(triple string) string {
|
||||
return CanonicalArchName(triple)
|
||||
}
|
||||
|
||||
// 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).
|
||||
@@ -231,6 +247,9 @@ func (c *Config) LibcPath(name string) (path string, precompiled bool) {
|
||||
if c.ABI() != "" {
|
||||
archname += "-" + c.ABI()
|
||||
}
|
||||
if c.Target.SoftFloat {
|
||||
archname += "-softfloat"
|
||||
}
|
||||
|
||||
// Try to load a precompiled library.
|
||||
precompiledDir := filepath.Join(goenv.Get("TINYGOROOT"), "pkg", archname, name)
|
||||
@@ -443,7 +462,7 @@ func (c *Config) BinaryFormat(ext string) string {
|
||||
|
||||
// Programmer returns the flash method and OpenOCD interface name given a
|
||||
// particular configuration. It may either be all configured in the target JSON
|
||||
// file or be modified using the -programmmer command-line option.
|
||||
// file or be modified using the -programmer command-line option.
|
||||
func (c *Config) Programmer() (method, openocdInterface string) {
|
||||
switch c.Options.Programmer {
|
||||
case "":
|
||||
|
||||
@@ -23,6 +23,7 @@ type Options struct {
|
||||
GOOS string // environment variable
|
||||
GOARCH string // environment variable
|
||||
GOARM string // environment variable (only used with GOARCH=arm)
|
||||
GOMIPS string // environment variable (only used with GOARCH=mips and GOARCH=mipsle)
|
||||
Directory string // working dir, leave it unset to use the current working dir
|
||||
Target string
|
||||
Opt string
|
||||
|
||||
+154
-95
@@ -30,6 +30,7 @@ type TargetSpec struct {
|
||||
Features string `json:"features,omitempty"`
|
||||
GOOS string `json:"goos,omitempty"`
|
||||
GOARCH string `json:"goarch,omitempty"`
|
||||
SoftFloat bool // used for non-baremetal systems (GOMIPS=softfloat etc)
|
||||
BuildTags []string `json:"build-tags,omitempty"`
|
||||
GC string `json:"gc,omitempty"`
|
||||
Scheduler string `json:"scheduler,omitempty"`
|
||||
@@ -86,6 +87,10 @@ func (spec *TargetSpec) overrideProperties(child *TargetSpec) error {
|
||||
if src.Uint() != 0 {
|
||||
dst.Set(src)
|
||||
}
|
||||
case reflect.Bool:
|
||||
if src.Bool() {
|
||||
dst.Set(src)
|
||||
}
|
||||
case reflect.Ptr: // for pointers, copy if not nil
|
||||
if !src.IsNil() {
|
||||
dst.Set(src)
|
||||
@@ -172,63 +177,7 @@ func (spec *TargetSpec) resolveInherits() error {
|
||||
// Load a target specification.
|
||||
func LoadTarget(options *Options) (*TargetSpec, error) {
|
||||
if options.Target == "" {
|
||||
// Configure based on GOOS/GOARCH environment variables (falling back to
|
||||
// runtime.GOOS/runtime.GOARCH), and generate a LLVM target based on it.
|
||||
var llvmarch string
|
||||
switch options.GOARCH {
|
||||
case "386":
|
||||
llvmarch = "i386"
|
||||
case "amd64":
|
||||
llvmarch = "x86_64"
|
||||
case "arm64":
|
||||
llvmarch = "aarch64"
|
||||
case "arm":
|
||||
switch options.GOARM {
|
||||
case "5":
|
||||
llvmarch = "armv5"
|
||||
case "6":
|
||||
llvmarch = "armv6"
|
||||
case "7":
|
||||
llvmarch = "armv7"
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM)
|
||||
}
|
||||
case "mips":
|
||||
llvmarch = "mips"
|
||||
case "mipsle":
|
||||
llvmarch = "mipsel"
|
||||
case "wasm":
|
||||
llvmarch = "wasm32"
|
||||
default:
|
||||
llvmarch = options.GOARCH
|
||||
}
|
||||
llvmvendor := "unknown"
|
||||
llvmos := options.GOOS
|
||||
switch llvmos {
|
||||
case "darwin":
|
||||
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer
|
||||
// to iOS!
|
||||
llvmos = "macosx10.12.0"
|
||||
if llvmarch == "aarch64" {
|
||||
// Looks like Apple prefers to call this architecture ARM64
|
||||
// instead of AArch64.
|
||||
llvmarch = "arm64"
|
||||
llvmos = "macosx11.0.0"
|
||||
}
|
||||
llvmvendor = "apple"
|
||||
case "wasip1":
|
||||
llvmos = "wasi"
|
||||
}
|
||||
// Target triples (which actually have four components, but are called
|
||||
// triples for historical reasons) have the form:
|
||||
// arch-vendor-os-environment
|
||||
target := llvmarch + "-" + llvmvendor + "-" + llvmos
|
||||
if options.GOOS == "windows" {
|
||||
target += "-gnu"
|
||||
} else if options.GOARCH == "arm" {
|
||||
target += "-gnueabihf"
|
||||
}
|
||||
return defaultTarget(options.GOOS, options.GOARCH, target)
|
||||
return defaultTarget(options)
|
||||
}
|
||||
|
||||
// See whether there is a target specification for this target (e.g.
|
||||
@@ -289,14 +238,13 @@ func GetTargetSpecs() (map[string]*TargetSpec, error) {
|
||||
return maps, nil
|
||||
}
|
||||
|
||||
func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
// No target spec available. Use the default one, useful on most systems
|
||||
// with a regular OS.
|
||||
// Load a target from environment variables (which default to
|
||||
// runtime.GOOS/runtime.GOARCH).
|
||||
func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
spec := TargetSpec{
|
||||
Triple: triple,
|
||||
GOOS: goos,
|
||||
GOARCH: goarch,
|
||||
BuildTags: []string{goos, goarch},
|
||||
GOOS: options.GOOS,
|
||||
GOARCH: options.GOARCH,
|
||||
BuildTags: []string{options.GOOS, options.GOARCH},
|
||||
GC: "precise",
|
||||
Scheduler: "tasks",
|
||||
Linker: "cc",
|
||||
@@ -304,38 +252,109 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
GDB: []string{"gdb"},
|
||||
PortReset: "false",
|
||||
}
|
||||
switch goarch {
|
||||
|
||||
// Configure target based on GOARCH.
|
||||
var llvmarch string
|
||||
switch options.GOARCH {
|
||||
case "386":
|
||||
llvmarch = "i386"
|
||||
spec.CPU = "pentium4"
|
||||
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
||||
case "amd64":
|
||||
llvmarch = "x86_64"
|
||||
spec.CPU = "x86-64"
|
||||
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
||||
case "arm":
|
||||
spec.CPU = "generic"
|
||||
spec.CFlags = append(spec.CFlags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||
switch strings.Split(triple, "-")[0] {
|
||||
case "armv5":
|
||||
spec.Features = "+armv5t,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
case "armv6":
|
||||
spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
case "armv7":
|
||||
spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-thumb-mode,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
subarch := strings.Split(options.GOARM, ",")
|
||||
if len(subarch) > 2 {
|
||||
return nil, fmt.Errorf("invalid GOARM=%s, must be of form <num>,[hardfloat|softfloat]", options.GOARM)
|
||||
}
|
||||
archLevel := subarch[0]
|
||||
var fpu string
|
||||
if len(subarch) >= 2 {
|
||||
fpu = subarch[1]
|
||||
} else {
|
||||
// Pick the default fpu value: softfloat for armv5 and hardfloat
|
||||
// above that.
|
||||
if archLevel == "5" {
|
||||
fpu = "softfloat"
|
||||
} else {
|
||||
fpu = "hardfloat"
|
||||
}
|
||||
}
|
||||
switch fpu {
|
||||
case "softfloat":
|
||||
spec.CFlags = append(spec.CFlags, "-msoft-float")
|
||||
spec.SoftFloat = true
|
||||
case "hardfloat":
|
||||
// Hardware floating point support is the default everywhere except
|
||||
// on ARMv5 where it needs to be enabled explicitly.
|
||||
if archLevel == "5" {
|
||||
spec.CFlags = append(spec.CFlags, "-mfpu=vfpv2")
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid extension GOARM=%s, must be softfloat or hardfloat", options.GOARM)
|
||||
}
|
||||
switch archLevel {
|
||||
case "5":
|
||||
llvmarch = "armv5"
|
||||
if spec.SoftFloat {
|
||||
spec.Features = "+armv5t,+soft-float,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
} else {
|
||||
spec.Features = "+armv5t,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
case "6":
|
||||
llvmarch = "armv6"
|
||||
if spec.SoftFloat {
|
||||
spec.Features = "+armv6,+dsp,+soft-float,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
} else {
|
||||
spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
case "7":
|
||||
llvmarch = "armv7"
|
||||
if spec.SoftFloat {
|
||||
spec.Features = "+armv7-a,+dsp,+soft-float,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
} else {
|
||||
spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-thumb-mode,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid GOARM=%s, must be of form <num>,[hardfloat|softfloat] where num is 5, 6, or 7", options.GOARM)
|
||||
}
|
||||
case "arm64":
|
||||
spec.CPU = "generic"
|
||||
if goos == "darwin" {
|
||||
llvmarch = "aarch64"
|
||||
if options.GOOS == "darwin" {
|
||||
spec.Features = "+fp-armv8,+neon"
|
||||
} else if goos == "windows" {
|
||||
// Looks like Apple prefers to call this architecture ARM64
|
||||
// instead of AArch64.
|
||||
llvmarch = "arm64"
|
||||
} else if options.GOOS == "windows" {
|
||||
spec.Features = "+fp-armv8,+neon,-fmv"
|
||||
} else { // linux
|
||||
spec.Features = "+fp-armv8,+neon,-fmv,-outline-atomics"
|
||||
}
|
||||
case "mips", "mipsle":
|
||||
spec.CPU = "mips32r2"
|
||||
spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls"
|
||||
spec.CFlags = append(spec.CFlags, "-fno-pic")
|
||||
if options.GOOS == "mips" {
|
||||
llvmarch = "mips" // big endian
|
||||
} else {
|
||||
llvmarch = "mipsel" // little endian
|
||||
}
|
||||
switch options.GOMIPS {
|
||||
case "hardfloat":
|
||||
spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls"
|
||||
case "softfloat":
|
||||
spec.SoftFloat = true
|
||||
spec.Features = "+mips32r2,+soft-float,-noabicalls"
|
||||
spec.CFlags = append(spec.CFlags, "-msoft-float")
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS)
|
||||
}
|
||||
case "wasm":
|
||||
llvmarch = "wasm32"
|
||||
spec.CPU = "generic"
|
||||
spec.Features = "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext"
|
||||
spec.BuildTags = append(spec.BuildTags, "tinygo.wasm")
|
||||
@@ -344,24 +363,39 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
"-mnontrapping-fptoint",
|
||||
"-msign-ext",
|
||||
)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH)
|
||||
}
|
||||
if goos == "darwin" {
|
||||
|
||||
// Configure target based on GOOS.
|
||||
llvmos := options.GOOS
|
||||
llvmvendor := "unknown"
|
||||
switch options.GOOS {
|
||||
case "darwin":
|
||||
platformVersion := "10.12.0"
|
||||
if options.GOARCH == "arm64" {
|
||||
platformVersion = "11.0.0" // first macosx platform with arm64 support
|
||||
}
|
||||
llvmvendor = "apple"
|
||||
spec.Linker = "ld.lld"
|
||||
spec.Libc = "darwin-libSystem"
|
||||
arch := strings.Split(triple, "-")[0]
|
||||
platformVersion := strings.TrimPrefix(strings.Split(triple, "-")[2], "macosx")
|
||||
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
|
||||
// iOS!
|
||||
llvmos = "macosx" + platformVersion
|
||||
spec.LDFlags = append(spec.LDFlags,
|
||||
"-flavor", "darwin",
|
||||
"-dead_strip",
|
||||
"-arch", arch,
|
||||
"-arch", llvmarch,
|
||||
"-platform_version", "macos", platformVersion, platformVersion,
|
||||
)
|
||||
} else if goos == "linux" {
|
||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||
"src/runtime/runtime_unix.c")
|
||||
case "linux":
|
||||
spec.Linker = "ld.lld"
|
||||
spec.RTLib = "compiler-rt"
|
||||
spec.Libc = "musl"
|
||||
spec.LDFlags = append(spec.LDFlags, "--gc-sections")
|
||||
if goarch == "arm64" {
|
||||
if options.GOARCH == "arm64" {
|
||||
// Disable outline atomics. For details, see:
|
||||
// https://cpufun.substack.com/p/atomics-in-aarch64
|
||||
// A better way would be to fully support outline atomics, which
|
||||
@@ -375,7 +409,9 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
// proper threading.
|
||||
spec.CFlags = append(spec.CFlags, "-mno-outline-atomics")
|
||||
}
|
||||
} else if goos == "windows" {
|
||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||
"src/runtime/runtime_unix.c")
|
||||
case "windows":
|
||||
spec.Linker = "ld.lld"
|
||||
spec.Libc = "mingw-w64"
|
||||
// Note: using a medium code model, low image base and no ASLR
|
||||
@@ -384,7 +420,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
// 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 goarch {
|
||||
switch options.GOARCH {
|
||||
case "amd64":
|
||||
spec.LDFlags = append(spec.LDFlags,
|
||||
"-m", "i386pep",
|
||||
@@ -401,7 +437,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
"--no-insert-timestamp",
|
||||
"--no-dynamicbase",
|
||||
)
|
||||
} else if goos == "wasip1" {
|
||||
case "wasip1":
|
||||
spec.GC = "" // use default GC
|
||||
spec.Scheduler = "asyncify"
|
||||
spec.Linker = "wasm-ld"
|
||||
@@ -417,28 +453,50 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
"src/runtime/asm_tinygowasm.S",
|
||||
"src/internal/task/task_asyncify_wasm.S",
|
||||
)
|
||||
} else {
|
||||
spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie
|
||||
llvmos = "wasi"
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown GOOS=%s", options.GOOS)
|
||||
}
|
||||
if goarch != "wasm" {
|
||||
|
||||
// Target triples (which actually have four components, but are called
|
||||
// triples for historical reasons) have the form:
|
||||
// arch-vendor-os-environment
|
||||
spec.Triple = llvmarch + "-" + llvmvendor + "-" + llvmos
|
||||
if options.GOOS == "windows" {
|
||||
spec.Triple += "-gnu"
|
||||
} else if options.GOOS == "linux" {
|
||||
// We use musl on Linux (not glibc) so we should use -musleabi* instead
|
||||
// of -gnueabi*.
|
||||
// The *hf suffix selects between soft/hard floating point ABI.
|
||||
if spec.SoftFloat {
|
||||
spec.Triple += "-musleabi"
|
||||
} else {
|
||||
spec.Triple += "-musleabihf"
|
||||
}
|
||||
}
|
||||
|
||||
// Add extra assembly files (needed for the scheduler etc).
|
||||
if options.GOARCH != "wasm" {
|
||||
suffix := ""
|
||||
if goos == "windows" && goarch == "amd64" {
|
||||
if options.GOOS == "windows" && options.GOARCH == "amd64" {
|
||||
// Windows uses a different calling convention on amd64 from other
|
||||
// operating systems so we need separate assembly files.
|
||||
suffix = "_windows"
|
||||
}
|
||||
asmGoarch := goarch
|
||||
if goarch == "mips" || goarch == "mipsle" {
|
||||
asmGoarch := options.GOARCH
|
||||
if options.GOARCH == "mips" || options.GOARCH == "mipsle" {
|
||||
asmGoarch = "mipsx"
|
||||
}
|
||||
spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/asm_"+asmGoarch+suffix+".S")
|
||||
spec.ExtraFiles = append(spec.ExtraFiles, "src/internal/task/task_stack_"+asmGoarch+suffix+".S")
|
||||
}
|
||||
if goarch != runtime.GOARCH {
|
||||
|
||||
// Configure the emulator.
|
||||
if options.GOARCH != runtime.GOARCH {
|
||||
// Some educated guesses as to how to invoke helper programs.
|
||||
spec.GDB = []string{"gdb-multiarch"}
|
||||
if goos == "linux" {
|
||||
switch goarch {
|
||||
if options.GOOS == "linux" {
|
||||
switch options.GOARCH {
|
||||
case "386":
|
||||
// amd64 can _usually_ run 32-bit programs, so skip the emulator in that case.
|
||||
if runtime.GOARCH != "amd64" {
|
||||
@@ -457,11 +515,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if goos != runtime.GOOS {
|
||||
if goos == "windows" {
|
||||
if options.GOOS != runtime.GOOS {
|
||||
if options.GOOS == "windows" {
|
||||
spec.Emulator = "wine {}"
|
||||
}
|
||||
}
|
||||
|
||||
return &spec, nil
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ func (b *builder) createUnsafeSliceStringCheck(name string, ptr, len llvm.Value,
|
||||
// However, in practice, it is also necessary to check that the length is
|
||||
// not too big that a GEP wouldn't be possible without wrapping the pointer.
|
||||
// These two checks (non-negative and not too big) can be merged into one
|
||||
// using an unsiged greater than.
|
||||
// using an unsigned greater than.
|
||||
|
||||
// Make sure the len value is at least as big as a uintptr.
|
||||
len = b.extendInteger(len, lenType, b.uintptrType)
|
||||
|
||||
@@ -15,6 +15,16 @@ func (b *builder) createAtomicOp(name string) llvm.Value {
|
||||
oldVal := b.CreateAtomicRMW(llvm.AtomicRMWBinOpAdd, ptr, val, llvm.AtomicOrderingSequentiallyConsistent, true)
|
||||
// Return the new value, not the original value returned by atomicrmw.
|
||||
return b.CreateAdd(oldVal, val, "")
|
||||
case "AndInt32", "AndInt64", "AndUint32", "AndUint64", "AndUintptr":
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
oldVal := b.CreateAtomicRMW(llvm.AtomicRMWBinOpAnd, ptr, val, llvm.AtomicOrderingSequentiallyConsistent, true)
|
||||
return oldVal
|
||||
case "OrInt32", "OrInt64", "OrUint32", "OrUint64", "OrUintptr":
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
oldVal := b.CreateAtomicRMW(llvm.AtomicRMWBinOpOr, ptr, val, llvm.AtomicOrderingSequentiallyConsistent, true)
|
||||
return oldVal
|
||||
case "SwapInt32", "SwapInt64", "SwapUint32", "SwapUint64", "SwapUintptr", "SwapPointer":
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
|
||||
@@ -242,7 +242,7 @@ func NewTargetMachine(config *Config) (llvm.TargetMachine, error) {
|
||||
}
|
||||
|
||||
// Sizes returns a types.Sizes appropriate for the given target machine. It
|
||||
// includes the correct int size and aligment as is necessary for the Go
|
||||
// includes the correct int size and alignment as is necessary for the Go
|
||||
// typechecker.
|
||||
func Sizes(machine llvm.TargetMachine) types.Sizes {
|
||||
targetData := machine.CreateTargetData()
|
||||
@@ -1963,7 +1963,7 @@ func (b *builder) getValue(expr ssa.Value, pos token.Pos) llvm.Value {
|
||||
return value
|
||||
} else {
|
||||
// indicates a compiler bug
|
||||
panic("local has not been parsed: " + expr.String())
|
||||
panic("SSA value not previously found in function: " + expr.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ func (b *builder) trackValue(value llvm.Value) {
|
||||
}
|
||||
}
|
||||
|
||||
// trackPointer creates a call to runtime.trackPointer, bitcasting the poitner
|
||||
// trackPointer creates a call to runtime.trackPointer, bitcasting the pointer
|
||||
// first if needed. The input value must be of LLVM pointer type.
|
||||
func (b *builder) trackPointer(value llvm.Value) {
|
||||
b.createRuntimeCall("trackPointer", []llvm.Value{value, b.stackChainAlloca}, "")
|
||||
|
||||
@@ -86,7 +86,7 @@ func (b *builder) createMakeInterface(val llvm.Value, typ types.Type, pos token.
|
||||
|
||||
// extractValueFromInterface extract the value from an interface value
|
||||
// (runtime._interface) under the assumption that it is of the type given in
|
||||
// llvmType. The behavior is undefied if the interface is nil or llvmType
|
||||
// llvmType. The behavior is undefined if the interface is nil or llvmType
|
||||
// doesn't match the underlying type of the interface.
|
||||
func (b *builder) extractValueFromInterface(itf llvm.Value, llvmType llvm.Type) llvm.Value {
|
||||
valuePtr := b.CreateExtractValue(itf, 1, "typeassert.value.ptr")
|
||||
|
||||
+3
-12
@@ -7,6 +7,7 @@ import (
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
@@ -418,21 +419,11 @@ func (c *compilerContext) getPointerBitmap(typ llvm.Type, pos token.Pos) *big.In
|
||||
}
|
||||
}
|
||||
|
||||
// archFamily returns the archtecture from the LLVM triple but with some
|
||||
// archFamily returns the architecture from the LLVM triple but with some
|
||||
// architecture names ("armv6", "thumbv7m", etc) merged into a single
|
||||
// architecture name ("arm").
|
||||
func (c *compilerContext) archFamily() string {
|
||||
arch := strings.Split(c.Triple, "-")[0]
|
||||
if strings.HasPrefix(arch, "arm64") {
|
||||
return "aarch64"
|
||||
}
|
||||
if strings.HasPrefix(arch, "arm") || strings.HasPrefix(arch, "thumb") {
|
||||
return "arm"
|
||||
}
|
||||
if arch == "mipsel" {
|
||||
return "mips"
|
||||
}
|
||||
return arch
|
||||
return compileopts.CanonicalArchName(c.Triple)
|
||||
}
|
||||
|
||||
// isThumb returns whether we're in ARM or in Thumb mode. It panics if the
|
||||
|
||||
@@ -207,7 +207,7 @@ func AppendToGlobal(mod llvm.Module, globalName string, values ...llvm.Value) {
|
||||
used.SetLinkage(llvm.AppendingLinkage)
|
||||
}
|
||||
|
||||
// Return the LLVM major version.
|
||||
// Version returns the LLVM major version.
|
||||
func Version() int {
|
||||
majorStr := strings.Split(llvm.Version, ".")[0]
|
||||
major, err := strconv.Atoi(majorStr)
|
||||
|
||||
+1
-1
@@ -326,7 +326,7 @@ func (b *builder) zeroUndefBytes(llvmType llvm.Type, ptr llvm.Value) error {
|
||||
if i < numFields-1 {
|
||||
nextOffset = b.targetData.ElementOffset(llvmStructType, i+1)
|
||||
} else {
|
||||
// Last field? Next offset is the total size of the allcoate struct.
|
||||
// Last field? Next offset is the total size of the allocate struct.
|
||||
nextOffset = b.targetData.TypeAllocSize(llvmStructType)
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -139,6 +139,8 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
// On *nix systems, the "abort" functuion in libc is used to handle fatal panics.
|
||||
// Mark it as noreturn so LLVM can optimize away code.
|
||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
|
||||
case "internal/abi.NoEscape":
|
||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||
case "runtime.alloc":
|
||||
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
|
||||
// returns values that are never null and never alias to an existing value.
|
||||
@@ -216,7 +218,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
||||
// should be created right away.
|
||||
// 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" {
|
||||
if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" {
|
||||
irbuilder := c.ctx.NewBuilder()
|
||||
b := newBuilder(c, irbuilder, fn)
|
||||
b.createFunction()
|
||||
@@ -353,7 +355,7 @@ func (c *compilerContext) checkWasmImport(f *ssa.Function, pragma string) {
|
||||
}
|
||||
if f.Blocks != nil {
|
||||
// Defined functions cannot be exported.
|
||||
c.addError(f.Pos(), fmt.Sprintf("can only use //go:wasmimport on declarations"))
|
||||
c.addError(f.Pos(), "can only use //go:wasmimport on declarations")
|
||||
return
|
||||
}
|
||||
if f.Signature.Results().Len() > 1 {
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
||||
// Also useful:
|
||||
// https://web.archive.org/web/20220529105937/https://www.linux-mips.org/wiki/Syscall
|
||||
// The syscall number goes in r2, the result also in r2.
|
||||
// Register r7 is both an input paramter and an output parameter: if it
|
||||
// Register r7 is both an input parameter and an output parameter: if it
|
||||
// is non-zero, the system call failed and r2 is the error code.
|
||||
// The code below implements the O32 syscall ABI, not the N32 ABI. It
|
||||
// could implement both at the same time if needed (like what appears to
|
||||
|
||||
@@ -43,7 +43,7 @@ func CreateDiagnostics(err error) ProgramDiagnostic {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
// Right now, the compiler will only show errors for the first pacakge that
|
||||
// Right now, the compiler will only show errors for the first package that
|
||||
// fails to build. This is likely to change in the future.
|
||||
return ProgramDiagnostic{
|
||||
createPackageDiagnostic(err),
|
||||
@@ -147,7 +147,7 @@ func createDiagnostics(err error) []Diagnostic {
|
||||
// last package
|
||||
fmt.Fprintln(buf, "\timports", pkgPath+": "+err.Err.Error())
|
||||
} else {
|
||||
// not the last pacakge
|
||||
// not the last package
|
||||
fmt.Fprintln(buf, "\timports", pkgPath)
|
||||
}
|
||||
}
|
||||
|
||||
+38
-22
@@ -7,7 +7,6 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/diagnostics"
|
||||
@@ -15,38 +14,55 @@ import (
|
||||
|
||||
// Test the error messages of the TinyGo compiler.
|
||||
func TestErrors(t *testing.T) {
|
||||
for _, name := range []string{
|
||||
"cgo",
|
||||
"compiler",
|
||||
"interp",
|
||||
"loader-importcycle",
|
||||
"loader-invaliddep",
|
||||
"loader-invalidpackage",
|
||||
"loader-nopackage",
|
||||
"optimizer",
|
||||
"syntax",
|
||||
"types",
|
||||
// TODO: nicely formatted error messages for:
|
||||
// - duplicate symbols in ld.lld (currently only prints bitcode file)
|
||||
type errorTest struct {
|
||||
name string
|
||||
target string
|
||||
}
|
||||
for _, tc := range []errorTest{
|
||||
{name: "cgo"},
|
||||
{name: "compiler"},
|
||||
{name: "interp"},
|
||||
{name: "linker-flashoverflow", target: "cortex-m-qemu"},
|
||||
{name: "linker-ramoverflow", target: "cortex-m-qemu"},
|
||||
{name: "linker-undefined", target: "darwin/arm64"},
|
||||
{name: "linker-undefined", target: "linux/amd64"},
|
||||
//{name: "linker-undefined", target: "windows/amd64"}, // TODO: no source location
|
||||
{name: "linker-undefined", target: "cortex-m-qemu"},
|
||||
//{name: "linker-undefined", target: "wasip1"}, // TODO: no source location
|
||||
{name: "loader-importcycle"},
|
||||
{name: "loader-invaliddep"},
|
||||
{name: "loader-invalidpackage"},
|
||||
{name: "loader-nopackage"},
|
||||
{name: "optimizer"},
|
||||
{name: "syntax"},
|
||||
{name: "types"},
|
||||
} {
|
||||
name := tc.name
|
||||
if tc.target != "" {
|
||||
name += "#" + tc.target
|
||||
}
|
||||
target := tc.target
|
||||
if target == "" {
|
||||
target = "wasip1"
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
testErrorMessages(t, "./testdata/errors/"+name+".go")
|
||||
options := optionsFromTarget(target, sema)
|
||||
testErrorMessages(t, "./testdata/errors/"+tc.name+".go", &options)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testErrorMessages(t *testing.T, filename string) {
|
||||
func testErrorMessages(t *testing.T, filename string, options *compileopts.Options) {
|
||||
t.Parallel()
|
||||
|
||||
// Parse expected error messages.
|
||||
expected := readErrorMessages(t, filename)
|
||||
|
||||
// Try to build a binary (this should fail with an error).
|
||||
tmpdir := t.TempDir()
|
||||
err := Build(filename, tmpdir+"/out", &compileopts.Options{
|
||||
Target: "wasip1",
|
||||
Semaphore: sema,
|
||||
InterpTimeout: 180 * time.Second,
|
||||
Debug: true,
|
||||
VerifyIR: true,
|
||||
Opt: "z",
|
||||
})
|
||||
err := Build(filename, tmpdir+"/out", options)
|
||||
if err == nil {
|
||||
t.Fatal("expected to get a compiler error")
|
||||
}
|
||||
|
||||
@@ -7,14 +7,12 @@ require (
|
||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee
|
||||
github.com/chromedp/chromedp v0.7.6
|
||||
github.com/client9/misspell v0.3.4
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
|
||||
github.com/mattn/go-colorable v0.1.13
|
||||
github.com/mattn/go-tty v0.0.4
|
||||
github.com/mgechev/revive v1.3.7
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
|
||||
go.bug.st/serial v1.6.0
|
||||
golang.org/x/net v0.26.0
|
||||
@@ -25,23 +23,14 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/chavacava/garif v0.1.0 // indirect
|
||||
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||
github.com/creack/goselect v0.1.2 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c h1:4T0Vj1UkGgcpkRrmn7SbokebnlfxJcMZPgWtOYACAAA=
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c/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/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc=
|
||||
github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww=
|
||||
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee h1:+SFdIVfQpG0s0DHYzou0kgfE0n0ZjKPwbiRJsXrZegU=
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
@@ -13,17 +9,10 @@ github.com/chromedp/chromedp v0.7.6 h1:2juGaktzjwULlsn+DnvIZXFUckEp5xs+GOBroaea+
|
||||
github.com/chromedp/chromedp v0.7.6/go.mod h1:ayT4YU/MGAALNfOg9gNrpGSAdnU51PMx+FCeuT1iXzo=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
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.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
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=
|
||||
@@ -51,41 +40,24 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
|
||||
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0=
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
||||
github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE=
|
||||
github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
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.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
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/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -103,7 +75,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
||||
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.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240627184919-3b50c76783a8 h1:bLsZXRUBavt++CJlMN7sppNziqu3LyamESLhFJcpqFQ=
|
||||
|
||||
+11
-1
@@ -30,8 +30,11 @@ var Keys = []string{
|
||||
}
|
||||
|
||||
func init() {
|
||||
if Get("GOARCH") == "arm" {
|
||||
switch Get("GOARCH") {
|
||||
case "arm":
|
||||
Keys = append(Keys, "GOARM")
|
||||
case "mips", "mipsle":
|
||||
Keys = append(Keys, "GOMIPS")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +131,13 @@ func Get(name string) string {
|
||||
// difference between ARMv6 and ARMv7. ARMv6 binaries are much smaller,
|
||||
// especially when floating point instructions are involved.
|
||||
return "6"
|
||||
case "GOMIPS":
|
||||
gomips := os.Getenv("GOMIPS")
|
||||
if gomips == "" {
|
||||
// Default to hardfloat (this matches the Go toolchain).
|
||||
gomips = "hardfloat"
|
||||
}
|
||||
return gomips
|
||||
case "GOROOT":
|
||||
readGoEnvVars()
|
||||
return goEnvVars.GOROOT
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
// Version of TinyGo.
|
||||
// Update this value before release of new version of software.
|
||||
const version = "0.33.0-dev"
|
||||
const version = "0.33.0"
|
||||
|
||||
var (
|
||||
// This variable is set at build time using -ldflags parameters.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// TODO: remove this (by merging it into the top-level go.mod)
|
||||
// once the top level go.mod specifies a go new enough to make our version of misspell happy.
|
||||
|
||||
module tools
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/golangci/misspell v0.6.0
|
||||
github.com/mgechev/revive v1.3.9
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/chavacava/garif v0.1.0 // indirect
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
)
|
||||
@@ -0,0 +1,56 @@
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc=
|
||||
github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
|
||||
github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
|
||||
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
|
||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0=
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
||||
github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A=
|
||||
github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
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=
|
||||
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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
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=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -5,9 +5,9 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
_ "github.com/client9/misspell"
|
||||
_ "github.com/golangci/misspell"
|
||||
_ "github.com/mgechev/revive"
|
||||
)
|
||||
|
||||
//go:generate go install github.com/client9/misspell/cmd/misspell
|
||||
//go:generate go install github.com/golangci/misspell/cmd/misspell
|
||||
//go:generate go install github.com/mgechev/revive
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ All in all, this design provides several benefits:
|
||||
it should be a whole lot faster for loops as it doesn't have to call into
|
||||
LLVM (via CGo) for every operation.
|
||||
|
||||
As mentioned, this partial evaulator comes in three parts: a compiler, an
|
||||
As mentioned, this partial evaluator comes in three parts: a compiler, an
|
||||
interpreter, and a memory manager.
|
||||
|
||||
## Compiler
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ func newRunner(mod llvm.Module, timeout time.Duration, debug bool) *runner {
|
||||
return &r
|
||||
}
|
||||
|
||||
// Dispose deallocates all alloated LLVM resources.
|
||||
// Dispose deallocates all allocated LLVM resources.
|
||||
func (r *runner) dispose() {
|
||||
r.targetData.Dispose()
|
||||
r.targetData = llvm.TargetData{}
|
||||
|
||||
+1
-1
Submodule lib/macos-minimal-sdk updated: ebb736fda2...91ac2eabd8
+2
-1
@@ -236,6 +236,7 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
|
||||
"device/": false,
|
||||
"examples/": false,
|
||||
"internal/": true,
|
||||
"internal/abi/": false,
|
||||
"internal/binary/": false,
|
||||
"internal/bytealg/": false,
|
||||
"internal/cm/": false,
|
||||
@@ -247,11 +248,11 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
|
||||
"net/": true,
|
||||
"net/http/": false,
|
||||
"os/": true,
|
||||
"os/user/": false,
|
||||
"reflect/": false,
|
||||
"runtime/": false,
|
||||
"sync/": true,
|
||||
"testing/": true,
|
||||
"unique/": false,
|
||||
}
|
||||
|
||||
if goMinor >= 19 {
|
||||
|
||||
+1
-1
@@ -180,7 +180,7 @@ func Load(config *compileopts.Config, inputPkg string, typeChecker types.Config)
|
||||
if len(fields) >= 2 {
|
||||
// There is some file/line/column information.
|
||||
if n, err := strconv.Atoi(fields[len(fields)-2]); err == nil {
|
||||
// Format: filename.go:line:colum
|
||||
// Format: filename.go:line:column
|
||||
pos.Filename = strings.Join(fields[:len(fields)-2], ":")
|
||||
pos.Line = n
|
||||
pos.Column, _ = strconv.Atoi(fields[len(fields)-1])
|
||||
|
||||
@@ -808,7 +808,7 @@ func Run(pkgName string, options *compileopts.Options, cmdArgs []string) error {
|
||||
|
||||
// buildAndRun builds and runs the given program, writing output to stdout and
|
||||
// errors to os.Stderr. It takes care of emulators (qemu, wasmtime, etc) and
|
||||
// passes command line arguments and evironment variables in a way appropriate
|
||||
// passes command line arguments and environment variables in a way appropriate
|
||||
// for the given emulator.
|
||||
func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, cmdArgs, environmentVars []string, timeout time.Duration, run func(cmd *exec.Cmd, result builder.BuildResult) error) (builder.BuildResult, error) {
|
||||
|
||||
@@ -936,7 +936,7 @@ func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, c
|
||||
|
||||
// Configure stdout/stderr. The stdout may go to a buffer, not a real
|
||||
// stdout.
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stdout = newOutputWriter(stdout, result.Executable)
|
||||
cmd.Stderr = os.Stderr
|
||||
if config.EmulatorName() == "simavr" {
|
||||
cmd.Stdout = nil // don't print initial load commands
|
||||
@@ -958,7 +958,7 @@ func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, c
|
||||
err = run(cmd, result)
|
||||
if err != nil {
|
||||
if ctx != nil && ctx.Err() == context.DeadlineExceeded {
|
||||
stdout.Write([]byte(fmt.Sprintf("--- timeout of %s exceeded, terminating...\n", timeout)))
|
||||
fmt.Fprintf(stdout, "--- timeout of %s exceeded, terminating...\n", timeout)
|
||||
err = ctx.Err()
|
||||
}
|
||||
return result, &commandError{"failed to run compiled binary", result.Binary, err}
|
||||
@@ -1437,7 +1437,7 @@ func main() {
|
||||
flag.BoolVar(&flagTest, "test", false, "supply -test flag to go list")
|
||||
}
|
||||
var outpath string
|
||||
if command == "help" || command == "build" || command == "build-library" || command == "test" {
|
||||
if command == "help" || command == "build" || command == "test" {
|
||||
flag.StringVar(&outpath, "o", "", "output filename")
|
||||
}
|
||||
|
||||
@@ -1467,7 +1467,8 @@ func main() {
|
||||
case "clang", "ld.lld", "wasm-ld":
|
||||
err := builder.RunTool(command, os.Args[2:]...)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
// The tool should have printed an error message already.
|
||||
// Don't print another error message here.
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
@@ -1498,6 +1499,7 @@ func main() {
|
||||
GOOS: goenv.Get("GOOS"),
|
||||
GOARCH: goenv.Get("GOARCH"),
|
||||
GOARM: goenv.Get("GOARM"),
|
||||
GOMIPS: goenv.Get("GOMIPS"),
|
||||
Target: *target,
|
||||
StackSize: stackSize,
|
||||
Opt: *opt,
|
||||
@@ -1570,50 +1572,6 @@ func main() {
|
||||
|
||||
err := Build(pkgName, outpath, options)
|
||||
handleCompilerError(err)
|
||||
case "build-library":
|
||||
// Note: this command is only meant to be used while making a release!
|
||||
if outpath == "" {
|
||||
fmt.Fprintln(os.Stderr, "No output filename supplied (-o).")
|
||||
usage(command)
|
||||
os.Exit(1)
|
||||
}
|
||||
if *target == "" {
|
||||
fmt.Fprintln(os.Stderr, "No target (-target).")
|
||||
}
|
||||
if flag.NArg() != 1 {
|
||||
fmt.Fprintf(os.Stderr, "Build-library only accepts exactly one library name as argument, %d given\n", flag.NArg())
|
||||
usage(command)
|
||||
os.Exit(1)
|
||||
}
|
||||
var lib *builder.Library
|
||||
switch name := flag.Arg(0); name {
|
||||
case "compiler-rt":
|
||||
lib = &builder.CompilerRT
|
||||
case "picolibc":
|
||||
lib = &builder.Picolibc
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unknown library: %s\n", name)
|
||||
os.Exit(1)
|
||||
}
|
||||
tmpdir, err := os.MkdirTemp("", "tinygo*")
|
||||
if err != nil {
|
||||
handleCompilerError(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
spec, err := compileopts.LoadTarget(options)
|
||||
if err != nil {
|
||||
handleCompilerError(err)
|
||||
}
|
||||
config := &compileopts.Config{
|
||||
Options: options,
|
||||
Target: spec,
|
||||
}
|
||||
path, err := lib.Load(config, tmpdir)
|
||||
handleCompilerError(err)
|
||||
err = copyFile(path, outpath)
|
||||
if err != nil {
|
||||
handleCompilerError(err)
|
||||
}
|
||||
case "flash", "gdb", "lldb":
|
||||
pkgName := filepath.ToSlash(flag.Arg(0))
|
||||
if command == "flash" {
|
||||
@@ -1673,7 +1631,7 @@ func main() {
|
||||
for i := range bufs {
|
||||
err := bufs[i].flush(os.Stdout, os.Stderr)
|
||||
if err != nil {
|
||||
// There was an error writing to stdout or stderr, so we probbably cannot print this.
|
||||
// There was an error writing to stdout or stderr, so we probably cannot print this.
|
||||
select {
|
||||
case fail <- struct{}{}:
|
||||
default:
|
||||
@@ -1780,6 +1738,7 @@ func main() {
|
||||
GOOS string `json:"goos"`
|
||||
GOARCH string `json:"goarch"`
|
||||
GOARM string `json:"goarm"`
|
||||
GOMIPS string `json:"gomips"`
|
||||
BuildTags []string `json:"build_tags"`
|
||||
GC string `json:"garbage_collector"`
|
||||
Scheduler string `json:"scheduler"`
|
||||
@@ -1790,6 +1749,7 @@ func main() {
|
||||
GOOS: config.GOOS(),
|
||||
GOARCH: config.GOARCH(),
|
||||
GOARM: config.GOARM(),
|
||||
GOMIPS: config.GOMIPS(),
|
||||
BuildTags: config.BuildTags(),
|
||||
GC: config.GC(),
|
||||
Scheduler: config.Scheduler(),
|
||||
|
||||
+17
-5
@@ -8,7 +8,6 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -37,7 +36,7 @@ var supportedLinuxArches = map[string]string{
|
||||
"X86Linux": "linux/386",
|
||||
"ARMLinux": "linux/arm/6",
|
||||
"ARM64Linux": "linux/arm64",
|
||||
"MIPSLinux": "linux/mipsle",
|
||||
"MIPSLinux": "linux/mipsle/hardfloat",
|
||||
"WASIp1": "wasip1/wasm",
|
||||
}
|
||||
|
||||
@@ -98,6 +97,9 @@ func TestBuild(t *testing.T) {
|
||||
if minor >= 22 {
|
||||
tests = append(tests, "go1.22/")
|
||||
}
|
||||
if minor >= 23 {
|
||||
tests = append(tests, "go1.23/")
|
||||
}
|
||||
|
||||
if *testTarget != "" {
|
||||
// This makes it possible to run one specific test (instead of all),
|
||||
@@ -213,7 +215,7 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
}
|
||||
}
|
||||
if options.GOOS == "linux" && (options.GOARCH == "mips" || options.GOARCH == "mipsle") {
|
||||
if name == "atomic.go" {
|
||||
if name == "atomic.go" || name == "timers.go" {
|
||||
// 64-bit atomic operations aren't currently supported on MIPS.
|
||||
continue
|
||||
}
|
||||
@@ -244,6 +246,11 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
// some compiler changes).
|
||||
continue
|
||||
|
||||
case "timers.go":
|
||||
// Crashes starting with Go 1.23.
|
||||
// Bug: https://github.com/llvm/llvm-project/issues/104032
|
||||
continue
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
@@ -326,6 +333,7 @@ func optionsFromTarget(target string, sema chan struct{}) compileopts.Options {
|
||||
GOOS: goenv.Get("GOOS"),
|
||||
GOARCH: goenv.Get("GOARCH"),
|
||||
GOARM: goenv.Get("GOARM"),
|
||||
GOMIPS: goenv.Get("GOMIPS"),
|
||||
Target: target,
|
||||
Semaphore: sema,
|
||||
InterpTimeout: 180 * time.Second,
|
||||
@@ -349,8 +357,11 @@ func optionsFromOSARCH(osarch string, sema chan struct{}) compileopts.Options {
|
||||
VerifyIR: true,
|
||||
Opt: "z",
|
||||
}
|
||||
if options.GOARCH == "arm" {
|
||||
switch options.GOARCH {
|
||||
case "arm":
|
||||
options.GOARM = parts[2]
|
||||
case "mips", "mipsle":
|
||||
options.GOMIPS = parts[2]
|
||||
}
|
||||
return options
|
||||
}
|
||||
@@ -696,7 +707,8 @@ func TestMain(m *testing.M) {
|
||||
// Invoke a specific tool.
|
||||
err := builder.RunTool(os.Args[1], os.Args[2:]...)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
// The tool should have printed an error message already.
|
||||
// Don't print another error message here.
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
acces,access
|
||||
acuire,acquire
|
||||
addess,address
|
||||
adust,adjust
|
||||
allcoate,allocate
|
||||
alloated,allocated
|
||||
archtecture,architecture
|
||||
arcive,archive
|
||||
ardiuno,arduino
|
||||
beconfigured,be configured
|
||||
calcluate,calculate
|
||||
colum,column
|
||||
configration,configuration
|
||||
contants,constants
|
||||
cricital,critical
|
||||
deffered,deferred
|
||||
evaulator,evaluator
|
||||
evironment,environment
|
||||
freqency,frequency
|
||||
frquency,frequency
|
||||
implmented,implemented
|
||||
interrput,interrupt
|
||||
interrut,interrupt
|
||||
interupt,interrupt
|
||||
measuing,measuring
|
||||
numer of,number of
|
||||
orignal,original
|
||||
overrided,overridden
|
||||
poiners,pointers
|
||||
poitner,pointer
|
||||
probbably,probably
|
||||
recogized,recognized
|
||||
refection,reflection
|
||||
requries,requires
|
||||
satisifying,satisfying
|
||||
simulataneously,simultaneously
|
||||
suggets,suggests
|
||||
transmition,transmission
|
||||
undefied,undefined
|
||||
unecessary,unnecessary
|
||||
unsiged,unsigned
|
||||
|
+41
-19
@@ -197,31 +197,14 @@ func Monitor(executable, port string, config *compileopts.Config) error {
|
||||
|
||||
go func() {
|
||||
buf := make([]byte, 100*1024)
|
||||
var line []byte
|
||||
writer := newOutputWriter(os.Stdout, executable)
|
||||
for {
|
||||
n, err := serialConn.Read(buf)
|
||||
if err != nil {
|
||||
errCh <- fmt.Errorf("read error: %w", err)
|
||||
return
|
||||
}
|
||||
start := 0
|
||||
for i, c := range buf[:n] {
|
||||
if c == '\n' {
|
||||
os.Stdout.Write(buf[start : i+1])
|
||||
start = i + 1
|
||||
address := extractPanicAddress(line)
|
||||
if address != 0 {
|
||||
loc, err := addressToLine(executable, address)
|
||||
if err == nil && loc.IsValid() {
|
||||
fmt.Printf("[tinygo: panic at %s]\n", loc.String())
|
||||
}
|
||||
}
|
||||
line = line[:0]
|
||||
} else {
|
||||
line = append(line, c)
|
||||
}
|
||||
}
|
||||
os.Stdout.Write(buf[start:n])
|
||||
writer.Write(buf[:n])
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -400,3 +383,42 @@ func readDWARF(executable string) (*dwarf.Data, error) {
|
||||
return nil, errors.New("unknown binary format")
|
||||
}
|
||||
}
|
||||
|
||||
type outputWriter struct {
|
||||
out io.Writer
|
||||
executable string
|
||||
line []byte
|
||||
}
|
||||
|
||||
// newOutputWriter returns an io.Writer that will intercept panic addresses and
|
||||
// will try to insert a source location in the output if the source location can
|
||||
// be found in the executable.
|
||||
func newOutputWriter(out io.Writer, executable string) *outputWriter {
|
||||
return &outputWriter{
|
||||
out: out,
|
||||
executable: executable,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *outputWriter) Write(p []byte) (n int, err error) {
|
||||
start := 0
|
||||
for i, c := range p {
|
||||
if c == '\n' {
|
||||
w.out.Write(p[start : i+1])
|
||||
start = i + 1
|
||||
address := extractPanicAddress(w.line)
|
||||
if address != 0 {
|
||||
loc, err := addressToLine(w.executable, address)
|
||||
if err == nil && loc.Filename != "" {
|
||||
fmt.Printf("[tinygo: panic at %s]\n", loc.String())
|
||||
}
|
||||
}
|
||||
w.line = w.line[:0]
|
||||
} else {
|
||||
w.line = append(w.line, c)
|
||||
}
|
||||
}
|
||||
w.out.Write(p[start:])
|
||||
n = len(p)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// This implementation of crypto/rand uses the arc4random_buf function
|
||||
// (available on both MacOS and WASI) to generate random numbers.
|
||||
//
|
||||
// Note: arc4random_buf (unlike what the name suggets) does not use the insecure
|
||||
// Note: arc4random_buf (unlike what the name suggests) does not use the insecure
|
||||
// RC4 cipher. Instead, it uses a high-quality cipher, varying by the libc
|
||||
// implementation.
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ type Dialer struct {
|
||||
//
|
||||
// The returned Conn, if any, will always be of type *Conn.
|
||||
func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return nil, errors.New("tls:DialContext not implmented")
|
||||
return nil, errors.New("tls:DialContext not implemented")
|
||||
}
|
||||
|
||||
// LoadX509KeyPair reads and parses a public/private key pair from a pair
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// Package abi exposes low-level details of the Go compiler/runtime
|
||||
package abi
|
||||
@@ -0,0 +1,10 @@
|
||||
package abi
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Tell the compiler the given pointer doesn't escape.
|
||||
// The compiler knows about this function and will give the nocapture parameter
|
||||
// attribute.
|
||||
func NoEscape(p unsafe.Pointer) unsafe.Pointer {
|
||||
return p
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package abi
|
||||
|
||||
// These two signatures are present to satisfy the expectation of some programs
|
||||
// (in particular internal/syscall/unix on MacOS). They do not currently have an
|
||||
// implementation, in part because TinyGo doesn't use ABI0 or ABIInternal (it
|
||||
// uses a C-like calling convention).
|
||||
|
||||
func FuncPCABI0(f interface{}) uintptr {
|
||||
panic("unimplemented: internal/abi.FuncPCABI0")
|
||||
}
|
||||
|
||||
func FuncPCABIInternal(f interface{}) uintptr {
|
||||
panic("unimplemented: internal/abi.FuncPCABIInternal")
|
||||
}
|
||||
@@ -42,6 +42,31 @@ func Compare(a, b []byte) int {
|
||||
}
|
||||
}
|
||||
|
||||
// This function was copied from the Go 1.23 source tree (with runtime_cmpstring
|
||||
// manually inlined).
|
||||
func CompareString(a, b string) int {
|
||||
l := len(a)
|
||||
if len(b) < l {
|
||||
l = len(b)
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
c1, c2 := a[i], b[i]
|
||||
if c1 < c2 {
|
||||
return -1
|
||||
}
|
||||
if c1 > c2 {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
if len(a) < len(b) {
|
||||
return -1
|
||||
}
|
||||
if len(a) > len(b) {
|
||||
return +1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Count the number of instances of a byte in a slice.
|
||||
func Count(b []byte, c byte) int {
|
||||
// Use a simple implementation, as there is no intrinsic that does this like we want.
|
||||
|
||||
@@ -180,7 +180,7 @@ func (pwm PWM) Configure(config PWMConfig) error {
|
||||
// Set the PWM mode to fast PWM (mode = 3).
|
||||
avr.TCCR0A.Set(avr.TCCR0A_WGM00 | avr.TCCR0A_WGM01)
|
||||
// monotonic timer is using the same time as PWM:0
|
||||
// we must adust internal settings of monotonic timer when PWM:0 settings changed
|
||||
// we must adjust internal settings of monotonic timer when PWM:0 settings changed
|
||||
adjustMonotonicTimer()
|
||||
} else {
|
||||
avr.TCCR2B.Set(prescaler)
|
||||
@@ -718,7 +718,7 @@ func (pwm PWM) Set(channel uint8, value uint32) {
|
||||
}
|
||||
}
|
||||
// monotonic timer is using the same time as PWM:0
|
||||
// we must adust internal settings of monotonic timer when PWM:0 settings changed
|
||||
// we must adjust internal settings of monotonic timer when PWM:0 settings changed
|
||||
adjustMonotonicTimer()
|
||||
case 1:
|
||||
mask := interrupt.Disable()
|
||||
|
||||
@@ -56,7 +56,7 @@ func (pwm PWM) Configure(config PWMConfig) error {
|
||||
// Set the PWM mode to fast PWM (mode = 3).
|
||||
avr.TCCR0A.Set(avr.TCCR0A_WGM00 | avr.TCCR0A_WGM01)
|
||||
// monotonic timer is using the same time as PWM:0
|
||||
// we must adust internal settings of monotonic timer when PWM:0 settings changed
|
||||
// we must adjust internal settings of monotonic timer when PWM:0 settings changed
|
||||
adjustMonotonicTimer()
|
||||
} else {
|
||||
avr.TCCR2B.Set(prescaler)
|
||||
@@ -385,7 +385,7 @@ func (pwm PWM) Set(channel uint8, value uint32) {
|
||||
}
|
||||
}
|
||||
// monotonic timer is using the same time as PWM:0
|
||||
// we must adust internal settings of monotonic timer when PWM:0 settings changed
|
||||
// we must adjust internal settings of monotonic timer when PWM:0 settings changed
|
||||
adjustMonotonicTimer()
|
||||
case 1:
|
||||
mask := interrupt.Disable()
|
||||
|
||||
@@ -480,7 +480,7 @@ func (uart *UART) enableTransmitter() {
|
||||
uart.Bus.SetCONF0_TXFIFO_RST(0)
|
||||
// TXINFO empty threshold is when txfifo_empty_int interrupt produced after the amount of data in Tx-FIFO is less than this register value.
|
||||
uart.Bus.SetCONF1_TXFIFO_EMPTY_THRHD(uart_empty_thresh_default)
|
||||
// we are not using interrut on TX since write we are waiting for FIFO to have space.
|
||||
// we are not using interrupt on TX since write we are waiting for FIFO to have space.
|
||||
// uart.Bus.INT_ENA.SetBits(esp.UART_INT_ENA_TXFIFO_EMPTY_INT_ENA)
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ const (
|
||||
|
||||
var (
|
||||
errUnsupportedSPIController = errors.New("SPI controller not supported. Use SPI0 or SPI1.")
|
||||
errI2CTxAbort = errors.New("I2C transmition has been aborted.")
|
||||
errI2CTxAbort = errors.New("I2C transmission has been aborted.")
|
||||
)
|
||||
|
||||
func (p Pin) setFPIOAIOPull(pull fpioaPullMode) {
|
||||
@@ -619,7 +619,7 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
dataLen -= fifoLen
|
||||
}
|
||||
|
||||
// Wait for transmition to complete.
|
||||
// Wait for transmission to complete.
|
||||
for i2c.Bus.STATUS.HasBits(kendryte.I2C_STATUS_ACTIVITY) || !i2c.Bus.STATUS.HasBits(kendryte.I2C_STATUS_TFE) {
|
||||
}
|
||||
|
||||
|
||||
@@ -451,7 +451,7 @@ func (p Pin) getGPIO() (norm *nxp.GPIO_Type, fast *nxp.GPIO_Type) {
|
||||
}
|
||||
}
|
||||
|
||||
// getPad returns both the pad and mux configration registers for a given Pin.
|
||||
// getPad returns both the pad and mux configuration registers for a given Pin.
|
||||
func (p Pin) getPad() (pad *volatile.Register32, mux *volatile.Register32) {
|
||||
switch p.getPort() {
|
||||
case portA:
|
||||
|
||||
@@ -24,7 +24,7 @@ var (
|
||||
// here: https://github.com/vmilea/pico_i2c_slave
|
||||
|
||||
// Features: Taken from datasheet.
|
||||
// Default controller mode, with target mode available (not simulataneously).
|
||||
// Default controller mode, with target mode available (not simultaneously).
|
||||
// Default target address of RP2040: 0x055
|
||||
// Supports 10-bit addressing in controller mode
|
||||
// 16-element transmit buffer
|
||||
@@ -36,7 +36,7 @@ var (
|
||||
// GPIO config
|
||||
// Each controller must connect its clock SCL and data SDA to one pair of GPIOs.
|
||||
// The I2C standard requires that drivers drivea signal low, or when not driven the signal will be pulled high.
|
||||
// This applies to SCL and SDA. The GPIO pads should beconfigured for:
|
||||
// This applies to SCL and SDA. The GPIO pads should be configured for:
|
||||
// Pull-up enabled
|
||||
// Slew rate limited
|
||||
// Schmitt trigger enabled
|
||||
|
||||
@@ -399,7 +399,7 @@ func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
|
||||
// pclk1 clock speed is main frequency divided by PCLK1 prescaler (div 2)
|
||||
pclk1 := CPUFrequency() / 2
|
||||
|
||||
// set freqency range to PCLK1 clock speed in MHz
|
||||
// set frequency range to PCLK1 clock speed in MHz
|
||||
// aka setting the value 36 means to use 36 MHz clock
|
||||
return pclk1 / 1000000
|
||||
}
|
||||
|
||||
@@ -256,10 +256,10 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
}
|
||||
|
||||
// set frequency dependent on PCLK prescaler. Since these are rather weird
|
||||
// speeds due to the CPU freqency, pick a range up to that frquency for
|
||||
// speeds due to the CPU frequency, pick a range up to that frequency for
|
||||
// clients to use more human-understandable numbers, e.g. nearest 100KHz
|
||||
|
||||
// These are based on APB2 clock frquency (84MHz on the discovery board)
|
||||
// These are based on APB2 clock frequency (84MHz on the discovery board)
|
||||
// TODO: also include the MCU/APB clock setting in the equation
|
||||
switch {
|
||||
case localFrequency < 328125:
|
||||
|
||||
@@ -327,10 +327,10 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||
localFrequency := config.Frequency
|
||||
|
||||
// set frequency dependent on PCLK prescaler. Since these are rather weird
|
||||
// speeds due to the CPU freqency, pick a range up to that frquency for
|
||||
// speeds due to the CPU frequency, pick a range up to that frequency for
|
||||
// clients to use more human-understandable numbers, e.g. nearest 100KHz
|
||||
|
||||
// These are based on 80MHz peripheral clock frquency
|
||||
// These are based on 80MHz peripheral clock frequency
|
||||
switch {
|
||||
case localFrequency < 312500:
|
||||
conf = stm32.SPI_CR1_BR_Div256
|
||||
|
||||
@@ -103,7 +103,7 @@ var classHID = [ClassHIDTypeLen]byte{
|
||||
0x00, // CountryCode
|
||||
0x01, // NumDescriptors
|
||||
0x22, // ClassType
|
||||
0x90, // ClassLength L
|
||||
0x91, // ClassLength L
|
||||
0x00, // ClassLength H
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ var CDCHID = Descriptor{
|
||||
EndpointEP5OUT.Bytes(),
|
||||
}),
|
||||
HID: map[uint16][]byte{
|
||||
2: Append([][]byte{
|
||||
2: Append([][]byte{ // Update ClassLength in classHID whenever the array length is modified!
|
||||
HIDUsagePageGenericDesktop,
|
||||
HIDUsageDesktopKeyboard,
|
||||
HIDCollectionApplication,
|
||||
@@ -210,6 +210,7 @@ var CDCHID = Descriptor{
|
||||
HIDReportSize(16),
|
||||
HIDReportCount(1),
|
||||
HIDInputDataAryAbs,
|
||||
HIDCollectionEnd}),
|
||||
HIDCollectionEnd,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
package descriptor
|
||||
|
||||
import "math"
|
||||
|
||||
const (
|
||||
hidUsagePage = 0x05
|
||||
hidUsage = 0x09
|
||||
hidUsagePage = 0x04
|
||||
hidUsage = 0x08
|
||||
hidLogicalMinimum = 0x14
|
||||
hidLogicalMaximum = 0x24
|
||||
hidUsageMinimum = 0x18
|
||||
hidUsageMaximum = 0x28
|
||||
hidPhysicalMinimum = 0x34
|
||||
hidPhysicalMaximum = 0x44
|
||||
hidUnitExponent = 0x55
|
||||
hidUnit = 0x65
|
||||
hidCollection = 0xa1
|
||||
hidInput = 0x81
|
||||
hidOutput = 0x91
|
||||
hidReportSize = 0x75
|
||||
hidReportCount = 0x95
|
||||
hidReportID = 0x85
|
||||
hidUnitExponent = 0x54
|
||||
hidUnit = 0x64
|
||||
hidCollection = 0xA0
|
||||
hidInput = 0x80
|
||||
hidOutput = 0x90
|
||||
hidReportSize = 0x74
|
||||
hidReportCount = 0x94
|
||||
hidReportID = 0x84
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -27,191 +29,192 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
HIDUsagePageGenericDesktop = []byte{hidUsagePage, 0x01}
|
||||
HIDUsagePageSimulationControls = []byte{hidUsagePage, 0x02}
|
||||
HIDUsagePageVRControls = []byte{hidUsagePage, 0x03}
|
||||
HIDUsagePageSportControls = []byte{hidUsagePage, 0x04}
|
||||
HIDUsagePageGameControls = []byte{hidUsagePage, 0x05}
|
||||
HIDUsagePageGenericControls = []byte{hidUsagePage, 0x06}
|
||||
HIDUsagePageKeyboard = []byte{hidUsagePage, 0x07}
|
||||
HIDUsagePageLED = []byte{hidUsagePage, 0x08}
|
||||
HIDUsagePageButton = []byte{hidUsagePage, 0x09}
|
||||
HIDUsagePageOrdinal = []byte{hidUsagePage, 0x0A}
|
||||
HIDUsagePageTelephony = []byte{hidUsagePage, 0x0B}
|
||||
HIDUsagePageConsumer = []byte{hidUsagePage, 0x0C}
|
||||
HIDUsagePageDigitizers = []byte{hidUsagePage, 0x0D}
|
||||
HIDUsagePageHaptics = []byte{hidUsagePage, 0x0E}
|
||||
HIDUsagePagePhysicalInput = []byte{hidUsagePage, 0x0F}
|
||||
HIDUsagePageUnicode = []byte{hidUsagePage, 0x10}
|
||||
HIDUsagePageSoC = []byte{hidUsagePage, 0x11}
|
||||
HIDUsagePageEyeHeadTrackers = []byte{hidUsagePage, 0x12}
|
||||
HIDUsagePageAuxDisplay = []byte{hidUsagePage, 0x14}
|
||||
HIDUsagePageSensors = []byte{hidUsagePage, 0x20}
|
||||
HIDUsagePageMedicalInstrument = []byte{hidUsagePage, 0x40}
|
||||
HIDUsagePageBrailleDisplay = []byte{hidUsagePage, 0x41}
|
||||
HIDUsagePageLighting = []byte{hidUsagePage, 0x59}
|
||||
HIDUsagePageMonitor = []byte{hidUsagePage, 0x80}
|
||||
HIDUsagePageMonitorEnum = []byte{hidUsagePage, 0x81}
|
||||
HIDUsagePageVESA = []byte{hidUsagePage, 0x82}
|
||||
HIDUsagePagePower = []byte{hidUsagePage, 0x84}
|
||||
HIDUsagePageBatterySystem = []byte{hidUsagePage, 0x85}
|
||||
HIDUsagePageBarcodeScanner = []byte{hidUsagePage, 0x8C}
|
||||
HIDUsagePageScales = []byte{hidUsagePage, 0x8D}
|
||||
HIDUsagePageMagneticStripe = []byte{hidUsagePage, 0x8E}
|
||||
HIDUsagePageCameraControl = []byte{hidUsagePage, 0x90}
|
||||
HIDUsagePageArcade = []byte{hidUsagePage, 0x91}
|
||||
HIDUsagePageGaming = []byte{hidUsagePage, 0x92}
|
||||
HIDUsagePageGenericDesktop = HIDUsagePage(0x01)
|
||||
HIDUsagePageSimulationControls = HIDUsagePage(0x02)
|
||||
HIDUsagePageVRControls = HIDUsagePage(0x03)
|
||||
HIDUsagePageSportControls = HIDUsagePage(0x04)
|
||||
HIDUsagePageGameControls = HIDUsagePage(0x05)
|
||||
HIDUsagePageGenericControls = HIDUsagePage(0x06)
|
||||
HIDUsagePageKeyboard = HIDUsagePage(0x07)
|
||||
HIDUsagePageLED = HIDUsagePage(0x08)
|
||||
HIDUsagePageButton = HIDUsagePage(0x09)
|
||||
HIDUsagePageOrdinal = HIDUsagePage(0x0A)
|
||||
HIDUsagePageTelephony = HIDUsagePage(0x0B)
|
||||
HIDUsagePageConsumer = HIDUsagePage(0x0C)
|
||||
HIDUsagePageDigitizers = HIDUsagePage(0x0D)
|
||||
HIDUsagePageHaptics = HIDUsagePage(0x0E)
|
||||
HIDUsagePagePhysicalInput = HIDUsagePage(0x0F)
|
||||
HIDUsagePageUnicode = HIDUsagePage(0x10)
|
||||
HIDUsagePageSoC = HIDUsagePage(0x11)
|
||||
HIDUsagePageEyeHeadTrackers = HIDUsagePage(0x12)
|
||||
HIDUsagePageAuxDisplay = HIDUsagePage(0x14)
|
||||
HIDUsagePageSensors = HIDUsagePage(0x20)
|
||||
HIDUsagePageMedicalInstrument = HIDUsagePage(0x40)
|
||||
HIDUsagePageBrailleDisplay = HIDUsagePage(0x41)
|
||||
HIDUsagePageLighting = HIDUsagePage(0x59)
|
||||
HIDUsagePageMonitor = HIDUsagePage(0x80)
|
||||
HIDUsagePageMonitorEnum = HIDUsagePage(0x81)
|
||||
HIDUsagePageVESA = HIDUsagePage(0x82)
|
||||
HIDUsagePagePower = HIDUsagePage(0x84)
|
||||
HIDUsagePageBatterySystem = HIDUsagePage(0x85)
|
||||
HIDUsagePageBarcodeScanner = HIDUsagePage(0x8C)
|
||||
HIDUsagePageScales = HIDUsagePage(0x8D)
|
||||
HIDUsagePageMagneticStripe = HIDUsagePage(0x8E)
|
||||
HIDUsagePageCameraControl = HIDUsagePage(0x90)
|
||||
HIDUsagePageArcade = HIDUsagePage(0x91)
|
||||
HIDUsagePageGaming = HIDUsagePage(0x92)
|
||||
)
|
||||
|
||||
var (
|
||||
HIDUsageDesktopPointer = []byte{hidUsage, 0x01}
|
||||
HIDUsageDesktopMouse = []byte{hidUsage, 0x02}
|
||||
HIDUsageDesktopJoystick = []byte{hidUsage, 0x04}
|
||||
HIDUsageDesktopGamepad = []byte{hidUsage, 0x05}
|
||||
HIDUsageDesktopKeyboard = []byte{hidUsage, 0x06}
|
||||
HIDUsageDesktopKeypad = []byte{hidUsage, 0x07}
|
||||
HIDUsageDesktopMultiaxis = []byte{hidUsage, 0x08}
|
||||
HIDUsageDesktopTablet = []byte{hidUsage, 0x09}
|
||||
HIDUsageDesktopWaterCooling = []byte{hidUsage, 0x0A}
|
||||
HIDUsageDesktopChassis = []byte{hidUsage, 0x0B}
|
||||
HIDUsageDesktopWireless = []byte{hidUsage, 0x0C}
|
||||
HIDUsageDesktopPortable = []byte{hidUsage, 0x0D}
|
||||
HIDUsageDesktopSystemMultiaxis = []byte{hidUsage, 0x0E}
|
||||
HIDUsageDesktopSpatial = []byte{hidUsage, 0x0F}
|
||||
HIDUsageDesktopAssistive = []byte{hidUsage, 0x10}
|
||||
HIDUsageDesktopDock = []byte{hidUsage, 0x11}
|
||||
HIDUsageDesktopDockable = []byte{hidUsage, 0x12}
|
||||
HIDUsageDesktopCallState = []byte{hidUsage, 0x13}
|
||||
HIDUsageDesktopX = []byte{hidUsage, 0x30}
|
||||
HIDUsageDesktopY = []byte{hidUsage, 0x31}
|
||||
HIDUsageDesktopZ = []byte{hidUsage, 0x32}
|
||||
HIDUsageDesktopRx = []byte{hidUsage, 0x33}
|
||||
HIDUsageDesktopRy = []byte{hidUsage, 0x34}
|
||||
HIDUsageDesktopRz = []byte{hidUsage, 0x35}
|
||||
HIDUsageDesktopSlider = []byte{hidUsage, 0x36}
|
||||
HIDUsageDesktopDial = []byte{hidUsage, 0x37}
|
||||
HIDUsageDesktopWheel = []byte{hidUsage, 0x38}
|
||||
HIDUsageDesktopHatSwitch = []byte{hidUsage, 0x39}
|
||||
HIDUsageDesktopCountedBuffer = []byte{hidUsage, 0x3A}
|
||||
HIDUsageDesktopPointer = HIDUsage(0x01)
|
||||
HIDUsageDesktopMouse = HIDUsage(0x02)
|
||||
HIDUsageDesktopJoystick = HIDUsage(0x04)
|
||||
HIDUsageDesktopGamepad = HIDUsage(0x05)
|
||||
HIDUsageDesktopKeyboard = HIDUsage(0x06)
|
||||
HIDUsageDesktopKeypad = HIDUsage(0x07)
|
||||
HIDUsageDesktopMultiaxis = HIDUsage(0x08)
|
||||
HIDUsageDesktopTablet = HIDUsage(0x09)
|
||||
HIDUsageDesktopWaterCooling = HIDUsage(0x0A)
|
||||
HIDUsageDesktopChassis = HIDUsage(0x0B)
|
||||
HIDUsageDesktopWireless = HIDUsage(0x0C)
|
||||
HIDUsageDesktopPortable = HIDUsage(0x0D)
|
||||
HIDUsageDesktopSystemMultiaxis = HIDUsage(0x0E)
|
||||
HIDUsageDesktopSpatial = HIDUsage(0x0F)
|
||||
HIDUsageDesktopAssistive = HIDUsage(0x10)
|
||||
HIDUsageDesktopDock = HIDUsage(0x11)
|
||||
HIDUsageDesktopDockable = HIDUsage(0x12)
|
||||
HIDUsageDesktopCallState = HIDUsage(0x13)
|
||||
HIDUsageDesktopX = HIDUsage(0x30)
|
||||
HIDUsageDesktopY = HIDUsage(0x31)
|
||||
HIDUsageDesktopZ = HIDUsage(0x32)
|
||||
HIDUsageDesktopRx = HIDUsage(0x33)
|
||||
HIDUsageDesktopRy = HIDUsage(0x34)
|
||||
HIDUsageDesktopRz = HIDUsage(0x35)
|
||||
HIDUsageDesktopSlider = HIDUsage(0x36)
|
||||
HIDUsageDesktopDial = HIDUsage(0x37)
|
||||
HIDUsageDesktopWheel = HIDUsage(0x38)
|
||||
HIDUsageDesktopHatSwitch = HIDUsage(0x39)
|
||||
HIDUsageDesktopCountedBuffer = HIDUsage(0x3A)
|
||||
)
|
||||
|
||||
var (
|
||||
HIDUsageConsumerControl = []byte{hidUsage, 0x01}
|
||||
HIDUsageConsumerNumericKeypad = []byte{hidUsage, 0x02}
|
||||
HIDUsageConsumerProgrammableButtons = []byte{hidUsage, 0x03}
|
||||
HIDUsageConsumerMicrophone = []byte{hidUsage, 0x04}
|
||||
HIDUsageConsumerHeadphone = []byte{hidUsage, 0x05}
|
||||
HIDUsageConsumerGraphicEqualizer = []byte{hidUsage, 0x06}
|
||||
HIDUsageConsumerControl = HIDUsage(0x01)
|
||||
HIDUsageConsumerNumericKeypad = HIDUsage(0x02)
|
||||
HIDUsageConsumerProgrammableButtons = HIDUsage(0x03)
|
||||
HIDUsageConsumerMicrophone = HIDUsage(0x04)
|
||||
HIDUsageConsumerHeadphone = HIDUsage(0x05)
|
||||
HIDUsageConsumerGraphicEqualizer = HIDUsage(0x06)
|
||||
)
|
||||
|
||||
var (
|
||||
HIDCollectionPhysical = []byte{hidCollection, 0x00}
|
||||
HIDCollectionApplication = []byte{hidCollection, 0x01}
|
||||
HIDCollectionEnd = []byte{0xc0}
|
||||
HIDCollectionPhysical = HIDCollection(0x00)
|
||||
HIDCollectionApplication = HIDCollection(0x01)
|
||||
HIDCollectionEnd = []byte{0xC0}
|
||||
)
|
||||
|
||||
var (
|
||||
// Input (Data,Ary,Abs), Key arrays (6 bytes)
|
||||
HIDInputDataAryAbs = []byte{hidInput, 0x00}
|
||||
HIDInputDataAryAbs = HIDInput(0x00)
|
||||
|
||||
// Input (Data, Variable, Absolute), Modifier byte
|
||||
HIDInputDataVarAbs = []byte{hidInput, 0x02}
|
||||
HIDInputDataVarAbs = HIDInput(0x02)
|
||||
|
||||
// Input (Const,Var,Abs), Modifier byte
|
||||
HIDInputConstVarAbs = []byte{hidInput, 0x03}
|
||||
HIDInputConstVarAbs = HIDInput(0x03)
|
||||
|
||||
// Input (Data, Variable, Relative), 2 position bytes (X & Y)
|
||||
HIDInputDataVarRel = []byte{hidInput, 0x06}
|
||||
HIDInputDataVarRel = HIDInput(0x06)
|
||||
|
||||
// Output (Data, Variable, Absolute), Modifier byte
|
||||
HIDOutputDataVarAbs = []byte{hidOutput, 0x02}
|
||||
HIDOutputDataVarAbs = HIDOutput(0x02)
|
||||
|
||||
// Output (Const, Variable, Absolute), Modifier byte
|
||||
HIDOutputConstVarAbs = []byte{hidOutput, 0x03}
|
||||
HIDOutputConstVarAbs = HIDOutput(0x03)
|
||||
)
|
||||
|
||||
func hidShortItem(tag byte, value uint32) []byte {
|
||||
switch {
|
||||
case value <= math.MaxUint8:
|
||||
return []byte{tag | hidSizeValue1, byte(value)}
|
||||
case value <= math.MaxUint16:
|
||||
return []byte{tag | hidSizeValue2, byte(value), byte(value >> 8)}
|
||||
default:
|
||||
return []byte{tag | hidSizeValue4, byte(value), byte(value >> 8), byte(value >> 16), byte(value >> 24)}
|
||||
}
|
||||
}
|
||||
|
||||
func hidShortItemSigned(tag byte, value int32) []byte {
|
||||
switch {
|
||||
case math.MinInt8 <= value && value <= math.MaxInt8:
|
||||
return []byte{tag | hidSizeValue1, byte(value)}
|
||||
case math.MinInt16 <= value && value <= math.MaxInt16:
|
||||
return []byte{tag | hidSizeValue2, byte(value), byte(value >> 8)}
|
||||
default:
|
||||
return []byte{tag | hidSizeValue4, byte(value), byte(value >> 8), byte(value >> 16), byte(value >> 24)}
|
||||
}
|
||||
}
|
||||
|
||||
func HIDReportSize(size int) []byte {
|
||||
return []byte{hidReportSize, byte(size)}
|
||||
return hidShortItem(hidReportSize, uint32(size))
|
||||
}
|
||||
|
||||
func HIDReportCount(count int) []byte {
|
||||
return []byte{hidReportCount, byte(count)}
|
||||
return hidShortItem(hidReportCount, uint32(count))
|
||||
}
|
||||
|
||||
func HIDReportID(id int) []byte {
|
||||
return []byte{hidReportID, byte(id)}
|
||||
return hidShortItem(hidReportID, uint32(id))
|
||||
}
|
||||
|
||||
func HIDLogicalMinimum(min int) []byte {
|
||||
switch {
|
||||
case min < -32767 || 65535 < min:
|
||||
return []byte{hidLogicalMinimum + hidSizeValue4, uint8(min), uint8(min >> 8), uint8(min >> 16), uint8(min >> 24)}
|
||||
case min < -127 || 255 < min:
|
||||
return []byte{hidLogicalMinimum + hidSizeValue2, uint8(min), uint8(min >> 8)}
|
||||
default:
|
||||
return []byte{hidLogicalMinimum + hidSizeValue1, byte(min)}
|
||||
}
|
||||
return hidShortItemSigned(hidLogicalMinimum, int32(min))
|
||||
}
|
||||
|
||||
func HIDLogicalMaximum(max int) []byte {
|
||||
switch {
|
||||
case max < -32767 || 65535 < max:
|
||||
return []byte{hidLogicalMaximum + hidSizeValue4, uint8(max), uint8(max >> 8), uint8(max >> 16), uint8(max >> 24)}
|
||||
case max < -127 || 255 < max:
|
||||
return []byte{hidLogicalMaximum + hidSizeValue2, uint8(max), uint8(max >> 8)}
|
||||
default:
|
||||
return []byte{hidLogicalMaximum + hidSizeValue1, byte(max)}
|
||||
}
|
||||
return hidShortItemSigned(hidLogicalMaximum, int32(max))
|
||||
}
|
||||
|
||||
func HIDUsageMinimum(min int) []byte {
|
||||
switch {
|
||||
case min < -32767 || 65535 < min:
|
||||
return []byte{hidUsageMinimum + hidSizeValue4, uint8(min), uint8(min >> 8), uint8(min >> 16), uint8(min >> 24)}
|
||||
case min < -127 || 255 < min:
|
||||
return []byte{hidUsageMinimum + hidSizeValue2, uint8(min), uint8(min >> 8)}
|
||||
default:
|
||||
return []byte{hidUsageMinimum + hidSizeValue1, byte(min)}
|
||||
}
|
||||
return hidShortItem(hidUsageMinimum, uint32(min))
|
||||
}
|
||||
|
||||
func HIDUsageMaximum(max int) []byte {
|
||||
switch {
|
||||
case max < -32767 || 65535 < max:
|
||||
return []byte{hidUsageMaximum + hidSizeValue4, uint8(max), uint8(max >> 8), uint8(max >> 16), uint8(max >> 24)}
|
||||
case max < -127 || 255 < max:
|
||||
return []byte{hidUsageMaximum + hidSizeValue2, uint8(max), uint8(max >> 8)}
|
||||
default:
|
||||
return []byte{hidUsageMaximum + hidSizeValue1, byte(max)}
|
||||
}
|
||||
return hidShortItem(hidUsageMaximum, uint32(max))
|
||||
}
|
||||
|
||||
func HIDPhysicalMinimum(min int) []byte {
|
||||
switch {
|
||||
case min < -32767 || 65535 < min:
|
||||
return []byte{hidPhysicalMinimum + hidSizeValue4, uint8(min), uint8(min >> 8), uint8(min >> 16), uint8(min >> 24)}
|
||||
case min < -127 || 255 < min:
|
||||
return []byte{hidPhysicalMinimum + hidSizeValue2, uint8(min), uint8(min >> 8)}
|
||||
default:
|
||||
return []byte{hidPhysicalMinimum + hidSizeValue1, byte(min)}
|
||||
}
|
||||
return hidShortItemSigned(hidPhysicalMinimum, int32(min))
|
||||
}
|
||||
|
||||
func HIDPhysicalMaximum(max int) []byte {
|
||||
switch {
|
||||
case max < -32767 || 65535 < max:
|
||||
return []byte{hidPhysicalMaximum + hidSizeValue4, uint8(max), uint8(max >> 8), uint8(max >> 16), uint8(max >> 24)}
|
||||
case max < -127 || 255 < max:
|
||||
return []byte{hidPhysicalMaximum + hidSizeValue2, uint8(max), uint8(max >> 8)}
|
||||
default:
|
||||
return []byte{hidPhysicalMaximum + hidSizeValue1, byte(max)}
|
||||
}
|
||||
return hidShortItemSigned(hidPhysicalMaximum, int32(max))
|
||||
}
|
||||
|
||||
func HIDUnitExponent(exp int) []byte {
|
||||
return []byte{hidUnitExponent, byte(exp)}
|
||||
// 4 Bit two's complement
|
||||
return hidShortItem(hidUnitExponent, uint32(exp&0xF))
|
||||
}
|
||||
|
||||
func HIDUnit(unit int) []byte {
|
||||
return []byte{hidUnit, byte(unit)}
|
||||
func HIDUnit(unit uint32) []byte {
|
||||
return hidShortItem(hidUnit, unit)
|
||||
}
|
||||
|
||||
func HIDUsagePage(id uint16) []byte {
|
||||
return hidShortItem(hidUsagePage, uint32(id))
|
||||
}
|
||||
|
||||
func HIDUsage(id uint32) []byte {
|
||||
return hidShortItem(hidUsage, id)
|
||||
}
|
||||
|
||||
func HIDCollection(id uint32) []byte {
|
||||
return hidShortItem(hidCollection, id)
|
||||
}
|
||||
|
||||
func HIDInput(flags uint32) []byte {
|
||||
return hidShortItem(hidInput, flags)
|
||||
}
|
||||
|
||||
func HIDOutput(flags uint32) []byte {
|
||||
return hidShortItem(hidOutput, flags)
|
||||
}
|
||||
|
||||
@@ -95,17 +95,15 @@ var JoystickDefaultHIDReport = Append([][]byte{
|
||||
HIDReportSize(4),
|
||||
HIDInputDataVarAbs,
|
||||
HIDUsageDesktopHatSwitch,
|
||||
HIDLogicalMinimum(0),
|
||||
HIDLogicalMaximum(7),
|
||||
HIDPhysicalMinimum(0),
|
||||
HIDPhysicalMaximum(315),
|
||||
HIDUnit(0x14),
|
||||
HIDReportCount(1),
|
||||
HIDReportSize(4),
|
||||
HIDInputDataVarAbs,
|
||||
HIDInputConstVarAbs,
|
||||
HIDUsageDesktopPointer,
|
||||
HIDLogicalMinimum(-32767),
|
||||
HIDLogicalMaximum(32767),
|
||||
HIDPhysicalMinimum(0),
|
||||
HIDPhysicalMaximum(0),
|
||||
HIDUnit(0),
|
||||
HIDReportCount(6),
|
||||
HIDReportSize(16),
|
||||
HIDCollectionPhysical,
|
||||
|
||||
@@ -67,6 +67,10 @@ func (c Definitions) Descriptor() []byte {
|
||||
|
||||
func (c Definitions) NewState() State {
|
||||
bufSize := 1
|
||||
hatSwitches := make([]HatDirection, c.HatSwitchCnt)
|
||||
for i := range hatSwitches {
|
||||
hatSwitches[i] = HatCenter
|
||||
}
|
||||
axises := make([]*AxisValue, 0, len(c.AxisDefs))
|
||||
for _, v := range c.AxisDefs {
|
||||
|
||||
@@ -77,16 +81,14 @@ func (c Definitions) NewState() State {
|
||||
}
|
||||
btnSize := (c.ButtonCnt + 7) / 8
|
||||
bufSize += btnSize
|
||||
if c.HatSwitchCnt > 0 {
|
||||
bufSize++
|
||||
}
|
||||
bufSize += (len(hatSwitches) + 1) / 2
|
||||
bufSize += len(axises) * 2
|
||||
initBuf := make([]byte, bufSize)
|
||||
initBuf[0] = c.ReportID
|
||||
return State{
|
||||
buf: initBuf,
|
||||
Buttons: make([]byte, btnSize),
|
||||
HatSwitches: make([]HatDirection, c.HatSwitchCnt),
|
||||
HatSwitches: hatSwitches,
|
||||
Axises: axises,
|
||||
}
|
||||
}
|
||||
@@ -103,7 +105,11 @@ func (s State) MarshalBinary() ([]byte, error) {
|
||||
s.buf = append(s.buf, s.Buttons...)
|
||||
if len(s.HatSwitches) > 0 {
|
||||
hat := byte(0)
|
||||
for _, v := range s.HatSwitches {
|
||||
for i, v := range s.HatSwitches {
|
||||
if i != 0 && i%2 == 0 {
|
||||
s.buf = append(s.buf, hat)
|
||||
hat = 0
|
||||
}
|
||||
hat <<= 4
|
||||
hat |= byte(v & 0xf)
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ func (p *Process) Release() error {
|
||||
return p.release()
|
||||
}
|
||||
|
||||
// FindProcess looks for a running process by its pid.
|
||||
// Keep compatibility with golang and always succeed and return new proc with pid on Linux.
|
||||
func FindProcess(pid int) (*Process, error) {
|
||||
return findProcess(pid)
|
||||
|
||||
@@ -290,16 +290,6 @@ func (f *File) Sync() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Truncate is a stub, not yet implemented
|
||||
func (f *File) Truncate(size int64) (err error) {
|
||||
if f.handle == nil {
|
||||
err = ErrClosed
|
||||
} else {
|
||||
err = ErrNotImplemented
|
||||
}
|
||||
return &PathError{Op: "truncate", Path: f.name, Err: err}
|
||||
}
|
||||
|
||||
// LinkError records an error during a link or symlink or rename system call and
|
||||
// the paths that caused it.
|
||||
type LinkError struct {
|
||||
|
||||
@@ -55,6 +55,19 @@ func NewFile(fd uintptr, name string) *File {
|
||||
return &File{&file{handle: unixFileHandle(fd), name: name}}
|
||||
}
|
||||
|
||||
// Truncate changes the size of the named file.
|
||||
// If the file is a symbolic link, it changes the size of the link's target.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func Truncate(name string, size int64) error {
|
||||
e := ignoringEINTR(func() error {
|
||||
return syscall.Truncate(name, size)
|
||||
})
|
||||
if e != nil {
|
||||
return &PathError{Op: "truncate", Path: name, Err: e}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Pipe() (r *File, w *File, err error) {
|
||||
var p [2]int
|
||||
err = handleSyscallError(syscall.Pipe2(p[:], syscall.O_CLOEXEC))
|
||||
@@ -125,6 +138,18 @@ func Readlink(name string) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Truncate changes the size of the file.
|
||||
// It does not change the I/O offset.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
// Alternatively just use 'raw' syscall by file name
|
||||
func (f *File) Truncate(size int64) (err error) {
|
||||
if f.handle == nil {
|
||||
return ErrClosed
|
||||
}
|
||||
|
||||
return Truncate(f.name, size)
|
||||
}
|
||||
|
||||
// ReadAt reads up to len(b) bytes from the File starting at the given absolute offset.
|
||||
// It returns the number of bytes read and any error encountered, possibly io.EOF.
|
||||
// At end of file, Pread returns 0, io.EOF.
|
||||
|
||||
@@ -59,6 +59,16 @@ func Pipe() (r *File, w *File, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (f *unixFileHandle) Truncate(size int64) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
// Truncate changes the size of the named file.
|
||||
// If the file is a symbolic link, it changes the size of the link's target.
|
||||
func Truncate(name string, size int64) error {
|
||||
return &PathError{Op: "truncate", Path: name, Err: ErrNotImplemented}
|
||||
}
|
||||
|
||||
func tempDir() string {
|
||||
n := uint32(syscall.MAX_PATH)
|
||||
for {
|
||||
@@ -106,6 +116,15 @@ func (f unixFileHandle) Sync() error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
// Truncate changes the size of the named file.
|
||||
// If the file is a symbolic link, it changes the size of the link's target.
|
||||
func (f *File) Truncate(size int64) error {
|
||||
if f.handle == nil {
|
||||
return &PathError{Op: "truncate", Path: f.name, Err: ErrClosed}
|
||||
}
|
||||
return Truncate(f.name, size)
|
||||
}
|
||||
|
||||
// isWindowsNulName reports whether name is os.DevNull ('NUL') on Windows.
|
||||
// True is returned if name is 'NUL' whatever the case.
|
||||
func isWindowsNulName(name string) bool {
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestStatBadDir(t *testing.T) {
|
||||
badDir := filepath.Join(dir, "not-exist/really-not-exist")
|
||||
_, err := Stat(badDir)
|
||||
if pe, ok := err.(*fs.PathError); !ok || !IsNotExist(err) || pe.Path != badDir {
|
||||
t.Errorf("Mkdir error = %#v; want PathError for path %q satisifying IsNotExist", err, badDir)
|
||||
t.Errorf("Mkdir error = %#v; want PathError for path %q satisfying IsNotExist", err, badDir)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ func TestMkdirTempBadDir(t *testing.T) {
|
||||
badDir := filepath.Join(dir, "not-exist")
|
||||
_, err = MkdirTemp(badDir, "foo")
|
||||
if pe, ok := err.(*fs.PathError); !ok || !IsNotExist(err) || pe.Path != badDir {
|
||||
t.Errorf("TempDir error = %#v; want PathError for path %q satisifying IsNotExist", err, badDir)
|
||||
t.Errorf("TempDir error = %#v; want PathError for path %q satisfying IsNotExist", err, badDir)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
//go:build darwin || (linux && !baremetal && !js && !wasi)
|
||||
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package os_test
|
||||
|
||||
import (
|
||||
. "os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTruncate(t *testing.T) {
|
||||
// Truncate is not supported on Windows or wasi at the moment
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "wasip1" || runtime.GOOS == "wasip2" {
|
||||
t.Logf("skipping test on %s", runtime.GOOS)
|
||||
return
|
||||
}
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
file := filepath.Join(tmpDir, "truncate_test")
|
||||
|
||||
fd, err := Create(file)
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: got %v, want nil", file, err)
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
// truncate up to 0x100
|
||||
if err := fd.Truncate(0x100); err != nil {
|
||||
t.Fatalf("truncate %q: got %v, want nil", file, err)
|
||||
}
|
||||
|
||||
// check if size is 0x100
|
||||
fi, err := Stat(file)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q: got %v, want nil", file, err)
|
||||
}
|
||||
|
||||
if fi.Size() != 0x100 {
|
||||
t.Fatalf("size of %q is %d; want 0x100", file, fi.Size())
|
||||
}
|
||||
|
||||
// truncate down to 0x80
|
||||
if err := fd.Truncate(0x80); err != nil {
|
||||
t.Fatalf("truncate %q: got %v, want nil", file, err)
|
||||
}
|
||||
|
||||
// check if size is 0x80
|
||||
fi, err = Stat(file)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q: got %v, want nil", file, err)
|
||||
}
|
||||
|
||||
if fi.Size() != 0x80 {
|
||||
t.Fatalf("size of %q is %d; want 0x80", file, fi.Size())
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package user
|
||||
|
||||
import "errors"
|
||||
|
||||
// User represents a user account.
|
||||
type User struct {
|
||||
// Uid is the user ID.
|
||||
// On POSIX systems, this is a decimal number representing the uid.
|
||||
// On Windows, this is a security identifier (SID) in a string format.
|
||||
// On Plan 9, this is the contents of /dev/user.
|
||||
Uid string
|
||||
// Gid is the primary group ID.
|
||||
// On POSIX systems, this is a decimal number representing the gid.
|
||||
// On Windows, this is a SID in a string format.
|
||||
// On Plan 9, this is the contents of /dev/user.
|
||||
Gid string
|
||||
// Username is the login name.
|
||||
Username string
|
||||
// Name is the user's real or display name.
|
||||
// It might be blank.
|
||||
// On POSIX systems, this is the first (or only) entry in the GECOS field
|
||||
// list.
|
||||
// On Windows, this is the user's display name.
|
||||
// On Plan 9, this is the contents of /dev/user.
|
||||
Name string
|
||||
// HomeDir is the path to the user's home directory (if they have one).
|
||||
HomeDir string
|
||||
}
|
||||
|
||||
// Current returns the current user.
|
||||
//
|
||||
// The first call will cache the current user information.
|
||||
// Subsequent calls will return the cached value and will not reflect
|
||||
// changes to the current user.
|
||||
func Current() (*User, error) {
|
||||
return nil, errors.New("user: Current not implemented")
|
||||
}
|
||||
|
||||
// Lookup always returns an error.
|
||||
func Lookup(username string) (*User, error) {
|
||||
return nil, errors.New("user: Lookup not implemented")
|
||||
}
|
||||
|
||||
// Group represents a grouping of users.
|
||||
//
|
||||
// On POSIX systems Gid contains a decimal number representing the group ID.
|
||||
type Group struct {
|
||||
Gid string // group ID
|
||||
Name string // group name
|
||||
}
|
||||
|
||||
// LookupGroup always returns an error.
|
||||
func LookupGroup(name string) (*Group, error) {
|
||||
return nil, errors.New("user: LookupGroup not implemented")
|
||||
}
|
||||
+40
-17
@@ -1102,20 +1102,6 @@ func init() {
|
||||
cycleMap3["different"] = cycleMap3
|
||||
}
|
||||
|
||||
type deepEqualInterface interface {
|
||||
Foo()
|
||||
}
|
||||
type deepEqualConcrete struct {
|
||||
int
|
||||
}
|
||||
|
||||
func (deepEqualConcrete) Foo() {}
|
||||
|
||||
var (
|
||||
deepEqualConcrete1 = deepEqualConcrete{1}
|
||||
deepEqualConcrete2 = deepEqualConcrete{2}
|
||||
)
|
||||
|
||||
var deepEqualTests = []DeepEqualTest{
|
||||
// Equalities
|
||||
{nil, nil, true},
|
||||
@@ -1133,7 +1119,6 @@ var deepEqualTests = []DeepEqualTest{
|
||||
{[]byte{1, 2, 3}, []byte{1, 2, 3}, true},
|
||||
{[]MyByte{1, 2, 3}, []MyByte{1, 2, 3}, true},
|
||||
{MyBytes{1, 2, 3}, MyBytes{1, 2, 3}, true},
|
||||
{map[deepEqualInterface]string{deepEqualConcrete1: "a"}, map[deepEqualInterface]string{deepEqualConcrete1: "a"}, true},
|
||||
|
||||
// Inequalities
|
||||
{1, 2, false},
|
||||
@@ -1155,7 +1140,6 @@ var deepEqualTests = []DeepEqualTest{
|
||||
{fn3, fn3, false},
|
||||
{[][]int{{1}}, [][]int{{2}}, false},
|
||||
{&structWithSelfPtr{p: &structWithSelfPtr{s: "a"}}, &structWithSelfPtr{p: &structWithSelfPtr{s: "b"}}, false},
|
||||
{map[deepEqualInterface]string{deepEqualConcrete1: "a"}, map[deepEqualInterface]string{deepEqualConcrete2: "a"}, false},
|
||||
|
||||
// Fun with floating point.
|
||||
{math.NaN(), math.NaN(), false},
|
||||
@@ -4913,7 +4897,7 @@ func TestComparable(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverflow(t *testing.T) {
|
||||
func TestValueOverflow(t *testing.T) {
|
||||
if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
|
||||
t.Errorf("%v wrongly overflows float64", 1e300)
|
||||
}
|
||||
@@ -4952,6 +4936,45 @@ func TestOverflow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeOverflow(t *testing.T) {
|
||||
if ovf := TypeFor[float64]().OverflowFloat(1e300); ovf {
|
||||
t.Errorf("%v wrongly overflows float64", 1e300)
|
||||
}
|
||||
|
||||
maxFloat32 := float64((1<<24 - 1) << (127 - 23))
|
||||
if ovf := TypeFor[float32]().OverflowFloat(maxFloat32); ovf {
|
||||
t.Errorf("%v wrongly overflows float32", maxFloat32)
|
||||
}
|
||||
ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
|
||||
if ovf := TypeFor[float32]().OverflowFloat(ovfFloat32); !ovf {
|
||||
t.Errorf("%v should overflow float32", ovfFloat32)
|
||||
}
|
||||
if ovf := TypeFor[float32]().OverflowFloat(-ovfFloat32); !ovf {
|
||||
t.Errorf("%v should overflow float32", -ovfFloat32)
|
||||
}
|
||||
|
||||
maxInt32 := int64(0x7fffffff)
|
||||
if ovf := TypeFor[int32]().OverflowInt(maxInt32); ovf {
|
||||
t.Errorf("%v wrongly overflows int32", maxInt32)
|
||||
}
|
||||
if ovf := TypeFor[int32]().OverflowInt(-1 << 31); ovf {
|
||||
t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
|
||||
}
|
||||
ovfInt32 := int64(1 << 31)
|
||||
if ovf := TypeFor[int32]().OverflowInt(ovfInt32); !ovf {
|
||||
t.Errorf("%v should overflow int32", ovfInt32)
|
||||
}
|
||||
|
||||
maxUint32 := uint64(0xffffffff)
|
||||
if ovf := TypeFor[uint32]().OverflowUint(maxUint32); ovf {
|
||||
t.Errorf("%v wrongly overflows uint32", maxUint32)
|
||||
}
|
||||
ovfUint32 := uint64(1 << 32)
|
||||
if ovf := TypeFor[uint32]().OverflowUint(ovfUint32); !ovf {
|
||||
t.Errorf("%v should overflow uint32", ovfUint32)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
func checkSameType(t *testing.T, x Type, y any) {
|
||||
|
||||
+74
-4
@@ -392,6 +392,22 @@ type Type interface {
|
||||
// It panics if the type's Kind is not Func.
|
||||
// It panics if i is not in the range [0, NumOut()).
|
||||
Out(i int) Type
|
||||
|
||||
// OverflowComplex reports whether the complex128 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Complex64 or Complex128.
|
||||
OverflowComplex(x complex128) bool
|
||||
|
||||
// OverflowFloat reports whether the float64 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Float32 or Float64.
|
||||
OverflowFloat(x float64) bool
|
||||
|
||||
// OverflowInt reports whether the int64 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Int, Int8, Int16, Int32, or Int64.
|
||||
OverflowInt(x int64) bool
|
||||
|
||||
// OverflowUint reports whether the uint64 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
|
||||
OverflowUint(x uint64) bool
|
||||
}
|
||||
|
||||
// Constants for the 'meta' byte.
|
||||
@@ -404,7 +420,7 @@ const (
|
||||
|
||||
// The base type struct. All type structs start with this.
|
||||
type rawType struct {
|
||||
meta uint8 // metadata byte, contains kind and flags (see contants above)
|
||||
meta uint8 // metadata byte, contains kind and flags (see constants above)
|
||||
}
|
||||
|
||||
// All types that have an element type: named, chan, slice, array, map (but not
|
||||
@@ -774,7 +790,7 @@ func (t *rawType) rawFieldByNameFunc(match func(string) bool) (rawStructField, [
|
||||
if match(name) {
|
||||
found = append(found, result{
|
||||
rawStructFieldFromPointer(descriptor, field.fieldType, data, flagsByte, name, offset),
|
||||
append(ll.index, int(i)),
|
||||
append(ll.index[:len(ll.index):len(ll.index)], int(i)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -787,7 +803,7 @@ func (t *rawType) rawFieldByNameFunc(match func(string) bool) (rawStructField, [
|
||||
|
||||
nextlevel = append(nextlevel, fieldWalker{
|
||||
t: embedded,
|
||||
index: append(ll.index, int(i)),
|
||||
index: append(ll.index[:len(ll.index):len(ll.index)], int(i)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1060,8 +1076,10 @@ func (t *rawType) Name() string {
|
||||
panic("corrupt name data")
|
||||
}
|
||||
|
||||
if t.Kind() <= UnsafePointer {
|
||||
if kind := t.Kind(); kind < UnsafePointer {
|
||||
return t.Kind().String()
|
||||
} else if kind == UnsafePointer {
|
||||
return "Pointer"
|
||||
}
|
||||
|
||||
return ""
|
||||
@@ -1079,6 +1097,58 @@ func (t rawType) Out(i int) Type {
|
||||
panic("unimplemented: (reflect.Type).Out()")
|
||||
}
|
||||
|
||||
// OverflowComplex reports whether the complex128 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Complex64 or Complex128.
|
||||
func (t rawType) OverflowComplex(x complex128) bool {
|
||||
k := t.Kind()
|
||||
switch k {
|
||||
case Complex64:
|
||||
return overflowFloat32(real(x)) || overflowFloat32(imag(x))
|
||||
case Complex128:
|
||||
return false
|
||||
}
|
||||
panic("reflect: OverflowComplex of non-complex type")
|
||||
}
|
||||
|
||||
// OverflowFloat reports whether the float64 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Float32 or Float64.
|
||||
func (t rawType) OverflowFloat(x float64) bool {
|
||||
k := t.Kind()
|
||||
switch k {
|
||||
case Float32:
|
||||
return overflowFloat32(x)
|
||||
case Float64:
|
||||
return false
|
||||
}
|
||||
panic("reflect: OverflowFloat of non-float type")
|
||||
}
|
||||
|
||||
// OverflowInt reports whether the int64 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Int, Int8, Int16, Int32, or Int64.
|
||||
func (t rawType) OverflowInt(x int64) bool {
|
||||
k := t.Kind()
|
||||
switch k {
|
||||
case Int, Int8, Int16, Int32, Int64:
|
||||
bitSize := t.Size() * 8
|
||||
trunc := (x << (64 - bitSize)) >> (64 - bitSize)
|
||||
return x != trunc
|
||||
}
|
||||
panic("reflect: OverflowInt of non-int type")
|
||||
}
|
||||
|
||||
// OverflowUint reports whether the uint64 x cannot be represented by type t.
|
||||
// It panics if t's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
|
||||
func (t rawType) OverflowUint(x uint64) bool {
|
||||
k := t.Kind()
|
||||
switch k {
|
||||
case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
|
||||
bitSize := t.Size() * 8
|
||||
trunc := (x << (64 - bitSize)) >> (64 - bitSize)
|
||||
return x != trunc
|
||||
}
|
||||
panic("reflect: OverflowUint of non-uint type")
|
||||
}
|
||||
|
||||
func (t rawType) Method(i int) Method {
|
||||
panic("unimplemented: (reflect.Type).Method()")
|
||||
}
|
||||
|
||||
+16
-29
@@ -646,10 +646,10 @@ func (v Value) Slice3(i, j, k int) Value {
|
||||
panic("unimplemented: (reflect.Value).Slice3()")
|
||||
}
|
||||
|
||||
//go:linkname maplen runtime.hashmapLenUnsafePointer
|
||||
//go:linkname maplen runtime.hashmapLen
|
||||
func maplen(p unsafe.Pointer) int
|
||||
|
||||
//go:linkname chanlen runtime.chanLenUnsafePointer
|
||||
//go:linkname chanlen runtime.chanLen
|
||||
func chanlen(p unsafe.Pointer) int
|
||||
|
||||
// Len returns the length of this value for slices, strings, arrays, channels,
|
||||
@@ -671,7 +671,7 @@ func (v Value) Len() int {
|
||||
}
|
||||
}
|
||||
|
||||
//go:linkname chancap runtime.chanCapUnsafePointer
|
||||
//go:linkname chancap runtime.chanCap
|
||||
func chancap(p unsafe.Pointer) int
|
||||
|
||||
// Cap returns the capacity of this value for arrays, channels and slices.
|
||||
@@ -965,13 +965,13 @@ func (v Value) MapKeys() []Value {
|
||||
return keys
|
||||
}
|
||||
|
||||
//go:linkname hashmapStringGet runtime.hashmapStringGetUnsafePointer
|
||||
//go:linkname hashmapStringGet runtime.hashmapStringGet
|
||||
func hashmapStringGet(m unsafe.Pointer, key string, value unsafe.Pointer, valueSize uintptr) bool
|
||||
|
||||
//go:linkname hashmapBinaryGet runtime.hashmapBinaryGetUnsafePointer
|
||||
//go:linkname hashmapBinaryGet runtime.hashmapBinaryGet
|
||||
func hashmapBinaryGet(m unsafe.Pointer, key, value unsafe.Pointer, valueSize uintptr) bool
|
||||
|
||||
//go:linkname hashmapInterfaceGet runtime.hashmapInterfaceGetUnsafePointer
|
||||
//go:linkname hashmapInterfaceGet runtime.hashmapInterfaceGet
|
||||
func hashmapInterfaceGet(m unsafe.Pointer, key interface{}, value unsafe.Pointer, valueSize uintptr) bool
|
||||
|
||||
func (v Value) MapIndex(key Value) Value {
|
||||
@@ -982,9 +982,7 @@ func (v Value) MapIndex(key Value) Value {
|
||||
vkey := v.typecode.key()
|
||||
|
||||
// compare key type with actual key type of map
|
||||
// AssignableTo is not implemented for interfaces
|
||||
// avoid: "reflect: unimplemented: AssignableTo with interface"
|
||||
if vkey.Kind() != Interface && !key.typecode.AssignableTo(vkey) {
|
||||
if !key.typecode.AssignableTo(vkey) {
|
||||
// type error?
|
||||
panic("reflect.Value.MapIndex: incompatible types for key")
|
||||
}
|
||||
@@ -1020,7 +1018,7 @@ func (v Value) MapIndex(key Value) Value {
|
||||
//go:linkname hashmapNewIterator runtime.hashmapNewIterator
|
||||
func hashmapNewIterator() unsafe.Pointer
|
||||
|
||||
//go:linkname hashmapNext runtime.hashmapNextUnsafePointer
|
||||
//go:linkname hashmapNext runtime.hashmapNext
|
||||
func hashmapNext(m unsafe.Pointer, it unsafe.Pointer, key, value unsafe.Pointer) bool
|
||||
|
||||
func (v Value) MapRange() *MapIter {
|
||||
@@ -1714,18 +1712,7 @@ func extendSlice(v Value, n int) sliceHeader {
|
||||
old = *(*sliceHeader)(v.value)
|
||||
}
|
||||
|
||||
var nbuf unsafe.Pointer
|
||||
var nlen, ncap uintptr
|
||||
|
||||
if old.len+uintptr(n) > old.cap {
|
||||
// we need to grow the slice
|
||||
nbuf, nlen, ncap = sliceGrow(old.data, old.len, old.cap, old.cap+uintptr(n), v.typecode.elem().Size())
|
||||
} else {
|
||||
// we can reuse the slice we have
|
||||
nbuf = old.data
|
||||
nlen = old.len
|
||||
ncap = old.cap
|
||||
}
|
||||
nbuf, nlen, ncap := sliceGrow(old.data, old.len, old.cap, old.len+uintptr(n), v.typecode.elem().Size())
|
||||
|
||||
return sliceHeader{
|
||||
data: nbuf,
|
||||
@@ -1799,22 +1786,22 @@ func (v Value) Grow(n int) {
|
||||
slice.cap = newslice.cap
|
||||
}
|
||||
|
||||
//go:linkname hashmapStringSet runtime.hashmapStringSetUnsafePointer
|
||||
//go:linkname hashmapStringSet runtime.hashmapStringSet
|
||||
func hashmapStringSet(m unsafe.Pointer, key string, value unsafe.Pointer)
|
||||
|
||||
//go:linkname hashmapBinarySet runtime.hashmapBinarySetUnsafePointer
|
||||
//go:linkname hashmapBinarySet runtime.hashmapBinarySet
|
||||
func hashmapBinarySet(m unsafe.Pointer, key, value unsafe.Pointer)
|
||||
|
||||
//go:linkname hashmapInterfaceSet runtime.hashmapInterfaceSetUnsafePointer
|
||||
//go:linkname hashmapInterfaceSet runtime.hashmapInterfaceSet
|
||||
func hashmapInterfaceSet(m unsafe.Pointer, key interface{}, value unsafe.Pointer)
|
||||
|
||||
//go:linkname hashmapStringDelete runtime.hashmapStringDeleteUnsafePointer
|
||||
//go:linkname hashmapStringDelete runtime.hashmapStringDelete
|
||||
func hashmapStringDelete(m unsafe.Pointer, key string)
|
||||
|
||||
//go:linkname hashmapBinaryDelete runtime.hashmapBinaryDeleteUnsafePointer
|
||||
//go:linkname hashmapBinaryDelete runtime.hashmapBinaryDelete
|
||||
func hashmapBinaryDelete(m unsafe.Pointer, key unsafe.Pointer)
|
||||
|
||||
//go:linkname hashmapInterfaceDelete runtime.hashmapInterfaceDeleteUnsafePointer
|
||||
//go:linkname hashmapInterfaceDelete runtime.hashmapInterfaceDelete
|
||||
func hashmapInterfaceDelete(m unsafe.Pointer, key interface{})
|
||||
|
||||
func (v Value) SetMapIndex(key, elem Value) {
|
||||
@@ -1943,7 +1930,7 @@ func (v Value) FieldByNameFunc(match func(string) bool) Value {
|
||||
return Value{}
|
||||
}
|
||||
|
||||
//go:linkname hashmapMake runtime.hashmapMakeUnsafePointer
|
||||
//go:linkname hashmapMake runtime.hashmapMake
|
||||
func hashmapMake(keySize, valueSize uintptr, sizeHint uintptr, alg uint8) unsafe.Pointer
|
||||
|
||||
// MakeMapWithSize creates a new map with the specified type and initial space
|
||||
|
||||
@@ -164,7 +164,7 @@ func TestTinyMap(t *testing.T) {
|
||||
// make sure we can get it out
|
||||
v2 := refut.MapIndex(ValueOf(unmarshalerText{"x", "y"}))
|
||||
if !v2.IsValid() || !v2.Bool() {
|
||||
t.Errorf("Failed to look up map struct key with refection")
|
||||
t.Errorf("Failed to look up map struct key with reflection")
|
||||
}
|
||||
|
||||
// put in a key with reflection
|
||||
|
||||
@@ -9,7 +9,12 @@ const deferExtraRegs = 0
|
||||
|
||||
const callInstSize = 5 // "call someFunction" is 5 bytes
|
||||
|
||||
const linux_MAP_ANONYMOUS = 0x20
|
||||
const (
|
||||
linux_MAP_ANONYMOUS = 0x20
|
||||
linux_SIGBUS = 7
|
||||
linux_SIGILL = 4
|
||||
linux_SIGSEGV = 11
|
||||
)
|
||||
|
||||
// Align on word boundary.
|
||||
func align(ptr uintptr) uintptr {
|
||||
|
||||
@@ -9,7 +9,12 @@ const deferExtraRegs = 0
|
||||
|
||||
const callInstSize = 5 // "call someFunction" is 5 bytes
|
||||
|
||||
const linux_MAP_ANONYMOUS = 0x20
|
||||
const (
|
||||
linux_MAP_ANONYMOUS = 0x20
|
||||
linux_SIGBUS = 7
|
||||
linux_SIGILL = 4
|
||||
linux_SIGSEGV = 11
|
||||
)
|
||||
|
||||
// Align a pointer.
|
||||
// Note that some amd64 instructions (like movaps) expect 16-byte aligned
|
||||
|
||||
@@ -11,7 +11,12 @@ const deferExtraRegs = 0
|
||||
|
||||
const callInstSize = 4 // "bl someFunction" is 4 bytes
|
||||
|
||||
const linux_MAP_ANONYMOUS = 0x20
|
||||
const (
|
||||
linux_MAP_ANONYMOUS = 0x20
|
||||
linux_SIGBUS = 7
|
||||
linux_SIGILL = 4
|
||||
linux_SIGSEGV = 11
|
||||
)
|
||||
|
||||
// Align on the maximum alignment for this platform (double).
|
||||
func align(ptr uintptr) uintptr {
|
||||
|
||||
@@ -9,7 +9,12 @@ const deferExtraRegs = 0
|
||||
|
||||
const callInstSize = 4 // "bl someFunction" is 4 bytes
|
||||
|
||||
const linux_MAP_ANONYMOUS = 0x20
|
||||
const (
|
||||
linux_MAP_ANONYMOUS = 0x20
|
||||
linux_SIGBUS = 7
|
||||
linux_SIGILL = 4
|
||||
linux_SIGSEGV = 11
|
||||
)
|
||||
|
||||
// Align on word boundary.
|
||||
func align(ptr uintptr) uintptr {
|
||||
|
||||
@@ -9,7 +9,12 @@ const deferExtraRegs = 0
|
||||
|
||||
const callInstSize = 8 // "jal someFunc" is 4 bytes, plus a MIPS delay slot
|
||||
|
||||
const linux_MAP_ANONYMOUS = 0x800
|
||||
const (
|
||||
linux_MAP_ANONYMOUS = 0x800
|
||||
linux_SIGBUS = 10
|
||||
linux_SIGILL = 4
|
||||
linux_SIGSEGV = 11
|
||||
)
|
||||
|
||||
// It appears that MIPS has a maximum alignment of 8 bytes.
|
||||
func align(ptr uintptr) uintptr {
|
||||
|
||||
@@ -9,7 +9,12 @@ const deferExtraRegs = 0
|
||||
|
||||
const callInstSize = 8 // "jal someFunc" is 4 bytes, plus a MIPS delay slot
|
||||
|
||||
const linux_MAP_ANONYMOUS = 0x800
|
||||
const (
|
||||
linux_MAP_ANONYMOUS = 0x800
|
||||
linux_SIGBUS = 10
|
||||
linux_SIGILL = 4
|
||||
linux_SIGSEGV = 11
|
||||
)
|
||||
|
||||
// It appears that MIPS has a maximum alignment of 8 bytes.
|
||||
func align(ptr uintptr) uintptr {
|
||||
|
||||
@@ -148,12 +148,6 @@ func chanLen(c *channel) int {
|
||||
return int(c.bufUsed)
|
||||
}
|
||||
|
||||
// wrapper for use in reflect
|
||||
func chanLenUnsafePointer(p unsafe.Pointer) int {
|
||||
c := (*channel)(p)
|
||||
return chanLen(c)
|
||||
}
|
||||
|
||||
// Return the capacity of this chan, called from the cap builtin.
|
||||
// A nil chan is defined as having capacity 0.
|
||||
//
|
||||
@@ -165,12 +159,6 @@ func chanCap(c *channel) int {
|
||||
return int(c.bufSize)
|
||||
}
|
||||
|
||||
// wrapper for use in reflect
|
||||
func chanCapUnsafePointer(p unsafe.Pointer) int {
|
||||
c := (*channel)(p)
|
||||
return chanCap(c)
|
||||
}
|
||||
|
||||
// resumeRX resumes the next receiver and returns the destination pointer.
|
||||
// If the ok value is true, then the caller is expected to store a value into this pointer.
|
||||
func (ch *channel) resumeRX(ok bool) unsafe.Pointer {
|
||||
|
||||
@@ -26,7 +26,7 @@ type stackChainObject struct {
|
||||
//
|
||||
// Therefore, we only need to scan the system stack.
|
||||
// It is relatively easy to scan the system stack while we're on it: we can
|
||||
// simply read __stack_pointer and __global_base and scan the area inbetween.
|
||||
// simply read __stack_pointer and __global_base and scan the area in between.
|
||||
// Unfortunately, it's hard to get the system stack pointer while we're on a
|
||||
// goroutine stack. But when we're on a goroutine stack, the system stack is in
|
||||
// the scheduler which means there shouldn't be anything on the system stack
|
||||
|
||||
@@ -87,10 +87,6 @@ func hashmapMake(keySize, valueSize uintptr, sizeHint uintptr, alg uint8) *hashm
|
||||
}
|
||||
}
|
||||
|
||||
func hashmapMakeUnsafePointer(keySize, valueSize uintptr, sizeHint uintptr, alg uint8) unsafe.Pointer {
|
||||
return (unsafe.Pointer)(hashmapMake(keySize, valueSize, sizeHint, alg))
|
||||
}
|
||||
|
||||
// Remove all entries from the map, without actually deallocating the space for
|
||||
// it. This is used for the clear builtin, and can be used to reuse a map (to
|
||||
// avoid extra heap allocations).
|
||||
@@ -178,10 +174,6 @@ func hashmapLen(m *hashmap) int {
|
||||
return int(m.count)
|
||||
}
|
||||
|
||||
func hashmapLenUnsafePointer(m unsafe.Pointer) int {
|
||||
return hashmapLen((*hashmap)(m))
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func hashmapBucketSize(m *hashmap) uintptr {
|
||||
return unsafe.Sizeof(hashmapBucket{}) + uintptr(m.keySize)*8 + uintptr(m.valueSize)*8
|
||||
@@ -268,10 +260,6 @@ func hashmapSet(m *hashmap, key unsafe.Pointer, value unsafe.Pointer, hash uint3
|
||||
*emptySlotTophash = tophash
|
||||
}
|
||||
|
||||
func hashmapSetUnsafePointer(m unsafe.Pointer, key unsafe.Pointer, value unsafe.Pointer, hash uint32) {
|
||||
hashmapSet((*hashmap)(m), key, value, hash)
|
||||
}
|
||||
|
||||
// hashmapInsertIntoNewBucket creates a new bucket, inserts the given key and
|
||||
// value into the bucket, and returns a pointer to this bucket.
|
||||
func hashmapInsertIntoNewBucket(m *hashmap, key, value unsafe.Pointer, tophash uint8) *hashmapBucket {
|
||||
@@ -352,10 +340,6 @@ func hashmapGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr, hash u
|
||||
return false
|
||||
}
|
||||
|
||||
func hashmapGetUnsafePointer(m unsafe.Pointer, key, value unsafe.Pointer, valueSize uintptr, hash uint32) bool {
|
||||
return hashmapGet((*hashmap)(m), key, value, valueSize, hash)
|
||||
}
|
||||
|
||||
// Delete a given key from the map. No-op when the key does not exist in the
|
||||
// map.
|
||||
//
|
||||
@@ -456,10 +440,6 @@ func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) boo
|
||||
}
|
||||
}
|
||||
|
||||
func hashmapNextUnsafePointer(m unsafe.Pointer, it unsafe.Pointer, key, value unsafe.Pointer) bool {
|
||||
return hashmapNext((*hashmap)(m), (*hashmapIterator)(it), key, value)
|
||||
}
|
||||
|
||||
// Hashmap with plain binary data keys (not containing strings etc.).
|
||||
func hashmapBinarySet(m *hashmap, key, value unsafe.Pointer) {
|
||||
if m == nil {
|
||||
@@ -469,10 +449,6 @@ func hashmapBinarySet(m *hashmap, key, value unsafe.Pointer) {
|
||||
hashmapSet(m, key, value, hash)
|
||||
}
|
||||
|
||||
func hashmapBinarySetUnsafePointer(m unsafe.Pointer, key, value unsafe.Pointer) {
|
||||
hashmapBinarySet((*hashmap)(m), key, value)
|
||||
}
|
||||
|
||||
func hashmapBinaryGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr) bool {
|
||||
if m == nil {
|
||||
memzero(value, uintptr(valueSize))
|
||||
@@ -482,10 +458,6 @@ func hashmapBinaryGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr)
|
||||
return hashmapGet(m, key, value, valueSize, hash)
|
||||
}
|
||||
|
||||
func hashmapBinaryGetUnsafePointer(m unsafe.Pointer, key, value unsafe.Pointer, valueSize uintptr) bool {
|
||||
return hashmapBinaryGet((*hashmap)(m), key, value, valueSize)
|
||||
}
|
||||
|
||||
func hashmapBinaryDelete(m *hashmap, key unsafe.Pointer) {
|
||||
if m == nil {
|
||||
return
|
||||
@@ -494,10 +466,6 @@ func hashmapBinaryDelete(m *hashmap, key unsafe.Pointer) {
|
||||
hashmapDelete(m, key, hash)
|
||||
}
|
||||
|
||||
func hashmapBinaryDeleteUnsafePointer(m unsafe.Pointer, key unsafe.Pointer) {
|
||||
hashmapBinaryDelete((*hashmap)(m), key)
|
||||
}
|
||||
|
||||
// Hashmap with string keys (a common case).
|
||||
|
||||
func hashmapStringEqual(x, y unsafe.Pointer, n uintptr) bool {
|
||||
@@ -522,10 +490,6 @@ func hashmapStringSet(m *hashmap, key string, value unsafe.Pointer) {
|
||||
hashmapSet(m, unsafe.Pointer(&key), value, hash)
|
||||
}
|
||||
|
||||
func hashmapStringSetUnsafePointer(m unsafe.Pointer, key string, value unsafe.Pointer) {
|
||||
hashmapStringSet((*hashmap)(m), key, value)
|
||||
}
|
||||
|
||||
func hashmapStringGet(m *hashmap, key string, value unsafe.Pointer, valueSize uintptr) bool {
|
||||
if m == nil {
|
||||
memzero(value, uintptr(valueSize))
|
||||
@@ -535,10 +499,6 @@ func hashmapStringGet(m *hashmap, key string, value unsafe.Pointer, valueSize ui
|
||||
return hashmapGet(m, unsafe.Pointer(&key), value, valueSize, hash)
|
||||
}
|
||||
|
||||
func hashmapStringGetUnsafePointer(m unsafe.Pointer, key string, value unsafe.Pointer, valueSize uintptr) bool {
|
||||
return hashmapStringGet((*hashmap)(m), key, value, valueSize)
|
||||
}
|
||||
|
||||
func hashmapStringDelete(m *hashmap, key string) {
|
||||
if m == nil {
|
||||
return
|
||||
@@ -547,10 +507,6 @@ func hashmapStringDelete(m *hashmap, key string) {
|
||||
hashmapDelete(m, unsafe.Pointer(&key), hash)
|
||||
}
|
||||
|
||||
func hashmapStringDeleteUnsafePointer(m unsafe.Pointer, key string) {
|
||||
hashmapStringDelete((*hashmap)(m), key)
|
||||
}
|
||||
|
||||
// Hashmap with interface keys (for everything else).
|
||||
|
||||
// This is a method that is intentionally unexported in the reflect package. It
|
||||
@@ -654,10 +610,6 @@ func hashmapInterfaceSet(m *hashmap, key interface{}, value unsafe.Pointer) {
|
||||
hashmapSet(m, unsafe.Pointer(&key), value, hash)
|
||||
}
|
||||
|
||||
func hashmapInterfaceSetUnsafePointer(m unsafe.Pointer, key interface{}, value unsafe.Pointer) {
|
||||
hashmapInterfaceSet((*hashmap)(m), key, value)
|
||||
}
|
||||
|
||||
func hashmapInterfaceGet(m *hashmap, key interface{}, value unsafe.Pointer, valueSize uintptr) bool {
|
||||
if m == nil {
|
||||
memzero(value, uintptr(valueSize))
|
||||
@@ -667,10 +619,6 @@ func hashmapInterfaceGet(m *hashmap, key interface{}, value unsafe.Pointer, valu
|
||||
return hashmapGet(m, unsafe.Pointer(&key), value, valueSize, hash)
|
||||
}
|
||||
|
||||
func hashmapInterfaceGetUnsafePointer(m unsafe.Pointer, key interface{}, value unsafe.Pointer, valueSize uintptr) bool {
|
||||
return hashmapInterfaceGet((*hashmap)(m), key, value, valueSize)
|
||||
}
|
||||
|
||||
func hashmapInterfaceDelete(m *hashmap, key interface{}) {
|
||||
if m == nil {
|
||||
return
|
||||
@@ -678,7 +626,3 @@ func hashmapInterfaceDelete(m *hashmap, key interface{}) {
|
||||
hash := hashmapInterfaceHash(key, m.seed)
|
||||
hashmapDelete(m, unsafe.Pointer(&key), hash)
|
||||
}
|
||||
|
||||
func hashmapInterfaceDeleteUnsafePointer(m unsafe.Pointer, key interface{}) {
|
||||
hashmapInterfaceDelete((*hashmap)(m), key)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func Disable() (state State) {
|
||||
// Restore restores interrupts to what they were before. Give the previous state
|
||||
// returned by Disable as a parameter. If interrupts were disabled before
|
||||
// calling Disable, this will not re-enable interrupts, allowing for nested
|
||||
// cricital sections.
|
||||
// critical sections.
|
||||
func Restore(state State) {
|
||||
// SREG is at I/O address 0x3f.
|
||||
device.AsmFull("out 0x3f, {state}", map[string]interface{}{
|
||||
|
||||
@@ -46,7 +46,7 @@ func Disable() (state State) {
|
||||
// Restore restores interrupts to what they were before. Give the previous state
|
||||
// returned by Disable as a parameter. If interrupts were disabled before
|
||||
// calling Disable, this will not re-enable interrupts, allowing for nested
|
||||
// cricital sections.
|
||||
// critical sections.
|
||||
func Restore(state State) {
|
||||
arm.EnableInterrupts(uintptr(state))
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ func handleException(mcause uintptr) {
|
||||
println("*** Exception: mcause:", mcause)
|
||||
switch uint32(mcause & 0x1f) {
|
||||
case 1:
|
||||
println("*** virtual addess:", riscv.MTVAL.Get())
|
||||
println("*** virtual address:", riscv.MTVAL.Get())
|
||||
case 2:
|
||||
println("*** opcode:", riscv.MTVAL.Get())
|
||||
case 5:
|
||||
|
||||
@@ -92,7 +92,7 @@ func Disable() (state State) {
|
||||
// Restore restores interrupts to what they were before. Give the previous state
|
||||
// returned by Disable as a parameter. If interrupts were disabled before
|
||||
// calling Disable, this will not re-enable interrupts, allowing for nested
|
||||
// cricital sections.
|
||||
// critical sections.
|
||||
func Restore(state State) {
|
||||
// Restore interrupts to the previous state.
|
||||
gba.INTERRUPT.PAUSE.Set(uint16(state))
|
||||
|
||||
@@ -21,7 +21,7 @@ func Disable() (state State) {
|
||||
// Restore restores interrupts to what they were before. Give the previous state
|
||||
// returned by Disable as a parameter. If interrupts were disabled before
|
||||
// calling Disable, this will not re-enable interrupts, allowing for nested
|
||||
// cricital sections.
|
||||
// critical sections.
|
||||
func Restore(state State) {}
|
||||
|
||||
// In returns whether the system is currently in an interrupt.
|
||||
|
||||
@@ -23,7 +23,7 @@ func Disable() (state State) {
|
||||
// Restore restores interrupts to what they were before. Give the previous state
|
||||
// returned by Disable as a parameter. If interrupts were disabled before
|
||||
// calling Disable, this will not re-enable interrupts, allowing for nested
|
||||
// cricital sections.
|
||||
// critical sections.
|
||||
func Restore(state State) {
|
||||
riscv.EnableInterrupts(uintptr(state))
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user