Commit 1e542169 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent eaa81cd4
This diff is collapsed.
...@@ -234,59 +234,59 @@ type CodecCodeGen interface { ...@@ -234,59 +234,59 @@ type CodecCodeGen interface {
} }
// sizer/encode/decode codegen // sizer/encode/decode codegen
type coderForFunc struct { type commonCoder struct {
recvName string // receiver/type for top-level func recvName string // receiver/type for top-level func
typeName string // or empty typeName string // or empty
varN int // suffix to add to variables (size0, size1, ...) - for nested computations
varUsed map[string]bool // whether a variable was used
} }
func (c *coderForFunc) setFunc(recvName, typeName string) { func (c *commonCoder) setFunc(recvName, typeName string) {
c.recvName = recvName c.recvName = recvName
c.typeName = typeName c.typeName = typeName
} }
// get variable name for varname
func (c *commonCoder) var__(varname string) string {
return fmt.Sprintf("%s%d", varname, c.varN)
}
func (c *commonCoder) var_(varname string) string {
varnameX := c.var__(varname)
if c.varUsed == nil {
c.varUsed = make(map[string]bool)
}
c.varUsed[varname] = true
return varnameX
}
type sizer struct { type sizer struct {
Buffer // buffer for code Buffer // buffer for code
n int // fixed part of size n int // fixed part of size
symLenv []string // symbolic part of size symLenv []string // symbolic part of size
varN int // suffix to add to variables (size0, size1, ...) - for nested computations commonCoder
varUsed map[string]bool // whether a variable was used
coderForFunc
}
// get variable name for varname
func (s *sizer) var__(varname string) string {
return fmt.Sprintf("%s%d", varname, s.varN)
}
func (s *sizer) var_(varname string) string {
varnameX := s.var__(varname)
if s.varUsed == nil {
s.varUsed = make(map[string]bool)
}
s.varUsed[varname] = true
return varnameX
} }
// create new sizer for subsize calculation (e.g. for loop) // create new sizer for subsize calculation (e.g. for loop)
func (s *sizer) subSizer() *sizer { func (s *sizer) subSizer() *sizer {
return &sizer{varN: s.varN + 1} return &sizer{commonCoder: commonCoder{varN: s.varN + 1}}
} }
type encoder struct { type encoder struct {
Buffer // XXX Buffer // XXX
n int n int
coderForFunc commonCoder
} }
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 commonCoder
} }
var _ CodecCodeGen = (*sizer)(nil) var _ CodecCodeGen = (*sizer)(nil)
...@@ -354,12 +354,19 @@ func (d *decoder) generatedCode() string { ...@@ -354,12 +354,19 @@ func (d *decoder) generatedCode() string {
if d.recvName != "" { if d.recvName != "" {
code.emit("func (%s *%s) NEODecode(data []byte) (int, error) {", d.recvName, d.typeName) code.emit("func (%s *%s) NEODecode(data []byte) (int, error) {", d.recvName, d.typeName)
} }
code.emit("var nread uint32") if d.varUsed["nread"] {
code.emit("var %v uint32", d.var__("nread"))
}
code.Write(d.Bytes()) // XXX -> d.buf.Bytes() ? code.Write(d.Bytes()) // XXX -> d.buf.Bytes() ?
// epilogue // epilogue
code.emit("return int(nread) + %v, nil", d.n) retexpr := fmt.Sprintf("%v", d.n)
if d.varUsed["nread"] {
retexpr += fmt.Sprintf(" + int(%v)", d.var__("nread"))
}
code.emit("return %v, nil", retexpr)
code.emit("\noverflow:") code.emit("\noverflow:")
code.emit("return 0, ErrDecodeOverflow") code.emit("return 0, ErrDecodeOverflow")
code.emit("goto overflow") // TODO check if overflow used at all and remove code.emit("goto overflow") // TODO check if overflow used at all and remove
...@@ -431,7 +438,7 @@ func (d *decoder) genStrBytes(assignto string) { ...@@ -431,7 +438,7 @@ func (d *decoder) genStrBytes(assignto string) {
d.emit("if uint32(len(data)) < l { goto overflow }") d.emit("if uint32(len(data)) < l { goto overflow }")
d.emit("%v= string(data[:l])", assignto) d.emit("%v= string(data[:l])", assignto)
d.emit("data = data[l:]") d.emit("data = data[l:]")
d.emit("nread += %v + l", d.n) d.emit("%v += %v + l", d.var_("nread"), d.n)
d.emit("}") d.emit("}")
d.n = 0 d.n = 0
} }
...@@ -481,7 +488,7 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object) ...@@ -481,7 +488,7 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object)
d.emit("{") d.emit("{")
d.genBasic("l:", types.Typ[types.Uint32], nil) d.genBasic("l:", types.Typ[types.Uint32], nil)
d.emit("data = data[%v:]", d.n) d.emit("data = data[%v:]", d.n)
d.emit("nread += %v", d.n) d.emit("%v += %v", d.var_("nread"), d.n)
d.n = 0 d.n = 0
d.emit("%v= make(%v, l)", assignto, typeName(typ)) d.emit("%v= make(%v, l)", assignto, typeName(typ))
// TODO size check // TODO size check
...@@ -492,7 +499,7 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object) ...@@ -492,7 +499,7 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object)
// XXX try to avoid (*) in a // XXX try to avoid (*) in a
codegenType("(*a)", typ.Elem(), obj, d) codegenType("(*a)", typ.Elem(), obj, d)
d.emit("data = data[%v:]", d.n) // FIXME wrt slice of slice ? d.emit("data = data[%v:]", d.n) // FIXME wrt slice of slice ?
d.emit("nread += %v", d.n) d.emit("%v += %v", d.var_("nread"), d.n)
d.emit("}") d.emit("}")
//d.emit("%v= string(data[:l])", assignto) //d.emit("%v= string(data[:l])", assignto)
d.emit("}") d.emit("}")
...@@ -548,7 +555,7 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) { ...@@ -548,7 +555,7 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
d.emit("{") d.emit("{")
d.genBasic("l:", types.Typ[types.Uint32], nil) d.genBasic("l:", types.Typ[types.Uint32], nil)
d.emit("data = data[%v:]", d.n) d.emit("data = data[%v:]", d.n)
d.emit("nread += %v", d.n) d.emit("%v += %v", d.var_("nread"), d.n)
d.n = 0 d.n = 0
d.emit("%v= make(%v, l)", assignto, typeName(typ)) d.emit("%v= make(%v, l)", assignto, typeName(typ))
// TODO size check // TODO size check
...@@ -572,7 +579,7 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) { ...@@ -572,7 +579,7 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
} }
d.emit("data = data[%v:]", d.n) // FIXME wrt map of map ? d.emit("data = data[%v:]", d.n) // FIXME wrt map of map ?
d.emit("nread += %v", d.n) d.emit("%v += %v", d.var_("nread"), d.n)
d.emit("}") d.emit("}")
//d.emit("%v= string(data[:l])", assignto) //d.emit("%v= string(data[:l])", assignto)
d.emit("}") d.emit("}")
......
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