Commit 13ab0872 authored by Kenton Varda's avatar Kenton Varda

Compile inline lists (TODO: code generation).

parent 7f20d533
......@@ -161,7 +161,10 @@ lookupDesc scope name = lookupDesc (descParent scope) name
builtinTypeMap :: Map.Map String Desc
builtinTypeMap = Map.fromList
([(builtinTypeName t, DescBuiltinType t) | t <- builtinTypes] ++
[("List", DescBuiltinList), ("Inline", DescBuiltinInline), ("id", DescBuiltinId)])
[("List", DescBuiltinList),
("Inline", DescBuiltinInline),
("InlineList", DescBuiltinInlineList),
("id", DescBuiltinId)])
------------------------------------------------------------------------------------------
......@@ -246,6 +249,12 @@ compileValue pos (InlineStructType desc) v = compileValue pos (StructType desc)
compileValue _ (ListType t) (ListFieldValue l) =
fmap ListDesc (doAll [ compileValue vpos t v | Located vpos v <- l ])
compileValue pos (InlineListType t s) (ListFieldValue l) = do
elements <- doAll [ compileValue vpos t v | Located vpos v <- l ]
when (List.genericLength elements /= s) $
makeError pos $ printf "Fixed-size list must have exactly %d elements." s
return $ ListDesc elements
compileValue pos (BuiltinType BuiltinVoid) _ = makeError pos "Void fields cannot have values."
compileValue pos (BuiltinType BuiltinBool) _ = makeExpectError pos "boolean"
compileValue pos (BuiltinType BuiltinInt8) _ = makeExpectError pos "integer"
......@@ -263,9 +272,9 @@ compileValue pos (BuiltinType BuiltinData) _ = makeExpectError pos "string"
compileValue pos (EnumType _) _ = makeExpectError pos "enumerant name"
compileValue pos (StructType _) _ = makeExpectError pos "parenthesized list of field assignments"
compileValue pos (InlineStructType _) _ = makeExpectError pos "parenthesized list of field assignments"
compileValue pos (InterfaceType _) _ = makeError pos "Interfaces can't have default values."
compileValue pos (ListType _) _ = makeExpectError pos "list"
compileValue pos (InlineListType _ _) _ = makeExpectError pos "list"
descAsType _ (DescEnum desc) = succeed (EnumType desc)
descAsType _ (DescStruct desc) = succeed (StructType desc)
......@@ -276,33 +285,39 @@ descAsType name DescBuiltinList = makeError (declNamePos name) message where
message = printf "'List' requires exactly one type parameter." (declNameString name)
descAsType name DescBuiltinInline = makeError (declNamePos name) message where
message = printf "'Inline' requires exactly one type parameter." (declNameString name)
descAsType name DescBuiltinInlineList = makeError (declNamePos name) message where
message = printf "'InlineList' requires exactly one type parameter." (declNameString name)
descAsType name _ = makeError (declNamePos name) message where
message = printf "'%s' is not a type." (declNameString name)
compileType :: Desc -> TypeExpression -> Status TypeDesc
compileType scope (TypeExpression n []) = do
desc <- lookupDesc scope n
descAsType n desc
compileType scope (TypeExpression n (param:moreParams)) = do
compileType scope (TypeExpression n params) = do
desc <- lookupDesc scope n
case desc of
DescBuiltinList ->
if null moreParams
then fmap ListType (compileType scope param)
else makeError (declNamePos n) "'List' requires exactly one type parameter."
DescBuiltinInline ->
if null moreParams
then do
inner <- compileType scope param
case inner of
StructType s -> if structIsFixedWidth s
then return (InlineStructType s)
else makeError (declNamePos n) $
printf "'%s' cannot be inlined because it is not fixed-width."
(structName s)
_ -> makeError (declNamePos n) "'Inline' parameter must be a struct type."
else makeError (declNamePos n) "'Inline' requires exactly one type parameter."
_ -> makeError (declNamePos n) "Only the type 'List' can have type parameters."
DescBuiltinList -> case params of
[TypeParameterType param] -> fmap ListType (compileType scope param)
_ -> makeError (declNamePos n) "'List' requires exactly one type parameter."
DescBuiltinInline -> case params of
[TypeParameterType param] -> do
inner <- compileType scope param
case inner of
StructType s -> if structIsFixedWidth s
then return (InlineStructType s)
else makeError (declNamePos n) $
printf "'%s' cannot be inlined because it is not fixed-width."
(structName s)
_ -> makeError (declNamePos n) "'Inline' parameter must be a struct type."
_ -> makeError (declNamePos n) "'Inline' requires exactly one type parameter."
DescBuiltinInlineList -> case params of
[TypeParameterType param, TypeParameterInteger size] -> do
inner <- compileType scope param
return $ InlineListType inner size
_ -> makeError (declNamePos n)
"'InlineList' requires exactly two type parameters: a type and a size."
_ -> case params of
[] -> descAsType n desc
_ -> makeError (declNamePos n) $
printf "'%s' doesn't take parameters." (declNameString n)
compileAnnotation :: Desc -> AnnotationTarget -> Annotation
-> Status (Maybe AnnotationDesc, ValueDesc)
......
......@@ -91,6 +91,7 @@ isPrimitive (StructType _) = False
isPrimitive (InlineStructType _) = False
isPrimitive (InterfaceType _) = False
isPrimitive (ListType _) = False
isPrimitive (InlineListType _ _) = False
isBlob (BuiltinType BuiltinText) = True
isBlob (BuiltinType BuiltinData) = True
......@@ -254,7 +255,7 @@ fieldContext parent desc = mkStrContext context where
Nothing -> MuVariable ""
Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v)
context "fieldElementSize" =
MuVariable $ cxxFieldSizeString $ elementSize $ elementType $ fieldType desc
MuVariable $ cxxFieldSizeString $ fieldSize $ elementType $ fieldType desc
context "fieldElementType" =
MuVariable $ cxxTypeString $ elementType $ fieldType desc
context "fieldUnion" = case fieldUnion desc of
......
......@@ -38,12 +38,19 @@ declNameImport (RelativeName _) = Nothing
declNameImport (ImportName s) = Just s
declNameImport (MemberName parent _) = declNameImport parent
data TypeExpression = TypeExpression DeclName [TypeExpression]
data TypeParameter = TypeParameterType TypeExpression
| TypeParameterInteger Integer
deriving (Show)
data TypeExpression = TypeExpression DeclName [TypeParameter]
deriving (Show)
typeParameterImports :: TypeParameter -> [Located String]
typeParameterImports (TypeParameterType t) = typeImports t
typeParameterImports (TypeParameterInteger _) = []
typeImports :: TypeExpression -> [Located String]
typeImports (TypeExpression name params) =
maybeToList (declNameImport name) ++ concatMap typeImports params
maybeToList (declNameImport name) ++ concatMap typeParameterImports params
data Annotation = Annotation DeclName (Located FieldValue) deriving(Show)
......
......@@ -149,10 +149,14 @@ declName = do
members <- many (period >> located anyIdentifier)
return (foldl MemberName base members :: DeclName)
typeParameter :: TokenParser TypeParameter
typeParameter = liftM TypeParameterInteger literalInt
<|> liftM TypeParameterType typeExpression
typeExpression :: TokenParser TypeExpression
typeExpression = do
name <- declName
suffixes <- option [] (parenthesizedList typeExpression)
suffixes <- option [] (parenthesizedList typeParameter)
return (TypeExpression name suffixes)
nameWithOrdinal :: TokenParser (Located String, Located Integer)
......
......@@ -56,6 +56,7 @@ data Desc = DescFile FileDesc
| DescBuiltinType BuiltinType
| DescBuiltinList
| DescBuiltinInline
| DescBuiltinInlineList
| DescBuiltinId
descName (DescFile _) = "(top-level)"
......@@ -73,6 +74,7 @@ descName (DescAnnotation d) = annotationName d
descName (DescBuiltinType d) = builtinTypeName d
descName DescBuiltinList = "List"
descName DescBuiltinInline = "Inline"
descName DescBuiltinInlineList = "InlineList"
descName DescBuiltinId = "id"
descId (DescFile d) = fileId d
......@@ -90,6 +92,7 @@ descId (DescAnnotation d) = annotationId d
descId (DescBuiltinType _) = Nothing
descId DescBuiltinList = Nothing
descId DescBuiltinInline = Nothing
descId DescBuiltinInlineList = Nothing
descId DescBuiltinId = Just "0U0T3e_SnatEfk6UcH2tcjTt1E0"
-- Gets the ID if explicitly defined, or generates it by appending ".name" to the parent's ID.
......@@ -115,6 +118,7 @@ descParent (DescAnnotation d) = annotationParent d
descParent (DescBuiltinType _) = error "Builtin type has no parent."
descParent DescBuiltinList = error "Builtin type has no parent."
descParent DescBuiltinInline = error "Builtin type has no parent."
descParent DescBuiltinInlineList = error "Builtin type has no parent."
descParent DescBuiltinId = error "Builtin annotation has no parent."
descFile (DescFile d) = d
......@@ -135,6 +139,7 @@ descAnnotations (DescAnnotation d) = annotationAnnotations d
descAnnotations (DescBuiltinType _) = Map.empty
descAnnotations DescBuiltinList = Map.empty
descAnnotations DescBuiltinInline = Map.empty
descAnnotations DescBuiltinInlineList = Map.empty
descAnnotations DescBuiltinId = Map.empty
descRuntimeImports (DescFile _) = error "Not to be called on files."
......@@ -152,6 +157,7 @@ descRuntimeImports (DescAnnotation d) = annotationRuntimeImports d
descRuntimeImports (DescBuiltinType _) = []
descRuntimeImports DescBuiltinList = []
descRuntimeImports DescBuiltinInline = []
descRuntimeImports DescBuiltinInlineList = []
descRuntimeImports DescBuiltinId = []
type MemberMap = Map.Map String (Maybe Desc)
......@@ -221,6 +227,7 @@ data TypeDesc = BuiltinType BuiltinType
| InlineStructType StructDesc
| InterfaceType InterfaceDesc
| ListType TypeDesc
| InlineListType TypeDesc Integer
typeRuntimeImports (BuiltinType _) = []
typeRuntimeImports (EnumType d) = [descFile (DescEnum d)]
......@@ -228,6 +235,7 @@ typeRuntimeImports (StructType d) = [descFile (DescStruct d)]
typeRuntimeImports (InlineStructType d) = [descFile (DescStruct d)]
typeRuntimeImports (InterfaceType d) = [descFile (DescInterface d)]
typeRuntimeImports (ListType d) = typeRuntimeImports d
typeRuntimeImports (InlineListType d _) = typeRuntimeImports d
data DataSectionSize = DataSection1 | DataSection8 | DataSection16 | DataSection32
| DataSectionWords Integer
......@@ -310,19 +318,24 @@ fieldSize (InlineStructType StructDesc { structDataSize = ds, structPointerCount
SizeInlineComposite ds ps
fieldSize (InterfaceType _) = SizeReference
fieldSize (ListType _) = SizeReference
elementSize (StructType StructDesc { structDataSize = DataSection1, structPointerCount = 0 }) =
SizeData Size1
elementSize (StructType StructDesc { structDataSize = DataSection8, structPointerCount = 0 }) =
SizeData Size8
elementSize (StructType StructDesc { structDataSize = DataSection16, structPointerCount = 0 }) =
SizeData Size16
elementSize (StructType StructDesc { structDataSize = DataSection32, structPointerCount = 0 }) =
SizeData Size32
elementSize (StructType StructDesc { structDataSize = ds, structPointerCount = pc }) =
SizeInlineComposite ds pc
elementSize (InlineStructType s) = elementSize (StructType s)
elementSize t = fieldSize t
fieldSize (InlineListType element size) = let
minDataSectionForBits bits
| bits <= 1 = DataSection1
| bits <= 8 = DataSection8
| bits <= 16 = DataSection16
| bits <= 32 = DataSection32
| otherwise = DataSectionWords $ div (bits + 63) 64
dataSection = case fieldSize element of
SizeVoid -> DataSectionWords 0
SizeData s -> minDataSectionForBits $ dataSizeInBits s * size
SizeReference -> DataSectionWords 0
SizeInlineComposite ds _ -> minDataSectionForBits $ dataSectionBits ds
pointerCount = case fieldSize element of
SizeVoid -> 0
SizeData _ -> 0
SizeReference -> size
SizeInlineComposite _ pc -> pc
in SizeInlineComposite dataSection pointerCount
-- Render the type descriptor's name as a string, appropriate for use in the given scope.
typeName :: Desc -> TypeDesc -> String
......@@ -332,6 +345,7 @@ typeName scope (StructType desc) = descQualifiedName scope (DescStruct desc)
typeName scope (InlineStructType desc) = descQualifiedName scope (DescStruct desc)
typeName scope (InterfaceType desc) = descQualifiedName scope (DescInterface desc)
typeName scope (ListType t) = "List(" ++ typeName scope t ++ ")"
typeName scope (InlineListType t s) = printf "InlineList(%s, %d)" (typeName scope t) s
-- Computes the qualified name for the given descriptor within the given scope.
-- At present the scope is only used to determine whether the target is in the same file. If
......@@ -589,6 +603,7 @@ descToCode indent self@(DescAnnotation desc) = printf "%sannotation %s: %s on(%s
descToCode _ (DescBuiltinType _) = error "Can't print code for builtin type."
descToCode _ DescBuiltinList = error "Can't print code for builtin type."
descToCode _ DescBuiltinInline = error "Can't print code for builtin type."
descToCode _ DescBuiltinInlineList = error "Can't print code for builtin type."
descToCode _ DescBuiltinId = error "Can't print code for builtin annotation."
maybeBlockCode :: String -> [Desc] -> String
......
......@@ -66,13 +66,7 @@ encodeDataValue _ (Float64Desc v) = EncodedBytes $ bytes (doubleToWord v) 8
encodeDataValue _ (TextDesc _) = error "Not fixed-width data."
encodeDataValue _ (DataDesc _) = error "Not fixed-width data."
encodeDataValue _ (EnumerantValueDesc v) = EncodedBytes $ bytes (enumerantNumber v) 2
encodeDataValue (StructType desc) (StructValueDesc assignments) = let
(dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0
in if null refBytes && null childBytes
then EncodedBytes dataBytes
else error "encodeDataValue called on struct that wasn't plain data."
encodeDataValue (InlineStructType desc) v = encodeDataValue (StructType desc) v
encodeDataValue _ (StructValueDesc _) = error "Type/value mismatch."
encodeDataValue _ (StructValueDesc _) = error "Not fixed-width data."
encodeDataValue _ (ListDesc _) = error "Not fixed-width data."
encodeMaskedDataValue t v Nothing = encodeDataValue t v
......@@ -86,18 +80,19 @@ encodePointerValue _ (DataDesc d) =
(encodeListReference (SizeData Size8) (genericLength d), padToWord d)
encodePointerValue (StructType desc) (StructValueDesc assignments) = let
(dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0
in (encodeStructReference desc, concat [padToWord dataBytes, refBytes, childBytes])
encodePointerValue (InlineStructType desc) v = encodePointerValue (StructType desc) v
encodePointerValue (ListType elementType) (ListDesc items) =
(encodeListReference (elementSize elementType) (genericLength items),
encodeList elementType items)
in (encodeStructReference desc, concat [dataBytes, refBytes, childBytes])
encodePointerValue (InlineStructType _) _ =
error "Tried to encode inline struct as a pointer."
encodePointerValue (ListType elementType) (ListDesc items) = encodeList elementType items
encodePointerValue (InlineListType _ _) _ =
error "Tried to encode inline list as a pointer."
encodePointerValue _ _ = error "Unknown pointer type."
-- Given a sorted list of (bitOffset, data), pack into a byte array.
packBytes :: Integer -- Total size of array to pack, in bits.
-> [(Integer, EncodedData)] -- (offset, data) pairs to pack. Must be in order.
-> [Word8]
packBytes size = loop 0 where
packBytes size = padToWord . loop 0 where
loop :: Integer -> [(Integer, EncodedData)] -> [Word8]
loop bit [] | bit <= size = genericReplicate (div (size - bit + 7) 8) 0
loop bit [] | bit > size = error "Data values overran size."
......@@ -136,6 +131,13 @@ encodeStructReference desc offset =
bytes (dataSectionWordSize $ structDataSize desc) 2 ++
bytes (structPointerCount desc) 2
encodeInlineStructListReference elementDataSize elementPointerCount elementCount offset = let
dataBits = dataSectionBits elementDataSize * elementCount
dataWords = div (dataBits + 63) 64
in bytes (offset * 4 + structTag) 4 ++
bytes dataWords 2 ++
bytes (elementPointerCount * elementCount) 2
encodeListReference elemSize@(SizeInlineComposite ds rc) elementCount offset =
bytes (offset * 4 + listTag) 4 ++
bytes (fieldSizeEnum elemSize + shiftL (elementCount * (dataSectionWordSize ds + rc)) 3) 4
......@@ -179,73 +181,173 @@ structDataSectionValues assignments = let
encodeMaskedDataValue (fieldType f) v (fieldDefaultValue f))
| (f@FieldDesc { fieldOffset = DataOffset _ _ }, v) <- assignments]
inlineStructValues = do -- List monad!
(FieldDesc { fieldOffset = InlineCompositeOffset off _ sectionSize _ },
StructValueDesc v) <- assignments
inlineCompositeValues = do -- List monad!
(FieldDesc { fieldType = t
, fieldOffset = InlineCompositeOffset off _ sectionSize _ }, v) <- assignments
let bitOffset = off * dataSizeInBits (dataSectionAlignment sectionSize)
(pos, v2) <- structDataSectionValues v
(pos, v2) <- case (t, v) of
(InlineStructType _, StructValueDesc v2) -> structDataSectionValues v2
(InlineListType t2 _, ListDesc v2) -> inlineListDataSectionValues t2 v2
_ -> error "Non-inline-composite had inline-composite offset."
return (pos + bitOffset, v2)
unionTags = [(unionTagOffset u * 16,
encodeDataValue (BuiltinType BuiltinUInt16) (UInt16Desc $ fromIntegral n))
| (FieldDesc {fieldUnion = Just (u, n)}, _) <- assignments]
in simpleValues ++ inlineStructValues ++ unionTags
in simpleValues ++ inlineCompositeValues ++ unionTags
structPointerSectionValues :: [(FieldDesc, ValueDesc)] -> [(Integer, (Integer -> [Word8], [Word8]))]
structPointerSectionValues assignments = let
simpleValues = [(off, encodePointerValue (fieldType f) v)
| (f@FieldDesc { fieldOffset = PointerOffset off }, v) <- assignments]
inlineStructValues = do -- List monad!
(FieldDesc { fieldOffset = InlineCompositeOffset _ off _ _ },
StructValueDesc v) <- assignments
(pos, v2) <- structPointerSectionValues v
inlineCompositeValues = do -- List monad!
(FieldDesc { fieldType = t
, fieldOffset = InlineCompositeOffset _ off _ _ }, v) <- assignments
(pos, v2) <- case (t, v) of
(InlineStructType _, StructValueDesc v2) -> structPointerSectionValues v2
(InlineListType t2 _, ListDesc v2) -> inlineListPointerSectionValues t2 v2
_ -> error "Non-inline-composite had inline-composite offset."
return (pos + off, v2)
in simpleValues ++ inlineStructValues
in simpleValues ++ inlineCompositeValues
encodeList elementType elements = case elementSize elementType of
SizeVoid -> []
SizeInlineComposite _ _ -> let
handleStructType desc = let
count = genericLength elements
tag = encodeStructReference desc count
(elemBytes, childBytes) = encodeStructList 0 desc [v | StructValueDesc v <- elements]
in concat [tag, elemBytes, childBytes]
in case elementType of
StructType desc -> handleStructType desc
InlineStructType desc -> handleStructType desc
_ -> error "Only structs can be inline composites."
SizeReference -> refBytes ++ childBytes where
encodedElements = zip [0..] $ map (encodePointerValue elementType) elements
(refBytes, childBytes) = packPointers (genericLength elements) encodedElements 0
SizeData size -> let
bits = dataSizeInBits size
encodedElements = zip [0,bits..] $ map (encodeDataValue elementType) elements
in padToWord $ packBytes (genericLength elements * bits) encodedElements
------------------------------------------------------------------------------------------
encodeList :: TypeDesc -- Type of each element.
-> [ValueDesc] -- Element values.
-> (Integer -> [Word8], -- Encodes the pointer, given the offset.
[Word8]) -- Body bytes.
-- Encode a list of empty structs as void.
encodeList (StructType StructDesc {
structDataSize = DataSectionWords 0, structPointerCount = 0 }) elements =
(encodeListReference SizeVoid (genericLength elements), [])
-- Encode an inline-composite struct list. Not used in cases where the struct is data-only and
-- fits into 32 bits or less.
encodeStructList :: Integer -> StructDesc -> [[(FieldDesc, ValueDesc)]] -> ([Word8], [Word8])
encodeStructList o desc elements = loop (o + eSize * genericLength elements) elements where
-- Encode a list of sub-word data-only structs as a list of primitives.
encodeList (StructType desc@StructDesc { structDataSize = ds, structPointerCount = 0 }) elements
| dataSectionBits ds <= 64 = let
in (encodeListReference (SizeData $ dataSectionAlignment ds) (genericLength elements),
inlineStructListDataSection desc elements)
-- Encode a list of single-pointer structs as a list of pointers.
encodeList (StructType desc@StructDesc {
structDataSize = DataSectionWords 0, structPointerCount = 1 }) elements = let
(refBytes, childBytes) = inlineStructListPointerSection desc elements
in (encodeListReference SizeReference (genericLength elements), refBytes ++ childBytes)
-- Encode a list of any other sort of struct.
encodeList (StructType desc) elements = let
count = genericLength elements
tag = encodeStructReference desc count
eSize = dataSectionWordSize (structDataSize desc) + structPointerCount desc
structElems = [v | StructValueDesc v <- elements]
(elemBytes, childBytes) = loop (eSize * genericLength structElems) structElems
loop _ [] = ([], [])
loop offset (element:rest) = let
offsetFromElementEnd = offset - eSize
(dataBytes, refBytes, childBytes) = encodeStruct desc element offsetFromElementEnd
childLen = genericLength childBytes
(dataBytes, refBytes, childBytes2) = encodeStruct desc element offsetFromElementEnd
childLen = genericLength childBytes2
childWordLen = if mod childLen 8 == 0
then div childLen 8
else error "Child not word-aligned."
(restBytes, restChildren) = loop (offsetFromElementEnd + childWordLen) rest
in (padToWord dataBytes ++ refBytes ++ restBytes, childBytes ++ restChildren)
in (dataBytes ++ refBytes ++ restBytes, childBytes2 ++ restChildren)
in (encodeListReference (SizeInlineComposite (structDataSize desc) (structPointerCount desc))
(genericLength elements),
concat [tag, elemBytes, childBytes])
-- A list of inline structs is encoded into separate data and pointer sections, and the
-- pointer to it is actually a struct pointer.
encodeList (InlineStructType desc) elements = let
dataBytes = inlineStructListDataSection desc elements
(refBytes, childBytes) = inlineStructListPointerSection desc elements
in case (structDataSize desc, structPointerCount desc) of
(ds, 0) -> -- If only data, encode as a primitive list.
(encodeListReference (SizeData $ dataSectionAlignment ds)
(div (genericLength elements * dataSectionBits ds)
(dataSizeInBits (dataSectionAlignment ds))),
dataBytes)
(DataSectionWords 0, pc) -> -- If only pointers, encode as a pointer list.
(encodeListReference SizeReference (genericLength elements * pc),
refBytes ++ childBytes)
(ds, pc) -> -- Otherwise, encode as a struct.
(encodeInlineStructListReference ds pc (genericLength elements),
concat [dataBytes, refBytes, childBytes])
-- Encode a list of inline lists by just concatenating all the elements. The number of inner
-- lists can be determined at runtime by dividing the total size by the fixed inline list size.
encodeList (InlineListType t _) elements = encodeList t (concat [l | ListDesc l <- elements])
-- Encode primitive types.
encodeList elementType elements = let
eSize = fieldSize elementType
dataBytes = case eSize of
SizeVoid -> []
SizeInlineComposite _ _ -> error "All inline composites should have been handled above."
SizeReference -> refBytes ++ childBytes where
encodedElements = zip [0..] $ map (encodePointerValue elementType) elements
(refBytes, childBytes) = packPointers (genericLength elements) encodedElements 0
SizeData size -> let
bits = dataSizeInBits size
encodedElements = zip [0,bits..] $ map (encodeDataValue elementType) elements
in packBytes (genericLength elements * bits) encodedElements
in (encodeListReference eSize (genericLength elements), dataBytes)
---------------------------------------------
inlineListDataSectionValues elementType elements = case fieldSize elementType of
SizeVoid -> []
(SizeInlineComposite _ _) -> case elementType of
InlineStructType desc -> inlineStructListDataSectionValues desc elements
InlineListType t _ -> inlineListDataSectionValues t (concat [l | ListDesc l <- elements])
_ -> error "Unknown inline composite type."
SizeReference -> []
SizeData size -> let
bits = dataSizeInBits size
in zip [0,bits..] $ map (encodeDataValue elementType) elements
inlineListPointerSectionValues elementType elements = case fieldSize elementType of
SizeVoid -> []
(SizeInlineComposite _ _) -> case elementType of
InlineStructType desc -> inlineStructListPointerSectionValues desc elements
InlineListType t _ -> inlineListPointerSectionValues t (concat [l | ListDesc l <- elements])
_ -> error "Unknown inline composite type."
SizeReference -> zip [0..] $ map (encodePointerValue elementType) elements
SizeData _ -> []
inlineStructListDataSection elementDesc elements =
packBytes (genericLength elements * dataSectionBits (structDataSize elementDesc))
(sortBy (compare `on` fst) $ inlineStructListDataSectionValues elementDesc elements)
inlineStructListDataSectionValues elementDesc elements = do
let bits = dataSectionBits $ structDataSize elementDesc
(i, StructValueDesc e) <- zip [0..] elements
(off, v) <- structDataSectionValues e
return (off + bits * i, v)
inlineStructListPointerSection elementDesc elements =
packPointers
(genericLength elements * structPointerCount elementDesc)
(sortBy (compare `on` fst) $ inlineStructListPointerSectionValues elementDesc elements)
0
inlineStructListPointerSectionValues elementDesc elements = do
let ptrs = structPointerCount elementDesc
(i, StructValueDesc e) <- zip [0..] elements
(off, v) <- structPointerSectionValues e
return (off + ptrs * i, v)
------------------------------------------------------------------------------------------
encodeMessage (StructType desc) (StructValueDesc assignments) = let
(dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0
in concat [encodeStructReference desc (0::Integer), padToWord dataBytes, refBytes, childBytes]
in concat [encodeStructReference desc (0::Integer), dataBytes, refBytes, childBytes]
encodeMessage (InlineStructType desc) val = encodeMessage (StructType desc) val
encodeMessage (ListType elementType) (ListDesc elements) =
encodeListReference (elementSize elementType) (genericLength elements) (0::Integer) ++
encodeList elementType elements
encodeMessage (ListType elementType) (ListDesc elements) = let
(ptr, listBytes) = encodeList elementType elements
in ptr (0::Integer) ++ listBytes
encodeMessage (InlineListType elementType _) val = encodeMessage (ListType elementType) val
encodeMessage _ _ = error "Not a message."
......@@ -355,7 +355,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{/fieldIsInlineStruct}}
{{/fieldIsStruct}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsList}}
{{#fieldIsNonStructList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
......@@ -367,9 +367,7 @@ inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
}
{{/fieldIsList}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsNonStructList}}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
......@@ -423,6 +421,18 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
{{/fieldIsNonStructList}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsStructList}}
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.getListField(
{{fieldOffset}} * ::capnproto::REFERENCES,
::capnproto::internal::FieldSize::INLINE_COMPOSITE,
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
......
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