Package ai.tegmentum.webassembly4j.runtime.gc


package ai.tegmentum.webassembly4j.runtime.gc
WasmGC Object Bridge -- automatic marshalling between Java objects and WebAssembly GC struct instances.

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 to WasmGC type mapping
Java TypeGC Field TypeNotes
int / Integeri32
long / Longi64
float / Floatf32
double / Doublef64
boolean / Booleani320 = false, 1 = true
@GcMapped classstructref (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. Use GcExtension.createArray(ai.tegmentum.webassembly4j.api.gc.GcArrayType, ai.tegmentum.webassembly4j.api.gc.GcValue...) directly for array data.
See Also: