Compare commits

...

50 Commits

Author SHA1 Message Date
Ayke van Laethem ef4f46f1d1 all: version 0.33.0 2024-08-20 09:21:48 +02:00
Ayke van Laethem 16cd500000 ci: update apt repo for sizediff toolchain
This was still at jammy (22.04), while the CI container was noble
(24.04). Somehow this didn't break, but it certainly isn't ideal to
install packages across Ubuntu versions!
2024-08-20 08:33:49 +02:00
deadprogram 16950780d3 targets: remove import-memory flag from wasm-unknown target to fix #4319
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-08-17 18:16:39 +02:00
Ayke van Laethem 7e284a37fc ci: use Go 1.23 2024-08-17 11:49:14 +02:00
Ayke van Laethem b6c53a6f0e darwin: work around a linker error for the mime/quotedprintable tests
This is needed for Go 1.23 support.

These functions should ideally get implemented. Until that's done, just
panic here. Apparently panicking in internal/abi.FuncPCABI0 is enough to
fix all linker errors for mime/quotedprintable.
2024-08-17 11:49:14 +02:00
Ayke van Laethem 8b626e6ea7 compiler: add support for Go 1.23 range-over-func 2024-08-17 11:49:14 +02:00
Ayke van Laethem 1d1f4fc401 syscall: add all MacOS errno values
ELOOP is used starting with Go 1.23. But I figured I could just add the
whole set.
2024-08-17 11:49:14 +02:00
Ayke van Laethem 250426c1e5 sync: add Map.Clear()
This was added in Go 1.23 and is needed for the net/mail package.
2024-08-17 11:49:14 +02:00
Ayke van Laethem e300e90a63 reflect: implement Type.Overflow* functions
They're already implemented for the Value equivalents. But since Go
1.23, such methods also exist for reflect.Type.
2024-08-17 11:49:14 +02:00
Ayke van Laethem e865db232b runtime: implement timers for Go 1.23
There were a number of changes in time.Timer/time.Ticker that need a
separate implementation for Go 1.22 and Go 1.23.
2024-08-17 11:49:14 +02:00
Ayke van Laethem db2a06a9bb internal/abi: implement initial version of this package
This package can never be a full version as seen in upstream Go, because
TinyGo is very different. But it is necessary to define so that no code
can accidentally use this package (now or in the future).

It currently defines:

  - NoEscape which is needed by strings.Builder since Go 1.23.
  - FuncPCABI* which is needed by internal/syscall/unix on MacOS.
2024-08-17 11:49:14 +02:00
Ayke van Laethem 560fd0a558 unique: implement custom version of unique package
This version probably isn't as fast as the upstream version, but it is
good enough for now. It also doesn't free unreferenced handles like the
upstream version.
2024-08-17 11:49:14 +02:00
Ayke van Laethem b8048112df internal/bytealg: add CompareString
This function was added to Go many years ago, but is starting to be used
in packages in Go 1.23.
2024-08-17 11:49:14 +02:00
Ayke van Laethem b51cda9721 sync/atomic: add And* and Or* compiler intrinsics needed for Go 1.23 2024-08-17 11:49:14 +02:00
Damian Gryski 4d60d679d3 compiler: fixup Sprintf uses 2024-08-15 13:57:02 +02:00
Damian Gryski 9932f2e126 builder: os.SEEK_CUR -> io.SeekCurrent 2024-08-15 13:57:02 +02:00
Ayke van Laethem bf8d6460da os/user: use stdlib version of this package
I tried implementing enough CGo support to get the native os/user
package to work. But I hit a few bugs, probably in CGo itself. Then I
realized I could just as well set the osusergo build tag to disable CGo
for this specific case.

This actually gets the os/user package to work correctly on Linux (I
confirmed it returns my name/uid/homedir etc). On other systems, it
probably just returns an error if it can't determine these kinds of
things. But that's no worse than the current behavior which just doesn't
do anything at all.
2024-08-15 12:15:45 +02:00
Dan Kegel d3e67cf18c make spellfix: fix top level files, too.
Do manual fix in GNUmakefile, since spellchecking that is just too meta.
2024-08-15 10:34:35 +02:00
Dan Kegel 5d82a7eee6 misspell.csv: add another misspelling. Fix by hand, since spellfix is too timid to fix in non-whitespace context? 2024-08-15 10:34:35 +02:00
Dan Kegel c82ff057f5 Fix 'numer of', since 'NUMER' by itself is valid abbrev for numerator.
Oddly, misspell was not able to detect this one, even though in
theory it allows detecting multiword typos, so the fix was done by
hand.
2024-08-15 10:34:35 +02:00
Dan Kegel 5368dd22c5 misspell.csv: add new misspellings; also check in result of 'make spellfix'. 2024-08-15 10:34:35 +02:00
Ayke van Laethem 194396d715 unix: print a message when a fatal signal happens
Print a message for SIGBUS, SIGSEGV, and SIGILL when they happen.
These signals are always fatal, but it's very useful to know which of
them happened.

