// Replace len([]rune(string)) with runtime.countrunes(string).
return mkcall("countrunes", n.Type(), init, typecheck.Conv(n.X.(*ir.ConvExpr).X, types.Types[types.TSTRING]))
}
+ if isByteCount(n) {
+ _, len := backingArrayPtrLen(cheapExpr(n.X.(*ir.ConvExpr).X, init))
+ return len
+ }
n.X = walkExpr(n.X, init)
func isRuneCount(n ir.Node) bool {
return base.Flag.N == 0 && !base.Flag.Cfg.Instrumenting && n.Op() == ir.OLEN && n.(*ir.UnaryExpr).X.Op() == ir.OSTR2RUNES
}
+
+// isByteCount reports whether n is of the form len(string([]byte)).
+func isByteCount(n ir.Node) bool {
+ return base.Flag.N == 0 && !base.Flag.Cfg.Instrumenting && n.Op() == ir.OLEN &&
+ (n.(*ir.UnaryExpr).X.Op() == ir.OBYTES2STR || n.(*ir.UnaryExpr).X.Op() == ir.OBYTES2STRTMP)
+}
return len([]rune(s))
}
+func CountBytes(s []byte) int {
+ // amd64:-`.*runtime.slicebytetostring`
+ return len(string(s))
+}
+
func ToByteSlice() []byte { // Issue #24698
// amd64:`LEAQ\ttype:\[3\]uint8`
// amd64:`CALL\truntime\.newobject`