diff --git a/benchmark/src/main/java/org/capnproto/benchmark/TestCase.java b/benchmark/src/main/java/org/capnproto/benchmark/TestCase.java index e74f336..a3cb29c 100644 --- a/benchmark/src/main/java/org/capnproto/benchmark/TestCase.java +++ b/benchmark/src/main/java/org/capnproto/benchmark/TestCase.java @@ -11,10 +11,13 @@ import org.capnproto.StructFactory; import org.capnproto.MessageBuilder; import org.capnproto.MessageReader; -public abstract class TestCase, - RequestBuilder, RequestReader, +public abstract class TestCase, + RequestBuilder extends org.capnproto.StructBuilder, + RequestReader extends org.capnproto.StructReader, ResponseFactory extends StructFactory, - ResponseBuilder, ResponseReader, Expectation> { + ResponseBuilder extends org.capnproto.StructBuilder, + ResponseReader extends org.capnproto.StructReader, Expectation> { public abstract Expectation setupRequest(Common.FastRand rng, RequestBuilder request); public abstract void handleRequest(RequestReader request, ResponseBuilder response); public abstract boolean checkResponse(ResponseReader response, Expectation expected); diff --git a/compiler/src/main/cpp/capnpc-java.c++ b/compiler/src/main/cpp/capnpc-java.c++ index fd542ec..29afea3 100644 --- a/compiler/src/main/cpp/capnpc-java.c++ +++ b/compiler/src/main/cpp/capnpc-java.c++ @@ -763,7 +763,7 @@ private: ");\n"); case Section::POINTERS: return kj::strTree( - spaces(indent), " _getPointerField(", slot.offset, ").clear();\n"); + spaces(indent), " _clearPointerField(", slot.offset, ");\n"); } KJ_UNREACHABLE; }, @@ -947,20 +947,20 @@ private: kj::strTree( kj::mv(unionDiscrim.builderIsDecl), spaces(indent), " public final boolean has", titleCase, "() {\n", - spaces(indent), " return !_getPointerField(", offset, ").isNull();\n", + spaces(indent), " return !_pointerFieldIsNull(", offset, ");\n", spaces(indent), " }\n", spaces(indent), " public org.capnproto.AnyPointer.Builder get", titleCase, "() {\n", unionDiscrim.check, - spaces(indent), " return new org.capnproto.AnyPointer.Builder(_getPointerField(", - offset, "));\n", + spaces(indent), " return new org.capnproto.AnyPointer.Builder(this.segment, this.pointers + ", + offset, ");\n", spaces(indent), " }\n", spaces(indent), " public org.capnproto.AnyPointer.Builder init", titleCase, "() {\n", unionDiscrim.set, spaces(indent), " org.capnproto.AnyPointer.Builder result =\n", - spaces(indent), " new org.capnproto.AnyPointer.Builder(_getPointerField(", - offset, "));\n", + spaces(indent), " new org.capnproto.AnyPointer.Builder(this.segment, this.pointers +", + offset, ");\n", spaces(indent), " result.clear();\n", spaces(indent), " return result;\n", spaces(indent), " }\n", @@ -994,7 +994,7 @@ private: spaces(indent), " }\n", spaces(indent), " public final void set", titleCase, "(", type, ".Reader value) {\n", unionDiscrim.set, - spaces(indent), " _getPointerField(", offset, ").setStruct(value);\n", + spaces(indent), " _setPointerField(", type, ".factory,", offset, ", value);\n", spaces(indent), " }\n", spaces(indent), " public final ", type, ".Builder init", titleCase, "() {\n", unionDiscrim.set, @@ -1031,7 +1031,7 @@ private: kj::mv(unionDiscrim.builderIsDecl), spaces(indent), " public final boolean has", titleCase, "() {\n", unionDiscrim.has, - spaces(indent), " return !_getPointerField(", offset, ").isNull();\n", + spaces(indent), " return !_pointerFieldIsNull(", offset, ");\n", spaces(indent), " }\n", spaces(indent), " public final ", type, ".Builder get", titleCase, "() {\n", spaces(indent), " return _getPointerField(", factory, ", ", @@ -1039,11 +1039,11 @@ private: spaces(indent), " }\n", spaces(indent), " public final void set", titleCase, "(", type, ".Reader value) {\n", unionDiscrim.set, - spaces(indent), " _getPointerField(", offset, ").set", blobKind, "(value);\n", + spaces(indent), " _setPointerField(", factory, ", ", offset, ", value);\n", spaces(indent), " }\n", spaces(indent), " public final void set", titleCase, "(", setterInputType, " value) {\n", unionDiscrim.set, - spaces(indent), " _getPointerField(", offset, ").set", blobKind, "( new", + spaces(indent), " _setPointerField(", factory, ", ", offset, ", new", type, ".Reader(value));\n", spaces(indent), " }\n", @@ -1077,7 +1077,7 @@ private: kj::strTree( kj::mv(unionDiscrim.builderIsDecl), spaces(indent), " public final boolean has", titleCase, "() {\n", - spaces(indent), " return !_getPointerField(", offset, ").isNull();\n", + spaces(indent), " return !_pointerFieldIsNull(", offset, ");\n", spaces(indent), " }\n", spaces(indent), " public final ", builderClass, @@ -1086,7 +1086,7 @@ private: spaces(indent), " }\n", spaces(indent), " public final void set", titleCase, "(", readerClass, " value) {\n", - spaces(indent), " _getPointerField(", offset, ").setList(value);\n", + spaces(indent), " _setPointerField(", listFactory, ", ", offset, ", value);\n", spaces(indent), " }\n", spaces(indent), " public final ", builderClass, diff --git a/runtime/src/main/java/org/capnproto/AnyPointer.java b/runtime/src/main/java/org/capnproto/AnyPointer.java index 09e81e1..8df2e64 100644 --- a/runtime/src/main/java/org/capnproto/AnyPointer.java +++ b/runtime/src/main/java/org/capnproto/AnyPointer.java @@ -19,22 +19,25 @@ public final class AnyPointer { } public static final class Builder { - public final PointerBuilder builder; + final SegmentBuilder segment; + final int pointer; - public Builder(PointerBuilder builder) { - this.builder = builder; + public Builder(SegmentBuilder segment, int pointer) { + this.segment = segment; + this.pointer = pointer; } public final T initAs(InitFromPointerBuilder factory) { - return factory.initFromPointerBuilder(this.builder.segment, this.builder.pointer); + return factory.initFromPointerBuilder(this.segment, this.pointer); } public final T initAs(InitSizedFromPointerBuilder factory, int elementCount) { - return factory.initSizedFromPointerBuilder(this.builder.segment, this.builder.pointer, elementCount); + return factory.initSizedFromPointerBuilder(this.segment, this.pointer, elementCount); } public final void clear() { - this.builder.clear(); + WireHelpers.zeroObject(this.segment, 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 515a08e..ec0df65 100644 --- a/runtime/src/main/java/org/capnproto/Data.java +++ b/runtime/src/main/java/org/capnproto/Data.java @@ -5,12 +5,13 @@ import java.nio.ByteBuffer; public final class Data { public static final class Factory implements FromPointerReaderBlobDefault, FromPointerBuilderBlobDefault, + SetPointerBuilder, InitSizedFromPointerBuilder { - public Reader fromPointerReaderBlobDefault(SegmentReader segment, int pointer, java.nio.ByteBuffer defaultBuffer, + public final Reader fromPointerReaderBlobDefault(SegmentReader segment, int pointer, java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { return WireHelpers.readDataPointer(segment, pointer, defaultBuffer, defaultOffset, defaultSize); } - public Builder fromPointerBuilderBlobDefault(SegmentBuilder segment, int pointer, + public final Builder fromPointerBuilderBlobDefault(SegmentBuilder segment, int pointer, java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { return WireHelpers.getWritableDataPointer(pointer, segment, @@ -19,9 +20,13 @@ public final class Data { defaultSize); } - public Builder initSizedFromPointerBuilder(SegmentBuilder segment, int pointer, int size) { + public final Builder initSizedFromPointerBuilder(SegmentBuilder segment, int pointer, int size) { return WireHelpers.initDataPointer(pointer, segment, size); } + + public final void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value) { + WireHelpers.setDataPointer(pointer, segment, value); + } } public static final Factory factory = new Factory(); diff --git a/runtime/src/main/java/org/capnproto/DataList.java b/runtime/src/main/java/org/capnproto/DataList.java index 7e8cd9e..7a4055e 100644 --- a/runtime/src/main/java/org/capnproto/DataList.java +++ b/runtime/src/main/java/org/capnproto/DataList.java @@ -69,7 +69,7 @@ public final class DataList { } public final void set(int index, Data.Reader value) { - _getPointerElement(index).setData(value); + _setPointerElement(Data.factory, index, value); } public final class Iterator implements java.util.Iterator { diff --git a/runtime/src/main/java/org/capnproto/ListBuilder.java b/runtime/src/main/java/org/capnproto/ListBuilder.java index 64a96e9..35f8ae1 100644 --- a/runtime/src/main/java/org/capnproto/ListBuilder.java +++ b/runtime/src/main/java/org/capnproto/ListBuilder.java @@ -104,13 +104,6 @@ public class ListBuilder { (byte)(indexBit % 8)); } - - protected final PointerBuilder _getPointerElement(int index) { - return new PointerBuilder( - this.segment, - (this.ptr + (index * this.step / Constants.BITS_PER_BYTE)) / Constants.BYTES_PER_WORD); - } - protected final T _getPointerElement(FromPointerBuilder factory, int index, SegmentReader defaultSegment, int defaultOffset) { return factory.fromPointerBuilder( this.segment, @@ -139,4 +132,11 @@ public class ListBuilder { (this.ptr + (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.ptr + (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 b7c9c19..bf28be7 100644 --- a/runtime/src/main/java/org/capnproto/ListFactory.java +++ b/runtime/src/main/java/org/capnproto/ListFactory.java @@ -1,8 +1,11 @@ package org.capnproto; -public abstract class ListFactory implements ListBuilder.Factory, FromPointerBuilder, - InitSizedFromPointerBuilder, - ListReader.Factory, FromPointerReader { +public abstract class ListFactory + implements ListBuilder.Factory, FromPointerBuilder, + InitSizedFromPointerBuilder, + SetPointerBuilder, + ListReader.Factory, FromPointerReader { + final byte elementSize; ListFactory(byte elementSize) {this.elementSize = elementSize;} @@ -30,4 +33,8 @@ public abstract class ListFactory implements ListBuilder.Factor public Builder initSizedFromPointerBuilder(SegmentBuilder segment, int pointer, int elementCount) { return WireHelpers.initListPointer(this, pointer, segment, elementCount, this.elementSize); } + + public final void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value) { + WireHelpers.setListPointer(segment, pointer, value); + } } diff --git a/runtime/src/main/java/org/capnproto/ListList.java b/runtime/src/main/java/org/capnproto/ListList.java index 12b8ffd..9abb7b8 100644 --- a/runtime/src/main/java/org/capnproto/ListList.java +++ b/runtime/src/main/java/org/capnproto/ListList.java @@ -1,7 +1,7 @@ package org.capnproto; public final class ListList { - public static final class Factory + public static final class Factory extends ListFactory, Reader> { public final ListFactory factory; diff --git a/runtime/src/main/java/org/capnproto/MessageBuilder.java b/runtime/src/main/java/org/capnproto/MessageBuilder.java index 129001e..3ca90ef 100644 --- a/runtime/src/main/java/org/capnproto/MessageBuilder.java +++ b/runtime/src/main/java/org/capnproto/MessageBuilder.java @@ -30,7 +30,7 @@ public final class MessageBuilder { throw new Error("could not allocate root pointer"); } - AnyPointer.Builder ptr = new AnyPointer.Builder(PointerBuilder.getRoot(rootSegment, location)); + AnyPointer.Builder ptr = new AnyPointer.Builder(rootSegment, location); return ptr.initAs(factory); } diff --git a/runtime/src/main/java/org/capnproto/PointerBuilder.java b/runtime/src/main/java/org/capnproto/PointerBuilder.java deleted file mode 100644 index c5b1442..0000000 --- a/runtime/src/main/java/org/capnproto/PointerBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.capnproto; - -public final class PointerBuilder { - final SegmentBuilder segment; - final int pointer; // word offset - - public PointerBuilder(SegmentBuilder segment, int pointer) { - this.segment = segment; - this.pointer = pointer; - } - - public static PointerBuilder getRoot(SegmentBuilder segment, int location) { - return new PointerBuilder(segment, location); - } - - public final boolean isNull() { - return this.segment.buffer.getLong(this.pointer) == 0; - } - - public final void setList(ListReader value) { - WireHelpers.setListPointer(this.segment, this.pointer, value); - } - - public final void setStruct(StructReader value) { - WireHelpers.setStructPointer(this.segment, this.pointer, value); - } - - public final void setText(Text.Reader value) { - WireHelpers.setTextPointer(this.pointer, this.segment, value); - } - - public final void setData(Data.Reader value) { - WireHelpers.setDataPointer(this.pointer, this.segment, value); - } - - public final void clear() { - WireHelpers.zeroObject(this.segment, this.pointer); - this.segment.buffer.putLong(this.pointer * 8, 0L); - } -} diff --git a/runtime/src/main/java/org/capnproto/SetPointerBuilder.java b/runtime/src/main/java/org/capnproto/SetPointerBuilder.java new file mode 100644 index 0000000..575956f --- /dev/null +++ b/runtime/src/main/java/org/capnproto/SetPointerBuilder.java @@ -0,0 +1,5 @@ +package org.capnproto; + +public interface SetPointerBuilder { + void setPointerBuilder(SegmentBuilder segment, 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 3a34962..578e89a 100644 --- a/runtime/src/main/java/org/capnproto/StructBuilder.java +++ b/runtime/src/main/java/org/capnproto/StructBuilder.java @@ -149,8 +149,14 @@ public class StructBuilder { Double.doubleToLongBits(value) ^ mask); } - protected final PointerBuilder _getPointerField(int index) { - return new PointerBuilder(this.segment, this.pointers + index); + protected final boolean _pointerFieldIsNull(int ptrIndex) { + return this.segment.buffer.getLong((this.pointers + ptrIndex) * Constants.BYTES_PER_WORD) == 0; + } + + protected final void _clearPointerField(int ptrIndex) { + int pointer = this.pointers + ptrIndex; + WireHelpers.zeroObject(this.segment, pointer); + this.segment.buffer.putLong(pointer * 8, 0L); } protected final T _getPointerField(FromPointerBuilder factory, int index, SegmentReader defaultSegment, int defaultOffset) { @@ -170,4 +176,8 @@ public class StructBuilder { return factory.initSizedFromPointerBuilder(this.segment, this.pointers + index, elementCount); } + protected final void _setPointerField(SetPointerBuilder factory, int index, Reader value) { + factory.setPointerBuilder(this.segment, this.pointers + index, value); + } + } diff --git a/runtime/src/main/java/org/capnproto/StructFactory.java b/runtime/src/main/java/org/capnproto/StructFactory.java index 29ff4be..6a84916 100644 --- a/runtime/src/main/java/org/capnproto/StructFactory.java +++ b/runtime/src/main/java/org/capnproto/StructFactory.java @@ -1,8 +1,10 @@ package org.capnproto; -public abstract class StructFactory implements FromPointerBuilder, StructBuilder.Factory, - InitFromPointerBuilder, - FromPointerReader, StructReader.Factory { +public abstract class StructFactory + implements FromPointerBuilder, StructBuilder.Factory, + InitFromPointerBuilder, + SetPointerBuilder, + FromPointerReader, StructReader.Factory { public final Reader fromPointerReader(SegmentReader segment, int pointer, SegmentReader defaultSegment, int defaultOffset, int nestingLimit) { @@ -20,5 +22,9 @@ public abstract class StructFactory implements FromPointerBuild return WireHelpers.initStructPointer(this, pointer, segment, this.structSize()); } + public final void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value) { + WireHelpers.setStructPointer(segment, 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 9751d8f..73cc7a0 100644 --- a/runtime/src/main/java/org/capnproto/StructList.java +++ b/runtime/src/main/java/org/capnproto/StructList.java @@ -1,7 +1,7 @@ package org.capnproto; public final class StructList { - public static final class Factory + public static final class Factory extends ListFactory, Reader> { public final StructFactory factory; diff --git a/runtime/src/main/java/org/capnproto/StructReader.java b/runtime/src/main/java/org/capnproto/StructReader.java index d73e6cd..3207e6f 100644 --- a/runtime/src/main/java/org/capnproto/StructReader.java +++ b/runtime/src/main/java/org/capnproto/StructReader.java @@ -136,7 +136,7 @@ public class StructReader { } protected final boolean _pointerFieldIsNull(int ptrIndex) { - return this.segment.buffer.getLong(this.pointers + ptrIndex) == 0; + return this.segment.buffer.getLong((this.pointers + ptrIndex) * Constants.BYTES_PER_WORD) == 0; } protected final T _getPointerField(FromPointerReader factory, int ptrIndex, SegmentReader defaultSegment, int defaultOffset) { diff --git a/runtime/src/main/java/org/capnproto/Text.java b/runtime/src/main/java/org/capnproto/Text.java index df6f3bc..d1ac749 100644 --- a/runtime/src/main/java/org/capnproto/Text.java +++ b/runtime/src/main/java/org/capnproto/Text.java @@ -5,13 +5,14 @@ import java.nio.ByteBuffer; public final class Text { public static final class Factory implements FromPointerReaderBlobDefault, FromPointerBuilderBlobDefault, + SetPointerBuilder, InitSizedFromPointerBuilder { - public Reader fromPointerReaderBlobDefault(SegmentReader segment, int pointer, java.nio.ByteBuffer defaultBuffer, + public final Reader fromPointerReaderBlobDefault(SegmentReader segment, int pointer, java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { return WireHelpers.readTextPointer(segment, pointer, defaultBuffer, defaultOffset, defaultSize); } - public Builder fromPointerBuilderBlobDefault(SegmentBuilder segment, int pointer, + public final Builder fromPointerBuilderBlobDefault(SegmentBuilder segment, int pointer, java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { return WireHelpers.getWritableTextPointer(pointer, segment, @@ -20,9 +21,13 @@ public final class Text { defaultSize); } - public Builder initSizedFromPointerBuilder(SegmentBuilder segment, int pointer, int size) { + public final Builder initSizedFromPointerBuilder(SegmentBuilder segment, int pointer, int size) { return WireHelpers.initTextPointer(pointer, segment, size); } + + public final void setPointerBuilder(SegmentBuilder segment, int pointer, Reader value) { + WireHelpers.setTextPointer(pointer, segment, value); + } } public static final Factory factory = new Factory(); diff --git a/runtime/src/main/java/org/capnproto/TextList.java b/runtime/src/main/java/org/capnproto/TextList.java index b994ee5..844ced1 100644 --- a/runtime/src/main/java/org/capnproto/TextList.java +++ b/runtime/src/main/java/org/capnproto/TextList.java @@ -69,7 +69,7 @@ public final class TextList { } public final void set(int index, Text.Reader value) { - _getPointerElement(index).setText(value); + _setPointerElement(Text.factory, index, value); } public final class Iterator implements java.util.Iterator { diff --git a/runtime/src/test/scala/org/capnproto/LayoutTest.scala b/runtime/src/test/scala/org/capnproto/LayoutTest.scala index 729378e..3070b98 100644 --- a/runtime/src/test/scala/org/capnproto/LayoutTest.scala +++ b/runtime/src/test/scala/org/capnproto/LayoutTest.scala @@ -114,12 +114,10 @@ class LayoutSuite extends FunSuite { val buffer = java.nio.ByteBuffer.allocate(1024 * 8); buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN); - val pointerBuilder = PointerBuilder.getRoot( - new SegmentBuilder(buffer, new BuilderArena(BuilderArena.SUGGESTED_FIRST_SEGMENT_WORDS, - BuilderArena.SUGGESTED_ALLOCATION_STRATEGY)), - 0); + val segment = new SegmentBuilder(buffer, new BuilderArena(BuilderArena.SUGGESTED_FIRST_SEGMENT_WORDS, + BuilderArena.SUGGESTED_ALLOCATION_STRATEGY)) val factory = new BareStructBuilder(new StructSize(2, 4, FieldSize.INLINE_COMPOSITE)); - val builder = WireHelpers.initStructPointer(factory, pointerBuilder.pointer, pointerBuilder.segment, factory.structSize()); + val builder = WireHelpers.initStructPointer(factory, 0, segment, factory.structSize()); setupStruct(builder); checkStruct(builder); }