Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Kirill Smelkov
neo
Commits
abb30701
Commit
abb30701
authored
Jan 25, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
f24296e3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
63 additions
and
33 deletions
+63
-33
t/neo/protogen.go
t/neo/protogen.go
+63
-33
No files found.
t/neo/protogen.go
View file @
abb30701
...
...
@@ -338,12 +338,55 @@ func (s *SymSize) IsZero() bool {
return
s
.
num
==
0
&&
len
(
s
.
exprv
)
==
0
}
// XXX just use `... = SymSize{}` ?
func
(
s
*
SymSize
)
Reset
()
{
*
s
=
SymSize
{}
}
// decoder overflow check state
type
OverflowCheck
struct
{
// size to check for overflow
size
SymSize
// whether overflow was already checked for current decodings
// (if yes, size updates will be ignored)
checked
bool
// stack operated by {Push,Pop}Checked
checkedStk
[]
bool
}
// push/pop checked state
func
(
o
*
OverflowCheck
)
PushChecked
(
checked
bool
)
{
o
.
checkedStk
=
append
(
o
.
checkedStk
,
o
.
checked
)
o
.
checked
=
checked
}
func
(
o
*
OverflowCheck
)
PopChecked
()
bool
{
popret
:=
o
.
checked
l
:=
len
(
o
.
checkedStk
)
o
.
checked
=
o
.
checkedStk
[
l
-
1
]
o
.
checkedStk
=
o
.
checkedStk
[
:
l
-
1
]
return
popret
}
// Add and AddExpr update .size accordingly, but only if overflow was not
// already marked as checked
func
(
o
*
OverflowCheck
)
Add
(
n
int
)
{
if
!
o
.
checked
{
o
.
size
.
Add
(
n
)
}
}
func
(
o
*
OverflowCheck
)
AddExpr
(
format
string
,
a
...
interface
{})
{
if
!
o
.
checked
{
o
.
size
.
AddExpr
(
format
,
a
...
)
}
}
// XXX naming ok?
// XXX -> Gen_NEOEncodedLen ?
// sizeCodeGen generates code to compute encoded size of a packet
...
...
@@ -374,7 +417,7 @@ type encoder struct {
//
// overflow checks and, when convenient, nread updates are grouped and emitted
// so that they are performed in the beginning of greedy fixed-wire-size
// blocks.
// blocks
- checking as much as possible in one go
.
//
// TODO more text?
type
decoder
struct
{
...
...
@@ -387,10 +430,7 @@ type decoder struct {
n
int
// current read position in data.
// size that will be checked for overflow at current overflow check point
overflowCheckSize
SymSize
// whether overflow was already checked for current decodings
overflowChecked
bool
overflowCheck
OverflowCheck
}
var
_
CodeGenerator
=
(
*
sizeCodeGen
)(
nil
)
...
...
@@ -457,15 +497,15 @@ func (d *decoder) resetPos() {
// 2. mark current place as next overflow checkpoint to eventually emit
//
// it is inserted
// - before reading variable sized item
// - in the beginning of
loop inside XXX ok?
// - before reading
a
variable sized item
// - in the beginning of
a loop inside
func
(
d
*
decoder
)
overflowCheckpoint
()
{
//d.bufDone.emit("// overflow check point")
if
!
d
.
overflowCheck
S
ize
.
IsZero
()
{
d
.
bufDone
.
emit
(
"if uint32(len(data)) < %v { goto overflow }"
,
&
d
.
overflowCheck
S
ize
)
if
!
d
.
overflowCheck
.
s
ize
.
IsZero
()
{
d
.
bufDone
.
emit
(
"if uint32(len(data)) < %v { goto overflow }"
,
&
d
.
overflowCheck
.
s
ize
)
}
d
.
overflowCheck
S
ize
.
Reset
()
d
.
overflowCheck
.
s
ize
.
Reset
()
d
.
bufDone
.
Write
(
d
.
buf
.
Bytes
())
d
.
buf
.
Reset
()
...
...
@@ -490,7 +530,7 @@ func (d *decoder) generatedCode() string {
}
code
.
emit
(
"return %v, nil"
,
retexpr
)
//
overflow
is not used only for empty structs
//
`goto overflow`
is not used only for empty structs
if
(
&
types
.
StdSizes
{
8
,
8
})
.
Sizeof
(
d
.
typ
)
>
0
{
code
.
emit
(
"
\n
overflow:"
)
code
.
emit
(
"return 0, ErrDecodeOverflow"
)
...
...
@@ -524,13 +564,9 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ
dataptr
:=
fmt
.
Sprintf
(
"data[%v:]"
,
d
.
n
)
decoded
:=
fmt
.
Sprintf
(
basic
.
decode
,
dataptr
)
d
.
n
+=
basic
.
wireSize
if
!
d
.
overflowChecked
{
d
.
overflowCheckSize
.
Add
(
basic
.
wireSize
)
}
d
.
overflowCheck
.
Add
(
basic
.
wireSize
)
if
userType
!=
nil
&&
userType
!=
typ
{
// userType is a named type over some basic, like
// type ClusterState int32
// -> need to cast
// need to cast (like in encode case)
decoded
=
fmt
.
Sprintf
(
"%v(%v)"
,
typeName
(
userType
),
decoded
)
}
// NOTE no space before "=" - to be able to merge with ":"
...
...
@@ -566,7 +602,7 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
d
.
n
=
0
d
.
overflowCheckpoint
()
d
.
overflowCheck
Size
.
AddExpr
(
"l"
)
d
.
overflowCheck
.
AddExpr
(
"l"
)
switch
t
:=
typ
.
(
type
)
{
case
*
types
.
Basic
:
...
...
@@ -576,7 +612,7 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
d
.
emit
(
"%v= string(data[:l])"
,
assignto
)
case
*
types
.
Slice
:
// TODO not copy, but reference data from original
// TODO
eventually do
not copy, but reference data from original
d
.
emit
(
"%v= make(%v, l)"
,
assignto
,
typeName
(
typ
))
d
.
emit
(
"copy(%v, data[:l])"
,
assignto
)
...
...
@@ -603,9 +639,7 @@ func (d *decoder) genArray1(assignto string, typ *types.Array) {
typLen
:=
int
(
typ
.
Len
())
d
.
emit
(
"copy(%v[:], data[%v:%v])"
,
assignto
,
d
.
n
,
d
.
n
+
typLen
)
d
.
n
+=
typLen
if
!
d
.
overflowChecked
{
d
.
overflowCheckSize
.
Add
(
typLen
)
}
d
.
overflowCheck
.
Add
(
typLen
)
}
...
...
@@ -662,11 +696,11 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object)
// if size(item)==const - check overflow in one go
elemSize
,
elemFixed
:=
typeSizeFixed
(
typ
.
Elem
())
overflowCheckedCur
:=
d
.
overflowChecked
if
elemFixed
{
d
.
overflowCheckpoint
()
d
.
overflowCheckSize
.
AddExpr
(
"l * %v"
,
elemSize
)
d
.
overflowChecked
=
true
d
.
overflowCheck
.
AddExpr
(
"l * %v"
,
elemSize
)
d
.
overflowCheck
.
PushChecked
(
true
)
defer
d
.
overflowCheck
.
PopChecked
()
d
.
emit
(
"%v += l * %v"
,
d
.
var_
(
"nread"
),
elemSize
)
}
...
...
@@ -691,8 +725,6 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object)
}
d
.
emit
(
"}"
)
d
.
overflowChecked
=
overflowCheckedCur
d
.
emit
(
"}"
)
}
...
...
@@ -759,11 +791,11 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
keySize
,
keyFixed
:=
typeSizeFixed
(
typ
.
Key
())
elemSize
,
elemFixed
:=
typeSizeFixed
(
typ
.
Elem
())
itemFixed
:=
keyFixed
&&
elemFixed
overflowCheckedCur
:=
d
.
overflowChecked
if
itemFixed
{
d
.
overflowCheckpoint
()
d
.
overflowCheckSize
.
AddExpr
(
"l * %v"
,
keySize
+
elemSize
)
d
.
overflowChecked
=
true
d
.
overflowCheck
.
AddExpr
(
"l * %v"
,
keySize
+
elemSize
)
d
.
overflowCheck
.
PushChecked
(
true
)
defer
d
.
overflowCheck
.
PopChecked
()
d
.
emit
(
"%v += l * %v"
,
d
.
var_
(
"nread"
),
keySize
+
elemSize
)
}
...
...
@@ -800,8 +832,6 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
}
d
.
emit
(
"}"
)
d
.
overflowChecked
=
overflowCheckedCur
d
.
emit
(
"}"
)
}
...
...
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