diff --git a/runtime/src/main/java/org/capnproto/BuilderArena.java b/runtime/src/main/java/org/capnproto/BuilderArena.java index 37dc774..4e6f8a6 100644 --- a/runtime/src/main/java/org/capnproto/BuilderArena.java +++ b/runtime/src/main/java/org/capnproto/BuilderArena.java @@ -24,6 +24,7 @@ package org.capnproto; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; +import java.util.List; public final class BuilderArena implements Arena { public enum AllocationStrategy { @@ -38,6 +39,35 @@ public final class BuilderArena implements Arena { public final ArrayList segments; private Allocator allocator; + private CapTableBuilder localCapTable = new CapTableBuilder() { + + List capTable = new ArrayList<>(); + + @Override + public int injectCap(ClientHook cap) { + int result = this.capTable.size(); + capTable.add(cap); + return result; + } + + @Override + public void dropCap(int index) { + if (index < this.capTable.size()) { + assert false : "Invalid capability descriptor in message."; + return; + } + this.capTable.set(index, null); + + } + + @Override + public ClientHook extractCap(int index) { + return index < this.capTable.size() + ? this.capTable.get(index) + : null; + } + }; + public BuilderArena(int firstSegmentSizeWords, AllocationStrategy allocationStrategy) { this.segments = new ArrayList(); { @@ -64,6 +94,16 @@ public final class BuilderArena implements Arena { this.allocator = allocator; } + CapTableBuilder getLocalCapTable() { + return this.localCapTable; + } + + CapTableBuilder releaseLocalCapTable() { + var tmp = this.localCapTable; + this.localCapTable = null; + return tmp; + } + @Override public final SegmentReader tryGetSegment(int id) { return this.segments.get(id); diff --git a/runtime/src/main/java/org/capnproto/MessageBuilder.java b/runtime/src/main/java/org/capnproto/MessageBuilder.java index 40d714d..98a5560 100644 --- a/runtime/src/main/java/org/capnproto/MessageBuilder.java +++ b/runtime/src/main/java/org/capnproto/MessageBuilder.java @@ -85,9 +85,9 @@ public final class MessageBuilder { if (location != 0) { throw new RuntimeException("First allocated word of new segment was not at offset 0"); } - return new AnyPointer.Builder(rootSegment, location); + return new AnyPointer.Builder(rootSegment, this.arena.getLocalCapTable(), location); } else { - return new AnyPointer.Builder(rootSegment, 0); + return new AnyPointer.Builder(rootSegment, this.arena.getLocalCapTable(), 0); } }