-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add all the docs section to the static site
- Loading branch information
Showing
6 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
--- | ||
id: Host functions | ||
sidebar_position: 1 | ||
sidebar_label: Host functions | ||
--- | ||
|
||
### Host Functions | ||
|
||
On its own, Wasm can't do anything but compute. It cannot affect the outside world. This might seem like a weakness | ||
but it's actually Wasm's greatest strength. By default, programs are sandboxed and have no capabilities. If you want a program | ||
to have capabilities, you must provide them. This puts you in the seat of the operating system. A module can | ||
ask for a capability by listing an "import" function in it's bytecode format. You can fulfill this import with a host | ||
function written in Java. Regardless of the language of the module, it can call this Java function when it needs. | ||
If it helps, you can think of host functions like syscalls or a languages standard library but you decide what they | ||
are and how they behave and it's written in Java. | ||
|
||
Let's download another example module to demonstrate this: | ||
|
||
```bash | ||
curl https://raw.githubusercontent.com/dylibso/chicory/main/wasm-corpus/src/main/resources/compiled/host-function.wat.wasm > logger.wasm | ||
``` | ||
|
||
<!-- | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
//DEPS com.dylibso.chicory:runtime:999-SNAPSHOT | ||
``` | ||
--> | ||
<!-- | ||
```java | ||
docs.FileOps.copyFromWasmCorpus("host-function.wat.wasm", "logger.wasm"); | ||
``` | ||
--> | ||
|
||
This module expects us to fulfil an import with the name `console.log` which will allow the module to log to the stdout. | ||
Let's write that host function: | ||
|
||
<!-- | ||
```java | ||
public String hostFunctionResult = ""; | ||
public void println(String value) { | ||
hostFunctionResult += value + "\n"; | ||
} | ||
``` | ||
--> | ||
|
||
|
||
```java | ||
import com.dylibso.chicory.runtime.Instance; | ||
import com.dylibso.chicory.runtime.HostFunction; | ||
import com.dylibso.chicory.wasm.types.ValueType; | ||
|
||
var func = new HostFunction( | ||
"console", | ||
"log", | ||
(Instance instance, long... args) -> { // decompiled is: console_log(13, 0); | ||
var len = (int) args[0]; | ||
var offset = (int) args[1]; | ||
var message = instance.memory().readString(offset, len); | ||
println(message); | ||
return null; | ||
}, | ||
List.of(ValueType.I32, ValueType.I32), | ||
List.of()); | ||
``` | ||
|
||
Again we're dealing with pointers here. The module calls `console.log` with the length of the string | ||
and the pointer (offset) in its memory. We again use the `Memory` class but this time we're pulling a string | ||
*out* of memory. We can then print that to stdout on behalf of our Wasm program. | ||
|
||
Note that the HostFunction needs 3 things: | ||
|
||
1. A lambda to call when the Wasm module invokes the import | ||
2. The namespace and function name of the import (in our case it's console and log respectively) | ||
3. The Wasm type signature (this function takes 2 i32s as arguments and returns nothing) | ||
|
||
Now we just need to pass this host function in during our instantiation phase: | ||
|
||
```java | ||
import com.dylibso.chicory.wasm.Parser; | ||
import com.dylibso.chicory.runtime.ExternalValues; | ||
var hostFunctions = new ExternalValues(new HostFunction[] {func}); | ||
var instance = Instance.builder(Parser.parse(new File("./logger.wasm"))).withExternalValues(hostFunctions).build(); | ||
var logIt = instance.export("logIt"); | ||
logIt.apply(); | ||
// should print "Hello, World!" 10 times | ||
``` | ||
|
||
<!-- | ||
```java | ||
docs.FileOps.writeResult("docs/usage", "host-functions.md.result", hostFunctionResult); | ||
``` | ||
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
--- | ||
id: Linking | ||
sidebar_position: 1 | ||
sidebar_label: Linking | ||
--- | ||
|
||
### Store and Instantiating Multiple Modules | ||
|
||
A [Store][spec] is an intermediate-level abstraction that collects Wasm function, global, memory, and table instances | ||
as named entities. | ||
|
||
It simplifies creating instances when there are a lot of interdependencies, by collecting all the | ||
|
||
In the simplest case, it allows to register single host functions, globals, memories and tables: | ||
|
||
<!-- | ||
TODO: should we make this more explicit? | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
//DEPS com.dylibso.chicory:runtime:999-SNAPSHOT | ||
import com.dylibso.chicory.wasm.Parser; | ||
import com.dylibso.chicory.runtime.Instance; | ||
import com.dylibso.chicory.runtime.HostFunction; | ||
import com.dylibso.chicory.runtime.ExternalValues; | ||
import com.dylibso.chicory.wasm.types.ValueType; | ||
var func = new HostFunction( | ||
"console", | ||
"log", | ||
(Instance instance, long... args) -> { // decompiled is: console_log(13, 0); | ||
var len = (int) args[0]; | ||
var offset = (int) args[1]; | ||
var message = instance.memory().readString(offset, len); | ||
println(message); | ||
return null; | ||
}, | ||
List.of(ValueType.I32, ValueType.I32), | ||
List.of()); | ||
var hostFunctions = new ExternalValues(new HostFunction[] {func}); | ||
var instance = Instance.builder(Parser.parse(new File("./logger.wasm"))).withExternalValues(hostFunctions).build(); | ||
``` | ||
--> | ||
|
||
```java | ||
import com.dylibso.chicory.runtime.Store; | ||
|
||
// instantiate the store | ||
var store = new Store(); | ||
// registers `console.log` in the store (see the previous section for the definition of `func`) | ||
store.addFunction(func); | ||
``` | ||
|
||
However, the store also automatically exposes the exports of a module to the other instances that are registered. | ||
|
||
```java | ||
// registers the `instance` created earlier (see the previous section) with the name `logger` | ||
store.register("logger", instance); | ||
// now the exported function `logIt` can be imported by other modules as `logger.logIt` | ||
``` | ||
|
||
There is also a shorthand method to instantiate a module and register the resulting instance: | ||
|
||
```java | ||
var logger2 = store.instantiate("logger2", Parser.parse(new File("./logger.wasm"))); | ||
``` | ||
|
||
This is equivalent to: | ||
|
||
```java | ||
var external = store.toExternalValues(); | ||
var m = Parser.parse(new File("./logger.wasm")); | ||
var instance = Instance.builder(m).withExternalValues(external).build(); | ||
store.register("logger2", instance); | ||
``` | ||
|
||
Notice that registering two instances with the same name results in overwriting the | ||
functions, globals, memories, tables with matching names. In this case, the new `logger2.logIt` function | ||
overwrote the old `logger2.logIt` function. | ||
|
||
The current `Store` is a mutable object, not meant to be shared (it is not thread-safe). | ||
|
||
A `Store` _does not_ resolve interdependencies between modules in itself: if your set of modules | ||
have interdependencies, you will have to instantiate and register them in the right order. | ||
|
||
[spec]: https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#store%E2%91%A0 | ||
|
||
<!-- | ||
```java | ||
docs.FileOps.writeResult("docs/usage", "linking.md.result", "empty"); | ||
``` | ||
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
id: Logging | ||
sidebar_position: 1 | ||
sidebar_label: Logging | ||
--- | ||
|
||
### Logging | ||
|
||
For maximum compatibility and to avoid external dependencies we use, by default, the JDK Platform Logging (JEP 264). | ||
You can configure it by providing a `logging.properties` using the `java.util.logging.config.file` property and [here](https://docs.oracle.com/cd/E57471_01/bigData.100/data_processing_bdd/src/rdp_logging_config.html) you can find the possible configurations. | ||
|
||
For more advanced configuration scenarios we encourage you to provide an alternative, compatible, adapter: | ||
|
||
- [slf4j](https://www.slf4j.org/manual.html#jep264) | ||
- [log4j2](https://logging.apache.org/log4j/2.x/log4j-jpl.html) | ||
|
||
It's also possible to provide a custom `com.dylibso.chicory.log.Logger` implementation if JDK Platform Logging is not available or doesn't fit. | ||
|
||
<!-- | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
docs.FileOps.writeResult("docs/usage", "logging.md.result", "empty"); | ||
``` | ||
--> |
10 changes: 10 additions & 0 deletions
10
docs/tests/approvals/docs-usage-host-functions.md.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! | ||
Hello, World! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
empty |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
empty |