So far, we've pretended to be js/wasm in baremetal targets to make the
stdlib happy. Unfortunately, this has various problems because
syscall/js (a dependency of many stdlib packages) thinks it can do JS
calls, and emulating them gets quite hard with all changes to the
syscall/js packages in Go 1.12.
This commit does a few things:
* It lets baremetal targets pretend to be linux/arm instead of
js/wasm.
* It lets the loader only select particular packages from the src
overlay, instead of inserting them just before GOROOT. This makes it
possible to pick which packages to overlay for a given target.
* It adds a baremetal-only syscall package that stubs out almost all
syscalls.
Before this commit, goroutine support was spread through the compiler.
This commit changes this support, so that the compiler itself only
generates simple intrinsics and leaves the real support to a compiler
pass that runs as one of the TinyGo-specific optimization passes.
The biggest change, that was done together with the rewrite, was support
for goroutines in WebAssembly for JavaScript. The challenge in
JavaScript is that in general no blocking operations are allowed, which
means that programs that call time.Sleep() but do not start goroutines
also have to be scheduled by the scheduler.
This reduces complexity in the compiler without affecting binary sizes
too much.
Cortex-M0: no changes
Linux x64: no changes
WebAssembly: some testcases (calls, coroutines, map) are slightly bigger
This can be used in the future to trigger garbage collection. For now,
it provides a more useful error message in case the heap is completely
filled up.
Make sure every to-be-implemented GC can use the same interface. As a
result, a 1MB chunk of RAM is allocated on Unix systems on init instead
of allocating on demand.
Let each target handle its own initialization/finalization sequence
instead of providing one in the runtime with hooks for memory
initialization etc. This is much more flexible although it causes a
little bit of code duplication.
This increases code size by 1 instruction (2 bytes) because LLVM isn't
yet smart enough to recognize that it doesn't need to clear a register
to use 0: it can just use r1 which is always 0 according to the
convention. It makes initialization a lot easier to read, however.
time.Sleep now compiles on all systems, so lets use that.
Additionally, do a few improvements in time unit handling for the
scheduler. This should lead to somewhat longer sleep durations without
wrapping (on some platforms).
Some examples got smaller, some got bigger. In particular, code using
the scheduler got bigger and the blinky1 example got smaller (especially
on Arduino: 380 -> 314 bytes).
This specifically fixes unix alloc(): previously when allocation fails
it would (recursively) call alloc() again to create an interface due to
lacking escape analysis.
Also, all other cases shouldn't try to allocate just because something
bad happens at runtime.
TODO: implement escape analysis.
CGo depends on syscall, which (in the standard library) depends on sync,
which depends on the runtime. There are also other import cycles. To be
able to use the syscall package from upstream, stop using CGo.