Skip to content

Commit

Permalink
add all the docs section to the static site
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaTP committed Oct 18, 2024
1 parent 1ae6db6 commit 8fc794d
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 0 deletions.
93 changes: 93 additions & 0 deletions docs/docs/usage/host-functions.md
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);
```
-->
92 changes: 92 additions & 0 deletions docs/docs/usage/linking.md
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");
```
-->
24 changes: 24 additions & 0 deletions docs/docs/usage/logging.md
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 docs/tests/approvals/docs-usage-host-functions.md.approved.txt
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!
1 change: 1 addition & 0 deletions docs/tests/approvals/docs-usage-linking.md.approved.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
empty
1 change: 1 addition & 0 deletions docs/tests/approvals/docs-usage-logging.md.approved.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
empty

0 comments on commit 8fc794d

Please sign in to comment.