From 14237610fb62622d34731c9fbd7fce25ad46496d Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Mon, 27 Feb 2017 18:42:38 -0500 Subject: [PATCH] Fix bug in double-far creation and add StructListUpgradeDoubleFar test. --- .../scala/org/capnproto/EncodingSuite.scala | 45 +++++++++++++++++++ .../main/java/org/capnproto/WireHelpers.java | 5 ++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/compiler/src/test/scala/org/capnproto/EncodingSuite.scala b/compiler/src/test/scala/org/capnproto/EncodingSuite.scala index 8043c66..d419f0c 100644 --- a/compiler/src/test/scala/org/capnproto/EncodingSuite.scala +++ b/compiler/src/test/scala/org/capnproto/EncodingSuite.scala @@ -180,6 +180,51 @@ class EncodingSuite extends FunSuite { } } + test("StructListUpgradeDoubleFar") { + val bytes = Array[Byte]( + 1,0,0,0,0x1f,0,0,0, // list, inline composite, 3 words + 4, 0, 0, 0, 1, 0, 2, 0, // struct tag. 1 element, 1 word data, 2 pointers. + 91,0,0,0,0,0,0,0, // data: 91 + 0x05,0,0,0, 0x42,0,0,0, // list pointer, offset 1, type = BYTE, length 8. + 0,0,0,0,0,0,0,0, // null pointer + 0x68,0x65,0x6c,0x6c,0x6f,0x21,0x21,0) // "hello!!" + + val segment = java.nio.ByteBuffer.wrap(bytes) + segment.order(java.nio.ByteOrder.LITTLE_ENDIAN) + val messageReader = new MessageReader(Array(segment), ReaderOptions.DEFAULT_READER_OPTIONS) + + val oldFactory = new StructList.Factory(TestOldVersion.factory) + val oldVersion = messageReader.getRoot(oldFactory) + + oldVersion.size() should equal (1) + oldVersion.get(0).getOld1() should equal (91) + oldVersion.get(0).getOld2().toString() should equal ("hello!!") + + // Make the first segment exactly large enough to fit the original message. + // This leaves no room for a far pointer landing pad in the first segment. + val message = new MessageBuilder(6) + message.setRoot(oldFactory, oldVersion) + + val segments = message.getSegmentsForOutput() + segments.length should equal (1) + segments(0).limit() should equal (6 * 8) + + val newVersion = message.getRoot(new StructList.Factory(TestNewVersion.factory)) + newVersion.size() should equal (1) + newVersion.get(0).getOld1() should equal (91) + newVersion.get(0).getOld2().toString() should equal ("hello!!") + + Serialize.write((new java.io.FileOutputStream("/Users/dwrensha/Desktop/test.dat")).getChannel(), + message) + + val segments1 = message.getSegmentsForOutput() + segments(0).limit() should equal (6 * 8) + for (ii <- 8 to (5 * 8) - 1) { + // Check the the old list, including the tag, was zeroed. + segments(0).get(ii) 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/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index d62af7f..2ff9f1b 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -363,7 +363,7 @@ final class WireHelpers { FarPointer.setSegmentId(farSegment.buffer, landingPadOffset, srcSegment.id); WirePointer.setKindWithZeroOffset(farSegment.buffer, landingPadOffset + 1, - WirePointer.kind(srcTarget)); + WirePointer.kind(src)); farSegment.buffer.putInt((landingPadOffset + 1) * Constants.BYTES_PER_WORD + 4, srcSegment.buffer.getInt(srcOffset * Constants.BYTES_PER_WORD + 4)); @@ -659,8 +659,9 @@ final class WireHelpers { } //# Zero out old location. See explanation in getWritableStructPointer(). + //# Make sure to include the tag word. memset(resolved.segment.buffer, resolved.ptr * Constants.BYTES_PER_WORD, - (byte)0, oldStep * elementCount * Constants.BYTES_PER_WORD); + (byte)0, (1 + oldStep * elementCount) * Constants.BYTES_PER_WORD); return factory.constructBuilder(allocation.segment, newPtr * Constants.BYTES_PER_WORD, elementCount,