Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 65 additions & 2 deletions graalwasm/graalwasm-embed-c-code-guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public class App {
public static void main(String[] args) throws IOException {
// Find the WebAssembly module resource
URL wasmFile = App.class.getResource("floyd.wasm");
Source source = Source.newBuilder("wasm", wasmFile).name("example").build();
Source source = Source.newBuilder("wasm", wasmFile).build();

// Create Wasm context
try (Context context = Context.newBuilder("wasm").option("wasm.Builtins", "wasi_snapshot_preview1").build()) {
Expand All @@ -180,7 +180,70 @@ public class App {
}
```

## 4. Building and Testing the Application
## 4. Using Java functions from WebAssembly

You can also call Java functions from WebAssembly by importing them into your WebAssembly modules.
For this example, let's try to move the logic which computes the next element of the output (by doing an integer increment) to a Java function.

We need to add the following to our C file to declare an external function whose implementation we will provide in Java:

```c
extern int javaInc(int number)
__attribute__((
__import_module__("env"),
__import_name__("java-increment"),
));
```

This introduces an import in the resulting WebAssembly module.
The import will pull a function named `java-increment` from the imported module `env`.
Within our C code, this function will be available under the name `javaInc`.
We can update our `floyd` function to use `javaInc` like so:

```c
void floyd(int rows) {
int number = 1;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= i; j++) {
printf("%d ", number);
number = javaInc(number);
}
printf(".\n");
}
}
```

Then, in our Java application, we pass in an import object when instantiating our WebAssembly module.
This import object maps module names to module objects, with each module object mapping function names to function definitions.

```java
...
import java.util.Map;
import org.graalvm.polyglot.proxy.ProxyExecutable;
import org.graalvm.polyglot.proxy.ProxyObject;

public class App {

public static Object javaIncrement(Value... v) {
return Value.asValue(v[0].asInt() + 1);
}

public static void main(String[] args) throws IOException {
...
// Compile and instantiate the module with host function
Value module = context.eval(source);
Value instance = module.newInstance(ProxyObject.fromMap(
Map.of("env", ProxyObject.fromMap(
Map.of("java-increment", (ProxyExecutable) App::javaIncrement)
))
));
...
}
}
}
```

## 5. Building and Testing the Application

Compile and run this Java application with Maven:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static Object javaIncrement(Value... v) {
public static void main(String[] args) throws IOException {
// Find the WebAssembly module resource
URL wasmFile = App.class.getResource("floyd.wasm");
Source source = Source.newBuilder("wasm", wasmFile).name("example").build();
Source source = Source.newBuilder("wasm", wasmFile).build();

// Create Wasm context
try (Context context = Context.newBuilder("wasm")
Expand Down