Commit daa5bbe8 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent e833702e
...@@ -381,10 +381,10 @@ func (s *SymSize) Reset() { ...@@ -381,10 +381,10 @@ func (s *SymSize) Reset() {
// decoder overflow check state // decoder overflow check state
type OverflowCheck struct { type OverflowCheck struct {
// accumulator for size to check at overflow check point // accumulator for size to check at overflow check point
size SymSize checkSize SymSize
// whether overflow was already checked for current decodings // whether overflow was already checked for current decodings
// (if yes, size updates will be ignored) // (if yes, checkSize updates will be ignored)
checked bool checked bool
// stack operated by {Push,Pop}Checked // stack operated by {Push,Pop}Checked
...@@ -407,17 +407,17 @@ func (o *OverflowCheck) PopChecked() bool { ...@@ -407,17 +407,17 @@ func (o *OverflowCheck) PopChecked() bool {
// Add and AddExpr update .size accordingly, but only if overflow was not // Add and AddExpr update .checkSize accordingly, but only if overflow was not
// already marked as checked // already marked as checked
func (o *OverflowCheck) Add(n int) { func (o *OverflowCheck) Add(n int) {
if !o.checked { if !o.checked {
o.size.Add(n) o.checkSize.Add(n)
} }
} }
func (o *OverflowCheck) AddExpr(format string, a ...interface{}) { func (o *OverflowCheck) AddExpr(format string, a ...interface{}) {
if !o.checked { if !o.checked {
o.size.AddExpr(format, a...) o.checkSize.AddExpr(format, a...)
} }
} }
...@@ -473,11 +473,11 @@ type decoder struct { ...@@ -473,11 +473,11 @@ type decoder struct {
bufDone Buffer bufDone Buffer
n int // current read position in data. n int // current read position in data.
nread int // numeric part of nread return XXX nread int // numeric part of total nread return
// overflow check state and size that will be checked for overflow at // overflow check state and size that will be checked for overflow at
// current overflow check point // current overflow check point
overflowCheck OverflowCheck overflow OverflowCheck
} }
var _ CodeGenerator = (*sizer)(nil) var _ CodeGenerator = (*sizer)(nil)
...@@ -530,7 +530,6 @@ func (d *decoder) resetPos() { ...@@ -530,7 +530,6 @@ func (d *decoder) resetPos() {
} }
// XXX place? // XXX place?
// XXX naming -> overflowCheck() ?
// mark current place for delayed insertion of overflow check code // mark current place for delayed insertion of overflow check code
// //
// delayed: because we go forward in decode path scanning ahead as far as we // delayed: because we go forward in decode path scanning ahead as far as we
...@@ -538,7 +537,7 @@ func (d *decoder) resetPos() { ...@@ -538,7 +537,7 @@ func (d *decoder) resetPos() {
// fixed size would be to read - insert checking condition for accumulated size // fixed size would be to read - insert checking condition for accumulated size
// to here-marked overflow checkpoint. // to here-marked overflow checkpoint.
// //
// so overflowCheckPoint does: // so overflowCheck does:
// 1. emit overflow checking code for previous overflow checkpoint // 1. emit overflow checking code for previous overflow checkpoint
// 2. mark current place as next overflow checkpoint to eventually emit // 2. mark current place as next overflow checkpoint to eventually emit
// //
...@@ -546,15 +545,15 @@ func (d *decoder) resetPos() { ...@@ -546,15 +545,15 @@ func (d *decoder) resetPos() {
// - before reading a variable sized item // - before reading a variable sized item
// - in the beginning of a loop inside // - in the beginning of a loop inside
// - right after loop exit // - right after loop exit
func (d *decoder) overflowCheckPoint() { func (d *decoder) overflowCheck() {
// nop if we know overflow was already checked // nop if we know overflow was already checked
if d.overflowCheck.checked { if d.overflow.checked {
return return
} }
//d.bufDone.emit("// overflow check point") //d.bufDone.emit("// overflow check point")
if !d.overflowCheck.size.IsZero() { if !d.overflow.checkSize.IsZero() {
d.bufDone.emit("if uint32(len(data)) < %v { goto overflow }", &d.overflowCheck.size) d.bufDone.emit("if uint32(len(data)) < %v { goto overflow }", &d.overflow.checkSize)
// if size for overflow check was only numeric - just // if size for overflow check was only numeric - just
// accumulate it at compile time // accumulate it at compile time
...@@ -564,14 +563,14 @@ func (d *decoder) overflowCheckPoint() { ...@@ -564,14 +563,14 @@ func (d *decoder) overflowCheckPoint() {
// parts, because just above whole expression num + symbolic // parts, because just above whole expression num + symbolic
// was just given to compiler so compiler shoud have it just computed. // was just given to compiler so compiler shoud have it just computed.
// XXX recheck ^^^ actually good with the compiler // XXX recheck ^^^ actually good with the compiler
if d.overflowCheck.size.IsNumeric() { if d.overflow.checkSize.IsNumeric() {
d.nread += d.overflowCheck.size.num d.nread += d.overflow.checkSize.num
} else { } else {
d.bufDone.emit("%v += %v", d.var_("nread"), &d.overflowCheck.size) d.bufDone.emit("%v += %v", d.var_("nread"), &d.overflow.checkSize)
} }
} }
d.overflowCheck.size.Reset() d.overflow.checkSize.Reset()
d.bufDone.Write(d.buf.Bytes()) d.bufDone.Write(d.buf.Bytes())
d.buf.Reset() d.buf.Reset()
...@@ -579,7 +578,7 @@ func (d *decoder) overflowCheckPoint() { ...@@ -579,7 +578,7 @@ func (d *decoder) overflowCheckPoint() {
func (d *decoder) generatedCode() string { func (d *decoder) generatedCode() string {
// flush for last overflow check point // flush for last overflow check point
d.overflowCheckPoint() d.overflowCheck()
code := Buffer{} code := Buffer{}
// prologue // prologue
...@@ -640,7 +639,7 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ ...@@ -640,7 +639,7 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ
d.emit("%s= %s", assignto, decoded) d.emit("%s= %s", assignto, decoded)
d.n += basic.wireSize d.n += basic.wireSize
d.overflowCheck.Add(basic.wireSize) d.overflow.Add(basic.wireSize)
} }
// emit code to size/encode/decode array with sizeof(elem)==1 // emit code to size/encode/decode array with sizeof(elem)==1
...@@ -658,7 +657,7 @@ func (d *decoder) genArray1(assignto string, typ *types.Array) { ...@@ -658,7 +657,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
d.overflowCheck.Add(typLen) d.overflow.Add(typLen)
} }
// emit code to size/encode/decode string or []byte // emit code to size/encode/decode string or []byte
...@@ -686,8 +685,8 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) { ...@@ -686,8 +685,8 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
d.resetPos() d.resetPos()
d.overflowCheckPoint() d.overflowCheck()
d.overflowCheck.AddExpr("l") d.overflow.AddExpr("l")
switch t := typ.(type) { switch t := typ.(type) {
case *types.Basic: case *types.Basic:
...@@ -764,19 +763,19 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object) ...@@ -764,19 +763,19 @@ 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())
if elemFixed { if elemFixed {
d.overflowCheckPoint() d.overflowCheck()
d.overflowCheck.AddExpr("l * %v", elemSize) d.overflow.AddExpr("l * %v", elemSize)
d.overflowCheck.PushChecked(true) d.overflow.PushChecked(true)
defer d.overflowCheck.PopChecked() defer d.overflow.PopChecked()
} }
d.emit("%v= make(%v, l)", assignto, typeName(typ)) d.emit("%v= make(%v, l)", assignto, typeName(typ))
d.emit("for i := 0; uint32(i) < l; i++ {") d.emit("for i := 0; uint32(i) < l; i++ {")
d.emit("a := &%s[i]", assignto) d.emit("a := &%s[i]", assignto)
d.overflowCheckPoint() // -> overflowCheckPointLoopEntry ? d.overflowCheck() // -> overflowCheckLoopEntry ?
var nreadCur int var nreadCur int
if !d.overflowCheck.checked { // TODO merge-in into overflow checker if !d.overflow.checked { // TODO merge-in into overflow checker
nreadCur = d.nread nreadCur = d.nread
d.nread = 0 d.nread = 0
} }
...@@ -786,10 +785,10 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object) ...@@ -786,10 +785,10 @@ func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object)
d.resetPos() d.resetPos()
d.emit("}") d.emit("}")
d.overflowCheckPoint() // -> overflowCheckPointLoopExit("l") ? d.overflowCheck() // -> overflowCheckPointLoopExit("l") ?
// merge-in numeric nread updates from loop // merge-in numeric nread updates from loop
if !d.overflowCheck.checked { if !d.overflow.checked {
if d.nread != 0 { if d.nread != 0 {
d.emit("%v += l * %v", d.var_("nread"), d.nread) d.emit("%v += l * %v", d.var_("nread"), d.nread)
} }
...@@ -863,19 +862,19 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) { ...@@ -863,19 +862,19 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
elemSize, elemFixed := typeSizeFixed(typ.Elem()) elemSize, elemFixed := typeSizeFixed(typ.Elem())
itemFixed := keyFixed && elemFixed itemFixed := keyFixed && elemFixed
if itemFixed { if itemFixed {
d.overflowCheckPoint() d.overflowCheck()
d.overflowCheck.AddExpr("l * %v", keySize + elemSize) d.overflow.AddExpr("l * %v", keySize + elemSize)
d.overflowCheck.PushChecked(true) d.overflow.PushChecked(true)
defer d.overflowCheck.PopChecked() defer d.overflow.PopChecked()
} }
d.emit("%v= make(%v, l)", assignto, typeName(typ)) d.emit("%v= make(%v, l)", assignto, typeName(typ))
d.emit("m := %v", assignto) d.emit("m := %v", assignto)
d.emit("for i := 0; uint32(i) < l; i++ {") d.emit("for i := 0; uint32(i) < l; i++ {")
d.overflowCheckPoint() // -> overflowCheckPointLoopEntry ? d.overflowCheck() // -> overflowCheckPointLoopEntry ?
var nreadCur int var nreadCur int
if !d.overflowCheck.checked { // TODO merge-in into overflow checker if !d.overflow.checked { // TODO merge-in into overflow checker
nreadCur = d.nread nreadCur = d.nread
d.nread = 0 d.nread = 0
} }
...@@ -897,10 +896,10 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) { ...@@ -897,10 +896,10 @@ func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
d.resetPos() d.resetPos()
d.emit("}") d.emit("}")
d.overflowCheckPoint() // -> overflowCheckPointLoopExit("l") ? d.overflowCheck() // -> overflowCheckPointLoopExit("l") ?
// merge-in numeric nread updates from loop // merge-in numeric nread updates from loop
if !d.overflowCheck.checked { if !d.overflow.checked {
if d.nread != 0 { if d.nread != 0 {
d.emit("%v += l * %v", d.var_("nread"), d.nread) d.emit("%v += l * %v", d.var_("nread"), d.nread)
} }
......
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