Commit Graph

32 Commits

Author SHA1 Message Date
Jake Bailey 18033ebc36 compiler, runtime, reflect: generate type-specific hash/equal (#5359)
* compiler, runtime, reflect: generate type-specific hash/equal for composite map keys

For map keys that are not trivially binary-comparable, the compiler now
generates type-specific hash and equal functions as LLVM IR instead of
going through the interface+reflection path. This covers comparable
types: strings, floats, complex numbers, interfaces, channels, and
composites containing any mix of these.

Previously, maps with composite keys containing strings or floats
converted the key to interface{}, hashed via reflection, and compared
through interface equality. Now the compiler walks struct fields and
array elements directly, dispatching to the right runtime helper for
each field type and storing keys at their actual type.

Struct keys are always handled field-by-field so padding bytes do not
affect equality or hashing. Blank fields are ignored, matching Go
equality. Generated hash/equal function names use canonical underlying
type structure so structurally identical key types can share generated
functions. Padding zeroing before map operations is no longer needed
because structs no longer use the binary key path.

Also fix reflect map iteration for interface-keyed maps: MapIter.Key
returns an interface Value for map[interface{}] keys instead of
unpacking to the concrete key kind.

* compiler: generate loops for array map key hash/equal

Previously, array key hash and equal functions were unrolled at compile
time, generating one block of IR per element. For large arrays like
[1000]int inside a struct with non-binary fields, this caused code
explosion.

Now, binary-element arrays dispatch directly to hash32/memequal for the
whole array. Non-binary-element arrays generate an LLVM IR loop. The
equal loop short-circuits on the first mismatch.

Small arrays are still unrolled instead of looping, keeping the simple
cases compact.

* reflect: fix at-runtime map issues from review, and more found locally

Maps created through reflect.MakeMap need hash/equal behavior that
matches compiler-created maps. Add hashmapMakeReflect for composite key
types, using runtime closures that reconstruct interface{} values from
raw key bytes and delegate to the interface hash and equality paths.

Interface-keyed maps are already stored as interface values, so use the
existing interface hash/equal helpers directly for those. This keeps
reflect insert, lookup, delete, and compiled lookup paths consistent.

Also fix addressable small values used as interface map keys or
interface map values. loadSmallValue puts small indirect values back in
the pointer-sized interface data field the same way valueInterfaceUnsafe
does.

* compiler, interp, reflect: fix pointer map literals; remove interface fallback

Package-level map literals with pointer keys (both *T and
unsafe.Pointer) crash the compiler: the interp pass panics when trying
to hash pointer data as raw bytes, because pointer values in the interp
memory model are symbolic identities that do not fit in a byte.

Fix this by setting a recoverable error flag instead of panicking. The
interp detects the error after each instruction and defers the map
insert to runtime init code, where real addresses are available for
hashing. This matches how the interp already handles other operations
it cannot evaluate at compile time.

With this fix, unsafe.Pointer can also be classified as a binary map
key, which was the last type requiring the interface-based fallback.
Since all comparable types now use either the binary or the
compiler-generated hash/equal path, remove the interface fallback from
the compiler and reflect packages.

* compiler, transform: always pass hash/equal function pointers to hashmapMakeGeneric

The compiler now always resolves the hash and equal functions at compile
time and passes them directly to hashmapMakeGeneric, instead of passing
an algorithm enum to hashmapMake and resolving at runtime. For string
keys, the runtime hashmapStringPtrHash/hashmapStringEqual functions are
referenced directly. For binary keys, hash32/memequal are referenced.

The old hashmapMake with alg enum is retained for reflect, which still
needs runtime resolution when creating maps dynamically.

The OptimizeMaps transform pass is updated to handle both hashmapMake
and hashmapMakeGeneric, and to recognize hashmapGenericSet in addition
to hashmapBinarySet and hashmapStringSet. The now-unused
hashmapCanGenerateHashEqual helper is removed.

* runtime: store large map keys and values indirectly

When a map key or value exceeds 128 bytes, the bucket now stores a
pointer to separately allocated memory instead of the data inline. This
matches Go's MapMaxKeyBytes/MapMaxElemBytes threshold and prevents
bucket sizes from exploding for large key/value types.

For example, map[[256]byte]int previously used 2128 bytes per bucket
(16 header + 256*8 keys + 8*8 values); now it uses 144 bytes per bucket
(16 header + 8*8 pointers + 8*8 values).

The indirection is fully encapsulated in the runtime via helper
functions. Store the computed key and value slot sizes on the hashmap so
all runtime and reflect paths use the same bucket layout, including
non-indirect keys and values.

Add big-key golden coverage and benchmarks. Make the benchmark vary
enough key bytes to exercise hashing.
2026-05-18 13:31:27 +02:00
Ben Krieger 821f2aeae0 Fix linker errors for runtime.vgetrandom and crypto/internal/sysrand.fatal 2025-09-19 15:32:01 +02:00
deadprogram e5bdfb0962 fix: increase the timeout for chromedp to connect to the headless browser used for running
the wasm tests.

Also add favicon link to avoid extra fetches during test runs.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-09-11 08:34:38 -04:00
deadprogram e80c6c48a1 chore: create separate go.mod file for testing dependencies for wasm tests
that use Chromium headless browser to avoid use of older incompatible version.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-09-11 08:34:38 -04:00
deadprogram 35adbffa54 fix: additional params to create chromium browser for testing
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-07-10 11:47:37 +02:00
Ayke van Laethem c08b2dfe06 wasm: add Boehm GC support
This adds support for `-gc=boehm` on `-target=wasip1` and `-target=wasm`
(in a browser or NodeJS). Notably it does *not* add Boehm GC support for
`-target=wasip2`, since that target doesn't have a real libc.
2025-06-13 14:42:23 +02:00
deadprogram d04eea7185 fix: add NoSandbox flag to chrome headless that is run during WASM tests, since
this is now required for Ubuntu 23+ and we are using Ubuntu 24+ when running
Github Actions.

See https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md

Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-02-12 17:13:56 +01:00
archie2x 5abf1e998d Fix #4421: Add -C DIR flag (#4422)
feature: Fix #4421: Add `-C DIR` flag

Signed-off-by: Roger Standridge <9526806+archie2x@users.noreply.github.com>
2024-09-13 07:05:44 +02:00
Randy Reddig fe27b674cd reflect: use int in StringHeader and SliceHeader on non-AVR platforms (#4156) 2024-05-14 14:04:54 +02:00
Yurii Soldak 8d4d3c6201 build: drop deprecated build tags 2022-12-19 23:20:11 +01:00
Anuraag Agrawal b731919f97 Fix panic when size 0 passed to malloc 2022-11-21 21:00:36 +01:00
Anuraag Agrawal 03d1c44265 wasm,wasi: make sure buffers returned by malloc are not freed until f… (#3148)
* wasm,wasi: make sure buffers returned by malloc are not freed until free is called
2022-09-15 09:14:39 +02:00
Ayke van Laethem 4695da83b7 all: drop support for Go 1.16 and Go 1.17 2022-08-30 12:38:06 +02:00
Damian Gryski 24b1bfcecd tests/runtime: add benchmarks for runtime memhash 2022-07-05 08:54:55 +02:00
Dan Kegel ada11090a2 smoketest: add regression test for 'tinygo test ./...', see #2892
tests/testing/recurse has two directories with tests;
"make smoketest" now does "tinygo test ./..." in that directory
and fails if it does not run both directories' tests.
2022-06-11 12:11:08 +02:00
Kyle Conroy b406422277 test: Add text/template smoke test 2022-02-24 12:32:40 -05:00
Dan Kegel 9c3f9537be os: add stubs for Readlink and File.Seek for baremetal targets, with smoke test.
Test currently enabled on pybadge (chosen at random)

TODO:
- enable test on arduino; currently fails with "interp: ptrtoint integer size..." (#2389)
- enable test on nintendoswitch; currently fails with many missing definitions (#2530)
2022-01-21 07:39:47 +01:00
Nia Waldvogel 7c3a22d289 wasmtest: fix resource cleanup and add logging
The chromedp context was not cancelled, so resources may have been leaking.
Additionally this waits for the browser to start before the timer starts, and extends the timeout to 20 seconds.
Logging from chromedp has also been enabled, which may help identify possible issues?
2022-01-18 19:29:29 +01:00
Nia Waldvogel d86dd642b3 main (test): add tests to tinygo test 2022-01-03 18:59:19 -05:00
Ayke van Laethem 1d2c17753a tests: improve wasm tests slightly
These wasm tests weren't passing in GitHub Actions and also weren't
passing on my laptop. I'm not sure why, I think there are a few race
conditions that are going on.

This commit attempts to fix this at least to a degree:

  - The context deadline is increased from 5 seconds to 10 seconds.
  - The tests are not running in parallel anymore.
  - Some `Sleep` calls were removed, they do not appear to be necessary
    (and if they were, sleeping is the wrong solution to solve race
    conditions).

Overall the tests are taking a few seconds more, but on the other hand
they seem to be passing more reliable. At least for me, on my laptop
(and hopefully also in CI).
2021-11-21 12:17:34 +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
Ayke van Laethem 59d53182bb all: use new testing features of Go 1.14 and 1.15
This simplifies the tests a bit.
2021-08-16 21:19:26 +02:00
Ayke van Laethem 25c7bfd404 ci: drop support for Go 1.13 and 1.14
They aren't supported anymore in CI, and because untested code is broken
code, let's remove support for these Go versions altogether.
2021-08-16 21:19:26 +02:00
Ayke van Laethem c25a7cc747 testing: test testing package using tinygo test 2021-08-12 13:23:41 +02:00
Dan Kegel 55789fd2c2 src/testing/benchmark.go: add subset implementation of Benchmark
Partially fixes #1808

Allows the following to succeed:

curl "https://golang.org/test/fibo.go?m=text" > fibo.go
tinygo build -o fibo fibo.go
./fibo -bench
2021-08-06 08:19:15 +02:00
Elliott Sales de Andrade f3bdebe2a6 Use httptest to serve wasm test files.
This picks a port automatically, so avoids any conflicts that might
arise from running the tests in parallel.
2021-01-25 19:12:31 +01:00
Elliott Sales de Andrade 5642d72fbe Update to current chromedp. 2021-01-24 23:13:42 +01:00
Brad Peabody 4918395f88 added test for wasm log output
callback case for log test
2020-05-27 08:43:29 +02:00
Brad Peabody 95f509b109 wasm test suite (#1116)
* wasm: add test suite using headlless chrome
2020-05-23 14:12:01 +02:00
Brad Erickson 61f711ef26 Add common test logging methods such as Errorf/Fatalf/Printf
Implements nearly all of the test logging methods for both T and B
structs. Majority of the code has been copied from:
golang.org/src/testing/testing.go
then updated to match the existing testing.go structure.

Code structure/function/method order mimics upstream.

Both FailNow() and SkipNow() cannot be completely implemented,
because they require an early exit from the goroutine. Instead,
they call Error() to report the limitation.

This incomplete implementation allows more detailed test logging and
increases compatiblity with upstream.
2019-08-13 20:59:09 +02:00
Brad Erickson 7c758b0dfc testing: Add Benchmark B struct stub
This struct allows test files containing basic benchmarks to compile
and run, but will not run the benchmarks themselves.

For #491
2019-08-11 14:51:02 +02:00
Carolyn Van Slyck 208e1719ad Add test command to tinygo (#243)
* Add test command to tinygo
2019-06-18 12:23:59 +02:00