Commit 7f20d533 authored by Kenton Varda's avatar Kenton Varda

Implement inline structs.

parent 9e7acd4b
This diff is collapsed.
...@@ -415,7 +415,7 @@ struct WireHelpers { ...@@ -415,7 +415,7 @@ struct WireHelpers {
ref->structRef.set(size); ref->structRef.set(size);
// Build the StructBuilder. // Build the StructBuilder.
return StructBuilder(segment, ptr, reinterpret_cast<WireReference*>(ptr + size.data)); return StructBuilder(segment, ptr, reinterpret_cast<WireReference*>(ptr + size.data), 0 * BITS);
} }
static CAPNPROTO_ALWAYS_INLINE(StructBuilder getWritableStructReference( static CAPNPROTO_ALWAYS_INLINE(StructBuilder getWritableStructReference(
...@@ -442,7 +442,7 @@ struct WireHelpers { ...@@ -442,7 +442,7 @@ struct WireHelpers {
"Trying to update struct with incorrect reference count."); "Trying to update struct with incorrect reference count.");
} }
return StructBuilder(segment, ptr, reinterpret_cast<WireReference*>(ptr + size.data)); return StructBuilder(segment, ptr, reinterpret_cast<WireReference*>(ptr + size.data), 0 * BITS);
} }
static CAPNPROTO_ALWAYS_INLINE(ListBuilder initListReference( static CAPNPROTO_ALWAYS_INLINE(ListBuilder initListReference(
...@@ -603,7 +603,7 @@ struct WireHelpers { ...@@ -603,7 +603,7 @@ struct WireHelpers {
if (ref == nullptr || ref->isNull()) { if (ref == nullptr || ref->isNull()) {
useDefault: useDefault:
if (defaultValue == nullptr) { if (defaultValue == nullptr) {
return StructReader(nullptr, nullptr, nullptr, 0 * WORDS, 0 * REFERENCES, 0 * BITS, return StructReader(nullptr, nullptr, nullptr, 0 * BITS, 0 * REFERENCES, 0 * BITS,
std::numeric_limits<int>::max()); std::numeric_limits<int>::max());
} }
segment = nullptr; segment = nullptr;
...@@ -637,7 +637,7 @@ struct WireHelpers { ...@@ -637,7 +637,7 @@ struct WireHelpers {
return StructReader( return StructReader(
segment, ptr, reinterpret_cast<const WireReference*>(ptr + ref->structRef.dataSize.get()), segment, ptr, reinterpret_cast<const WireReference*>(ptr + ref->structRef.dataSize.get()),
ref->structRef.dataSize.get(), ref->structRef.dataSize.get() * BITS_PER_WORD,
ref->structRef.refCount.get(), ref->structRef.refCount.get(),
0 * BITS, nestingLimit - 1); 0 * BITS, nestingLimit - 1);
} }
...@@ -752,7 +752,8 @@ struct WireHelpers { ...@@ -752,7 +752,8 @@ struct WireHelpers {
} }
return ListReader(segment, ptr, size, wordsPerElement * BITS_PER_WORD, return ListReader(segment, ptr, size, wordsPerElement * BITS_PER_WORD,
tag->structRef.dataSize.get(), tag->structRef.refCount.get(), nestingLimit - 1); tag->structRef.dataSize.get() * BITS_PER_WORD,
tag->structRef.refCount.get(), nestingLimit - 1);
} else { } else {
// The elements of the list are NOT structs. // The elements of the list are NOT structs.
...@@ -774,28 +775,17 @@ struct WireHelpers { ...@@ -774,28 +775,17 @@ struct WireHelpers {
// old version of the protocol. We need to verify that the struct's first field matches // old version of the protocol. We need to verify that the struct's first field matches
// what the sender sent us. // what the sender sent us.
WordCount dataSize; BitCount dataSize = 0 * BITS;
WireReferenceCount referenceCount; WireReferenceCount referenceCount = 0 * REFERENCES;
switch (ref->listRef.elementSize()) { switch (ref->listRef.elementSize()) {
case FieldSize::VOID: case FieldSize::VOID: break;
dataSize = 0 * WORDS; case FieldSize::BIT: dataSize = 1 * BITS; break;
referenceCount = 0 * REFERENCES; case FieldSize::BYTE: dataSize = 8 * BITS; break;
break; case FieldSize::TWO_BYTES: dataSize = 16 * BITS; break;
case FieldSize::FOUR_BYTES: dataSize = 32 * BITS; break;
case FieldSize::BIT: case FieldSize::EIGHT_BYTES: dataSize = 64 * BITS; break;
case FieldSize::BYTE: case FieldSize::REFERENCE: referenceCount = 1 * REFERENCES; break;
case FieldSize::TWO_BYTES:
case FieldSize::FOUR_BYTES:
case FieldSize::EIGHT_BYTES:
dataSize = 1 * WORDS;
referenceCount = 0 * REFERENCES;
break;
case FieldSize::REFERENCE:
dataSize = 0 * WORDS;
referenceCount = 1 * REFERENCES;
break;
case FieldSize::INLINE_COMPOSITE: case FieldSize::INLINE_COMPOSITE:
FAIL_CHECK(); FAIL_CHECK();
...@@ -978,7 +968,7 @@ StructReader StructBuilder::asReader() const { ...@@ -978,7 +968,7 @@ StructReader StructBuilder::asReader() const {
static_assert(sizeof(WireReference::structRef.refCount) == 2, static_assert(sizeof(WireReference::structRef.refCount) == 2,
"Has the maximum reference count changed?"); "Has the maximum reference count changed?");
return StructReader(segment, data, references, return StructReader(segment, data, references,
0xffff * WORDS, 0xffff * REFERENCES, 0 * BITS, std::numeric_limits<int>::max()); 0xffffffff * BITS, 0xffff * REFERENCES, 0 * BITS, std::numeric_limits<int>::max());
} }
StructReader StructReader::readRootTrusted(const word* location) { StructReader StructReader::readRootTrusted(const word* location) {
...@@ -998,7 +988,7 @@ StructReader StructReader::readRoot( ...@@ -998,7 +988,7 @@ StructReader StructReader::readRoot(
} }
StructReader StructReader::readEmpty() { StructReader StructReader::readEmpty() {
return StructReader(nullptr, nullptr, nullptr, 0 * WORDS, 0 * REFERENCES, 0 * BITS, return StructReader(nullptr, nullptr, nullptr, 0 * BITS, 0 * REFERENCES, 0 * BITS,
std::numeric_limits<int>::max()); std::numeric_limits<int>::max());
} }
...@@ -1031,7 +1021,7 @@ StructBuilder ListBuilder::getStructElement( ...@@ -1031,7 +1021,7 @@ StructBuilder ListBuilder::getStructElement(
ElementCount index, decltype(WORDS/ELEMENTS) elementSize, WordCount structDataSize) const { ElementCount index, decltype(WORDS/ELEMENTS) elementSize, WordCount structDataSize) const {
word* structPtr = ptr + elementSize * index; word* structPtr = ptr + elementSize * index;
return StructBuilder(segment, structPtr, return StructBuilder(segment, structPtr,
reinterpret_cast<WireReference*>(structPtr + structDataSize)); reinterpret_cast<WireReference*>(structPtr + structDataSize), 0 * BITS);
} }
ListBuilder ListBuilder::initListElement( ListBuilder ListBuilder::initListElement(
...@@ -1087,9 +1077,9 @@ ListReader ListBuilder::asReader(FieldSize elementSize) const { ...@@ -1087,9 +1077,9 @@ ListReader ListBuilder::asReader(FieldSize elementSize) const {
std::numeric_limits<int>::max()); std::numeric_limits<int>::max());
} }
ListReader ListBuilder::asReader(WordCount dataSize, WireReferenceCount referenceCount) const { ListReader ListBuilder::asReader(BitCount dataSize, WireReferenceCount referenceCount) const {
return ListReader(segment, ptr, elementCount, return ListReader(segment, ptr, elementCount,
(dataSize + referenceCount * WORDS_PER_REFERENCE) * BITS_PER_WORD / ELEMENTS, (dataSize + referenceCount * WORDS_PER_REFERENCE * BITS_PER_WORD) / ELEMENTS,
dataSize, referenceCount, std::numeric_limits<int>::max()); dataSize, referenceCount, std::numeric_limits<int>::max());
} }
...@@ -1103,7 +1093,7 @@ StructReader ListReader::getStructElement(ElementCount index) const { ...@@ -1103,7 +1093,7 @@ StructReader ListReader::getStructElement(ElementCount index) const {
const byte* structPtr = reinterpret_cast<const byte*>(ptr) + indexBit / BITS_PER_BYTE; const byte* structPtr = reinterpret_cast<const byte*>(ptr) + indexBit / BITS_PER_BYTE;
return StructReader( return StructReader(
segment, structPtr, segment, structPtr,
reinterpret_cast<const WireReference*>(structPtr + structDataSize * BYTES_PER_WORD), reinterpret_cast<const WireReference*>(structPtr + structDataSize / BITS_PER_BYTE),
structDataSize, structReferenceCount, indexBit % BITS_PER_BYTE, nestingLimit - 1); structDataSize, structReferenceCount, indexBit % BITS_PER_BYTE, nestingLimit - 1);
} }
......
This diff is collapsed.
...@@ -57,6 +57,9 @@ using ::capnproto::test::TestUnion; ...@@ -57,6 +57,9 @@ using ::capnproto::test::TestUnion;
using ::capnproto::test::TestUnionDefaults; using ::capnproto::test::TestUnionDefaults;
using ::capnproto::test::TestNestedTypes; using ::capnproto::test::TestNestedTypes;
using ::capnproto::test::TestUsing; using ::capnproto::test::TestUsing;
using ::capnproto::test::TestInlineLayout;
using ::capnproto::test::TestInlineUnions;
using ::capnproto::test::TestInlineDefaults;
void initTestMessage(test::TestAllTypes::Builder builder); void initTestMessage(test::TestAllTypes::Builder builder);
void initTestMessage(test::TestDefaults::Builder builder); void initTestMessage(test::TestDefaults::Builder builder);
......
...@@ -213,7 +213,6 @@ struct TestUnion { ...@@ -213,7 +213,6 @@ struct TestUnion {
bit5 @42: Bool; bit5 @42: Bool;
bit6 @43: Bool; bit6 @43: Bool;
bit7 @44: Bool; bit7 @44: Bool;
byte0 @49: UInt8;
# Interleave two unions to be really annoying. # Interleave two unions to be really annoying.
# Also declare in reverse order to make sure union discriminant values are sorted by field number # Also declare in reverse order to make sure union discriminant values are sorted by field number
...@@ -233,6 +232,8 @@ struct TestUnion { ...@@ -233,6 +232,8 @@ struct TestUnion {
u3f0s8 @48: Int8; u3f0s8 @48: Int8;
u3f0s1 @46: Bool; u3f0s1 @46: Bool;
} }
byte0 @49: UInt8;
} }
struct TestUnionDefaults { struct TestUnionDefaults {
...@@ -274,3 +275,140 @@ struct TestUsing { ...@@ -274,3 +275,140 @@ struct TestUsing {
outerNestedEnum @1 :OuterNestedEnum = bar; outerNestedEnum @1 :OuterNestedEnum = bar;
innerNestedEnum @0 :NestedEnum = quux; innerNestedEnum @0 :NestedEnum = quux;
} }
struct TestInline0 fixed(0 bits) {}
struct TestInline1 fixed(1 bits) { f @0: Bool; }
struct TestInline8 fixed(8 bits) { f0 @0: Bool; f1 @1: Bool; f2 @2: Bool; }
struct TestInline16 fixed(16 bits) { f0 @0: UInt8; f1 @1: UInt8; }
struct TestInline32 fixed(32 bits) { f0 @0: UInt8; f1 @1: UInt16; }
struct TestInline64 fixed(64 bits) { f0 @0: UInt8; f1 @1: UInt32; }
struct TestInline128 fixed(2 words) { f0 @0: UInt64; f1 @1: UInt64; }
struct TestInline192 fixed(3 words) { f0 @0: UInt64; f1 @1: UInt64; f2 @2: UInt64; }
struct TestInline0p fixed(0 bits, 1 pointers) { f @0 :Inline(TestInline0); p0 @1 :Text; }
struct TestInline1p fixed(1 bits, 1 pointers) { f @0 :Inline(TestInline1); p0 @1 :Text; }
struct TestInline8p fixed(8 bits, 1 pointers) { f @0 :Inline(TestInline8); p0 @1 :Text; }
struct TestInline16p fixed(16 bits, 2 pointers) { f @0 :Inline(TestInline16); p0 @1 :Text; p1 @2 :Text; }
struct TestInline32p fixed(32 bits, 2 pointers) { f @0 :Inline(TestInline32); p0 @1 :Text; p1 @2 :Text; }
struct TestInline64p fixed(64 bits, 2 pointers) { f @0 :Inline(TestInline64); p0 @1 :Text; p1 @2 :Text; }
struct TestInline128p fixed(2 words, 3 pointers) { f @0 :Inline(TestInline128); p0 @1 :Text; p1 @2 :Text; p2 @3 :Text; }
struct TestInline192p fixed(3 words, 3 pointers) { f @0 :Inline(TestInline192); p0 @1 :Text; p1 @2 :Text; p2 @3 :Text; }
struct TestInlineLayout {
f0 @0 :Inline(TestInline0);
f1 @1 :Inline(TestInline1);
f8 @2 :Inline(TestInline8);
f16 @3 :Inline(TestInline16);
f32 @4 :Inline(TestInline32);
f64 @5 :Inline(TestInline64);
f128 @6 :Inline(TestInline128);
f192 @7 :Inline(TestInline192);
f0p @8 :Inline(TestInline0p);
f1p @9 :Inline(TestInline1p);
f8p @10 :Inline(TestInline8p);
f16p @11 :Inline(TestInline16p);
f32p @12 :Inline(TestInline32p);
f64p @13 :Inline(TestInline64p);
f128p @14 :Inline(TestInline128p);
f192p @15 :Inline(TestInline192p);
f1Offset @16 :Inline(TestInline1);
bit @17 :Bool;
}
struct TestInlineUnions {
union0 @0 union {
f0 @4 :Inline(TestInline0);
f1 @5 :Inline(TestInline1);
f8 @6 :Inline(TestInline8);
f16 @7 :Inline(TestInline16);
f32 @8 :Inline(TestInline32);
f64 @9 :Inline(TestInline64);
f128 @10 :Inline(TestInline128);
f192 @11 :Inline(TestInline192);
f0p @12 :Inline(TestInline0p);
f1p @13 :Inline(TestInline1p);
f8p @14 :Inline(TestInline8p);
f16p @15 :Inline(TestInline16p);
f32p @16 :Inline(TestInline32p);
f64p @17 :Inline(TestInline64p);
f128p @18 :Inline(TestInline128p);
f192p @19 :Inline(TestInline192p);
}
# Pack one bit in order to make pathological situation for union1.
bit0 @20: Bool;
union1 @1 union {
f0 @21 :Inline(TestInline0);
f1 @22 :Inline(TestInline1);
f8 @23 :Inline(TestInline8);
f16 @24 :Inline(TestInline16);
f32 @25 :Inline(TestInline32);
f64 @26 :Inline(TestInline64);
f128 @27 :Inline(TestInline128);
f192 @28 :Inline(TestInline192);
}
# Fill in the rest of that bitfield from earlier.
bit2 @29: Bool;
bit3 @30: Bool;
bit4 @31: Bool;
bit5 @32: Bool;
bit6 @33: Bool;
bit7 @34: Bool;
# Interleave two unions to be really annoying.
union2 @2 union {
f1p @35 :Inline(TestInline1p);
f8p @37 :Inline(TestInline8p);
f16p @40 :Inline(TestInline16p);
f32p @42 :Inline(TestInline32p);
f64p @44 :Inline(TestInline64p);
f128p @46 :Inline(TestInline128p);
f192p @48 :Inline(TestInline192p);
}
union3 @3 union {
f1p @36 :Inline(TestInline1p);
f8p @38 :Inline(TestInline8p);
f16p @41 :Inline(TestInline16p);
f32p @43 :Inline(TestInline32p);
f64p @45 :Inline(TestInline64p);
f128p @47 :Inline(TestInline128p);
f192p @49 :Inline(TestInline192p);
}
byte0 @39: UInt8;
}
struct TestInlineDefaults {
normal @0 :TestInlineLayout = (
f0 = (),
f1 = (f = true),
f8 = (f0 = true, f1 = false, f2 = true),
f16 = (f0 = 123, f1 = 45),
f32 = (f0 = 67, f1 = 8901),
f64 = (f0 = 234, f1 = 567890123),
f128 = (f0 = 1234567890123, f1 = 4567890123456),
f192 = (f0 = 7890123456789, f1 = 2345678901234, f2 = 5678901234567),
f0p = (p0 = "foo"),
f1p = (f = (f = false), p0 = "bar"),
f8p = (f = (f0 = true, f1 = true, f2 = false), p0 = "baz"),
f16p = (f = (f0 = 98, f1 = 76), p0 = "qux", p1 = "quux"),
f32p = (f = (f0 = 54, f1 = 32109), p0 = "corge", p1 = "grault"),
f64p = (f = (f0 = 87, f1 = 654321098), p0 = "garply", p1 = "waldo"),
f128p = (f = (f0 = 7654321098765, f1 = 4321098765432),
p0 = "fred", p1 = "plugh", p2 = "xyzzy"),
f192p = (f = (f0 = 1098765432109, f1 = 8765432109876, f2 = 5432109876543),
p0 = "thud", p1 = "foobar", p2 = "barbaz"));
unions @1 :TestInlineUnions = (
union0 = f32(f0 = 67, f1 = 8901),
union1 = f128(f0 = 1234567890123, f1 = 4567890123456),
union2 = f1p(p0 = "foo"),
union3 = f16p(f = (f0 = 98, f1 = 76), p0 = "qux", p1 = "quux"));
}
...@@ -651,6 +651,11 @@ inline constexpr decltype(BYTES / ELEMENTS) bytesPerElement() { ...@@ -651,6 +651,11 @@ inline constexpr decltype(BYTES / ELEMENTS) bytesPerElement() {
return sizeof(T) * BYTES / ELEMENTS; return sizeof(T) * BYTES / ELEMENTS;
} }
template <typename T>
inline constexpr decltype(BITS / ELEMENTS) bitsPerElement() {
return sizeof(T) * 8 * BITS / ELEMENTS;
}
#ifndef __CDT_PARSER__ #ifndef __CDT_PARSER__
template <typename T, typename U> template <typename T, typename U>
......
...@@ -4,6 +4,13 @@ cabal-version: >=1.2 ...@@ -4,6 +4,13 @@ cabal-version: >=1.2
build-type: Simple build-type: Simple
author: kenton author: kenton
-- How to get stack traces:
-- 1. Compile normally and do not clean.
-- 2. Add "-prof -fprof-auto -osuf .prof.o" to ghc-options and compile again.
-- (TODO: Figure out how to add these through "cabal configure" instead of by editing
-- this file. --enable-executable-profiling alone doesn't appear to get the job done.)
-- 3. Run with +RTS -xc -RTS on the command line.
executable capnpc executable capnpc
hs-source-dirs: src hs-source-dirs: src
main-is: Main.hs main-is: Main.hs
......
This diff is collapsed.
...@@ -88,6 +88,7 @@ hashString str = ...@@ -88,6 +88,7 @@ hashString str =
isPrimitive t@(BuiltinType _) = not $ isBlob t isPrimitive t@(BuiltinType _) = not $ isBlob t
isPrimitive (EnumType _) = True isPrimitive (EnumType _) = True
isPrimitive (StructType _) = False isPrimitive (StructType _) = False
isPrimitive (InlineStructType _) = False
isPrimitive (InterfaceType _) = False isPrimitive (InterfaceType _) = False
isPrimitive (ListType _) = False isPrimitive (ListType _) = False
...@@ -96,8 +97,12 @@ isBlob (BuiltinType BuiltinData) = True ...@@ -96,8 +97,12 @@ isBlob (BuiltinType BuiltinData) = True
isBlob _ = False isBlob _ = False
isStruct (StructType _) = True isStruct (StructType _) = True
isStruct (InlineStructType _) = True
isStruct _ = False isStruct _ = False
isInlineStruct (InlineStructType _) = True
isInlineStruct _ = False
isList (ListType _) = True isList (ListType _) = True
isList _ = False isList _ = False
...@@ -130,18 +135,30 @@ cxxTypeString (BuiltinType BuiltinText) = " ::capnproto::Text" ...@@ -130,18 +135,30 @@ cxxTypeString (BuiltinType BuiltinText) = " ::capnproto::Text"
cxxTypeString (BuiltinType BuiltinData) = " ::capnproto::Data" cxxTypeString (BuiltinType BuiltinData) = " ::capnproto::Data"
cxxTypeString (EnumType desc) = globalName $ DescEnum desc cxxTypeString (EnumType desc) = globalName $ DescEnum desc
cxxTypeString (StructType desc) = globalName $ DescStruct desc cxxTypeString (StructType desc) = globalName $ DescStruct desc
cxxTypeString (InlineStructType desc) = globalName $ DescStruct desc
cxxTypeString (InterfaceType desc) = globalName $ DescInterface desc cxxTypeString (InterfaceType desc) = globalName $ DescInterface desc
cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"] cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"]
cxxFieldSizeString Size0 = "VOID"; cxxFieldSizeString SizeVoid = "VOID";
cxxFieldSizeString Size1 = "BIT"; cxxFieldSizeString (SizeData Size1) = "BIT";
cxxFieldSizeString Size8 = "BYTE"; cxxFieldSizeString (SizeData Size8) = "BYTE";
cxxFieldSizeString Size16 = "TWO_BYTES"; cxxFieldSizeString (SizeData Size16) = "TWO_BYTES";
cxxFieldSizeString Size32 = "FOUR_BYTES"; cxxFieldSizeString (SizeData Size32) = "FOUR_BYTES";
cxxFieldSizeString Size64 = "EIGHT_BYTES"; cxxFieldSizeString (SizeData Size64) = "EIGHT_BYTES";
cxxFieldSizeString SizeReference = "REFERENCE"; cxxFieldSizeString SizeReference = "REFERENCE";
cxxFieldSizeString (SizeInlineComposite _ _) = "INLINE_COMPOSITE"; cxxFieldSizeString (SizeInlineComposite _ _) = "INLINE_COMPOSITE";
fieldOffsetInteger VoidOffset = "0"
fieldOffsetInteger (DataOffset _ o) = show o
fieldOffsetInteger (PointerOffset o) = show o
fieldOffsetInteger (InlineCompositeOffset d p ds ps) = let
bitSize = dataSectionBits ds
bitOffset = case ds of
DataSectionWords _ -> d * 64
_ -> d * bitSize
in printf "%d * ::capnproto::BITS, %d * ::capnproto::BITS, \
\%d * ::capnproto::REFERENCES, %d * ::capnproto::REFERENCES" bitOffset bitSize p ps
isDefaultZero VoidDesc = True isDefaultZero VoidDesc = True
isDefaultZero (BoolDesc b) = not b isDefaultZero (BoolDesc b) = not b
isDefaultZero (Int8Desc i) = i == 0 isDefaultZero (Int8Desc i) = i == 0
...@@ -221,6 +238,7 @@ fieldContext parent desc = mkStrContext context where ...@@ -221,6 +238,7 @@ fieldContext parent desc = mkStrContext context where
context "fieldIsPrimitive" = MuBool $ isPrimitive $ fieldType desc context "fieldIsPrimitive" = MuBool $ isPrimitive $ fieldType desc
context "fieldIsBlob" = MuBool $ isBlob $ fieldType desc context "fieldIsBlob" = MuBool $ isBlob $ fieldType desc
context "fieldIsStruct" = MuBool $ isStruct $ fieldType desc context "fieldIsStruct" = MuBool $ isStruct $ fieldType desc
context "fieldIsInlineStruct" = MuBool $ isInlineStruct $ fieldType desc
context "fieldIsList" = MuBool $ isList $ fieldType desc context "fieldIsList" = MuBool $ isList $ fieldType desc
context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc
context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc
...@@ -231,7 +249,7 @@ fieldContext parent desc = mkStrContext context where ...@@ -231,7 +249,7 @@ fieldContext parent desc = mkStrContext context where
Nothing -> muNull Nothing -> muNull
context "fieldType" = MuVariable $ cxxTypeString $ fieldType desc context "fieldType" = MuVariable $ cxxTypeString $ fieldType desc
context "fieldBlobType" = MuVariable $ blobTypeString $ fieldType desc context "fieldBlobType" = MuVariable $ blobTypeString $ fieldType desc
context "fieldOffset" = MuVariable $ fieldOffset desc context "fieldOffset" = MuVariable $ fieldOffsetInteger $ fieldOffset desc
context "fieldDefaultMask" = case fieldDefaultValue desc of context "fieldDefaultMask" = case fieldDefaultValue desc of
Nothing -> MuVariable "" Nothing -> MuVariable ""
Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v) Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v)
...@@ -283,8 +301,8 @@ structContext parent desc = mkStrContext context where ...@@ -283,8 +301,8 @@ structContext parent desc = mkStrContext context where
context "structFullName" = MuVariable $ fullName (DescStruct desc) context "structFullName" = MuVariable $ fullName (DescStruct desc)
context "structFields" = MuList $ map (fieldContext context) $ structFields desc context "structFields" = MuList $ map (fieldContext context) $ structFields desc
context "structUnions" = MuList $ map (unionContext context) $ structUnions desc context "structUnions" = MuList $ map (unionContext context) $ structUnions desc
context "structDataSize" = MuVariable $ packingDataSize $ structPacking desc context "structDataSize" = MuVariable $ dataSectionWordSize $ structDataSize desc
context "structReferenceCount" = MuVariable $ packingReferenceCount $ structPacking desc context "structReferenceCount" = MuVariable $ structPointerCount desc
context "structNestedEnums" = context "structNestedEnums" =
MuList $ map (enumContext context) [m | DescEnum m <- structMembers desc] MuList $ map (enumContext context) [m | DescEnum m <- structMembers desc]
context "structNestedStructs" = context "structNestedStructs" =
......
...@@ -95,7 +95,8 @@ data Declaration = UsingDecl (Located String) DeclName ...@@ -95,7 +95,8 @@ data Declaration = UsingDecl (Located String) DeclName
| ConstantDecl (Located String) TypeExpression [Annotation] (Located FieldValue) | ConstantDecl (Located String) TypeExpression [Annotation] (Located FieldValue)
| EnumDecl (Located String) [Annotation] [Declaration] | EnumDecl (Located String) [Annotation] [Declaration]
| EnumerantDecl (Located String) (Located Integer) [Annotation] | EnumerantDecl (Located String) (Located Integer) [Annotation]
| StructDecl (Located String) [Annotation] [Declaration] | StructDecl (Located String) (Maybe (Located (Integer, Integer)))
[Annotation] [Declaration]
| FieldDecl (Located String) (Located Integer) | FieldDecl (Located String) (Located Integer)
TypeExpression [Annotation] (Maybe (Located FieldValue)) TypeExpression [Annotation] (Maybe (Located FieldValue))
| UnionDecl (Located String) (Located Integer) [Annotation] [Declaration] | UnionDecl (Located String) (Located Integer) [Annotation] [Declaration]
...@@ -110,7 +111,7 @@ declarationName (UsingDecl n _) = Just n ...@@ -110,7 +111,7 @@ declarationName (UsingDecl n _) = Just n
declarationName (ConstantDecl n _ _ _) = Just n declarationName (ConstantDecl n _ _ _) = Just n
declarationName (EnumDecl n _ _) = Just n declarationName (EnumDecl n _ _) = Just n
declarationName (EnumerantDecl n _ _) = Just n declarationName (EnumerantDecl n _ _) = Just n
declarationName (StructDecl n _ _) = Just n declarationName (StructDecl n _ _ _) = Just n
declarationName (FieldDecl n _ _ _ _) = Just n declarationName (FieldDecl n _ _ _ _) = Just n
declarationName (UnionDecl n _ _ _) = Just n declarationName (UnionDecl n _ _ _) = Just n
declarationName (InterfaceDecl n _ _) = Just n declarationName (InterfaceDecl n _ _) = Just n
...@@ -122,7 +123,7 @@ declImports (UsingDecl _ name) = maybeToList (declNameImport name) ...@@ -122,7 +123,7 @@ declImports (UsingDecl _ name) = maybeToList (declNameImport name)
declImports (ConstantDecl _ t ann _) = typeImports t ++ concatMap annotationImports ann declImports (ConstantDecl _ t ann _) = typeImports t ++ concatMap annotationImports ann
declImports (EnumDecl _ ann decls) = concatMap annotationImports ann ++ concatMap declImports decls declImports (EnumDecl _ ann decls) = concatMap annotationImports ann ++ concatMap declImports decls
declImports (EnumerantDecl _ _ ann) = concatMap annotationImports ann declImports (EnumerantDecl _ _ ann) = concatMap annotationImports ann
declImports (StructDecl _ ann decls) = concatMap annotationImports ann ++ declImports (StructDecl _ _ ann decls) = concatMap annotationImports ann ++
concatMap declImports decls concatMap declImports decls
declImports (FieldDecl _ _ t ann _) = typeImports t ++ concatMap annotationImports ann declImports (FieldDecl _ _ t ann _) = typeImports t ++ concatMap annotationImports ann
declImports (UnionDecl _ _ ann decls) = concatMap annotationImports ann ++ declImports (UnionDecl _ _ ann decls) = concatMap annotationImports ann ++
......
...@@ -49,6 +49,7 @@ keywords = ...@@ -49,6 +49,7 @@ keywords =
, (UnionKeyword, "union") , (UnionKeyword, "union")
, (InterfaceKeyword, "interface") , (InterfaceKeyword, "interface")
, (AnnotationKeyword, "annotation") , (AnnotationKeyword, "annotation")
, (FixedKeyword, "fixed")
] ]
languageDef :: T.LanguageDef st languageDef :: T.LanguageDef st
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
module Parser (parseFile) where module Parser (parseFile) where
import Data.Generics import Data.Generics
import Data.Maybe(fromMaybe)
import Text.Parsec hiding (tokens) import Text.Parsec hiding (tokens)
import Token import Token
import Grammar import Grammar
...@@ -65,6 +66,7 @@ tokenErrorString StructKeyword = "keyword \"struct\"" ...@@ -65,6 +66,7 @@ tokenErrorString StructKeyword = "keyword \"struct\""
tokenErrorString UnionKeyword = "keyword \"union\"" tokenErrorString UnionKeyword = "keyword \"union\""
tokenErrorString InterfaceKeyword = "keyword \"interface\"" tokenErrorString InterfaceKeyword = "keyword \"interface\""
tokenErrorString AnnotationKeyword = "keyword \"annotation\"" tokenErrorString AnnotationKeyword = "keyword \"annotation\""
tokenErrorString FixedKeyword = "keyword \"fixed\""
type TokenParser = Parsec [Located Token] [ParseError] type TokenParser = Parsec [Located Token] [ParseError]
...@@ -120,6 +122,7 @@ structKeyword = tokenParser (matchSimpleToken StructKeyword) <?> "\"struct\"" ...@@ -120,6 +122,7 @@ structKeyword = tokenParser (matchSimpleToken StructKeyword) <?> "\"struct\""
unionKeyword = tokenParser (matchSimpleToken UnionKeyword) <?> "\"union\"" unionKeyword = tokenParser (matchSimpleToken UnionKeyword) <?> "\"union\""
interfaceKeyword = tokenParser (matchSimpleToken InterfaceKeyword) <?> "\"interface\"" interfaceKeyword = tokenParser (matchSimpleToken InterfaceKeyword) <?> "\"interface\""
annotationKeyword = tokenParser (matchSimpleToken AnnotationKeyword) <?> "\"annotation\"" annotationKeyword = tokenParser (matchSimpleToken AnnotationKeyword) <?> "\"annotation\""
fixedKeyword = tokenParser (matchSimpleToken FixedKeyword) <?> "\"fixed\""
exactIdentifier s = tokenParser (matchSimpleToken $ Identifier s) <?> "\"" ++ s ++ "\"" exactIdentifier s = tokenParser (matchSimpleToken $ Identifier s) <?> "\"" ++ s ++ "\""
...@@ -223,9 +226,39 @@ enumerantDecl = do ...@@ -223,9 +226,39 @@ enumerantDecl = do
structDecl statements = do structDecl statements = do
structKeyword structKeyword
name <- located typeIdentifier name <- located typeIdentifier
fixed <- optionMaybe fixedSpec
annotations <- many annotation annotations <- many annotation
children <- parseBlock structLine statements children <- parseBlock structLine statements
return (StructDecl name annotations children) return (StructDecl name fixed annotations children)
fixedSpec = do
fixedKeyword
Located pos sizes <- located $ parenthesizedList fixedSize
(dataSize, pointerSize) <- foldM combineFixedSizes (Nothing, Nothing) sizes
return $ Located pos (fromMaybe 0 dataSize, fromMaybe 0 pointerSize)
data FixedSize = FixedData Integer | FixedPointers Integer
combineFixedSizes :: (Maybe Integer, Maybe Integer) -> FixedSize
-> TokenParser (Maybe Integer, Maybe Integer)
combineFixedSizes (Nothing, p) (FixedData d) = return (Just d, p)
combineFixedSizes (Just _, _) (FixedData _) =
fail "Multiple data section size specifications."
combineFixedSizes (d, Nothing) (FixedPointers p) = return (d, Just p)
combineFixedSizes (_, Just _) (FixedPointers _) =
fail "Multiple pointer section size specifications."
fixedSize = do
size <- literalInt
(exactIdentifier "bit" >> return (FixedData size))
<|> (exactIdentifier "bits" >> return (FixedData size))
<|> (exactIdentifier "byte" >> return (FixedData (8 * size)))
<|> (exactIdentifier "bytes" >> return (FixedData (8 * size)))
<|> (exactIdentifier "word" >> return (FixedData (64 * size)))
<|> (exactIdentifier "words" >> return (FixedData (64 * size)))
<|> (exactIdentifier "pointer" >> return (FixedPointers size))
<|> (exactIdentifier "pointers" >> return (FixedPointers size))
<?> "\"bits\", \"bytes\", \"words\", or \"pointers\""
structLine :: Maybe [Located Statement] -> TokenParser Declaration structLine :: Maybe [Located Statement] -> TokenParser Declaration
structLine Nothing = usingDecl <|> constantDecl <|> fieldDecl <|> annotationDecl structLine Nothing = usingDecl <|> constantDecl <|> fieldDecl <|> annotationDecl
......
This diff is collapsed.
...@@ -74,6 +74,7 @@ data Token = Identifier String ...@@ -74,6 +74,7 @@ data Token = Identifier String
| UnionKeyword | UnionKeyword
| InterfaceKeyword | InterfaceKeyword
| AnnotationKeyword | AnnotationKeyword
| FixedKeyword
deriving (Data, Typeable, Show, Eq) deriving (Data, Typeable, Show, Eq)
data Statement = Line TokenSequence data Statement = Line TokenSequence
......
This diff is collapsed.
...@@ -295,6 +295,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}( ...@@ -295,6 +295,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
{{/fieldIsBlob}} {{/fieldIsBlob}}
{{! ------------------------------------------------------------------------------------------- }} {{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsStruct}} {{#fieldIsStruct}}
{{^fieldIsInlineStruct}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
...@@ -324,6 +325,34 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -324,6 +325,34 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}} {{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}})); {{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
} }
{{/fieldIsInlineStruct}}
{{#fieldIsInlineStruct}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Reader(_reader.getInlineStructField(
{{fieldOffset}}));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initInlineStructField(
{{fieldOffset}}));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.getInlineStructField(
{{fieldOffset}}));
}
{{/fieldIsInlineStruct}}
{{/fieldIsStruct}} {{/fieldIsStruct}}
{{! ------------------------------------------------------------------------------------------- }} {{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsList}} {{#fieldIsList}}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment