cmd/compile,runtime: provide index information on bounds check failure

A few examples (for accessing a slice of length 3):

   s[-1]    runtime error: index out of range [-1]
   s[3]     runtime error: index out of range [3] with length 3
   s[-1:0]  runtime error: slice bounds out of range [-1:]
   s[3:0]   runtime error: slice bounds out of range [3:0]
   s[3:-1]  runtime error: slice bounds out of range [:-1]
   s[3:4]   runtime error: slice bounds out of range [:4] with capacity 3
   s[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3

Note that in cases where there are multiple things wrong with the
indexes (e.g. s[3:-1]), we report one of those errors kind of
arbitrarily, currently the rightmost one.

An exhaustive set of examples is in issue30116[u].out in the CL.

The message text has the same prefix as the old message text. That
leads to slightly awkward phrasing but hopefully minimizes the chance
that code depending on the error text will break.

Increases the size of the go binary by 0.5% (amd64). The panic functions
take arguments in registers in order to keep the size of the compiled code
as small as possible.

Fixes #30116

Change-Id: Idb99a827b7888822ca34c240eca87b7e44a04fdd
Reviewed-on: https://go-review.googlesource.com/c/go/+/161477
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Keith Randall 2019-02-06 14:12:36 -08:00 committed by Keith Randall
parent b48bda9c6f
commit 2c423f063b
59 changed files with 4464 additions and 355 deletions

View file

@ -926,6 +926,20 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.OpAMD64LoweredPanicBoundsA, ssa.OpAMD64LoweredPanicBoundsB, ssa.OpAMD64LoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(int64(2 * gc.Widthptr)) // space used in callee args area by assembly stubs
case ssa.OpAMD64LoweredPanicExtendA, ssa.OpAMD64LoweredPanicExtendB, ssa.OpAMD64LoweredPanicExtendC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
s.UseArgs(int64(3 * gc.Widthptr)) // space used in callee args area by assembly stubs
case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:

View file

@ -711,6 +711,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.OpARMLoweredPanicBoundsA, ssa.OpARMLoweredPanicBoundsB, ssa.OpARMLoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(8) // space used in callee args area by assembly stubs
case ssa.OpARMLoweredPanicExtendA, ssa.OpARMLoweredPanicExtendB, ssa.OpARMLoweredPanicExtendC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
s.UseArgs(12) // space used in callee args area by assembly stubs
case ssa.OpARMDUFFZERO:
p := s.Prog(obj.ADUFFZERO)
p.To.Type = obj.TYPE_MEM

View file

@ -846,6 +846,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.OpARM64LoweredPanicBoundsA, ssa.OpARM64LoweredPanicBoundsB, ssa.OpARM64LoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(16) // space used in callee args area by assembly stubs
case ssa.OpARM64LoweredNilCheck:
// Issue a load which will fault if arg is nil.
p := s.Prog(arm64.AMOVB)

View file

@ -10,8 +10,6 @@ var runtimeDecls = [...]struct {
typ int
}{
{"newobject", funcTag, 4},
{"panicindex", funcTag, 5},
{"panicslice", funcTag, 5},
{"panicdivide", funcTag, 5},
{"panicshift", funcTag, 5},
{"panicmakeslicelen", funcTag, 5},
@ -20,138 +18,154 @@ var runtimeDecls = [...]struct {
{"gopanic", funcTag, 7},
{"gorecover", funcTag, 10},
{"goschedguarded", funcTag, 5},
{"printbool", funcTag, 12},
{"printfloat", funcTag, 14},
{"printint", funcTag, 16},
{"printhex", funcTag, 18},
{"printuint", funcTag, 18},
{"printcomplex", funcTag, 20},
{"printstring", funcTag, 22},
{"printpointer", funcTag, 23},
{"printiface", funcTag, 23},
{"printeface", funcTag, 23},
{"printslice", funcTag, 23},
{"goPanicIndex", funcTag, 12},
{"goPanicIndexU", funcTag, 14},
{"goPanicSliceAlen", funcTag, 12},
{"goPanicSliceAlenU", funcTag, 14},
{"goPanicSliceAcap", funcTag, 12},
{"goPanicSliceAcapU", funcTag, 14},
{"goPanicSliceB", funcTag, 12},
{"goPanicSliceBU", funcTag, 14},
{"goPanicSlice3Alen", funcTag, 12},
{"goPanicSlice3AlenU", funcTag, 14},
{"goPanicSlice3Acap", funcTag, 12},
{"goPanicSlice3AcapU", funcTag, 14},
{"goPanicSlice3B", funcTag, 12},
{"goPanicSlice3BU", funcTag, 14},
{"goPanicSlice3C", funcTag, 12},
{"goPanicSlice3CU", funcTag, 14},
{"printbool", funcTag, 16},
{"printfloat", funcTag, 18},
{"printint", funcTag, 20},
{"printhex", funcTag, 22},
{"printuint", funcTag, 22},
{"printcomplex", funcTag, 24},
{"printstring", funcTag, 26},
{"printpointer", funcTag, 27},
{"printiface", funcTag, 27},
{"printeface", funcTag, 27},
{"printslice", funcTag, 27},
{"printnl", funcTag, 5},
{"printsp", funcTag, 5},
{"printlock", funcTag, 5},
{"printunlock", funcTag, 5},
{"concatstring2", funcTag, 26},
{"concatstring3", funcTag, 27},
{"concatstring4", funcTag, 28},
{"concatstring5", funcTag, 29},
{"concatstrings", funcTag, 31},
{"cmpstring", funcTag, 33},
{"intstring", funcTag, 36},
{"slicebytetostring", funcTag, 38},
{"slicebytetostringtmp", funcTag, 39},
{"slicerunetostring", funcTag, 42},
{"stringtoslicebyte", funcTag, 43},
{"stringtoslicerune", funcTag, 46},
{"slicecopy", funcTag, 48},
{"slicestringcopy", funcTag, 49},
{"decoderune", funcTag, 50},
{"countrunes", funcTag, 51},
{"convI2I", funcTag, 52},
{"convT16", funcTag, 54},
{"convT32", funcTag, 54},
{"convT64", funcTag, 54},
{"convTstring", funcTag, 54},
{"convTslice", funcTag, 54},
{"convT2E", funcTag, 55},
{"convT2Enoptr", funcTag, 55},
{"convT2I", funcTag, 55},
{"convT2Inoptr", funcTag, 55},
{"assertE2I", funcTag, 52},
{"assertE2I2", funcTag, 56},
{"assertI2I", funcTag, 52},
{"assertI2I2", funcTag, 56},
{"panicdottypeE", funcTag, 57},
{"panicdottypeI", funcTag, 57},
{"panicnildottype", funcTag, 58},
{"ifaceeq", funcTag, 60},
{"efaceeq", funcTag, 60},
{"fastrand", funcTag, 62},
{"makemap64", funcTag, 64},
{"makemap", funcTag, 65},
{"makemap_small", funcTag, 66},
{"mapaccess1", funcTag, 67},
{"mapaccess1_fast32", funcTag, 68},
{"mapaccess1_fast64", funcTag, 68},
{"mapaccess1_faststr", funcTag, 68},
{"mapaccess1_fat", funcTag, 69},
{"mapaccess2", funcTag, 70},
{"mapaccess2_fast32", funcTag, 71},
{"mapaccess2_fast64", funcTag, 71},
{"mapaccess2_faststr", funcTag, 71},
{"mapaccess2_fat", funcTag, 72},
{"mapassign", funcTag, 67},
{"mapassign_fast32", funcTag, 68},
{"mapassign_fast32ptr", funcTag, 68},
{"mapassign_fast64", funcTag, 68},
{"mapassign_fast64ptr", funcTag, 68},
{"mapassign_faststr", funcTag, 68},
{"mapiterinit", funcTag, 73},
{"mapdelete", funcTag, 73},
{"mapdelete_fast32", funcTag, 74},
{"mapdelete_fast64", funcTag, 74},
{"mapdelete_faststr", funcTag, 74},
{"mapiternext", funcTag, 75},
{"mapclear", funcTag, 76},
{"makechan64", funcTag, 78},
{"makechan", funcTag, 79},
{"chanrecv1", funcTag, 81},
{"chanrecv2", funcTag, 82},
{"chansend1", funcTag, 84},
{"closechan", funcTag, 23},
{"writeBarrier", varTag, 86},
{"typedmemmove", funcTag, 87},
{"typedmemclr", funcTag, 88},
{"typedslicecopy", funcTag, 89},
{"selectnbsend", funcTag, 90},
{"selectnbrecv", funcTag, 91},
{"selectnbrecv2", funcTag, 93},
{"selectsetpc", funcTag, 58},
{"selectgo", funcTag, 94},
{"concatstring2", funcTag, 30},
{"concatstring3", funcTag, 31},
{"concatstring4", funcTag, 32},
{"concatstring5", funcTag, 33},
{"concatstrings", funcTag, 35},
{"cmpstring", funcTag, 36},
{"intstring", funcTag, 39},
{"slicebytetostring", funcTag, 41},
{"slicebytetostringtmp", funcTag, 42},
{"slicerunetostring", funcTag, 45},
{"stringtoslicebyte", funcTag, 46},
{"stringtoslicerune", funcTag, 49},
{"slicecopy", funcTag, 51},
{"slicestringcopy", funcTag, 52},
{"decoderune", funcTag, 53},
{"countrunes", funcTag, 54},
{"convI2I", funcTag, 55},
{"convT16", funcTag, 57},
{"convT32", funcTag, 57},
{"convT64", funcTag, 57},
{"convTstring", funcTag, 57},
{"convTslice", funcTag, 57},
{"convT2E", funcTag, 58},
{"convT2Enoptr", funcTag, 58},
{"convT2I", funcTag, 58},
{"convT2Inoptr", funcTag, 58},
{"assertE2I", funcTag, 55},
{"assertE2I2", funcTag, 59},
{"assertI2I", funcTag, 55},
{"assertI2I2", funcTag, 59},
{"panicdottypeE", funcTag, 60},
{"panicdottypeI", funcTag, 60},
{"panicnildottype", funcTag, 61},
{"ifaceeq", funcTag, 63},
{"efaceeq", funcTag, 63},
{"fastrand", funcTag, 65},
{"makemap64", funcTag, 67},
{"makemap", funcTag, 68},
{"makemap_small", funcTag, 69},
{"mapaccess1", funcTag, 70},
{"mapaccess1_fast32", funcTag, 71},
{"mapaccess1_fast64", funcTag, 71},
{"mapaccess1_faststr", funcTag, 71},
{"mapaccess1_fat", funcTag, 72},
{"mapaccess2", funcTag, 73},
{"mapaccess2_fast32", funcTag, 74},
{"mapaccess2_fast64", funcTag, 74},
{"mapaccess2_faststr", funcTag, 74},
{"mapaccess2_fat", funcTag, 75},
{"mapassign", funcTag, 70},
{"mapassign_fast32", funcTag, 71},
{"mapassign_fast32ptr", funcTag, 71},
{"mapassign_fast64", funcTag, 71},
{"mapassign_fast64ptr", funcTag, 71},
{"mapassign_faststr", funcTag, 71},
{"mapiterinit", funcTag, 76},
{"mapdelete", funcTag, 76},
{"mapdelete_fast32", funcTag, 77},
{"mapdelete_fast64", funcTag, 77},
{"mapdelete_faststr", funcTag, 77},
{"mapiternext", funcTag, 78},
{"mapclear", funcTag, 79},
{"makechan64", funcTag, 81},
{"makechan", funcTag, 82},
{"chanrecv1", funcTag, 84},
{"chanrecv2", funcTag, 85},
{"chansend1", funcTag, 87},
{"closechan", funcTag, 27},
{"writeBarrier", varTag, 89},
{"typedmemmove", funcTag, 90},
{"typedmemclr", funcTag, 91},
{"typedslicecopy", funcTag, 92},
{"selectnbsend", funcTag, 93},
{"selectnbrecv", funcTag, 94},
{"selectnbrecv2", funcTag, 96},
{"selectsetpc", funcTag, 61},
{"selectgo", funcTag, 97},
{"block", funcTag, 5},
{"makeslice", funcTag, 95},
{"makeslice64", funcTag, 96},
{"growslice", funcTag, 98},
{"memmove", funcTag, 99},
{"memclrNoHeapPointers", funcTag, 100},
{"memclrHasPointers", funcTag, 100},
{"memequal", funcTag, 101},
{"memequal8", funcTag, 102},
{"memequal16", funcTag, 102},
{"memequal32", funcTag, 102},
{"memequal64", funcTag, 102},
{"memequal128", funcTag, 102},
{"int64div", funcTag, 103},
{"uint64div", funcTag, 104},
{"int64mod", funcTag, 103},
{"uint64mod", funcTag, 104},
{"float64toint64", funcTag, 105},
{"float64touint64", funcTag, 106},
{"float64touint32", funcTag, 107},
{"int64tofloat64", funcTag, 108},
{"uint64tofloat64", funcTag, 109},
{"uint32tofloat64", funcTag, 110},
{"complex128div", funcTag, 111},
{"racefuncenter", funcTag, 112},
{"makeslice", funcTag, 98},
{"makeslice64", funcTag, 99},
{"growslice", funcTag, 101},
{"memmove", funcTag, 102},
{"memclrNoHeapPointers", funcTag, 103},
{"memclrHasPointers", funcTag, 103},
{"memequal", funcTag, 104},
{"memequal8", funcTag, 105},
{"memequal16", funcTag, 105},
{"memequal32", funcTag, 105},
{"memequal64", funcTag, 105},
{"memequal128", funcTag, 105},
{"int64div", funcTag, 106},
{"uint64div", funcTag, 107},
{"int64mod", funcTag, 106},
{"uint64mod", funcTag, 107},
{"float64toint64", funcTag, 108},
{"float64touint64", funcTag, 109},
{"float64touint32", funcTag, 110},
{"int64tofloat64", funcTag, 111},
{"uint64tofloat64", funcTag, 112},
{"uint32tofloat64", funcTag, 113},
{"complex128div", funcTag, 114},
{"racefuncenter", funcTag, 115},
{"racefuncenterfp", funcTag, 5},
{"racefuncexit", funcTag, 5},
{"raceread", funcTag, 112},
{"racewrite", funcTag, 112},
{"racereadrange", funcTag, 113},
{"racewriterange", funcTag, 113},
{"msanread", funcTag, 113},
{"msanwrite", funcTag, 113},
{"x86HasPOPCNT", varTag, 11},
{"x86HasSSE41", varTag, 11},
{"arm64HasATOMICS", varTag, 11},
{"raceread", funcTag, 115},
{"racewrite", funcTag, 115},
{"racereadrange", funcTag, 116},
{"racewriterange", funcTag, 116},
{"msanread", funcTag, 116},
{"msanwrite", funcTag, 116},
{"x86HasPOPCNT", varTag, 15},
{"x86HasSSE41", varTag, 15},
{"arm64HasATOMICS", varTag, 15},
}
func runtimeTypes() []*types.Type {
var typs [114]*types.Type
var typs [117]*types.Type
typs[0] = types.Bytetype
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[TANY]
@ -163,108 +177,111 @@ func runtimeTypes() []*types.Type {
typs[8] = types.Types[TINT32]
typs[9] = types.NewPtr(typs[8])
typs[10] = functype(nil, []*Node{anonfield(typs[9])}, []*Node{anonfield(typs[6])})
typs[11] = types.Types[TBOOL]
typs[12] = functype(nil, []*Node{anonfield(typs[11])}, nil)
typs[13] = types.Types[TFLOAT64]
typs[14] = functype(nil, []*Node{anonfield(typs[13])}, nil)
typs[15] = types.Types[TINT64]
typs[11] = types.Types[TINT]
typs[12] = functype(nil, []*Node{anonfield(typs[11]), anonfield(typs[11])}, nil)
typs[13] = types.Types[TUINT]
typs[14] = functype(nil, []*Node{anonfield(typs[13]), anonfield(typs[11])}, nil)
typs[15] = types.Types[TBOOL]
typs[16] = functype(nil, []*Node{anonfield(typs[15])}, nil)
typs[17] = types.Types[TUINT64]
typs[17] = types.Types[TFLOAT64]
typs[18] = functype(nil, []*Node{anonfield(typs[17])}, nil)
typs[19] = types.Types[TCOMPLEX128]
typs[19] = types.Types[TINT64]
typs[20] = functype(nil, []*Node{anonfield(typs[19])}, nil)
typs[21] = types.Types[TSTRING]
typs[21] = types.Types[TUINT64]
typs[22] = functype(nil, []*Node{anonfield(typs[21])}, nil)
typs[23] = functype(nil, []*Node{anonfield(typs[2])}, nil)
typs[24] = types.NewArray(typs[0], 32)
typs[25] = types.NewPtr(typs[24])
typs[26] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[27] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[28] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[29] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[30] = types.NewSlice(typs[21])
typs[31] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[30])}, []*Node{anonfield(typs[21])})
typs[32] = types.Types[TINT]
typs[33] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[32])})
typs[34] = types.NewArray(typs[0], 4)
typs[35] = types.NewPtr(typs[34])
typs[36] = functype(nil, []*Node{anonfield(typs[35]), anonfield(typs[15])}, []*Node{anonfield(typs[21])})
typs[37] = types.NewSlice(typs[0])
typs[38] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[37])}, []*Node{anonfield(typs[21])})
typs[39] = functype(nil, []*Node{anonfield(typs[37])}, []*Node{anonfield(typs[21])})
typs[40] = types.Runetype
typs[41] = types.NewSlice(typs[40])
typs[42] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[41])}, []*Node{anonfield(typs[21])})
typs[43] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21])}, []*Node{anonfield(typs[37])})
typs[44] = types.NewArray(typs[40], 32)
typs[45] = types.NewPtr(typs[44])
typs[46] = functype(nil, []*Node{anonfield(typs[45]), anonfield(typs[21])}, []*Node{anonfield(typs[41])})
typs[47] = types.Types[TUINTPTR]
typs[48] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[47])}, []*Node{anonfield(typs[32])})
typs[49] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
typs[50] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[32])}, []*Node{anonfield(typs[40]), anonfield(typs[32])})
typs[51] = functype(nil, []*Node{anonfield(typs[21])}, []*Node{anonfield(typs[32])})
typs[52] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
typs[53] = types.Types[TUNSAFEPTR]
typs[54] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[53])})
typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[11])})
typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
typs[58] = functype(nil, []*Node{anonfield(typs[1])}, nil)
typs[59] = types.NewPtr(typs[47])
typs[60] = functype(nil, []*Node{anonfield(typs[59]), anonfield(typs[53]), anonfield(typs[53])}, []*Node{anonfield(typs[11])})
typs[61] = types.Types[TUINT32]
typs[62] = functype(nil, nil, []*Node{anonfield(typs[61])})
typs[63] = types.NewMap(typs[2], typs[2])
typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[63])})
typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[3])}, []*Node{anonfield(typs[63])})
typs[66] = functype(nil, nil, []*Node{anonfield(typs[63])})
typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3])}, nil)
typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[2])}, nil)
typs[75] = functype(nil, []*Node{anonfield(typs[3])}, nil)
typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63])}, nil)
typs[77] = types.NewChan(typs[2], types.Cboth)
typs[78] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[77])})
typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[77])})
typs[80] = types.NewChan(typs[2], types.Crecv)
typs[81] = functype(nil, []*Node{anonfield(typs[80]), anonfield(typs[3])}, nil)
typs[82] = functype(nil, []*Node{anonfield(typs[80]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[83] = types.NewChan(typs[2], types.Csend)
typs[23] = types.Types[TCOMPLEX128]
typs[24] = functype(nil, []*Node{anonfield(typs[23])}, nil)
typs[25] = types.Types[TSTRING]
typs[26] = functype(nil, []*Node{anonfield(typs[25])}, nil)
typs[27] = functype(nil, []*Node{anonfield(typs[2])}, nil)
typs[28] = types.NewArray(typs[0], 32)
typs[29] = types.NewPtr(typs[28])
typs[30] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
typs[31] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
typs[32] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
typs[33] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
typs[34] = types.NewSlice(typs[25])
typs[35] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[34])}, []*Node{anonfield(typs[25])})
typs[36] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[11])})
typs[37] = types.NewArray(typs[0], 4)
typs[38] = types.NewPtr(typs[37])
typs[39] = functype(nil, []*Node{anonfield(typs[38]), anonfield(typs[19])}, []*Node{anonfield(typs[25])})
typs[40] = types.NewSlice(typs[0])
typs[41] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[40])}, []*Node{anonfield(typs[25])})
typs[42] = functype(nil, []*Node{anonfield(typs[40])}, []*Node{anonfield(typs[25])})
typs[43] = types.Runetype
typs[44] = types.NewSlice(typs[43])
typs[45] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[44])}, []*Node{anonfield(typs[25])})
typs[46] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25])}, []*Node{anonfield(typs[40])})
typs[47] = types.NewArray(typs[43], 32)
typs[48] = types.NewPtr(typs[47])
typs[49] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[25])}, []*Node{anonfield(typs[44])})
typs[50] = types.Types[TUINTPTR]
typs[51] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[50])}, []*Node{anonfield(typs[11])})
typs[52] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[11])})
typs[53] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[11])}, []*Node{anonfield(typs[43]), anonfield(typs[11])})
typs[54] = functype(nil, []*Node{anonfield(typs[25])}, []*Node{anonfield(typs[11])})
typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
typs[56] = types.Types[TUNSAFEPTR]
typs[57] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[56])})
typs[58] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[15])})
typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
typs[61] = functype(nil, []*Node{anonfield(typs[1])}, nil)
typs[62] = types.NewPtr(typs[50])
typs[63] = functype(nil, []*Node{anonfield(typs[62]), anonfield(typs[56]), anonfield(typs[56])}, []*Node{anonfield(typs[15])})
typs[64] = types.Types[TUINT32]
typs[65] = functype(nil, nil, []*Node{anonfield(typs[64])})
typs[66] = types.NewMap(typs[2], typs[2])
typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19]), anonfield(typs[3])}, []*Node{anonfield(typs[66])})
typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11]), anonfield(typs[3])}, []*Node{anonfield(typs[66])})
typs[69] = functype(nil, nil, []*Node{anonfield(typs[66])})
typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, nil)
typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, nil)
typs[78] = functype(nil, []*Node{anonfield(typs[3])}, nil)
typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66])}, nil)
typs[80] = types.NewChan(typs[2], types.Cboth)
typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19])}, []*Node{anonfield(typs[80])})
typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[80])})
typs[83] = types.NewChan(typs[2], types.Crecv)
typs[84] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, nil)
typs[85] = types.NewArray(typs[0], 3)
typs[86] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[85]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])})
typs[87] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
typs[88] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
typs[90] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[91] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[80])}, []*Node{anonfield(typs[11])})
typs[92] = types.NewPtr(typs[11])
typs[93] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[92]), anonfield(typs[80])}, []*Node{anonfield(typs[11])})
typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[32]), anonfield(typs[11])})
typs[95] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[53])})
typs[96] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[53])})
typs[97] = types.NewSlice(typs[2])
typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[97]), anonfield(typs[32])}, []*Node{anonfield(typs[97])})
typs[99] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[47])}, nil)
typs[100] = functype(nil, []*Node{anonfield(typs[53]), anonfield(typs[47])}, nil)
typs[101] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[47])}, []*Node{anonfield(typs[11])})
typs[102] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[103] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
typs[104] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
typs[105] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
typs[106] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
typs[107] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[61])})
typs[108] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
typs[109] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
typs[110] = functype(nil, []*Node{anonfield(typs[61])}, []*Node{anonfield(typs[13])})
typs[111] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
typs[112] = functype(nil, []*Node{anonfield(typs[47])}, nil)
typs[113] = functype(nil, []*Node{anonfield(typs[47]), anonfield(typs[47])}, nil)
typs[85] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
typs[86] = types.NewChan(typs[2], types.Csend)
typs[87] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, nil)
typs[88] = types.NewArray(typs[0], 3)
typs[89] = tostruct([]*Node{namedfield("enabled", typs[15]), namedfield("pad", typs[88]), namedfield("needed", typs[15]), namedfield("cgo", typs[15]), namedfield("alignme", typs[21])})
typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[11])})
typs[93] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
typs[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[83])}, []*Node{anonfield(typs[15])})
typs[95] = types.NewPtr(typs[15])
typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[95]), anonfield(typs[83])}, []*Node{anonfield(typs[15])})
typs[97] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[11]), anonfield(typs[15])})
typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11]), anonfield(typs[11])}, []*Node{anonfield(typs[56])})
typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[56])})
typs[100] = types.NewSlice(typs[2])
typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[100]), anonfield(typs[11])}, []*Node{anonfield(typs[100])})
typs[102] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, nil)
typs[103] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50])}, nil)
typs[104] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[15])})
typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
typs[106] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
typs[107] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[108] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[19])})
typs[109] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[21])})
typs[110] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[64])})
typs[111] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[17])})
typs[112] = functype(nil, []*Node{anonfield(typs[21])}, []*Node{anonfield(typs[17])})
typs[113] = functype(nil, []*Node{anonfield(typs[64])}, []*Node{anonfield(typs[17])})
typs[114] = functype(nil, []*Node{anonfield(typs[23]), anonfield(typs[23])}, []*Node{anonfield(typs[23])})
typs[115] = functype(nil, []*Node{anonfield(typs[50])}, nil)
typs[116] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
return typs[:]
}

View file

@ -15,8 +15,6 @@ package runtime
import "unsafe"
func newobject(typ *byte) *any
func panicindex()
func panicslice()
func panicdivide()
func panicshift()
func panicmakeslicelen()
@ -27,6 +25,25 @@ func gopanic(interface{})
func gorecover(*int32) interface{}
func goschedguarded()
// Note: these declarations are just for wasm port.
// Other ports call assembly stubs instead.
func goPanicIndex(x int, y int)
func goPanicIndexU(x uint, y int)
func goPanicSliceAlen(x int, y int)
func goPanicSliceAlenU(x uint, y int)
func goPanicSliceAcap(x int, y int)
func goPanicSliceAcapU(x uint, y int)
func goPanicSliceB(x int, y int)
func goPanicSliceBU(x uint, y int)
func goPanicSlice3Alen(x int, y int)
func goPanicSlice3AlenU(x uint, y int)
func goPanicSlice3Acap(x int, y int)
func goPanicSlice3AcapU(x uint, y int)
func goPanicSlice3B(x int, y int)
func goPanicSlice3BU(x uint, y int)
func goPanicSlice3C(x int, y int)
func goPanicSlice3CU(x uint, y int)
func printbool(bool)
func printfloat(float64)
func printint(int64)

View file

@ -300,10 +300,8 @@ var (
panicshift,
panicdottypeE,
panicdottypeI,
panicindex,
panicnildottype,
panicoverflow,
panicslice,
raceread,
racereadrange,
racewrite,
@ -316,6 +314,9 @@ var (
Udiv,
writeBarrier *obj.LSym
BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym
ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym
// GO386=387
ControlWord64trunc,
ControlWord32 *obj.LSym

View file

@ -80,10 +80,8 @@ func initssaconfig() {
panicdivide = sysfunc("panicdivide")
panicdottypeE = sysfunc("panicdottypeE")
panicdottypeI = sysfunc("panicdottypeI")
panicindex = sysfunc("panicindex")
panicnildottype = sysfunc("panicnildottype")
panicoverflow = sysfunc("panicoverflow")
panicslice = sysfunc("panicslice")
panicshift = sysfunc("panicshift")
raceread = sysfunc("raceread")
racereadrange = sysfunc("racereadrange")
@ -96,6 +94,59 @@ func initssaconfig() {
typedmemmove = sysfunc("typedmemmove")
Udiv = sysvar("udiv") // asm func with special ABI
writeBarrier = sysvar("writeBarrier") // struct { bool; ... }
if thearch.LinkArch.Family == sys.Wasm {
BoundsCheckFunc[ssa.BoundsIndex] = sysvar("goPanicIndex")
BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("goPanicIndexU")
BoundsCheckFunc[ssa.BoundsSliceAlen] = sysvar("goPanicSliceAlen")
BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysvar("goPanicSliceAlenU")
BoundsCheckFunc[ssa.BoundsSliceAcap] = sysvar("goPanicSliceAcap")
BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysvar("goPanicSliceAcapU")
BoundsCheckFunc[ssa.BoundsSliceB] = sysvar("goPanicSliceB")
BoundsCheckFunc[ssa.BoundsSliceBU] = sysvar("goPanicSliceBU")
BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysvar("goPanicSlice3Alen")
BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("goPanicSlice3AlenU")
BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysvar("goPanicSlice3Acap")
BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("goPanicSlice3AcapU")
BoundsCheckFunc[ssa.BoundsSlice3B] = sysvar("goPanicSlice3B")
BoundsCheckFunc[ssa.BoundsSlice3BU] = sysvar("goPanicSlice3BU")
BoundsCheckFunc[ssa.BoundsSlice3C] = sysvar("goPanicSlice3C")
BoundsCheckFunc[ssa.BoundsSlice3CU] = sysvar("goPanicSlice3CU")
} else {
BoundsCheckFunc[ssa.BoundsIndex] = sysvar("panicIndex")
BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("panicIndexU")
BoundsCheckFunc[ssa.BoundsSliceAlen] = sysvar("panicSliceAlen")
BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysvar("panicSliceAlenU")
BoundsCheckFunc[ssa.BoundsSliceAcap] = sysvar("panicSliceAcap")
BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysvar("panicSliceAcapU")
BoundsCheckFunc[ssa.BoundsSliceB] = sysvar("panicSliceB")
BoundsCheckFunc[ssa.BoundsSliceBU] = sysvar("panicSliceBU")
BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysvar("panicSlice3Alen")
BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("panicSlice3AlenU")
BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysvar("panicSlice3Acap")
BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("panicSlice3AcapU")
BoundsCheckFunc[ssa.BoundsSlice3B] = sysvar("panicSlice3B")
BoundsCheckFunc[ssa.BoundsSlice3BU] = sysvar("panicSlice3BU")
BoundsCheckFunc[ssa.BoundsSlice3C] = sysvar("panicSlice3C")
BoundsCheckFunc[ssa.BoundsSlice3CU] = sysvar("panicSlice3CU")
}
if thearch.LinkArch.PtrSize == 4 {
ExtendCheckFunc[ssa.BoundsIndex] = sysvar("panicExtendIndex")
ExtendCheckFunc[ssa.BoundsIndexU] = sysvar("panicExtendIndexU")
ExtendCheckFunc[ssa.BoundsSliceAlen] = sysvar("panicExtendSliceAlen")
ExtendCheckFunc[ssa.BoundsSliceAlenU] = sysvar("panicExtendSliceAlenU")
ExtendCheckFunc[ssa.BoundsSliceAcap] = sysvar("panicExtendSliceAcap")
ExtendCheckFunc[ssa.BoundsSliceAcapU] = sysvar("panicExtendSliceAcapU")
ExtendCheckFunc[ssa.BoundsSliceB] = sysvar("panicExtendSliceB")
ExtendCheckFunc[ssa.BoundsSliceBU] = sysvar("panicExtendSliceBU")
ExtendCheckFunc[ssa.BoundsSlice3Alen] = sysvar("panicExtendSlice3Alen")
ExtendCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("panicExtendSlice3AlenU")
ExtendCheckFunc[ssa.BoundsSlice3Acap] = sysvar("panicExtendSlice3Acap")
ExtendCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("panicExtendSlice3AcapU")
ExtendCheckFunc[ssa.BoundsSlice3B] = sysvar("panicExtendSlice3B")
ExtendCheckFunc[ssa.BoundsSlice3BU] = sysvar("panicExtendSlice3BU")
ExtendCheckFunc[ssa.BoundsSlice3C] = sysvar("panicExtendSlice3C")
ExtendCheckFunc[ssa.BoundsSlice3CU] = sysvar("panicExtendSlice3CU")
}
// GO386=387 runtime definitions
ControlWord64trunc = sysvar("controlWord64trunc") // uint16
@ -575,6 +626,11 @@ func (s *state) newValue4(op ssa.Op, t *types.Type, arg0, arg1, arg2, arg3 *ssa.
return s.curBlock.NewValue4(s.peekPos(), op, t, arg0, arg1, arg2, arg3)
}
// newValue4 adds a new value with four arguments and an auxint value to the current block.
func (s *state) newValue4I(op ssa.Op, t *types.Type, aux int64, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
return s.curBlock.NewValue4I(s.peekPos(), op, t, aux, arg0, arg1, arg2, arg3)
}
// entryNewValue0 adds a new value with no arguments to the entry block.
func (s *state) entryNewValue0(op ssa.Op, t *types.Type) *ssa.Value {
return s.f.Entry.NewValue0(src.NoXPos, op, t)
@ -2262,11 +2318,8 @@ func (s *state) expr(n *Node) *ssa.Value {
}
a := s.expr(n.Left)
i := s.expr(n.Right)
i = s.extendIndex(i, panicindex)
if !n.Bounded() {
len := s.newValue1(ssa.OpStringLen, types.Types[TINT], a)
s.boundsCheck(i, len)
}
len := s.newValue1(ssa.OpStringLen, types.Types[TINT], a)
i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
ptrtyp := s.f.Config.Types.BytePtr
ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
if Isconst(n.Right, CTINT) {
@ -2288,14 +2341,12 @@ func (s *state) expr(n *Node) *ssa.Value {
// Bounds check will never succeed. Might as well
// use constants for the bounds check.
z := s.constInt(types.Types[TINT], 0)
s.boundsCheck(z, z)
s.boundsCheck(z, z, ssa.BoundsIndex, false)
// The return value won't be live, return junk.
return s.newValue0(ssa.OpUnknown, n.Type)
}
i = s.extendIndex(i, panicindex)
if !n.Bounded() {
s.boundsCheck(i, s.constInt(types.Types[TINT], bound))
}
len := s.constInt(types.Types[TINT], bound)
i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
return s.newValue1I(ssa.OpArraySelect, n.Type, 0, a)
}
p := s.addr(n, false)
@ -2353,13 +2404,13 @@ func (s *state) expr(n *Node) *ssa.Value {
var i, j, k *ssa.Value
low, high, max := n.SliceBounds()
if low != nil {
i = s.extendIndex(s.expr(low), panicslice)
i = s.expr(low)
}
if high != nil {
j = s.extendIndex(s.expr(high), panicslice)
j = s.expr(high)
}
if max != nil {
k = s.extendIndex(s.expr(max), panicslice)
k = s.expr(max)
}
p, l, c := s.slice(n.Left.Type, v, i, j, k, n.Bounded())
return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
@ -2369,10 +2420,10 @@ func (s *state) expr(n *Node) *ssa.Value {
var i, j *ssa.Value
low, high, _ := n.SliceBounds()
if low != nil {
i = s.extendIndex(s.expr(low), panicslice)
i = s.expr(low)
}
if high != nil {
j = s.extendIndex(s.expr(high), panicslice)
j = s.expr(high)
}
p, l, _ := s.slice(n.Left.Type, v, i, j, nil, n.Bounded())
return s.newValue2(ssa.OpStringMake, n.Type, p, l)
@ -2680,15 +2731,15 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
// The bounds check must fail. Might as well
// ignore the actual index and just use zeros.
z := s.constInt(types.Types[TINT], 0)
s.boundsCheck(z, z)
s.boundsCheck(z, z, ssa.BoundsIndex, false)
return
}
if n != 1 {
s.Fatalf("assigning to non-1-length array")
}
// Rewrite to a = [1]{v}
i = s.extendIndex(i, panicindex)
s.boundsCheck(i, s.constInt(types.Types[TINT], 1))
len := s.constInt(types.Types[TINT], 1)
i = s.boundsCheck(i, len, ssa.BoundsIndex, false)
v := s.newValue1(ssa.OpArrayMake1, t, right)
s.assign(left.Left, v, false, 0)
return
@ -3875,21 +3926,15 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
if n.Left.Type.IsSlice() {
a := s.expr(n.Left)
i := s.expr(n.Right)
i = s.extendIndex(i, panicindex)
len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], a)
if !n.Bounded() {
s.boundsCheck(i, len)
}
i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
p := s.newValue1(ssa.OpSlicePtr, t, a)
return s.newValue2(ssa.OpPtrIndex, t, p, i)
} else { // array
a := s.addr(n.Left, bounded)
i := s.expr(n.Right)
i = s.extendIndex(i, panicindex)
len := s.constInt(types.Types[TINT], n.Left.Type.NumElem())
if !n.Bounded() {
s.boundsCheck(i, len)
}
i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left.Type.Elem()), a, i)
}
case ODEREF:
@ -4028,32 +4073,70 @@ func (s *state) nilCheck(ptr *ssa.Value) {
s.newValue2(ssa.OpNilCheck, types.TypeVoid, ptr, s.mem())
}
// boundsCheck generates bounds checking code. Checks if 0 <= idx < len, branches to exit if not.
// len must be known to be nonnegative.
// boundsCheck generates bounds checking code. Checks if 0 <= idx <[=] len, branches to exit if not.
// Starts a new block on return.
// idx is already converted to full int width.
func (s *state) boundsCheck(idx, len *ssa.Value) {
if Debug['B'] != 0 {
return
// On input, len must be converted to full int width and be nonnegative.
// Returns idx converted to full int width.
// If bounded is true then caller guarantees the index is not out of bounds
// (but boundsCheck will still extend the index to full int width).
func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
idx = s.extendIndex(idx, len, kind, bounded)
if bounded || Debug['B'] != 0 {
// If bounded or bounds checking is flag-disabled, then no check necessary,
// just return the extended index.
return idx
}
// bounds check
cmp := s.newValue2(ssa.OpIsInBounds, types.Types[TBOOL], idx, len)
s.check(cmp, panicindex)
}
bNext := s.f.NewBlock(ssa.BlockPlain)
bPanic := s.f.NewBlock(ssa.BlockExit)
// sliceBoundsCheck generates slice bounds checking code. Checks if 0 <= idx <= len, branches to exit if not.
// len must be known to be nonnegative.
// Starts a new block on return.
// idx and len are already converted to full int width.
func (s *state) sliceBoundsCheck(idx, len *ssa.Value) {
if Debug['B'] != 0 {
return
if !idx.Type.IsSigned() {
switch kind {
case ssa.BoundsIndex:
kind = ssa.BoundsIndexU
case ssa.BoundsSliceAlen:
kind = ssa.BoundsSliceAlenU
case ssa.BoundsSliceAcap:
kind = ssa.BoundsSliceAcapU
case ssa.BoundsSliceB:
kind = ssa.BoundsSliceBU
case ssa.BoundsSlice3Alen:
kind = ssa.BoundsSlice3AlenU
case ssa.BoundsSlice3Acap:
kind = ssa.BoundsSlice3AcapU
case ssa.BoundsSlice3B:
kind = ssa.BoundsSlice3BU
case ssa.BoundsSlice3C:
kind = ssa.BoundsSlice3CU
}
}
// bounds check
cmp := s.newValue2(ssa.OpIsSliceInBounds, types.Types[TBOOL], idx, len)
s.check(cmp, panicslice)
var cmp *ssa.Value
if kind == ssa.BoundsIndex || kind == ssa.BoundsIndexU {
cmp = s.newValue2(ssa.OpIsInBounds, types.Types[TBOOL], idx, len)
} else {
cmp = s.newValue2(ssa.OpIsSliceInBounds, types.Types[TBOOL], idx, len)
}
b := s.endBlock()
b.Kind = ssa.BlockIf
b.SetControl(cmp)
b.Likely = ssa.BranchLikely
b.AddEdgeTo(bNext)
b.AddEdgeTo(bPanic)
s.startBlock(bPanic)
if thearch.LinkArch.Family == sys.Wasm {
// TODO(khr): figure out how to do "register" based calling convention for bounds checks.
// Should be similar to gcWriteBarrier, but I can't make it work.
s.rtcall(BoundsCheckFunc[kind], false, nil, idx, len)
} else {
mem := s.newValue3I(ssa.OpPanicBounds, types.TypeMem, int64(kind), idx, len, s.mem())
s.endBlock().SetControl(mem)
}
s.startBlock(bNext)
return idx
}
// If cmp (a bool) is false, panic using the given function.
@ -4307,21 +4390,36 @@ func (s *state) slice(t *types.Type, v, i, j, k *ssa.Value, bounded bool) (p, l,
if j == nil {
j = len
}
three := true
if k == nil {
three = false
k = cap
}
if !bounded {
// Panic if slice indices are not in bounds.
// Make sure we check these in reverse order so that we're always
// comparing against a value known to be nonnegative. See issue 28797.
// Panic if slice indices are not in bounds.
// Make sure we check these in reverse order so that we're always
// comparing against a value known to be nonnegative. See issue 28797.
if three {
if k != cap {
s.sliceBoundsCheck(k, cap)
kind := ssa.BoundsSlice3Alen
if t.IsSlice() {
kind = ssa.BoundsSlice3Acap
}
k = s.boundsCheck(k, cap, kind, bounded)
}
if j != k {
s.sliceBoundsCheck(j, k)
j = s.boundsCheck(j, k, ssa.BoundsSlice3B, bounded)
}
s.sliceBoundsCheck(i, j)
i = s.boundsCheck(i, j, ssa.BoundsSlice3C, bounded)
} else {
if j != k {
kind := ssa.BoundsSliceAlen
if t.IsSlice() {
kind = ssa.BoundsSliceAcap
}
j = s.boundsCheck(j, k, kind, bounded)
}
i = s.boundsCheck(i, j, ssa.BoundsSliceB, bounded)
}
// Generate the following code assuming that indexes are in bounds.
@ -5432,26 +5530,66 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
}
// extendIndex extends v to a full int width.
// panic using the given function if v does not fit in an int (only on 32-bit archs).
func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value {
size := v.Type.Size()
// panic with the given kind if v does not fit in an int (only on 32-bit archs).
func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
size := idx.Type.Size()
if size == s.config.PtrSize {
return v
return idx
}
if size > s.config.PtrSize {
// truncate 64-bit indexes on 32-bit pointer archs. Test the
// high word and branch to out-of-bounds failure if it is not 0.
if Debug['B'] == 0 {
hi := s.newValue1(ssa.OpInt64Hi, types.Types[TUINT32], v)
cmp := s.newValue2(ssa.OpEq32, types.Types[TBOOL], hi, s.constInt32(types.Types[TUINT32], 0))
s.check(cmp, panicfn)
var lo *ssa.Value
if idx.Type.IsSigned() {
lo = s.newValue1(ssa.OpInt64Lo, types.Types[TINT], idx)
} else {
lo = s.newValue1(ssa.OpInt64Lo, types.Types[TUINT], idx)
}
return s.newValue1(ssa.OpTrunc64to32, types.Types[TINT], v)
if bounded || Debug['B'] != 0 {
return lo
}
bNext := s.f.NewBlock(ssa.BlockPlain)
bPanic := s.f.NewBlock(ssa.BlockExit)
hi := s.newValue1(ssa.OpInt64Hi, types.Types[TUINT32], idx)
cmp := s.newValue2(ssa.OpEq32, types.Types[TBOOL], hi, s.constInt32(types.Types[TUINT32], 0))
if !idx.Type.IsSigned() {
switch kind {
case ssa.BoundsIndex:
kind = ssa.BoundsIndexU
case ssa.BoundsSliceAlen:
kind = ssa.BoundsSliceAlenU
case ssa.BoundsSliceAcap:
kind = ssa.BoundsSliceAcapU
case ssa.BoundsSliceB:
kind = ssa.BoundsSliceBU
case ssa.BoundsSlice3Alen:
kind = ssa.BoundsSlice3AlenU
case ssa.BoundsSlice3Acap:
kind = ssa.BoundsSlice3AcapU
case ssa.BoundsSlice3B:
kind = ssa.BoundsSlice3BU
case ssa.BoundsSlice3C:
kind = ssa.BoundsSlice3CU
}
}
b := s.endBlock()
b.Kind = ssa.BlockIf
b.SetControl(cmp)
b.Likely = ssa.BranchLikely
b.AddEdgeTo(bNext)
b.AddEdgeTo(bPanic)
s.startBlock(bPanic)
mem := s.newValue4I(ssa.OpPanicExtend, types.TypeMem, int64(kind), hi, lo, len, s.mem())
s.endBlock().SetControl(mem)
s.startBlock(bNext)
return lo
}
// Extend value to the required size
var op ssa.Op
if v.Type.IsSigned() {
if idx.Type.IsSigned() {
switch 10*size + s.config.PtrSize {
case 14:
op = ssa.OpSignExt8to32
@ -5464,7 +5602,7 @@ func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value {
case 48:
op = ssa.OpSignExt32to64
default:
s.Fatalf("bad signed index extension %s", v.Type)
s.Fatalf("bad signed index extension %s", idx.Type)
}
} else {
switch 10*size + s.config.PtrSize {
@ -5479,10 +5617,10 @@ func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value {
case 48:
op = ssa.OpZeroExt32to64
default:
s.Fatalf("bad unsigned index extension %s", v.Type)
s.Fatalf("bad unsigned index extension %s", idx.Type)
}
}
return s.newValue1(op, types.Types[TINT], v)
return s.newValue1(op, types.Types[TINT], idx)
}
// CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values.
@ -5612,6 +5750,14 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) {
}
}
// UseArgs records the fact that an instruction needs a certain amount of
// callee args space for its use.
func (s *SSAGenState) UseArgs(n int64) {
if s.maxarg < n {
s.maxarg = n
}
}
// fieldIdx finds the index of the field referred to by the ODOT node n.
func fieldIdx(n *Node) int {
t := n.Left.Type

View file

@ -485,6 +485,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.OpMIPSLoweredPanicBoundsA, ssa.OpMIPSLoweredPanicBoundsB, ssa.OpMIPSLoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(8) // space used in callee args area by assembly stubs
case ssa.OpMIPSLoweredPanicExtendA, ssa.OpMIPSLoweredPanicExtendB, ssa.OpMIPSLoweredPanicExtendC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
s.UseArgs(12) // space used in callee args area by assembly stubs
case ssa.OpMIPSLoweredAtomicLoad:
s.Prog(mips.ASYNC)

View file

@ -489,6 +489,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.OpMIPS64LoweredPanicBoundsA, ssa.OpMIPS64LoweredPanicBoundsB, ssa.OpMIPS64LoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(16) // space used in callee args area by assembly stubs
case ssa.OpMIPS64LoweredAtomicLoad32, ssa.OpMIPS64LoweredAtomicLoad64:
as := mips.AMOVV
if v.Op == ssa.OpMIPS64LoweredAtomicLoad32 {

View file

@ -1183,6 +1183,13 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.OpPPC64LoweredPanicBoundsA, ssa.OpPPC64LoweredPanicBoundsB, ssa.OpPPC64LoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(16) // space used in callee args area by assembly stubs
case ssa.OpPPC64LoweredNilCheck:
if objabi.GOOS == "aix" {
// CMP Rarg0, R0

View file

@ -514,6 +514,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.OpS390XLoweredPanicBoundsA, ssa.OpS390XLoweredPanicBoundsB, ssa.OpS390XLoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(16) // space used in callee args area by assembly stubs
case ssa.OpS390XFLOGR, ssa.OpS390XPOPCNT,
ssa.OpS390XNEG, ssa.OpS390XNEGW,
ssa.OpS390XMOVWBR, ssa.OpS390XMOVDBR:

View file

@ -512,6 +512,18 @@ func (b *Block) NewValue4(pos src.XPos, op Op, t *types.Type, arg0, arg1, arg2,
return v
}
// NewValue4I returns a new value in the block with four arguments and and auxint value.
func (b *Block) NewValue4I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1, arg2, arg3 *Value) *Value {
v := b.Func.newValue(op, t, b, pos)
v.AuxInt = auxint
v.Args = []*Value{arg0, arg1, arg2, arg3}
arg0.Uses++
arg1.Uses++
arg2.Uses++
arg3.Uses++
return v
}
// constVal returns a constant value for c.
func (f *Func) constVal(op Op, t *types.Type, c int64, setAuxInt bool) *Value {
if f.constants == nil {

View file

@ -385,6 +385,14 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 -> (LoweredPanicExtendA [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 -> (LoweredPanicExtendB [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 -> (LoweredPanicExtendC [kind] hi lo y mem)
// ***************************
// Above: lowering rules
// Below: optimizations

View file

@ -86,6 +86,8 @@ func init() {
ax = buildReg("AX")
cx = buildReg("CX")
dx = buildReg("DX")
bx = buildReg("BX")
si = buildReg("SI")
gp = buildReg("AX CX DX BX BP SI DI")
fp = buildReg("X0 X1 X2 X3 X4 X5 X6 X7")
gpsp = gp | buildReg("SP")
@ -524,6 +526,17 @@ func init() {
// It saves all GP registers if necessary, but may clobber others.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{dx, bx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{cx, dx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{ax, cx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
// Extend ops are the same as Bounds ops except the indexes are 64-bit.
{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, dx, bx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, cx, dx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, ax, cx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
// Constant flag values. For any comparison, there are 5 possible
// outcomes: the three from the signed total order (<,==,>) and the
// three from the unsigned total order. The == cases overlap.

View file

@ -225,7 +225,8 @@
(NeqPtr x y) && config.PtrSize == 4 -> (SETNE (CMPL x y))
(Neq(32|64)F x y) -> (SETNEF (UCOMIS(S|D) x y))
(Int64Hi x) -> (SHRQconst [32] x) // needed for amd64p32
(Int64Hi x) -> (SHRQconst [32] x) // needed for amd64p32
(Int64Lo x) -> x
// Lowering loads
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t) && config.PtrSize == 8) -> (MOVQload ptr mem)
@ -561,6 +562,15 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
// For amd64p32
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 -> (LoweredPanicExtendA [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 -> (LoweredPanicExtendB [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 -> (LoweredPanicExtendC [kind] hi lo y mem)
// ***************************
// Above: lowering rules
// Below: optimizations

View file

@ -93,6 +93,8 @@ func init() {
ax = buildReg("AX")
cx = buildReg("CX")
dx = buildReg("DX")
bx = buildReg("BX")
si = buildReg("SI")
gp = buildReg("AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15")
fp = buildReg("X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15")
gpsp = gp | buildReg("SP")
@ -709,6 +711,19 @@ func init() {
// It saves all GP registers if necessary, but may clobber others.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{dx, bx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{cx, dx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{ax, cx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
// amd64p32 only: PanicBounds ops take 32-bit indexes.
// The Extend ops are the same as the Bounds ops except the indexes are 64-bit.
{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, dx, bx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, cx, dx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, ax, cx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
// Constant flag values. For any comparison, there are 5 possible
// outcomes: the three from the signed total order (<,==,>) and the
// three from the unsigned total order. The == cases overlap.

View file

@ -406,6 +406,14 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 -> (LoweredPanicExtendA [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 -> (LoweredPanicExtendB [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 -> (LoweredPanicExtendC [kind] hi lo y mem)
// Optimizations
// fold offset into address

View file

@ -600,6 +600,10 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
// Optimizations
// Absorb boolean tests into block

View file

@ -130,6 +130,10 @@ func init() {
gpspsbg = gpspg | buildReg("SB")
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
r0 = buildReg("R0")
r1 = buildReg("R1")
r2 = buildReg("R2")
r3 = buildReg("R3")
)
// Common regInfo
var (
@ -650,6 +654,13 @@ func init() {
// It saves all GP registers if necessary,
// but clobbers R30 (LR) because it's a call.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
}
blocks := []blockData{

View file

@ -94,6 +94,11 @@ func init() {
gpspsbg = gpspg | buildReg("SB")
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
r0 = buildReg("R0")
r1 = buildReg("R1")
r2 = buildReg("R2")
r3 = buildReg("R3")
r4 = buildReg("R4")
)
// Common regInfo
var (
@ -526,6 +531,17 @@ func init() {
// See runtime/stubs.go for a more detailed discussion.
{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
// Extend ops are the same as Bounds ops except the indexes are 64-bit.
{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r2, r3}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r1, r2}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r0, r1}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
// Constant flag values. For any comparison, there are 5 possible
// outcomes: the three from the signed total order (<,==,>) and the
// three from the unsigned total order. The == cases overlap.

View file

@ -410,6 +410,13 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 -> (LoweredPanicExtendA [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 -> (LoweredPanicExtendB [kind] hi lo y mem)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 -> (LoweredPanicExtendC [kind] hi lo y mem)
// Optimizations

View file

@ -412,6 +412,10 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
// Optimizations
// Absorb boolean tests into block

View file

@ -136,6 +136,10 @@ func init() {
lo = buildReg("LO")
hi = buildReg("HI")
callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
r1 = buildReg("R1")
r2 = buildReg("R2")
r3 = buildReg("R3")
r4 = buildReg("R4")
)
// Common regInfo
var (
@ -420,6 +424,13 @@ func init() {
// but clobbers R31 (LR) because it's a call
// and R23 (REGTMP).
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
}
blocks := []blockData{

View file

@ -120,6 +120,11 @@ func init() {
lo = buildReg("LO")
hi = buildReg("HI")
callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
r1 = buildReg("R1")
r2 = buildReg("R2")
r3 = buildReg("R3")
r4 = buildReg("R4")
r5 = buildReg("R5")
)
// Common regInfo
var (
@ -390,6 +395,17 @@ func init() {
// but clobbers R31 (LR) because it's a call
// and R23 (REGTMP).
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
// Extend ops are the same as Bounds ops except the indexes are 64-bit.
{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r3, r4}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r2, r3}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r1, r2}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
}
blocks := []blockData{

View file

@ -655,6 +655,10 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
// Optimizations
// Note that PPC "logical" immediates come in 0:15 and 16:31 unsigned immediate forms,
// so ORconst, XORconst easily expand into a pair.

View file

@ -158,6 +158,10 @@ func init() {
fpstore = regInfo{inputs: []regMask{gp | sp | sb, fp}}
fpstoreidx = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, fp}}
callerSave = regMask(gp | fp | gr)
r3 = buildReg("R3")
r4 = buildReg("R4")
r5 = buildReg("R5")
r6 = buildReg("R6")
)
ops := []opData{
{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true}, // arg0 + arg1
@ -537,6 +541,13 @@ func init() {
// but may clobber anything else, including R31 (REGTMP).
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ buildReg("R0 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R20 R21 g")) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r6}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r5}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
// (InvertFlags (CMP a b)) == (CMP b a)
// So if we want (LessThan (CMP a b)) but we can't do that because a is a constant,
// then we do (LessThan (InvertFlags (CMP b a))) instead.

View file

@ -419,6 +419,10 @@
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem)
// ***************************
// Above: lowering rules
// Below: optimizations

View file

@ -127,6 +127,9 @@ func init() {
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
r1 = buildReg("R1")
r2 = buildReg("R2")
r3 = buildReg("R3")
)
// Common slices of register masks
var (
@ -463,6 +466,13 @@ func init() {
// but clobbers R14 (LR) because it's a call.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// default registers to match so we don't need to copy registers around unnecessarily.
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
// Constant flag values. For any comparison, there are 5 possible
// outcomes: the three from the signed total order (<,==,>) and the
// three from the unsigned total order. The == cases overlap.

View file

@ -369,6 +369,14 @@ var genericOps = []opData{
// arch-dependent), and is not a safe-point.
{name: "WB", argLength: 3, typ: "Mem", aux: "Sym", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
// PanicBounds and PanicExtend generate a runtime panic.
// Their arguments provide index values to use in panic messages.
// Both PanicBounds and PanicExtend have an AuxInt value from the BoundsKind type (in ../op.go).
// PanicBounds' index is int sized.
// PanicExtend's index is int64 sized. (PanicExtend is only used on 32-bit archs.)
{name: "PanicBounds", argLength: 3, aux: "Int64", typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory.
{name: "PanicExtend", argLength: 4, aux: "Int64", typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory.
// Function calls. Arguments to the call have already been written to the stack.
// Return values appear on the stack. The method receiver, if any, is treated
// as a phantom first argument.

View file

@ -165,3 +165,70 @@ func (x ValAndOff) add(off int64) int64 {
}
return makeValAndOff(x.Val(), x.Off()+off)
}
type BoundsKind uint8
const (
BoundsIndex BoundsKind = iota // indexing operation, 0 <= idx < len failed
BoundsIndexU // ... with unsigned idx
BoundsSliceAlen // 2-arg slicing operation, 0 <= high <= len failed
BoundsSliceAlenU // ... with unsigned high
BoundsSliceAcap // 2-arg slicing operation, 0 <= high <= cap failed
BoundsSliceAcapU // ... with unsigned high
BoundsSliceB // 2-arg slicing operation, 0 <= low <= high failed
BoundsSliceBU // ... with unsigned low
BoundsSlice3Alen // 3-arg slicing operation, 0 <= max <= len failed
BoundsSlice3AlenU // ... with unsigned max
BoundsSlice3Acap // 3-arg slicing operation, 0 <= max <= cap failed
BoundsSlice3AcapU // ... with unsigned max
BoundsSlice3B // 3-arg slicing operation, 0 <= high <= max failed
BoundsSlice3BU // ... with unsigned high
BoundsSlice3C // 3-arg slicing operation, 0 <= low <= high failed
BoundsSlice3CU // ... with unsigned low
BoundsKindCount
)
// boundsAPI determines which register arguments a bounds check call should use. For an [a:b:c] slice, we do:
// CMPQ c, cap
// JA fail1
// CMPQ b, c
// JA fail2
// CMPQ a, b
// JA fail3
//
// fail1: CALL panicSlice3Acap (c, cap)
// fail2: CALL panicSlice3B (b, c)
// fail3: CALL panicSlice3C (a, b)
//
// When we register allocate that code, we want the same register to be used for
// the first arg of panicSlice3Acap and the second arg to panicSlice3B. That way,
// initializing that register once will satisfy both calls.
// That desire ends up dividing the set of bounds check calls into 3 sets. This function
// determines which set to use for a given panic call.
// The first arg for set 0 should be the second arg for set 1.
// The first arg for set 1 should be the second arg for set 2.
func boundsABI(b int64) int {
switch BoundsKind(b) {
case BoundsSlice3Alen,
BoundsSlice3AlenU,
BoundsSlice3Acap,
BoundsSlice3AcapU:
return 0
case BoundsSliceAlen,
BoundsSliceAlenU,
BoundsSliceAcap,
BoundsSliceAcapU,
BoundsSlice3B,
BoundsSlice3BU:
return 1
case BoundsIndex,
BoundsIndexU,
BoundsSliceB,
BoundsSliceBU,
BoundsSlice3C,
BoundsSlice3CU:
return 2
default:
panic("bad BoundsKind")
}
}

View file

@ -463,6 +463,12 @@ const (
Op386LoweredGetCallerSP
Op386LoweredNilCheck
Op386LoweredWB
Op386LoweredPanicBoundsA
Op386LoweredPanicBoundsB
Op386LoweredPanicBoundsC
Op386LoweredPanicExtendA
Op386LoweredPanicExtendB
Op386LoweredPanicExtendC
Op386FlagEQ
Op386FlagLT_ULT
Op386FlagLT_UGT
@ -844,6 +850,12 @@ const (
OpAMD64LoweredGetCallerSP
OpAMD64LoweredNilCheck
OpAMD64LoweredWB
OpAMD64LoweredPanicBoundsA
OpAMD64LoweredPanicBoundsB
OpAMD64LoweredPanicBoundsC
OpAMD64LoweredPanicExtendA
OpAMD64LoweredPanicExtendB
OpAMD64LoweredPanicExtendC
OpAMD64FlagEQ
OpAMD64FlagLT_ULT
OpAMD64FlagLT_UGT
@ -1115,6 +1127,12 @@ const (
OpARMLoweredGetClosurePtr
OpARMLoweredGetCallerSP
OpARMLoweredGetCallerPC
OpARMLoweredPanicBoundsA
OpARMLoweredPanicBoundsB
OpARMLoweredPanicBoundsC
OpARMLoweredPanicExtendA
OpARMLoweredPanicExtendB
OpARMLoweredPanicExtendC
OpARMFlagEQ
OpARMFlagLT_ULT
OpARMFlagLT_UGT
@ -1403,6 +1421,9 @@ const (
OpARM64LoweredAtomicAnd8
OpARM64LoweredAtomicOr8
OpARM64LoweredWB
OpARM64LoweredPanicBoundsA
OpARM64LoweredPanicBoundsB
OpARM64LoweredPanicBoundsC
OpMIPSADD
OpMIPSADDconst
@ -1506,6 +1527,12 @@ const (
OpMIPSLoweredGetCallerSP
OpMIPSLoweredGetCallerPC
OpMIPSLoweredWB
OpMIPSLoweredPanicBoundsA
OpMIPSLoweredPanicBoundsB
OpMIPSLoweredPanicBoundsC
OpMIPSLoweredPanicExtendA
OpMIPSLoweredPanicExtendB
OpMIPSLoweredPanicExtendC
OpMIPS64ADDV
OpMIPS64ADDVconst
@ -1619,6 +1646,9 @@ const (
OpMIPS64LoweredGetCallerSP
OpMIPS64LoweredGetCallerPC
OpMIPS64LoweredWB
OpMIPS64LoweredPanicBoundsA
OpMIPS64LoweredPanicBoundsB
OpMIPS64LoweredPanicBoundsC
OpPPC64ADD
OpPPC64ADDconst
@ -1799,6 +1829,9 @@ const (
OpPPC64LoweredAtomicAnd8
OpPPC64LoweredAtomicOr8
OpPPC64LoweredWB
OpPPC64LoweredPanicBoundsA
OpPPC64LoweredPanicBoundsB
OpPPC64LoweredPanicBoundsC
OpPPC64InvertFlags
OpPPC64FlagEQ
OpPPC64FlagLT
@ -1994,6 +2027,9 @@ const (
OpS390XLoweredRound32F
OpS390XLoweredRound64F
OpS390XLoweredWB
OpS390XLoweredPanicBoundsA
OpS390XLoweredPanicBoundsB
OpS390XLoweredPanicBoundsC
OpS390XFlagEQ
OpS390XFlagLT
OpS390XFlagGT
@ -2351,6 +2387,8 @@ const (
OpMoveWB
OpZeroWB
OpWB
OpPanicBounds
OpPanicExtend
OpClosureCall
OpStaticCall
OpInterCall
@ -5588,6 +5626,75 @@ var opcodeTable = [...]opInfo{
clobbers: 65280, // X0 X1 X2 X3 X4 X5 X6 X7
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // DX
{1, 8}, // BX
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // CX
{1, 4}, // DX
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
{1, 2}, // CX
},
},
},
{
name: "LoweredPanicExtendA",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 64}, // SI
{1, 4}, // DX
{2, 8}, // BX
},
},
},
{
name: "LoweredPanicExtendB",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 64}, // SI
{1, 2}, // CX
{2, 4}, // DX
},
},
},
{
name: "LoweredPanicExtendC",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 64}, // SI
{1, 1}, // AX
{2, 2}, // CX
},
},
},
{
name: "FlagEQ",
argLen: 0,
@ -11113,6 +11220,75 @@ var opcodeTable = [...]opInfo{
clobbers: 4294901760, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // DX
{1, 8}, // BX
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // CX
{1, 4}, // DX
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // AX
{1, 2}, // CX
},
},
},
{
name: "LoweredPanicExtendA",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 64}, // SI
{1, 4}, // DX
{2, 8}, // BX
},
},
},
{
name: "LoweredPanicExtendB",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 64}, // SI
{1, 2}, // CX
{2, 4}, // DX
},
},
},
{
name: "LoweredPanicExtendC",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 64}, // SI
{1, 1}, // AX
{2, 2}, // CX
},
},
},
{
name: "FlagEQ",
argLen: 0,
@ -14847,6 +15023,75 @@ var opcodeTable = [...]opInfo{
},
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // R2
{1, 8}, // R3
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
{1, 4}, // R2
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // R0
{1, 2}, // R1
},
},
},
{
name: "LoweredPanicExtendA",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 16}, // R4
{1, 4}, // R2
{2, 8}, // R3
},
},
},
{
name: "LoweredPanicExtendB",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 16}, // R4
{1, 2}, // R1
{2, 4}, // R2
},
},
},
{
name: "LoweredPanicExtendC",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 16}, // R4
{1, 1}, // R0
{2, 2}, // R1
},
},
},
{
name: "FlagEQ",
argLen: 0,
@ -18610,6 +18855,39 @@ var opcodeTable = [...]opInfo{
clobbers: 9223372035244163072, // R30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // R2
{1, 8}, // R3
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
{1, 4}, // R2
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // R0
{1, 2}, // R1
},
},
},
{
name: "ADD",
@ -20000,6 +20278,75 @@ var opcodeTable = [...]opInfo{
clobbers: 140737219919872, // R31 F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30 HI LO
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 8}, // R3
{1, 16}, // R4
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // R2
{1, 8}, // R3
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
{1, 4}, // R2
},
},
},
{
name: "LoweredPanicExtendA",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 32}, // R5
{1, 8}, // R3
{2, 16}, // R4
},
},
},
{
name: "LoweredPanicExtendB",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 32}, // R5
{1, 4}, // R2
{2, 8}, // R3
},
},
},
{
name: "LoweredPanicExtendC",
auxType: auxInt64,
argLen: 4,
reg: regInfo{
inputs: []inputInfo{
{0, 32}, // R5
{1, 2}, // R1
{2, 4}, // R2
},
},
},
{
name: "ADDV",
@ -21530,6 +21877,39 @@ var opcodeTable = [...]opInfo{
clobbers: 4611686018293170176, // R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 HI LO
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 8}, // R3
{1, 16}, // R4
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // R2
{1, 8}, // R3
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
{1, 4}, // R2
},
},
},
{
name: "ADD",
@ -24010,6 +24390,39 @@ var opcodeTable = [...]opInfo{
clobbers: 576460746931503104, // R16 R17 R18 R19 R22 R23 R24 R25 R26 R27 R28 R29 R31 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 32}, // R5
{1, 64}, // R6
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 16}, // R4
{1, 32}, // R5
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 8}, // R3
{1, 16}, // R4
},
},
},
{
name: "InvertFlags",
argLen: 1,
@ -26871,6 +27284,39 @@ var opcodeTable = [...]opInfo{
clobbers: 4294918144, // R14 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
},
},
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 4}, // R2
{1, 8}, // R3
},
},
},
{
name: "LoweredPanicBoundsB",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
{1, 4}, // R2
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
reg: regInfo{
inputs: []inputInfo{
{0, 1}, // R0
{1, 2}, // R1
},
},
},
{
name: "FlagEQ",
argLen: 0,
@ -29693,6 +30139,18 @@ var opcodeTable = [...]opInfo{
symEffect: SymNone,
generic: true,
},
{
name: "PanicBounds",
auxType: auxInt64,
argLen: 3,
generic: true,
},
{
name: "PanicExtend",
auxType: auxInt64,
argLen: 4,
generic: true,
},
{
name: "ClosureCall",
auxType: auxInt64,

View file

@ -587,6 +587,10 @@ func rewriteValue386(v *Value) bool {
return rewriteValue386_OpOr8_0(v)
case OpOrB:
return rewriteValue386_OpOrB_0(v)
case OpPanicBounds:
return rewriteValue386_OpPanicBounds_0(v)
case OpPanicExtend:
return rewriteValue386_OpPanicExtend_0(v)
case OpRound32F:
return rewriteValue386_OpRound32F_0(v)
case OpRound64F:
@ -22897,6 +22901,132 @@ func rewriteValue386_OpOrB_0(v *Value) bool {
return true
}
}
func rewriteValue386_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(Op386LoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(Op386LoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(Op386LoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValue386_OpPanicExtend_0(v *Value) bool {
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicExtendA [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 0) {
break
}
v.reset(Op386LoweredPanicExtendA)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicExtendB [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 1) {
break
}
v.reset(Op386LoweredPanicExtendB)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicExtendC [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 2) {
break
}
v.reset(Op386LoweredPanicExtendC)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValue386_OpRound32F_0(v *Value) bool {
// match: (Round32F x)
// cond:

View file

@ -831,6 +831,8 @@ func rewriteValueAMD64(v *Value) bool {
return rewriteValueAMD64_OpHmul64u_0(v)
case OpInt64Hi:
return rewriteValueAMD64_OpInt64Hi_0(v)
case OpInt64Lo:
return rewriteValueAMD64_OpInt64Lo_0(v)
case OpInterCall:
return rewriteValueAMD64_OpInterCall_0(v)
case OpIsInBounds:
@ -991,6 +993,10 @@ func rewriteValueAMD64(v *Value) bool {
return rewriteValueAMD64_OpOr8_0(v)
case OpOrB:
return rewriteValueAMD64_OpOrB_0(v)
case OpPanicBounds:
return rewriteValueAMD64_OpPanicBounds_0(v)
case OpPanicExtend:
return rewriteValueAMD64_OpPanicExtend_0(v)
case OpPopCount16:
return rewriteValueAMD64_OpPopCount16_0(v)
case OpPopCount32:
@ -59244,6 +59250,18 @@ func rewriteValueAMD64_OpInt64Hi_0(v *Value) bool {
return true
}
}
func rewriteValueAMD64_OpInt64Lo_0(v *Value) bool {
// match: (Int64Lo x)
// cond:
// result: x
for {
x := v.Args[0]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
}
func rewriteValueAMD64_OpInterCall_0(v *Value) bool {
// match: (InterCall [argwid] entry mem)
// cond:
@ -61695,6 +61713,132 @@ func rewriteValueAMD64_OpOrB_0(v *Value) bool {
return true
}
}
func rewriteValueAMD64_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpAMD64LoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpAMD64LoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpAMD64LoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueAMD64_OpPanicExtend_0(v *Value) bool {
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicExtendA [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpAMD64LoweredPanicExtendA)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicExtendB [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpAMD64LoweredPanicExtendB)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicExtendC [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpAMD64LoweredPanicExtendC)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueAMD64_OpPopCount16_0(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types

View file

@ -719,6 +719,10 @@ func rewriteValueARM(v *Value) bool {
return rewriteValueARM_OpOr8_0(v)
case OpOrB:
return rewriteValueARM_OpOrB_0(v)
case OpPanicBounds:
return rewriteValueARM_OpPanicBounds_0(v)
case OpPanicExtend:
return rewriteValueARM_OpPanicExtend_0(v)
case OpRound32F:
return rewriteValueARM_OpRound32F_0(v)
case OpRound64F:
@ -20075,6 +20079,132 @@ func rewriteValueARM_OpOrB_0(v *Value) bool {
return true
}
}
func rewriteValueARM_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpARMLoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpARMLoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpARMLoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpPanicExtend_0(v *Value) bool {
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicExtendA [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpARMLoweredPanicExtendA)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicExtendB [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpARMLoweredPanicExtendB)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicExtendC [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpARMLoweredPanicExtendC)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM_OpRound32F_0(v *Value) bool {
// match: (Round32F x)
// cond:

View file

@ -789,6 +789,8 @@ func rewriteValueARM64(v *Value) bool {
return rewriteValueARM64_OpOr8_0(v)
case OpOrB:
return rewriteValueARM64_OpOrB_0(v)
case OpPanicBounds:
return rewriteValueARM64_OpPanicBounds_0(v)
case OpPopCount16:
return rewriteValueARM64_OpPopCount16_0(v)
case OpPopCount32:
@ -35631,6 +35633,66 @@ func rewriteValueARM64_OpOrB_0(v *Value) bool {
return true
}
}
func rewriteValueARM64_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpARM64LoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpARM64LoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpARM64LoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueARM64_OpPopCount16_0(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types

View file

@ -405,6 +405,10 @@ func rewriteValueMIPS(v *Value) bool {
return rewriteValueMIPS_OpOr8_0(v)
case OpOrB:
return rewriteValueMIPS_OpOrB_0(v)
case OpPanicBounds:
return rewriteValueMIPS_OpPanicBounds_0(v)
case OpPanicExtend:
return rewriteValueMIPS_OpPanicExtend_0(v)
case OpRound32F:
return rewriteValueMIPS_OpRound32F_0(v)
case OpRound64F:
@ -6975,6 +6979,132 @@ func rewriteValueMIPS_OpOrB_0(v *Value) bool {
return true
}
}
func rewriteValueMIPS_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpMIPSLoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpMIPSLoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpMIPSLoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueMIPS_OpPanicExtend_0(v *Value) bool {
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicExtendA [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpMIPSLoweredPanicExtendA)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicExtendB [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpMIPSLoweredPanicExtendB)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicExtend [kind] hi lo y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicExtendC [kind] hi lo y mem)
for {
kind := v.AuxInt
_ = v.Args[3]
hi := v.Args[0]
lo := v.Args[1]
y := v.Args[2]
mem := v.Args[3]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpMIPSLoweredPanicExtendC)
v.AuxInt = kind
v.AddArg(hi)
v.AddArg(lo)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueMIPS_OpRound32F_0(v *Value) bool {
// match: (Round32F x)
// cond:

View file

@ -469,6 +469,8 @@ func rewriteValueMIPS64(v *Value) bool {
return rewriteValueMIPS64_OpOr8_0(v)
case OpOrB:
return rewriteValueMIPS64_OpOrB_0(v)
case OpPanicBounds:
return rewriteValueMIPS64_OpPanicBounds_0(v)
case OpRound32F:
return rewriteValueMIPS64_OpRound32F_0(v)
case OpRound64F:
@ -7412,6 +7414,66 @@ func rewriteValueMIPS64_OpOrB_0(v *Value) bool {
return true
}
}
func rewriteValueMIPS64_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpMIPS64LoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpMIPS64LoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpMIPS64LoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueMIPS64_OpRound32F_0(v *Value) bool {
// match: (Round32F x)
// cond:

View file

@ -547,6 +547,8 @@ func rewriteValuePPC64(v *Value) bool {
return rewriteValuePPC64_OpPPC64XOR_0(v) || rewriteValuePPC64_OpPPC64XOR_10(v)
case OpPPC64XORconst:
return rewriteValuePPC64_OpPPC64XORconst_0(v)
case OpPanicBounds:
return rewriteValuePPC64_OpPanicBounds_0(v)
case OpPopCount16:
return rewriteValuePPC64_OpPopCount16_0(v)
case OpPopCount32:
@ -26076,6 +26078,66 @@ func rewriteValuePPC64_OpPPC64XORconst_0(v *Value) bool {
}
return false
}
func rewriteValuePPC64_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpPPC64LoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpPPC64LoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpPPC64LoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValuePPC64_OpPopCount16_0(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types

View file

@ -385,6 +385,8 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpOr8_0(v)
case OpOrB:
return rewriteValueS390X_OpOrB_0(v)
case OpPanicBounds:
return rewriteValueS390X_OpPanicBounds_0(v)
case OpPopCount16:
return rewriteValueS390X_OpPopCount16_0(v)
case OpPopCount32:
@ -4965,6 +4967,66 @@ func rewriteValueS390X_OpOrB_0(v *Value) bool {
return true
}
}
func rewriteValueS390X_OpPanicBounds_0(v *Value) bool {
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 0
// result: (LoweredPanicBoundsA [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 0) {
break
}
v.reset(OpS390XLoweredPanicBoundsA)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 1
// result: (LoweredPanicBoundsB [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 1) {
break
}
v.reset(OpS390XLoweredPanicBoundsB)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
// match: (PanicBounds [kind] x y mem)
// cond: boundsABI(kind) == 2
// result: (LoweredPanicBoundsC [kind] x y mem)
for {
kind := v.AuxInt
_ = v.Args[2]
x := v.Args[0]
y := v.Args[1]
mem := v.Args[2]
if !(boundsABI(kind) == 2) {
break
}
v.reset(OpS390XLoweredPanicBoundsC)
v.AuxInt = kind
v.AddArg(x)
v.AddArg(y)
v.AddArg(mem)
return true
}
return false
}
func rewriteValueS390X_OpPopCount16_0(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types

View file

@ -758,6 +758,20 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Name = obj.NAME_EXTERN
p.To.Sym = v.Aux.(*obj.LSym)
case ssa.Op386LoweredPanicBoundsA, ssa.Op386LoweredPanicBoundsB, ssa.Op386LoweredPanicBoundsC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
s.UseArgs(8) // space used in callee args area by assembly stubs
case ssa.Op386LoweredPanicExtendA, ssa.Op386LoweredPanicExtendB, ssa.Op386LoweredPanicExtendC:
p := s.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
s.UseArgs(12) // space used in callee args area by assembly stubs
case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter:
s.Call(v)
case ssa.Op386NEGL,

View file

@ -1401,3 +1401,155 @@ flush:
MOVL 12(SP), BP
MOVL 16(SP), SI
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSlice3CU(SB)
// Extended versions for 64-bit indexes.
TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendIndex(SB)
TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendIndexU(SB)
TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAlen(SB)
TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAlenU(SB)
TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAcap(SB)
TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAcapU(SB)
TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSliceB(SB)
TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSliceBU(SB)
TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3Alen(SB)
TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3AlenU(SB)
TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3Acap(SB)
TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3AcapU(SB)
TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSlice3B(SB)
TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSlice3BU(SB)
TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSlice3C(SB)
TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSlice3CU(SB)

View file

@ -1628,3 +1628,73 @@ TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
MOVQ $2, AX
BYTE $0xcc
RET
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
MOVQ AX, x+0(FP)
MOVQ CX, y+8(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
MOVQ AX, x+0(FP)
MOVQ CX, y+8(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
MOVQ CX, x+0(FP)
MOVQ DX, y+8(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
MOVQ CX, x+0(FP)
MOVQ DX, y+8(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
MOVQ CX, x+0(FP)
MOVQ DX, y+8(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
MOVQ CX, x+0(FP)
MOVQ DX, y+8(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
MOVQ AX, x+0(FP)
MOVQ CX, y+8(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
MOVQ AX, x+0(FP)
MOVQ CX, y+8(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
MOVQ DX, x+0(FP)
MOVQ BX, y+8(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
MOVQ DX, x+0(FP)
MOVQ BX, y+8(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
MOVQ DX, x+0(FP)
MOVQ BX, y+8(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
MOVQ DX, x+0(FP)
MOVQ BX, y+8(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
MOVQ CX, x+0(FP)
MOVQ DX, y+8(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
MOVQ CX, x+0(FP)
MOVQ DX, y+8(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
MOVQ AX, x+0(FP)
MOVQ CX, y+8(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
MOVQ AX, x+0(FP)
MOVQ CX, y+8(FP)
JMP runtime·goPanicSlice3CU(SB)

View file

@ -607,3 +607,155 @@ flush:
MOVQ 56(SP), R11
MOVQ 64(SP), R12
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
MOVL DX, x+0(FP)
MOVL BX, y+4(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
MOVL CX, x+0(FP)
MOVL DX, y+4(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
MOVL AX, x+0(FP)
MOVL CX, y+4(FP)
JMP runtime·goPanicSlice3CU(SB)
// Extended versions for 64-bit indexes.
TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendIndex(SB)
TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendIndexU(SB)
TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAlen(SB)
TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAlenU(SB)
TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAcap(SB)
TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSliceAcapU(SB)
TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSliceB(SB)
TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSliceBU(SB)
TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3Alen(SB)
TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3AlenU(SB)
TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3Acap(SB)
TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL DX, lo+4(FP)
MOVL BX, y+8(FP)
JMP runtime·goPanicExtendSlice3AcapU(SB)
TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSlice3B(SB)
TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL CX, lo+4(FP)
MOVL DX, y+8(FP)
JMP runtime·goPanicExtendSlice3BU(SB)
TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSlice3C(SB)
TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
MOVL SI, hi+0(FP)
MOVL AX, lo+4(FP)
MOVL CX, y+8(FP)
JMP runtime·goPanicExtendSlice3CU(SB)

View file

@ -969,3 +969,155 @@ flush:
MOVM.IA.W (R13), [R14]
MOVM.IA.W (R13), [R2-R9,R12]
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
MOVW R0, x+0(FP)
MOVW R1, y+4(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
MOVW R0, x+0(FP)
MOVW R1, y+4(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
MOVW R0, x+0(FP)
MOVW R1, y+4(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
MOVW R0, x+0(FP)
MOVW R1, y+4(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
MOVW R0, x+0(FP)
MOVW R1, y+4(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
MOVW R0, x+0(FP)
MOVW R1, y+4(FP)
JMP runtime·goPanicSlice3CU(SB)
// Extended versions for 64-bit indexes.
TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R0, lo+4(FP)
MOVW R1, y+8(FP)
JMP runtime·goPanicExtendIndex(SB)
TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R0, lo+4(FP)
MOVW R1, y+8(FP)
JMP runtime·goPanicExtendIndexU(SB)
TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAlen(SB)
TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAlenU(SB)
TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAcap(SB)
TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAcapU(SB)
TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R0, lo+4(FP)
MOVW R1, y+8(FP)
JMP runtime·goPanicExtendSliceB(SB)
TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R0, lo+4(FP)
MOVW R1, y+8(FP)
JMP runtime·goPanicExtendSliceBU(SB)
TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3Alen(SB)
TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3AlenU(SB)
TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3Acap(SB)
TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3AcapU(SB)
TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3B(SB)
TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3BU(SB)
TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R0, lo+4(FP)
MOVW R1, y+8(FP)
JMP runtime·goPanicExtendSlice3C(SB)
TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
MOVW R4, hi+0(FP)
MOVW R0, lo+4(FP)
MOVW R1, y+8(FP)
JMP runtime·goPanicExtendSlice3CU(SB)

View file

@ -1245,3 +1245,73 @@ flush:
MOVD 184(RSP), R25
MOVD 192(RSP), R26
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSlice3CU(SB)

View file

@ -750,3 +750,73 @@ flush:
MOVV 168(R29), R24
MOVV 176(R29), R25
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
MOVV R1, x+0(FP)
MOVV R2, y+8(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
MOVV R1, x+0(FP)
MOVV R2, y+8(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
MOVV R2, x+0(FP)
MOVV R3, y+8(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
MOVV R2, x+0(FP)
MOVV R3, y+8(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
MOVV R2, x+0(FP)
MOVV R3, y+8(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
MOVV R2, x+0(FP)
MOVV R3, y+8(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
MOVV R1, x+0(FP)
MOVV R2, y+8(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
MOVV R1, x+0(FP)
MOVV R2, y+8(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
MOVV R3, x+0(FP)
MOVV R4, y+8(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
MOVV R3, x+0(FP)
MOVV R4, y+8(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
MOVV R3, x+0(FP)
MOVV R4, y+8(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
MOVV R3, x+0(FP)
MOVV R4, y+8(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
MOVV R2, x+0(FP)
MOVV R3, y+8(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
MOVV R2, x+0(FP)
MOVV R3, y+8(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
MOVV R1, x+0(FP)
MOVV R2, y+8(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
MOVV R1, x+0(FP)
MOVV R2, y+8(FP)
JMP runtime·goPanicSlice3CU(SB)

View file

@ -764,3 +764,155 @@ flush:
MOVW 92(R29), R25
MOVW 96(R29), R28
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSlice3CU(SB)
// Extended versions for 64-bit indexes.
TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendIndex(SB)
TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendIndexU(SB)
TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAlen(SB)
TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAlenU(SB)
TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAcap(SB)
TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSliceAcapU(SB)
TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSliceB(SB)
TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSliceBU(SB)
TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3Alen(SB)
TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3AlenU(SB)
TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3Acap(SB)
TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3AcapU(SB)
TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3B(SB)
TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3BU(SB)
TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSlice3C(SB)
TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSlice3CU(SB)

View file

@ -976,3 +976,73 @@ flush:
MOVD (FIXED_FRAME+96)(R1), R14
MOVD (FIXED_FRAME+104)(R1), R15
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
MOVD R3, x+0(FP)
MOVD R4, y+8(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
MOVD R3, x+0(FP)
MOVD R4, y+8(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
MOVD R4, x+0(FP)
MOVD R5, y+8(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
MOVD R4, x+0(FP)
MOVD R5, y+8(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
MOVD R4, x+0(FP)
MOVD R5, y+8(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
MOVD R4, x+0(FP)
MOVD R5, y+8(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
MOVD R3, x+0(FP)
MOVD R4, y+8(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
MOVD R3, x+0(FP)
MOVD R4, y+8(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
MOVD R5, x+0(FP)
MOVD R6, y+8(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
MOVD R5, x+0(FP)
MOVD R6, y+8(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
MOVD R5, x+0(FP)
MOVD R6, y+8(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
MOVD R5, x+0(FP)
MOVD R6, y+8(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
MOVD R4, x+0(FP)
MOVD R5, y+8(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
MOVD R4, x+0(FP)
MOVD R5, y+8(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
MOVD R3, x+0(FP)
MOVD R4, y+8(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
MOVD R3, x+0(FP)
MOVD R4, y+8(FP)
JMP runtime·goPanicSlice3CU(SB)

View file

@ -863,3 +863,73 @@ flush:
MOVD 24(R15), R0 // restore R0
LMG 32(R15), R5, R12 // restore R5 - R12
JMP ret
// Note: these functions use a special calling convention to save generated code space.
// Arguments are passed in registers, but the space for those arguments are allocated
// in the caller's stack frame. These stubs write the args into that stack space and
// then tail call to the corresponding runtime handler.
// The tail call makes these stubs disappear in backtraces.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicIndex(SB)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicIndexU(SB)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAlen(SB)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAlenU(SB)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
MOVD R2, x+0(FP)
MOVD R3, y+8(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
MOVD R1, x+0(FP)
MOVD R2, y+8(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
MOVD R0, x+0(FP)
MOVD R1, y+8(FP)
JMP runtime·goPanicSlice3CU(SB)

View file

@ -53,6 +53,21 @@ func (e *TypeAssertionError) Error() string {
": missing method " + e.missingMethod
}
//go:nosplit
// itoa converts val to a decimal representation. The result is
// written somewhere within buf and the location of the result is returned.
// buf must be at least 20 bytes.
func itoa(buf []byte, val uint64) []byte {
i := len(buf) - 1
for val >= 10 {
buf[i] = byte(val%10 + '0')
i--
val /= 10
}
buf[i] = byte(val + '0')
return buf[i:]
}
// An errorString represents a runtime error described by a single string.
type errorString string
@ -73,6 +88,99 @@ func (e plainError) Error() string {
return string(e)
}
// An boundsError represents a an indexing or slicing operation gone wrong.
type boundsError struct {
x int64
y int
// Values in an index or slice expression can be signed or unsigned.
// That means we'd need 65 bits to encode all possible indexes, from -2^63 to 2^64-1.
// Instead, we keep track of whether x should be interpreted as signed or unsigned.
// y is known to be nonnegative and to fit in an int.
signed bool
code boundsErrorCode
}
type boundsErrorCode uint8
const (
boundsIndex boundsErrorCode = iota // s[x], 0 <= x < len(s) failed
boundsSliceAlen // s[?:x], 0 <= x <= len(s) failed
boundsSliceAcap // s[?:x], 0 <= x <= cap(s) failed
boundsSliceB // s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen)
boundsSlice3Alen // s[?:?:x], 0 <= x <= len(s) failed
boundsSlice3Acap // s[?:?:x], 0 <= x <= cap(s) failed
boundsSlice3B // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen)
boundsSlice3C // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen)
// Note: in the above, len(s) and cap(s) are stored in y
)
// boundsErrorFmts provide error text for various out-of-bounds panics.
// Note: if you change these strings, you should adjust the size of the buffer
// in boundsError.Error below as well.
var boundsErrorFmts = [...]string{
boundsIndex: "index out of range [%x] with length %y",
boundsSliceAlen: "slice bounds out of range [:%x] with length %y",
boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
boundsSliceB: "slice bounds out of range [%x:%y]",
boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
boundsSlice3B: "slice bounds out of range [:%x:%y]",
boundsSlice3C: "slice bounds out of range [%x:%y:]",
}
// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
var boundsNegErrorFmts = [...]string{
boundsIndex: "index out of range [%x]",
boundsSliceAlen: "slice bounds out of range [:%x]",
boundsSliceAcap: "slice bounds out of range [:%x]",
boundsSliceB: "slice bounds out of range [%x:]",
boundsSlice3Alen: "slice bounds out of range [::%x]",
boundsSlice3Acap: "slice bounds out of range [::%x]",
boundsSlice3B: "slice bounds out of range [:%x:]",
boundsSlice3C: "slice bounds out of range [%x::]",
}
func (e boundsError) RuntimeError() {}
func appendIntStr(b []byte, v int64, signed bool) []byte {
if signed && v < 0 {
b = append(b, '-')
v = -v
}
var buf [20]byte
b = append(b, itoa(buf[:], uint64(v))...)
return b
}
func (e boundsError) Error() string {
fmt := boundsErrorFmts[e.code]
if e.signed && e.x < 0 {
fmt = boundsNegErrorFmts[e.code]
}
// max message length is 99: "runtime error: slice bounds out of range [::%x] with capacity %y"
// x can be at most 20 characters. y can be at most 19.
b := make([]byte, 0, 100)
b = append(b, "runtime error: "...)
for i := 0; i < len(fmt); i++ {
c := fmt[i]
if c != '%' {
b = append(b, c)
continue
}
i++
switch fmt[i] {
case 'x':
b = appendIntStr(b, e.x, e.signed)
case 'y':
b = appendIntStr(b, int64(e.y), true)
}
}
return string(b)
}
type stringer interface {
String() string
}

View file

@ -338,18 +338,6 @@ func nanotime() int64 {
return ns
}
//go:nosplit
func itoa(buf []byte, val uint64) []byte {
i := len(buf) - 1
for val >= 10 {
buf[i] = byte(val%10 + '0')
i--
val /= 10
}
buf[i] = byte(val + '0')
return buf[i:]
}
var goexits = []byte("go: exit ")
var emptystatus = []byte("\x00")
var exiting uint32

View file

@ -10,85 +10,176 @@ import (
"unsafe"
)
// Calling panic with one of the errors below will call errorString.Error
// which will call mallocgc to concatenate strings. That will fail if
// malloc is locked, causing a confusing error message. Throw a better
// error message instead.
func panicCheckMalloc(err error) {
// Check to make sure we can really generate a panic. If the panic
// was generated from the runtime, or from inside malloc, then convert
// to a throw of msg.
// pc should be the program counter of the compiler-generated code that
// triggered this panic.
func panicCheck1(pc uintptr, msg string) {
if sys.GoarchWasm == 0 && hasPrefix(funcname(findfunc(pc)), "runtime.") {
// Note: wasm can't tail call, so we can't get the original caller's pc.
throw(msg)
}
// TODO: is this redundant? How could we be in malloc
// but not in the runtime? runtime/internal/*, maybe?
gp := getg()
if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
throw(string(err.(errorString)))
throw(msg)
}
}
var indexError = error(errorString("index out of range"))
// Same as above, but calling from the runtime is allowed.
func panicCheck2(err string) {
gp := getg()
if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
throw(err)
}
}
// The panic{index,slice,divide,shift} functions are called by
// The panic{Index,Slice,divide,shift} functions are called by
// code generated by the compiler for out of bounds index expressions,
// out of bounds slice expressions, division by zero, and shift by negative.
// The panicdivide (again), panicoverflow, panicfloat, and panicmem
// functions are called by the signal handler when a signal occurs
// indicating the respective problem.
//
// Since panic{index,slice,shift} are never called directly, and
// Since panic{Index,Slice,shift} are never called directly, and
// since the runtime package should never have an out of bounds slice
// or array reference or negative shift, if we see those functions called from the
// runtime package we turn the panic into a throw. That will dump the
// entire runtime stack for easier debugging.
//
// The panic{Index,Slice} functions are implemented in assembly and tail call
// to the goPanic{Index,Slice} functions below. This is done so we can use
// a space-minimal register calling convention.
func panicindex() {
if hasPrefix(funcname(findfunc(getcallerpc())), "runtime.") {
throw(string(indexError.(errorString)))
}
panicCheckMalloc(indexError)
panic(indexError)
// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
func goPanicIndex(x int, y int) {
panicCheck1(getcallerpc(), "index out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsIndex})
}
func goPanicIndexU(x uint, y int) {
panicCheck1(getcallerpc(), "index out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsIndex})
}
var sliceError = error(errorString("slice bounds out of range"))
// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
func goPanicSliceAlen(x int, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAlen})
}
func goPanicSliceAlenU(x uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAlen})
}
func goPanicSliceAcap(x int, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAcap})
}
func goPanicSliceAcapU(x uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAcap})
}
func panicslice() {
if hasPrefix(funcname(findfunc(getcallerpc())), "runtime.") {
throw(string(sliceError.(errorString)))
}
panicCheckMalloc(sliceError)
panic(sliceError)
// failures in the comparisons for s[x:y], 0 <= x <= y
func goPanicSliceB(x int, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
}
func goPanicSliceBU(x uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceB})
}
// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
func goPanicSlice3Alen(x int, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Alen})
}
func goPanicSlice3AlenU(x uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Alen})
}
func goPanicSlice3Acap(x int, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Acap})
}
func goPanicSlice3AcapU(x uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Acap})
}
// failures in the comparisons for s[:x:y], 0 <= x <= y
func goPanicSlice3B(x int, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3B})
}
func goPanicSlice3BU(x uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3B})
}
// failures in the comparisons for s[x:y:], 0 <= x <= y
func goPanicSlice3C(x int, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3C})
}
func goPanicSlice3CU(x uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
}
// Implemented in assembly, as they take arguments in registers.
// Declared here to mark them as ABIInternal.
func panicIndex(x int, y int)
func panicIndexU(x uint, y int)
func panicSliceAlen(x int, y int)
func panicSliceAlenU(x uint, y int)
func panicSliceAcap(x int, y int)
func panicSliceAcapU(x uint, y int)
func panicSliceB(x int, y int)
func panicSliceBU(x uint, y int)
func panicSlice3Alen(x int, y int)
func panicSlice3AlenU(x uint, y int)
func panicSlice3Acap(x int, y int)
func panicSlice3AcapU(x uint, y int)
func panicSlice3B(x int, y int)
func panicSlice3BU(x uint, y int)
func panicSlice3C(x int, y int)
func panicSlice3CU(x uint, y int)
var shiftError = error(errorString("negative shift amount"))
func panicshift() {
panicCheck1(getcallerpc(), "negative shift amount")
panic(shiftError)
}
var divideError = error(errorString("integer divide by zero"))
func panicdivide() {
panicCheckMalloc(divideError)
panicCheck2("integer divide by zero")
panic(divideError)
}
var overflowError = error(errorString("integer overflow"))
func panicoverflow() {
panicCheckMalloc(overflowError)
panicCheck2("integer overflow")
panic(overflowError)
}
var shiftError = error(errorString("negative shift amount"))
func panicshift() {
if hasPrefix(funcname(findfunc(getcallerpc())), "runtime.") {
throw(string(shiftError.(errorString)))
}
panicCheckMalloc(shiftError)
panic(shiftError)
}
var floatError = error(errorString("floating point error"))
func panicfloat() {
panicCheckMalloc(floatError)
panicCheck2("floating point error")
panic(floatError)
}
var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
func panicmem() {
panicCheckMalloc(memoryError)
panicCheck2("invalid memory address or nil pointer dereference")
panic(memoryError)
}

105
src/runtime/panic32.go Normal file
View file

@ -0,0 +1,105 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386 amd64p32 arm mips mipsle
package runtime
// Additional index/slice error paths for 32-bit platforms.
// Used when the high word of a 64-bit index is not zero.
// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
func goPanicExtendIndex(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "index out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsIndex})
}
func goPanicExtendIndexU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "index out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsIndex})
}
// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
func goPanicExtendSliceAlen(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceAlen})
}
func goPanicExtendSliceAlenU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceAlen})
}
func goPanicExtendSliceAcap(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceAcap})
}
func goPanicExtendSliceAcapU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceAcap})
}
// failures in the comparisons for s[x:y], 0 <= x <= y
func goPanicExtendSliceB(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceB})
}
func goPanicExtendSliceBU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceB})
}
// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
func goPanicExtendSlice3Alen(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3Alen})
}
func goPanicExtendSlice3AlenU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3Alen})
}
func goPanicExtendSlice3Acap(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3Acap})
}
func goPanicExtendSlice3AcapU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3Acap})
}
// failures in the comparisons for s[:x:y], 0 <= x <= y
func goPanicExtendSlice3B(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3B})
}
func goPanicExtendSlice3BU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3B})
}
// failures in the comparisons for s[x:y:], 0 <= x <= y
func goPanicExtendSlice3C(hi int, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3C})
}
func goPanicExtendSlice3CU(hi uint, lo uint, y int) {
panicCheck1(getcallerpc(), "slice bounds out of range")
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3C})
}
// Implemented in assembly, as they take arguments in registers.
// Declared here to mark them as ABIInternal.
func panicExtendIndex(hi int, lo uint, y int)
func panicExtendIndexU(hi uint, lo uint, y int)
func panicExtendSliceAlen(hi int, lo uint, y int)
func panicExtendSliceAlenU(hi uint, lo uint, y int)
func panicExtendSliceAcap(hi int, lo uint, y int)
func panicExtendSliceAcapU(hi uint, lo uint, y int)
func panicExtendSliceB(hi int, lo uint, y int)
func panicExtendSliceBU(hi uint, lo uint, y int)
func panicExtendSlice3Alen(hi int, lo uint, y int)
func panicExtendSlice3AlenU(hi uint, lo uint, y int)
func panicExtendSlice3Acap(hi int, lo uint, y int)
func panicExtendSlice3AcapU(hi uint, lo uint, y int)
func panicExtendSlice3B(hi int, lo uint, y int)
func panicExtendSlice3BU(hi uint, lo uint, y int)
func panicExtendSlice3C(hi int, lo uint, y int)
func panicExtendSlice3CU(hi uint, lo uint, y int)

View file

@ -20,7 +20,7 @@ var sink16 uint16
// ------------- //
func load_le64(b []byte) {
// amd64:`MOVQ\s\(.*\),`,-`MOV[BWL]`,-`OR`
// amd64:`MOVQ\s\(.*\),`,-`MOV[BWL]\t[^$]`,-`OR`
// s390x:`MOVDBR\s\(.*\),`
// arm64:`MOVD\s\(R[0-9]+\),`,-`MOV[BHW]`
// ppc64le:`MOVD\s`,-`MOV[BHW]Z`
@ -28,7 +28,7 @@ func load_le64(b []byte) {
}
func load_le64_idx(b []byte, idx int) {
// amd64:`MOVQ\s\(.*\)\(.*\*1\),`,-`MOV[BWL]`,-`OR`
// amd64:`MOVQ\s\(.*\)\(.*\*1\),`,-`MOV[BWL]\t[^$]`,-`OR`
// s390x:`MOVDBR\s\(.*\)\(.*\*1\),`
// arm64:`MOVD\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[BHW]`
// ppc64le:`MOVD\s`,-`MOV[BHW]Z\s`
@ -68,7 +68,7 @@ func load_le16_idx(b []byte, idx int) {
}
func load_be64(b []byte) {
// amd64:`BSWAPQ`,-`MOV[BWL]`,-`OR`
// amd64:`BSWAPQ`,-`MOV[BWL]\t[^$]`,-`OR`
// s390x:`MOVD\s\(.*\),`
// arm64:`REV`,`MOVD\s\(R[0-9]+\),`,-`MOV[BHW]`,-`REVW`,-`REV16W`
// ppc64le:`MOVDBR`
@ -76,7 +76,7 @@ func load_be64(b []byte) {
}
func load_be64_idx(b []byte, idx int) {
// amd64:`BSWAPQ`,-`MOV[BWL]`,-`OR`
// amd64:`BSWAPQ`,-`MOV[BWL]\t[^$]`,-`OR`
// s390x:`MOVD\s\(.*\)\(.*\*1\),`
// arm64:`REV`,`MOVD\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[WHB]`,-`REVW`,-`REV16W`
// ppc64le:`MOVDBR`
@ -141,7 +141,7 @@ func load_le_byte4_uint32_inv(s []byte) uint32 {
func load_le_byte8_uint64(s []byte) uint64 {
// arm64:`MOVD\t\(R[0-9]+\)`,-`ORR`,-`MOV[BHW]`
// amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]`,-`OR`
// amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]\t[^$]`,-`OR`
return uint64(s[0]) | uint64(s[1])<<8 | uint64(s[2])<<16 | uint64(s[3])<<24 | uint64(s[4])<<32 | uint64(s[5])<<40 | uint64(s[6])<<48 | uint64(s[7])<<56
}
@ -180,7 +180,7 @@ func load_be_byte8_uint64(s []byte) uint64 {
func load_be_byte8_uint64_inv(s []byte) uint64 {
// arm64:`MOVD\t\(R[0-9]+\)`,`REV`,-`ORR`,-`REVW`,-`REV16W`,-`MOV[BHW]`
// amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]`,-`OR`
// amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]\t[^$]`,-`OR`
return uint64(s[7]) | uint64(s[6])<<8 | uint64(s[5])<<16 | uint64(s[4])<<24 | uint64(s[3])<<32 | uint64(s[2])<<40 | uint64(s[1])<<48 | uint64(s[0])<<56
}

View file

@ -48,7 +48,7 @@ func test16(x []byte) uint16 {
panic("no fault or bounds check failure happened")
}
s := fmt.Sprintf("%s", r)
if s != "runtime error: index out of range" {
if s != "runtime error: index out of range [1] with length 1" {
panic("bad panic: " + s)
}
}()
@ -66,7 +66,7 @@ func test16i(x []byte, i int) uint16 {
panic("no fault or bounds check failure happened")
}
s := fmt.Sprintf("%s", r)
if s != "runtime error: index out of range" {
if s != "runtime error: index out of range [1] with length 1" {
panic("bad panic: " + s)
}
}()
@ -80,7 +80,7 @@ func test32(x []byte) uint32 {
panic("no fault or bounds check failure happened")
}
s := fmt.Sprintf("%s", r)
if s != "runtime error: index out of range" {
if s != "runtime error: index out of range [1] with length 1" {
panic("bad panic: " + s)
}
}()
@ -94,7 +94,7 @@ func test32i(x []byte, i int) uint32 {
panic("no fault or bounds check failure happened")
}
s := fmt.Sprintf("%s", r)
if s != "runtime error: index out of range" {
if s != "runtime error: index out of range [1] with length 1" {
panic("bad panic: " + s)
}
}()
@ -108,7 +108,7 @@ func test64(x []byte) uint64 {
panic("no fault or bounds check failure happened")
}
s := fmt.Sprintf("%s", r)
if s != "runtime error: index out of range" {
if s != "runtime error: index out of range [1] with length 1" {
panic("bad panic: " + s)
}
}()
@ -123,7 +123,7 @@ func test64i(x []byte, i int) uint64 {
panic("no fault or bounds check failure happened")
}
s := fmt.Sprintf("%s", r)
if s != "runtime error: index out of range" {
if s != "runtime error: index out of range [1] with length 1" {
panic("bad panic: " + s)
}
}()

View file

@ -0,0 +1,112 @@
// run
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This test makes sure the text output for bounds check failures is as expected.
package main
import (
"fmt"
"os"
"runtime"
"text/tabwriter"
)
// Testing with length 3 slices, arrays, and strings.
// Large (>1<<32) values are included to test 32-bit platforms.
var indexes = []int64{-9876543210, -1, 0, 2, 3, 9876543210}
var slices = []int64{-9876543210, -1, 0, 3, 4, 9876543210}
var w *tabwriter.Writer
func main() {
w = tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight)
defer w.Flush()
doIndex()
doSlice()
doSlice3()
}
func doIndex() {
a := []int{1, 2, 3}
for _, i := range indexes {
printPanic(fmt.Sprintf("slice[%d]", i), func() {
_ = a[i]
})
}
b := [3]int{1, 2, 3}
for _, i := range indexes {
printPanic(fmt.Sprintf("array[%d]", i), func() {
_ = b[i]
})
}
c := "123"
for _, i := range indexes {
printPanic(fmt.Sprintf("string[%d]", i), func() {
_ = c[i]
})
}
}
func doSlice() {
a := []int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
printPanic(fmt.Sprintf("slice[%d:%d]", i, j), func() {
_ = a[i:j]
})
}
}
b := [3]int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
printPanic(fmt.Sprintf("array[%d:%d]", i, j), func() {
_ = b[i:j]
})
}
}
c := "123"
for _, i := range slices {
for _, j := range slices {
printPanic(fmt.Sprintf("string[%d:%d]", i, j), func() {
_ = c[i:j]
})
}
}
}
func doSlice3() {
a := []int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
for _, k := range slices {
printPanic(fmt.Sprintf("slice[%d:%d:%d]", i, j, k), func() {
_ = a[i:j:k]
})
}
}
}
b := [3]int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
for _, k := range slices {
printPanic(fmt.Sprintf("array[%d:%d:%d]", i, j, k), func() {
_ = b[i:j:k]
})
}
}
}
}
func printPanic(msg string, f func()) {
defer func() {
res := "no panic"
if e := recover(); e != nil {
res = e.(runtime.Error).Error()
}
fmt.Fprintf(w, "%s\t %s\n", msg, res)
}()
f()
}

View file

@ -0,0 +1,558 @@
slice[-9876543210] runtime error: index out of range [-9876543210]
slice[-1] runtime error: index out of range [-1]
slice[0] no panic
slice[2] no panic
slice[3] runtime error: index out of range [3] with length 3
slice[9876543210] runtime error: index out of range [9876543210] with length 3
array[-9876543210] runtime error: index out of range [-9876543210]
array[-1] runtime error: index out of range [-1]
array[0] no panic
array[2] no panic
array[3] runtime error: index out of range [3] with length 3
array[9876543210] runtime error: index out of range [9876543210] with length 3
string[-9876543210] runtime error: index out of range [-9876543210]
string[-1] runtime error: index out of range [-1]
string[0] no panic
string[2] no panic
string[3] runtime error: index out of range [3] with length 3
string[9876543210] runtime error: index out of range [9876543210] with length 3
slice[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
slice[-9876543210:-1] runtime error: slice bounds out of range [:-1]
slice[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
slice[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
slice[-9876543210:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
slice[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
slice[-1:-1] runtime error: slice bounds out of range [:-1]
slice[-1:0] runtime error: slice bounds out of range [-1:]
slice[-1:3] runtime error: slice bounds out of range [-1:]
slice[-1:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
slice[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
slice[0:-1] runtime error: slice bounds out of range [:-1]
slice[0:0] no panic
slice[0:3] no panic
slice[0:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[0:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
slice[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
slice[3:-1] runtime error: slice bounds out of range [:-1]
slice[3:0] runtime error: slice bounds out of range [3:0]
slice[3:3] no panic
slice[3:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[3:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
slice[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
slice[4:-1] runtime error: slice bounds out of range [:-1]
slice[4:0] runtime error: slice bounds out of range [4:0]
slice[4:3] runtime error: slice bounds out of range [4:3]
slice[4:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[4:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
slice[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
slice[9876543210:-1] runtime error: slice bounds out of range [:-1]
slice[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
slice[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
slice[9876543210:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
array[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
array[-9876543210:-1] runtime error: slice bounds out of range [:-1]
array[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
array[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
array[-9876543210:4] runtime error: slice bounds out of range [:4] with length 3
array[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
array[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
array[-1:-1] runtime error: slice bounds out of range [:-1]
array[-1:0] runtime error: slice bounds out of range [-1:]
array[-1:3] runtime error: slice bounds out of range [-1:]
array[-1:4] runtime error: slice bounds out of range [:4] with length 3
array[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
array[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
array[0:-1] runtime error: slice bounds out of range [:-1]
array[0:0] no panic
array[0:3] no panic
array[0:4] runtime error: slice bounds out of range [:4] with length 3
array[0:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
array[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
array[3:-1] runtime error: slice bounds out of range [:-1]
array[3:0] runtime error: slice bounds out of range [3:0]
array[3:3] no panic
array[3:4] runtime error: slice bounds out of range [:4] with length 3
array[3:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
array[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
array[4:-1] runtime error: slice bounds out of range [:-1]
array[4:0] runtime error: slice bounds out of range [4:0]
array[4:3] runtime error: slice bounds out of range [4:3]
array[4:4] runtime error: slice bounds out of range [:4] with length 3
array[4:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
array[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
array[9876543210:-1] runtime error: slice bounds out of range [:-1]
array[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
array[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
array[9876543210:4] runtime error: slice bounds out of range [:4] with length 3
array[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
string[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
string[-9876543210:-1] runtime error: slice bounds out of range [:-1]
string[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
string[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
string[-9876543210:4] runtime error: slice bounds out of range [:4] with length 3
string[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
string[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
string[-1:-1] runtime error: slice bounds out of range [:-1]
string[-1:0] runtime error: slice bounds out of range [-1:]
string[-1:3] runtime error: slice bounds out of range [-1:]
string[-1:4] runtime error: slice bounds out of range [:4] with length 3
string[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
string[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
string[0:-1] runtime error: slice bounds out of range [:-1]
string[0:0] no panic
string[0:3] no panic
string[0:4] runtime error: slice bounds out of range [:4] with length 3
string[0:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
string[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
string[3:-1] runtime error: slice bounds out of range [:-1]
string[3:0] runtime error: slice bounds out of range [3:0]
string[3:3] no panic
string[3:4] runtime error: slice bounds out of range [:4] with length 3
string[3:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
string[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
string[4:-1] runtime error: slice bounds out of range [:-1]
string[4:0] runtime error: slice bounds out of range [4:0]
string[4:3] runtime error: slice bounds out of range [4:3]
string[4:4] runtime error: slice bounds out of range [:4] with length 3
string[4:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
string[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
string[9876543210:-1] runtime error: slice bounds out of range [:-1]
string[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
string[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
string[9876543210:4] runtime error: slice bounds out of range [:4] with length 3
string[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
slice[-9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[-9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
slice[-9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
slice[-9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
slice[-9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
slice[-9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
slice[-9876543210:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-9876543210:0:-1] runtime error: slice bounds out of range [::-1]
slice[-9876543210:0:0] runtime error: slice bounds out of range [-9876543210::]
slice[-9876543210:0:3] runtime error: slice bounds out of range [-9876543210::]
slice[-9876543210:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-9876543210:3:-1] runtime error: slice bounds out of range [::-1]
slice[-9876543210:3:0] runtime error: slice bounds out of range [:3:0]
slice[-9876543210:3:3] runtime error: slice bounds out of range [-9876543210::]
slice[-9876543210:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-9876543210:4:-1] runtime error: slice bounds out of range [::-1]
slice[-9876543210:4:0] runtime error: slice bounds out of range [:4:0]
slice[-9876543210:4:3] runtime error: slice bounds out of range [:4:3]
slice[-9876543210:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[-9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
slice[-9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
slice[-9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-1:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-1:-9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[-1:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
slice[-1:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
slice[-1:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-1:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-1:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-1:-1:-1] runtime error: slice bounds out of range [::-1]
slice[-1:-1:0] runtime error: slice bounds out of range [:-1:]
slice[-1:-1:3] runtime error: slice bounds out of range [:-1:]
slice[-1:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-1:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-1:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-1:0:-1] runtime error: slice bounds out of range [::-1]
slice[-1:0:0] runtime error: slice bounds out of range [-1::]
slice[-1:0:3] runtime error: slice bounds out of range [-1::]
slice[-1:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-1:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-1:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-1:3:-1] runtime error: slice bounds out of range [::-1]
slice[-1:3:0] runtime error: slice bounds out of range [:3:0]
slice[-1:3:3] runtime error: slice bounds out of range [-1::]
slice[-1:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-1:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-1:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-1:4:-1] runtime error: slice bounds out of range [::-1]
slice[-1:4:0] runtime error: slice bounds out of range [:4:0]
slice[-1:4:3] runtime error: slice bounds out of range [:4:3]
slice[-1:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-1:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[-1:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[-1:9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[-1:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
slice[-1:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
slice[-1:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[-1:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[0:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[0:-9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[0:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
slice[0:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
slice[0:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[0:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[0:-1:-1] runtime error: slice bounds out of range [::-1]
slice[0:-1:0] runtime error: slice bounds out of range [:-1:]
slice[0:-1:3] runtime error: slice bounds out of range [:-1:]
slice[0:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[0:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[0:0:-1] runtime error: slice bounds out of range [::-1]
slice[0:0:0] no panic
slice[0:0:3] no panic
slice[0:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[0:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[0:3:-1] runtime error: slice bounds out of range [::-1]
slice[0:3:0] runtime error: slice bounds out of range [:3:0]
slice[0:3:3] no panic
slice[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[0:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[0:4:-1] runtime error: slice bounds out of range [::-1]
slice[0:4:0] runtime error: slice bounds out of range [:4:0]
slice[0:4:3] runtime error: slice bounds out of range [:4:3]
slice[0:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[0:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[0:9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[0:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
slice[0:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
slice[0:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[3:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[3:-9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[3:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
slice[3:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
slice[3:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[3:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[3:-1:-1] runtime error: slice bounds out of range [::-1]
slice[3:-1:0] runtime error: slice bounds out of range [:-1:]
slice[3:-1:3] runtime error: slice bounds out of range [:-1:]
slice[3:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[3:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[3:0:-1] runtime error: slice bounds out of range [::-1]
slice[3:0:0] runtime error: slice bounds out of range [3:0:]
slice[3:0:3] runtime error: slice bounds out of range [3:0:]
slice[3:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[3:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[3:3:-1] runtime error: slice bounds out of range [::-1]
slice[3:3:0] runtime error: slice bounds out of range [:3:0]
slice[3:3:3] no panic
slice[3:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[3:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[3:4:-1] runtime error: slice bounds out of range [::-1]
slice[3:4:0] runtime error: slice bounds out of range [:4:0]
slice[3:4:3] runtime error: slice bounds out of range [:4:3]
slice[3:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[3:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[3:9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[3:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
slice[3:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
slice[3:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[4:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[4:-9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[4:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
slice[4:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
slice[4:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[4:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[4:-1:-1] runtime error: slice bounds out of range [::-1]
slice[4:-1:0] runtime error: slice bounds out of range [:-1:]
slice[4:-1:3] runtime error: slice bounds out of range [:-1:]
slice[4:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[4:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[4:0:-1] runtime error: slice bounds out of range [::-1]
slice[4:0:0] runtime error: slice bounds out of range [4:0:]
slice[4:0:3] runtime error: slice bounds out of range [4:0:]
slice[4:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[4:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[4:3:-1] runtime error: slice bounds out of range [::-1]
slice[4:3:0] runtime error: slice bounds out of range [:3:0]
slice[4:3:3] runtime error: slice bounds out of range [4:3:]
slice[4:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[4:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[4:4:-1] runtime error: slice bounds out of range [::-1]
slice[4:4:0] runtime error: slice bounds out of range [:4:0]
slice[4:4:3] runtime error: slice bounds out of range [:4:3]
slice[4:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[4:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[4:9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[4:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
slice[4:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
slice[4:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
slice[9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
slice[9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
slice[9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
slice[9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
slice[9876543210:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[9876543210:0:-1] runtime error: slice bounds out of range [::-1]
slice[9876543210:0:0] runtime error: slice bounds out of range [9876543210:0:]
slice[9876543210:0:3] runtime error: slice bounds out of range [9876543210:0:]
slice[9876543210:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[9876543210:3:-1] runtime error: slice bounds out of range [::-1]
slice[9876543210:3:0] runtime error: slice bounds out of range [:3:0]
slice[9876543210:3:3] runtime error: slice bounds out of range [9876543210:3:]
slice[9876543210:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[9876543210:4:-1] runtime error: slice bounds out of range [::-1]
slice[9876543210:4:0] runtime error: slice bounds out of range [:4:0]
slice[9876543210:4:3] runtime error: slice bounds out of range [:4:3]
slice[9876543210:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
slice[9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
slice[9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
slice[9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
slice[9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
slice[9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
array[-9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
array[-9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
array[-9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
array[-9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[-9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
array[-9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
array[-9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
array[-9876543210:-1:4] runtime error: slice bounds out of range [::4] with length 3
array[-9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-9876543210:0:-1] runtime error: slice bounds out of range [::-1]
array[-9876543210:0:0] runtime error: slice bounds out of range [-9876543210::]
array[-9876543210:0:3] runtime error: slice bounds out of range [-9876543210::]
array[-9876543210:0:4] runtime error: slice bounds out of range [::4] with length 3
array[-9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-9876543210:3:-1] runtime error: slice bounds out of range [::-1]
array[-9876543210:3:0] runtime error: slice bounds out of range [:3:0]
array[-9876543210:3:3] runtime error: slice bounds out of range [-9876543210::]
array[-9876543210:3:4] runtime error: slice bounds out of range [::4] with length 3
array[-9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-9876543210:4:-1] runtime error: slice bounds out of range [::-1]
array[-9876543210:4:0] runtime error: slice bounds out of range [:4:0]
array[-9876543210:4:3] runtime error: slice bounds out of range [:4:3]
array[-9876543210:4:4] runtime error: slice bounds out of range [::4] with length 3
array[-9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
array[-9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
array[-9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
array[-9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[-9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-1:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-1:-9876543210:-1] runtime error: slice bounds out of range [::-1]
array[-1:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
array[-1:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
array[-1:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[-1:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-1:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-1:-1:-1] runtime error: slice bounds out of range [::-1]
array[-1:-1:0] runtime error: slice bounds out of range [:-1:]
array[-1:-1:3] runtime error: slice bounds out of range [:-1:]
array[-1:-1:4] runtime error: slice bounds out of range [::4] with length 3
array[-1:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-1:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-1:0:-1] runtime error: slice bounds out of range [::-1]
array[-1:0:0] runtime error: slice bounds out of range [-1::]
array[-1:0:3] runtime error: slice bounds out of range [-1::]
array[-1:0:4] runtime error: slice bounds out of range [::4] with length 3
array[-1:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-1:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-1:3:-1] runtime error: slice bounds out of range [::-1]
array[-1:3:0] runtime error: slice bounds out of range [:3:0]
array[-1:3:3] runtime error: slice bounds out of range [-1::]
array[-1:3:4] runtime error: slice bounds out of range [::4] with length 3
array[-1:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-1:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-1:4:-1] runtime error: slice bounds out of range [::-1]
array[-1:4:0] runtime error: slice bounds out of range [:4:0]
array[-1:4:3] runtime error: slice bounds out of range [:4:3]
array[-1:4:4] runtime error: slice bounds out of range [::4] with length 3
array[-1:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[-1:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[-1:9876543210:-1] runtime error: slice bounds out of range [::-1]
array[-1:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
array[-1:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
array[-1:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[-1:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[0:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[0:-9876543210:-1] runtime error: slice bounds out of range [::-1]
array[0:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
array[0:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
array[0:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[0:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[0:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[0:-1:-1] runtime error: slice bounds out of range [::-1]
array[0:-1:0] runtime error: slice bounds out of range [:-1:]
array[0:-1:3] runtime error: slice bounds out of range [:-1:]
array[0:-1:4] runtime error: slice bounds out of range [::4] with length 3
array[0:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[0:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[0:0:-1] runtime error: slice bounds out of range [::-1]
array[0:0:0] no panic
array[0:0:3] no panic
array[0:0:4] runtime error: slice bounds out of range [::4] with length 3
array[0:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[0:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[0:3:-1] runtime error: slice bounds out of range [::-1]
array[0:3:0] runtime error: slice bounds out of range [:3:0]
array[0:3:3] no panic
array[0:3:4] runtime error: slice bounds out of range [::4] with length 3
array[0:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[0:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[0:4:-1] runtime error: slice bounds out of range [::-1]
array[0:4:0] runtime error: slice bounds out of range [:4:0]
array[0:4:3] runtime error: slice bounds out of range [:4:3]
array[0:4:4] runtime error: slice bounds out of range [::4] with length 3
array[0:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[0:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[0:9876543210:-1] runtime error: slice bounds out of range [::-1]
array[0:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
array[0:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
array[0:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[0:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[3:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[3:-9876543210:-1] runtime error: slice bounds out of range [::-1]
array[3:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
array[3:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
array[3:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[3:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[3:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[3:-1:-1] runtime error: slice bounds out of range [::-1]
array[3:-1:0] runtime error: slice bounds out of range [:-1:]
array[3:-1:3] runtime error: slice bounds out of range [:-1:]
array[3:-1:4] runtime error: slice bounds out of range [::4] with length 3
array[3:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[3:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[3:0:-1] runtime error: slice bounds out of range [::-1]
array[3:0:0] runtime error: slice bounds out of range [3:0:]
array[3:0:3] runtime error: slice bounds out of range [3:0:]
array[3:0:4] runtime error: slice bounds out of range [::4] with length 3
array[3:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[3:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[3:3:-1] runtime error: slice bounds out of range [::-1]
array[3:3:0] runtime error: slice bounds out of range [:3:0]
array[3:3:3] no panic
array[3:3:4] runtime error: slice bounds out of range [::4] with length 3
array[3:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[3:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[3:4:-1] runtime error: slice bounds out of range [::-1]
array[3:4:0] runtime error: slice bounds out of range [:4:0]
array[3:4:3] runtime error: slice bounds out of range [:4:3]
array[3:4:4] runtime error: slice bounds out of range [::4] with length 3
array[3:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[3:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[3:9876543210:-1] runtime error: slice bounds out of range [::-1]
array[3:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
array[3:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
array[3:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[3:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[4:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[4:-9876543210:-1] runtime error: slice bounds out of range [::-1]
array[4:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
array[4:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
array[4:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[4:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[4:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[4:-1:-1] runtime error: slice bounds out of range [::-1]
array[4:-1:0] runtime error: slice bounds out of range [:-1:]
array[4:-1:3] runtime error: slice bounds out of range [:-1:]
array[4:-1:4] runtime error: slice bounds out of range [::4] with length 3
array[4:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[4:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[4:0:-1] runtime error: slice bounds out of range [::-1]
array[4:0:0] runtime error: slice bounds out of range [4:0:]
array[4:0:3] runtime error: slice bounds out of range [4:0:]
array[4:0:4] runtime error: slice bounds out of range [::4] with length 3
array[4:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[4:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[4:3:-1] runtime error: slice bounds out of range [::-1]
array[4:3:0] runtime error: slice bounds out of range [:3:0]
array[4:3:3] runtime error: slice bounds out of range [4:3:]
array[4:3:4] runtime error: slice bounds out of range [::4] with length 3
array[4:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[4:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[4:4:-1] runtime error: slice bounds out of range [::-1]
array[4:4:0] runtime error: slice bounds out of range [:4:0]
array[4:4:3] runtime error: slice bounds out of range [:4:3]
array[4:4:4] runtime error: slice bounds out of range [::4] with length 3
array[4:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[4:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[4:9876543210:-1] runtime error: slice bounds out of range [::-1]
array[4:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
array[4:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
array[4:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[4:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
array[9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
array[9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
array[9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
array[9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
array[9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
array[9876543210:-1:4] runtime error: slice bounds out of range [::4] with length 3
array[9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[9876543210:0:-1] runtime error: slice bounds out of range [::-1]
array[9876543210:0:0] runtime error: slice bounds out of range [9876543210:0:]
array[9876543210:0:3] runtime error: slice bounds out of range [9876543210:0:]
array[9876543210:0:4] runtime error: slice bounds out of range [::4] with length 3
array[9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[9876543210:3:-1] runtime error: slice bounds out of range [::-1]
array[9876543210:3:0] runtime error: slice bounds out of range [:3:0]
array[9876543210:3:3] runtime error: slice bounds out of range [9876543210:3:]
array[9876543210:3:4] runtime error: slice bounds out of range [::4] with length 3
array[9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[9876543210:4:-1] runtime error: slice bounds out of range [::-1]
array[9876543210:4:0] runtime error: slice bounds out of range [:4:0]
array[9876543210:4:3] runtime error: slice bounds out of range [:4:3]
array[9876543210:4:4] runtime error: slice bounds out of range [::4] with length 3
array[9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
array[9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
array[9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
array[9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
array[9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
array[9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
array[9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3

View file

@ -0,0 +1,112 @@
// run
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This test makes sure the text output for bounds check failures is as expected.
package main
import (
"fmt"
"os"
"runtime"
"text/tabwriter"
)
// Testing with length 3 slices, arrays, and strings.
// A large (>1<<32) value is included to test 32-bit platforms.
var indexes = []uint64{0, 2, 3, 1<<32 - 1, 1<<64 - 1}
var slices = []uint64{0, 3, 4, 1<<32 - 1, 1<<64 - 1}
var w *tabwriter.Writer
func main() {
w = tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight)
defer w.Flush()
doIndex()
doSlice()
doSlice3()
}
func doIndex() {
a := []int{1, 2, 3}
for _, i := range indexes {
printPanic(fmt.Sprintf("slice[%d]", i), func() {
_ = a[i]
})
}
b := [3]int{1, 2, 3}
for _, i := range indexes {
printPanic(fmt.Sprintf("array[%d]", i), func() {
_ = b[i]
})
}
c := "123"
for _, i := range indexes {
printPanic(fmt.Sprintf("string[%d]", i), func() {
_ = c[i]
})
}
}
func doSlice() {
a := []int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
printPanic(fmt.Sprintf("slice[%d:%d]", i, j), func() {
_ = a[i:j]
})
}
}
b := [3]int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
printPanic(fmt.Sprintf("array[%d:%d]", i, j), func() {
_ = b[i:j]
})
}
}
c := "123"
for _, i := range slices {
for _, j := range slices {
printPanic(fmt.Sprintf("string[%d:%d]", i, j), func() {
_ = c[i:j]
})
}
}
}
func doSlice3() {
a := []int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
for _, k := range slices {
printPanic(fmt.Sprintf("slice[%d:%d:%d]", i, j, k), func() {
_ = a[i:j:k]
})
}
}
}
b := [3]int{1, 2, 3}
for _, i := range slices {
for _, j := range slices {
for _, k := range slices {
printPanic(fmt.Sprintf("array[%d:%d:%d]", i, j, k), func() {
_ = b[i:j:k]
})
}
}
}
}
func printPanic(msg string, f func()) {
defer func() {
res := "no panic"
if e := recover(); e != nil {
res = e.(runtime.Error).Error()
}
fmt.Fprintf(w, "%s\t %s\n", msg, res)
}()
f()
}

View file

@ -0,0 +1,340 @@
slice[0] no panic
slice[2] no panic
slice[3] runtime error: index out of range [3] with length 3
slice[4294967295] runtime error: index out of range [4294967295] with length 3
slice[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
array[0] no panic
array[2] no panic
array[3] runtime error: index out of range [3] with length 3
array[4294967295] runtime error: index out of range [4294967295] with length 3
array[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
string[0] no panic
string[2] no panic
string[3] runtime error: index out of range [3] with length 3
string[4294967295] runtime error: index out of range [4294967295] with length 3
string[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
slice[0:0] no panic
slice[0:3] no panic
slice[0:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[0:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
slice[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
slice[3:0] runtime error: slice bounds out of range [3:0]
slice[3:3] no panic
slice[3:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[3:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
slice[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
slice[4:0] runtime error: slice bounds out of range [4:0]
slice[4:3] runtime error: slice bounds out of range [4:3]
slice[4:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[4:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
slice[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
slice[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
slice[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
slice[4294967295:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
slice[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
slice[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
slice[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
slice[18446744073709551615:4] runtime error: slice bounds out of range [:4] with capacity 3
slice[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
slice[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
array[0:0] no panic
array[0:3] no panic
array[0:4] runtime error: slice bounds out of range [:4] with length 3
array[0:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
array[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
array[3:0] runtime error: slice bounds out of range [3:0]
array[3:3] no panic
array[3:4] runtime error: slice bounds out of range [:4] with length 3
array[3:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
array[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
array[4:0] runtime error: slice bounds out of range [4:0]
array[4:3] runtime error: slice bounds out of range [4:3]
array[4:4] runtime error: slice bounds out of range [:4] with length 3
array[4:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
array[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
array[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
array[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
array[4294967295:4] runtime error: slice bounds out of range [:4] with length 3
array[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
array[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
array[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
array[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
array[18446744073709551615:4] runtime error: slice bounds out of range [:4] with length 3
array[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
array[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
string[0:0] no panic
string[0:3] no panic
string[0:4] runtime error: slice bounds out of range [:4] with length 3
string[0:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
string[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
string[3:0] runtime error: slice bounds out of range [3:0]
string[3:3] no panic
string[3:4] runtime error: slice bounds out of range [:4] with length 3
string[3:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
string[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
string[4:0] runtime error: slice bounds out of range [4:0]
string[4:3] runtime error: slice bounds out of range [4:3]
string[4:4] runtime error: slice bounds out of range [:4] with length 3
string[4:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
string[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
string[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
string[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
string[4294967295:4] runtime error: slice bounds out of range [:4] with length 3
string[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
string[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
string[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
string[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
string[18446744073709551615:4] runtime error: slice bounds out of range [:4] with length 3
string[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
string[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
slice[0:0:0] no panic
slice[0:0:3] no panic
slice[0:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[0:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[0:3:0] runtime error: slice bounds out of range [:3:0]
slice[0:3:3] no panic
slice[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[0:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[0:4:0] runtime error: slice bounds out of range [:4:0]
slice[0:4:3] runtime error: slice bounds out of range [:4:3]
slice[0:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[0:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[0:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
slice[0:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
slice[0:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[0:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[0:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
slice[0:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
slice[0:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[0:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[0:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[3:0:0] runtime error: slice bounds out of range [3:0:]
slice[3:0:3] runtime error: slice bounds out of range [3:0:]
slice[3:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[3:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[3:3:0] runtime error: slice bounds out of range [:3:0]
slice[3:3:3] no panic
slice[3:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[3:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[3:4:0] runtime error: slice bounds out of range [:4:0]
slice[3:4:3] runtime error: slice bounds out of range [:4:3]
slice[3:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[3:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[3:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
slice[3:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
slice[3:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[3:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[3:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
slice[3:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
slice[3:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[3:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[3:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4:0:0] runtime error: slice bounds out of range [4:0:]
slice[4:0:3] runtime error: slice bounds out of range [4:0:]
slice[4:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4:3:0] runtime error: slice bounds out of range [:3:0]
slice[4:3:3] runtime error: slice bounds out of range [4:3:]
slice[4:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4:4:0] runtime error: slice bounds out of range [:4:0]
slice[4:4:3] runtime error: slice bounds out of range [:4:3]
slice[4:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
slice[4:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
slice[4:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
slice[4:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
slice[4:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4294967295:0:0] runtime error: slice bounds out of range [4294967295:0:]
slice[4294967295:0:3] runtime error: slice bounds out of range [4294967295:0:]
slice[4294967295:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4294967295:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4294967295:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4294967295:3:0] runtime error: slice bounds out of range [:3:0]
slice[4294967295:3:3] runtime error: slice bounds out of range [4294967295:3:]
slice[4294967295:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4294967295:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4294967295:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4294967295:4:0] runtime error: slice bounds out of range [:4:0]
slice[4294967295:4:3] runtime error: slice bounds out of range [:4:3]
slice[4294967295:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4294967295:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4294967295:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4294967295:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
slice[4294967295:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
slice[4294967295:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4294967295:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4294967295:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[4294967295:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
slice[4294967295:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
slice[4294967295:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[4294967295:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[4294967295:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[18446744073709551615:0:0] runtime error: slice bounds out of range [18446744073709551615:0:]
slice[18446744073709551615:0:3] runtime error: slice bounds out of range [18446744073709551615:0:]
slice[18446744073709551615:0:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[18446744073709551615:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[18446744073709551615:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[18446744073709551615:3:0] runtime error: slice bounds out of range [:3:0]
slice[18446744073709551615:3:3] runtime error: slice bounds out of range [18446744073709551615:3:]
slice[18446744073709551615:3:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[18446744073709551615:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[18446744073709551615:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[18446744073709551615:4:0] runtime error: slice bounds out of range [:4:0]
slice[18446744073709551615:4:3] runtime error: slice bounds out of range [:4:3]
slice[18446744073709551615:4:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[18446744073709551615:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[18446744073709551615:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[18446744073709551615:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
slice[18446744073709551615:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
slice[18446744073709551615:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[18446744073709551615:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[18446744073709551615:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
slice[18446744073709551615:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
slice[18446744073709551615:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
slice[18446744073709551615:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
slice[18446744073709551615:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
slice[18446744073709551615:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
array[0:0:0] no panic
array[0:0:3] no panic
array[0:0:4] runtime error: slice bounds out of range [::4] with length 3
array[0:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[0:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[0:3:0] runtime error: slice bounds out of range [:3:0]
array[0:3:3] no panic
array[0:3:4] runtime error: slice bounds out of range [::4] with length 3
array[0:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[0:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[0:4:0] runtime error: slice bounds out of range [:4:0]
array[0:4:3] runtime error: slice bounds out of range [:4:3]
array[0:4:4] runtime error: slice bounds out of range [::4] with length 3
array[0:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[0:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[0:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
array[0:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
array[0:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
array[0:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[0:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[0:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
array[0:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
array[0:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
array[0:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[0:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[3:0:0] runtime error: slice bounds out of range [3:0:]
array[3:0:3] runtime error: slice bounds out of range [3:0:]
array[3:0:4] runtime error: slice bounds out of range [::4] with length 3
array[3:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[3:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[3:3:0] runtime error: slice bounds out of range [:3:0]
array[3:3:3] no panic
array[3:3:4] runtime error: slice bounds out of range [::4] with length 3
array[3:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[3:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[3:4:0] runtime error: slice bounds out of range [:4:0]
array[3:4:3] runtime error: slice bounds out of range [:4:3]
array[3:4:4] runtime error: slice bounds out of range [::4] with length 3
array[3:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[3:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[3:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
array[3:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
array[3:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
array[3:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[3:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[3:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
array[3:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
array[3:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
array[3:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[3:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4:0:0] runtime error: slice bounds out of range [4:0:]
array[4:0:3] runtime error: slice bounds out of range [4:0:]
array[4:0:4] runtime error: slice bounds out of range [::4] with length 3
array[4:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4:3:0] runtime error: slice bounds out of range [:3:0]
array[4:3:3] runtime error: slice bounds out of range [4:3:]
array[4:3:4] runtime error: slice bounds out of range [::4] with length 3
array[4:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4:4:0] runtime error: slice bounds out of range [:4:0]
array[4:4:3] runtime error: slice bounds out of range [:4:3]
array[4:4:4] runtime error: slice bounds out of range [::4] with length 3
array[4:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
array[4:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
array[4:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
array[4:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
array[4:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
array[4:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
array[4:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4294967295:0:0] runtime error: slice bounds out of range [4294967295:0:]
array[4294967295:0:3] runtime error: slice bounds out of range [4294967295:0:]
array[4294967295:0:4] runtime error: slice bounds out of range [::4] with length 3
array[4294967295:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4294967295:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4294967295:3:0] runtime error: slice bounds out of range [:3:0]
array[4294967295:3:3] runtime error: slice bounds out of range [4294967295:3:]
array[4294967295:3:4] runtime error: slice bounds out of range [::4] with length 3
array[4294967295:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4294967295:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4294967295:4:0] runtime error: slice bounds out of range [:4:0]
array[4294967295:4:3] runtime error: slice bounds out of range [:4:3]
array[4294967295:4:4] runtime error: slice bounds out of range [::4] with length 3
array[4294967295:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4294967295:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4294967295:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
array[4294967295:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
array[4294967295:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
array[4294967295:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4294967295:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[4294967295:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
array[4294967295:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
array[4294967295:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
array[4294967295:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[4294967295:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[18446744073709551615:0:0] runtime error: slice bounds out of range [18446744073709551615:0:]
array[18446744073709551615:0:3] runtime error: slice bounds out of range [18446744073709551615:0:]
array[18446744073709551615:0:4] runtime error: slice bounds out of range [::4] with length 3
array[18446744073709551615:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[18446744073709551615:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[18446744073709551615:3:0] runtime error: slice bounds out of range [:3:0]
array[18446744073709551615:3:3] runtime error: slice bounds out of range [18446744073709551615:3:]
array[18446744073709551615:3:4] runtime error: slice bounds out of range [::4] with length 3
array[18446744073709551615:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[18446744073709551615:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[18446744073709551615:4:0] runtime error: slice bounds out of range [:4:0]
array[18446744073709551615:4:3] runtime error: slice bounds out of range [:4:3]
array[18446744073709551615:4:4] runtime error: slice bounds out of range [::4] with length 3
array[18446744073709551615:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[18446744073709551615:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[18446744073709551615:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
array[18446744073709551615:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
array[18446744073709551615:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
array[18446744073709551615:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[18446744073709551615:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
array[18446744073709551615:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
array[18446744073709551615:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
array[18446744073709551615:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
array[18446744073709551615:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
array[18446744073709551615:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3