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 {
...
@@ -338,12 +338,55 @@ func (s *SymSize) IsZero() bool {
return
s
.
num
==
0
&&
len
(
s
.
exprv
)
==
0
return
s
.
num
==
0
&&
len
(
s
.
exprv
)
==
0
}
}
// XXX just use `... = SymSize{}` ?
func
(
s
*
SymSize
)
Reset
()
{
func
(
s
*
SymSize
)
Reset
()
{
*
s
=
SymSize
{}
*
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 naming ok?
// XXX -> Gen_NEOEncodedLen ?
// XXX -> Gen_NEOEncodedLen ?
// sizeCodeGen generates code to compute encoded size of a packet
// sizeCodeGen generates code to compute encoded size of a packet
...
@@ -374,7 +417,7 @@ type encoder struct {
...
@@ -374,7 +417,7 @@ type encoder struct {
//
//
// overflow checks and, when convenient, nread updates are grouped and emitted
// overflow checks and, when convenient, nread updates are grouped and emitted
// so that they are performed in the beginning of greedy fixed-wire-size
// 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?
// TODO more text?
type
decoder
struct
{
type
decoder
struct
{
...
@@ -387,10 +430,7 @@ type decoder struct {
...
@@ -387,10 +430,7 @@ type decoder struct {
n
int
// current read position in data.
n
int
// current read position in data.
// size that will be checked for overflow at current overflow check point
// size that will be checked for overflow at current overflow check point
overflowCheckSize
SymSize
overflowCheck
OverflowCheck
// whether overflow was already checked for current decodings
overflowChecked
bool
}
}
var
_
CodeGenerator
=
(
*
sizeCodeGen
)(
nil
)
var
_
CodeGenerator
=
(
*
sizeCodeGen
)(
nil
)
...
@@ -457,15 +497,15 @@ func (d *decoder) resetPos() {
...
@@ -457,15 +497,15 @@ func (d *decoder) resetPos() {
// 2. mark current place as next overflow checkpoint to eventually emit
// 2. mark current place as next overflow checkpoint to eventually emit
//
//
// it is inserted
// it is inserted
// - before reading variable sized item
// - before reading
a
variable sized item
// - in the beginning of
loop inside XXX ok?
// - in the beginning of
a loop inside
func
(
d
*
decoder
)
overflowCheckpoint
()
{
func
(
d
*
decoder
)
overflowCheckpoint
()
{
//d.bufDone.emit("// overflow check point")
//d.bufDone.emit("// overflow check point")
if
!
d
.
overflowCheck
S
ize
.
IsZero
()
{
if
!
d
.
overflowCheck
.
s
ize
.
IsZero
()
{
d
.
bufDone
.
emit
(
"if uint32(len(data)) < %v { goto overflow }"
,
&
d
.
overflowCheck
S
ize
)
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
.
bufDone
.
Write
(
d
.
buf
.
Bytes
())
d
.
buf
.
Reset
()
d
.
buf
.
Reset
()
...
@@ -490,7 +530,7 @@ func (d *decoder) generatedCode() string {
...
@@ -490,7 +530,7 @@ func (d *decoder) generatedCode() string {
}
}
code
.
emit
(
"return %v, nil"
,
retexpr
)
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
{
if
(
&
types
.
StdSizes
{
8
,
8
})
.
Sizeof
(
d
.
typ
)
>
0
{
code
.
emit
(
"
\n
overflow:"
)
code
.
emit
(
"
\n
overflow:"
)
code
.
emit
(
"return 0, ErrDecodeOverflow"
)
code
.
emit
(
"return 0, ErrDecodeOverflow"
)
...
@@ -524,13 +564,9 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ
...
@@ -524,13 +564,9 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ
dataptr
:=
fmt
.
Sprintf
(
"data[%v:]"
,
d
.
n
)
dataptr
:=
fmt
.
Sprintf
(
"data[%v:]"
,
d
.
n
)
decoded
:=
fmt
.
Sprintf
(
basic
.
decode
,
dataptr
)
decoded
:=
fmt
.
Sprintf
(
basic
.
decode
,
dataptr
)
d
.
n
+=
basic
.
wireSize
d
.
n
+=
basic
.
wireSize
if
!
d
.
overflowChecked
{
d
.
overflowCheck
.
Add
(
basic
.
wireSize
)
d
.
overflowCheckSize
.
Add
(
basic
.
wireSize
)
}
if
userType
!=
nil
&&
userType
!=
typ
{
if
userType
!=
nil
&&
userType
!=
typ
{
// userType is a named type over some basic, like
// need to cast (like in encode case)
// type ClusterState int32
// -> need to cast
decoded
=
fmt
.
Sprintf
(
"%v(%v)"
,
typeName
(
userType
),
decoded
)
decoded
=
fmt
.
Sprintf
(
"%v(%v)"
,
typeName
(
userType
),
decoded
)
}
}
// NOTE no space before "=" - to be able to merge with ":"
// NOTE no space before "=" - to be able to merge with ":"
...
@@ -566,7 +602,7 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
...
@@ -566,7 +602,7 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
d
.
n
=
0
d
.
n
=
0
d
.
overflowCheckpoint
()
d
.
overflowCheckpoint
()
d
.
overflowCheck
Size
.
AddExpr
(
"l"
)
d
.
overflowCheck
.
AddExpr
(
"l"
)
switch
t
:=
typ
.
(
type
)
{
switch
t
:=
typ
.
(
type
)
{
case
*
types
.
Basic
:
case
*
types
.
Basic
:
...
@@ -576,7 +612,7 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
...
@@ -576,7 +612,7 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
d
.
emit
(
"%v= string(data[:l])"
,
assignto
)
d
.
emit
(
"%v= string(data[:l])"
,
assignto
)
case
*
types
.
Slice
:
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
(
"%v= make(%v, l)"
,
assignto
,
typeName
(
typ
))
d
.
emit
(
"copy(%v, data[:l])"
,
assignto
)
d
.
emit
(
"copy(%v, data[:l])"
,
assignto
)
...
@@ -603,9 +639,7 @@ func (d *decoder) genArray1(assignto string, typ *types.Array) {
...
@@ -603,9 +639,7 @@ func (d *decoder) genArray1(assignto string, typ *types.Array) {
typLen
:=
int
(
typ
.
Len
())
typLen
:=
int
(
typ
.
Len
())
d
.
emit
(
"copy(%v[:], data[%v:%v])"
,
assignto
,
d
.
n
,
d
.
n
+
typLen
)
d
.
emit
(
"copy(%v[:], data[%v:%v])"
,
assignto
,
d
.
n
,
d
.
n
+
typLen
)
d
.
n
+=
typLen
d
.
n
+=
typLen
if
!
d
.
overflowChecked
{
d
.
overflowCheck
.
Add
(
typLen
)
d
.
overflowCheckSize
.
Add
(
typLen
)
}
}
}
...
@@ -662,11 +696,11 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object)
...
@@ -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
// if size(item)==const - check overflow in one go
elemSize
,
elemFixed
:=
typeSizeFixed
(
typ
.
Elem
())
elemSize
,
elemFixed
:=
typeSizeFixed
(
typ
.
Elem
())
overflowCheckedCur
:=
d
.
overflowChecked
if
elemFixed
{
if
elemFixed
{
d
.
overflowCheckpoint
()
d
.
overflowCheckpoint
()
d
.
overflowCheckSize
.
AddExpr
(
"l * %v"
,
elemSize
)
d
.
overflowCheck
.
AddExpr
(
"l * %v"
,
elemSize
)
d
.
overflowChecked
=
true
d
.
overflowCheck
.
PushChecked
(
true
)
defer
d
.
overflowCheck
.
PopChecked
()
d
.
emit
(
"%v += l * %v"
,
d
.
var_
(
"nread"
),
elemSize
)
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)
...
@@ -691,8 +725,6 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object)
}
}
d
.
emit
(
"}"
)
d
.
emit
(
"}"
)
d
.
overflowChecked
=
overflowCheckedCur
d
.
emit
(
"}"
)
d
.
emit
(
"}"
)
}
}
...
@@ -759,11 +791,11 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
...
@@ -759,11 +791,11 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
keySize
,
keyFixed
:=
typeSizeFixed
(
typ
.
Key
())
keySize
,
keyFixed
:=
typeSizeFixed
(
typ
.
Key
())
elemSize
,
elemFixed
:=
typeSizeFixed
(
typ
.
Elem
())
elemSize
,
elemFixed
:=
typeSizeFixed
(
typ
.
Elem
())
itemFixed
:=
keyFixed
&&
elemFixed
itemFixed
:=
keyFixed
&&
elemFixed
overflowCheckedCur
:=
d
.
overflowChecked
if
itemFixed
{
if
itemFixed
{
d
.
overflowCheckpoint
()
d
.
overflowCheckpoint
()
d
.
overflowCheckSize
.
AddExpr
(
"l * %v"
,
keySize
+
elemSize
)
d
.
overflowCheck
.
AddExpr
(
"l * %v"
,
keySize
+
elemSize
)
d
.
overflowChecked
=
true
d
.
overflowCheck
.
PushChecked
(
true
)
defer
d
.
overflowCheck
.
PopChecked
()
d
.
emit
(
"%v += l * %v"
,
d
.
var_
(
"nread"
),
keySize
+
elemSize
)
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) {
...
@@ -800,8 +832,6 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
}
}
d
.
emit
(
"}"
)
d
.
emit
(
"}"
)
d
.
overflowChecked
=
overflowCheckedCur
d
.
emit
(
"}"
)
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