From fd3efb080ef6ce4280389c7420e10e7104ca5d5b Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Sun, 9 Nov 2014 16:32:51 -0500 Subject: [PATCH] add a Zeroing test and fix some bugs --- .../scala/org/capnproto/EncodingTest.scala | 30 ++++++++++++++++++- .../java/org/capnproto/MessageBuilder.java | 17 +++++++---- .../main/java/org/capnproto/WireHelpers.java | 5 ++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/compiler/src/test/scala/org/capnproto/EncodingTest.scala b/compiler/src/test/scala/org/capnproto/EncodingTest.scala index 4e97eab..c998a85 100644 --- a/compiler/src/test/scala/org/capnproto/EncodingTest.scala +++ b/compiler/src/test/scala/org/capnproto/EncodingTest.scala @@ -50,7 +50,7 @@ class EncodingSuite extends FunSuite { TestUtil.initTestMessage(allTypes); val message2 = new MessageBuilder(); - val allTypes2 = message.initRoot(TestAllTypes.factory); + val allTypes2 = message2.initRoot(TestAllTypes.factory); allTypes2.setStructField(allTypes.asReader()); TestUtil.checkTestMessage(allTypes2.getStructField()); @@ -58,6 +58,34 @@ class EncodingSuite extends FunSuite { TestUtil.checkTestMessage(reader); } + test("Zeroing") { + val message = new MessageBuilder(); + val allTypes = message.initRoot(TestAllTypes.factory); + + val structList = allTypes.initStructList(3); + TestUtil.initTestMessage(structList.get(0)); + + val structField = allTypes.initStructField(); + TestUtil.initTestMessage(structField); + + TestUtil.initTestMessage(structList.get(1)); + TestUtil.initTestMessage(structList.get(2)); + TestUtil.checkTestMessage(structList.get(0)); + allTypes.initStructList(0); + + TestUtil.checkTestMessage(allTypes.getStructField()); + val allTypesReader = allTypes.asReader(); + TestUtil.checkTestMessage(allTypesReader.getStructField()); + + val any = message.initRoot(AnyPointer.factory); + val segments = message.getSegmentsForOutput(); + for (segment <- segments) { + for (jj <- 0 to segment.limit - 1) { + segment.get(jj) should equal (0); + } + } + } + test("Generics") { val message = new MessageBuilder(); val factory = TestGenerics.newFactory(TestAllTypes.factory, Text.factory); diff --git a/runtime/src/main/java/org/capnproto/MessageBuilder.java b/runtime/src/main/java/org/capnproto/MessageBuilder.java index 6983bf9..d8ec266 100644 --- a/runtime/src/main/java/org/capnproto/MessageBuilder.java +++ b/runtime/src/main/java/org/capnproto/MessageBuilder.java @@ -46,13 +46,18 @@ public final class MessageBuilder { public T initRoot(FromPointerBuilder factory) { SegmentBuilder rootSegment = this.arena.segments.get(0); - int location = rootSegment.allocate(1); - if (location == SegmentBuilder.FAILED_ALLOCATION) { - throw new Error("could not allocate root pointer"); + if (rootSegment.currentSize() == 0) { + int location = rootSegment.allocate(1); + if (location == SegmentBuilder.FAILED_ALLOCATION) { + throw new Error("could not allocate root pointer"); + } + if (location != 0) { + throw new Error("First allocated word of new segment was not at offset 0"); + } + return factory.initFromPointerBuilder(rootSegment, location, 0); + } else { + return factory.initFromPointerBuilder(rootSegment, 0, 0); } - - AnyPointer.Builder ptr = new AnyPointer.Builder(rootSegment, location); - return ptr.initAs(factory); } public final java.nio.ByteBuffer[] getSegmentsForOutput() { diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index 5669022..91f27c5 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -48,6 +48,11 @@ final class WireHelpers { int amount, // in words byte kind) { + long ref = segment.get(refOffset); + if (!WirePointer.isNull(ref)) { + zeroObject(segment, refOffset); + } + if (amount == 0 && kind == WirePointer.STRUCT) { WirePointer.setKindAndTargetForEmptyStruct(segment.buffer, refOffset); return new AllocateResult(refOffset, refOffset, segment);