Commit 8d794c02 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 7429c8ba
...@@ -404,9 +404,10 @@ func (p *AcceptIdentification) NEOEncodedLen() int { ...@@ -404,9 +404,10 @@ func (p *AcceptIdentification) NEOEncodedLen() int {
size += 30 size += 30
for i := 0; i < len(p.KnownMasterList); i++ { for i := 0; i < len(p.KnownMasterList); i++ {
a := &p.KnownMasterList[i] a := &p.KnownMasterList[i]
size += 10 + len((*a).Address.Host) size += 10 + len((*a).Address.Host)
} }
return 0 + len(p.Primary.Host) + size return 30 + len(p.Primary.Host) + size
} }
func (p *AcceptIdentification) NEOEncode(data []byte) { func (p *AcceptIdentification) NEOEncode(data []byte) {
...@@ -726,9 +727,10 @@ func (p *AnswerPartitionTable) NEOEncodedLen() int { ...@@ -726,9 +727,10 @@ func (p *AnswerPartitionTable) NEOEncodedLen() int {
size += 12 size += 12
for i := 0; i < len(p.RowList); i++ { for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i] a := &p.RowList[i]
size += 8 + len((*a).CellList)*8 size += 8 + len((*a).CellList)*8
} }
return 0 + size return 12 + size
} }
func (p *AnswerPartitionTable) NEOEncode(data []byte) { func (p *AnswerPartitionTable) NEOEncode(data []byte) {
...@@ -816,9 +818,10 @@ func (p *NotifyPartitionTable) NEOEncodedLen() int { ...@@ -816,9 +818,10 @@ func (p *NotifyPartitionTable) NEOEncodedLen() int {
size += 12 size += 12
for i := 0; i < len(p.RowList); i++ { for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i] a := &p.RowList[i]
size += 8 + len((*a).CellList)*8 size += 8 + len((*a).CellList)*8
} }
return 0 + size return 12 + size
} }
func (p *NotifyPartitionTable) NEOEncode(data []byte) { func (p *NotifyPartitionTable) NEOEncode(data []byte) {
...@@ -2600,9 +2603,10 @@ func (p *AnswerPartitionList) NEOEncodedLen() int { ...@@ -2600,9 +2603,10 @@ func (p *AnswerPartitionList) NEOEncodedLen() int {
size += 12 size += 12
for i := 0; i < len(p.RowList); i++ { for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i] a := &p.RowList[i]
size += 8 + len((*a).CellList)*8 size += 8 + len((*a).CellList)*8
} }
return 0 + size return 12 + size
} }
func (p *AnswerPartitionList) NEOEncode(data []byte) { func (p *AnswerPartitionList) NEOEncode(data []byte) {
...@@ -2713,9 +2717,10 @@ func (p *AnswerNodeList) NEOEncodedLen() int { ...@@ -2713,9 +2717,10 @@ func (p *AnswerNodeList) NEOEncodedLen() int {
size += 4 size += 4
for i := 0; i < len(p.NodeList); i++ { for i := 0; i < len(p.NodeList); i++ {
a := &p.NodeList[i] a := &p.NodeList[i]
size += 26 + len((*a).Address.Host) size += 26 + len((*a).Address.Host)
} }
return 0 + size return 4 + size
} }
func (p *AnswerNodeList) NEOEncode(data []byte) { func (p *AnswerNodeList) NEOEncode(data []byte) {
...@@ -2925,9 +2930,10 @@ func (p *NotifyNodeInformation) NEOEncodedLen() int { ...@@ -2925,9 +2930,10 @@ func (p *NotifyNodeInformation) NEOEncodedLen() int {
size += 4 size += 4
for i := 0; i < len(p.NodeList); i++ { for i := 0; i < len(p.NodeList); i++ {
a := &p.NodeList[i] a := &p.NodeList[i]
size += 26 + len((*a).Address.Host) size += 26 + len((*a).Address.Host)
} }
return 0 + size return 4 + size
} }
func (p *NotifyNodeInformation) NEOEncode(data []byte) { func (p *NotifyNodeInformation) NEOEncode(data []byte) {
......
...@@ -210,8 +210,8 @@ func (b *Buffer) emit(format string, a ...interface{}) { ...@@ -210,8 +210,8 @@ func (b *Buffer) emit(format string, a ...interface{}) {
// interface of codegenerator for coder/decoder // interface of codegenerator for coder/decoder
type CodecCodeGen interface { type CodecCodeGen interface {
genPrologue(recvName, typeName string) // tell codegen it should generate code for top-level function
genEpilogue() setFunc(recvName, typeName string)
// emit code to process basic fixed types (not string) // emit code to process basic fixed types (not string)
// userType is type actually used in source (for which typ is underlying), or nil // userType is type actually used in source (for which typ is underlying), or nil
...@@ -223,44 +223,68 @@ type CodecCodeGen interface { ...@@ -223,44 +223,68 @@ type CodecCodeGen interface {
// XXX particular case of slice // XXX particular case of slice
genStrBytes(path string) genStrBytes(path string)
// get generated code.
// for top-level functions this is whole function including return and closing }
// for not function this is generated code needed for resultExpr()
generatedCode() string generatedCode() string
// get result expression
// this is result of computations for not top-level code XXX
resultExpr() string
} }
// sizer/encode/decode codegen // sizer/encode/decode codegen
type coderForFunc struct {
recvName string // receiver/type for top-level func
typeName string // or empty
}
func (c *coderForFunc) setFunc(recvName, typeName string) {
c.recvName = recvName
c.typeName = typeName
}
type sizer struct { type sizer struct {
Buffer // XXX Buffer // buffer for code
n int n int // fixed part of size
symLenv []string // symbolic lengths to add to size symLenv []string // symbolic part of size
varN int // suffix to add to variables (size0, size1, ...) - for nested computations
varSizeUsed bool // whether var size was used varSizeUsed bool // whether var size was used
recvName string // receiver/type for top-level func coderForFunc
typeName string // or empty }
// get variable name for varname
func (s *sizer) var_(varname string) string {
return fmt.Sprintf("%s%d", varname, s.varN)
}
// create new sizer for subsize calculation (e.g. for loop)
func (s *sizer) subSizer() *sizer {
return &sizer{varN: s.varN + 1}
} }
type encoder struct { type encoder struct {
Buffer // XXX Buffer // XXX
n int n int
coderForFunc
} }
type decoder struct { type decoder struct {
Buffer // buffer for generated code Buffer // buffer for generated code
n int // current decode position in data n int // current decode position in data
coderForFunc
} }
var _ CodecCodeGen = (*sizer)(nil) var _ CodecCodeGen = (*sizer)(nil)
var _ CodecCodeGen = (*encoder)(nil) var _ CodecCodeGen = (*encoder)(nil)
var _ CodecCodeGen = (*decoder)(nil) var _ CodecCodeGen = (*decoder)(nil)
func (s *sizer) generatedCode() string { func (s *sizer) resultExpr() string {
prologue := Buffer{}
if s.recvName != "" {
prologue.emit("func (%s *%s) NEOEncodedLen() int {", s.recvName, s.typeName)
}
if s.varSizeUsed {
prologue.emit("var size int")
}
epilogue := Buffer{}
size := fmt.Sprintf("%v", s.n) size := fmt.Sprintf("%v", s.n)
if len(s.symLenv) > 0 { if len(s.symLenv) > 0 {
size += " + " + strings.Join(s.symLenv, " + ") size += " + " + strings.Join(s.symLenv, " + ")
...@@ -268,61 +292,74 @@ func (s *sizer) generatedCode() string { ...@@ -268,61 +292,74 @@ func (s *sizer) generatedCode() string {
if s.varSizeUsed { if s.varSizeUsed {
size += " + size" size += " + size"
} }
epilogue.emit("return %v", size) return size
epilogue.emit("}\n")
return prologue.String() + s.String() + epilogue.String() // XXX -> d.buf.String() ?
} }
func (e *encoder) generatedCode() string { func (s *sizer) generatedCode() string {
return e.String() // XXX -> d.buf.String() ? code := Buffer{}
} // prologue
if s.recvName != "" {
code.emit("func (%s *%s) NEOEncodedLen() int {", s.recvName, s.typeName)
}
if s.varSizeUsed {
code.emit("var size int")
}
func (d *decoder) generatedCode() string { code.Write(s.Bytes()) // XXX -> s.buf.Bytes() ?
return d.String() // XXX -> d.buf.String() ?
}
func (s *sizer) genPrologue(recvName, typeName string) { // epilogue
s.recvName = recvName if s.recvName != "" {
s.typeName = typeName code.emit("return %v", s.resultExpr())
//s.emit("func (%s *%s) NEOEncodedLen() int {", recvName, typeName) code.emit("}\n")
} }
func (e *encoder) genPrologue(recvName, typeName string) { return code.String()
e.emit("func (%s *%s) NEOEncode(data []byte) {", recvName, typeName)
} }
func (d *decoder) genPrologue(recvName, typeName string) { func (e *encoder) resultExpr() string {
d.emit("func (%s *%s) NEODecode(data []byte) (int, error) {", recvName, typeName) panic("should not be called (?)")
d.emit("var nread uint32")
} }
func (s *sizer) genEpilogue() { func (e *encoder) generatedCode() string {
/* code := Buffer{}
size := fmt.Sprintf("%v", s.n) // prologue
if len(s.symLenv) > 0 { if e.recvName != "" {
size += " + " + strings.Join(s.symLenv, " + ") code.emit("func (%s *%s) NEOEncode(data []byte) {", e.recvName, e.typeName)
}
if s.varSizeUsed {
size += " + size"
} }
s.emit("return %v", size)
s.emit("}\n") code.Write(e.Bytes()) // XXX -> e.buf.Bytes() ?
*/
// epilogue
code.emit("}\n")
return code.String()
} }
func (e *encoder) genEpilogue() { func (d *decoder) resultExpr() string {
e.emit("}\n") panic("should not be called (?)")
} }
func (d *decoder) genEpilogue() { func (d *decoder) generatedCode() string {
d.emit("return int(nread) + %v, nil", d.n) code := Buffer{}
d.emit("\noverflow:") // prologue
d.emit("return 0, ErrDecodeOverflow") if d.recvName != "" {
d.emit("goto overflow") // TODO check if overflow used at all and remove code.emit("func (%s *%s) NEODecode(data []byte) (int, error) {", d.recvName, d.typeName)
d.emit("}\n") }
code.emit("var nread uint32")
code.Write(d.Bytes()) // XXX -> d.buf.Bytes() ?
// epilogue
code.emit("return int(nread) + %v, nil", d.n)
code.emit("\noverflow:")
code.emit("return 0, ErrDecodeOverflow")
code.emit("goto overflow") // TODO check if overflow used at all and remove
code.emit("}\n")
return code.String()
} }
func (s *sizer) genBasic(path string, typ *types.Basic, userType types.Type) { func (s *sizer) genBasic(path string, typ *types.Basic, userType types.Type) {
basic := basicTypes[typ.Kind()] basic := basicTypes[typ.Kind()]
s.n += basic.wireSize s.n += basic.wireSize
...@@ -365,7 +402,6 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ ...@@ -365,7 +402,6 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ
func (s *sizer) genStrBytes(path string) { func (s *sizer) genStrBytes(path string) {
s.n += 4 s.n += 4
s.symLenv = append(s.symLenv, fmt.Sprintf("len(%s)", path)) s.symLenv = append(s.symLenv, fmt.Sprintf("len(%s)", path))
//s.n = 0
} }
func (e *encoder) genStrBytes(path string) { func (e *encoder) genStrBytes(path string) {
...@@ -407,16 +443,15 @@ func (s *sizer) genSlice(path string, typ *types.Slice, obj types.Object) { ...@@ -407,16 +443,15 @@ func (s *sizer) genSlice(path string, typ *types.Slice, obj types.Object) {
s.varSizeUsed = true s.varSizeUsed = true
s.n += 4 s.n += 4
s.emit("size += %v", s.n) s.emit("size += %v", s.n)
s.n = 0
s.emit("for i := 0; i < len(%v); i++ {", path) s.emit("for i := 0; i < len(%v); i++ {", path)
s.emit("a := &%s[i]", path) s.emit("a := &%s[i]", path)
//codegenType("(*a)", typ.Elem(), obj, s) //codegenType("(*a)", typ.Elem(), obj, s)
sloop := &sizer{} sloop := s.subSizer()
codegenType("(*a)", typ.Elem(), obj, sloop) codegenType("(*a)", typ.Elem(), obj, sloop)
// FIXME vvv if symLenv is ø; -> turn into "result" function // FIXME vvv if symLenv is ø; -> turn into "result" function
s.emit("size += %v + %v", sloop.n, strings.Join(sloop.symLenv, " + ")) s.emit(sloop.generatedCode())
s.emit("size += %v", sloop.resultExpr())
s.emit("}") s.emit("}")
s.n = 0
} }
func (e *encoder) genSlice(path string, typ *types.Slice, obj types.Object) { func (e *encoder) genSlice(path string, typ *types.Slice, obj types.Object) {
...@@ -470,8 +505,10 @@ func (s *sizer) genMap(path string, typ *types.Map, obj types.Object) { ...@@ -470,8 +505,10 @@ func (s *sizer) genMap(path string, typ *types.Map, obj types.Object) {
return return
} }
panic("UNTESTED")
s.varSizeUsed = true s.varSizeUsed = true
s.emit("size += %v + 4", s.n) s.n += 4
s.emit("size += %v", s.n)
s.n = 0 s.n = 0
s.emit("for key := range %s {", path) s.emit("for key := range %s {", path)
codegenType("key", typ.Key(), obj, s) codegenType("key", typ.Key(), obj, s)
...@@ -591,7 +628,7 @@ func codegenType(path string, typ types.Type, obj types.Object, codegen CodecCod ...@@ -591,7 +628,7 @@ func codegenType(path string, typ types.Type, obj types.Object, codegen CodecCod
// generate encoder/decode funcs for a type declaration typespec // generate encoder/decode funcs for a type declaration typespec
func generateCodecCode(typespec *ast.TypeSpec, codec CodecCodeGen) string { func generateCodecCode(typespec *ast.TypeSpec, codec CodecCodeGen) string {
codec.genPrologue("p", typespec.Name.Name) codec.setFunc("p", typespec.Name.Name)
// type & object which refers to this type // type & object which refers to this type
typ := info.Types[typespec.Type].Type typ := info.Types[typespec.Type].Type
...@@ -599,6 +636,5 @@ func generateCodecCode(typespec *ast.TypeSpec, codec CodecCodeGen) string { ...@@ -599,6 +636,5 @@ func generateCodecCode(typespec *ast.TypeSpec, codec CodecCodeGen) string {
codegenType("p", typ, obj, codec) codegenType("p", typ, obj, codec)
codec.genEpilogue()
return codec.generatedCode() return codec.generatedCode()
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment