Package ai.tegmentum.webassembly4j.runtime.gc
This package provides a high-level bridge for passing structured data between Java and WebAssembly using the WasmGC (Garbage Collection) proposal instead of linear memory. Objects live on the Wasm runtime's managed heap and are garbage-collected automatically -- no manual allocation or freeing is needed.
Quick Start
Annotate a Java class or record with GcMapped:
@GcMapped
public class Point {
double x;
double y;
public Point() {}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
}
Create a GcMarshaller from a GcExtension
and marshal objects in both directions:
GcExtension gc = instance.extension(GcExtension.class)
.orElseThrow(() -> new UnsupportedOperationException("GC not supported"));
GcMarshaller marshaller = GcMarshaller.forExtension(gc);
// Java -> GC struct
Point p = new Point(3.0, 4.0);
GcStructInstance struct = marshaller.marshal(p);
// GC struct -> Java
Point result = marshaller.unmarshal(struct, Point.class);
assert result.x == 3.0;
assert result.y == 4.0;
Type Mapping
The following Java types are supported as fields in @GcMapped classes:
| Java Type | GC Field Type | Notes |
|---|---|---|
int / Integer | i32 | |
long / Long | i64 | |
float / Float | f32 | |
double / Double | f64 | |
boolean / Boolean | i32 | 0 = false, 1 = true |
@GcMapped class | structref (nullable) | Recursively marshalled |
static and transient fields are excluded. Fields are
mapped in declaration order.
Records
Java records work naturally:
@GcMapped
public record Vec3(float x, float y, float z) {}
Vec3 v = new Vec3(1.0f, 2.0f, 3.0f);
GcStructInstance struct = marshaller.marshal(v);
Vec3 roundTripped = marshaller.unmarshal(struct, Vec3.class);
Records are unmarshalled via their canonical constructor. Regular classes require a no-arg constructor; fields are set reflectively.
Nested Structs
Fields whose type is also @GcMapped are marshalled as nested
GC struct references:
@GcMapped
public record Line(Point start, Point end) {}
Line line = new Line(new Point(0, 0), new Point(1, 1));
GcStructInstance struct = marshaller.marshal(line);
// The struct has two reference fields pointing to nested Point structs
GcStructInstance startStruct = (GcStructInstance) struct.getField(0).asReference();
Null nested references are marshalled as GcValue.nullValue() and
unmarshalled back to null.
Interface Proxy Binding
GcProxyFactory creates Java interface proxies that automatically
marshal @GcMapped parameters and return values through GC structs.
This mirrors ProxyFactory
but uses the GC heap instead of linear memory:
@GcMapped
record Point(double x, double y) {}
interface Geometry extends AutoCloseable {
@WasmExport("rotate_point")
Point rotate(Point p, double angle);
@WasmExport("distance")
double distance(Point a, Point b);
}
GcExtension gc = instance.extension(GcExtension.class).orElseThrow();
Geometry geom = GcProxyFactory.create(
Geometry.class, engine, module, instance, gc);
Point rotated = geom.rotate(new Point(1, 0), Math.PI / 2);
double dist = geom.distance(new Point(0, 0), new Point(3, 4));
Primitive parameters pass through directly to the Wasm function.
@GcMapped parameters are marshalled to GcStructInstance
before the call, and @GcMapped return types are unmarshalled
after.
When to Use GC vs Linear Memory
- Use GC marshalling when working with languages that compile to WasmGC (Kotlin/Wasm, Dart, OCaml, Java via J2Wasm), or when you want automatic lifetime management for structured data.
- Use linear memory marshalling (via
ProxyFactory) when working with languages that compile to traditional Wasm with linear memory (C, C++, Rust, Go).
Limitations
- Not all runtimes support WasmGC. Check for
instance.extension(GcExtension.class)availability. - Java's GC and the Wasm runtime's GC are separate collectors. Java references to GC objects pin them on the Wasm heap, but cross-heap reference cycles are not automatically collected.
- String fields are not supported (no native string type in WasmGC). Use linear memory marshalling for string-heavy interfaces.
- Array fields (e.g.,
int[]) are not yet supported. UseGcExtension.createArray(ai.tegmentum.webassembly4j.api.gc.GcArrayType, ai.tegmentum.webassembly4j.api.gc.GcValue...)directly for array data.
- See Also:
-
ClassDescriptionMarks a Java class or record as mappable to a WebAssembly GC struct type.Marshals Java objects to and from WebAssembly GC struct instances.Creates Java interface proxies that marshal method arguments and return values through WebAssembly GC struct types instead of linear memory.Maps Java classes annotated with
GcMappedto WebAssembly GC struct types.