diff --git a/runtime/src/main/java/org/capnproto/AnyPointer.java b/runtime/src/main/java/org/capnproto/AnyPointer.java index 5c3fac2..9e5d6c9 100644 --- a/runtime/src/main/java/org/capnproto/AnyPointer.java +++ b/runtime/src/main/java/org/capnproto/AnyPointer.java @@ -23,35 +23,24 @@ package org.capnproto; public final class AnyPointer { public static final class Factory implements PointerFactory { - public final Reader fromPointerReader(SegmentReader segment, int pointer, int nestingLimit) { - return new Reader(segment, pointer, nestingLimit); - } public final Reader fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { - var result = new Reader(segment, pointer, nestingLimit); - result.capTable = capTable; - return result; - } - public final Builder fromPointerBuilder(SegmentBuilder segment, int pointer) { - return new Builder(segment, pointer); + return new Reader(segment, capTable, pointer, nestingLimit); } public final Builder fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { - var result = new Builder(segment, pointer); - result.capTable = capTable; - return result; + return new Builder(segment, capTable, pointer); } - public final Builder initFromPointerBuilder(SegmentBuilder segment, int pointer, int elementCount) { - Builder result = new Builder(segment, pointer); + public final Builder initFromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, int elementCount) { + Builder result = new Builder(segment, capTable, pointer); result.clear(); return result; } } public static final Factory factory = new Factory(); - public final static class Reader { + public final static class Reader extends Capability.ReaderContext { final SegmentReader segment; final int pointer; // offset in words final int nestingLimit; - CapTableReader capTable; public Reader(SegmentReader segment, int pointer, int nestingLimit) { this.segment = segment; @@ -59,6 +48,13 @@ public final class AnyPointer { this.nestingLimit = nestingLimit; } + public Reader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { + this.segment = segment; + this.pointer = pointer; + this.nestingLimit = nestingLimit; + this.capTable = capTable; + } + final Reader imbue(CapTableReader capTable) { var result = new Reader(segment, pointer, nestingLimit); result.capTable = capTable; @@ -94,20 +90,23 @@ public final class AnyPointer { } } - public static final class Builder { + public static final class Builder extends Capability.BuilderContext { final SegmentBuilder segment; final int pointer; - CapTableBuilder capTable; public Builder(SegmentBuilder segment, int pointer) { this.segment = segment; this.pointer = pointer; } + Builder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { + this.segment = segment; + this.pointer = pointer; + this.capTable = capTable; + } + final Builder imbue(CapTableBuilder capTable) { - var result = new Builder(segment, pointer); - result.capTable = capTable; - return result; + return new Builder(segment, capTable, pointer); } public final boolean isNull() { @@ -115,19 +114,19 @@ public final class AnyPointer { } public final T getAs(FromPointerBuilder factory) { - return factory.fromPointerBuilder(this.segment, this.pointer); + return factory.fromPointerBuilder(this.segment, this.capTable, this.pointer); } public final T initAs(FromPointerBuilder factory) { - return factory.initFromPointerBuilder(this.segment, this.pointer, 0); + return factory.initFromPointerBuilder(this.segment, this.capTable, this.pointer, 0); } public final T initAs(FromPointerBuilder factory, int elementCount) { - return factory.initFromPointerBuilder(this.segment, this.pointer, elementCount); + return factory.initFromPointerBuilder(this.segment, this.capTable, this.pointer, elementCount); } public final void setAs(SetPointerBuilder factory, U reader) { - factory.setPointerBuilder(this.segment, this.pointer, reader); + factory.setPointerBuilder(this.segment, this.capTable, this.pointer, reader); } public final void setAsCapability(Capability.Client cap) { @@ -135,11 +134,11 @@ public final class AnyPointer { } public final Reader asReader() { - return new Reader(segment, pointer, java.lang.Integer.MAX_VALUE); + return new Reader(segment, this.capTable, pointer, java.lang.Integer.MAX_VALUE); } public final void clear() { - WireHelpers.zeroObject(this.segment, this.pointer); + WireHelpers.zeroObject(this.segment, this.capTable, this.pointer); this.segment.buffer.putLong(this.pointer * 8, 0L); } } diff --git a/runtime/src/main/java/org/capnproto/Data.java b/runtime/src/main/java/org/capnproto/Data.java index b751ee5..b97def1 100644 --- a/runtime/src/main/java/org/capnproto/Data.java +++ b/runtime/src/main/java/org/capnproto/Data.java @@ -40,44 +40,41 @@ public final class Data { } @Override - public Reader fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { - return fromPointerReader(segment, pointer, nestingLimit); + public final Reader fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { + return WireHelpers.readDataPointer(segment, pointer, null, 0, 0); } @Override public final Builder fromPointerBuilderBlobDefault( SegmentBuilder segment, + CapTableBuilder capTable, int pointer, java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { return WireHelpers.getWritableDataPointer(pointer, segment, + capTable, defaultBuffer, defaultOffset, defaultSize); } - @Override - public final Builder fromPointerBuilder(SegmentBuilder segment, int pointer) { + public final Builder fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { return WireHelpers.getWritableDataPointer(pointer, segment, + capTable, null, 0, 0); } @Override - public Builder fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { - return fromPointerBuilder(segment, pointer); + public final Builder initFromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, int size) { + return WireHelpers.initDataPointer(pointer, segment, capTable, size); } @Override - public final Builder initFromPointerBuilder(SegmentBuilder segment, int pointer, int size) { - return WireHelpers.initDataPointer(pointer, segment, size); - } - - @Override - public final void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value) { - WireHelpers.setDataPointer(pointer, segment, value); + public final void setPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, Reader value) { + WireHelpers.setDataPointer(pointer, segment, capTable, value); } } public static final Factory factory = new Factory(); diff --git a/runtime/src/main/java/org/capnproto/FromPointerBuilder.java b/runtime/src/main/java/org/capnproto/FromPointerBuilder.java index 5476e24..1a2342a 100644 --- a/runtime/src/main/java/org/capnproto/FromPointerBuilder.java +++ b/runtime/src/main/java/org/capnproto/FromPointerBuilder.java @@ -22,13 +22,14 @@ package org.capnproto; public interface FromPointerBuilder { - T fromPointerBuilder(SegmentBuilder segment, int pointer); - default T fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { - + default T fromPointerBuilder(SegmentBuilder segment, int pointer) { return fromPointerBuilder(segment, pointer); } - T initFromPointerBuilder(SegmentBuilder segment, int pointer, int elementCount); - default T initFromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, int elementCount) { - return initFromPointerBuilder(segment, pointer, elementCount); + + T fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer); + + default T initFromPointerBuilder(SegmentBuilder segment, int pointer, int elementCount) { + return initFromPointerBuilder(segment, null, pointer, elementCount); } + T initFromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, int elementCount); } diff --git a/runtime/src/main/java/org/capnproto/FromPointerBuilderBlobDefault.java b/runtime/src/main/java/org/capnproto/FromPointerBuilderBlobDefault.java index 377fb3a..3004bee 100644 --- a/runtime/src/main/java/org/capnproto/FromPointerBuilderBlobDefault.java +++ b/runtime/src/main/java/org/capnproto/FromPointerBuilderBlobDefault.java @@ -22,6 +22,11 @@ package org.capnproto; public interface FromPointerBuilderBlobDefault { - T fromPointerBuilderBlobDefault(SegmentBuilder segment, int pointer, + default T fromPointerBuilderBlobDefault(SegmentBuilder segment, int pointer, + java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { + return fromPointerBuilderBlobDefault(segment, null, pointer, defaultBuffer, defaultOffset, defaultSize); + } + + T fromPointerBuilderBlobDefault(SegmentBuilder segment, CapTableBuilder capTable, int pointer, java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize); } diff --git a/runtime/src/main/java/org/capnproto/FromPointerBuilderRefDefault.java b/runtime/src/main/java/org/capnproto/FromPointerBuilderRefDefault.java index 50c8b3d..44d56e8 100644 --- a/runtime/src/main/java/org/capnproto/FromPointerBuilderRefDefault.java +++ b/runtime/src/main/java/org/capnproto/FromPointerBuilderRefDefault.java @@ -22,5 +22,10 @@ package org.capnproto; public interface FromPointerBuilderRefDefault { - T fromPointerBuilderRefDefault(SegmentBuilder segment, int pointer, SegmentReader defaultSegment, int defaultOffset); + + default T fromPointerBuilderRefDefault(SegmentBuilder segment, int pointer, SegmentReader defaultSegment, int defaultOffset) { + return fromPointerBuilderRefDefault(segment, null, pointer, defaultSegment, defaultOffset); + } + + T fromPointerBuilderRefDefault(SegmentBuilder segment, CapTableBuilder capTable, int pointer, SegmentReader defaultSegment, int defaultOffset); } diff --git a/runtime/src/main/java/org/capnproto/FromPointerReader.java b/runtime/src/main/java/org/capnproto/FromPointerReader.java index 042afe9..5738cc5 100644 --- a/runtime/src/main/java/org/capnproto/FromPointerReader.java +++ b/runtime/src/main/java/org/capnproto/FromPointerReader.java @@ -22,9 +22,8 @@ package org.capnproto; public interface FromPointerReader { - T fromPointerReader(SegmentReader segment, int pointer, int nestingLimit); - - default T fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { - return fromPointerReader(segment, pointer, nestingLimit); + default T fromPointerReader(SegmentReader segment, int pointer, int nestingLimit) { + return fromPointerReader(segment, null, pointer, nestingLimit); } + T fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit); } diff --git a/runtime/src/main/java/org/capnproto/FromPointerReaderRefDefault.java b/runtime/src/main/java/org/capnproto/FromPointerReaderRefDefault.java index e6d05e0..cf30163 100644 --- a/runtime/src/main/java/org/capnproto/FromPointerReaderRefDefault.java +++ b/runtime/src/main/java/org/capnproto/FromPointerReaderRefDefault.java @@ -22,5 +22,8 @@ package org.capnproto; public interface FromPointerReaderRefDefault { - T fromPointerReaderRefDefault(SegmentReader segment, int pointer, SegmentReader defaultSegment, int defaultOffset, int nestingLimit); + default T fromPointerReaderRefDefault(SegmentReader segment, int pointer, SegmentReader defaultSegment, int defaultOffset, int nestingLimit) { + return fromPointerReaderRefDefault(segment, null, pointer, defaultSegment, defaultOffset, nestingLimit); + } + T fromPointerReaderRefDefault(SegmentReader segment, CapTableReader capTable, int pointer, SegmentReader defaultSegment, int defaultOffset, int nestingLimit); } diff --git a/runtime/src/main/java/org/capnproto/ListBuilder.java b/runtime/src/main/java/org/capnproto/ListBuilder.java index b91006a..7af8840 100644 --- a/runtime/src/main/java/org/capnproto/ListBuilder.java +++ b/runtime/src/main/java/org/capnproto/ListBuilder.java @@ -21,11 +21,22 @@ package org.capnproto; -public class ListBuilder { +import java.util.List; + +public class ListBuilder extends Capability.BuilderContext { public interface Factory { T constructBuilder(SegmentBuilder segment, int ptr, int elementCount, int step, int structDataSize, short structPointerCount); + default T constructBuilder(SegmentBuilder segment, CapTableBuilder capTable, int ptr, + int elementCount, int step, + int structDataSize, short structPointerCount) { + var result = constructBuilder(segment, ptr, elementCount, step, structDataSize, structPointerCount); + if (result instanceof Capability.BuilderContext) { + ((Capability.BuilderContext) result).capTable = capTable; + } + return result; + } } final SegmentBuilder segment; @@ -34,7 +45,6 @@ public class ListBuilder { final int step; // in bits final int structDataSize; // in bits final short structPointerCount; - CapTableBuilder capTable; public ListBuilder(SegmentBuilder segment, int ptr, int elementCount, int step, @@ -120,6 +130,7 @@ public class ListBuilder { int structPointers = (structData + (this.structDataSize / 8)) / 8; return factory.constructBuilder(this.segment, + this.capTable, structData, structPointers, this.structDataSize, @@ -129,18 +140,21 @@ public class ListBuilder { protected final T _getPointerElement(FromPointerBuilder factory, int index) { return factory.fromPointerBuilder( this.segment, + this.capTable, (this.ptr + (int)((long)index * this.step / Constants.BITS_PER_BYTE)) / Constants.BYTES_PER_WORD); } protected final T _initPointerElement(FromPointerBuilder factory, int index, int elementCount) { return factory.initFromPointerBuilder( this.segment, + this.capTable, (this.ptr + (int)((long)index * this.step / Constants.BITS_PER_BYTE)) / Constants.BYTES_PER_WORD, elementCount); } protected final void _setPointerElement(SetPointerBuilder factory, int index, Reader value) { factory.setPointerBuilder(this.segment, + this.capTable, (this.ptr + (int)((long)index * this.step / Constants.BITS_PER_BYTE)) / Constants.BYTES_PER_WORD, value); } diff --git a/runtime/src/main/java/org/capnproto/ListFactory.java b/runtime/src/main/java/org/capnproto/ListFactory.java index e3d6fc0..61752c2 100644 --- a/runtime/src/main/java/org/capnproto/ListFactory.java +++ b/runtime/src/main/java/org/capnproto/ListFactory.java @@ -32,12 +32,13 @@ public abstract class ListFactory { T constructReader(SegmentReader segment, int ptr, int elementCount, int step, int structDataSize, short structPointerCount, int nestingLimit); + default T constructReader(SegmentBuilder segment, CapTableReader capTable, int ptr, + int elementCount, int step, + int structDataSize, short structPointerCount, int nestingLimit) { + var result = constructReader(segment, ptr, elementCount, step, structDataSize, structPointerCount, nestingLimit); + if (result instanceof Capability.ReaderContext) { + ((Capability.ReaderContext) result).capTable = capTable; + } + return result; + } } final SegmentReader segment; @@ -37,7 +46,6 @@ public class ListReader { final int structDataSize; // in bits final short structPointerCount; final int nestingLimit; - CapTableReader capTable; public ListReader() { this.segment = null; @@ -60,7 +68,6 @@ public class ListReader { this.structDataSize = structDataSize; this.structPointerCount = structPointerCount; this.nestingLimit = nestingLimit; - } ListReader imbue(CapTableReader capTable) { diff --git a/runtime/src/main/java/org/capnproto/SetPointerBuilder.java b/runtime/src/main/java/org/capnproto/SetPointerBuilder.java index 636c3a2..c1566e1 100644 --- a/runtime/src/main/java/org/capnproto/SetPointerBuilder.java +++ b/runtime/src/main/java/org/capnproto/SetPointerBuilder.java @@ -22,5 +22,5 @@ package org.capnproto; public interface SetPointerBuilder { - void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value); + void setPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, Reader value); } diff --git a/runtime/src/main/java/org/capnproto/StructBuilder.java b/runtime/src/main/java/org/capnproto/StructBuilder.java index c62bcef..0bded78 100644 --- a/runtime/src/main/java/org/capnproto/StructBuilder.java +++ b/runtime/src/main/java/org/capnproto/StructBuilder.java @@ -21,10 +21,18 @@ package org.capnproto; -public class StructBuilder { +public class StructBuilder extends Capability.BuilderContext { public interface Factory { T constructBuilder(SegmentBuilder segment, int data, int pointers, int dataSize, short pointerCount); + default T constructBuilder(SegmentBuilder segment, CapTableBuilder capTable, int data, int pointers, int dataSize, + short pointerCount) { + var result = constructBuilder(segment, data, pointers, dataSize, pointerCount); + if (result instanceof Capability.BuilderContext) { + ((Capability.BuilderContext) result).capTable = capTable; + } + return result; + } StructSize structSize(); } @@ -33,7 +41,6 @@ public class StructBuilder { protected final int pointers; // word offset of pointer section protected final int dataSize; // in bits protected final short pointerCount; - protected CapTableBuilder capTable; public StructBuilder(SegmentBuilder segment, int data, int pointers, int dataSize, short pointerCount) { @@ -44,12 +51,6 @@ public class StructBuilder { this.pointerCount = pointerCount; } - StructBuilder imbue(CapTableBuilder capTable) { - var result = new StructBuilder(this.segment, this.data, this.pointers, this.dataSize, this.pointerCount); - result.capTable = capTable; - return result; - } - protected final boolean _getBooleanField(int offset) { int bitOffset = offset; int position = this.data + (bitOffset / 8); @@ -179,30 +180,30 @@ public class StructBuilder { protected final void _clearPointerField(int ptrIndex) { int pointer = this.pointers + ptrIndex; - WireHelpers.zeroObject(this.segment, pointer); + WireHelpers.zeroObject(this.segment, this.capTable, pointer); this.segment.buffer.putLong(pointer * 8, 0L); } protected final T _getPointerField(FromPointerBuilder factory, int index) { - return factory.fromPointerBuilder(this.segment, this.pointers + index); + return factory.fromPointerBuilder(this.segment, this.capTable, this.pointers + index); } protected final T _getPointerField(FromPointerBuilderRefDefault factory, int index, SegmentReader defaultSegment, int defaultOffset) { - return factory.fromPointerBuilderRefDefault(this.segment, this.pointers + index, defaultSegment, defaultOffset); + return factory.fromPointerBuilderRefDefault(this.segment, this.capTable, this.pointers + index, defaultSegment, defaultOffset); } protected final T _getPointerField(FromPointerBuilderBlobDefault factory, int index, java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { - return factory.fromPointerBuilderBlobDefault(this.segment, this.pointers + index, defaultBuffer, defaultOffset, defaultSize); + return factory.fromPointerBuilderBlobDefault(this.segment, this.capTable, this.pointers + index, defaultBuffer, defaultOffset, defaultSize); } protected final T _initPointerField(FromPointerBuilder factory, int index, int elementCount) { - return factory.initFromPointerBuilder(this.segment, this.pointers + index, elementCount); + return factory.initFromPointerBuilder(this.segment, this.capTable, this.pointers + index, elementCount); } protected final void _setPointerField(SetPointerBuilder factory, int index, Reader value) { - factory.setPointerBuilder(this.segment, this.pointers + index, value); + factory.setPointerBuilder(this.segment, this.capTable, this.pointers + index, value); } protected final void _copyContentFrom(StructReader other) { @@ -251,14 +252,16 @@ public class StructBuilder { // Zero out all pointers in the target. for (int ii = 0; ii < this.pointerCount; ++ii) { - WireHelpers.zeroObject(this.segment, this.pointers + ii); + WireHelpers.zeroObject(this.segment, this.capTable, this.pointers + ii); } this.segment.buffer.putLong(this.pointers * Constants.BYTES_PER_WORD, 0); for (int ii = 0; ii < sharedPointerCount; ++ii) { WireHelpers.copyPointer(this.segment, + this.capTable, this.pointers + ii, other.segment, + other.capTable, other.pointers + ii, other.nestingLimit); } diff --git a/runtime/src/main/java/org/capnproto/StructFactory.java b/runtime/src/main/java/org/capnproto/StructFactory.java index f10c488..615cae7 100644 --- a/runtime/src/main/java/org/capnproto/StructFactory.java +++ b/runtime/src/main/java/org/capnproto/StructFactory.java @@ -28,44 +28,35 @@ public abstract class StructFactory, FromPointerReaderRefDefault, StructReader.Factory { - public final Reader fromPointerReaderRefDefault(SegmentReader segment, int pointer, + public final Reader fromPointerReaderRefDefault(SegmentReader segment, CapTableReader capTable, int pointer, SegmentReader defaultSegment, int defaultOffset, int nestingLimit) { return WireHelpers.readStructPointer(this, segment, + capTable, pointer, defaultSegment, defaultOffset, nestingLimit); } - public final Reader fromPointerReader(SegmentReader segment, int pointer, int nestingLimit) { - return fromPointerReaderRefDefault(segment, pointer, null, 0, nestingLimit); - } public final Reader fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { - var result = fromPointerReaderRefDefault(segment, pointer, null, 0, nestingLimit); - result.capTable = capTable; - return result; + return fromPointerReaderRefDefault(segment, capTable, pointer, null, 0, nestingLimit); } - public final Builder fromPointerBuilderRefDefault(SegmentBuilder segment, int pointer, + public final Builder fromPointerBuilderRefDefault(SegmentBuilder segment, CapTableBuilder capTable, int pointer, SegmentReader defaultSegment, int defaultOffset) { - return WireHelpers.getWritableStructPointer(this, pointer, segment, this.structSize(), + return WireHelpers.getWritableStructPointer(this, pointer, segment, capTable, this.structSize(), defaultSegment, defaultOffset); } - public final Builder fromPointerBuilder(SegmentBuilder segment, int pointer) { - return WireHelpers.getWritableStructPointer(this, pointer, segment, this.structSize(), - null, 0); - } public final Builder fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { - var result = fromPointerBuilder(segment, pointer); - result.capTable = capTable; - return result; + return WireHelpers.getWritableStructPointer(this, pointer, segment, capTable, this.structSize(), + null, 0); } - public final Builder initFromPointerBuilder(SegmentBuilder segment, int pointer, int elementCount) { - return WireHelpers.initStructPointer(this, pointer, segment, this.structSize()); + public final Builder initFromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, int elementCount) { + return WireHelpers.initStructPointer(this, pointer, segment, capTable, this.structSize()); } - public final void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value) { - WireHelpers.setStructPointer(segment, pointer, value); + public final void setPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, Reader value) { + WireHelpers.setStructPointer(segment, capTable, pointer, value); } public abstract Reader asReader(Builder builder); diff --git a/runtime/src/main/java/org/capnproto/StructList.java b/runtime/src/main/java/org/capnproto/StructList.java index b97ad92..df80387 100644 --- a/runtime/src/main/java/org/capnproto/StructList.java +++ b/runtime/src/main/java/org/capnproto/StructList.java @@ -56,9 +56,10 @@ public final class StructList { } @Override - public final Builder fromPointerBuilderRefDefault(SegmentBuilder segment, int pointer, + public final Builder fromPointerBuilderRefDefault(SegmentBuilder segment, CapTableBuilder capTable, int pointer, SegmentReader defaultSegment, int defaultOffset) { return WireHelpers.getWritableStructListPointer(this, + capTable, pointer, segment, factory.structSize(), @@ -67,8 +68,9 @@ public final class StructList { } @Override - public final Builder fromPointerBuilder(SegmentBuilder segment, int pointer) { + public final Builder fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { return WireHelpers.getWritableStructListPointer(this, + capTable, pointer, segment, factory.structSize(), @@ -76,9 +78,9 @@ public final class StructList { } @Override - public final Builder initFromPointerBuilder(SegmentBuilder segment, int pointer, + public final Builder initFromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, int elementCount) { - return WireHelpers.initStructListPointer(this, pointer, segment, elementCount, factory.structSize()); + return WireHelpers.initStructListPointer(this, capTable, pointer, segment, elementCount, factory.structSize()); } } diff --git a/runtime/src/main/java/org/capnproto/StructReader.java b/runtime/src/main/java/org/capnproto/StructReader.java index aa676d5..9f1b557 100644 --- a/runtime/src/main/java/org/capnproto/StructReader.java +++ b/runtime/src/main/java/org/capnproto/StructReader.java @@ -21,11 +21,20 @@ package org.capnproto; -public class StructReader { +public class StructReader extends Capability.ReaderContext { public interface Factory { - abstract T constructReader(SegmentReader segment, int data, int pointers, + T constructReader(SegmentReader segment, int data, int pointers, int dataSize, short pointerCount, int nestingLimit); + default T constructReader(SegmentReader segment, CapTableReader capTable, int data, int pointers, + int dataSize, short pointerCount, + int nestingLimit) { + var result = constructReader(segment, data, pointers, dataSize, pointerCount, nestingLimit); + if (result instanceof Capability.ReaderContext) { + ((Capability.ReaderContext) result).capTable = capTable; + } + return result; + } } protected final SegmentReader segment; @@ -34,7 +43,6 @@ public class StructReader { protected final int dataSize; // in bits protected final short pointerCount; protected final int nestingLimit; - protected CapTableReader capTable; public StructReader() { this.segment = SegmentReader.EMPTY; @@ -169,6 +177,7 @@ public class StructReader { this.nestingLimit); } else { return factory.fromPointerReader(SegmentReader.EMPTY, + this.capTable, 0, this.nestingLimit); } @@ -179,12 +188,14 @@ public class StructReader { SegmentReader defaultSegment, int defaultOffset) { if (ptrIndex < this.pointerCount) { return factory.fromPointerReaderRefDefault(this.segment, + this.capTable, this.pointers + ptrIndex, defaultSegment, defaultOffset, this.nestingLimit); } else { return factory.fromPointerReaderRefDefault(SegmentReader.EMPTY, + this.capTable, 0, defaultSegment, defaultOffset, diff --git a/runtime/src/main/java/org/capnproto/Text.java b/runtime/src/main/java/org/capnproto/Text.java index cc129cc..50d15f4 100644 --- a/runtime/src/main/java/org/capnproto/Text.java +++ b/runtime/src/main/java/org/capnproto/Text.java @@ -37,45 +37,37 @@ public final class Text { } @Override - public final Reader fromPointerReader(SegmentReader segment, int pointer, int nestingLimit) { + public final Reader fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { return WireHelpers.readTextPointer(segment, pointer, null, 0, 0); } @Override - public final Reader fromPointerReader(SegmentReader segment, CapTableReader capTable, int pointer, int nestingLimit) { - return fromPointerReader(segment, pointer, nestingLimit); - } - - @Override - public final Builder fromPointerBuilderBlobDefault(SegmentBuilder segment, int pointer, - java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { + public final Builder fromPointerBuilderBlobDefault(SegmentBuilder segment, CapTableBuilder capTable, int pointer, + java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { return WireHelpers.getWritableTextPointer(pointer, segment, + capTable, defaultBuffer, defaultOffset, defaultSize); } @Override - public final Builder fromPointerBuilder(SegmentBuilder segment, int pointer) { + public final Builder fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { return WireHelpers.getWritableTextPointer(pointer, segment, + capTable, null, 0, 0); } @Override - public Builder fromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer) { - return fromPointerBuilder(segment, pointer); + public Builder initFromPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, int size) { + return WireHelpers.initTextPointer(pointer, segment, capTable, size); } @Override - public final Builder initFromPointerBuilder(SegmentBuilder segment, int pointer, int size) { - return WireHelpers.initTextPointer(pointer, segment, size); - } - - @Override - public final void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value) { - WireHelpers.setTextPointer(pointer, segment, value); + public void setPointerBuilder(SegmentBuilder segment, CapTableBuilder capTable, int pointer, Reader value) { + WireHelpers.setTextPointer(pointer, segment, capTable, value); } } public static final Factory factory = new Factory(); diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index 72a1e1e..f96ca2c 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -49,12 +49,13 @@ final class WireHelpers { static AllocateResult allocate(int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, int amount, // in words byte kind) { long ref = segment.get(refOffset); if (!WirePointer.isNull(ref)) { - zeroObject(segment, refOffset); + zeroObject(segment, capTable, refOffset); } if (amount == 0 && kind == WirePointer.STRUCT) { @@ -174,7 +175,7 @@ final class WireHelpers { } } - static void zeroObject(SegmentBuilder segment, int refOffset) { + static void zeroObject(SegmentBuilder segment, CapTableBuilder capTable, int refOffset) { //# Zero out the pointed-to object. Use when the pointer is //# about to be overwritten making the target object no longer //# reachable. @@ -187,7 +188,7 @@ final class WireHelpers { switch (WirePointer.kind(ref)) { case WirePointer.STRUCT: case WirePointer.LIST: - zeroObject(segment, ref, WirePointer.target(refOffset, ref)); + zeroObject(segment, capTable, ref, WirePointer.target(refOffset, ref)); break; case WirePointer.FAR: { segment = segment.getArena().getSegment(FarPointer.getSegmentId(ref)); @@ -197,13 +198,13 @@ final class WireHelpers { if (FarPointer.isDoubleFar(ref)) { SegmentBuilder otherSegment = segment.getArena().getSegment(FarPointer.getSegmentId(ref)); if (otherSegment.isWritable()) { - zeroObject(otherSegment, padOffset + 1, FarPointer.positionInSegment(pad)); + zeroObject(otherSegment, capTable, padOffset + 1, FarPointer.positionInSegment(pad)); } segment.buffer.putLong(padOffset * 8, 0L); segment.buffer.putLong((padOffset + 1) * 8, 0L); } else { - zeroObject(segment, padOffset); + zeroObject(segment, capTable, padOffset); segment.buffer.putLong(padOffset * 8, 0L); } } @@ -211,12 +212,20 @@ final class WireHelpers { break; } case WirePointer.OTHER: { - // TODO + assert WirePointer.isCapability(ref) : "Unknown pointer type"; + if (WirePointer.isCapability(ref)) { + var capIndex = WirePointer.upper32Bits(ref); + assert capTable != null: "Cannot zero out capability pointer with no capTable"; + if (capTable != null) { + capTable.dropCap(capIndex); + } + } + break; } } } - static void zeroObject(SegmentBuilder segment, long tag, int ptr) { + static void zeroObject(SegmentBuilder segment, CapTableBuilder capTable, long tag, int ptr) { //# We shouldn't zero out external data linked into the message. if (!segment.isWritable()) return; @@ -225,7 +234,7 @@ final class WireHelpers { int pointerSection = ptr + StructPointer.dataSize(tag); int count = StructPointer.ptrCount(tag); for (int ii = 0; ii < count; ++ii) { - zeroObject(segment, pointerSection + ii); + zeroObject(segment, capTable, pointerSection + ii); } memset(segment.buffer, ptr * Constants.BYTES_PER_WORD, (byte)0, StructPointer.wordSize(tag) * Constants.BYTES_PER_WORD); @@ -248,7 +257,7 @@ final class WireHelpers { case ElementSize.POINTER: { int count = ListPointer.elementCount(tag); for (int ii = 0; ii < count; ++ii) { - zeroObject(segment, ptr + ii); + zeroObject(segment, capTable, ptr + ii); } memset(segment.buffer, ptr * Constants.BYTES_PER_WORD, (byte)0, count * Constants.BYTES_PER_WORD); @@ -267,7 +276,7 @@ final class WireHelpers { for (int ii = 0; ii < count; ++ii) { pos += dataSize; for (int jj = 0; jj < pointerCount; ++jj) { - zeroObject(segment, pos); + zeroObject(segment, capTable, pos); pos += Constants.POINTER_SIZE_IN_WORDS; } } @@ -392,9 +401,17 @@ final class WireHelpers { int refOffset, SegmentBuilder segment, StructSize size) { - AllocateResult allocation = allocate(refOffset, segment, size.total(), WirePointer.STRUCT); + return initStructPointer(factory, refOffset, segment, null, size); + } + + static T initStructPointer(StructBuilder.Factory factory, + int refOffset, + SegmentBuilder segment, + CapTableBuilder capTable, + StructSize size) { + AllocateResult allocation = allocate(refOffset, segment, capTable, size.total(), WirePointer.STRUCT); StructPointer.setFromStructSize(allocation.segment.buffer, allocation.refOffset, size); - return factory.constructBuilder(allocation.segment, allocation.ptr * Constants.BYTES_PER_WORD, + return factory.constructBuilder(allocation.segment, capTable, allocation.ptr * Constants.BYTES_PER_WORD, allocation.ptr + size.data, size.data * 64, size.pointers); } @@ -402,6 +419,7 @@ final class WireHelpers { static T getWritableStructPointer(StructBuilder.Factory factory, int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, StructSize size, SegmentReader defaultSegment, int defaultOffset) { @@ -409,7 +427,7 @@ final class WireHelpers { int target = WirePointer.target(refOffset, ref); if (WirePointer.isNull(ref)) { if (defaultSegment == null) { - return initStructPointer(factory, refOffset, segment, size); + return initStructPointer(factory, refOffset, segment, capTable, size); } else { throw new RuntimeException("unimplemented"); } @@ -432,7 +450,7 @@ final class WireHelpers { //# Don't let allocate() zero out the object just yet. zeroPointerAndFars(segment, refOffset); - AllocateResult allocation = allocate(refOffset, segment, + AllocateResult allocation = allocate(refOffset, segment, capTable, totalSize, WirePointer.STRUCT); StructPointer.set(allocation.segment.buffer, allocation.refOffset, @@ -458,11 +476,11 @@ final class WireHelpers { memset(resolved.segment.buffer, resolved.ptr * Constants.BYTES_PER_WORD, (byte)0, (oldDataSize + oldPointerCount * Constants.WORDS_PER_POINTER) * Constants.BYTES_PER_WORD); - return factory.constructBuilder(allocation.segment, allocation.ptr * Constants.BYTES_PER_WORD, + return factory.constructBuilder(allocation.segment, capTable, allocation.ptr * Constants.BYTES_PER_WORD, newPointerSection, newDataSize * Constants.BITS_PER_WORD, newPointerCount); } else { - return factory.constructBuilder(resolved.segment, resolved.ptr * Constants.BYTES_PER_WORD, + return factory.constructBuilder(resolved.segment, capTable, resolved.ptr * Constants.BYTES_PER_WORD, oldPointerSection, oldDataSize * Constants.BITS_PER_WORD, oldPointerCount); } @@ -470,6 +488,7 @@ final class WireHelpers { } static T initListPointer(ListBuilder.Factory factory, + CapTableBuilder capTable, int refOffset, SegmentBuilder segment, int elementCount, @@ -480,7 +499,7 @@ final class WireHelpers { int pointerCount = ElementSize.pointersPerElement(elementSize); int step = dataSize + pointerCount * Constants.BITS_PER_POINTER; int wordCount = roundBitsUpToWords((long)elementCount * (long)step); - AllocateResult allocation = allocate(refOffset, segment, wordCount, WirePointer.LIST); + AllocateResult allocation = allocate(refOffset, segment, capTable, wordCount, WirePointer.LIST); ListPointer.set(allocation.segment.buffer, allocation.refOffset, elementSize, elementCount); @@ -490,6 +509,7 @@ final class WireHelpers { } static T initStructListPointer(ListBuilder.Factory factory, + CapTableBuilder capTable, int refOffset, SegmentBuilder segment, int elementCount, @@ -498,7 +518,7 @@ final class WireHelpers { //# Allocate the list, prefixed by a single WirePointer. int wordCount = elementCount * wordsPerElement; - AllocateResult allocation = allocate(refOffset, segment, Constants.POINTER_SIZE_IN_WORDS + wordCount, + AllocateResult allocation = allocate(refOffset, segment, capTable, Constants.POINTER_SIZE_IN_WORDS + wordCount, WirePointer.LIST); //# Initialize the pointer. @@ -516,6 +536,7 @@ final class WireHelpers { static T getWritableListPointer(ListBuilder.Factory factory, int origRefOffset, SegmentBuilder origSegment, + CapTableBuilder capTable, byte elementSize, SegmentReader defaultSegment, int defaultOffset) { @@ -572,6 +593,7 @@ final class WireHelpers { } static T getWritableStructListPointer(ListBuilder.Factory factory, + CapTableBuilder capTable, int origRefOffset, SegmentBuilder origSegment, StructSize elementSize, @@ -624,7 +646,7 @@ final class WireHelpers { //# Don't let allocate() zero out the object just yet. zeroPointerAndFars(origSegment, origRefOffset); - AllocateResult allocation = allocate(origRefOffset, origSegment, + AllocateResult allocation = allocate(origRefOffset, origSegment, capTable, totalSize + Constants.POINTER_SIZE_IN_WORDS, WirePointer.LIST); @@ -678,7 +700,7 @@ final class WireHelpers { if (oldSize == ElementSize.VOID) { //# Nothing to copy, just allocate a new list. - return initStructListPointer(factory, origRefOffset, origSegment, + return initStructListPointer(factory, capTable, origRefOffset, origSegment, elementCount, elementSize); } else { //# Upgrading to an inline composite list. @@ -704,7 +726,7 @@ final class WireHelpers { //# Don't let allocate() zero out the object just yet. zeroPointerAndFars(origSegment, origRefOffset); - AllocateResult allocation = allocate(origRefOffset, origSegment, + AllocateResult allocation = allocate(origRefOffset, origSegment, capTable, totalWords + Constants.POINTER_SIZE_IN_WORDS, WirePointer.LIST); @@ -754,12 +776,13 @@ final class WireHelpers { // size is in bytes static Text.Builder initTextPointer(int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, int size) { //# The byte list must include a NUL terminator. int byteSize = size + 1; //# Allocate the space. - AllocateResult allocation = allocate(refOffset, segment, roundBytesUpToWords(byteSize), + AllocateResult allocation = allocate(refOffset, segment, capTable, roundBytesUpToWords(byteSize), WirePointer.LIST); //# Initialize the pointer. @@ -770,8 +793,9 @@ final class WireHelpers { static Text.Builder setTextPointer(int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, Text.Reader value) { - Text.Builder builder = initTextPointer(refOffset, segment, value.size); + Text.Builder builder = initTextPointer(refOffset, segment, capTable, value.size); ByteBuffer slice = value.buffer.duplicate(); slice.position(value.offset); @@ -783,6 +807,7 @@ final class WireHelpers { static Text.Builder getWritableTextPointer(int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { @@ -792,7 +817,7 @@ final class WireHelpers { if (defaultBuffer == null) { return new Text.Builder(); } else { - Text.Builder builder = initTextPointer(refOffset, segment, defaultSize); + Text.Builder builder = initTextPointer(refOffset, segment, capTable, defaultSize); // TODO is there a way to do this with bulk methods? for (int i = 0; i < builder.size; ++i) { builder.buffer.put(builder.offset + i, defaultBuffer.get(defaultOffset * 8 + i)); @@ -826,9 +851,10 @@ final class WireHelpers { // size is in bytes static Data.Builder initDataPointer(int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, int size) { //# Allocate the space. - AllocateResult allocation = allocate(refOffset, segment, roundBytesUpToWords(size), + AllocateResult allocation = allocate(refOffset, segment, capTable, roundBytesUpToWords(size), WirePointer.LIST); //# Initialize the pointer. @@ -839,8 +865,9 @@ final class WireHelpers { static Data.Builder setDataPointer(int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, Data.Reader value) { - Data.Builder builder = initDataPointer(refOffset, segment, value.size); + Data.Builder builder = initDataPointer(refOffset, segment, capTable, value.size); // TODO is there a way to do this with bulk methods? for (int i = 0; i < builder.size; ++i) { @@ -851,6 +878,7 @@ final class WireHelpers { static Data.Builder getWritableDataPointer(int refOffset, SegmentBuilder segment, + CapTableBuilder capTable, ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { @@ -860,7 +888,7 @@ final class WireHelpers { if (defaultBuffer == null) { return new Data.Builder(); } else { - Data.Builder builder = initDataPointer(refOffset, segment, defaultSize); + Data.Builder builder = initDataPointer(refOffset, segment, capTable, defaultSize); // TODO is there a way to do this with bulk methods? for (int i = 0; i < builder.size; ++i) { builder.buffer.put(builder.offset + i, defaultBuffer.get(defaultOffset * 8 + i)); @@ -887,6 +915,7 @@ final class WireHelpers { static T readStructPointer(StructReader.Factory factory, SegmentReader segment, + CapTableReader capTable, int refOffset, SegmentReader defaultSegment, int defaultOffset, @@ -918,6 +947,7 @@ final class WireHelpers { resolved.segment.arena.checkReadLimit(StructPointer.wordSize(resolved.ref)); return factory.constructReader(resolved.segment, + capTable, resolved.ptr * Constants.BYTES_PER_WORD, (resolved.ptr + dataSizeWords), dataSizeWords * Constants.BITS_PER_WORD, @@ -926,11 +956,11 @@ final class WireHelpers { } - static SegmentBuilder setStructPointer(SegmentBuilder segment, int refOffset, StructReader value) { + static SegmentBuilder setStructPointer(SegmentBuilder segment, CapTableBuilder capTable, int refOffset, StructReader value) { short dataSize = (short)roundBitsUpToWords(value.dataSize); int totalSize = dataSize + value.pointerCount * Constants.POINTER_SIZE_IN_WORDS; - AllocateResult allocation = allocate(refOffset, segment, totalSize, WirePointer.STRUCT); + AllocateResult allocation = allocate(refOffset, segment, capTable, totalSize, WirePointer.STRUCT); StructPointer.set(allocation.segment.buffer, allocation.refOffset, dataSize, value.pointerCount); @@ -943,25 +973,25 @@ final class WireHelpers { int pointerSection = allocation.ptr + dataSize; for (int i = 0; i < value.pointerCount; ++i) { - copyPointer(allocation.segment, pointerSection + i, value.segment, value.pointers + i, + copyPointer(allocation.segment, capTable, pointerSection + i, value.segment, value.capTable, value.pointers + i, value.nestingLimit); } return allocation.segment; }; - static SegmentBuilder setListPointer(SegmentBuilder segment, int refOffset, ListReader value) { + static SegmentBuilder setListPointer(SegmentBuilder segment, CapTableBuilder capTable, int refOffset, ListReader value) { int totalSize = roundBitsUpToWords(value.elementCount * value.step); if (value.step <= Constants.BITS_PER_WORD) { //# List of non-structs. - AllocateResult allocation = allocate(refOffset, segment, totalSize, WirePointer.LIST); + AllocateResult allocation = allocate(refOffset, segment, capTable, totalSize, WirePointer.LIST); if (value.structPointerCount == 1) { //# List of pointers. ListPointer.set(allocation.segment.buffer, allocation.refOffset, ElementSize.POINTER, value.elementCount); for (int i = 0; i < value.elementCount; ++i) { - copyPointer(allocation.segment, allocation.ptr + i, - value.segment, value.ptr / Constants.BYTES_PER_WORD + i, value.nestingLimit); + copyPointer(allocation.segment, capTable,allocation.ptr + i, + value.segment, value.capTable, value.ptr / Constants.BYTES_PER_WORD + i, value.nestingLimit); } } else { //# List of data. @@ -984,7 +1014,7 @@ final class WireHelpers { return allocation.segment; } else { //# List of structs. - AllocateResult allocation = allocate(refOffset, segment, totalSize + Constants.POINTER_SIZE_IN_WORDS, WirePointer.LIST); + AllocateResult allocation = allocate(refOffset, segment, capTable, totalSize + Constants.POINTER_SIZE_IN_WORDS, WirePointer.LIST); ListPointer.setInlineComposite(allocation.segment.buffer, allocation.refOffset, totalSize); short dataSize = (short)roundBitsUpToWords(value.structDataSize); short pointerCount = value.structPointerCount; @@ -1005,7 +1035,7 @@ final class WireHelpers { srcOffset += dataSize; for (int j = 0; j < pointerCount; ++j) { - copyPointer(allocation.segment, dstOffset, value.segment, srcOffset, value.nestingLimit); + copyPointer(allocation.segment, capTable, dstOffset, value.segment, value.capTable, srcOffset, value.nestingLimit); dstOffset += Constants.POINTER_SIZE_IN_WORDS; srcOffset += Constants.POINTER_SIZE_IN_WORDS; } @@ -1031,8 +1061,8 @@ final class WireHelpers { dstDup.put(srcDup); } - static SegmentBuilder copyPointer(SegmentBuilder dstSegment, int dstOffset, - SegmentReader srcSegment, int srcOffset, int nestingLimit) { + static SegmentBuilder copyPointer(SegmentBuilder dstSegment, CapTableBuilder dstCapTable, int dstOffset, + SegmentReader srcSegment, CapTableReader srcCapTable, int srcOffset, int nestingLimit) { // Deep-copy the object pointed to by src into dst. It turns out we can't reuse // readStructPointer(), etc. because they do type checking whereas here we want to accept any // valid pointer. @@ -1053,7 +1083,7 @@ final class WireHelpers { throw new DecodeException("Message is too deeply nested or contains cycles. See org.capnproto.ReaderOptions."); } resolved.segment.arena.checkReadLimit(StructPointer.wordSize(resolved.ref)); - return setStructPointer(dstSegment, dstOffset, + return setStructPointer(dstSegment, dstCapTable, dstOffset, new StructReader(resolved.segment, resolved.ptr * Constants.BYTES_PER_WORD, resolved.ptr + StructPointer.dataSize(resolved.ref), @@ -1088,7 +1118,7 @@ final class WireHelpers { resolved.segment.arena.checkReadLimit(elementCount); } - return setListPointer(dstSegment, dstOffset, + return setListPointer(dstSegment, dstCapTable, dstOffset, new ListReader(resolved.segment, ptr * Constants.BYTES_PER_WORD, elementCount, @@ -1111,7 +1141,7 @@ final class WireHelpers { resolved.segment.arena.checkReadLimit(elementCount); } - return setListPointer(dstSegment, dstOffset, + return setListPointer(dstSegment, dstCapTable, dstOffset, new ListReader(resolved.segment, resolved.ptr * Constants.BYTES_PER_WORD, elementCount, @@ -1132,6 +1162,7 @@ final class WireHelpers { static T readListPointer(ListReader.Factory factory, SegmentReader segment, int refOffset, + CapTableReader capTable, SegmentReader defaultSegment, int defaultOffset, byte expectedElementSize, @@ -1316,16 +1347,19 @@ final class WireHelpers { long ref = segment.get(refOffset); if (!WirePointer.isNull(ref)) { - zeroObject(segment, refOffset); + zeroObject(segment, capTable, refOffset); } if (cap == null) { // TODO check zeroMemory behaviour zeroPointerAndFars(segment, refOffset); } - else { + else if (capTable != null) { WirePointer.setCap(segment.buffer, refOffset, capTable.injectCap(cap)); } + else { + assert false: "Cannot set capability pointer without capTable"; + } } static ClientHook readCapabilityPointer(SegmentReader segment, CapTableReader capTable, int refOffset, int maxValue) { @@ -1339,6 +1373,10 @@ final class WireHelpers { return Capability.newBrokenCap("Calling capability extracted from a non-capability pointer."); } + if (capTable == null) { + return Capability.newBrokenCap("Cannot read capability pointer without capTable."); + } + var cap = capTable.extractCap(WirePointer.upper32Bits(ref)); if (cap == null) { return Capability.newBrokenCap("Calling invalid capability pointer."); diff --git a/runtime/src/test/java/org/capnproto/LayoutTest.java b/runtime/src/test/java/org/capnproto/LayoutTest.java index 4ed6042..d023abb 100644 --- a/runtime/src/test/java/org/capnproto/LayoutTest.java +++ b/runtime/src/test/java/org/capnproto/LayoutTest.java @@ -25,7 +25,7 @@ public class LayoutTest { ReaderArena arena = new ReaderArena(new ByteBuffer[]{ buffer }, 0x7fffffffffffffffL); - StructReader reader = WireHelpers.readStructPointer(new BareStructReader(), arena.tryGetSegment(0), 0, null, 0, 0x7fffffff); + StructReader reader = WireHelpers.readStructPointer(new BareStructReader(), arena.tryGetSegment(0), null,0, null, 0, 0x7fffffff); Assert.assertEquals(reader._getLongField(0), 0xefcdab8967452301L); Assert.assertEquals(reader._getLongField(1), 0L); diff --git a/runtime/src/test/java/org/capnproto/TwoPartyTest.java b/runtime/src/test/java/org/capnproto/TwoPartyTest.java index 2b00a39..6178dd9 100644 --- a/runtime/src/test/java/org/capnproto/TwoPartyTest.java +++ b/runtime/src/test/java/org/capnproto/TwoPartyTest.java @@ -22,7 +22,7 @@ class TestCap0 { public Client(ClientHook hook) { super(hook); } - public Client(Capability.Client cap) { super(cap.getHook()); } + public Client(Capability.Client cap) { super(cap.hook); } public Client(Capability.Server server) { super(server); } @@ -85,7 +85,7 @@ class TestCap1 { public Client(ClientHook hook) { super(hook); } - public Client(Capability.Client cap) { super(cap.getHook()); } + public Client(Capability.Client cap) { super(cap.hook); } public Client(Capability.Server server) { super(server); } } @@ -111,7 +111,8 @@ class TestCap1 { class TestCap0Impl extends TestCap0.Server { - final TestCap1.Client testCap1 = new TestCap1.Client(new TestCap1Impl()); + final TestCap1.Client testCap1a = new TestCap1.Client(new TestCap1Impl()); + final TestCap1.Client testCap1b = new TestCap1.Client(new TestCap1Impl()); public CompletableFuture testMethod0(TestCap0.Server.TestMethod0Context ctx) { var params = ctx.getParams(); @@ -124,7 +125,11 @@ class TestCap0Impl extends TestCap0.Server { var params = ctx.getParams(); var results = ctx.getResults(); var res0 = results.getResult0(); - res0.setAsCapability(testCap1); + res0.setAsCapability(testCap1a); + var res1 = results.getResult1(); + res1.setAsCapability(testCap1b); + var res2 = results.getResult2(); + res2.setAsCapability(testCap1b); return CompletableFuture.completedFuture(null); } } @@ -195,12 +200,19 @@ public class TwoPartyTest { var params = request.params(); var resultsPromise = request.send(); while (!resultsPromise.isDone()) { - CompletableFuture.anyOf(resultsPromise, server.runOnce()).join(); + CompletableFuture.anyOf(resultsPromise, server.runOnce(), client.runOnce()).join(); } Assert.assertTrue(resultsPromise.isDone()); var results = resultsPromise.get(); - var any = results.getResult0(); - var cap1 = any.getAsCapability(); + var cap0 = results.getResult0().getAsCapability(); + Assert.assertFalse(cap0.hook.isNull()); + Assert.assertFalse(cap0.hook.isError()); + var cap1 = results.getResult1().getAsCapability(); + Assert.assertFalse(cap1.hook.isNull()); + Assert.assertFalse(cap1.hook.isError()); + var cap2 = results.getResult2().getAsCapability(); + Assert.assertFalse(cap2.hook.isNull()); + Assert.assertFalse(cap2.hook.isError()); } @Test diff --git a/runtime/src/test/java/org/capnproto/demo/Demo.java b/runtime/src/test/java/org/capnproto/demo/Demo.java index 2b531dd..2ae5ba2 100644 --- a/runtime/src/test/java/org/capnproto/demo/Demo.java +++ b/runtime/src/test/java/org/capnproto/demo/Demo.java @@ -166,7 +166,7 @@ public final class Demo { public static class TestResults1 { - public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)0,(short)1); + public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)0,(short)3); public static final class Factory extends org.capnproto.StructFactory { public Factory() { } @@ -206,6 +206,32 @@ public final class Demo { return _initPointerField(org.capnproto.AnyPointer.factory, 0, size); } + public final boolean hasResult1() { + return !_pointerFieldIsNull(1); + } + public org.capnproto.AnyPointer.Builder getResult1() { + return _getPointerField(org.capnproto.AnyPointer.factory, 1); + } + public org.capnproto.AnyPointer.Builder initResult1() { + return _initPointerField(org.capnproto.AnyPointer.factory, 1, 0); + } + public org.capnproto.AnyPointer.Builder initResult1(int size) { + return _initPointerField(org.capnproto.AnyPointer.factory, 1, size); + } + + public final boolean hasResult2() { + return !_pointerFieldIsNull(2); + } + public org.capnproto.AnyPointer.Builder getResult2() { + return _getPointerField(org.capnproto.AnyPointer.factory, 2); + } + public org.capnproto.AnyPointer.Builder initResult2() { + return _initPointerField(org.capnproto.AnyPointer.factory, 2, 0); + } + public org.capnproto.AnyPointer.Builder initResult2(int size) { + return _initPointerField(org.capnproto.AnyPointer.factory, 2, size); + } + } public static final class Reader extends org.capnproto.StructReader { @@ -219,6 +245,18 @@ public final class Demo { public org.capnproto.AnyPointer.Reader getResult0() { return _getPointerField(org.capnproto.AnyPointer.factory, 0); } + public boolean hasResult1() { + return !_pointerFieldIsNull(1); + } + public org.capnproto.AnyPointer.Reader getResult1() { + return _getPointerField(org.capnproto.AnyPointer.factory, 1); + } + public boolean hasResult2() { + return !_pointerFieldIsNull(2); + } + public org.capnproto.AnyPointer.Reader getResult2() { + return _getPointerField(org.capnproto.AnyPointer.factory, 2); + } } } @@ -230,20 +268,25 @@ public static final org.capnproto.SegmentReader b_b301b4acd180f012 = org.capnproto.GeneratedClassSupport.decodeRawBytes( "\u0000\u0000\u0000\u0000\u0005\u0000\u0006\u0000" + "\u0012\u00f0\u0080\u00d1\u00ac\u00b4\u0001\u00b3" + - "\u0011\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u003a\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + "\u00c4\u0053\u0042\u00d6\u0097\u0077\u00b5\u0091" + "\u0000\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0015\u0000\u0000\u0000\u00ea\u0000\u0000\u0000" + - "\u0021\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + + "\u0015\u0000\u0000\u0000\u0032\u0002\u0000\u0000" + + "\u0035\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u001d\u0000\u0000\u0000\u003f\u0000\u0000\u0000" + + "\u0031\u0000\u0000\u0000\u003f\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0064\u0065\u006d\u006f\u0070\u0061\u0072\u0061" + - "\u006d\u0073\u002e\u0063\u0061\u0070\u006e\u0070" + - "\u003a\u0054\u0065\u0073\u0074\u0050\u0061\u0072" + - "\u0061\u006d\u0073\u0030\u0000\u0000\u0000\u0000" + + "\u0072\u0075\u006e\u0074\u0069\u006d\u0065\u002f" + + "\u0073\u0072\u0063\u002f\u0074\u0065\u0073\u0074" + + "\u002f\u006a\u0061\u0076\u0061\u002f\u006f\u0072" + + "\u0067\u002f\u0063\u0061\u0070\u006e\u0070\u0072" + + "\u006f\u0074\u006f\u002f\u0064\u0065\u006d\u006f" + + "\u002f\u0064\u0065\u006d\u006f\u0070\u0061\u0072" + + "\u0061\u006d\u0073\u002e\u0063\u0061\u0070\u006e" + + "\u0070\u003a\u0054\u0065\u0073\u0074\u0050\u0061" + + "\u0072\u0061\u006d\u0073\u0030\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + "\u0004\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + @@ -265,20 +308,25 @@ public static final org.capnproto.SegmentReader b_96a42e5421b52881 = org.capnproto.GeneratedClassSupport.decodeRawBytes( "\u0000\u0000\u0000\u0000\u0005\u0000\u0006\u0000" + "\u0081\u0028\u00b5\u0021\u0054\u002e\u00a4\u0096" + - "\u0011\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u003a\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + "\u00c4\u0053\u0042\u00d6\u0097\u0077\u00b5\u0091" + "\u0000\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0015\u0000\u0000\u0000\u00f2\u0000\u0000\u0000" + - "\u0021\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + + "\u0015\u0000\u0000\u0000\u003a\u0002\u0000\u0000" + + "\u0035\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u001d\u0000\u0000\u0000\u003f\u0000\u0000\u0000" + + "\u0031\u0000\u0000\u0000\u003f\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0064\u0065\u006d\u006f\u0070\u0061\u0072\u0061" + - "\u006d\u0073\u002e\u0063\u0061\u0070\u006e\u0070" + - "\u003a\u0054\u0065\u0073\u0074\u0052\u0065\u0073" + - "\u0075\u006c\u0074\u0073\u0030\u0000\u0000\u0000" + + "\u0072\u0075\u006e\u0074\u0069\u006d\u0065\u002f" + + "\u0073\u0072\u0063\u002f\u0074\u0065\u0073\u0074" + + "\u002f\u006a\u0061\u0076\u0061\u002f\u006f\u0072" + + "\u0067\u002f\u0063\u0061\u0070\u006e\u0070\u0072" + + "\u006f\u0074\u006f\u002f\u0064\u0065\u006d\u006f" + + "\u002f\u0064\u0065\u006d\u006f\u0070\u0061\u0072" + + "\u0061\u006d\u0073\u002e\u0063\u0061\u0070\u006e" + + "\u0070\u003a\u0054\u0065\u0073\u0074\u0052\u0065" + + "\u0073\u0075\u006c\u0074\u0073\u0030\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + "\u0004\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + @@ -300,20 +348,25 @@ public static final org.capnproto.SegmentReader b_e10363a8b6220957 = org.capnproto.GeneratedClassSupport.decodeRawBytes( "\u0000\u0000\u0000\u0000\u0005\u0000\u0006\u0000" + "\u0057\u0009\"\u00b6\u00a8\u0063\u0003\u00e1" + - "\u0011\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + + "\u003a\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + "\u00c4\u0053\u0042\u00d6\u0097\u0077\u00b5\u0091" + "\u0001\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0015\u0000\u0000\u0000\u00ea\u0000\u0000\u0000" + - "\u0021\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + + "\u0015\u0000\u0000\u0000\u0032\u0002\u0000\u0000" + + "\u0035\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u001d\u0000\u0000\u0000\u003f\u0000\u0000\u0000" + + "\u0031\u0000\u0000\u0000\u003f\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0064\u0065\u006d\u006f\u0070\u0061\u0072\u0061" + - "\u006d\u0073\u002e\u0063\u0061\u0070\u006e\u0070" + - "\u003a\u0054\u0065\u0073\u0074\u0050\u0061\u0072" + - "\u0061\u006d\u0073\u0031\u0000\u0000\u0000\u0000" + + "\u0072\u0075\u006e\u0074\u0069\u006d\u0065\u002f" + + "\u0073\u0072\u0063\u002f\u0074\u0065\u0073\u0074" + + "\u002f\u006a\u0061\u0076\u0061\u002f\u006f\u0072" + + "\u0067\u002f\u0063\u0061\u0070\u006e\u0070\u0072" + + "\u006f\u0074\u006f\u002f\u0064\u0065\u006d\u006f" + + "\u002f\u0064\u0065\u006d\u006f\u0070\u0061\u0072" + + "\u0061\u006d\u0073\u002e\u0063\u0061\u0070\u006e" + + "\u0070\u003a\u0054\u0065\u0073\u0074\u0050\u0061" + + "\u0072\u0061\u006d\u0073\u0031\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + "\u0004\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + @@ -335,29 +388,48 @@ public static final org.capnproto.SegmentReader b_99852ee4d45ddb3e = org.capnproto.GeneratedClassSupport.decodeRawBytes( "\u0000\u0000\u0000\u0000\u0005\u0000\u0006\u0000" + "\u003e\u00db\u005d\u00d4\u00e4\u002e\u0085\u0099" + - "\u0011\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + + "\u003a\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + "\u00c4\u0053\u0042\u00d6\u0097\u0077\u00b5\u0091" + - "\u0001\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + + "\u0003\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0015\u0000\u0000\u0000\u00f2\u0000\u0000\u0000" + - "\u0021\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + + "\u0015\u0000\u0000\u0000\u003a\u0002\u0000\u0000" + + "\u0035\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u001d\u0000\u0000\u0000\u003f\u0000\u0000\u0000" + + "\u0031\u0000\u0000\u0000\u00af\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0064\u0065\u006d\u006f\u0070\u0061\u0072\u0061" + - "\u006d\u0073\u002e\u0063\u0061\u0070\u006e\u0070" + - "\u003a\u0054\u0065\u0073\u0074\u0052\u0065\u0073" + - "\u0075\u006c\u0074\u0073\u0031\u0000\u0000\u0000" + + "\u0072\u0075\u006e\u0074\u0069\u006d\u0065\u002f" + + "\u0073\u0072\u0063\u002f\u0074\u0065\u0073\u0074" + + "\u002f\u006a\u0061\u0076\u0061\u002f\u006f\u0072" + + "\u0067\u002f\u0063\u0061\u0070\u006e\u0070\u0072" + + "\u006f\u0074\u006f\u002f\u0064\u0065\u006d\u006f" + + "\u002f\u0064\u0065\u006d\u006f\u0070\u0061\u0072" + + "\u0061\u006d\u0073\u002e\u0063\u0061\u0070\u006e" + + "\u0070\u003a\u0054\u0065\u0073\u0074\u0052\u0065" + + "\u0073\u0075\u006c\u0074\u0073\u0031\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + - "\u0004\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + + "\u000c\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\r\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + + "\u0045\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0008\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u0014\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0040\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u004c\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0001\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0049\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0044\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0050\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0002\u0000\u0000\u0000\u0002\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0002\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u004d\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0048\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0054\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0072\u0065\u0073\u0075\u006c\u0074\u0030\u0000" + "\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + @@ -365,6 +437,22 @@ public static final org.capnproto.SegmentReader b_99852ee4d45ddb3e = "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0072\u0065\u0073\u0075\u006c\u0074\u0031\u0000" + + "\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0072\u0065\u0073\u0075\u006c\u0074\u0032\u0000" + + "\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + ""); } } diff --git a/runtime/src/test/java/org/capnproto/demo/demoparams.capnp b/runtime/src/test/java/org/capnproto/demo/demoparams.capnp index 5c2cae4..560cad4 100644 --- a/runtime/src/test/java/org/capnproto/demo/demoparams.capnp +++ b/runtime/src/test/java/org/capnproto/demo/demoparams.capnp @@ -18,6 +18,8 @@ struct TestParams1 { struct TestResults1 { result0 @0 :AnyPointer; + result1 @1 :AnyPointer; + result2 @2 :AnyPointer; }