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
5f08f50d
Commit
5f08f50d
authored
Apr 26, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Get rid of stupid hacks to allow single-bit structs.
parent
dcfd0915
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
200 additions
and
259 deletions
+200
-259
encoding-test.c++
c++/src/capnproto/encoding-test.c++
+7
-47
layout-test.c++
c++/src/capnproto/layout-test.c++
+8
-8
layout.c++
c++/src/capnproto/layout.c++
+51
-43
layout.h
c++/src/capnproto/layout.h
+80
-98
test.capnp
c++/src/capnproto/test.capnp
+27
-35
Compiler.hs
compiler/src/Compiler.hs
+3
-3
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+9
-9
Parser.hs
compiler/src/Parser.hs
+3
-4
Semantics.hs
compiler/src/Semantics.hs
+4
-4
c++-header.mustache
compiler/src/c++-header.mustache
+8
-8
No files found.
c++/src/capnproto/encoding-test.c++
View file @
5f08f50d
...
...
@@ -294,7 +294,6 @@ TEST(Encoding, InlineStructUnionLayout) {
initUnion<TestInlineUnions>([](TestInlineUnions::Builder b) {b.setter;})
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
0
},
-
1
),
INIT_UNION
(
getUnion0
().
initF0
()));
EXPECT_EQ
(
UnionState
({
1
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF1
().
setF
(
1
)));
EXPECT_EQ
(
UnionState
({
2
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF8
().
setF0
(
true
)));
EXPECT_EQ
(
UnionState
({
3
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF16
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
4
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF32
().
setF0
(
1
)));
...
...
@@ -303,7 +302,6 @@ TEST(Encoding, InlineStructUnionLayout) {
EXPECT_EQ
(
UnionState
({
7
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF192
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
8
,
0
,
0
,
0
},
-
1
),
INIT_UNION
(
getUnion0
().
initF0p
().
initF
()));
EXPECT_EQ
(
UnionState
({
9
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF1p
().
initF
().
setF
(
1
)));
EXPECT_EQ
(
UnionState
({
10
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF8p
().
initF
().
setF0
(
true
)));
EXPECT_EQ
(
UnionState
({
11
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF16p
().
initF
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
12
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF32p
().
initF
().
setF0
(
1
)));
...
...
@@ -312,7 +310,6 @@ TEST(Encoding, InlineStructUnionLayout) {
EXPECT_EQ
(
UnionState
({
15
,
0
,
0
,
0
},
0
),
INIT_UNION
(
getUnion0
().
initF192p
().
initF
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
8
,
0
,
0
,
0
},
ptr
(
0
)),
INIT_UNION
(
getUnion0
().
initF0p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
9
,
0
,
0
,
0
},
ptr
(
0
)),
INIT_UNION
(
getUnion0
().
initF1p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
10
,
0
,
0
,
0
},
ptr
(
0
)),
INIT_UNION
(
getUnion0
().
initF8p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
11
,
0
,
0
,
0
},
ptr
(
0
)),
INIT_UNION
(
getUnion0
().
initF16p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
12
,
0
,
0
,
0
},
ptr
(
0
)),
INIT_UNION
(
getUnion0
().
initF32p
().
setP0
(
"1"
)));
...
...
@@ -321,7 +318,6 @@ TEST(Encoding, InlineStructUnionLayout) {
EXPECT_EQ
(
UnionState
({
15
,
0
,
0
,
0
},
ptr
(
0
)),
INIT_UNION
(
getUnion0
().
initF192p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
0
},
-
1
),
INIT_UNION
(
getUnion1
().
initF0
()));
EXPECT_EQ
(
UnionState
({
0
,
1
,
0
,
0
},
193
),
INIT_UNION
(
getUnion1
().
initF1
().
setF
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
2
,
0
,
0
},
200
),
INIT_UNION
(
getUnion1
().
initF8
().
setF0
(
true
)));
EXPECT_EQ
(
UnionState
({
0
,
3
,
0
,
0
},
208
),
INIT_UNION
(
getUnion1
().
initF16
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
4
,
0
,
0
},
224
),
INIT_UNION
(
getUnion1
().
initF32
().
setF0
(
1
)));
...
...
@@ -329,8 +325,6 @@ TEST(Encoding, InlineStructUnionLayout) {
EXPECT_EQ
(
UnionState
({
0
,
6
,
0
,
0
},
256
),
INIT_UNION
(
getUnion1
().
initF128
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
7
,
0
,
0
},
256
),
INIT_UNION
(
getUnion1
().
initF192
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
0
},
448
),
INIT_UNION
(
getUnion2
().
initF1p
().
initF
().
setF
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
0
},
449
),
INIT_UNION
(
getUnion3
().
initF1p
().
initF
().
setF
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
1
,
0
},
456
),
INIT_UNION
(
getUnion2
().
initF8p
().
initF
().
setF0
(
true
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
1
},
464
),
INIT_UNION
(
getUnion3
().
initF8p
().
initF
().
setF0
(
true
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
2
,
0
},
480
),
INIT_UNION
(
getUnion2
().
initF16p
().
initF
().
setF0
(
1
)));
...
...
@@ -344,8 +338,6 @@ TEST(Encoding, InlineStructUnionLayout) {
EXPECT_EQ
(
UnionState
({
0
,
0
,
6
,
0
},
960
),
INIT_UNION
(
getUnion2
().
initF192p
().
initF
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
6
},
1152
),
INIT_UNION
(
getUnion3
().
initF192p
().
initF
().
setF0
(
1
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
0
},
ptr
(
3
)),
INIT_UNION
(
getUnion2
().
initF1p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
0
},
ptr
(
4
)),
INIT_UNION
(
getUnion3
().
initF1p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
1
,
0
},
ptr
(
3
)),
INIT_UNION
(
getUnion2
().
initF8p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
0
,
1
},
ptr
(
4
)),
INIT_UNION
(
getUnion3
().
initF8p
().
setP0
(
"1"
)));
EXPECT_EQ
(
UnionState
({
0
,
0
,
2
,
0
},
ptr
(
5
)),
INIT_UNION
(
getUnion2
().
initF16p
().
setP0
(
"1"
)));
...
...
@@ -367,9 +359,7 @@ TEST(Encoding, InitInlineStruct) {
auto
root
=
builder
.
getRoot
<
TestInlineLayout
>
();
// Set as many bits as we can.
root
.
initF1
().
setF
(
true
);
root
.
initF1Offset
().
setF
(
true
);
root
.
setBit
(
true
);
root
.
setPad1
(
0xffu
);
root
.
initF8
().
setF0
(
true
);
root
.
getF8
().
setF1
(
true
);
root
.
getF8
().
setF2
(
true
);
...
...
@@ -386,8 +376,8 @@ TEST(Encoding, InitInlineStruct) {
root
.
getF192
().
setF2
(
0xffffffffffffffffull
);
root
.
initF0p
().
setP0
(
"foo"
);
root
.
initF1p
().
setP0
(
"foo"
);
root
.
getF1p
().
initF
().
setF
(
true
);
root
.
setPad2
(
0xffu
);
root
.
setPadP
(
"foo"
);
root
.
initF8p
().
setP0
(
"foo"
);
root
.
initF16p
().
setP0
(
"foo"
);
root
.
getF16p
().
setP1
(
"foo"
);
...
...
@@ -403,21 +393,10 @@ TEST(Encoding, InitInlineStruct) {
root
.
getF192p
().
setP2
(
"foo"
);
// Now try re-initializing each thing and making sure the surrounding things aren't modified.
EXPECT_FALSE
(
root
.
initF1
().
getF
());
EXPECT_TRUE
(
root
.
getF1Offset
().
getF
());
root
.
getF1
().
setF
(
true
);
EXPECT_FALSE
(
root
.
initF1Offset
().
getF
());
EXPECT_TRUE
(
root
.
getF1
().
getF
());
EXPECT_TRUE
(
root
.
getBit
());
EXPECT_TRUE
(
root
.
getF8
().
getF0
());
root
.
getF1Offset
().
setF
(
true
);
EXPECT_FALSE
(
root
.
initF8
().
getF0
());
EXPECT_FALSE
(
root
.
getF8
().
getF1
());
EXPECT_FALSE
(
root
.
getF8
().
getF2
());
EXPECT_TRUE
(
root
.
getF1
().
getF
());
EXPECT_TRUE
(
root
.
getBit
());
EXPECT_EQ
(
0xffu
,
root
.
getPad1
());
EXPECT_EQ
(
0xffu
,
root
.
getF16
().
getF0
());
root
.
initF8
().
setF0
(
true
);
root
.
getF8
().
setF1
(
true
);
...
...
@@ -461,22 +440,17 @@ TEST(Encoding, InitInlineStruct) {
EXPECT_EQ
(
0u
,
root
.
getF192
().
getF2
());
EXPECT_EQ
(
0xffffffffffffffffull
,
root
.
getF128
().
getF0
());
EXPECT_EQ
(
0xffffffffffffffffull
,
root
.
getF128
().
getF1
());
EXPECT_
TRUE
(
root
.
getF1p
().
getF
().
getF
());
EXPECT_
EQ
(
0xffu
,
root
.
getPad2
());
root
.
getF192
().
setF0
(
0xffffffffffffffffull
);
root
.
getF192
().
setF1
(
0xffffffffffffffffull
);
root
.
getF192
().
setF2
(
0xffffffffffffffffull
);
EXPECT_EQ
(
""
,
root
.
initF0p
().
getP0
());
EXPECT_EQ
(
"foo"
,
root
.
get
F1p
().
getP0
());
EXPECT_EQ
(
"foo"
,
root
.
get
PadP
());
root
.
getF0p
().
setP0
(
"foo"
);
EXPECT_EQ
(
""
,
root
.
initF1p
().
getP0
());
EXPECT_EQ
(
"foo"
,
root
.
getF0p
().
getP0
());
EXPECT_EQ
(
"foo"
,
root
.
getF8p
().
getP0
());
root
.
getF1p
().
setP0
(
"foo"
);
EXPECT_EQ
(
""
,
root
.
initF8p
().
getP0
());
EXPECT_EQ
(
"foo"
,
root
.
get
F1p
().
getP0
());
EXPECT_EQ
(
"foo"
,
root
.
get
PadP
());
EXPECT_EQ
(
"foo"
,
root
.
getF16p
().
getP0
());
root
.
initF8p
().
setP0
(
"foo"
);
...
...
@@ -525,7 +499,6 @@ TEST(Encoding, InlineDefaults) {
{
auto
normal
=
reader
.
getNormal
();
EXPECT_TRUE
(
normal
.
getF1
().
getF
());
EXPECT_TRUE
(
normal
.
getF8
().
getF0
());
EXPECT_FALSE
(
normal
.
getF8
().
getF1
());
EXPECT_TRUE
(
normal
.
getF8
().
getF2
());
...
...
@@ -541,7 +514,6 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ
(
2345678901234ull
,
normal
.
getF192
().
getF1
());
EXPECT_EQ
(
5678901234567ull
,
normal
.
getF192
().
getF2
());
EXPECT_FALSE
(
normal
.
getF1p
().
getF
().
getF
());
EXPECT_TRUE
(
normal
.
getF8p
().
getF
().
getF0
());
EXPECT_TRUE
(
normal
.
getF8p
().
getF
().
getF1
());
EXPECT_FALSE
(
normal
.
getF8p
().
getF
().
getF2
());
...
...
@@ -558,7 +530,6 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ
(
5432109876543ull
,
normal
.
getF192p
().
getF
().
getF2
());
EXPECT_EQ
(
"foo"
,
normal
.
getF0p
().
getP0
());
EXPECT_EQ
(
"bar"
,
normal
.
getF1p
().
getP0
());
EXPECT_EQ
(
"baz"
,
normal
.
getF8p
().
getP0
());
EXPECT_EQ
(
"qux"
,
normal
.
getF16p
().
getP0
());
EXPECT_EQ
(
"quux"
,
normal
.
getF16p
().
getP1
());
...
...
@@ -585,9 +556,6 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ
(
1234567890123ull
,
unions
.
getUnion1
().
getF128
().
getF0
());
EXPECT_EQ
(
4567890123456ull
,
unions
.
getUnion1
().
getF128
().
getF1
());
ASSERT_EQ
(
TestInlineUnions
::
Union2
::
F1P
,
unions
.
getUnion2
().
which
());
EXPECT_EQ
(
"foo"
,
unions
.
getUnion2
().
getF1p
().
getP0
());
ASSERT_EQ
(
TestInlineUnions
::
Union3
::
F16P
,
unions
.
getUnion3
().
which
());
EXPECT_EQ
(
98u
,
unions
.
getUnion3
().
getF16p
().
getF
().
getF0
());
EXPECT_EQ
(
76u
,
unions
.
getUnion3
().
getF16p
().
getF
().
getF1
());
...
...
@@ -659,10 +627,6 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ
(
Void
::
VOID
,
lists
.
getStructList0
()[
0
].
getF
());
EXPECT_EQ
(
Void
::
VOID
,
lists
.
getStructList0
()[
1
].
getF
());
EXPECT_TRUE
(
lists
.
getStructList1
()[
0
].
getF
());
EXPECT_FALSE
(
lists
.
getStructList1
()[
1
].
getF
());
// EXPECT_TRUE(lists.getStructList1()[2].getF());
EXPECT_TRUE
(
lists
.
getStructList8
()[
0
].
getF0
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
0
].
getF1
());
EXPECT_FALSE
(
lists
.
getStructList8
()[
0
].
getF2
());
...
...
@@ -717,10 +681,6 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ
(
"baz"
,
lists
.
getStructList0p
()[
2
].
getP0
());
EXPECT_EQ
(
"qux"
,
lists
.
getStructList0p
()[
3
].
getP0
());
EXPECT_TRUE
(
lists
.
getStructList1p
()[
0
].
getF
().
getF
());
EXPECT_EQ
(
"quux"
,
lists
.
getStructList1p
()[
0
].
getP0
());
EXPECT_EQ
(
"corge"
,
lists
.
getStructList1p
()[
1
].
getP0
());
EXPECT_TRUE
(
lists
.
getStructList8p
()[
0
].
getF
().
getF0
());
EXPECT_EQ
(
"grault"
,
lists
.
getStructList8p
()[
0
].
getP0
());
EXPECT_EQ
(
"garply"
,
lists
.
getStructList8p
()[
1
].
getP0
());
...
...
c++/src/capnproto/layout-test.c++
View file @
5f08f50d
...
...
@@ -102,7 +102,7 @@ static const AlignedData<2> SUBSTRUCT_DEFAULT = {{0,0,0,0,1,0,0,0, 0,0,0,0,0,0,
static
const
AlignedData
<
2
>
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
=
{{
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}};
static
constexpr
StructSize
STRUCTLIST_ELEMENT_SIZE
(
1
*
WORDS
,
1
*
REFERENCES
,
64
*
BIT
S
);
static
constexpr
StructSize
STRUCTLIST_ELEMENT_SIZE
(
1
*
WORDS
,
1
*
REFERENCES
,
8
*
BYTE
S
);
static
void
setupStruct
(
StructBuilder
builder
)
{
builder
.
setDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
0x1011121314151617ull
);
...
...
@@ -120,7 +120,7 @@ static void setupStruct(StructBuilder builder) {
{
StructBuilder
subStruct
=
builder
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BIT
S
));
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
8
*
BYTE
S
));
subStruct
.
setDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
123
);
}
...
...
@@ -139,7 +139,7 @@ static void setupStruct(StructBuilder builder) {
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
element
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
300
+
i
);
element
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BIT
S
))
element
.
initStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
8
*
BYTE
S
))
.
setDataField
<
int32_t
>
(
0
*
ELEMENTS
,
400
+
i
);
}
}
...
...
@@ -174,7 +174,7 @@ static void checkStruct(StructBuilder builder) {
{
StructBuilder
subStruct
=
builder
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BIT
S
),
SUBSTRUCT_DEFAULT
.
words
);
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
8
*
BYTE
S
),
SUBSTRUCT_DEFAULT
.
words
);
EXPECT_EQ
(
123u
,
subStruct
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
));
}
...
...
@@ -193,7 +193,7 @@ static void checkStruct(StructBuilder builder) {
StructBuilder
element
=
list
.
getStructElement
(
i
*
ELEMENTS
,
STRUCTLIST_ELEMENT_SIZE
);
EXPECT_EQ
(
300
+
i
,
element
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
EXPECT_EQ
(
400
+
i
,
element
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
64
*
BIT
S
),
element
.
getStructField
(
0
*
REFERENCES
,
StructSize
(
1
*
WORDS
,
0
*
REFERENCES
,
8
*
BYTE
S
),
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT
.
words
)
.
getDataField
<
int32_t
>
(
0
*
ELEMENTS
));
}
...
...
@@ -272,7 +272,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
1
28
*
BIT
S
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
1
6
*
BYTE
S
));
setupStruct
(
builder
);
// word count:
...
...
@@ -308,7 +308,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
1
28
*
BIT
S
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
1
6
*
BYTE
S
));
setupStruct
(
builder
);
// Verify that we made 15 segments.
...
...
@@ -345,7 +345,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
word
*
rootLocation
=
segment
->
allocate
(
1
*
WORDS
);
StructBuilder
builder
=
StructBuilder
::
initRoot
(
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
1
28
*
BIT
S
));
segment
,
rootLocation
,
StructSize
(
2
*
WORDS
,
4
*
REFERENCES
,
1
6
*
BYTE
S
));
setupStruct
(
builder
);
// Verify that we made 6 segments.
...
...
c++/src/capnproto/layout.c++
View file @
5f08f50d
...
...
@@ -415,7 +415,7 @@ struct WireHelpers {
ref
->
structRef
.
set
(
size
);
// Build the StructBuilder.
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
0
*
BITS
,
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
size
.
pointers
);
}
...
...
@@ -443,7 +443,7 @@ struct WireHelpers {
"Trying to update struct with incorrect reference count."
);
}
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
0
*
BITS
,
return
StructBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
size
.
data
),
size
.
pointers
);
}
...
...
@@ -466,7 +466,7 @@ struct WireHelpers {
// Build the ListBuilder.
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
),
step
,
step
/
BITS_PER_REFERENCE
,
elementCount
);
step
/
BITS_PER_BYTE
,
step
/
BITS_PER_REFERENCE
,
elementCount
);
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initStructListReference
(
...
...
@@ -479,13 +479,12 @@ struct WireHelpers {
if
(
elementSize
.
pointers
==
1
*
REFERENCES
)
{
primitiveElementSize
=
FieldSize
::
REFERENCE
;
}
else
{
switch
(
elementSize
.
dataB
its
/
BIT
S
)
{
switch
(
elementSize
.
dataB
ytes
/
BYTE
S
)
{
case
0
:
primitiveElementSize
=
FieldSize
::
VOID
;
break
;
case
1
:
primitiveElementSize
=
FieldSize
::
BIT
;
break
;
case
8
:
primitiveElementSize
=
FieldSize
::
BYTE
;
break
;
case
16
:
primitiveElementSize
=
FieldSize
::
TWO_BYTES
;
break
;
case
32
:
primitiveElementSize
=
FieldSize
::
FOUR_BYTES
;
break
;
case
64
:
primitiveElementSize
=
FieldSize
::
EIGHT_BYTES
;
break
;
case
1
:
primitiveElementSize
=
FieldSize
::
BYTE
;
break
;
case
2
:
primitiveElementSize
=
FieldSize
::
TWO_BYTES
;
break
;
case
4
:
primitiveElementSize
=
FieldSize
::
FOUR_BYTES
;
break
;
case
8
:
primitiveElementSize
=
FieldSize
::
EIGHT_BYTES
;
break
;
default
:
FAIL_PRECOND
(
"Invalid struct size."
);
break
;
}
}
...
...
@@ -510,7 +509,7 @@ struct WireHelpers {
// Build the ListBuilder.
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
+
elementSize
.
data
),
wordsPerElement
*
B
IT
S_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
wordsPerElement
*
B
YTE
S_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
elementCount
);
}
...
...
@@ -521,7 +520,7 @@ struct WireHelpers {
if
(
ref
->
isNull
())
{
if
(
defaultValue
==
nullptr
)
{
return
ListBuilder
(
segment
,
nullptr
,
nullptr
,
0
*
B
IT
S
/
ELEMENTS
,
return
ListBuilder
(
segment
,
nullptr
,
nullptr
,
0
*
B
YTE
S
/
ELEMENTS
,
0
*
REFERENCES
/
ELEMENTS
,
0
*
ELEMENTS
);
}
ptr
=
copyMessage
(
segment
,
ref
,
defaultRef
);
...
...
@@ -543,12 +542,12 @@ struct WireHelpers {
WireReference
*
pointers
=
reinterpret_cast
<
WireReference
*>
(
data
+
tag
->
structRef
.
dataSize
.
get
());
auto
step
=
tag
->
structRef
.
wordSize
()
/
ELEMENTS
;
return
ListBuilder
(
segment
,
data
,
pointers
,
step
*
B
IT
S_PER_WORD
,
step
/
WORDS_PER_REFERENCE
,
return
ListBuilder
(
segment
,
data
,
pointers
,
step
*
B
YTE
S_PER_WORD
,
step
/
WORDS_PER_REFERENCE
,
tag
->
inlineCompositeListElementCount
());
}
else
{
decltype
(
BITS
/
ELEMENTS
)
step
=
bit
sPerElement
(
ref
->
listRef
.
elementSize
());
auto
step
=
byte
sPerElement
(
ref
->
listRef
.
elementSize
());
return
ListBuilder
(
segment
,
ptr
,
reinterpret_cast
<
WireReference
*>
(
ptr
),
step
,
step
/
B
IT
S_PER_REFERENCE
,
step
,
step
/
B
YTE
S_PER_REFERENCE
,
ref
->
listRef
.
elementCount
());
}
}
...
...
@@ -637,7 +636,7 @@ struct WireHelpers {
if
(
ref
==
nullptr
||
ref
->
isNull
())
{
useDefault
:
if
(
defaultValue
==
nullptr
)
{
return
StructReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
B
ITS
,
0
*
REFERENCES
,
0
*
BIT
S
,
return
StructReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
B
YTES
,
0
*
REFERENCE
S
,
std
::
numeric_limits
<
int
>::
max
());
}
segment
=
nullptr
;
...
...
@@ -671,9 +670,9 @@ struct WireHelpers {
return
StructReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
+
ref
->
structRef
.
dataSize
.
get
()),
ref
->
structRef
.
dataSize
.
get
()
*
B
IT
S_PER_WORD
,
ref
->
structRef
.
dataSize
.
get
()
*
B
YTE
S_PER_WORD
,
ref
->
structRef
.
refCount
.
get
(),
0
*
BITS
,
nestingLimit
-
1
);
nestingLimit
-
1
);
}
static
CAPNPROTO_ALWAYS_INLINE
(
ListReader
readListReference
(
...
...
@@ -684,7 +683,7 @@ struct WireHelpers {
useDefault
:
if
(
defaultValue
==
nullptr
)
{
return
ListReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
ELEMENTS
,
0
*
B
IT
S
/
ELEMENTS
,
0
*
REFERENCES
/
ELEMENTS
,
0
*
B
YTE
S
/
ELEMENTS
,
0
*
REFERENCES
/
ELEMENTS
,
nestingLimit
-
1
);
}
segment
=
nullptr
;
...
...
@@ -751,6 +750,11 @@ struct WireHelpers {
break
;
case
FieldSize
:
:
BIT
:
FAIL_VALIDATE_INPUT
(
"Expected a bit list, but got a list of structs."
)
{
goto
useDefault
;
}
break
;
case
FieldSize
:
:
BYTE
:
case
FieldSize
:
:
TWO_BYTES
:
case
FieldSize
:
:
FOUR_BYTES
:
...
...
@@ -790,13 +794,13 @@ struct WireHelpers {
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
+
tag
->
structRef
.
dataSize
.
get
()),
size
,
wordsPerElement
*
B
IT
S_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
tag
->
structRef
.
dataSize
.
get
()
*
B
IT
S_PER_WORD
,
size
,
wordsPerElement
*
B
YTE
S_PER_WORD
,
wordsPerElement
/
WORDS_PER_REFERENCE
,
tag
->
structRef
.
dataSize
.
get
()
*
B
YTE
S_PER_WORD
,
tag
->
structRef
.
refCount
.
get
(),
nestingLimit
-
1
);
}
else
{
// The elements of the list are NOT structs.
decltype
(
BITS
/
ELEMENTS
)
step
=
bitsPerElement
(
ref
->
listRef
.
elementSize
());
auto
step
=
bitsPerElement
(
ref
->
listRef
.
elementSize
());
if
(
segment
!=
nullptr
)
{
VALIDATE_INPUT
(
segment
->
containsInterval
(
ptr
,
ptr
+
...
...
@@ -808,34 +812,39 @@ struct WireHelpers {
if
(
ref
->
listRef
.
elementSize
()
==
expectedElementSize
)
{
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
),
ref
->
listRef
.
elementCount
(),
step
,
step
/
BITS_PER_REFERENC
E
,
nestingLimit
-
1
);
ref
->
listRef
.
elementCount
(),
step
/
BITS_PER_BYT
E
,
step
/
BITS_PER_REFERENCE
,
nestingLimit
-
1
);
}
else
if
(
expectedElementSize
==
FieldSize
::
INLINE_COMPOSITE
)
{
// We were expecting a struct list, but we received a list of some other type. Perhaps a
// non-struct list was recently upgraded to a struct list, but the sender is using the
// old version of the protocol. We need to verify that the struct's first field matches
// what the sender sent us.
B
itCount
dataSize
=
0
*
BIT
S
;
B
yteCount
dataSize
=
0
*
BYTE
S
;
WireReferenceCount
referenceCount
=
0
*
REFERENCES
;
switch
(
ref
->
listRef
.
elementSize
())
{
case
FieldSize
:
:
VOID
:
break
;
case
FieldSize
:
:
BIT
:
dataSize
=
1
*
BITS
;
break
;
case
FieldSize
:
:
BYTE
:
dataSize
=
8
*
BITS
;
break
;
case
FieldSize
:
:
TWO_BYTES
:
dataSize
=
16
*
BITS
;
break
;
case
FieldSize
:
:
FOUR_BYTES
:
dataSize
=
32
*
BITS
;
break
;
case
FieldSize
:
:
EIGHT_BYTES
:
dataSize
=
64
*
BITS
;
break
;
case
FieldSize
:
:
BYTE
:
dataSize
=
1
*
BYTES
;
break
;
case
FieldSize
:
:
TWO_BYTES
:
dataSize
=
2
*
BYTES
;
break
;
case
FieldSize
:
:
FOUR_BYTES
:
dataSize
=
4
*
BYTES
;
break
;
case
FieldSize
:
:
EIGHT_BYTES
:
dataSize
=
8
*
BYTES
;
break
;
case
FieldSize
:
:
REFERENCE
:
referenceCount
=
1
*
REFERENCES
;
break
;
case
FieldSize
:
:
BIT
:
FAIL_VALIDATE_INPUT
(
"Message contained a bit list where a struct list was expected."
)
{
dataSize
=
0
*
BYTES
;
}
break
;
case
FieldSize
:
:
INLINE_COMPOSITE
:
FAIL_CHECK
();
break
;
}
return
ListReader
(
segment
,
ptr
,
reinterpret_cast
<
const
WireReference
*>
(
ptr
),
ref
->
listRef
.
elementCount
(),
step
,
step
/
BITS_PER_REFERENC
E
,
dataSize
,
referenceCount
,
nestingLimit
-
1
);
ref
->
listRef
.
elementCount
(),
step
/
BITS_PER_BYT
E
,
step
/
BITS_PER_REFERENCE
,
dataSize
,
referenceCount
,
nestingLimit
-
1
);
}
else
{
PRECOND
(
segment
!=
nullptr
,
"Trusted message had incompatible list element type."
);
goto
useDefault
;
...
...
@@ -1010,7 +1019,7 @@ StructReader StructBuilder::asReader() const {
static_assert
(
sizeof
(
WireReference
::
structRef
.
refCount
)
==
2
,
"Has the maximum reference count changed?"
);
return
StructReader
(
segment
,
data
,
references
,
0xffffffff
*
B
ITS
,
0xffff
*
REFERENCES
,
0
*
BIT
S
,
std
::
numeric_limits
<
int
>::
max
());
0xffffffff
*
B
YTES
,
0xffff
*
REFERENCE
S
,
std
::
numeric_limits
<
int
>::
max
());
}
StructReader
StructReader
::
readRootTrusted
(
const
word
*
location
)
{
...
...
@@ -1030,7 +1039,7 @@ StructReader StructReader::readRoot(
}
StructReader
StructReader
::
readEmpty
()
{
return
StructReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
B
ITS
,
0
*
REFERENCES
,
0
*
BIT
S
,
return
StructReader
(
nullptr
,
nullptr
,
nullptr
,
0
*
B
YTES
,
0
*
REFERENCE
S
,
std
::
numeric_limits
<
int
>::
max
());
}
...
...
@@ -1061,11 +1070,10 @@ Data::Reader StructReader::getDataField(
StructBuilder
ListBuilder
::
getStructElement
(
ElementCount
index
,
StructSize
elementSize
)
const
{
// TODO: Inline this method?
B
itCount64
indexBit
=
ElementCount64
(
index
)
*
stepBit
s
;
byte
*
structData
=
reinterpret_cast
<
byte
*>
(
data
)
+
indexB
it
/
BITS_PER_BYTE
;
B
yteCount
indexByte
=
ElementCount64
(
index
)
*
stepByte
s
;
byte
*
structData
=
reinterpret_cast
<
byte
*>
(
data
)
+
indexB
yte
;
WireReference
*
structPointers
=
pointers
+
index
*
stepPointers
;
return
StructBuilder
(
segment
,
structData
,
structPointers
,
indexBit
%
BITS_PER_BYTE
,
elementSize
.
pointers
);
return
StructBuilder
(
segment
,
structData
,
structPointers
,
elementSize
.
pointers
);
}
ListBuilder
ListBuilder
::
initListElement
(
...
...
@@ -1117,13 +1125,13 @@ ListReader ListBuilder::asReader(FieldSize elementSize) const {
// TODO: For INLINE_COMPOSITE I suppose we could just check the tag?
PRECOND
(
elementSize
!=
FieldSize
::
INLINE_COMPOSITE
,
"Need to call the other asReader() overload for INLINE_COMPOSITE lists."
);
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepB
it
s
,
stepPointers
,
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepB
yte
s
,
stepPointers
,
std
::
numeric_limits
<
int
>::
max
());
}
ListReader
ListBuilder
::
asReader
(
StructSize
elementSize
)
const
{
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepB
it
s
,
stepPointers
,
elementSize
.
dataB
it
s
,
elementSize
.
pointers
,
std
::
numeric_limits
<
int
>::
max
());
return
ListReader
(
segment
,
data
,
pointers
,
elementCount
,
stepB
yte
s
,
stepPointers
,
elementSize
.
dataB
yte
s
,
elementSize
.
pointers
,
std
::
numeric_limits
<
int
>::
max
());
}
StructReader
ListReader
::
getStructElement
(
ElementCount
index
)
const
{
...
...
@@ -1133,11 +1141,11 @@ StructReader ListReader::getStructElement(ElementCount index) const {
return
StructReader
::
readEmpty
();
}
B
itCount64
indexBit
=
ElementCount64
(
index
)
*
stepBit
s
;
const
byte
*
structData
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
indexB
it
/
BITS_PER_BYTE
;
B
yteCount
indexByte
=
index
*
stepByte
s
;
const
byte
*
structData
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
indexB
yte
;
return
StructReader
(
segment
,
structData
,
pointers
+
index
*
stepPointers
,
structDataSize
,
structReferenceCount
,
indexBit
%
BITS_PER_BYTE
,
nestingLimit
-
1
);
structDataSize
,
structReferenceCount
,
nestingLimit
-
1
);
}
ListReader
ListReader
::
getListElement
(
...
...
c++/src/capnproto/layout.h
View file @
5f08f50d
...
...
@@ -101,6 +101,7 @@ enum class FieldSize: uint8_t {
};
typedef
decltype
(
BITS
/
ELEMENTS
)
BitsPerElement
;
typedef
decltype
(
BYTES
/
ELEMENTS
)
BytesPerElement
;
namespace
internal
{
static
constexpr
BitsPerElement
BITS_PER_ELEMENT_TABLE
[
8
]
=
{
...
...
@@ -119,6 +120,13 @@ inline constexpr BitsPerElement bitsPerElement(FieldSize size) {
return
internal
::
BITS_PER_ELEMENT_TABLE
[
static_cast
<
int
>
(
size
)];
}
inline
constexpr
BytesPerElement
bytesPerElement
(
FieldSize
size
)
{
// BIT gets rounded down to zero bytes. This is OK because bytesPerElement() is only used in
// cases where this doesn't matter, e.g. for computing stepBytes which is ignored by bit ops
// anyway.
return
bitsPerElement
(
size
)
/
BITS_PER_BYTE
;
}
template
<
int
wordCount
>
union
AlignedData
{
// Useful for declaring static constant data blobs as an array of bytes, but forcing those
...
...
@@ -132,15 +140,15 @@ struct StructSize {
WordCount16
data
;
WireReferenceCount16
pointers
;
B
itCount32
dataBit
s
;
//
If data == 1 word, dataBits may be 1, 8, 16, 32, or 64. Otherwise, it is data * BITS_PER_WORD.
//
This is used when packing inline structs
.
B
yteCount32
dataByte
s
;
//
Number of bytes in the data section. Must be data * 8 except when data == 1 in which case
//
this can be 1, 2, 4, or 8
.
inline
constexpr
WordCount
total
()
const
{
return
data
+
pointers
*
WORDS_PER_REFERENCE
;
}
StructSize
()
=
default
;
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
,
B
itCount
dataBit
s
)
:
data
(
data
),
pointers
(
pointers
),
dataB
its
(
dataBit
s
)
{}
inline
constexpr
StructSize
(
WordCount
data
,
WireReferenceCount
pointers
,
B
yteCount
dataByte
s
)
:
data
(
data
),
pointers
(
pointers
),
dataB
ytes
(
dataByte
s
)
{}
};
template
<
typename
T
>
...
...
@@ -286,13 +294,13 @@ public:
// or to the empty state if defaultValue is nullptr.
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
initInlineStructField
(
B
itCount
dataOffset
,
Bit
Count
inlineDataSize
,
B
yteCount
dataOffset
,
Byte
Count
inlineDataSize
,
WireReferenceCount
refIndex
,
WireReferenceCount
inlineRefCount
)
const
);
// Initialize an inlined struct field, given the position and size of the data and pointer
// sections.
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getInlineStructField
(
B
itCount
dataOffset
,
Bit
Count
inlineDataSize
,
B
yteCount
dataOffset
,
Byte
Count
inlineDataSize
,
WireReferenceCount
refIndex
,
WireReferenceCount
inlineRefCount
)
const
);
// Gets an inlined struct field, given the position and size of the data and pointer sections.
...
...
@@ -312,7 +320,7 @@ public:
// message). If the default value is null, an empty list is used.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initInlineDataListField
(
B
itCount
offset
,
Bit
Count
inlineSize
,
B
yteCount
offset
,
Byte
Count
inlineSize
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
// Initialize an inline list field.
...
...
@@ -322,12 +330,12 @@ public:
// Initialize an inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initInlineStructListField
(
B
it
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
B
yte
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
);
// Initialize an inline struct list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getInlineDataListField
(
B
it
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
B
yte
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
// Get an already-initialized inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getInlinePointerListField
(
...
...
@@ -335,7 +343,7 @@ public:
// Get an already-initialized inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getInlineStructListField
(
B
it
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
B
yte
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
);
// Get an already-initialized inline struct list field.
...
...
@@ -366,16 +374,12 @@ private:
void
*
data
;
// Pointer to the encoded data.
WireReference
*
references
;
// Pointer to the encoded references.
BitCount8
bit0Offset
;
// A special hack: When accessing a boolean with field number zero, pretend its offset is this
// instead of the usual zero. This is needed to support 1-bit inline structs.
WireReferenceCount16
referenceCount
;
// Size of the pointer segment, available only for the sake of computing size of List(Inline(T)).
inline
StructBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
references
,
BitCount8
bit0Offset
,
WireReferenceCount
referenceCount
)
:
segment
(
segment
),
data
(
data
),
references
(
references
),
bit0Offset
(
bit0Offset
),
WireReferenceCount
referenceCount
)
:
segment
(
segment
),
data
(
data
),
references
(
references
),
referenceCount
(
referenceCount
)
{}
friend
class
ListBuilder
;
...
...
@@ -386,7 +390,7 @@ class StructReader {
public
:
inline
StructReader
()
:
segment
(
nullptr
),
data
(
nullptr
),
references
(
nullptr
),
dataSize
(
0
),
referenceCount
(
0
),
bit0Offset
(
0
*
BITS
),
nestingLimit
(
0
)
{}
referenceCount
(
0
),
nestingLimit
(
0
)
{}
static
StructReader
readRootTrusted
(
const
word
*
location
);
static
StructReader
readRoot
(
const
word
*
location
,
SegmentReader
*
segment
,
int
nestingLimit
);
...
...
@@ -411,7 +415,7 @@ public:
// be null, in which case an empty struct is used.
CAPNPROTO_ALWAYS_INLINE
(
StructReader
getInlineStructField
(
B
itCount
dataOffset
,
Bit
Count
inlineDataSize
,
B
yteCount
dataOffset
,
Byte
Count
inlineDataSize
,
WireReferenceCount
refIndex
,
WireReferenceCount
inlineRefCount
)
const
);
// Gets an inlined struct field, given the position and size of the data and pointer sections.
...
...
@@ -421,7 +425,7 @@ public:
// initialized. The default value is allowed to be null, in which case an empty list is used.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
getInlineDataListField
(
B
it
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
B
yte
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
);
// Get an inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
getInlinePointerListField
(
...
...
@@ -429,7 +433,7 @@ public:
// Get an inline list field.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
getInlineStructListField
(
B
it
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
B
yte
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
);
// Get an inline struct list field.
...
...
@@ -449,24 +453,18 @@ private:
const
void
*
data
;
const
WireReference
*
references
;
B
it
Count32
dataSize
;
// Size of data segment.
B
yte
Count32
dataSize
;
// Size of data segment.
WireReferenceCount16
referenceCount
;
// Size of the reference segment.
BitCount8
bit0Offset
;
// A special hack: When accessing a boolean with field number zero, pretend its offset is this
// instead of the usual zero. This is needed to allow a boolean list to be upgraded to a list
// of structs, and to support 1-bit inline structs.
int
nestingLimit
;
// Limits the depth of message structures to guard against stack-overflow-based DoS attacks.
// Once this reaches zero, further pointers will be pruned.
// TODO: Limit to 8 bits for better alignment?
inline
StructReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
references
,
BitCount
dataSize
,
WireReferenceCount
referenceCount
,
BitCount
bit0Offset
,
int
nestingLimit
)
ByteCount
dataSize
,
WireReferenceCount
referenceCount
,
int
nestingLimit
)
:
segment
(
segment
),
data
(
data
),
references
(
references
),
dataSize
(
dataSize
),
referenceCount
(
referenceCount
),
bit0Offset
(
bit0Offset
),
dataSize
(
dataSize
),
referenceCount
(
referenceCount
),
nestingLimit
(
nestingLimit
)
{}
friend
class
ListReader
;
...
...
@@ -480,7 +478,7 @@ class ListBuilder {
public
:
inline
ListBuilder
()
:
segment
(
nullptr
),
data
(
nullptr
),
pointers
(
nullptr
),
elementCount
(
0
*
ELEMENTS
),
stepB
its
(
0
*
BIT
S
/
ELEMENTS
),
stepPointers
(
0
*
REFERENCES
/
ELEMENTS
)
{}
stepB
ytes
(
0
*
BYTE
S
/
ELEMENTS
),
stepPointers
(
0
*
REFERENCES
/
ELEMENTS
)
{}
inline
ElementCount
size
();
// The number of elements in the list.
...
...
@@ -540,15 +538,16 @@ private:
ElementCount
elementCount
;
// Number of elements in the list.
decltype
(
B
ITS
/
ELEMENTS
)
stepBit
s
;
decltype
(
B
YTES
/
ELEMENTS
)
stepByte
s
;
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
;
// The distance between elements. Can be tricky e.g. for inlined struct lists.
// Bit lists ignore stepBytes -- they are always tightly-packed.
inline
ListBuilder
(
SegmentBuilder
*
segment
,
void
*
data
,
WireReference
*
pointers
,
decltype
(
B
ITS
/
ELEMENTS
)
stepBit
s
,
decltype
(
B
YTES
/
ELEMENTS
)
stepByte
s
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
ElementCount
size
)
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
size
),
stepB
its
(
stepBit
s
),
stepPointers
(
stepPointers
)
{}
stepB
ytes
(
stepByte
s
),
stepPointers
(
stepPointers
)
{}
friend
class
StructBuilder
;
friend
struct
WireHelpers
;
...
...
@@ -558,7 +557,7 @@ class ListReader {
public
:
inline
ListReader
()
:
segment
(
nullptr
),
data
(
nullptr
),
pointers
(
nullptr
),
elementCount
(
0
),
stepB
its
(
0
*
BIT
S
/
ELEMENTS
),
stepPointers
(
0
*
REFERENCES
/
ELEMENTS
),
stepB
ytes
(
0
*
BYTE
S
/
ELEMENTS
),
stepPointers
(
0
*
REFERENCES
/
ELEMENTS
),
structDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
0
)
{}
inline
ElementCount
size
();
...
...
@@ -589,11 +588,12 @@ private:
ElementCount
elementCount
;
// Number of elements in the list.
decltype
(
B
ITS
/
ELEMENTS
)
stepBit
s
;
decltype
(
B
YTES
/
ELEMENTS
)
stepByte
s
;
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
;
// The distance between elements. Can be tricky e.g. for inlined struct lists.
// Bit lists ignore stepBytes -- they are always tightly-packed.
B
it
Count
structDataSize
;
B
yte
Count
structDataSize
;
WireReferenceCount
structReferenceCount
;
// If the elements are structs, the properties of the struct.
...
...
@@ -602,17 +602,17 @@ private:
// Once this reaches zero, further pointers will be pruned.
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
pointers
,
ElementCount
elementCount
,
decltype
(
B
ITS
/
ELEMENTS
)
stepBit
s
,
ElementCount
elementCount
,
decltype
(
B
YTES
/
ELEMENTS
)
stepByte
s
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
int
nestingLimit
)
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
stepB
its
(
stepBits
),
stepPointers
(
stepPointers
),
structDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
nestingLimit
)
{}
stepB
ytes
(
stepBytes
),
stepPointers
(
stepPointers
),
structDataSize
(
0
),
structReferenceCount
(
0
),
nestingLimit
(
nestingLimit
)
{}
inline
ListReader
(
SegmentReader
*
segment
,
const
void
*
data
,
const
WireReference
*
pointers
,
ElementCount
elementCount
,
decltype
(
B
ITS
/
ELEMENTS
)
stepBit
s
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
B
it
Count
structDataSize
,
ElementCount
elementCount
,
decltype
(
B
YTES
/
ELEMENTS
)
stepByte
s
,
decltype
(
REFERENCES
/
ELEMENTS
)
stepPointers
,
B
yte
Count
structDataSize
,
WireReferenceCount
structReferenceCount
,
int
nestingLimit
)
:
segment
(
segment
),
data
(
data
),
pointers
(
pointers
),
elementCount
(
elementCount
),
stepB
its
(
stepBit
s
),
stepPointers
(
stepPointers
),
structDataSize
(
structDataSize
),
stepB
ytes
(
stepByte
s
),
stepPointers
(
stepPointers
),
structDataSize
(
structDataSize
),
structReferenceCount
(
structReferenceCount
),
nestingLimit
(
nestingLimit
)
{}
friend
class
StructReader
;
...
...
@@ -631,10 +631,6 @@ inline T StructBuilder::getDataField(ElementCount offset) const {
template
<>
inline
bool
StructBuilder
::
getDataField
<
bool
>
(
ElementCount
offset
)
const
{
BitCount
boffset
=
offset
*
(
1
*
BITS
/
ELEMENTS
);
// This branch should always be optimized away when inlining.
if
(
boffset
==
0
*
BITS
)
boffset
=
bit0Offset
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
boffset
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
(
1
<<
(
boffset
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
...
...
@@ -658,10 +654,6 @@ inline void StructBuilder::setDataField(
template
<>
inline
void
StructBuilder
::
setDataField
<
bool
>
(
ElementCount
offset
,
bool
value
)
const
{
BitCount
boffset
=
offset
*
(
1
*
BITS
/
ELEMENTS
);
// This branch should always be optimized away when inlining.
if
(
boffset
==
0
*
BITS
)
boffset
=
bit0Offset
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
boffset
/
BITS_PER_BYTE
;
uint
bitnum
=
boffset
%
BITS_PER_BYTE
/
BITS
;
*
reinterpret_cast
<
uint8_t
*>
(
b
)
=
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
~
(
1
<<
bitnum
))
...
...
@@ -678,37 +670,29 @@ inline void StructBuilder::setDataField(
}
inline
StructBuilder
StructBuilder
::
initInlineStructField
(
B
itCount
dataOffset
,
Bit
Count
inlineDataSize
,
B
yteCount
dataOffset
,
Byte
Count
inlineDataSize
,
WireReferenceCount
refIndex
,
WireReferenceCount
inlineRefCount
)
const
{
// This branch should be optimized away.
if
(
inlineDataSize
==
1
*
BITS
)
{
setDataField
<
bool
>
(
dataOffset
/
(
1
*
BITS
/
ELEMENTS
),
false
);
}
else
{
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
/
BYTES
,
0
,
inlineDataSize
/
BITS_PER_BYTE
/
BYTES
);
}
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
,
0
,
inlineDataSize
/
BYTES
);
memset
(
reinterpret_cast
<
word
*>
(
references
)
+
refIndex
*
WORDS_PER_REFERENCE
,
0
,
inlineRefCount
*
WORDS_PER_REFERENCE
*
BYTES_PER_WORD
/
BYTES
);
return
getInlineStructField
(
dataOffset
,
inlineDataSize
,
refIndex
,
inlineRefCount
);
}
inline
StructBuilder
StructBuilder
::
getInlineStructField
(
B
itCount
dataOffset
,
Bit
Count
inlineDataSize
,
B
yteCount
dataOffset
,
Byte
Count
inlineDataSize
,
WireReferenceCount
refIndex
,
WireReferenceCount
inlineRefCount
)
const
{
return
StructBuilder
(
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
,
// WireReference is incomplete here so we have to cast around... Bah.
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
references
)
+
refIndex
*
WORDS_PER_REFERENCE
),
dataOffset
==
0
*
BITS
?
BitCount
(
bit0Offset
)
:
dataOffset
%
BITS_PER_BYTE
,
inlineRefCount
);
}
inline
ListBuilder
StructBuilder
::
initInlineDataListField
(
B
itCount
offset
,
Bit
Count
inlineSize
,
B
yteCount
offset
,
Byte
Count
inlineSize
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
offset
/
BITS_PER_BYTE
,
0
,
inlineSize
/
BITS_PER_BYTE
/
BYTES
);
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
offset
,
0
,
inlineSize
/
BYTES
);
return
getInlineDataListField
(
offset
,
elementCount
,
elementSize
);
}
...
...
@@ -721,20 +705,20 @@ inline ListBuilder StructBuilder::initInlinePointerListField(
}
inline
ListBuilder
StructBuilder
::
initInlineStructListField
(
B
it
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
B
yte
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
0
,
elementSize
.
dataB
its
/
BITS_PER_BYTE
/
BYTES
);
memset
(
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
,
0
,
elementSize
.
dataB
ytes
/
BYTES
);
memset
(
reinterpret_cast
<
word
*>
(
references
)
+
ptrOffset
*
WORDS_PER_REFERENCE
,
0
,
elementSize
.
pointers
*
BYTES_PER_REFERENCE
/
BYTES
);
return
getInlineStructListField
(
dataOffset
,
ptrOffset
,
elementCount
,
elementSize
);
}
inline
ListBuilder
StructBuilder
::
getInlineDataListField
(
B
it
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
B
yte
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
return
ListBuilder
(
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
offset
/
BITS_PER_BYTE
,
nullptr
,
b
it
sPerElement
(
elementSize
),
0
*
REFERENCES
/
ELEMENTS
,
elementCount
);
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
offset
,
nullptr
,
b
yte
sPerElement
(
elementSize
),
0
*
REFERENCES
/
ELEMENTS
,
elementCount
);
}
inline
ListBuilder
StructBuilder
::
getInlinePointerListField
(
...
...
@@ -743,17 +727,17 @@ inline ListBuilder StructBuilder::getInlinePointerListField(
segment
,
nullptr
,
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
references
)
+
offset
*
WORDS_PER_REFERENCE
),
0
*
B
IT
S
/
ELEMENTS
,
1
*
REFERENCES
/
ELEMENTS
,
elementCount
);
0
*
B
YTE
S
/
ELEMENTS
,
1
*
REFERENCES
/
ELEMENTS
,
elementCount
);
}
inline
ListBuilder
StructBuilder
::
getInlineStructListField
(
B
it
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
B
yte
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
return
ListBuilder
(
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
segment
,
reinterpret_cast
<
byte
*>
(
data
)
+
dataOffset
,
reinterpret_cast
<
WireReference
*>
(
reinterpret_cast
<
word
*>
(
references
)
+
ptrOffset
*
WORDS_PER_REFERENCE
),
elementSize
.
dataB
it
s
/
ELEMENTS
,
elementSize
.
pointers
/
ELEMENTS
,
elementSize
.
dataB
yte
s
/
ELEMENTS
,
elementSize
.
pointers
/
ELEMENTS
,
elementCount
);
}
...
...
@@ -761,7 +745,7 @@ inline ListBuilder StructBuilder::getInlineStructListField(
template
<
typename
T
>
T
StructReader
::
getDataField
(
ElementCount
offset
)
const
{
if
((
offset
+
1
*
ELEMENTS
)
*
capnproto
::
b
it
sPerElement
<
T
>
()
<=
dataSize
)
{
if
((
offset
+
1
*
ELEMENTS
)
*
capnproto
::
b
yte
sPerElement
<
T
>
()
<=
dataSize
)
{
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
data
)[
offset
/
ELEMENTS
].
get
();
}
else
{
return
static_cast
<
T
>
(
0
);
...
...
@@ -771,11 +755,7 @@ T StructReader::getDataField(ElementCount offset) const {
template
<>
inline
bool
StructReader
::
getDataField
<
bool
>
(
ElementCount
offset
)
const
{
BitCount
boffset
=
offset
*
(
1
*
BITS
/
ELEMENTS
);
// This branch should always be optimized away when inlining.
if
(
boffset
==
0
*
BITS
)
boffset
=
bit0Offset
;
if
(
boffset
<
dataSize
)
{
if
(
boffset
<
dataSize
*
BITS_PER_BYTE
)
{
const
byte
*
b
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
boffset
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
const
uint8_t
*>
(
b
)
&
(
1
<<
(
boffset
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
else
{
...
...
@@ -794,23 +774,22 @@ T StructReader::getDataField(ElementCount offset, typename MaskType<T>::Type mas
}
inline
StructReader
StructReader
::
getInlineStructField
(
B
itCount
dataOffset
,
Bit
Count
inlineDataSize
,
B
yteCount
dataOffset
,
Byte
Count
inlineDataSize
,
WireReferenceCount
refIndex
,
WireReferenceCount
inlineRefCount
)
const
{
return
StructReader
(
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
dataOffset
,
// WireReference is incomplete here so we have to cast around... Bah.
reinterpret_cast
<
const
WireReference
*>
(
reinterpret_cast
<
const
word
*>
(
references
)
+
refIndex
*
WORDS_PER_REFERENCE
),
dataSize
,
inlineRefCount
,
dataOffset
==
0
*
BITS
?
BitCount
(
bit0Offset
)
:
dataOffset
%
BITS_PER_BYTE
,
nestingLimit
);
}
inline
ListReader
StructReader
::
getInlineDataListField
(
B
it
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
B
yte
Count
offset
,
ElementCount
elementCount
,
FieldSize
elementSize
)
const
{
return
ListReader
(
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
offset
/
BITS_PER_BYTE
,
nullptr
,
elementCount
,
b
it
sPerElement
(
elementSize
),
0
*
REFERENCES
/
ELEMENTS
,
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
offset
,
nullptr
,
elementCount
,
b
yte
sPerElement
(
elementSize
),
0
*
REFERENCES
/
ELEMENTS
,
nestingLimit
);
}
...
...
@@ -820,19 +799,19 @@ inline ListReader StructReader::getInlinePointerListField(
segment
,
nullptr
,
reinterpret_cast
<
const
WireReference
*>
(
reinterpret_cast
<
const
word
*>
(
references
)
+
offset
*
WORDS_PER_REFERENCE
),
elementCount
,
0
*
B
IT
S
/
ELEMENTS
,
1
*
REFERENCES
/
ELEMENTS
,
elementCount
,
0
*
B
YTE
S
/
ELEMENTS
,
1
*
REFERENCES
/
ELEMENTS
,
nestingLimit
);
}
inline
ListReader
StructReader
::
getInlineStructListField
(
B
it
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
B
yte
Count
dataOffset
,
WireReferenceCount
ptrOffset
,
ElementCount
elementCount
,
StructSize
elementSize
)
const
{
return
ListReader
(
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
dataOffset
/
BITS_PER_BYTE
,
segment
,
reinterpret_cast
<
const
byte
*>
(
data
)
+
dataOffset
,
reinterpret_cast
<
const
WireReference
*>
(
reinterpret_cast
<
const
word
*>
(
references
)
+
ptrOffset
*
WORDS_PER_REFERENCE
),
elementCount
,
elementSize
.
dataB
it
s
/
ELEMENTS
,
elementSize
.
pointers
/
ELEMENTS
,
elementSize
.
dataB
it
s
,
elementSize
.
pointers
,
nestingLimit
);
elementCount
,
elementSize
.
dataB
yte
s
/
ELEMENTS
,
elementSize
.
pointers
/
ELEMENTS
,
elementSize
.
dataB
yte
s
,
elementSize
.
pointers
,
nestingLimit
);
}
// -------------------------------------------------------------------
...
...
@@ -842,12 +821,13 @@ inline ElementCount ListBuilder::size() { return elementCount; }
template
<
typename
T
>
inline
T
ListBuilder
::
getDataElement
(
ElementCount
index
)
const
{
return
reinterpret_cast
<
WireValue
<
T
>*>
(
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepB
its
/
BITS_PER_BYTE
)
->
get
();
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepB
ytes
)
->
get
();
}
template
<>
inline
bool
ListBuilder
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
BitCount
bindex
=
index
*
stepBits
;
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
(
1
<<
(
bindex
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
...
...
@@ -860,12 +840,13 @@ inline Void ListBuilder::getDataElement<Void>(ElementCount index) const {
template
<
typename
T
>
inline
void
ListBuilder
::
setDataElement
(
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
{
reinterpret_cast
<
WireValue
<
T
>*>
(
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepB
its
/
BITS_PER_BYTE
)
->
set
(
value
);
reinterpret_cast
<
byte
*>
(
data
)
+
index
*
stepB
ytes
)
->
set
(
value
);
}
template
<>
inline
void
ListBuilder
::
setDataElement
<
bool
>
(
ElementCount
index
,
bool
value
)
const
{
BitCount
bindex
=
index
*
stepBits
;
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
uint
bitnum
=
bindex
%
BITS_PER_BYTE
/
BITS
;
*
reinterpret_cast
<
uint8_t
*>
(
b
)
=
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
~
(
1
<<
bitnum
))
...
...
@@ -882,12 +863,13 @@ inline ElementCount ListReader::size() { return elementCount; }
template
<
typename
T
>
inline
T
ListReader
::
getDataElement
(
ElementCount
index
)
const
{
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
reinterpret_cast
<
const
byte
*>
(
data
)
+
index
*
stepB
its
/
BITS_PER_BYTE
)
->
get
();
reinterpret_cast
<
const
byte
*>
(
data
)
+
index
*
stepB
ytes
)
->
get
();
}
template
<>
inline
bool
ListReader
::
getDataElement
<
bool
>
(
ElementCount
index
)
const
{
BitCount
bindex
=
index
*
stepBits
;
// Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists.
BitCount
bindex
=
index
*
(
1
*
BITS
/
ELEMENTS
);
const
byte
*
b
=
reinterpret_cast
<
const
byte
*>
(
data
)
+
bindex
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
const
uint8_t
*>
(
b
)
&
(
1
<<
(
bindex
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
...
...
c++/src/capnproto/test.capnp
View file @
5f08f50d
...
...
@@ -276,27 +276,25 @@ struct TestUsing {
innerNestedEnum @0 :NestedEnum = quux;
}
struct TestInline0 fixed(0 bits) { f @0: Void; }
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 TestInline0 fixed() { f @0: Void; }
struct TestInline8 fixed(1 bytes) { f0 @0: Bool; f1 @1: Bool; f2 @2: Bool; }
struct TestInline16 fixed(2 bytes) { f0 @0: UInt8; f1 @1: UInt8; }
struct TestInline32 fixed(4 bytes) { f0 @0: UInt8; f1 @1: UInt16; }
struct TestInline64 fixed(8 bytes) { 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 TestInline0p fixed(1 pointers) { f @0 :Inline(TestInline0); p0 @1 :Text; }
struct TestInline8p fixed(1 bytes, 1 pointers) { f @0 :Inline(TestInline8); p0 @1 :Text; }
struct TestInline16p fixed(2 bytes, 2 pointers) { f @0 :Inline(TestInline16); p0 @1 :Text; p1 @2 :Text; }
struct TestInline32p fixed(4 bytes, 2 pointers) { f @0 :Inline(TestInline32); p0 @1 :Text; p1 @2 :Text; }
struct TestInline64p fixed(8 bytes, 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)
;
pad1 @1 :UInt8
;
f8 @2 :Inline(TestInline8);
f16 @3 :Inline(TestInline16);
f32 @4 :Inline(TestInline32);
...
...
@@ -305,22 +303,20 @@ struct TestInlineLayout {
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;
pad2 @9 :UInt8;
padP @10 :Text;
f8p @11 :Inline(TestInline8p);
f16p @12 :Inline(TestInline16p);
f32p @13 :Inline(TestInline32p);
f64p @14 :Inline(TestInline64p);
f128p @15 :Inline(TestInline128p);
f192p @16 :Inline(TestInline192p);
}
struct TestInlineUnions {
union0 @0 union {
f0 @4 :Inline(TestInline0);
f1 @5 :
Inline(TestInline1);
f1 @5 :
Bool; # There used to be a TestInline1 but it was decided to be a bad idea.
f8 @6 :Inline(TestInline8);
f16 @7 :Inline(TestInline16);
f32 @8 :Inline(TestInline32);
...
...
@@ -329,7 +325,7 @@ struct TestInlineUnions {
f192 @11 :Inline(TestInline192);
f0p @12 :Inline(TestInline0p);
f1p @13 :
Inline(TestInline1p)
;
f1p @13 :
Bool
;
f8p @14 :Inline(TestInline8p);
f16p @15 :Inline(TestInline16p);
f32p @16 :Inline(TestInline32p);
...
...
@@ -343,7 +339,7 @@ struct TestInlineUnions {
union1 @1 union {
f0 @21 :Inline(TestInline0);
f1 @22 :
Inline(TestInline1)
;
f1 @22 :
Bool
;
f8 @23 :Inline(TestInline8);
f16 @24 :Inline(TestInline16);
f32 @25 :Inline(TestInline32);
...
...
@@ -362,7 +358,7 @@ struct TestInlineUnions {
# Interleave two unions to be really annoying.
union2 @2 union {
f1p @35 :
Inline(TestInline1p)
;
f1p @35 :
Bool
;
f8p @37 :Inline(TestInline8p);
f16p @40 :Inline(TestInline16p);
f32p @42 :Inline(TestInline32p);
...
...
@@ -372,7 +368,7 @@ struct TestInlineUnions {
}
union3 @3 union {
f1p @36 :
Inline(TestInline1p)
;
f1p @36 :
Bool
;
f8p @38 :Inline(TestInline8p);
f16p @41 :Inline(TestInline16p);
f32p @43 :Inline(TestInline32p);
...
...
@@ -394,7 +390,7 @@ struct TestInlineLists {
textList @ 6 : InlineList(Text, 8);
structList0 @ 7 : InlineList(TestInline0, 2);
structList1 @ 8 : InlineList(
TestInline1
, 3);
structList1 @ 8 : InlineList(
Bool
, 3);
structList8 @ 9 : InlineList(TestInline8, 4);
structList16 @10 : InlineList(TestInline16, 2);
structList32 @11 : InlineList(TestInline32, 3);
...
...
@@ -403,7 +399,7 @@ struct TestInlineLists {
structList192 @14 : InlineList(TestInline192, 3);
structList0p @15 : InlineList(TestInline0p, 4);
structList1p @16 : InlineList(
TestInline1p
, 2);
structList1p @16 : InlineList(
Bool
, 2);
structList8p @17 : InlineList(TestInline8p, 3);
structList16p @18 : InlineList(TestInline16p, 4);
structList32p @19 : InlineList(TestInline32p, 2);
...
...
@@ -435,7 +431,6 @@ struct TestStructLists {
struct TestInlineDefaults {
normal @0 :TestInlineLayout = (
f0 = (f = void),
f1 = (f = true),
f8 = (f0 = true, f1 = false, f2 = true),
f16 = (f0 = 123, f1 = 45),
f32 = (f0 = 67, f1 = 8901),
...
...
@@ -444,7 +439,6 @@ struct TestInlineDefaults {
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"),
...
...
@@ -457,7 +451,7 @@ struct TestInlineDefaults {
unions @1 :TestInlineUnions = (
union0 = f32(f0 = 67, f1 = 8901),
union1 = f128(f0 = 1234567890123, f1 = 4567890123456),
union2 = f
1
p(p0 = "foo"),
union2 = f
8
p(p0 = "foo"),
union3 = f16p(f = (f0 = 98, f1 = 76), p0 = "qux", p1 = "quux"));
lists @2 :TestInlineLists = (
...
...
@@ -470,7 +464,6 @@ struct TestInlineDefaults {
textList = ["foo", "bar", "baz", "qux", "quux", "corge", "grault", "garply"],
structList0 = [(f = void), ()],
structList1 = [(f = true), (f = false), (f = true)],
structList8 = [(f0 = true, f1 = false, f2 = false),
(f0 = false, f1 = true, f2 = false),
(f0 = true, f1 = true, f2 = false),
...
...
@@ -487,7 +480,6 @@ struct TestInlineDefaults {
structList0p = [(f = (f = void), p0 = "foo"), (p0 = "bar"),
(f = (), p0 = "baz"), (p0 = "qux")],
structList1p = [(f = (f = true), p0 = "quux"), (p0 = "corge")],
structList8p = [(f = (f0 = true), p0 = "grault"), (p0 = "garply"), (p0 = "waldo")],
structList16p = [(f = (f0 = 123), p0 = "fred", p1 = "plugh"),
(p0 = "xyzzy", p1 = "thud"),
...
...
compiler/src/Compiler.hs
View file @
5f08f50d
...
...
@@ -682,7 +682,8 @@ packUnion :: UnionDesc -> PackingState -> Map.Map Integer UnionPackingState
packUnion
_
state
unionState
=
(
DataOffset
Size16
offset
,
newState
,
unionState
)
where
(
offset
,
newState
)
=
packData
Size16
state
stripHolesFromFirstWord
Size1
_
=
Size1
-- Nothing left to strip.
stripHolesFromFirstWord
Size1
_
=
error
"can't get this far"
stripHolesFromFirstWord
Size8
_
=
Size8
-- Don't reduce to less than a byte.
stripHolesFromFirstWord
size
holes
=
let
nextSize
=
pred
size
in
case
Map
.
lookup
nextSize
holes
of
...
...
@@ -717,13 +718,12 @@ enforceFixed Nothing sizes = return sizes
enforceFixed
(
Just
(
Located
pos
(
requestedDataSize
,
requestedPointerCount
)))
(
actualDataSize
,
actualPointerCount
)
=
do
validatedRequestedDataSize
<-
case
requestedDataSize
of
1
->
return
DataSection1
8
->
return
DataSection8
16
->
return
DataSection16
32
->
return
DataSection32
s
|
mod
s
64
==
0
->
return
$
DataSectionWords
$
div
s
64
_
->
makeError
pos
$
printf
"Struct data section size must be a whole number of words
\
\
or 0, 1,
8, 16, or 32 bit
s."
\
or 0, 1,
2, 4, or 8 byte
s."
recover
()
$
when
(
dataSectionBits
actualDataSize
>
dataSectionBits
validatedRequestedDataSize
)
$
makeError
pos
$
printf
"Struct data section size is %s which exceeds specified maximum of
\
...
...
compiler/src/CxxGenerator.hs
View file @
5f08f50d
...
...
@@ -161,12 +161,12 @@ fieldOffsetInteger VoidOffset = "0"
fieldOffsetInteger
(
DataOffset
_
o
)
=
show
o
fieldOffsetInteger
(
PointerOffset
o
)
=
show
o
fieldOffsetInteger
(
InlineCompositeOffset
d
p
ds
ps
)
=
let
b
itSize
=
dataSectionBits
ds
b
it
Offset
=
case
ds
of
DataSectionWords
_
->
d
*
64
_
->
d
*
b
it
Size
in
printf
"%d * ::capnproto::B
ITS, %d * ::capnproto::BIT
S,
\
\
%d * ::capnproto::REFERENCES, %d * ::capnproto::REFERENCES"
b
itOffset
bit
Size
p
ps
b
yteSize
=
div
(
dataSectionBits
ds
)
8
b
yte
Offset
=
case
ds
of
DataSectionWords
_
->
d
*
8
_
->
d
*
b
yte
Size
in
printf
"%d * ::capnproto::B
YTES, %d * ::capnproto::BYTE
S,
\
\
%d * ::capnproto::REFERENCES, %d * ::capnproto::REFERENCES"
b
yteOffset
byte
Size
p
ps
isDefaultZero
VoidDesc
=
True
isDefaultZero
(
BoolDesc
b
)
=
not
b
...
...
@@ -266,11 +266,11 @@ fieldContext parent desc = mkStrContext context where
_
->
muNull
context
"fieldInlineDataOffset"
=
case
fieldOffset
desc
of
InlineCompositeOffset
off
_
size
_
->
MuVariable
(
off
*
d
ataSizeInBits
(
dataSectionAlignment
size
)
)
MuVariable
(
off
*
d
iv
(
dataSizeInBits
(
dataSectionAlignment
size
))
8
)
_
->
muNull
context
"fieldInlineDataSize"
=
case
fieldOffset
desc
of
InlineCompositeOffset
_
_
size
_
->
MuVariable
$
d
ataSectionBits
size
MuVariable
$
d
iv
(
dataSectionBits
size
)
8
_
->
muNull
context
"fieldInlinePointerOffset"
=
case
fieldOffset
desc
of
InlineCompositeOffset
_
off
_
_
->
MuVariable
off
...
...
@@ -330,7 +330,7 @@ structContext parent desc = mkStrContext context where
context
"structFields"
=
MuList
$
map
(
fieldContext
context
)
$
structFields
desc
context
"structUnions"
=
MuList
$
map
(
unionContext
context
)
$
structUnions
desc
context
"structDataSize"
=
MuVariable
$
dataSectionWordSize
$
structDataSize
desc
context
"structDataB
its"
=
MuVariable
$
dataSectionBits
$
structDataSize
desc
context
"structDataB
ytes"
=
MuVariable
(
div
(
dataSectionBits
(
structDataSize
desc
))
8
)
context
"structReferenceCount"
=
MuVariable
$
structPointerCount
desc
context
"structNestedEnums"
=
MuList
$
map
(
enumContext
context
)
[
m
|
DescEnum
m
<-
structMembers
desc
]
...
...
compiler/src/Parser.hs
View file @
5f08f50d
...
...
@@ -254,15 +254,14 @@ combineFixedSizes (_, Just _) (FixedPointers _) =
fixedSize
=
do
size
<-
literalInt
(
exactIdentifier
"bit"
>>
return
(
FixedData
size
))
<|>
(
exactIdentifier
"bits"
>>
return
(
FixedData
size
))
<|>
(
exactIdentifier
"byte"
>>
return
(
FixedData
(
8
*
size
)))
-- We do not allow single-bit structs because most CPUs cannot address bits.
(
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
))
<?>
"
\"
b
its
\"
,
\"
b
ytes
\"
,
\"
words
\"
, or
\"
pointers
\"
"
<?>
"
\"
bytes
\"
,
\"
words
\"
, or
\"
pointers
\"
"
structLine
::
Maybe
[
Located
Statement
]
->
TokenParser
Declaration
structLine
Nothing
=
usingDecl
<|>
constantDecl
<|>
fieldDecl
<|>
annotationDecl
...
...
compiler/src/Semantics.hs
View file @
5f08f50d
...
...
@@ -263,9 +263,9 @@ dataSizeToSectionSize Size32 = DataSection32
dataSizeToSectionSize
Size64
=
DataSectionWords
1
dataSectionSizeString
DataSection1
=
"1 bits"
dataSectionSizeString
DataSection8
=
"
8 bit
s"
dataSectionSizeString
DataSection16
=
"
16 bit
s"
dataSectionSizeString
DataSection32
=
"
32 bit
s"
dataSectionSizeString
DataSection8
=
"
1 byte
s"
dataSectionSizeString
DataSection16
=
"
2 byte
s"
dataSectionSizeString
DataSection32
=
"
4 byte
s"
dataSectionSizeString
(
DataSectionWords
n
)
=
show
n
++
" words"
data
DataSize
=
Size1
|
Size8
|
Size16
|
Size32
|
Size64
deriving
(
Eq
,
Ord
,
Enum
)
...
...
@@ -319,9 +319,9 @@ fieldSize (InlineStructType StructDesc { structDataSize = ds, structPointerCount
fieldSize
(
InterfaceType
_
)
=
SizeReference
fieldSize
(
ListType
_
)
=
SizeReference
fieldSize
(
InlineListType
element
size
)
=
let
-- We intentionally do not allow single-bit lists because most CPUs cannot address bits.
minDataSectionForBits
bits
|
bits
<=
0
=
DataSectionWords
0
|
bits
<=
1
=
DataSection1
|
bits
<=
8
=
DataSection8
|
bits
<=
16
=
DataSection16
|
bits
<=
32
=
DataSection32
...
...
compiler/src/c++-header.mustache
View file @
5f08f50d
...
...
@@ -70,7 +70,7 @@ struct {{typeFullName}} {
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
::capnproto::internal::StructSize(
{{
structDataSize
}}
* ::capnproto::WORDS,
{{
structReferenceCount
}}
* ::capnproto::REFERENCES,
{{
structDataB
its
}}
* ::capnproto::BIT
S);
{{
structDataB
ytes
}}
* ::capnproto::BYTE
S);
{{/
typeStruct
}}
{{#
typeUnion
}}
...
...
@@ -375,7 +375,7 @@ inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Reader(_reader.getInlineDataListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::B
IT
S,
{{
fieldInlineDataOffset
}}
* ::capnproto::B
YTE
S,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::
{{
fieldElementSize
}}
));
}
...
...
@@ -386,8 +386,8 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.initInlineDataListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::B
IT
S,
{{
fieldInlineDataSize
}}
* ::capnproto::B
IT
S,
{{
fieldInlineDataOffset
}}
* ::capnproto::B
YTE
S,
{{
fieldInlineDataSize
}}
* ::capnproto::B
YTE
S,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::
{{
fieldElementSize
}}
));
}
...
...
@@ -397,7 +397,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.getInlineDataListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::B
IT
S,
{{
fieldInlineDataOffset
}}
* ::capnproto::B
YTE
S,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::
{{
fieldElementSize
}}
));
}
...
...
@@ -509,7 +509,7 @@ inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Reader(_reader.getInlineStructListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::B
IT
S,
{{
fieldInlineDataOffset
}}
* ::capnproto::B
YTE
S,
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
{{
fieldElementType
}}
::STRUCT_SIZE));
...
...
@@ -521,7 +521,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
{{
unionTagOffset
}}
* ::capnproto::ELEMENTS,
{{
unionTitleCase
}}
::
{{
fieldUpperCase
}}
);
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.initInlineStructListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::B
IT
S,
{{
fieldInlineDataOffset
}}
* ::capnproto::B
YTE
S,
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
{{
fieldElementType
}}
::STRUCT_SIZE));
...
...
@@ -532,7 +532,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
"Must check which() before get()ing a union member.");
{{/
fieldUnion
}}
return
{{
fieldType
}}
::Builder(_builder.getInlineStructListField(
{{
fieldInlineDataOffset
}}
* ::capnproto::B
IT
S,
{{
fieldInlineDataOffset
}}
* ::capnproto::B
YTE
S,
{{
fieldInlinePointerOffset
}}
* ::capnproto::REFERENCES,
{{
fieldInlineListSize
}}
* ::capnproto::ELEMENTS,
{{
fieldElementType
}}
::STRUCT_SIZE));
...
...
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