Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
13ab0872
Commit
13ab0872
authored
Apr 25, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Compile inline lists (TODO: code generation).
parent
7f20d533
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
242 additions
and
88 deletions
+242
-88
Compiler.hs
compiler/src/Compiler.hs
+30
-15
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+2
-1
Grammar.hs
compiler/src/Grammar.hs
+9
-2
Parser.hs
compiler/src/Parser.hs
+5
-1
Semantics.hs
compiler/src/Semantics.hs
+28
-13
WireFormat.hs
compiler/src/WireFormat.hs
+154
-52
c++-header.mustache
compiler/src/c++-header.mustache
+14
-4
No files found.
compiler/src/Compiler.hs
View file @
13ab0872
...
...
@@ -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,23 +285,20 @@ 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
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
...
...
@@ -301,8 +307,17 @@ compileType scope (TypeExpression n (param:moreParams)) = do
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."
_
->
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
)
...
...
compiler/src/CxxGenerator.hs
View file @
13ab0872
...
...
@@ -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
$
element
Size
$
elementType
$
fieldType
desc
MuVariable
$
cxxFieldSizeString
$
field
Size
$
elementType
$
fieldType
desc
context
"fieldElementType"
=
MuVariable
$
cxxTypeString
$
elementType
$
fieldType
desc
context
"fieldUnion"
=
case
fieldUnion
desc
of
...
...
compiler/src/Grammar.hs
View file @
13ab0872
...
...
@@ -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
type
Parameter
Imports
params
data
Annotation
=
Annotation
DeclName
(
Located
FieldValue
)
deriving
(
Show
)
...
...
compiler/src/Parser.hs
View file @
13ab0872
...
...
@@ -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
type
Expression
)
suffixes
<-
option
[]
(
parenthesizedList
type
Parameter
)
return
(
TypeExpression
name
suffixes
)
nameWithOrdinal
::
TokenParser
(
Located
String
,
Located
Integer
)
...
...
compiler/src/Semantics.hs
View file @
13ab0872
...
...
@@ -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
...
...
compiler/src/WireFormat.hs
View file @
13ab0872
...
...
@@ -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
]
inline
Struct
Values
=
do
-- List monad!
(
FieldDesc
{
field
Offset
=
InlineCompositeOffset
off
_
sectionSize
_
},
StructValueDesc
v
)
<-
assignments
inline
Composite
Values
=
do
-- List monad!
(
FieldDesc
{
field
Type
=
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
++
inline
Struct
Values
++
unionTags
in
simpleValues
++
inline
Composite
Values
++
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
++
inline
Struct
Values
in
simpleValues
++
inline
Composite
Values
encodeList
elementType
elements
=
case
elementSize
elementType
of
SizeVoid
->
[]
SizeInlineComposite
_
_
->
let
handleStructType
desc
=
let
------------------------------------------------------------------------------------------
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 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
(
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
-- 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
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
,
childBytes
2
)
=
encodeStruct
desc
element
offsetFromElementEnd
childLen
=
genericLength
childBytes
2
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."
compiler/src/c++-header.mustache
View file @
13ab0872
...
...
@@ -355,7 +355,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{/
fieldIsInlineStruct
}}
{{/
fieldIsStruct
}}
{{! ------------------------------------------------------------------------------------------- }}
{{#
fieldIsList
}}
{{#
fieldIs
NonStruct
List
}}
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>
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment