Commit f966fc41 authored by Kenton Varda's avatar Kenton Varda

Store primitive fields XOR'd with their defaults.

parent f3c4121b
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -216,7 +216,7 @@ struct List<T, false> { ...@@ -216,7 +216,7 @@ struct List<T, false> {
inline uint size() { return reader.size() / ELEMENTS; } inline uint size() { return reader.size() / ELEMENTS; }
inline typename T::Reader operator[](uint index) { inline typename T::Reader operator[](uint index) {
return typename T::Reader(reader.getStructElement(index * ELEMENTS, T::DEFAULT.words)); return typename T::Reader(reader.getStructElement(index * ELEMENTS));
} }
typedef internal::IndexingIterator<Reader, typename T::Reader> iterator; typedef internal::IndexingIterator<Reader, typename T::Reader> iterator;
...@@ -235,8 +235,7 @@ struct List<T, false> { ...@@ -235,8 +235,7 @@ struct List<T, false> {
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS; }
inline typename T::Builder operator[](uint index) { inline typename T::Builder operator[](uint index) {
return typename T::Builder(builder.getStructElement(index * ELEMENTS, return typename T::Builder(builder.getStructElement(index * ELEMENTS,
(T::DATA_SIZE + T::REFERENCE_COUNT * WORDS_PER_REFERENCE) / ELEMENTS, T::STRUCT_SIZE.total() / ELEMENTS, T::STRUCT_SIZE.data));
T::DATA_SIZE));
} }
typedef internal::IndexingIterator<Builder, typename T::Builder> iterator; typedef internal::IndexingIterator<Builder, typename T::Builder> iterator;
......
...@@ -38,7 +38,7 @@ MessageReader::~MessageReader() { ...@@ -38,7 +38,7 @@ MessageReader::~MessageReader() {
} }
} }
internal::StructReader MessageReader::getRoot(const word* defaultValue) { internal::StructReader MessageReader::getRootInternal() {
if (!allocatedArena) { if (!allocatedArena) {
static_assert(sizeof(internal::ReaderArena) <= sizeof(arenaSpace), static_assert(sizeof(internal::ReaderArena) <= sizeof(arenaSpace),
"arenaSpace is too small to hold a ReaderArena. Please increase it. This will break " "arenaSpace is too small to hold a ReaderArena. Please increase it. This will break "
...@@ -51,10 +51,9 @@ internal::StructReader MessageReader::getRoot(const word* defaultValue) { ...@@ -51,10 +51,9 @@ internal::StructReader MessageReader::getRoot(const word* defaultValue) {
if (segment == nullptr || if (segment == nullptr ||
!segment->containsInterval(segment->getStartPtr(), segment->getStartPtr() + 1)) { !segment->containsInterval(segment->getStartPtr(), segment->getStartPtr() + 1)) {
arena()->reportInvalidData("Message did not contain a root pointer."); arena()->reportInvalidData("Message did not contain a root pointer.");
return internal::StructReader::readRootTrusted(defaultValue, defaultValue); return internal::StructReader::readEmpty();
} else { } else {
return internal::StructReader::readRoot( return internal::StructReader::readRoot(segment->getStartPtr(), segment, options.nestingLimit);
segment->getStartPtr(), defaultValue, segment, options.nestingLimit);
} }
} }
...@@ -88,16 +87,16 @@ internal::SegmentBuilder* MessageBuilder::getRootSegment() { ...@@ -88,16 +87,16 @@ internal::SegmentBuilder* MessageBuilder::getRootSegment() {
} }
} }
internal::StructBuilder MessageBuilder::initRoot(const word* defaultValue) { internal::StructBuilder MessageBuilder::initRoot(internal::StructSize size) {
internal::SegmentBuilder* rootSegment = getRootSegment(); internal::SegmentBuilder* rootSegment = getRootSegment();
return internal::StructBuilder::initRoot( return internal::StructBuilder::initRoot(
rootSegment, rootSegment->getPtrUnchecked(0 * WORDS), defaultValue); rootSegment, rootSegment->getPtrUnchecked(0 * WORDS), size);
} }
internal::StructBuilder MessageBuilder::getRoot(const word* defaultValue) { internal::StructBuilder MessageBuilder::getRoot(internal::StructSize size) {
internal::SegmentBuilder* rootSegment = getRootSegment(); internal::SegmentBuilder* rootSegment = getRootSegment();
return internal::StructBuilder::getRoot( return internal::StructBuilder::getRoot(
rootSegment, rootSegment->getPtrUnchecked(0 * WORDS), defaultValue); rootSegment, rootSegment->getPtrUnchecked(0 * WORDS), size);
} }
ArrayPtr<const ArrayPtr<const word>> MessageBuilder::getSegmentsForOutput() { ArrayPtr<const ArrayPtr<const word>> MessageBuilder::getSegmentsForOutput() {
......
...@@ -144,7 +144,7 @@ private: ...@@ -144,7 +144,7 @@ private:
bool allocatedArena; bool allocatedArena;
internal::ReaderArena* arena() { return reinterpret_cast<internal::ReaderArena*>(arenaSpace); } internal::ReaderArena* arena() { return reinterpret_cast<internal::ReaderArena*>(arenaSpace); }
internal::StructReader getRoot(const word* defaultValue); internal::StructReader getRootInternal();
}; };
class MessageBuilder { class MessageBuilder {
...@@ -175,8 +175,8 @@ private: ...@@ -175,8 +175,8 @@ private:
internal::BuilderArena* arena() { return reinterpret_cast<internal::BuilderArena*>(arenaSpace); } internal::BuilderArena* arena() { return reinterpret_cast<internal::BuilderArena*>(arenaSpace); }
internal::SegmentBuilder* getRootSegment(); internal::SegmentBuilder* getRootSegment();
internal::StructBuilder initRoot(const word* defaultValue); internal::StructBuilder initRoot(internal::StructSize size);
internal::StructBuilder getRoot(const word* defaultValue); internal::StructBuilder getRoot(internal::StructSize size);
}; };
template <typename RootType> template <typename RootType>
...@@ -297,23 +297,22 @@ inline const ReaderOptions& MessageReader::getOptions() { ...@@ -297,23 +297,22 @@ inline const ReaderOptions& MessageReader::getOptions() {
template <typename RootType> template <typename RootType>
inline typename RootType::Reader MessageReader::getRoot() { inline typename RootType::Reader MessageReader::getRoot() {
return typename RootType::Reader(getRoot(RootType::DEFAULT.words)); return typename RootType::Reader(getRootInternal());
} }
template <typename RootType> template <typename RootType>
inline typename RootType::Builder MessageBuilder::initRoot() { inline typename RootType::Builder MessageBuilder::initRoot() {
return typename RootType::Builder(initRoot(RootType::DEFAULT.words)); return typename RootType::Builder(initRoot(RootType::STRUCT_SIZE));
} }
template <typename RootType> template <typename RootType>
inline typename RootType::Builder MessageBuilder::getRoot() { inline typename RootType::Builder MessageBuilder::getRoot() {
return typename RootType::Builder(getRoot(RootType::DEFAULT.words)); return typename RootType::Builder(getRoot(RootType::STRUCT_SIZE));
} }
template <typename RootType> template <typename RootType>
typename RootType::Reader readMessageTrusted(const word* data) { typename RootType::Reader readMessageTrusted(const word* data) {
return typename RootType::Reader(internal::StructReader::readRootTrusted( return typename RootType::Reader(internal::StructReader::readRootTrusted(data));
data, RootType::DEFAULT.words));
} }
} // namespace capnproto } // namespace capnproto
......
...@@ -67,7 +67,7 @@ struct TestAllTypes { ...@@ -67,7 +67,7 @@ struct TestAllTypes {
dataList @30 : List(Data); dataList @30 : List(Data);
structList @31 : List(TestAllTypes); structList @31 : List(TestAllTypes);
enumList @32 : List(TestEnum); enumList @32 : List(TestEnum);
interfaceList @33 : Void; # TODO interfaceList @33 : List(Void); # TODO
} }
struct TestDefaults { struct TestDefaults {
......
...@@ -29,6 +29,7 @@ import qualified Data.ByteString.UTF8 as ByteStringUTF8 ...@@ -29,6 +29,7 @@ import qualified Data.ByteString.UTF8 as ByteStringUTF8
import Data.FileEmbed(embedFile) import Data.FileEmbed(embedFile)
import Data.Word(Word8) import Data.Word(Word8)
import qualified Data.Digest.MD5 as MD5 import qualified Data.Digest.MD5 as MD5
import Data.Binary.IEEE754(floatToWord, doubleToWord)
import Text.Printf(printf) import Text.Printf(printf)
import Text.Hastache import Text.Hastache
import Text.Hastache.Context import Text.Hastache.Context
...@@ -106,25 +107,41 @@ cxxFieldSizeString Size64 = "EIGHT_BYTES"; ...@@ -106,25 +107,41 @@ cxxFieldSizeString Size64 = "EIGHT_BYTES";
cxxFieldSizeString SizeReference = "REFERENCE"; cxxFieldSizeString SizeReference = "REFERENCE";
cxxFieldSizeString (SizeInlineComposite _ _) = "INLINE_COMPOSITE"; cxxFieldSizeString (SizeInlineComposite _ _) = "INLINE_COMPOSITE";
cxxValueString VoidDesc = " ::capnproto::Void::VOID" isDefaultZero VoidDesc = True
cxxValueString (BoolDesc b) = if b then "true" else "false" isDefaultZero (BoolDesc b) = not b
cxxValueString (Int8Desc i) = show i isDefaultZero (Int8Desc i) = i == 0
cxxValueString (Int16Desc i) = show i isDefaultZero (Int16Desc i) = i == 0
cxxValueString (Int32Desc i) = show i isDefaultZero (Int32Desc i) = i == 0
cxxValueString (Int64Desc i) = show i ++ "ll" isDefaultZero (Int64Desc i) = i == 0
cxxValueString (UInt8Desc i) = show i isDefaultZero (UInt8Desc i) = i == 0
cxxValueString (UInt16Desc i) = show i isDefaultZero (UInt16Desc i) = i == 0
cxxValueString (UInt32Desc i) = show i ++ "u" isDefaultZero (UInt32Desc i) = i == 0
cxxValueString (UInt64Desc i) = show i ++ "llu" isDefaultZero (UInt64Desc i) = i == 0
cxxValueString (Float32Desc x) = show x ++ "f" isDefaultZero (Float32Desc x) = x == 0
cxxValueString (Float64Desc x) = show x isDefaultZero (Float64Desc x) = x == 0
cxxValueString (EnumValueValueDesc v) = isDefaultZero (EnumValueValueDesc v) = enumValueNumber v == 0
cxxTypeString (EnumType $ enumValueParent v) ++ "::" ++ isDefaultZero (TextDesc _) = error "Can't call isDefaultZero on aggregate types."
toUpperCaseWithUnderscores (enumValueName v) isDefaultZero (DataDesc _) = error "Can't call isDefaultZero on aggregate types."
cxxValueString (TextDesc _) = error "No default value literal for aggregate type." isDefaultZero (StructValueDesc _) = error "Can't call isDefaultZero on aggregate types."
cxxValueString (DataDesc _) = error "No default value literal for aggregate type." isDefaultZero (ListDesc _) = error "Can't call isDefaultZero on aggregate types."
cxxValueString (StructValueDesc _) = error "No default value literal for aggregate type."
cxxValueString (ListDesc _) = error "No default value literal for aggregate type." defaultMask VoidDesc = "0"
defaultMask (BoolDesc b) = if b then "true" else "false"
defaultMask (Int8Desc i) = show i
defaultMask (Int16Desc i) = show i
defaultMask (Int32Desc i) = show i
defaultMask (Int64Desc i) = show i ++ "ll"
defaultMask (UInt8Desc i) = show i
defaultMask (UInt16Desc i) = show i
defaultMask (UInt32Desc i) = show i ++ "u"
defaultMask (UInt64Desc i) = show i ++ "llu"
defaultMask (Float32Desc x) = show (floatToWord x) ++ "u"
defaultMask (Float64Desc x) = show (doubleToWord x) ++ "ul"
defaultMask (EnumValueValueDesc v) = show (enumValueNumber v)
defaultMask (TextDesc _) = error "Can't call defaultMask on aggregate types."
defaultMask (DataDesc _) = error "Can't call defaultMask on aggregate types."
defaultMask (StructValueDesc _) = error "Can't call defaultMask on aggregate types."
defaultMask (ListDesc _) = error "Can't call defaultMask on aggregate types."
defaultValueBytes _ (TextDesc s) = Just (UTF8.encode s ++ [0]) defaultValueBytes _ (TextDesc s) = Just (UTF8.encode s ++ [0])
defaultValueBytes _ (DataDesc d) = Just d defaultValueBytes _ (DataDesc d) = Just d
...@@ -132,25 +149,6 @@ defaultValueBytes t v@(StructValueDesc _) = Just $ encodeMessage t v ...@@ -132,25 +149,6 @@ defaultValueBytes t v@(StructValueDesc _) = Just $ encodeMessage t v
defaultValueBytes t v@(ListDesc _) = Just $ encodeMessage t v defaultValueBytes t v@(ListDesc _) = Just $ encodeMessage t v
defaultValueBytes _ _ = Nothing defaultValueBytes _ _ = Nothing
cxxDefaultDefault (BuiltinType BuiltinVoid) = " ::capnproto::Void::VOID"
cxxDefaultDefault (BuiltinType BuiltinBool) = "false"
cxxDefaultDefault (BuiltinType BuiltinInt8) = "0"
cxxDefaultDefault (BuiltinType BuiltinInt16) = "0"
cxxDefaultDefault (BuiltinType BuiltinInt32) = "0"
cxxDefaultDefault (BuiltinType BuiltinInt64) = "0"
cxxDefaultDefault (BuiltinType BuiltinUInt8) = "0"
cxxDefaultDefault (BuiltinType BuiltinUInt16) = "0"
cxxDefaultDefault (BuiltinType BuiltinUInt32) = "0"
cxxDefaultDefault (BuiltinType BuiltinUInt64) = "0"
cxxDefaultDefault (BuiltinType BuiltinFloat32) = "0"
cxxDefaultDefault (BuiltinType BuiltinFloat64) = "0"
cxxDefaultDefault (BuiltinType BuiltinText) = "\"\""
cxxDefaultDefault (EnumType desc) = cxxValueString $ EnumValueValueDesc $ head $ enumValues desc
cxxDefaultDefault (BuiltinType BuiltinData) = error "No default value literal for aggregate type."
cxxDefaultDefault (StructType _) = error "No default value literal for aggregate type."
cxxDefaultDefault (InterfaceType _) = error "No default value literal for aggregate type."
cxxDefaultDefault (ListType _) = error "No default value literal for aggregate type."
elementType (ListType t) = t elementType (ListType t) = t
elementType _ = error "Called elementType on non-list." elementType _ = error "Called elementType on non-list."
...@@ -197,9 +195,9 @@ fieldContext parent desc = mkStrContext context where ...@@ -197,9 +195,9 @@ fieldContext parent desc = mkStrContext context where
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 $ fieldOffset desc
context "fieldDefaultValue" = case fieldDefaultValue desc of context "fieldDefaultMask" = case fieldDefaultValue desc of
Just v -> MuVariable $ cxxValueString v Nothing -> MuVariable ""
Nothing -> MuVariable $ cxxDefaultDefault $ fieldType desc Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v)
context "fieldElementSize" = context "fieldElementSize" =
MuVariable $ cxxFieldSizeString $ elementSize $ elementType $ fieldType desc MuVariable $ cxxFieldSizeString $ elementSize $ elementType $ fieldType desc
context "fieldElementType" = context "fieldElementType" =
...@@ -212,8 +210,6 @@ structContext parent desc = mkStrContext context where ...@@ -212,8 +210,6 @@ structContext parent desc = mkStrContext context where
context "structDataSize" = MuVariable $ packingDataSize $ structPacking desc context "structDataSize" = MuVariable $ packingDataSize $ structPacking desc
context "structReferenceCount" = MuVariable $ packingReferenceCount $ structPacking desc context "structReferenceCount" = MuVariable $ packingReferenceCount $ structPacking desc
context "structChildren" = MuList [] -- TODO context "structChildren" = MuList [] -- TODO
context "structDefault" = MuList [defaultBytesContext context (StructType desc)
(encodeMessage (StructType desc) (StructValueDesc []))]
context s = parent s context s = parent s
fileContext desc = mkStrContext context where fileContext desc = mkStrContext context where
......
...@@ -25,8 +25,7 @@ module WireFormat(encodeMessage) where ...@@ -25,8 +25,7 @@ module WireFormat(encodeMessage) where
import Data.List(sortBy, genericLength, genericReplicate) import Data.List(sortBy, genericLength, genericReplicate)
import Data.Word import Data.Word
import Data.Bits(shiftL, shiftR, Bits, setBit) import Data.Bits(shiftL, shiftR, Bits, setBit, xor)
import qualified Data.Set as Set
import Semantics import Semantics
import Data.Binary.IEEE754(floatToWord, doubleToWord) import Data.Binary.IEEE754(floatToWord, doubleToWord)
import qualified Codec.Binary.UTF8.String as UTF8 import qualified Codec.Binary.UTF8.String as UTF8
...@@ -69,27 +68,34 @@ encodeDataValue (EnumValueValueDesc v) = bytes (enumValueNumber v) 2 ...@@ -69,27 +68,34 @@ encodeDataValue (EnumValueValueDesc v) = bytes (enumValueNumber v) 2
encodeDataValue (StructValueDesc _) = error "Not fixed-width data." encodeDataValue (StructValueDesc _) = error "Not fixed-width data."
encodeDataValue (ListDesc _) = error "Not fixed-width data." encodeDataValue (ListDesc _) = error "Not fixed-width data."
packBits :: Bits a => Int -> [Bool] -> a encodeMaskedDataValue v Nothing = encodeDataValue v
encodeMaskedDataValue v (Just d) = zipWith xor (encodeDataValue v) (encodeDataValue d)
packBits :: Bits a => Int -> [(Bool, Maybe Bool)] -> a
packBits _ [] = 0 packBits _ [] = 0
packBits offset (True:bits) = setBit (packBits (offset + 1) bits) offset packBits offset ((True, Nothing):bits) = setBit (packBits (offset + 1) bits) offset
packBits offset (False:bits) = packBits (offset + 1) bits packBits offset ((False, Nothing):bits) = packBits (offset + 1) bits
packBits offset ((b, Just d):bits) = packBits offset ((b /= d, Nothing):bits)
encodeData :: Integer -> [(Integer, TypeDesc, ValueDesc)] -> [Word8] -- The tuples are (offsetInBits, type, value, defaultValue) for each field to encode.
encodeData :: Integer -> [(Integer, TypeDesc, ValueDesc, Maybe ValueDesc)] -> [Word8]
encodeData size = loop 0 where encodeData size = loop 0 where
loop bit [] | bit == size = [] loop bit [] | bit == size = []
loop bit [] | bit > size = error "Data values overran size." loop bit [] | bit > size = error "Data values overran size."
loop bit [] = 0:loop (bit + 8) [] loop bit [] = 0:loop (bit + 8) []
loop bit rest@((valuePos, _, BoolDesc _):_) | valuePos == bit = let loop bit rest@((valuePos, _, BoolDesc _, _):_) | valuePos == bit = let
(bits, rest2) = popBits (bit + 8) rest (bits, rest2) = popBits (bit + 8) rest
in packBits 0 bits : loop (bit + 8) rest2 in packBits 0 bits : loop (bit + 8) rest2
loop bit ((valuePos, _, value):rest) | valuePos == bit = loop bit ((valuePos, _, value, defaultValue):rest) | valuePos == bit =
encodeDataValue value ++ loop (bit + sizeInBits (fieldValueSize value)) rest encodeMaskedDataValue value defaultValue ++
loop bit rest@((valuePos, _, _):_) | valuePos > bit = 0 : loop (bit + 8) rest loop (bit + sizeInBits (fieldValueSize value)) rest
loop bit rest@((valuePos, _, _, _):_) | valuePos > bit = 0 : loop (bit + 8) rest
loop _ _ = error "Data values were out-of-order." loop _ _ = error "Data values were out-of-order."
popBits limit ((valuePos, _, BoolDesc b):rest) | valuePos < limit = let popBits limit ((valuePos, _, BoolDesc b, d):rest) | valuePos < limit = let
(restBits, rest2) = popBits limit rest (restBits, rest2) = popBits limit rest
in (b:restBits, rest2) defaultB = fmap (\(BoolDesc b2) -> b2) d
in ((b, defaultB):restBits, rest2)
popBits _ rest = ([], rest) popBits _ rest = ([], rest)
encodeReferences :: Integer -> Integer -> [(Integer, TypeDesc, ValueDesc)] -> ([Word8], [Word8]) encodeReferences :: Integer -> Integer -> [(Integer, TypeDesc, ValueDesc)] -> ([Word8], [Word8])
...@@ -156,10 +162,6 @@ fieldSizeEnum (SizeInlineComposite _ _) = 7 ...@@ -156,10 +162,6 @@ fieldSizeEnum (SizeInlineComposite _ _) = 7
structTag = 0 structTag = 0
listTag = 1 listTag = 1
-- Is this field a non-retroactive member of a union? If so, its default value is not written.
isNonRetroUnionMember (FieldDesc {fieldNumber = n, fieldUnion = Just u}) = n > unionNumber u
isNonRetroUnionMember _ = False
-- What is this union's default tag value? If there is a retroactive field, it is that field's -- What is this union's default tag value? If there is a retroactive field, it is that field's
-- number, otherwise it is the union's number (meaning no field set). -- number, otherwise it is the union's number (meaning no field set).
unionDefault desc = UInt8Desc $ fromIntegral $ unionDefault desc = UInt8Desc $ fromIntegral $
...@@ -168,49 +170,24 @@ unionDefault desc = UInt8Desc $ fromIntegral $ ...@@ -168,49 +170,24 @@ unionDefault desc = UInt8Desc $ fromIntegral $
-- childOffset = number of words between the last reference and the location where children will -- childOffset = number of words between the last reference and the location where children will
-- be allocated. -- be allocated.
encodeStruct desc assignments childOffset = (dataBytes, referenceBytes, children) where encodeStruct desc assignments childOffset = (dataBytes, referenceBytes, children) where
explicitlyAssignedNums = Set.fromList [fieldNumber f | (f, _) <- assignments]
explicitlyAssignedUnions = Set.fromList
[unionNumber u | (FieldDesc {fieldUnion = Just u}, _) <- assignments]
-- Was this field explicitly assigned, or was another member of the same union explicitly
-- assigned? If so, its default value is not written.
isExplicitlyAssigned (FieldDesc {fieldNumber = n, fieldUnion = u}) =
Set.member n explicitlyAssignedNums ||
maybe False (flip Set.member explicitlyAssignedUnions . unionNumber) u
-- Values explicitly assigned. -- Values explicitly assigned.
explicitValues = [(fieldOffset f, fieldType f, v) | (f, v) <- assignments] explicitValues = [(fieldOffset f, fieldType f, v, fieldDefaultValue f) | (f, v) <- assignments]
-- Values from defaults.
defaultValues = [(o, fieldType field, v)
| field@(FieldDesc { fieldOffset = o, fieldDefaultValue = Just v}) <- structFields desc
-- Don't include default values for fields that were explicitly assigned.
, not $ isExplicitlyAssigned field
-- Don't encode defaults for union members since they'd overwrite each other, and anyway
-- they wouldn't be valid unless the union tag specified them, which by default it doesn't,
-- except of course in the case of retroactively-added fields. So do include retro fields.
, not $ isNonRetroUnionMember field
-- Don't encode defaults for references. Setting them to null has the same effect.
, isDataFieldSize $ fieldValueSize v ]
-- Values of union tags. -- Values of union tags.
unionValues = [(unionTagOffset u, BuiltinType BuiltinUInt8, UInt8Desc $ fromIntegral n) unionValues = [(unionTagOffset u, BuiltinType BuiltinUInt8, UInt8Desc $ fromIntegral n,
Just $ unionDefault u)
| (FieldDesc {fieldUnion = Just u, fieldNumber = n}, _) <- assignments] | (FieldDesc {fieldUnion = Just u, fieldNumber = n}, _) <- assignments]
-- Default values of union tags. allValues = explicitValues ++ unionValues
unionDefaultValues = [(unionTagOffset u, BuiltinType BuiltinUInt8, unionDefault u) allData = [ (o * sizeInBits (fieldValueSize v), t, v, d)
| u <- structUnions desc | (o, t, v, d) <- allValues, isDataFieldSize $ fieldValueSize v ]
, not $ Set.member (unionNumber u) explicitlyAssignedUnions] allReferences = [ (o, t, v) | (o, t, v, _) <- allValues
allValues = explicitValues ++ defaultValues ++ unionValues ++ unionDefaultValues
allData = [ (o * sizeInBits (fieldValueSize v), t, v)
| (o, t, v) <- allValues, isDataFieldSize $ fieldValueSize v ]
allReferences = [ (o, t, v) | (o, t, v) <- allValues
, not $ isDataFieldSize $ fieldValueSize v ] , not $ isDataFieldSize $ fieldValueSize v ]
sortedData = sortBy compareValues allData sortedData = sortBy compareDataValues allData
sortedReferences = sortBy compareValues allReferences compareDataValues (o1, _, _, _) (o2, _, _, _) = compare o1 o2
compareValues (o1, _, _) (o2, _, _) = compare o1 o2 sortedReferences = sortBy compareReferenceValues allReferences
compareReferenceValues (o1, _, _) (o2, _, _) = compare o1 o2
dataBytes = encodeData (packingDataSize (structPacking desc) * 64) sortedData dataBytes = encodeData (packingDataSize (structPacking desc) * 64) sortedData
(referenceBytes, children) = encodeReferences childOffset (referenceBytes, children) = encodeReferences childOffset
...@@ -228,7 +205,7 @@ encodeList elementType elements = case elementSize elementType of ...@@ -228,7 +205,7 @@ encodeList elementType elements = case elementSize elementType of
(refBytes, childBytes) = encodeReferences 0 (genericLength elements) (refBytes, childBytes) = encodeReferences 0 (genericLength elements)
$ zipWith (\i v -> (i, elementType, v)) [0..] elements $ zipWith (\i v -> (i, elementType, v)) [0..] elements
size -> encodeData (roundUpToMultiple 64 (genericLength elements * sizeInBits size)) size -> encodeData (roundUpToMultiple 64 (genericLength elements * sizeInBits size))
$ zipWith (\i v -> (i * sizeInBits size, elementType, v)) [0..] elements $ zipWith (\i v -> (i * sizeInBits size, elementType, v, Nothing)) [0..] elements
encodeMessage (StructType desc) (StructValueDesc assignments) = let encodeMessage (StructType desc) (StructValueDesc assignments) = let
(dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0 (dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0
......
...@@ -41,12 +41,9 @@ struct {{structName}} { ...@@ -41,12 +41,9 @@ struct {{structName}} {
struct {{structChildName}}; struct {{structChildName}};
{{/structChildren}} {{/structChildren}}
static constexpr ::capnproto::WordCount DATA_SIZE = {{structDataSize}} * ::capnproto::WORDS; static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
static constexpr ::capnproto::WireReferenceCount REFERENCE_COUNT = ::capnproto::internal::StructSize({{structDataSize}} * ::capnproto::WORDS,
{{structReferenceCount}} * ::capnproto::REFERENCES; {{structReferenceCount}} * ::capnproto::REFERENCES);
{{#structDefault}}
static const ::capnproto::internal::AlignedData<{{defaultWordCount}}> DEFAULT;
{{/structDefault}}
{{#structFields}} {{#structFields}}
{{#fieldDefaultBytes}} {{#fieldDefaultBytes}}
static const ::capnproto::internal::AlignedData<{{defaultWordCount}}> DEFAULT_{{fieldUpperCase}}; static const ::capnproto::internal::AlignedData<{{defaultWordCount}}> DEFAULT_{{fieldUpperCase}};
...@@ -140,7 +137,7 @@ private: ...@@ -140,7 +137,7 @@ private:
{{#fieldIsPrimitive}} {{#fieldIsPrimitive}}
inline {{fieldType}} {{structName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}} {{structName}}::Reader::get{{fieldTitleCase}}() {
return _reader.getDataField<{{fieldType}}>( return _reader.getDataField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::ELEMENTS, {{fieldDefaultValue}}); {{fieldOffset}} * ::capnproto::ELEMENTS{{fieldDefaultMask}});
} }
{{/fieldIsPrimitive}} {{/fieldIsPrimitive}}
{{#fieldIsBlob}} {{#fieldIsBlob}}
...@@ -159,7 +156,7 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() { ...@@ -159,7 +156,7 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() {
return {{fieldType}}::Reader(_reader.getStructField( return {{fieldType}}::Reader(_reader.getStructField(
{{fieldOffset}} * ::capnproto::REFERENCES, {{fieldOffset}} * ::capnproto::REFERENCES,
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}} {{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}{{fieldType}}::DEFAULT.words{{/fieldDefaultBytes}})); {{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
} }
{{/fieldIsStruct}} {{/fieldIsStruct}}
{{#fieldIsList}} {{#fieldIsList}}
...@@ -179,11 +176,12 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() { ...@@ -179,11 +176,12 @@ inline {{fieldType}}::Reader {{structName}}::Reader::get{{fieldTitleCase}}() {
// {{structName}}.{{fieldDecl}} // {{structName}}.{{fieldDecl}}
{{#fieldIsPrimitive}} {{#fieldIsPrimitive}}
inline {{fieldType}} {{structName}}::Builder::get{{fieldTitleCase}}() { inline {{fieldType}} {{structName}}::Builder::get{{fieldTitleCase}}() {
return _builder.getDataField<{{fieldType}}>({{fieldOffset}} * ::capnproto::ELEMENTS); return _builder.getDataField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::ELEMENTS{{fieldDefaultMask}});
} }
inline void {{structName}}::Builder::set{{fieldTitleCase}}({{fieldType}} value) { inline void {{structName}}::Builder::set{{fieldTitleCase}}({{fieldType}} value) {
return _builder.setDataField<{{fieldType}}>( return _builder.setDataField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::ELEMENTS, value); {{fieldOffset}} * ::capnproto::ELEMENTS, value{{fieldDefaultMask}});
} }
{{/fieldIsPrimitive}} {{/fieldIsPrimitive}}
{{#fieldIsBlob}} {{#fieldIsBlob}}
...@@ -205,14 +203,14 @@ inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(un ...@@ -205,14 +203,14 @@ inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(un
{{#fieldIsStruct}} {{#fieldIsStruct}}
inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}() { inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}() {
return {{fieldType}}::Builder(_builder.initStructField( return {{fieldType}}::Builder(_builder.initStructField(
{{fieldOffset}} * ::capnproto::REFERENCES, {{fieldType}}::DEFAULT.words)); {{fieldOffset}} * ::capnproto::REFERENCES, {{fieldType}}::STRUCT_SIZE));
} }
inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() { inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() {
{{! TODO: Support per-field default values. }} {{! TODO: Support per-field default values. }}
return {{fieldType}}::Builder(_builder.getStructField( return {{fieldType}}::Builder(_builder.getStructField(
{{fieldOffset}} * ::capnproto::REFERENCES, {{fieldOffset}} * ::capnproto::REFERENCES, {{fieldType}}::STRUCT_SIZE,
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}} {{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}{{fieldType}}::DEFAULT.words{{/fieldDefaultBytes}})); {{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
} }
{{/fieldIsStruct}} {{/fieldIsStruct}}
{{#fieldIsNonStructList}} {{#fieldIsNonStructList}}
...@@ -249,7 +247,7 @@ inline void {{structName}}::Builder::set{{fieldTitleCase}}( ...@@ -249,7 +247,7 @@ inline void {{structName}}::Builder::set{{fieldTitleCase}}(
inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(unsigned int size) { inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
return {{fieldType}}::Builder(_builder.initStructListField( return {{fieldType}}::Builder(_builder.initStructListField(
{{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::ELEMENTS, {{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::ELEMENTS,
{{fieldElementType}}::DEFAULT.words)); {{fieldElementType}}::STRUCT_SIZE));
} }
inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() { inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() {
return {{fieldType}}::Builder(_builder.getListField( return {{fieldType}}::Builder(_builder.getListField(
......
...@@ -32,13 +32,7 @@ namespace {{namespaceName}} { ...@@ -32,13 +32,7 @@ namespace {{namespaceName}} {
{{/fileNamespaces}} {{/fileNamespaces}}
{{#fileStructs}} {{#fileStructs}}
constexpr ::capnproto::WordCount {{structName}}::DATA_SIZE; constexpr ::capnproto::internal::StructSize {{structName}}::STRUCT_SIZE;
constexpr ::capnproto::WireReferenceCount {{structName}}::REFERENCE_COUNT;
{{#structDefault}}
const ::capnproto::internal::AlignedData<{{defaultWordCount}}> {{structName}}::DEFAULT = {
{ {{defaultByteList}} }
};
{{/structDefault}}
{{#structFields}} {{#structFields}}
{{#fieldDefaultBytes}} {{#fieldDefaultBytes}}
......
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