Also, it prints the location in the binary which can then be parsed by
`tinygo run` (see https://github.com/tinygo-org/tinygo/pull/4383).

While this does add some extra binary size, it's for Linux and MacOS
(systems that typically have plenty of RAM/storage) and could be very
useful when debugging some low-level crash such as a runtime bug.
2024-08-15 02:00:28 +02:00
Unrud 815784bd96 machine/usb/descriptor: Reset joystick physical 2024-08-14 18:43:27 +02:00
Unrud 7fc64a27b4 machine/usb/descriptor: Drop second joystick hat 2024-08-14 18:43:27 +02:00
Unrud c38bf27091 machine/usb/hid/joystick: Allow more hat switches 2024-08-14 18:43:27 +02:00
Unrud 9a2fab8874 machine/usb/descriptor: Add more HID... functions 2024-08-14 18:43:27 +02:00
Unrud f1516ad3ee machine/usb/descriptor: Fix encoding of values
The limit for positive values is incorrect and leads to an overflow (e.g. 0xFF and 0xFFFF become -1)
2024-08-14 18:43:27 +02:00
Ayke van Laethem 4dc07d6cc3 arm: support softfloat in GOARM environment variable
This adds softfloat support to GOARM, as proposed here:
https://github.com/golang/go/issues/61588

This is similar to https://github.com/tinygo-org/tinygo/pull/4189 but
with a few differences:

  * It is based on the work to support MIPS softfloat.
  * It fixes the issue that the default changed to softfloat everywhere.
    This PR defaults to softfloat on ARMv5 and hardfloat on ARMv6 and
    ARMv7.
  * It also compiles the C libraries (compiler-rt, musl) using the same
    soft/hard floating point support. This is important because
    otherwise a GOARM=7,softfloat binary could still contain hardware
    floating point instructions.
2024-08-14 16:25:42 +02:00
Ayke van Laethem a35b983a5d linux: use -musleabi* instead of -gnueabi* (or nothing)
This more accurately describes the libc we are using.
This also adds the environment to _all_ Linux systems, not just ARM. And
selects the correct ABI (soft/hardfloat) that's in use.

I don't know whether it has any practical implications, but LLVM appears
to be using this information so it seems wise to use the correct values.
2024-08-14 16:25:42 +02:00
Dan Kegel a47ff02c82 make spell: add a few missing misspellings, fix format of .csv file, also fix *.md 2024-08-14 12:00:55 +02:00
Dan Kegel e27b2c4ad6 circleci: our version of misspell is no longer supported with go < 1.21, so disable lint in go 1.19 ci job
I jumped through quite a few hoops to get test-llvm15-go119 to work, but this last hoop seems not worth jumping through:

  cd internal/tools && go generate -tags tools ./
  /go/pkg/mod/github.com/golangci/misspell@v0.6.0/mime.go:10:2: package slices is not in GOROOT (/usr/local/go/src/slices)
  tools.go:12: running "go": exit status 1
  make: *** [GNUmakefile:952: tools] Error 1

I mean, we could patch misspell to not use slices, or to use the prerelease slices, but...
2024-08-13 10:46:29 +02:00
dkegel-fastly 8135be4e90 GNUmakefile: add spellfix target, use it. (#4387)
TODO: Remove the go.mod/go.sum in internal/tools once doing so doesn't break CI (e.g. once we drop support for go 1.19)

* builder/cc1as.h: fix typo found by 'make spell'
* GNUmakefile: remove exception for inbetween, fix instance now found by 'make spell'
* GNUmakefile: remove exception for programmmer, fix instance now found by 'make spell'
* go.mod: use updated misspell. GNUmakefile: add spellfix target, use it.
* ignore directories properly when invoking spellchecker.
* make spell: give internal/tools its own go.mod, as misspell requires newer go
* make lint: depend on tools and run the installed revive
(which was perhaps implied by the change that added revive to internal/tools,
but not required in GNUmakefile until we gave internal/tools its own temporary go.mod)
* .github: now that 'make spell' works well, run it from CI
* GNUmakefile: make spell now aborts if it finds misspelt words, so what it finds doesn't get lost in CI logs
* GNUmakefile: tools: avoid -C option on go generate to make test-llvm15-go119 circleci job happy, see
https://cs.opensource.google/go/go/+/2af48cbb7d85e5fdc635e75b99f949010c607786
* internal/tools/go.mod: fix format of go version to leave out patchlevel, else go complains.
2024-08-12 14:24:38 -07:00
dkegel-fastly 835e73237e GNUmakefile: add "help" target (#4390)
Example output:

$ 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
lint                            Lint source tree
spell                           Spellcheck source tree

Might even work on windows, since git for windows comes with awk.
2024-08-12 10:19:16 -07:00
Ayke van Laethem eab1a5d7ec reflect, runtime: remove *UnsafePointer wrappers for functions
This was needed in the past because LLVM used typed pointers and there
was a mismatch between pointer types. But we've dropped support for
typed pointers a while ago so now we can remove these wrappers.

This is just a cleanup, it shouldn't have any practical effect.
2024-08-12 15:26:18 +02:00
Ayke van Laethem f188eaf5f9 mips: add GOMIPS=softfloat support
Previously, the compiler would default to hardfloat. This is not
supported by some MIPS CPUs.

This took me much longer than it should have because of a quirk in the
LLVM Mips backend: if the target-features string is not set (like during
LTO), the Mips backend picks the first function in the module and uses
that. Unfortunately, in the case of TinyGo this first function is
`llvm.dbg.value`, which is an LLVM intrinsic and doesn't have the
target-features string. I fixed it by adding a `-mllvm -mattr=` flag to
the linker.
2024-08-12 13:23:32 +02:00
Ayke van Laethem 6efc6d2bb6 compileopts: refactor defaultTarget function
Move triple calculation into defaultTarget. It was separate for historic
reasons that no longer apply. Merging the code makes future changes
easier (in particular, softfloat support).

The new code is actually shorter than the old code even though it has
more comments.
2024-08-12 13:23:32 +02:00
Roger Standridge d6e73b4c68 add os.Truncate(name, size) (see #4209)
See https://pkg.go.dev/os#Truncate
2024-08-11 02:42:30 -07:00
Ayke van Laethem 2e76cd3687 builder: interpret linker error messages
This shows nicely formatted error messages for missing symbol names and
for out-of-flash, out-of-RAM conditions (on microcontrollers with
limited flash/RAM).

Unfortunately the missing symbol name errors aren't available on Windows
and WebAssembly because the linker doesn't report source locations yet.
This is something that I could perhaps improve in LLD.
2024-08-11 01:48:11 -07:00
Ayke van Laethem 2eb39785fe cgo: add support for printf
The C printf function is sometimes needed for C files included using
CGo. This commit makes sure they're available on all systems where CGo
is fully supported (that is, everywhere except on AVR).

For baremetal systems using picolibc, I've picked the integer-only
version of printf to save on flash size. We might want to consider
providing a way to pick the floating point version instead, if needed.
2024-08-10 23:46:58 -07:00
Ayke van Laethem 3021e16bbf wasm: call __stdio_exit on exit
This flushes stdio, so that functions like puts and printf write out all
buffered data even if the output isn't connected to a terminal.

For discussion, see:
https://github.com/bytecodealliance/wasmtime/issues/7833
2024-08-10 23:46:58 -07:00
Ayke van Laethem 55f7d21ff5 builtins: add GENERIC_TF_SOURCES
This addes GENERIC_TF_SOURCES, which contains long double floating point
builtins (80 bit, 128 bit, etc).

This is needed for full printf support.
2024-08-10 23:46:58 -07:00
Kobayashi Shunta 841abb0903 feat: add node: specifier 2024-08-09 20:30:58 +02:00
Ayke van Laethem fb3d98ce6e compileopts: add CanonicalArchName to centralize arch detection
It's possible to detect the architecture from the target triple, but
there are a number of exceptions that make it unpleasant to use for this
purpose. There are just too many weird exceptions (like mips vs mipsel,
and armv6m vs thumv6m vs arm64 vs aarch64) so it's better to centralize
these to canonical architecture names.

I picked the architecture names that happen to match the musl
architecture names, because those seem the most natural to me.
2024-08-07 14:41:21 +02:00
Ayke van Laethem 020664591a main: show runtime panic addresses for tinygo run
This adds the same panic locations that are already present for
`tinygo flash -monitor`, but for `tinygo run` and `tinygo test`.

For example, this is the output that I get while working on some GC
code. It now shows the source location instead of just an address:

    $ tinygo test -v archive/zip
    === RUN   TestReader
    === RUN   TestReader/test.zip
    panic: runtime error at 0x000000000024d9b4: goroutine stack overflow
    [tinygo: panic at /home/ayke/src/tinygo/tinygo/src/internal/task/task_stack.go:58:15]
    FAIL    archive/zip     0.139s

(This particular location isn't all that useful, but it shows that the
feature works).
2024-08-06 13:28:07 +02:00
Ayke van Laethem 2d6d9eb76d ci: don't include prebuilt libraries in the release
These libraries will be automatically built when needed and cached.

The main reason these were needed is for play.tinygo.org, but I've now
prebuilt them there directly (so they don't need to be built for every
tarball).
2024-08-06 13:27:23 +02:00
leongross a8a532f9d6 os: add file.Truncate 2024-08-02 17:22:46 +02:00
L. Pereira 417a26d20c runtime: Simplify slice growing/appending code (#4287)
* reflect: rawFieldByNameFunc: copy index slice to avoid later overwrites

* runtime: Simplify slice growing/appending code

Refactor the slice appending function to rely on the slice growing
function, and remove branches/loops to use a branchfree variant.

Signed-off-by: L. Pereira <l.pereira@fastly.com>

* runtime: Remove one branch in sliceAppend()

Both branches were equivalent, so guard the overall logic in
sliceAppend() with the more general condition.

Signed-off-by: L. Pereira <l.pereira@fastly.com>

* runtime: Simplify slice growing calculation

Use `bits.Len()` rather than `32 - bits.LeadingZeros32()`.  They're
equivalent, but the Len version is a bit easier to read.

Signed-off-by: L. Pereira <l.pereira@fastly.com>

* reflect: Always call sliceGrow() in extendSlice()

sliceGrow() will return the old slice if its capacity is large enough.

Signed-off-by: L. Pereira <l.pereira@fastly.com>

---------

Signed-off-by: L. Pereira <l.pereira@fastly.com>
Co-authored-by: Damian Gryski <damian@gryski.com>
2024-07-31 13:20:12 -07:00
Ayke van Laethem 88f9fc3ce2 reflect: return correct name for unsafe.Pointer type
For some reason, the type kind name is "unsafe.Pointer" while the
.Name() method just returns "Pointer".

Not sure why this difference exists, but to be able to test .Name() in
testdata/reflect.go it needs to match.
2024-07-31 21:08:23 +02:00
Ayke van Laethem 84c376160f transform: use thinlto-pre-link passes
This improves compilation performance by about 5% in my quick test,
while increasing binary size on average by  0.13% when comparing the
smoke tests in the drivers repo (and about two thirds of that 0.13% is
actually caused by a single smoke test).

I think this is a good idea because it aligns the TinyGo optimization
sequence with what ThinLTO expects.
2024-07-31 21:07:20 +02:00
Ayke van Laethem 6184a6cd35 Revert "Getting DeepEqual to work with maps whose key is an interface (#4360)"
This reverts commit 1fd75ffbda.

The change is not correct and allows code to continue while it should
panic. For details, see:
https://github.com/tinygo-org/tinygo/pull/4360#issuecomment-2252943012
2024-07-29 14:10:02 +02:00
146 changed files with 2125 additions and 980 deletions
+5 -3
View File
@@ -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
+2 -2
View File
@@ -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 }}
+6 -4
View File
@@ -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
+1 -1
View File
@@ -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 \
+2
View File
@@ -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
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
+1 -1
View File
@@ -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
View File
@@ -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 "":
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+10
View File
@@ -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))
+2 -2
View File
@@ -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
View File
@@ -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}, "")
+1 -1
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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")
}
+1 -12
View File
@@ -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
)
+2 -31
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+30
View File
@@ -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
)
+56
View File
@@ -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=
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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{}
+2 -1
View File
@@ -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
View File
@@ -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])
+10 -50
View File
@@ -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
View File
@@ -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)
+41
View File
@@ -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
1 acces access
2 acuire acquire
3 addess address
4 adust adjust
5 allcoate allocate
6 alloated allocated
7 archtecture architecture
8 arcive archive
9 ardiuno arduino
10 beconfigured be configured
11 calcluate calculate
12 colum column
13 configration configuration
14 contants constants
15 cricital critical
16 deffered deferred
17 evaulator evaluator
18 evironment environment
19 freqency frequency
20 frquency frequency
21 implmented implemented
22 interrput interrupt
23 interrut interrupt
24 interupt interrupt
25 measuing measuring
26 numer of number of
27 orignal original
28 overrided overridden
29 poiners pointers
30 poitner pointer
31 probbably probably
32 recogized recognized
33 refection reflection
34 requries requires
35 satisifying satisfying
36 simulataneously simultaneously
37 suggets suggests
38 transmition transmission
39 undefied undefined
40 unecessary unnecessary
41 unsiged unsigned
+41 -19
View File
@@ -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
}
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
// Package abi exposes low-level details of the Go compiler/runtime
package abi
+10
View File
@@ -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
}
+14
View File
@@ -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")
}
+25
View File
@@ -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.
+2 -2
View File
@@ -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()
+2 -2
View File
@@ -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()
+1 -1
View File
@@ -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)
}
+2 -2
View File
@@ -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) {
}
+1 -1
View File
@@ -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:
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
}
+2 -2
View File
@@ -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:
+2 -2
View File
@@ -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
+4 -3
View File
@@ -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,
}),
},
}
+145 -142
View File
@@ -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)
}
+4 -6
View File
@@ -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,
+11 -5
View File
@@ -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)
}
+1
View File
@@ -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)
-10
View File
@@ -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 {
+25
View File
@@ -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.
+19
View File
@@ -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 {
+1 -1
View File
@@ -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)
}
}
+1 -1
View File
@@ -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)
}
}
+61
View File
@@ -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())
}
}
-59
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
+6 -1
View File
@@ -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 {
+6 -1
View File
@@ -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
+6 -1
View File
@@ -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 {
+6 -1
View File
@@ -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 {
+6 -1
View File
@@ -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 {
+6 -1
View File
@@ -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 {
-12
View File
@@ -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 {
+1 -1
View File
@@ -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
-56
View File
@@ -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)
}
+1 -1
View File
@@ -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{}{
+1 -1
View File
@@ -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))
}
+1 -1
View File
@@ -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))
+1 -1
View File
@@ -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