Commit b679665a authored by Martin Möhrmann's avatar Martin Möhrmann Committed by Martin Möhrmann

cmd/compile: move stringtoslicebytetmp to the backend

- removes the runtime function stringtoslicebytetmp
- removes the generation of calls to stringtoslicebytetmp from the frontend
- adds handling of OSTRARRAYBYTETMP in the backend

This reduces binary sizes and avoids function call overhead.

Change-Id: Ib9988d48549cee663b685b4897a483f94727b940
Reviewed-on: https://go-review.googlesource.com/32158Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
Reviewed-by: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Martin Möhrmann <martisch@uos.de>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent f595848e
...@@ -42,97 +42,96 @@ var runtimeDecls = [...]struct { ...@@ -42,97 +42,96 @@ var runtimeDecls = [...]struct {
{"slicebytetostringtmp", funcTag, 41}, {"slicebytetostringtmp", funcTag, 41},
{"slicerunetostring", funcTag, 44}, {"slicerunetostring", funcTag, 44},
{"stringtoslicebyte", funcTag, 45}, {"stringtoslicebyte", funcTag, 45},
{"stringtoslicebytetmp", funcTag, 46}, {"stringtoslicerune", funcTag, 48},
{"stringtoslicerune", funcTag, 49}, {"decoderune", funcTag, 49},
{"decoderune", funcTag, 50}, {"slicecopy", funcTag, 51},
{"slicecopy", funcTag, 52}, {"slicestringcopy", funcTag, 52},
{"slicestringcopy", funcTag, 53}, {"convI2I", funcTag, 53},
{"convI2I", funcTag, 54}, {"convT2E", funcTag, 54},
{"convT2E", funcTag, 55}, {"convT2I", funcTag, 54},
{"convT2I", funcTag, 55}, {"assertE2E", funcTag, 55},
{"assertE2E", funcTag, 56}, {"assertE2E2", funcTag, 56},
{"assertE2E2", funcTag, 57}, {"assertE2I", funcTag, 55},
{"assertE2I", funcTag, 56}, {"assertE2I2", funcTag, 56},
{"assertE2I2", funcTag, 57}, {"assertE2T", funcTag, 55},
{"assertE2T", funcTag, 56}, {"assertE2T2", funcTag, 56},
{"assertE2T2", funcTag, 57}, {"assertI2E", funcTag, 55},
{"assertI2E", funcTag, 56}, {"assertI2E2", funcTag, 56},
{"assertI2E2", funcTag, 57}, {"assertI2I", funcTag, 55},
{"assertI2I", funcTag, 56}, {"assertI2I2", funcTag, 56},
{"assertI2I2", funcTag, 57}, {"assertI2T", funcTag, 55},
{"assertI2T", funcTag, 56}, {"assertI2T2", funcTag, 56},
{"assertI2T2", funcTag, 57}, {"panicdottype", funcTag, 57},
{"panicdottype", funcTag, 58}, {"ifaceeq", funcTag, 58},
{"ifaceeq", funcTag, 59}, {"efaceeq", funcTag, 58},
{"efaceeq", funcTag, 59}, {"makemap", funcTag, 60},
{"makemap", funcTag, 61}, {"mapaccess1", funcTag, 61},
{"mapaccess1", funcTag, 62}, {"mapaccess1_fast32", funcTag, 62},
{"mapaccess1_fast32", funcTag, 63}, {"mapaccess1_fast64", funcTag, 62},
{"mapaccess1_fast64", funcTag, 63}, {"mapaccess1_faststr", funcTag, 62},
{"mapaccess1_faststr", funcTag, 63}, {"mapaccess1_fat", funcTag, 63},
{"mapaccess1_fat", funcTag, 64}, {"mapaccess2", funcTag, 64},
{"mapaccess2", funcTag, 65}, {"mapaccess2_fast32", funcTag, 65},
{"mapaccess2_fast32", funcTag, 66}, {"mapaccess2_fast64", funcTag, 65},
{"mapaccess2_fast64", funcTag, 66}, {"mapaccess2_faststr", funcTag, 65},
{"mapaccess2_faststr", funcTag, 66}, {"mapaccess2_fat", funcTag, 66},
{"mapaccess2_fat", funcTag, 67}, {"mapassign", funcTag, 61},
{"mapassign", funcTag, 62}, {"mapiterinit", funcTag, 67},
{"mapiterinit", funcTag, 68}, {"mapdelete", funcTag, 67},
{"mapdelete", funcTag, 68}, {"mapiternext", funcTag, 68},
{"mapiternext", funcTag, 69}, {"makechan", funcTag, 70},
{"makechan", funcTag, 71}, {"chanrecv1", funcTag, 72},
{"chanrecv1", funcTag, 73}, {"chanrecv2", funcTag, 73},
{"chanrecv2", funcTag, 74}, {"chansend1", funcTag, 75},
{"chansend1", funcTag, 76},
{"closechan", funcTag, 24}, {"closechan", funcTag, 24},
{"writeBarrier", varTag, 77}, {"writeBarrier", varTag, 76},
{"writebarrierptr", funcTag, 78}, {"writebarrierptr", funcTag, 77},
{"typedmemmove", funcTag, 79}, {"typedmemmove", funcTag, 78},
{"typedslicecopy", funcTag, 80}, {"typedslicecopy", funcTag, 79},
{"selectnbsend", funcTag, 81}, {"selectnbsend", funcTag, 80},
{"selectnbrecv", funcTag, 82}, {"selectnbrecv", funcTag, 81},
{"selectnbrecv2", funcTag, 84}, {"selectnbrecv2", funcTag, 83},
{"newselect", funcTag, 85}, {"newselect", funcTag, 84},
{"selectsend", funcTag, 81}, {"selectsend", funcTag, 80},
{"selectrecv", funcTag, 74}, {"selectrecv", funcTag, 73},
{"selectrecv2", funcTag, 86}, {"selectrecv2", funcTag, 85},
{"selectdefault", funcTag, 87}, {"selectdefault", funcTag, 86},
{"selectgo", funcTag, 88}, {"selectgo", funcTag, 87},
{"block", funcTag, 5}, {"block", funcTag, 5},
{"makeslice", funcTag, 90}, {"makeslice", funcTag, 89},
{"makeslice64", funcTag, 91}, {"makeslice64", funcTag, 90},
{"growslice", funcTag, 92}, {"growslice", funcTag, 91},
{"memmove", funcTag, 93}, {"memmove", funcTag, 92},
{"memclr", funcTag, 94}, {"memclr", funcTag, 93},
{"memequal", funcTag, 95}, {"memequal", funcTag, 94},
{"memequal8", funcTag, 96}, {"memequal8", funcTag, 95},
{"memequal16", funcTag, 96}, {"memequal16", funcTag, 95},
{"memequal32", funcTag, 96}, {"memequal32", funcTag, 95},
{"memequal64", funcTag, 96}, {"memequal64", funcTag, 95},
{"memequal128", funcTag, 96}, {"memequal128", funcTag, 95},
{"int64div", funcTag, 97}, {"int64div", funcTag, 96},
{"uint64div", funcTag, 98}, {"uint64div", funcTag, 97},
{"int64mod", funcTag, 97}, {"int64mod", funcTag, 96},
{"uint64mod", funcTag, 98}, {"uint64mod", funcTag, 97},
{"float64toint64", funcTag, 99}, {"float64toint64", funcTag, 98},
{"float64touint64", funcTag, 100}, {"float64touint64", funcTag, 99},
{"float64touint32", funcTag, 102}, {"float64touint32", funcTag, 101},
{"int64tofloat64", funcTag, 103}, {"int64tofloat64", funcTag, 102},
{"uint64tofloat64", funcTag, 104}, {"uint64tofloat64", funcTag, 103},
{"uint32tofloat64", funcTag, 105}, {"uint32tofloat64", funcTag, 104},
{"complex128div", funcTag, 106}, {"complex128div", funcTag, 105},
{"racefuncenter", funcTag, 107}, {"racefuncenter", funcTag, 106},
{"racefuncexit", funcTag, 5}, {"racefuncexit", funcTag, 5},
{"raceread", funcTag, 107}, {"raceread", funcTag, 106},
{"racewrite", funcTag, 107}, {"racewrite", funcTag, 106},
{"racereadrange", funcTag, 108}, {"racereadrange", funcTag, 107},
{"racewriterange", funcTag, 108}, {"racewriterange", funcTag, 107},
{"msanread", funcTag, 108}, {"msanread", funcTag, 107},
{"msanwrite", funcTag, 108}, {"msanwrite", funcTag, 107},
} }
func runtimeTypes() []*Type { func runtimeTypes() []*Type {
var typs [109]*Type var typs [108]*Type
typs[0] = bytetype typs[0] = bytetype
typs[1] = typPtr(typs[0]) typs[1] = typPtr(typs[0])
typs[2] = Types[TANY] typs[2] = Types[TANY]
...@@ -179,68 +178,67 @@ func runtimeTypes() []*Type { ...@@ -179,68 +178,67 @@ func runtimeTypes() []*Type {
typs[43] = typSlice(typs[42]) typs[43] = typSlice(typs[42])
typs[44] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[43])}, []*Node{anonfield(typs[6])}) typs[44] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[43])}, []*Node{anonfield(typs[6])})
typs[45] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[6])}, []*Node{anonfield(typs[39])}) typs[45] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[6])}, []*Node{anonfield(typs[39])})
typs[46] = functype(nil, []*Node{anonfield(typs[6])}, []*Node{anonfield(typs[39])}) typs[46] = typArray(typs[42], 32)
typs[47] = typArray(typs[42], 32) typs[47] = typPtr(typs[46])
typs[48] = typPtr(typs[47]) typs[48] = functype(nil, []*Node{anonfield(typs[47]), anonfield(typs[6])}, []*Node{anonfield(typs[43])})
typs[49] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[6])}, []*Node{anonfield(typs[43])}) typs[49] = functype(nil, []*Node{anonfield(typs[6]), anonfield(typs[33])}, []*Node{anonfield(typs[42]), anonfield(typs[33])})
typs[50] = functype(nil, []*Node{anonfield(typs[6]), anonfield(typs[33])}, []*Node{anonfield(typs[42]), anonfield(typs[33])}) typs[50] = Types[TUINTPTR]
typs[51] = Types[TUINTPTR] typs[51] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[50])}, []*Node{anonfield(typs[33])})
typs[52] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[51])}, []*Node{anonfield(typs[33])}) typs[52] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[33])})
typs[53] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[33])}) typs[53] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])}) typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])}) typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, nil)
typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, nil) typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, []*Node{anonfield(typs[13])}) typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
typs[58] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil) typs[58] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[13])})
typs[59] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[13])}) typs[59] = typMap(typs[2], typs[2])
typs[60] = typMap(typs[2], typs[2]) typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[59])})
typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[60])}) typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, []*Node{anonfield(typs[3])}) typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, []*Node{anonfield(typs[3])}) typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])}) typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[13])})
typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[13])}) typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[13])})
typs[66] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[13])}) typs[66] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[13])})
typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[13])}) typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, nil)
typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, nil) typs[68] = functype(nil, []*Node{anonfield(typs[3])}, nil)
typs[69] = functype(nil, []*Node{anonfield(typs[3])}, nil) typs[69] = typChan(typs[2], Cboth)
typs[70] = typChan(typs[2], Cboth) typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17])}, []*Node{anonfield(typs[69])})
typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17])}, []*Node{anonfield(typs[70])}) typs[71] = typChan(typs[2], Crecv)
typs[72] = typChan(typs[2], Crecv) typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3])}, nil)
typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[72]), anonfield(typs[3])}, nil) typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[72]), anonfield(typs[3])}, []*Node{anonfield(typs[13])}) typs[74] = typChan(typs[2], Csend)
typs[75] = typChan(typs[2], Csend) typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[74]), anonfield(typs[3])}, nil)
typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[75]), anonfield(typs[3])}, nil) typs[76] = tostruct([]*Node{namedfield("enabled", typs[13]), namedfield("needed", typs[13]), namedfield("cgo", typs[13])})
typs[77] = tostruct([]*Node{namedfield("enabled", typs[13]), namedfield("needed", typs[13]), namedfield("cgo", typs[13])}) typs[77] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil)
typs[78] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil) typs[78] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil) typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[33])})
typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[33])}) typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[74]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[75]), anonfield(typs[3])}, []*Node{anonfield(typs[13])}) typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[71])}, []*Node{anonfield(typs[13])})
typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[72])}, []*Node{anonfield(typs[13])}) typs[82] = typPtr(typs[13])
typs[83] = typPtr(typs[13]) typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[82]), anonfield(typs[71])}, []*Node{anonfield(typs[13])})
typs[84] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[83]), anonfield(typs[72])}, []*Node{anonfield(typs[13])}) typs[84] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[10])}, nil)
typs[85] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[10])}, nil) typs[85] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3]), anonfield(typs[82])}, []*Node{anonfield(typs[13])})
typs[86] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[72]), anonfield(typs[3]), anonfield(typs[83])}, []*Node{anonfield(typs[13])}) typs[86] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[13])})
typs[87] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[13])}) typs[87] = functype(nil, []*Node{anonfield(typs[1])}, nil)
typs[88] = functype(nil, []*Node{anonfield(typs[1])}, nil) typs[88] = typSlice(typs[2])
typs[89] = typSlice(typs[2]) typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[33]), anonfield(typs[33])}, []*Node{anonfield(typs[88])})
typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[33]), anonfield(typs[33])}, []*Node{anonfield(typs[89])}) typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[88])})
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[89])}) typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[88]), anonfield(typs[33])}, []*Node{anonfield(typs[88])})
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[89]), anonfield(typs[33])}, []*Node{anonfield(typs[89])}) typs[92] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, nil)
typs[93] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[51])}, nil) typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[50])}, nil)
typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[51])}, nil) typs[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[13])})
typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[51])}, []*Node{anonfield(typs[13])}) typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[13])}) typs[96] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
typs[97] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])}) typs[97] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
typs[98] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])}) typs[98] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[17])})
typs[99] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[17])}) typs[99] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[19])})
typs[100] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[19])}) typs[100] = Types[TUINT32]
typs[101] = Types[TUINT32] typs[101] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[100])})
typs[102] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[101])}) typs[102] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[15])})
typs[103] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[15])}) typs[103] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[15])})
typs[104] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[15])}) typs[104] = functype(nil, []*Node{anonfield(typs[100])}, []*Node{anonfield(typs[15])})
typs[105] = functype(nil, []*Node{anonfield(typs[101])}, []*Node{anonfield(typs[15])}) typs[105] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[106] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])}) typs[106] = functype(nil, []*Node{anonfield(typs[50])}, nil)
typs[107] = functype(nil, []*Node{anonfield(typs[51])}, nil) typs[107] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
typs[108] = functype(nil, []*Node{anonfield(typs[51]), anonfield(typs[51])}, nil)
return typs[:] return typs[:]
} }
...@@ -51,7 +51,6 @@ func slicebytetostring(*[32]byte, []byte) string ...@@ -51,7 +51,6 @@ func slicebytetostring(*[32]byte, []byte) string
func slicebytetostringtmp([]byte) string func slicebytetostringtmp([]byte) string
func slicerunetostring(*[32]byte, []rune) string func slicerunetostring(*[32]byte, []rune) string
func stringtoslicebyte(*[32]byte, string) []byte func stringtoslicebyte(*[32]byte, string) []byte
func stringtoslicebytetmp(string) []byte
func stringtoslicerune(*[32]rune, string) []rune func stringtoslicerune(*[32]rune, string) []rune
func decoderune(string, int) (retv rune, retk int) func decoderune(string, int) (retv rune, retk int)
func slicecopy(to any, fr any, wid uintptr) int func slicecopy(to any, fr any, wid uintptr) int
......
...@@ -314,6 +314,10 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) { ...@@ -314,6 +314,10 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
instrumentnode(&n.Left, init, 0, 0) instrumentnode(&n.Left, init, 0, 0)
goto ret goto ret
case OSTRARRAYBYTETMP:
instrumentnode(&n.Left, init, 0, 0)
goto ret
// should not appear in AST by now // should not appear in AST by now
case OSEND, case OSEND,
ORECV, ORECV,
......
...@@ -1428,6 +1428,11 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1428,6 +1428,11 @@ func (s *state) expr(n *Node) *ssa.Value {
ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), slice) ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), slice)
len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice) len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
return s.newValue2(ssa.OpStringMake, n.Type, ptr, len) return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
case OSTRARRAYBYTETMP:
str := s.expr(n.Left)
ptr := s.newValue1(ssa.OpStringPtr, ptrto(Types[TUINT8]), str)
len := s.newValue1(ssa.OpStringLen, Types[TINT], str)
return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len)
case OCFUNC: case OCFUNC:
aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: n.Type, Sym: n.Left.Sym}) aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: n.Type, Sym: n.Left.Sym})
return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb) return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
......
...@@ -1660,9 +1660,15 @@ opswitch: ...@@ -1660,9 +1660,15 @@ opswitch:
n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, Types[TSTRING])) n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, Types[TSTRING]))
// stringtoslicebytetmp(string) []byte;
case OSTRARRAYBYTETMP: case OSTRARRAYBYTETMP:
n = mkcall("stringtoslicebytetmp", n.Type, init, conv(n.Left, Types[TSTRING])) // []byte(string) conversion that creates a slice
// referring to the actual string bytes.
// This conversion is handled later by the backend and
// is only for use by internal compiler optimizations
// that know that the slice won't be mutated.
// The only such case today is:
// for i, c := range []byte(string)
n.Left = walkexpr(n.Left, init)
// stringtoslicerune(*[32]rune, string) []rune // stringtoslicerune(*[32]rune, string) []rune
case OSTRARRAYRUNE: case OSTRARRAYRUNE:
......
...@@ -147,18 +147,6 @@ func stringtoslicebyte(buf *tmpBuf, s string) []byte { ...@@ -147,18 +147,6 @@ func stringtoslicebyte(buf *tmpBuf, s string) []byte {
return b return b
} }
func stringtoslicebytetmp(s string) []byte {
// Return a slice referring to the actual string bytes.
// This is only for use by internal compiler optimizations
// that know that the slice won't be mutated.
// The only such case today is:
// for i, c := range []byte(str)
str := stringStructOf(&s)
ret := slice{array: str.str, len: str.len, cap: str.len}
return *(*[]byte)(unsafe.Pointer(&ret))
}
func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune { func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
// two passes. // two passes.
// unlike slicerunetostring, no race because strings are immutable. // unlike slicerunetostring, no race because strings are immutable.
......
...@@ -110,6 +110,30 @@ func testslice2() { ...@@ -110,6 +110,30 @@ func testslice2() {
} }
} }
// test that range over []byte(string) only evaluates
// the expression after "range" once.
func makenumstring() string {
nmake++
return "\x01\x02\x03\x04\x05"
}
func testslice3() {
s := byte(0)
nmake = 0
for _, v := range []byte(makenumstring()) {
s += v
}
if nmake != 1 {
println("range called makenumstring", nmake, "times")
panic("fail")
}
if s != 15 {
println("wrong sum ranging over []byte(makenumstring)", s)
panic("fail")
}
}
// test that range over array only evaluates // test that range over array only evaluates
// the expression after "range" once. // the expression after "range" once.
...@@ -392,6 +416,7 @@ func main() { ...@@ -392,6 +416,7 @@ func main() {
testslice() testslice()
testslice1() testslice1()
testslice2() testslice2()
testslice3()
teststring() teststring()
teststring1() teststring1()
teststring2() teststring2()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment