Scanning of allocas was entirely broken on WebAssembly. The code
intended to do this was never run. There were also no tests.
Looking into this further, I found that it is actually not really
necessary to do that: the C stack can be scanned conservatively and in
fact this was already done for goroutine stacks (because they live on
the heap and are always referenced). It wasn't done for the system stack
however.
With these fixes, I believe code should be both faster *and* more
correct.
I found this in my work to get opaque pointers supported in LLVM 15,
because the code that was never reached now finally got run and was
actually quite buggy.
* Add test.batch flag so standalone tests print PASS on pass
* Add comment; use single-dash flag style to match usage elsewhere
* Don't add test.batch for wasmtime
* Skip test.batch unless emulator name is blank
* Remove test.batch flag; buffer test output and show only on verbose or failure
* Remove FAIL when all tests fail to match go test output
Unfortunately the calling convention for variadic functions is different from
the calling convention of regular functions on darwin/arm64, and open happens
to be such a variadic function. The syscall package treated it like a regular
function, which resulted in buggy behavior.
This fix introduces a wrapper function. This is the cleanest change I could
come up with.
In some cases, regular integers were used. But we have a constant to
explicitly say these pins are undefined: `NoPin`. So use this.
A better solution would be to not require these constants, like with the
proposal in https://github.com/tinygo-org/tinygo/issues/3152. This
change is just a slight improvement over the current state.
This is a constant for internal use only, but was (unintentionally?)
exported. In addition, it doesn't follow the Go naming convention.
This change simply renames the constant so that it is unexported.
This removes level-triggered interrupts.
While working on https://github.com/tinygo-org/tinygo/pull/3170, I found
these level triggered interrupt constants. Apart from them being
inconsistent with each other (PinLowLevel vs PinLevelLow) I don't think
they are actually used anywhere. In addition, I removed the
PinNoInterrupt constant on the esp32c3. This makes the esp32c3 pass the
tests in #3170.
I looked into level-triggered interrupts and I really couldn't find a
good justification for them:
- They were added to the esp32c3 and the rp2040 together with other
pin interrupt types, meaning they were probably just added because
the chip supports the feature and not because they were actually
needed.
- Level interrupts aren't supported in TinyGo for any other chip, and
I haven't seen anybody ask for this feature.
- They aren't supported in the nrf series chips _at all_, and with a
quick search I found only very little demand for them in general.
- I tried to see whether there is any good use case for them, but I
couldn't really find one (where an edge triggered interrupt wouldn't
work just as well). If there is one where level triggered interrupts
are a real advantage over edge triggered interrupts, please let me
know.
Of course, we shouldn't remove a feature lightly. But in this case, I
can't think of an advantage of having this feature. I can think of
downsides: more maintenance and having to specify their behavior in the
machine package documentation.
In general, I would like to keep the machine package clean and only
support things that have a proven use case.
Similar to the rp2040, the nrf has an on-board temperature sensor.
The main reason why I added this function was to show how this new API
is more general and can be used on multiple chips.
Replace ADCChannel.ReadTemperature() with a simple ReadTemperature
function.
Not all chips will have a temperature sensor that is read by sampling an
ADC channel. The replacement ReadTemperature is simpler and more generic
to other chip families.
This breaks chips that were relying on the previous ReadTemperature
method. I hope it won't break a lot of existing code. If it does, a
fallback can be added.
This makes the code a bit cleaner because ErrTxInvalidSliceSize isn't
redefined in every file that uses SPI and Mode0/Mode1/Mode2/Mode3 is
defined for every target that uses SPI.
There are two main issues with these constants:
* They don't follow the Go naming convention.
* They call themselves "TWI", while it makes a lot more sense to refer
to the actual name which is I2C (or I²C).
I have not removed them but just deprecated them. Perhaps we can remove
them when we move towards version 1.0.
Some targets used capital PullUp/PullDown, while the documented standard
is Pullup/Pulldown. This commit fixes this mismatch, while preserving
compatibility with aliases that are marked deprecated.
These constants are for internal use only, so should not have been
exported. In addition, they didn't follow the Go naming convention
before this change.
All nrf chips have a cryptographically secure RNG on board. Therefore,
I've made the code more portable so that it works on all nrf chips.
I did remove a number of exported functions. I am of the opinion that
these should only be made available once we have an agreed upon API for
multiple chips. People who want to have greater control over the RNG
should use the device/nrf package directly instead.
I have also changed the behavior to always enable digital error
correction. Enabling it seems like a more conservative (and secure)
default to me. Again, people who would like to have it disabled can use
the device/nrf package directly.
The crypto/rand package is used for sensitive cryptographic operations.
Do not use the rp2040 RNG for this purpose, because it's not strong
enough for cryptography.
I think it is _possible_ to make use of the RP2040 RNG to create
cryptographically secure pseudo-random numbers, but it needs some
entropy calculation and secure hashing (blake2s or so) to make them
truly unpredictable.
The GC was originally designed for systems with a fixed amount of
memory, like baremetal systems. Therefore, it just used what it could
and ran a GC cycle when out of memory.
Other systems (like Linux or WebAssembly) are different. In those
systems, it is possible to grow the amount of memory on demand. But the
GC only actually grew the heap when it was really out of memory, not
when it was getting very close to being out of memory.
This patch fixes this by ensuring there is at least 33% headroom for the
GC. This means that programs can allocate around 50% more than what was
live in the last GC cycle. It should fix a performance cliff when a
program is almost, but not entirely, out of memory and the GC has to run
almost every heap allocation.
This documents memory constants. Somewhere, we should document what the
default memory size is (seems 2 pages so 128KB), as that determines the
initial heap size (which is a portion of that).
Signed-off-by: Adrian Cole <adrian@tetrate.io>
--allow-undefined can be a problem: it allows compiling code that will
fail when loaded. This change makes sure that if some symbols are
undefined, they are reported as an error by the linker.
Previously, people could get away with importing a function that was not
defined, like this:
func add(int a, int b) int
func test() {
println(add(3, 5))
}
This was always unintended but mostly worked. With this change, it isn't
possible anymore. Now every function needs to be marked with //export
explicitly:
//export add
func add(int a, int b) int
func test() {
println(add(3, 5))
}
As before, functions will be placed in the `env` module with the name
set from the `//export` tag. This can be overridden with
`//go:import-module`:
//go:import-module math
//export add
func add(int a, int b) int
func test() {
println(add(3, 5))
}
For the syscall/js package, I needed to give a list of symbols that are
undefined. This list is based on the JavaScript functions defined in
targets/wasm_exec.js.
This adds a summary of each wasm example, as before it was a bit unclear
how to do so. This also fixes the callback example which was broken.
Fixes#2568
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit fixes two related issues:
1. CanInterface was unimplemented. It now uses the same check as is
used in Interface() itself.
This issue led to https://github.com/tinygo-org/tinygo/issues/3033
2. Allow making an interface out of a string char element.
Doing this in one commit (instead of two) because they are shown to be
correct with the same tests.