-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restructure and improve the docs (#679)
Supersede #675 opening the PR in the main repo to (hopefully) get the Cloudflare preview. --------- Co-authored-by: David Phillips <[email protected]>
- Loading branch information
Showing
25 changed files
with
638 additions
and
206 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,2 @@ | ||
label: Examples | ||
position: 30 |
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,54 @@ | ||
--- | ||
sidebar_position: 1 | ||
sidebar_label: Rust | ||
title: Using Rust with Chicory | ||
--- | ||
## Compile Rust to Wasm | ||
|
||
Compiling a Rust library to Wasm is easy and can be performed using standard `rustc` options: | ||
|
||
```bash | ||
rustc --target=wasm32-unknown-unknown --crate-type=cdylib | ||
``` | ||
|
||
when you need to add support for wasi preview 1(typically when using CLIs) you can use: | ||
|
||
```bash | ||
rustc --target=wasm32-wasi --crate-type=bin | ||
``` | ||
|
||
## Using in Chicory | ||
|
||
<!-- | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
//DEPS com.dylibso.chicory:runtime:999-SNAPSHOT | ||
docs.FileOps.copyFromWasmCorpus("count_vowels.rs.wasm", "count_vowels.rs.wasm"); | ||
System.setOut(new PrintStream( | ||
new BufferedOutputStream( | ||
new FileOutputStream("docs/examples/rust.md.result")))); | ||
``` | ||
--> | ||
|
||
```java | ||
import com.dylibso.chicory.wasm.Parser; | ||
import com.dylibso.chicory.runtime.Instance; | ||
|
||
var instance = Instance.builder(Parser.parse(new File("count_vowels.rs.wasm"))).build(); | ||
|
||
var alloc = instance.export("alloc"); | ||
var dealloc = instance.export("dealloc"); | ||
var countVowels = instance.export("count_vowels"); | ||
|
||
var memory = instance.memory(); | ||
var message = "Hello, World!"; | ||
var len = message.getBytes().length; | ||
int ptr = (int) alloc.apply(len)[0]; | ||
|
||
memory.writeString(ptr, message); | ||
|
||
var result = countVowels.apply(ptr, len)[0]; | ||
System.out.println(result); | ||
``` |
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,2 @@ | ||
label: Experimental | ||
position: 20 |
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,152 @@ | ||
--- | ||
sidebar_position: 3 | ||
sidebar_label: AOT compilation | ||
title: AOT compilation | ||
--- | ||
## Runtime AOT | ||
|
||
<!-- | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
//DEPS com.dylibso.chicory:aot-experimental:999-SNAPSHOT | ||
import com.dylibso.chicory.wasm.Parser; | ||
import com.dylibso.chicory.wasm.WasmModule; | ||
import com.dylibso.chicory.runtime.Instance; | ||
import com.dylibso.chicory.runtime.Machine; | ||
import com.dylibso.chicory.runtime.InterpreterMachine; | ||
docs.FileOps.copyFromWasmCorpus("count_vowels.rs.wasm", "your.wasm"); | ||
``` | ||
--> | ||
|
||
The Ahead-of-Time compiler backend is a drop-in replacement for the interpreter, and it passes 100% of the same | ||
spec tests that the interpreter already supports. | ||
|
||
You can instantiate a module using the AoT by explicitly providing a `MachineFactory`. | ||
The default `Machine` implementation is the `InterpreterMachine`. | ||
|
||
You can opt in to the AoT mode by writing: | ||
|
||
```java | ||
import com.dylibso.chicory.experimental.aot.AotMachine; | ||
|
||
var module = Parser.parse(new File("your.wasm")); | ||
var instance = Instance.builder(module).withMachineFactory(AotMachine::new).build(); | ||
``` | ||
|
||
after you add the dependency: | ||
|
||
```xml | ||
<dependency> | ||
<groupId>com.dylibso.chicory</groupId> | ||
<artifactId>aot-experimental</artifactId> | ||
</dependency> | ||
``` | ||
|
||
This will translate every module you instantiate into Java bytecode on-the-fly and in-memory. | ||
The resulting code is usually expected to evaluate (much)faster and consume less memory. | ||
|
||
Please note that compiling and executing AoT modules at runtime requires: | ||
- an external dependency on [ASM](https://asm.ow2.io/) | ||
- the usage of runtime reflection | ||
|
||
This is usually fine when running on a standard JVM, but it involve some additional configuration when using tools like `native-image`. | ||
|
||
## Pre-compiled AOT | ||
|
||
You can use the AOT compiler at build-time, by leveraging a Maven plug-in to overcome the usage of reflection and external dependencies of the "Runtime AOT". | ||
|
||
This mode of execution reduces startup time and will remove the need for distributing | ||
the original Wasm binary. | ||
|
||
Key advantages are: | ||
|
||
- improved startup time because the translation occurs only once, when you are packaging your application | ||
- distribute Wasm modules as self-contained jars, making it a convenient way to distribute software that was not originally meant to run on the Java platform | ||
- same performance properties as the in-memory compiler (in fact, the compilation backend is the same) | ||
|
||
Example configuration of the Maven plug-in: | ||
|
||
```xml | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>com.dylibso.chicory</groupId> | ||
<artifactId>aot-maven-plugin-experimental</artifactId> | ||
<executions> | ||
<execution> | ||
<id>aot-gen</id> | ||
<goals> | ||
<goal>wasm-aot-gen</goal> | ||
</goals> | ||
<configuration> | ||
<!-- Translate the Wasm binary `add` into bytecode --> | ||
<wasmFile>src/main/resources/add.wasm</wasmFile> | ||
<!-- Generate classes under the following prefix --> | ||
<name>org.acme.wasm.Add</name> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
``` | ||
|
||
In the codebase you can use the generated module by configuring appropriately the `MachineFactory`: | ||
|
||
<!-- | ||
```java | ||
// mocking up the generated code | ||
class AddModule { | ||
|
||
public static WasmModule load() { | ||
return Parser.parse(new File("your.wasm")); | ||
} | ||
|
||
public static Machine create(Instance instance) { | ||
return new InterpreterMachine(instance); | ||
} | ||
} | ||
``` | ||
--> | ||
|
||
```java | ||
// load the bundled module | ||
var module = AddModule.load(); | ||
|
||
// instantiate the module with the pre-compiled code | ||
var instance = Instance.builder(module).withMachineFactory(AddModule::create).build(); | ||
``` | ||
|
||
#### IDE shortcomings | ||
|
||
In some IDEs the sources generated under the standard folder `target/generated-sources` are not automatically recognized. | ||
To overcome this limitation you can use an additional Maven Plugin for a smoother IDE experience: | ||
|
||
```xml | ||
<plugin> | ||
<groupId>org.codehaus.mojo</groupId> | ||
<artifactId>build-helper-maven-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>addSource</id> | ||
<phase>generate-sources</phase> | ||
<goals> | ||
<goal>add-source</goal> | ||
</goals> | ||
<configuration> | ||
<sources> | ||
<source>${project.build.directory}/generated-sources/chicory-aot</source> | ||
</sources> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
``` | ||
|
||
<!-- | ||
```java | ||
docs.FileOps.writeResult("docs/experimental", "aot.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,29 @@ | ||
--- | ||
sidebar_position: 4 | ||
sidebar_label: CLI | ||
title: CLI | ||
--- | ||
# Install and use the CLI | ||
|
||
The experimental Chicory CLI is available for download on Maven at the link: | ||
|
||
``` | ||
https://repo1.maven.org/maven2/com/dylibso/chicory/cli/<version>/cli-<version>.sh | ||
``` | ||
|
||
you can download the latest version and use it locally by typing: | ||
|
||
```bash | ||
export VERSION=$(curl -sS https://api.github.com/repos/dylibso/chicory/tags --header "Accept: application/json" | jq -r '.[0].name') | ||
curl -L -o chicory https://repo1.maven.org/maven2/com/dylibso/chicory/cli-experimental/${VERSION}/cli-experimental-${VERSION}.sh | ||
chmod a+x chicory | ||
./chicory | ||
``` | ||
|
||
<!-- | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
docs.FileOps.writeResult("docs/experimental", "cli.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,123 @@ | ||
--- | ||
sidebar_position: 2 | ||
sidebar_label: Annotations | ||
title: Annotations | ||
--- | ||
# Host Modules | ||
|
||
Instead of writing host functions by hand, you can write a class containing annotated methods | ||
and let the Chicory annotation processor generate the host functions for you. This is especially | ||
useful when you have many host functions. | ||
|
||
<!-- | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
//DEPS com.dylibso.chicory:runtime:999-SNAPSHOT | ||
``` | ||
--> | ||
|
||
```java | ||
@HostModule("demo") | ||
public final class Demo { | ||
|
||
public Demo() {}; | ||
|
||
@WasmExport | ||
public long add(int a, int b) { | ||
return a + b; | ||
} | ||
|
||
@WasmExport // the Wasm name is random_get | ||
public void randomGet(Memory memory, int ptr, int len) { | ||
byte[] data = new byte[len]; | ||
random.nextBytes(data); | ||
memory.write(ptr, data); | ||
} | ||
|
||
public HostFunction[] toHostFunctions() { | ||
return Demo_ModuleFactory.toHostFunctions(this); | ||
} | ||
} | ||
``` | ||
|
||
The `@HostModule` annotation marks the class as a host module and specifies the module name for | ||
all the host functions. The `@WasmExport` annotation marks a method as host function and optionally | ||
specifies the name of the function. If the name is not specified, then the Java method name is | ||
converted from camel case to snake case, as is a common convention in Wasm. | ||
|
||
The `Demo_ModuleFactory` class in `toHostFunctions()` is generated by the annotation processor. | ||
|
||
Host functions must be instance methods of the class. Static methods are not supported. | ||
This is because host functions will typically interact with instance state in the host class. | ||
|
||
To use the host module, you need to instantiate the host module and fetch the host functions: | ||
|
||
<!-- | ||
```java | ||
import com.dylibso.chicory.runtime.HostFunction; | ||
// bug in JShell: https://github.com/jbangdev/jbang/issues/1854 | ||
public class Demo { | ||
public Demo() {}; | ||
public HostFunction[] toHostFunctions() { | ||
return new HostFunction[0]; | ||
} | ||
} | ||
``` | ||
--> | ||
|
||
```java | ||
import com.dylibso.chicory.runtime.ImportValues; | ||
|
||
var demo = new Demo(); | ||
var imports = ImportValues.builder().addFunction(demo.toHostFunctions()).build(); | ||
``` | ||
|
||
### Type conversions | ||
|
||
The following conversions are supported: | ||
|
||
| Java Type | Wasm Type | | ||
|-------------------|------------| | ||
| `int` | `i32` | | ||
| `long` | `i64` | | ||
| `float` | `f32` | | ||
| `double` | `f64` | | ||
|
||
### Enabling the Annotation Processor | ||
|
||
In order to use host modules, you need to import the relevant annotations, e.g. in Maven: | ||
|
||
```xml | ||
<dependency> | ||
<groupId>com.dylibso.chicory</groupId> | ||
<artifactId>host-module-annotations-experimental</artifactId> | ||
<version>latest-release</version> | ||
</dependency> | ||
``` | ||
|
||
and configure the Java compiler to include the Chicory `host-module-processor-experimental` as an annotation processor. | ||
Exactly how this is done depends on the build system you are using, for instance, with Maven: | ||
|
||
```xml | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<path> | ||
<groupId>com.dylibso.chicory</groupId> | ||
<artifactId>host-module-processor-experimental</artifactId> | ||
<version>latest-release</version> | ||
</path> | ||
</annotationProcessorPaths> | ||
</configuration> | ||
</plugin> | ||
``` | ||
|
||
<!-- | ||
```java | ||
docs.FileOps.writeResult("docs/experimental", "host-modules.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 @@ | ||
--- | ||
sidebar_position: 1 | ||
sidebar_label: Why | ||
title: Why | ||
--- | ||
# Why? | ||
|
||
Chicory is a young project and we acknowledge that we are exploring and spearheading in many aspects the usage of Web Assembly on the JVM. | ||
|
||
Since there is(always) some degree of experimentation going on, and we want to have feedback by the community and early users, we decide to publish also `experimental` modules; everyone is welcome to try things out and report back the experience. | ||
|
||
Please note that if "something works" for you, its very unlikely that it will be removed completely, in most cases, expect slight public API changes or module renames to happen. | ||
|
||
The goal of having `experimental` modules is because they are not stabilized, we are not 100% confident in the design and we want to be able to perform breaking changes without respecting SemVer. | ||
|
||
This includes renaming artifactIDs, classes, methods, and reworking their usage according to user feedback and development progress. | ||
|
||
<!-- | ||
```java | ||
//DEPS com.dylibso.chicory:docs-lib:999-SNAPSHOT | ||
docs.FileOps.writeResult("docs/experimental", "why.md.result", "empty"); | ||
``` | ||
--> |
Oops, something went wrong.