Browse Source

codec: do not check for bounds in bytesDecReader.

Instead, allow the bounds checking to happen and throw an error.
This will be caught during recover and translated to an io.EOF.
Ugorji Nwoke 6 years ago
parent
commit
c9665baae2
2 changed files with 24 additions and 16 deletions
  1. 7 0
      codec/helper.go
  2. 17 16
      codec/reader.go

+ 7 - 0
codec/helper.go

@@ -107,6 +107,13 @@ package codec
 // but we had to explicitly reference the fields as opposed to using a function
 // but we had to explicitly reference the fields as opposed to using a function
 // to get the better performance that we were looking for.
 // to get the better performance that we were looking for.
 // For example, we explicitly call d.d.decRd.fn() instead of d.d.r().fn().
 // For example, we explicitly call d.d.decRd.fn() instead of d.d.r().fn().
+//
+// ------------------------------------------
+// Bounds Checking
+//    - Allow bytesDecReader to incur "bounds check error", and
+//      recover that as an io.EOF.
+//      This allows the bounds check branch to always be taken by the branch predictor,
+//      giving better performance (in theory), while ensuring that the code is shorter.
 
 
 import (
 import (
 	"bytes"
 	"bytes"

+ 17 - 16
codec/reader.go

@@ -850,7 +850,7 @@ func (z *bytesDecReader) readn1() (v uint8) {
 }
 }
 
 
 func (z *bytesDecReader) readn(num uint8) (bs [rwNLen]byte) {
 func (z *bytesDecReader) readn(num uint8) (bs [rwNLen]byte) {
-	// if z.c+2 >= uint(len(z.b)) {
+	// if z.c >= uint(len(z.b)) || z.c+uint(num) >= uint(len(z.b)) {
 	// 	panic(io.EOF)
 	// 	panic(io.EOF)
 	// }
 	// }
 
 
@@ -914,8 +914,9 @@ LOOP:
 	z.c = i
 	z.c = i
 	return
 	return
 	// }
 	// }
-	// END:
 	// panic(io.EOF)
 	// panic(io.EOF)
+
+	// END:
 	// // z.a = 0
 	// // z.a = 0
 	// z.c = blen
 	// z.c = blen
 	// return
 	// return
@@ -992,24 +993,24 @@ func (z *bytesDecReader) readUntil(stop byte, includeLast bool) (out []byte) {
 	// 	}
 	// 	}
 	// }
 	// }
 LOOP:
 LOOP:
-	if i < uint(len(z.b)) {
-		if z.b[i] == stop {
-			i++
-			if includeLast {
-				out = z.b[z.c:i]
-			} else {
-				out = z.b[z.c : i-1]
-			}
-			// z.a -= (i - z.c)
-			z.c = i
-			return
-		}
+	// if i < uint(len(z.b)) {
+	if z.b[i] == stop {
 		i++
 		i++
-		goto LOOP
+		if includeLast {
+			out = z.b[z.c:i]
+		} else {
+			out = z.b[z.c : i-1]
+		}
+		// z.a -= (i - z.c)
+		z.c = i
+		return
 	}
 	}
+	i++
+	goto LOOP
+	// }
+	// panic(io.EOF)
 	// z.a = 0
 	// z.a = 0
 	// z.c = blen
 	// z.c = blen
-	panic(io.EOF)
 }
 }
 
 
 func (z *bytesDecReader) track() {
 func (z *bytesDecReader) track() {