Commit Graph

94 Commits

Author SHA1 Message Date
Takeshi Yoneda
c20073d228 Removes unnecessary .Index field of FunctionInstance (#1270)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-22 18:55:35 +09:00
Takeshi Yoneda
f8eb6a8535 Removes unused function types on encoder/decoder (#1269)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-22 08:42:55 +01:00
Takeshi Yoneda
fe8784996c Avoides allocation with constExpr execution (#1257)
Previously executConstExpr is called various places, and therefore it was necessary to return interface{}
and that resulted in allocation per call.
This commit avoids the allocation by adding executConstExprI32 which is used by data segment manipulation,
and repurposes executConstExpr solely to global instance initialization.

As a result, this completely removes the allocation around const expr execution, and hence the perf improvement
in the instantiation phrase. The improvement diff is proportionate to the number of data segments and globals.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-20 12:56:25 +09:00
Takeshi Yoneda
8ab1615b53 Forbids empty name module imports (#1244)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Co-authored-by: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com>
2023-03-16 12:22:37 +09:00
Takeshi Yoneda
e17a85146a Holds wasm.Code as values on wasm.Module (#1243)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-15 14:45:54 +09:00
Takeshi Yoneda
350e81e632 Holds function types as values, not ptrs in wasm.Module (#1227)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-15 13:45:52 +09:00
Takeshi Yoneda
aba4ede088 Removes usage of host functions with Wasm optocdes (#1241)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-15 13:42:53 +09:00
Takeshi Yoneda
e42987a17a Holds memory/func defs, and validated elements as values in wasm.Module (#1224)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-13 14:52:01 +09:00
Takeshi Yoneda
7466f0e7bd Holds most fields as slice of values, not ptrs in wasm.Module (#1221)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-13 12:50:36 +09:00
Edoardo Vacchi
117474c477 refactor binary encoding to its own package (#1187)
move binary encoder to its own package

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
2023-03-03 07:21:22 +08:00
Takeshi Yoneda
d57bdecadb gojs/test: resolve race under scheduleTimeoutEvent (#1063)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-26 08:26:34 +09:00
Takeshi Yoneda
b63d4e6dcd Deletes namespace API (#1018)
Formerly, we introduced `wazero.Namespace` to help avoid module name or import conflicts while still sharing the runtime's compilation cache. Now that we've introduced `CompilationCache` `wazero.Namespace` is no longer necessary. By removing it, we reduce the conceptual load on end users as well internal complexity. Since most users don't use namespace, the change isn't very impactful.

Users who are only trying to avoid module name conflict can generate a name like below instead of using multiple runtimes:

```go
moduleName := fmt.Sprintf("%d", atomic.AddUint64(&m.instanceCounter, 1))
module, err := runtime.InstantiateModule(ctx, compiled, config.WithName(moduleName))
```

For `HostModuleBuilder` users, we no longer take `Namespace` as the last parameter of `Instantiate` method: 

```diff
 	// log to the console.
 	_, err := r.NewHostModuleBuilder("env").
 		NewFunctionBuilder().WithFunc(logString).Export("log").
-		Instantiate(ctx, r)
+		Instantiate(ctx)
 	if err != nil {
 		log.Panicln(err)
 	}
```


The following is an example diff a use of namespace can use to keep compilation cache while also ensuring their modules don't conflict:

```diff

 func useMultipleRuntimes(ctx context.Context, cache) {
-	r := wazero.NewRuntime(ctx)
+	cache := wazero.NewCompilationCache()
 
 	for i := 0; i < N; i++ {
-		// Create a new namespace to instantiate modules into.
-		ns := r.NewNamespace(ctx) // Note: this is closed when the Runtime is
+		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().WithCompilationCache(cache))
 
 		// Instantiate a new "env" module which exports a stateful function.
 		_, err := r.NewHostModuleBuilder("env").
```

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-10 14:11:46 +09:00
Takeshi Yoneda
e90e1985f3 Moves more func inst fields to comptime objects (#927)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-09 12:25:02 +09:00
Crypt Keeper
da3aa7a5ad Adds ExportedFunctionDefinitions and ExportedMemoryDefinitions (#986)
This adds ExportedFunctionDefinitions and ExportedMemoryDefinitions to
api.Module so that those who can't access CompileModule can see them.

Fixes #839

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-12-31 13:11:37 +08:00
Takeshi Yoneda
7666a2a7f7 Disable comp cache for host modules (#949)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-21 14:08:30 +09:00
Takeshi Yoneda
fafcb1cfee Removes unused FunctionInstance.LocalTypes (#925)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-15 14:40:09 +09:00
Takeshi Yoneda
fccbc7b2aa dwarf: fixes for unordered addresses of DWARF line entries (#905)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-09 09:12:33 +09:00
Takeshi Yoneda
4a60a8f4eb ModuleInstance.Functions/Exports as non-pointer slice (#894)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-07 12:45:06 +09:00
Anuraag Agrawal
5de9c3b4bc Store function objects in contiguous memory in heap (#892)
Signed-off-by: Anuraag Agrawal <anuraaga@gmail.com>
2022-12-06 17:07:16 +09:00
Takeshi Yoneda
b8adb361e8 Fixes FuncRef global initialization with imported globals (#888)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-06 14:32:12 +09:00
Crypt Keeper
af8105ba0e Adds ResultNames to HostFunctionBuilder and FunctionDefinition (#887)
This adds ResultNames to HostFunctionBuilder and FunctionDefinition
which helps for multi-results or special-cased ones.

End users can access result names in `FunctionDefinition.ResultNames` or
set for their own host functions via
`HostFunctionBuilder.WithResultNames`. This change adds them for all
built-in functions where result names help.

Most notably, GOOS=js uses `ProxyFunc` to allow logging when a function
returns multiple results. Before, the results were returned without
names: e.g. `11231,1` and now they are named like `n=11231,ok=1`.

We soon plan to allow more visibility in WASI, for example, logging
results that will write to memory offsets. This infrastructure makes it
possible to do that.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-12-06 14:30:55 +09:00
Takeshi Yoneda
6c4dd1cfd9 Adds support for DWARF based stack traces (#881)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-05 14:59:45 +09:00
Takeshi Yoneda
40e698e068 binary: adds custom section decoder (#877)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-01 20:08:40 +09:00
Takeshi Yoneda
8339045657 Ensures listeners only bound to compile time objects (#870)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-11-29 17:25:59 +09:00
Clifton Kaznocha
483dfe17c3 Replace module name check linear scan with map lookup (#844)
Signed-off-by: Clifton Kaznocha <ckaznocha@users.noreply.github.com>
2022-11-07 22:38:29 +01:00
Clifton Kaznocha
0f19bb21ff Optimizes slice initializations (#842)
Signed-off-by: Clifton Kaznocha <ckaznocha@users.noreply.github.com>
Co-authored-by: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com>
2022-11-07 08:25:37 +09:00
Clifton Kaznocha
f391a1d312 add ieee754 and leb128 byte slice funcs (#837)
Signed-off-by: Clifton Kaznocha <ckaznocha@users.noreply.github.com>
2022-11-03 10:23:35 +08:00
Crypt Keeper
be33572289 Adds HostFunctionBuilder to enable high performance host functions (#828)
This PR follows @hafeidejiangyou advice to not only enable end users to
avoid reflection when calling host functions, but also use that approach
ourselves internally. The performance results are staggering and will be
noticable in high performance applications.

Before
```
BenchmarkHostCall/Call
BenchmarkHostCall/Call-16            	 1000000	      1050 ns/op
Benchmark_EnvironGet/environGet
Benchmark_EnvironGet/environGet-16         	  525492	      2224 ns/op
```

Now
```
BenchmarkHostCall/Call
BenchmarkHostCall/Call-16            	14807203	        83.22 ns/op
Benchmark_EnvironGet/environGet
Benchmark_EnvironGet/environGet-16         	  951690	      1054 ns/op
```

To accomplish this, this PR consolidates code around host function
definition and enables a fast path for functions where the user takes
responsibility for defining its WebAssembly mappings. Existing users
will need to change their code a bit, as signatures have changed.

For example, we are now more strict that all host functions require a
context parameter zero. Also, we've replaced
`HostModuleBuilder.ExportFunction` and `ExportFunctions` with a new type
`HostFunctionBuilder` that consolidates the responsibility and the
documentation.

```diff
 ctx := context.Background()
-hello := func() {
+hello := func(context.Context) {
         fmt.Fprintln(stdout, "hello!")
 }
-_, err := r.NewHostModuleBuilder("env").ExportFunction("hello", hello).Instantiate(ctx, r)
+_, err := r.NewHostModuleBuilder("env").
+        NewFunctionBuilder().WithFunc(hello).Export("hello").
+        Instantiate(ctx, r)
```

Power users can now use `HostFunctionBuilder` to define functions that
won't use reflection. There are two choices of interfaces to use
depending on if that function needs access to the calling module or not:
`api.GoFunction` and `api.GoModuleFunction`. Here's an example defining
one.

```go
builder.WithGoFunction(api.GoFunc(func(ctx context.Context, params []uint64) []uint64 {
	x, y := uint32(params[0]), uint32(params[1])
	sum := x + y
	return []uint64{sum}
}, []api.ValueType{api.ValueTypeI32, api.ValueTypeI32}, []api.ValueType{api.ValueTypeI32})
```
As you'll notice and as documented, this approach is more verbose and
not for everyone. If you aren't making a low-level library, you are
likely able to afford the 1us penalty for the convenience of reflection.
However, we are happy to enable this option for foundational libraries
and those with high performance requirements (like ourselves)!

Fixes #825

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-10-28 07:51:08 -07:00
Crypt Keeper
1cbb496c26 Stops using "ex." to abbreviate "for example" (#827)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-10-24 11:51:48 +09:00
Crypt Keeper
9a623c4f88 Adds MemoryDefinition to CompiledModule and Memory (#817)
It is more often the case that projects are enabling a freestanding
target, and that may or may not have an exporting memory depending on
how that's interpreted. This adds the ability to inspect memories
similar to how you can already inspect compiled code prior to
instantiation. For example, you can enforce an ABI constraint that
"memory" must be exported even if WASI is not in use.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-29 13:37:52 +08:00
Crypt Keeper
761347db1e Replaces MemorySizer and CompileConfig with RuntimeConfig (#815)
We formerly introduced `MemorySizer` as a way to control capacity independently of size. This was the first and only feature in `CompileConfig`. While possibly used privately, `MemorySizer` has never been used in public GitHub code.

These APIs interfere with how we do caching of compiled modules. Notably, they can change the min or max defined in wasm, which invalidates some constants. This has also had a bad experience, forcing everyone to boilerplate`wazero.NewCompileConfig()` despite that API never being used in open source.

This addresses the use cases in a different way, by moving configuration to `RuntimeConfig` instead. This allows us to remove `MemorySizer` and `CompileConfig`, and the problems with them, yet still retaining functionality in case someone uses it.

* `RuntimeConfig.WithMemoryLimitPages(uint32)`: Prevents memory from growing to 4GB (spec limit) per instance.
  * This works regardless of whether the wasm encodes max or not. If there is no max, it becomes effectively this value.
* `RuntimeConfig.WithMemoryCapacityFromMax(bool)`: Prevents reallocations (when growing).
  * Wasm that never sets max will grow from min to the limit above.

Note: Those who want to change their wasm (ex insert a max where there was none), have to do that externally, ex via compiler settings or post-build transformations such as [wabin](https://github.com/tetratelabs/wabin)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-29 08:03:03 +08:00
Crypt Keeper
429334cf98 Renames ModuleBuilder to HostModuleBuilder and drops memory and globals (#812)
We at one point considered making `ModuleBuilder` create complete
WebAssembly binaries. However, we recently spun out
[wabin](https://github.com/tetratelabs/wabin), which allows this.

Meanwhile, the features in `ModuleBuilder` were confusing and misused.
For example, the only two cases memory was exported on GitHub were done
by accident. This is because host functions act on the guest's memory,
not their own.

Hence, this removes memory and globals from host side definitions, and
renames the type to HostModuleBuilder to clarify this is not ever going
to be used to construct normal Wasm binaries.

Most importantly, this simplifies the API and reduces a lot of code. It
is important to make changes like this, particularly deleting any
experimental things that didn't end up useful.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Anuraag Agrawal <anuraaga@gmail.com>
2022-09-28 14:42:14 +08:00
Takeshi Yoneda
5c64720b24 Update spectest v2 to latest (#809)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-09-21 10:06:43 +09:00
Crypt Keeper
b01effc8a9 Top-levels CoreFeatures and defaults to 2.0 (#800)
While compilers should be conservative when targeting WebAssembly Core
features, runtimes should be lenient as otherwise people need to
constantly turn on all features. Currently, most examples have to turn
on 2.0 features because compilers such as AssemblyScript and TinyGo use
them by default. This matches the policy with the reality, and should
make first time use easier.

This top-levels an internal type as `api.CoreFeatures` and defaults to
2.0 as opposed to 1.0, our previous default. This is less cluttered than
the excess of `WithXXX` methods we had prior to implementing all
planned WebAssembly Core Specification 1.0 features.

Finally, this backfills rationale as flat config types were a distinct
decision even if feature set selection muddied the topic.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-06 15:14:36 +08:00
Takeshi Yoneda
0bd2beedac Introduce CallEngine assigned to api.Function implementation. (#761)
This introduces wasm.CallEngine internal type, and assign it to the api.Function
implementations. api.Function.Call now uses that CallEngine assigned to it
to make function calls.

Internally, when creating CallEngine implementation, the compiler engine allocates
call frames and values stack. Previously, we allocate these stacks for each function calls,
which was a severe overhead as we can recognize in the benchmarks. As a result,
this reduces the memory usage (== reduces the GC jobs) as long as we reuse
the same api.Function multiple times.

As a side effect, now api.Function.Call is not goroutine-safe. So this adds the comment
about it on that method.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-08-24 16:11:15 +09:00
Crypt Keeper
939403c10b Makes it possible to implement FunctionListener and Factory (#716)
This simplifies FunctionListener definition by making it possible to
implement both interfaces without intermediate state. Passing the
function definition to the before/after callbacks is the key.

This also continues efforts towards Go 1.19 doc formatting.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-25 12:53:41 +08:00
Takeshi Yoneda
ed068597cd ci: adds Go 1.19.0-rc.2 into matrix (#714)
This adds the 1.19.0-rc2. in the testing matrix.

This also formats the Godocs across the codebase, as
Go 1.19 has started auto-formatting Godoc. https://github.com/tetratelabs/wazero/issues/426

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-07-25 11:14:00 +09:00
Crypt Keeper
1689fc1bbf Allows wasm-defined host functions to use memory in interpreter (#713)
Before, we allowed stubbed host functions to be defined in wasm instead
of Go. This improves performance and reduces a chance of side-effects vs
Go. In fact, any pure function was supported in wasm, provided it only
called pure functions.

This changes internals so that a wasm-defined host function can use
memory. Notably, host functions use the caller's memory, so this is
simpler to initially support in the interpreter.

This is needed to simplify and reduce performance hit of GOARCH=wasm,
GOOS=js code, which perform a lot of memory reads and do not have
idiomatic signatures.

Note: wasm-defined host functions remain internal until we gain
experience, at least conclusion of the wasm_exec host module.


Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-25 09:12:44 +08:00
Crypt Keeper
866fac2e96 Makes CacheNumInUint64 lazy and stops crashing in assemblyscript (#712)
* Makes CacheNumInUint64 lazy and stops crashing in assemblyscript

This makes CacheNumInUint64 lazy so that all tests for function types
don't need to handle it. This also changes the assemblyscript special
functions so they don't crash when attempting to log. Finally, this
refactors `wasm.Func` so that it can enclose the parameter names as it
is more sensible than defining them elsewhere.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-22 16:01:20 +08:00
Crypt Keeper
0da1af2d51 Supports mix of wasm and go funcs in the same module (#707)
This removes the constraint of a module being exclusively wasm or host
functions. Later pull requests can optimize special imports to be
implemented in wasm, particularly useful for disabled logging callbacks.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-19 11:55:37 +08:00
Crypt Keeper
040736caac Adds function names to host functions and improves logging listener (#697)
This improves the experimental logging listener to show parameter name
and values like so:

```
--> ._start.command_export()
        	--> .__wasm_call_ctors()
        		--> .__wasilibc_initialize_environ()
        			==> wasi_snapshot_preview1.environ_sizes_get(result.environc=1048572,result.environBufSize=1048568)
        			<== ESUCCESS
        		<-- ()
        		==> wasi_snapshot_preview1.fd_prestat_get(fd=3,result.prestat=1048568)
        		<== ESUCCESS
        		--> .dlmalloc(2)
        			--> .sbrk(0)
        			<-- (1114112)
        		<-- (1060080)
--snip--
```

The convention `==>` implies it was a host function call
(def.IsHostFunction). This also improves the lifecycle by creating
listeners during compile. Finally, this backfills param names for
assemblyscript and wasi.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-14 16:43:25 +08:00
Takeshi Yoneda
a6927d58ed Read unsigned leb128 for the index of ref.func in global initializer (#691)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-07-13 15:21:21 +09:00
Crypt Keeper
49e5bcb8c7 Top-levels FunctionDefinition to allow access to all function metadata (#686)
This top-levels `api.FunctionDefinition` which was formerly
experimental, and also adds import metadata to it. Now, it holds all
metadata known at compile time.

Here are the public API visible changes:
* api.ExportedFunction - replaced with api.FunctionDefinition as it is
  usable for all types of functions.
* api.Function - `.ParamTypes/ResultTypes()` are replaced with
  `.Definition().
* api.FunctionDefinition - extracted from experimental and adds
  `.Import()` to get the any imported module and function name.
* experimental.FunctionDefinition - replaced with
  api.FunctionDefinition.
* experimental.FunctionListenerFactory - adds first arg of the
  instantiated module name, as it can be different than compiled.
* wazero.CompiledModule - Adds `.ImportedFunctions()` and changes result
  type of `.ExportedFunctions()` to api.FunctionDefinition.

Internally, logic to create function definition are consolidated between
host and wasm-defined functions, notably wasm.Module now includes
`.BuildFunctionDefinitions()` which reduces duplication in
wasm.ModuleInstance `.BuildFunctions()`,

This obviates #681 by deleting the `ExportedFunction` type which
overlaps with this information.

This fixes #637 as it includes more metadata including imports.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-07-13 14:16:18 +08:00
Takeshi Yoneda
fb911b811c amd64: fix unsigned extension of i32 globals (#658)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-06-27 10:30:45 +09:00
Takeshi Yoneda
3068d17c77 interpreter,compiler(amd64): complete SIMD instructions (#624)
This completes the implementation of SIMD proposal for both
the interpreter and compiler(amd64).
This also fixes #210 by adding the complete documentation
over all the wazeroir operations.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Co-authored-by: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com>
2022-06-15 11:52:47 +09:00
Crypt Keeper
92ba4929e5 Drops support for the WebAssembly text format (#614)
This drops the text format (%.wat) and renames
InstantiateModuleFromCode to InstantiateModuleFromBinary as it is no
longer ambiguous.

We decided to stop supporting the text format as it isn't typically used
in production, yet costs a lot of work to develop. Given the resources
available and the increased work added with WebAssembly 2.0 and soon
WASI 2, we can't afford to spend the time on it.

The old parser is used only internally and will eventually be moved to
its own repository named watzero, possibly towards archival.

See #59

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-06-01 19:01:43 +08:00
Takeshi Yoneda
e493ebe98e Hide V128 from public packages (#575)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-05-17 09:01:46 -06:00
Takeshi Yoneda
064bcdddc6 Implements v128.const and adds support for vector value type. (#556)
This commit implements the v128.const, i32x4.add and i64x2.add in
interpreter mode and this adds support for the vector value types in the
locals and globals.

Notably, the vector type values can be passed and returned by exported functions
as well as host functions via two-uint64 encodings as described in #484 (comment).

Note: implementation of these instructions on JIT will be done in subsequent PR.

part of #484

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-05-16 13:17:26 +09:00
Takeshi Yoneda
bfac34e927 Adds limit on the number of tables per module (#549)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-05-12 20:04:35 +09:00
Takeshi Yoneda
5884a1f49a Pass all non-SIMD v2 core specification tests (#542)
This commit enables WebAssembly 2.0 Core Specification tests.
In order to pass the tests, this fixes several places mostly on the
validation logic.

Note that SIMD instructions are not implemented yet.

part of #484

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Co-authored-by: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com>
2022-05-12 17:07:53 +09:00