Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow imports to use functions from structs / Multi-threading #23

Closed
pkedy opened this issue May 31, 2019 · 3 comments
Closed

Allow imports to use functions from structs / Multi-threading #23

pkedy opened this issue May 31, 2019 · 3 comments
Labels
🎉 enhancement New feature or request

Comments

@pkedy
Copy link

pkedy commented May 31, 2019

Motivation

I am testing several WebAssembly runtimes here. In my use case I will be sending and receiving JSON payloads to a function in a multi-threaded host. Currently Imports.Append can only use exported function pointers which are global. Unless there is some meaning to context unsafe.Pointer, I cannot encapsulate the input/output JSON in a struct per Instance.

Also, It would also be nice if compilation and execution were separate steps. In a multi-threaded host, this would mean that the cost of compilation is only incurred once.

Proposed solution

This might not be possible with CGO but somehow use the implementation interface{} parameter of Imports.Append as the execution target. Currently it is only used to read the parameters and return type. Another approach could be to pass the Instance pointer as context and include a UserData field so that you can cast and delegate to a struct implementation.

For separation of compilation and execution, there might be a func wasm.NewModuleWithImports(code []byte, imports *Imports) *Module function that returns the compiled module instructions, etc. Then module.NewInstance would return a single VM with its own memory, etc.

Additional context

General question: How does the one use the context unsafe.Pointer parameter? I've tried casting it to *Instance and *Memory. Both attempts ended poorly (core dump). A sample in the README would be super helpful.

@pkedy pkedy added the 🎉 enhancement New feature or request label May 31, 2019
@hleb-albau
Copy link

hleb-albau commented Jun 1, 2019

So desirable feature.
Also, is it possible, to pass same type structs, but with new values without recompiling instance?

In general, is it ok to use wasm to create plugin system for regular application, that will invoke that wasm like regular function? For example, for each packet from iot device i need to decode it into some struct. That decoders will be supplied as wasm.

bors bot added a commit that referenced this issue Jun 4, 2019
26: feat(import) Support instance context API r=Hywan a=Hywan

Partially address #23.
Ping @YaronWittenstein

This PR brings an `InstanceContext` API:

1. From an imported function, call `IntoInstanceContext(context)` to cast the `unsafe.Pointer` into an `InstanceContext`,
2. Now, call the `Memory` method to get the instance context,
3. Use the `Memory.Data` method to read or write memor data.

Co-authored-by: Ivan Enderlin <[email protected]>
@Hywan
Copy link
Contributor

Hywan commented Jun 4, 2019

Thanks for your proposal. I read multiple requests:

  1. Module compilation and caching,
  2. Define imported function without cgo,
  3. Make context unsafe.Pointer no longer opaque in imported functions signature,
  4. Define instance context “user data”.

So, about 1, see #27.
About 2, imported function must rely on cgo so far. I don't see any other way to do that with the Wasm runtime.
About 3, see #26.
About 4, if you're talking about a way to pass data from within an imported function to the outside, I'm working on an “instance context data” API, see #28.

bors bot added a commit that referenced this issue Jun 5, 2019
34: feat(module) Support module serialization and deserialization r=Hywan a=Hywan

Sequel of #27 and #33.
Ping #23.

Example:

```go
	// Compiles the bytes into a WebAssembly module.
	module1, _ := wasm.Compile(GetBytes())
	defer module1.Close()

	// Serializes the module into a sequence of bytes.
	serialization, _ := module1.Serialize()

	// Do something with `serialization`.
	// Then later…

	// Deserializes the module.
	module2, _ := wasm.DeserializeModule(serialization)
	defer module2.Close()
	// And enjoy!

	// Instantiates the WebAssembly module.
	instance, _ := module2.Instantiate()
	defer instance.Close()

	// Gets an exported function.
	sum, functionExists := instance.Exports["sum"]

	fmt.Println(functionExists)

	// Calls the `sum` exported function with Go values.
	result, _ := sum(1, 2)

	fmt.Println(result)

	// Output:
	// true
	// 3
```

The final API is quite easy to use. I hope `[]byte` is a generic enough type to be accepted by Go caching libraries.

Co-authored-by: Ivan Enderlin <[email protected]>
@Hywan
Copy link
Contributor

Hywan commented Jun 24, 2019

I think all the questions have been addressed. I'm closing the issue. Feel free to speak if I missed one point and I'll re-open it. Thanks!

@Hywan Hywan closed this as completed Jun 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎉 enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants