Граф коммитов

2399 коммитов

Автор SHA1 Сообщение Дата
Ayke van Laethem
869e917dc6 all: add support for windows/amd64
This uses Mingw-w64, which seems to be the de facto standard for porting
Unixy programs to Windows.
2021-11-16 11:08:30 +01:00
Ayke van Laethem
41bcad9c19 runtime: only use CRLF on baremetal systems
We should only do this on baremetal systems, not on Linux, macOS, and
Windows. In fact, Windows will convert LF into CRLF in its putchar
function.
2021-11-16 11:08:30 +01:00
Ayke van Laethem
73ab44c178 builder: support -size= flag on the esp32
This fixes a small mistake when calculating binary size for an Xtensa
file. Previously it would exit with the following error:

    $ tinygo build -o test.elf -size=short -target=esp32-mini32 examples/serial
    panic: runtime error: index out of range [65521] with length 18

Now it runs as expected:

    $ tinygo build -o test.elf -size=short -target=esp32-mini32 examples/serial
       code    data     bss |   flash     ram
       2897       0    4136 |    2897    4136
2021-11-16 07:42:58 +01:00
Dan Kegel
b70b6076e3 net/ip, syscall/errno: Reduce code duplication by switching to internal/itoa.
internal/itoa wasn't around back in go 1.12 days when tinygo's syscall/errno.go was written.
It was only added as of go 1.17 ( https://github.com/golang/go/commit/061a6903a232cb868780b )
so we have to have an internal copy for now.
The internal copy should be deleted when tinygo drops support for go 1.16.

FWIW, the new version seems nicer.
It uses no allocations when converting 0,
and although the optimizer might make this moot, uses
a multiplication x 10 instead of a mod operation.
2021-11-16 02:13:52 +01:00
sago35
7b41d92198 device: add build tag for go1.17 2021-11-16 02:10:03 +01:00
Ayke van Laethem
2f4f3bd1ba wasi: restore support for -scheduler=none
The assembly symbols were not marked as hidden and so were exported,
leading to unreferenced symbols.

Example error message:

    Error: failed to run main module `/tmp/tinygo3961039405/main`

    Caused by:
        0: failed to instantiate "/tmp/tinygo3961039405/main"
        1: unknown import: `asyncify::stop_rewind` has not been defined

This commit fixes this issue.
2021-11-15 22:17:40 +01:00
Ayke van Laethem
7cb44fb373 all: add support for GOARM
This environment variable can be set to 5, 6, or 7 and controls which
ARM version (ARMv5, ARMv6, ARMv7) is used when compiling for GOARCH=arm.

I have picked the default value ARMv6, which I believe is supported on
most common single board computers including all Raspberry Pis. The
difference in code size is pretty big.

We could even go further and support ARMv4 if anybody is interested. It
should be pretty simple to add this if needed.
2021-11-15 11:53:44 +01:00
Ayke van Laethem
73ad825b67 ci: update Windows runner to windows-2019
The windows-2016 runner will soon be removed:
https://github.blog/changelog/2021-10-19-github-actions-the-windows-2016-runner-image-will-be-removed-from-github-hosted-runners-on-march-15-2022/
Therefore, switch to the next version.
2021-11-14 13:18:54 +01:00
Nia Waldvogel
539e1324c8 fix binaryen build in docker
Oops I forgot to install cmake and ninja.
2021-11-14 10:49:28 +01:00
Nia Waldvogel
641dcd7c16 internal/task: use asyncify on webassembly
This change implements a new "scheduler" for WebAssembly using binaryen's asyncify transform.
This is more reliable than the current "coroutines" transform, and works with non-Go code in the call stack.

runtime (js/wasm): handle scheduler nesting

If WASM calls into JS which calls back into WASM, it is possible for the scheduler to nest.
The event from the callback must be handled immediately, so the task cannot simply be deferred to the outer scheduler.
This creates a minimal scheduler loop which is used to handle such nesting.
2021-11-14 10:49:28 +01:00
Yurii Soldak
523d1f28cf nano-33-ble: internal i2c config, power led and sensors switch 2021-11-13 12:46:54 +01:00
Damian Gryski
782c57cc11 pass testing arguments to wasmtime 2021-11-13 12:01:20 +01:00
Ayke van Laethem
c1d697f868 compiler: fix indices into strings and arrays
This PR fixes two bugs at once:

 1. Indices were incorrectly extended to a bigger type. Specifically,
    unsigned integers were sign extended and signed integers were zero
    extended. This commit swaps them around.
 2. The getelementptr instruction was given the raw index, even if it
    was a uint8 for example. However, getelementptr assumes the indices
    are signed, and therefore an index of uint8(200) was interpreted as
    an index of int8(-56).
2021-11-13 11:04:24 +01:00
Ayke van Laethem
335fb71d2f reflect: add support for DeepEqual
The implementation has been mostly copied from the Go reference
implementation with some small changes to fit TinyGo.

Source: 77a11c05d6/src/reflect/deepequal.go

In addition, this commit also contains the following:

  - A set of tests copied from the Go reflect package.
  - An increased stack size for the riscv-qemu and hifive1-qemu targets
    (because they otherwise fail to run the tests). Because these
    targets are only used for testing, this seems fine to me.
2021-11-12 21:27:27 +01:00
Ayke van Laethem
5866a47e77 reflect: fix Value.Index() in a specific case
In the case where:

 - Value.Index() was called on an array
 - that array was bigger than a pointer
 - the element type fits in a pointer
 - the 'indirect' flag isn't set

the Value.Index() method would still (incorrectly) load the value.
This commit fixes that.

The next commit adds a test which would have triggered this bug so works
as a regression test.
2021-11-12 21:27:27 +01:00
Ayke van Laethem
823c9c25cf reflect: implement Value.Elem() for interface values 2021-11-12 21:27:27 +01:00
Ayke van Laethem
d15e32fb89 reflect: don't construct an interface-in-interface value
v.Interaface() could construct an interface in interface value if v was
of type interface. This is not correct, and doesn't follow upstream Go
behavior. Instead, it should return the interface value itself.
2021-11-12 21:27:27 +01:00
soypat
b534dd67e0 machine/rp2040: add interrupt API 2021-11-12 10:38:02 +01:00
Ayke van Laethem
6c02b4956c interp: fix reverting of extractvalue/insertvalue with multiple indices 2021-11-11 10:36:22 +01:00
Ayke van Laethem
1681ed02d3 interp: take care of constant globals
Constant globals can't have been modified, even if a pointer is passed
externally. Therefore, don't treat it as such in hasExternalStore.

In addition, it doesn't make sense to update values of constant globals
after the interp pass is finished. So don't do this.

TODO: track whether objects are actually modified and only update the
globals if this is the case.
2021-11-11 08:59:32 +01:00
Ayke van Laethem
7e68980c39 ci: improve caching for GitHub Actions
Previously the cache would be stale for every new branch.
With this change, PRs use the cache from the base branch and therefore
don't need to rebuild LLVM from scratch.
2021-11-10 18:55:17 +01:00
Ayke van Laethem
cf640290a3 compiler: add "target-cpu" and "target-features" attributes
This matches Clang, and with that, it adds support for inlining between
Go and C because LLVM only allows inlining if the "target-cpu" and
"target-features" string attributes match.

For example, take a look at the following code:

    // int add(int a, int b) {
    //   return a + b;
    // }
    import "C"

    func main() {
        println(C.add(3, 5))
    }

The 'add' function is not inlined into the main function before this
commit, but after it, it can be inlined and trivially be optimized to
`println(8)`.
2021-11-10 11:16:13 +01:00
Ayke van Laethem
78fec3719f all: add target-features string to all targets
This makes sure that the LLVM target features match the one generated by
Clang:

  - This fixes a bug introduced when setting the target CPU for all
    targets: Cortex-M4 would now start using floating point operations
    while they were disabled in C.
  - This will make it possible in the future to inline C functions in Go
    and vice versa. This will need some more work though.

There is a code size impact. Cortex-M4 targets are increased slightly in
binary size while Cortex-M0 targets tend to be reduced a little bit.
Other than that, there is little impact.
2021-11-07 09:26:46 +01:00
Ayke van Laethem
af4d0fe191 compileopts: fix reversed append in the target file
With this fix, `cflags` in the target JSON files is correctly ordered.
Previously, the cflags of a parent JSON file would come after the ones
in the child JSON file, which makes it hard to override properties in
the child JSON file.

Specifically, this fixes the case where targets/riscv32.json sets
`-march=rv32imac` and targets/esp32c3.json wants to override this using
`-march=rv32imc` but can't do this because its `-march` comes before the
riscv32.json one.
2021-11-07 09:26:46 +01:00
Ayke van Laethem
7caf0732fa transform: add debug info in interface lowering pass
This is fake debug info. It doesn't point to a source location because
there is no source location. However, it helps to correctly attribute
code size usage to particular packages.

I've also updated builder/sizes.go with some debugging helpers.
2021-11-06 10:50:55 +01:00
Ayke van Laethem
edcece33ca transform: refactor interrupt lowering
Instead of doing everything in the interrupt lowering pass, generate
some more code in gen-device to declare interrupt handler functions and
do some work in the compiler so that interrupt lowering becomes a lot
simpler.

This has several benefits:

  - Overall code is smaller, in particular the interrupt lowering pass.
  - The code should be a bit less "magical" and instead a bit easier to
    read. In particular, instead of having a magic
    runtime.callInterruptHandler (that is fully written by the interrupt
    lowering pass), the runtime calls a generated function like
    device/sifive.InterruptHandler where this switch already exists in
    code.
  - Debug information is improved. This can be helpful during actual
    debugging but is also useful for other uses of DWARF debug
    information.

For an example on debug information improvement, this is what a
backtrace might look like before this commit:

    Breakpoint 1, 0x00000b46 in UART0_IRQHandler ()
    (gdb) bt
    #0  0x00000b46 in UART0_IRQHandler ()
    #1  <signal handler called>
    [..etc]

Notice that the debugger doesn't see the source code location where it
has stopped.

After this commit, breaking at the same line might look like this:

    Breakpoint 1, (*machine.UART).handleInterrupt (arg1=..., uart=<optimized out>) at /home/ayke/src/github.com/tinygo-org/tinygo/src/machine/machine_nrf.go:200
    200			uart.Receive(byte(nrf.UART0.RXD.Get()))
    (gdb) bt
    #0  (*machine.UART).handleInterrupt (arg1=..., uart=<optimized out>) at /home/ayke/src/github.com/tinygo-org/tinygo/src/machine/machine_nrf.go:200
    #1  UART0_IRQHandler () at /home/ayke/src/github.com/tinygo-org/tinygo/src/device/nrf/nrf51.go:176
    #2  <signal handler called>
    [..etc]

By now, the debugger sees an actual source location for UART0_IRQHandler
(in the generated file) and an inlined function.
2021-11-06 09:40:15 +01:00
jaap aarts
30bbdd5aeb Make the frequency selection more flexible on stm32f103 2021-11-05 18:11:43 +01:00
jaap aarts
03383760d6 Fix SPI on stm32f103 2021-11-05 18:11:43 +01:00
Ayke van Laethem
fce403b7a0 targets: match LLVM triple to the one Clang uses
The target triples have to match mostly to be able to link LLVM modules.
Linking LLVM modules is already possible (the triples already match),
but testing becomes much easier when they match exactly.

For macOS, I picked "macosx10.12.0". That's an old and unsupported
version, but I had to pick _something_. Clang by default uses
"macos10.4.0", which is much older.
2021-11-05 09:42:00 +01:00
Ayke van Laethem
fb33f3813d runtime: only initialize os.runtime_args when needed
This generally means that code size is reduced, especially when the os
package is not imported.

Specifically:

  - On Linux (which currently statically links musl), it avoids calling
    malloc, which avoids including the musl C heap for small programs
    saving around 1.6kB.
  - On WASI, it avoids initializing the args slice when the os package
    is not used. This reduces binary size by around 1kB.
2021-11-05 08:50:36 +01:00
Ayke van Laethem
670fcf59d8 linux: reduce binary size in the common case
This commit changes the runtime.putchar implementation to directly call
the `write` system call. This reduces the binary size by around 2.7kB.
2021-11-05 08:50:36 +01:00
Ayke van Laethem
cceb655874 cgo: run CGo parser for all CGo fragments in a file
Previously, libclang was run on each fragment (import "C") separately.
However, in regular Go it's possible for later fragments to refer to
types in earlier fragments so they must have been parsed as one.

This commit changes the behavior to run only one C parser invocation for
each Go file.
2021-11-04 22:26:33 +01:00
Damian Gryski
13891d428f os: add File.WriteString and File.WriteAt
WriteString just does the simple and and converts the passed string
to a byte-slice.  This can be made zero-copy later with unsafe, if needed.

WriteAt returns ErrNotImplemented, to match Seek() and ReadAt().

Fixes #2157
2021-11-04 21:47:57 +01:00
Ayke van Laethem
6c9bb96bca wasm: update wasi-libc dependency
The latest version allows overriding the default CFLAGS. By default,
they're `-O2 -DNDEBUG`, thus not including DWARF debug information. This
commit changes this to include the `-g` flag.

Apart from an improved debug experience, this lets -size=full attribute
code to wasi-libc.

Before:

    $ tinygo build -o test.wasm -size=full ./testdata/alias.go
       code  rodata    data     bss |   flash     ram | package
    ------------------------------- | --------------- | -------
       1780       0     188  130733 |    1968  130921 | (unknown)
         84       0       0       0 |      84       0 | internal/task
        281       0       0       0 |     281       0 | main
       2374       0       4     147 |    2378     151 | runtime
    ------------------------------- | --------------- | -------
       4519       0     192  130880 |    4711  131072 | total

After:

    $ tinygo build -o test.wasm -size=full ./testdata/alias.go
       code  rodata    data     bss |   flash     ram | package
    ------------------------------- | --------------- | -------
         40       0     188  130733 |     228  130921 | (unknown)
       1740       0       0       0 |    1740       0 | C wasi-libc
         84       0       0       0 |      84       0 | internal/task
        281       0       0       0 |     281       0 | main
       2374       0       4     147 |    2378     151 | runtime
    ------------------------------- | --------------- | -------
       4519       0     192  130880 |    4711  131072 | total

The main difference here is the `(unknown)` code, which turns out to be
mostly wasi-libc in this trivial example.
2021-11-04 21:10:42 +01:00
Ayke van Laethem
403d93560b builder: build static binaries using musl on Linux
This commit adds support for musl-libc and uses it by default on Linux.
The main benefit of it is that binaries are always statically linked
instead of depending on the host libc, even when using CGo.

Advantages:
  - The resulting binaries are always statically linked.
  - No need for any tools on the host OS, like a compiler, linker, or
    libc in a release build of TinyGo.
  - This also simplifies cross compilation as no cross compiler is
    needed (it's all built into the TinyGo release build).

Disadvantages:
  - Binary size increases by 5-6 kilobytes if -no-debug is used. Binary
    size increases by a much larger margin when debugging symbols are
    included (the default behavior) because musl is built with debugging
    symbols enabled.
  - Musl does things a bit differently than glibc, and some CGo code
    might rely on the glibc behavior.
  - The first build takes a bit longer because musl needs to be built.

As an additional bonus, time is now obtained from the system in a way
that fixes the Y2038 problem because musl has been a bit more agressive
in switching to 64-bit time_t.
2021-11-04 17:15:38 +01:00
Ayke van Laethem
b344d65781 builder: reduce number of open files
MacOS X 10.14 has a soft limit of 256 open files by default, at least on
CircleCI. So don't keep object files open while writing the ar file to
reduce the number of open files at once.

Context: the musl libc has more than 256 object files in the .a file.
This resulted in the error "too many open files" on MacOS X 10.14 when
running in CircleCI.
2021-11-04 17:15:38 +01:00
Ayke van Laethem
c638f03b3c main: add -p flag to set parallelism
This is very useful for debugging.
2021-11-04 17:15:38 +01:00
Ayke van Laethem
79bdd3f79a picolibc: add include directory to build artefact
This is really just a preparatory commit for musl support. The idea is
to store not just the archive file (.a) but also an include directory.
This is optional for picolibc but required for musl, so the main purpose
of this commit is the refactor needed for this change.
2021-11-04 17:15:38 +01:00
Ayke van Laethem
39ff13fd1a wasm: specify wasi-libc in code, not in the JSON target file
This brings a bit more consistency to libc configuration. It seems
better to me to set the header flags all in the same place, instead of
some in Go code and some in JSON target files (depending on the target).
2021-11-04 17:15:38 +01:00
Ayke van Laethem
de6f831983 ci: switch to GitHub Actions for Windows builds
GitHub Actions is faster and much better integrated into GitHub than
Azure Pipelines, and is in general easier to use. Therefore, switch to
GitHub Actions for our Windows builds and tests.
2021-11-04 13:54:21 +01:00
Ayke van Laethem
fb6571e405 builder: add support for -size= flag for WebAssembly 2021-11-04 12:34:23 +01:00
Ayke van Laethem
29206cf0a4 targets: add CPU property everywhere
This is for consistency with Clang, which always adds a CPU flag even if
it's not specified in CFLAGS.

This commit also adds some tests to make sure the Clang target-cpu
matches the CPU property in the JSON files.

This does have an effect on the generated binaries. The effect is very
small though: on average just 0.2% increase in binary size, apparently
because Cortex-M3 and Cortex-M4 are compiled a bit differently. However,
when rebased on top of https://github.com/tinygo-org/tinygo/pull/2218
(minsize), the difference drops to -0.1% (a slight decrease on average).
2021-11-03 23:03:44 +01:00
Yurii Soldak
c2165f74d8 nano-33-ble: SoftDevice s140v7 support 2021-11-03 20:54:40 +01:00
Ayke van Laethem
02ef64f012 stacksize: hardcode some more frame sizes for __aeabi_* functions
These functions are defined in compiler-rt in assembly and therefore
don't have stack size information. However, they're often called so
these missing functions often inhibit stack size calculation.

Example, before:

    $ tinygo build -o test.elf -target=cortex-m-qemu -print-stacks ./testdata/float.go
    function                         stack usage (in bytes)
    Reset_Handler                    unknown, __aeabi_memclr does not have stack frame information
    runtime.run$1                    unknown, __aeabi_dcmpgt does not have stack frame information

After:

    $ tinygo build -o test.elf -target=cortex-m-qemu -print-stacks ./testdata/float.go
    function                         stack usage (in bytes)
    Reset_Handler                    260
    runtime.run$1                    224
2021-11-03 18:42:16 +01:00
Ayke van Laethem
5792f3a1cf builder: improve accuracy of the -size=full flag
This commit improves accuracy of the -size=full flag in a big way.
Instead of relying on symbol names to figure out by which package
symbols belong, it will instead mostly use DWARF debug information
(specifically, debug line tables and debug information for global
variables) relying on symbols only for some specific things. This is
much more accurate: it also accounts for inlined functions.

For example, here is how it looked previously when compiling a personal
project:

     code  rodata    data     bss |   flash     ram | package
     1902     333       0       0 |    2235       0 | (bootstrap)
       46     256       0       0 |     302       0 | github
        0     454       0       0 |     454       0 | handleHardFault$string
      154      24       4       4 |     182       8 | internal/task
     2498      83       5    2054 |    2586    2059 | machine
        0      16      24     130 |      40     154 | machine$alloc
     1664      32      12       8 |    1708      20 | main
        0       0       0     200 |       0     200 | main$alloc
     2476      79       0      36 |    2555      36 | runtime
      576       0       0       0 |     576       0 | tinygo
     9316    1277      45    2432 |   10638    2477 | (sum)
    11208       -      48    6548 |   11256    6596 | (all)

And here is how it looks now:

     code  rodata    data     bss |   flash     ram | package
  ------------------------------- | --------------- | -------
     1509       0      12      23 |    1521      35 | (unknown)
      660       0       0       0 |     660       0 | C compiler-rt
       58       0       0       0 |      58       0 | C picolibc
        0       0       0    4096 |       0    4096 | C stack
      174       0       0       0 |     174       0 | device/arm
        6       0       0       0 |       6       0 | device/sam
      598     256       0       0 |     854       0 | github.com/aykevl/ledsgo
      320      24       0       4 |     344       4 | internal/task
     1414      99      24    2181 |    1537    2205 | machine
      726     352      12     208 |    1090     220 | main
     3002     542       0      36 |    3544      36 | runtime
      848       0       0       0 |     848       0 | runtime/volatile
       70       0       0       0 |      70       0 | time
      550       0       0       0 |     550       0 | tinygo.org/x/drivers/ws2812
  ------------------------------- | --------------- | -------
     9935    1273      48    6548 |   11256    6596 | total

There are some notable differences:

  * Odd packages like main$alloc and handleHardFault$string are gone,
    instead their code is put in the correct package.
  * C libraries and the stack are now included in the list, they were
    previously part of the (bootstrap) pseudo-package.
  * Unknown bytes are slightly reduced. It should be possible to reduce
    it significantly more in the future: most of it is now caused by
    interface invoke wrappers.
  * Inlined functions are now correctly attributed. For example, the
    runtime/volatile package is normally entirely inlined.
  * There is no difference between (sum) and (all) anymore. A better
    code size algorithm now counts the code/data sizes correctly.
  * And last (but not least) there is a stylistic change: the table now
    looks more like a table. Especially the summary should be clearer
    now.

Future goals:

  * Improve debug information so that the (unknown) pseudo-package is
    reduced in size or even eliminated altogether.
  * Add support for other file formats, most importantly WebAssembly.
  * Perhaps provide a way to expand this report per file, or in a
    machine-readable format like JSON or CSV.
2021-11-03 16:28:04 +01:00
Ayke van Laethem
f63c389f1a compiler: change symbol name for string and packed data constants
This new symbol name format (package name + "$string" or "$pack" suffix)
is easier to parse for analysis.
2021-11-03 16:28:04 +01:00
Ayke van Laethem
7c24925aa7 compiler: add minsize attribute for -Oz
This matches the behavior of Clang, which uses optsize for -Os and adds
minsize for -Oz.

The code size change is all over the map, but using a hacked together
size comparison tool I've found that there is a slight reduction in
binary size overall (-1.6% with the tinygo smoke tests and -0.8% for the
drivers smoke test).
2021-11-03 13:40:13 +01:00
Ayke van Laethem
d7b7583e83 compiler: refactor when the optsize attribute is set
This commit has a few related changes:

  * It sets the optsize attribute immediately in the compiler instead of
    adding it to each function afterwards in a loop. This seems to me
    like the more appropriate way to do it.
  * It centralizes setting the optsize attribute in the transform
    package, to make later changes easier.
  * It sets the optsize in a few more places: to runtime.initAll and to
    WebAssembly i64 wrappers.

This commit does not affect the binary size of any of the smoke tests,
so should be risk-free.
2021-11-03 13:40:13 +01:00
Ayke van Laethem
1869efe954 interp: use object layout information for LLVM types
This commit will use the memory layout information for heap allocations
added in the previous commit to determine LLVM types, instead of
guessing their types based on the content. This fixes a bug in which
recursive data structures (such as doubly linked lists) would result in
a compiler stack overflow due to infinite recursion.

Not all heap allocations have a memory layout yet, but this can be
incrementally fixed in the future. So far, this commit should fix
(almost?) all cases of this stack overflow issue.
2021-11-02 22:16:15 +01:00
Ayke van Laethem
54dd75f7b3 interp: simplify pointer arithmetic in getLLVMValue
Instead of doing lots of complicated calculations to get the shortest
GEP, I'll just cast it to i8*, do the GEP, and optionally cast to the
requested type.

This currently produces ugly constant expressions, but once LLVM
switches to opaque pointer types all of this shouldn't matter anymore.
2021-11-02 22:16:15 +01:00