runtime: use internal/strconv

Runtime doing its own number formatting dates back to
when runtime was the bottom-most Go package.
Those days are long gone. Use internal/strconv to avoid
duplicating code and also to get better floating-point
formatting:

% go1.24.6 run x.go
+1.234568e+004
% go run x.go
12345.678
%

With accurate floating point it becomes necessary to
introduce separate printers for float32 vs float64 and
for complex64 vs complex128. Otherwise float32(93.7)
prints as 93.69999694824219.

Change-Id: I25ae3f09519342dc3d1dcabf4711651423e00128
Reviewed-on: https://go-review.googlesource.com/c/go/+/716002
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Russ Cox 2025-10-28 22:00:26 -04:00
parent 49c1da474d
commit 9035f7aea5
16 changed files with 381 additions and 423 deletions

View file

@ -49,11 +49,13 @@ func goPanicSlice3CU(x uint, y int)
func goPanicSliceConvert(x int, y int)
func printbool(bool)
func printfloat(float64)
func printfloat64(float64)
func printfloat32(float32)
func printint(int64)
func printhex(uint64)
func printuint(uint64)
func printcomplex(complex128)
func printcomplex128(complex128)
func printcomplex64(complex64)
func printstring(string)
func printpointer(any)
func printuintptr(uintptr)

View file

@ -56,182 +56,184 @@ var runtimeDecls = [...]struct {
{"goPanicSlice3CU", funcTag, 16},
{"goPanicSliceConvert", funcTag, 14},
{"printbool", funcTag, 17},
{"printfloat", funcTag, 19},
{"printint", funcTag, 21},
{"printhex", funcTag, 23},
{"printuint", funcTag, 23},
{"printcomplex", funcTag, 25},
{"printstring", funcTag, 27},
{"printpointer", funcTag, 28},
{"printuintptr", funcTag, 29},
{"printiface", funcTag, 28},
{"printeface", funcTag, 28},
{"printslice", funcTag, 28},
{"printfloat64", funcTag, 19},
{"printfloat32", funcTag, 21},
{"printint", funcTag, 23},
{"printhex", funcTag, 25},
{"printuint", funcTag, 25},
{"printcomplex128", funcTag, 27},
{"printcomplex64", funcTag, 29},
{"printstring", funcTag, 31},
{"printpointer", funcTag, 32},
{"printuintptr", funcTag, 33},
{"printiface", funcTag, 32},
{"printeface", funcTag, 32},
{"printslice", funcTag, 32},
{"printnl", funcTag, 9},
{"printsp", funcTag, 9},
{"printlock", funcTag, 9},
{"printunlock", funcTag, 9},
{"concatstring2", funcTag, 32},
{"concatstring3", funcTag, 33},
{"concatstring4", funcTag, 34},
{"concatstring5", funcTag, 35},
{"concatstrings", funcTag, 37},
{"concatbyte2", funcTag, 39},
{"concatbyte3", funcTag, 40},
{"concatbyte4", funcTag, 41},
{"concatbyte5", funcTag, 42},
{"concatbytes", funcTag, 43},
{"cmpstring", funcTag, 44},
{"intstring", funcTag, 47},
{"slicebytetostring", funcTag, 48},
{"slicebytetostringtmp", funcTag, 49},
{"slicerunetostring", funcTag, 52},
{"stringtoslicebyte", funcTag, 53},
{"stringtoslicerune", funcTag, 56},
{"slicecopy", funcTag, 57},
{"decoderune", funcTag, 58},
{"countrunes", funcTag, 59},
{"convT", funcTag, 60},
{"convTnoptr", funcTag, 60},
{"convT16", funcTag, 62},
{"convT32", funcTag, 64},
{"convT64", funcTag, 65},
{"convTstring", funcTag, 66},
{"convTslice", funcTag, 69},
{"assertE2I", funcTag, 70},
{"assertE2I2", funcTag, 70},
{"panicdottypeE", funcTag, 71},
{"panicdottypeI", funcTag, 71},
{"panicnildottype", funcTag, 72},
{"typeAssert", funcTag, 70},
{"interfaceSwitch", funcTag, 73},
{"ifaceeq", funcTag, 75},
{"efaceeq", funcTag, 75},
{"panicrangestate", funcTag, 76},
{"concatstring2", funcTag, 36},
{"concatstring3", funcTag, 37},
{"concatstring4", funcTag, 38},
{"concatstring5", funcTag, 39},
{"concatstrings", funcTag, 41},
{"concatbyte2", funcTag, 43},
{"concatbyte3", funcTag, 44},
{"concatbyte4", funcTag, 45},
{"concatbyte5", funcTag, 46},
{"concatbytes", funcTag, 47},
{"cmpstring", funcTag, 48},
{"intstring", funcTag, 51},
{"slicebytetostring", funcTag, 52},
{"slicebytetostringtmp", funcTag, 53},
{"slicerunetostring", funcTag, 56},
{"stringtoslicebyte", funcTag, 57},
{"stringtoslicerune", funcTag, 60},
{"slicecopy", funcTag, 61},
{"decoderune", funcTag, 62},
{"countrunes", funcTag, 63},
{"convT", funcTag, 64},
{"convTnoptr", funcTag, 64},
{"convT16", funcTag, 66},
{"convT32", funcTag, 68},
{"convT64", funcTag, 69},
{"convTstring", funcTag, 70},
{"convTslice", funcTag, 73},
{"assertE2I", funcTag, 74},
{"assertE2I2", funcTag, 74},
{"panicdottypeE", funcTag, 75},
{"panicdottypeI", funcTag, 75},
{"panicnildottype", funcTag, 76},
{"typeAssert", funcTag, 74},
{"interfaceSwitch", funcTag, 77},
{"ifaceeq", funcTag, 79},
{"efaceeq", funcTag, 79},
{"panicrangestate", funcTag, 80},
{"deferrangefunc", funcTag, 12},
{"rand", funcTag, 77},
{"rand32", funcTag, 78},
{"makemap64", funcTag, 80},
{"makemap", funcTag, 81},
{"makemap_small", funcTag, 82},
{"mapaccess1", funcTag, 83},
{"mapaccess1_fast32", funcTag, 84},
{"mapaccess1_fast64", funcTag, 85},
{"mapaccess1_faststr", funcTag, 86},
{"mapaccess1_fat", funcTag, 87},
{"mapaccess2", funcTag, 88},
{"mapaccess2_fast32", funcTag, 89},
{"mapaccess2_fast64", funcTag, 90},
{"mapaccess2_faststr", funcTag, 91},
{"mapaccess2_fat", funcTag, 92},
{"mapassign", funcTag, 83},
{"mapassign_fast32", funcTag, 84},
{"mapassign_fast32ptr", funcTag, 93},
{"mapassign_fast64", funcTag, 85},
{"mapassign_fast64ptr", funcTag, 93},
{"mapassign_faststr", funcTag, 86},
{"mapIterStart", funcTag, 94},
{"mapdelete", funcTag, 94},
{"mapdelete_fast32", funcTag, 95},
{"mapdelete_fast64", funcTag, 96},
{"mapdelete_faststr", funcTag, 97},
{"mapIterNext", funcTag, 98},
{"mapclear", funcTag, 99},
{"makechan64", funcTag, 101},
{"makechan", funcTag, 102},
{"chanrecv1", funcTag, 104},
{"chanrecv2", funcTag, 105},
{"chansend1", funcTag, 107},
{"closechan", funcTag, 108},
{"chanlen", funcTag, 109},
{"chancap", funcTag, 109},
{"writeBarrier", varTag, 111},
{"typedmemmove", funcTag, 112},
{"typedmemclr", funcTag, 113},
{"typedslicecopy", funcTag, 114},
{"selectnbsend", funcTag, 115},
{"selectnbrecv", funcTag, 116},
{"selectsetpc", funcTag, 117},
{"selectgo", funcTag, 118},
{"rand", funcTag, 81},
{"rand32", funcTag, 82},
{"makemap64", funcTag, 84},
{"makemap", funcTag, 85},
{"makemap_small", funcTag, 86},
{"mapaccess1", funcTag, 87},
{"mapaccess1_fast32", funcTag, 88},
{"mapaccess1_fast64", funcTag, 89},
{"mapaccess1_faststr", funcTag, 90},
{"mapaccess1_fat", funcTag, 91},
{"mapaccess2", funcTag, 92},
{"mapaccess2_fast32", funcTag, 93},
{"mapaccess2_fast64", funcTag, 94},
{"mapaccess2_faststr", funcTag, 95},
{"mapaccess2_fat", funcTag, 96},
{"mapassign", funcTag, 87},
{"mapassign_fast32", funcTag, 88},
{"mapassign_fast32ptr", funcTag, 97},
{"mapassign_fast64", funcTag, 89},
{"mapassign_fast64ptr", funcTag, 97},
{"mapassign_faststr", funcTag, 90},
{"mapIterStart", funcTag, 98},
{"mapdelete", funcTag, 98},
{"mapdelete_fast32", funcTag, 99},
{"mapdelete_fast64", funcTag, 100},
{"mapdelete_faststr", funcTag, 101},
{"mapIterNext", funcTag, 102},
{"mapclear", funcTag, 103},
{"makechan64", funcTag, 105},
{"makechan", funcTag, 106},
{"chanrecv1", funcTag, 108},
{"chanrecv2", funcTag, 109},
{"chansend1", funcTag, 111},
{"closechan", funcTag, 112},
{"chanlen", funcTag, 113},
{"chancap", funcTag, 113},
{"writeBarrier", varTag, 115},
{"typedmemmove", funcTag, 116},
{"typedmemclr", funcTag, 117},
{"typedslicecopy", funcTag, 118},
{"selectnbsend", funcTag, 119},
{"selectnbrecv", funcTag, 120},
{"selectsetpc", funcTag, 121},
{"selectgo", funcTag, 122},
{"block", funcTag, 9},
{"makeslice", funcTag, 119},
{"makeslice64", funcTag, 120},
{"makeslicecopy", funcTag, 121},
{"growslice", funcTag, 123},
{"unsafeslicecheckptr", funcTag, 124},
{"makeslice", funcTag, 123},
{"makeslice64", funcTag, 124},
{"makeslicecopy", funcTag, 125},
{"growslice", funcTag, 127},
{"unsafeslicecheckptr", funcTag, 128},
{"panicunsafeslicelen", funcTag, 9},
{"panicunsafeslicenilptr", funcTag, 9},
{"unsafestringcheckptr", funcTag, 125},
{"unsafestringcheckptr", funcTag, 129},
{"panicunsafestringlen", funcTag, 9},
{"panicunsafestringnilptr", funcTag, 9},
{"memmove", funcTag, 126},
{"memclrNoHeapPointers", funcTag, 127},
{"memclrHasPointers", funcTag, 127},
{"memequal", funcTag, 128},
{"memequal0", funcTag, 129},
{"memequal8", funcTag, 129},
{"memequal16", funcTag, 129},
{"memequal32", funcTag, 129},
{"memequal64", funcTag, 129},
{"memequal128", funcTag, 129},
{"f32equal", funcTag, 130},
{"f64equal", funcTag, 130},
{"c64equal", funcTag, 130},
{"c128equal", funcTag, 130},
{"strequal", funcTag, 130},
{"interequal", funcTag, 130},
{"nilinterequal", funcTag, 130},
{"memhash", funcTag, 131},
{"memhash0", funcTag, 132},
{"memhash8", funcTag, 132},
{"memhash16", funcTag, 132},
{"memhash32", funcTag, 132},
{"memhash64", funcTag, 132},
{"memhash128", funcTag, 132},
{"f32hash", funcTag, 133},
{"f64hash", funcTag, 133},
{"c64hash", funcTag, 133},
{"c128hash", funcTag, 133},
{"strhash", funcTag, 133},
{"interhash", funcTag, 133},
{"nilinterhash", funcTag, 133},
{"int64div", funcTag, 134},
{"uint64div", funcTag, 135},
{"int64mod", funcTag, 134},
{"uint64mod", funcTag, 135},
{"float64toint64", funcTag, 136},
{"float64touint64", funcTag, 137},
{"float64touint32", funcTag, 138},
{"int64tofloat64", funcTag, 139},
{"int64tofloat32", funcTag, 141},
{"uint64tofloat64", funcTag, 142},
{"uint64tofloat32", funcTag, 143},
{"uint32tofloat64", funcTag, 144},
{"complex128div", funcTag, 145},
{"racefuncenter", funcTag, 29},
{"memmove", funcTag, 130},
{"memclrNoHeapPointers", funcTag, 131},
{"memclrHasPointers", funcTag, 131},
{"memequal", funcTag, 132},
{"memequal0", funcTag, 133},
{"memequal8", funcTag, 133},
{"memequal16", funcTag, 133},
{"memequal32", funcTag, 133},
{"memequal64", funcTag, 133},
{"memequal128", funcTag, 133},
{"f32equal", funcTag, 134},
{"f64equal", funcTag, 134},
{"c64equal", funcTag, 134},
{"c128equal", funcTag, 134},
{"strequal", funcTag, 134},
{"interequal", funcTag, 134},
{"nilinterequal", funcTag, 134},
{"memhash", funcTag, 135},
{"memhash0", funcTag, 136},
{"memhash8", funcTag, 136},
{"memhash16", funcTag, 136},
{"memhash32", funcTag, 136},
{"memhash64", funcTag, 136},
{"memhash128", funcTag, 136},
{"f32hash", funcTag, 137},
{"f64hash", funcTag, 137},
{"c64hash", funcTag, 137},
{"c128hash", funcTag, 137},
{"strhash", funcTag, 137},
{"interhash", funcTag, 137},
{"nilinterhash", funcTag, 137},
{"int64div", funcTag, 138},
{"uint64div", funcTag, 139},
{"int64mod", funcTag, 138},
{"uint64mod", funcTag, 139},
{"float64toint64", funcTag, 140},
{"float64touint64", funcTag, 141},
{"float64touint32", funcTag, 142},
{"int64tofloat64", funcTag, 143},
{"int64tofloat32", funcTag, 144},
{"uint64tofloat64", funcTag, 145},
{"uint64tofloat32", funcTag, 146},
{"uint32tofloat64", funcTag, 147},
{"complex128div", funcTag, 148},
{"racefuncenter", funcTag, 33},
{"racefuncexit", funcTag, 9},
{"raceread", funcTag, 29},
{"racewrite", funcTag, 29},
{"racereadrange", funcTag, 146},
{"racewriterange", funcTag, 146},
{"msanread", funcTag, 146},
{"msanwrite", funcTag, 146},
{"msanmove", funcTag, 147},
{"asanread", funcTag, 146},
{"asanwrite", funcTag, 146},
{"checkptrAlignment", funcTag, 148},
{"checkptrArithmetic", funcTag, 150},
{"libfuzzerTraceCmp1", funcTag, 151},
{"libfuzzerTraceCmp2", funcTag, 152},
{"libfuzzerTraceCmp4", funcTag, 153},
{"libfuzzerTraceCmp8", funcTag, 154},
{"libfuzzerTraceConstCmp1", funcTag, 151},
{"libfuzzerTraceConstCmp2", funcTag, 152},
{"libfuzzerTraceConstCmp4", funcTag, 153},
{"libfuzzerTraceConstCmp8", funcTag, 154},
{"libfuzzerHookStrCmp", funcTag, 155},
{"libfuzzerHookEqualFold", funcTag, 155},
{"addCovMeta", funcTag, 157},
{"raceread", funcTag, 33},
{"racewrite", funcTag, 33},
{"racereadrange", funcTag, 149},
{"racewriterange", funcTag, 149},
{"msanread", funcTag, 149},
{"msanwrite", funcTag, 149},
{"msanmove", funcTag, 150},
{"asanread", funcTag, 149},
{"asanwrite", funcTag, 149},
{"checkptrAlignment", funcTag, 151},
{"checkptrArithmetic", funcTag, 153},
{"libfuzzerTraceCmp1", funcTag, 154},
{"libfuzzerTraceCmp2", funcTag, 155},
{"libfuzzerTraceCmp4", funcTag, 156},
{"libfuzzerTraceCmp8", funcTag, 157},
{"libfuzzerTraceConstCmp1", funcTag, 154},
{"libfuzzerTraceConstCmp2", funcTag, 155},
{"libfuzzerTraceConstCmp4", funcTag, 156},
{"libfuzzerTraceConstCmp8", funcTag, 157},
{"libfuzzerHookStrCmp", funcTag, 158},
{"libfuzzerHookEqualFold", funcTag, 158},
{"addCovMeta", funcTag, 160},
{"x86HasPOPCNT", varTag, 6},
{"x86HasSSE41", varTag, 6},
{"x86HasFMA", varTag, 6},
@ -241,11 +243,11 @@ var runtimeDecls = [...]struct {
{"loong64HasLAM_BH", varTag, 6},
{"loong64HasLSX", varTag, 6},
{"riscv64HasZbb", varTag, 6},
{"asanregisterglobals", funcTag, 127},
{"asanregisterglobals", funcTag, 131},
}
func runtimeTypes() []*types.Type {
var typs [158]*types.Type
var typs [161]*types.Type
typs[0] = types.ByteType
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[types.TANY]
@ -266,144 +268,147 @@ func runtimeTypes() []*types.Type {
typs[17] = newSig(params(typs[6]), nil)
typs[18] = types.Types[types.TFLOAT64]
typs[19] = newSig(params(typs[18]), nil)
typs[20] = types.Types[types.TINT64]
typs[20] = types.Types[types.TFLOAT32]
typs[21] = newSig(params(typs[20]), nil)
typs[22] = types.Types[types.TUINT64]
typs[22] = types.Types[types.TINT64]
typs[23] = newSig(params(typs[22]), nil)
typs[24] = types.Types[types.TCOMPLEX128]
typs[24] = types.Types[types.TUINT64]
typs[25] = newSig(params(typs[24]), nil)
typs[26] = types.Types[types.TSTRING]
typs[26] = types.Types[types.TCOMPLEX128]
typs[27] = newSig(params(typs[26]), nil)
typs[28] = newSig(params(typs[2]), nil)
typs[29] = newSig(params(typs[5]), nil)
typs[30] = types.NewArray(typs[0], 32)
typs[31] = types.NewPtr(typs[30])
typs[32] = newSig(params(typs[31], typs[26], typs[26]), params(typs[26]))
typs[33] = newSig(params(typs[31], typs[26], typs[26], typs[26]), params(typs[26]))
typs[34] = newSig(params(typs[31], typs[26], typs[26], typs[26], typs[26]), params(typs[26]))
typs[35] = newSig(params(typs[31], typs[26], typs[26], typs[26], typs[26], typs[26]), params(typs[26]))
typs[36] = types.NewSlice(typs[26])
typs[37] = newSig(params(typs[31], typs[36]), params(typs[26]))
typs[38] = types.NewSlice(typs[0])
typs[39] = newSig(params(typs[31], typs[26], typs[26]), params(typs[38]))
typs[40] = newSig(params(typs[31], typs[26], typs[26], typs[26]), params(typs[38]))
typs[41] = newSig(params(typs[31], typs[26], typs[26], typs[26], typs[26]), params(typs[38]))
typs[42] = newSig(params(typs[31], typs[26], typs[26], typs[26], typs[26], typs[26]), params(typs[38]))
typs[43] = newSig(params(typs[31], typs[36]), params(typs[38]))
typs[44] = newSig(params(typs[26], typs[26]), params(typs[13]))
typs[45] = types.NewArray(typs[0], 4)
typs[46] = types.NewPtr(typs[45])
typs[47] = newSig(params(typs[46], typs[20]), params(typs[26]))
typs[48] = newSig(params(typs[31], typs[1], typs[13]), params(typs[26]))
typs[49] = newSig(params(typs[1], typs[13]), params(typs[26]))
typs[50] = types.RuneType
typs[51] = types.NewSlice(typs[50])
typs[52] = newSig(params(typs[31], typs[51]), params(typs[26]))
typs[53] = newSig(params(typs[31], typs[26]), params(typs[38]))
typs[54] = types.NewArray(typs[50], 32)
typs[55] = types.NewPtr(typs[54])
typs[56] = newSig(params(typs[55], typs[26]), params(typs[51]))
typs[57] = newSig(params(typs[3], typs[13], typs[3], typs[13], typs[5]), params(typs[13]))
typs[58] = newSig(params(typs[26], typs[13]), params(typs[50], typs[13]))
typs[59] = newSig(params(typs[26]), params(typs[13]))
typs[60] = newSig(params(typs[1], typs[3]), params(typs[7]))
typs[61] = types.Types[types.TUINT16]
typs[62] = newSig(params(typs[61]), params(typs[7]))
typs[63] = types.Types[types.TUINT32]
typs[64] = newSig(params(typs[63]), params(typs[7]))
typs[65] = newSig(params(typs[22]), params(typs[7]))
typs[66] = newSig(params(typs[26]), params(typs[7]))
typs[67] = types.Types[types.TUINT8]
typs[68] = types.NewSlice(typs[67])
typs[69] = newSig(params(typs[68]), params(typs[7]))
typs[70] = newSig(params(typs[1], typs[1]), params(typs[1]))
typs[71] = newSig(params(typs[1], typs[1], typs[1]), nil)
typs[72] = newSig(params(typs[1]), nil)
typs[73] = newSig(params(typs[1], typs[1]), params(typs[13], typs[1]))
typs[74] = types.NewPtr(typs[5])
typs[75] = newSig(params(typs[74], typs[7], typs[7]), params(typs[6]))
typs[76] = newSig(params(typs[13]), nil)
typs[77] = newSig(nil, params(typs[22]))
typs[78] = newSig(nil, params(typs[63]))
typs[79] = types.NewMap(typs[2], typs[2])
typs[80] = newSig(params(typs[1], typs[20], typs[3]), params(typs[79]))
typs[81] = newSig(params(typs[1], typs[13], typs[3]), params(typs[79]))
typs[82] = newSig(nil, params(typs[79]))
typs[83] = newSig(params(typs[1], typs[79], typs[3]), params(typs[3]))
typs[84] = newSig(params(typs[1], typs[79], typs[63]), params(typs[3]))
typs[85] = newSig(params(typs[1], typs[79], typs[22]), params(typs[3]))
typs[86] = newSig(params(typs[1], typs[79], typs[26]), params(typs[3]))
typs[87] = newSig(params(typs[1], typs[79], typs[3], typs[1]), params(typs[3]))
typs[88] = newSig(params(typs[1], typs[79], typs[3]), params(typs[3], typs[6]))
typs[89] = newSig(params(typs[1], typs[79], typs[63]), params(typs[3], typs[6]))
typs[90] = newSig(params(typs[1], typs[79], typs[22]), params(typs[3], typs[6]))
typs[91] = newSig(params(typs[1], typs[79], typs[26]), params(typs[3], typs[6]))
typs[92] = newSig(params(typs[1], typs[79], typs[3], typs[1]), params(typs[3], typs[6]))
typs[93] = newSig(params(typs[1], typs[79], typs[7]), params(typs[3]))
typs[94] = newSig(params(typs[1], typs[79], typs[3]), nil)
typs[95] = newSig(params(typs[1], typs[79], typs[63]), nil)
typs[96] = newSig(params(typs[1], typs[79], typs[22]), nil)
typs[97] = newSig(params(typs[1], typs[79], typs[26]), nil)
typs[98] = newSig(params(typs[3]), nil)
typs[99] = newSig(params(typs[1], typs[79]), nil)
typs[100] = types.NewChan(typs[2], types.Cboth)
typs[101] = newSig(params(typs[1], typs[20]), params(typs[100]))
typs[102] = newSig(params(typs[1], typs[13]), params(typs[100]))
typs[103] = types.NewChan(typs[2], types.Crecv)
typs[104] = newSig(params(typs[103], typs[3]), nil)
typs[105] = newSig(params(typs[103], typs[3]), params(typs[6]))
typs[106] = types.NewChan(typs[2], types.Csend)
typs[107] = newSig(params(typs[106], typs[3]), nil)
typs[108] = newSig(params(typs[106]), nil)
typs[109] = newSig(params(typs[2]), params(typs[13]))
typs[110] = types.NewArray(typs[0], 3)
typs[111] = types.NewStruct([]*types.Field{types.NewField(src.NoXPos, Lookup("enabled"), typs[6]), types.NewField(src.NoXPos, Lookup("pad"), typs[110]), types.NewField(src.NoXPos, Lookup("cgo"), typs[6]), types.NewField(src.NoXPos, Lookup("alignme"), typs[22])})
typs[112] = newSig(params(typs[1], typs[3], typs[3]), nil)
typs[113] = newSig(params(typs[1], typs[3]), nil)
typs[114] = newSig(params(typs[1], typs[3], typs[13], typs[3], typs[13]), params(typs[13]))
typs[115] = newSig(params(typs[106], typs[3]), params(typs[6]))
typs[116] = newSig(params(typs[3], typs[103]), params(typs[6], typs[6]))
typs[117] = newSig(params(typs[74]), nil)
typs[118] = newSig(params(typs[1], typs[1], typs[74], typs[13], typs[13], typs[6]), params(typs[13], typs[6]))
typs[119] = newSig(params(typs[1], typs[13], typs[13]), params(typs[7]))
typs[120] = newSig(params(typs[1], typs[20], typs[20]), params(typs[7]))
typs[121] = newSig(params(typs[1], typs[13], typs[13], typs[7]), params(typs[7]))
typs[122] = types.NewSlice(typs[2])
typs[123] = newSig(params(typs[3], typs[13], typs[13], typs[13], typs[1]), params(typs[122]))
typs[124] = newSig(params(typs[1], typs[7], typs[20]), nil)
typs[125] = newSig(params(typs[7], typs[20]), nil)
typs[126] = newSig(params(typs[3], typs[3], typs[5]), nil)
typs[127] = newSig(params(typs[7], typs[5]), nil)
typs[128] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
typs[129] = newSig(params(typs[3], typs[3]), params(typs[6]))
typs[130] = newSig(params(typs[7], typs[7]), params(typs[6]))
typs[131] = newSig(params(typs[3], typs[5], typs[5]), params(typs[5]))
typs[132] = newSig(params(typs[7], typs[5]), params(typs[5]))
typs[133] = newSig(params(typs[3], typs[5]), params(typs[5]))
typs[134] = newSig(params(typs[20], typs[20]), params(typs[20]))
typs[135] = newSig(params(typs[22], typs[22]), params(typs[22]))
typs[136] = newSig(params(typs[18]), params(typs[20]))
typs[137] = newSig(params(typs[18]), params(typs[22]))
typs[138] = newSig(params(typs[18]), params(typs[63]))
typs[139] = newSig(params(typs[20]), params(typs[18]))
typs[140] = types.Types[types.TFLOAT32]
typs[141] = newSig(params(typs[20]), params(typs[140]))
typs[142] = newSig(params(typs[22]), params(typs[18]))
typs[143] = newSig(params(typs[22]), params(typs[140]))
typs[144] = newSig(params(typs[63]), params(typs[18]))
typs[145] = newSig(params(typs[24], typs[24]), params(typs[24]))
typs[146] = newSig(params(typs[5], typs[5]), nil)
typs[147] = newSig(params(typs[5], typs[5], typs[5]), nil)
typs[148] = newSig(params(typs[7], typs[1], typs[5]), nil)
typs[149] = types.NewSlice(typs[7])
typs[150] = newSig(params(typs[7], typs[149]), nil)
typs[151] = newSig(params(typs[67], typs[67], typs[15]), nil)
typs[152] = newSig(params(typs[61], typs[61], typs[15]), nil)
typs[153] = newSig(params(typs[63], typs[63], typs[15]), nil)
typs[154] = newSig(params(typs[22], typs[22], typs[15]), nil)
typs[155] = newSig(params(typs[26], typs[26], typs[15]), nil)
typs[156] = types.NewArray(typs[0], 16)
typs[157] = newSig(params(typs[7], typs[63], typs[156], typs[26], typs[13], typs[67], typs[67]), params(typs[63]))
typs[28] = types.Types[types.TCOMPLEX64]
typs[29] = newSig(params(typs[28]), nil)
typs[30] = types.Types[types.TSTRING]
typs[31] = newSig(params(typs[30]), nil)
typs[32] = newSig(params(typs[2]), nil)
typs[33] = newSig(params(typs[5]), nil)
typs[34] = types.NewArray(typs[0], 32)
typs[35] = types.NewPtr(typs[34])
typs[36] = newSig(params(typs[35], typs[30], typs[30]), params(typs[30]))
typs[37] = newSig(params(typs[35], typs[30], typs[30], typs[30]), params(typs[30]))
typs[38] = newSig(params(typs[35], typs[30], typs[30], typs[30], typs[30]), params(typs[30]))
typs[39] = newSig(params(typs[35], typs[30], typs[30], typs[30], typs[30], typs[30]), params(typs[30]))
typs[40] = types.NewSlice(typs[30])
typs[41] = newSig(params(typs[35], typs[40]), params(typs[30]))
typs[42] = types.NewSlice(typs[0])
typs[43] = newSig(params(typs[35], typs[30], typs[30]), params(typs[42]))
typs[44] = newSig(params(typs[35], typs[30], typs[30], typs[30]), params(typs[42]))
typs[45] = newSig(params(typs[35], typs[30], typs[30], typs[30], typs[30]), params(typs[42]))
typs[46] = newSig(params(typs[35], typs[30], typs[30], typs[30], typs[30], typs[30]), params(typs[42]))
typs[47] = newSig(params(typs[35], typs[40]), params(typs[42]))
typs[48] = newSig(params(typs[30], typs[30]), params(typs[13]))
typs[49] = types.NewArray(typs[0], 4)
typs[50] = types.NewPtr(typs[49])
typs[51] = newSig(params(typs[50], typs[22]), params(typs[30]))
typs[52] = newSig(params(typs[35], typs[1], typs[13]), params(typs[30]))
typs[53] = newSig(params(typs[1], typs[13]), params(typs[30]))
typs[54] = types.RuneType
typs[55] = types.NewSlice(typs[54])
typs[56] = newSig(params(typs[35], typs[55]), params(typs[30]))
typs[57] = newSig(params(typs[35], typs[30]), params(typs[42]))
typs[58] = types.NewArray(typs[54], 32)
typs[59] = types.NewPtr(typs[58])
typs[60] = newSig(params(typs[59], typs[30]), params(typs[55]))
typs[61] = newSig(params(typs[3], typs[13], typs[3], typs[13], typs[5]), params(typs[13]))
typs[62] = newSig(params(typs[30], typs[13]), params(typs[54], typs[13]))
typs[63] = newSig(params(typs[30]), params(typs[13]))
typs[64] = newSig(params(typs[1], typs[3]), params(typs[7]))
typs[65] = types.Types[types.TUINT16]
typs[66] = newSig(params(typs[65]), params(typs[7]))
typs[67] = types.Types[types.TUINT32]
typs[68] = newSig(params(typs[67]), params(typs[7]))
typs[69] = newSig(params(typs[24]), params(typs[7]))
typs[70] = newSig(params(typs[30]), params(typs[7]))
typs[71] = types.Types[types.TUINT8]
typs[72] = types.NewSlice(typs[71])
typs[73] = newSig(params(typs[72]), params(typs[7]))
typs[74] = newSig(params(typs[1], typs[1]), params(typs[1]))
typs[75] = newSig(params(typs[1], typs[1], typs[1]), nil)
typs[76] = newSig(params(typs[1]), nil)
typs[77] = newSig(params(typs[1], typs[1]), params(typs[13], typs[1]))
typs[78] = types.NewPtr(typs[5])
typs[79] = newSig(params(typs[78], typs[7], typs[7]), params(typs[6]))
typs[80] = newSig(params(typs[13]), nil)
typs[81] = newSig(nil, params(typs[24]))
typs[82] = newSig(nil, params(typs[67]))
typs[83] = types.NewMap(typs[2], typs[2])
typs[84] = newSig(params(typs[1], typs[22], typs[3]), params(typs[83]))
typs[85] = newSig(params(typs[1], typs[13], typs[3]), params(typs[83]))
typs[86] = newSig(nil, params(typs[83]))
typs[87] = newSig(params(typs[1], typs[83], typs[3]), params(typs[3]))
typs[88] = newSig(params(typs[1], typs[83], typs[67]), params(typs[3]))
typs[89] = newSig(params(typs[1], typs[83], typs[24]), params(typs[3]))
typs[90] = newSig(params(typs[1], typs[83], typs[30]), params(typs[3]))
typs[91] = newSig(params(typs[1], typs[83], typs[3], typs[1]), params(typs[3]))
typs[92] = newSig(params(typs[1], typs[83], typs[3]), params(typs[3], typs[6]))
typs[93] = newSig(params(typs[1], typs[83], typs[67]), params(typs[3], typs[6]))
typs[94] = newSig(params(typs[1], typs[83], typs[24]), params(typs[3], typs[6]))
typs[95] = newSig(params(typs[1], typs[83], typs[30]), params(typs[3], typs[6]))
typs[96] = newSig(params(typs[1], typs[83], typs[3], typs[1]), params(typs[3], typs[6]))
typs[97] = newSig(params(typs[1], typs[83], typs[7]), params(typs[3]))
typs[98] = newSig(params(typs[1], typs[83], typs[3]), nil)
typs[99] = newSig(params(typs[1], typs[83], typs[67]), nil)
typs[100] = newSig(params(typs[1], typs[83], typs[24]), nil)
typs[101] = newSig(params(typs[1], typs[83], typs[30]), nil)
typs[102] = newSig(params(typs[3]), nil)
typs[103] = newSig(params(typs[1], typs[83]), nil)
typs[104] = types.NewChan(typs[2], types.Cboth)
typs[105] = newSig(params(typs[1], typs[22]), params(typs[104]))
typs[106] = newSig(params(typs[1], typs[13]), params(typs[104]))
typs[107] = types.NewChan(typs[2], types.Crecv)
typs[108] = newSig(params(typs[107], typs[3]), nil)
typs[109] = newSig(params(typs[107], typs[3]), params(typs[6]))
typs[110] = types.NewChan(typs[2], types.Csend)
typs[111] = newSig(params(typs[110], typs[3]), nil)
typs[112] = newSig(params(typs[110]), nil)
typs[113] = newSig(params(typs[2]), params(typs[13]))
typs[114] = types.NewArray(typs[0], 3)
typs[115] = types.NewStruct([]*types.Field{types.NewField(src.NoXPos, Lookup("enabled"), typs[6]), types.NewField(src.NoXPos, Lookup("pad"), typs[114]), types.NewField(src.NoXPos, Lookup("cgo"), typs[6]), types.NewField(src.NoXPos, Lookup("alignme"), typs[24])})
typs[116] = newSig(params(typs[1], typs[3], typs[3]), nil)
typs[117] = newSig(params(typs[1], typs[3]), nil)
typs[118] = newSig(params(typs[1], typs[3], typs[13], typs[3], typs[13]), params(typs[13]))
typs[119] = newSig(params(typs[110], typs[3]), params(typs[6]))
typs[120] = newSig(params(typs[3], typs[107]), params(typs[6], typs[6]))
typs[121] = newSig(params(typs[78]), nil)
typs[122] = newSig(params(typs[1], typs[1], typs[78], typs[13], typs[13], typs[6]), params(typs[13], typs[6]))
typs[123] = newSig(params(typs[1], typs[13], typs[13]), params(typs[7]))
typs[124] = newSig(params(typs[1], typs[22], typs[22]), params(typs[7]))
typs[125] = newSig(params(typs[1], typs[13], typs[13], typs[7]), params(typs[7]))
typs[126] = types.NewSlice(typs[2])
typs[127] = newSig(params(typs[3], typs[13], typs[13], typs[13], typs[1]), params(typs[126]))
typs[128] = newSig(params(typs[1], typs[7], typs[22]), nil)
typs[129] = newSig(params(typs[7], typs[22]), nil)
typs[130] = newSig(params(typs[3], typs[3], typs[5]), nil)
typs[131] = newSig(params(typs[7], typs[5]), nil)
typs[132] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
typs[133] = newSig(params(typs[3], typs[3]), params(typs[6]))
typs[134] = newSig(params(typs[7], typs[7]), params(typs[6]))
typs[135] = newSig(params(typs[3], typs[5], typs[5]), params(typs[5]))
typs[136] = newSig(params(typs[7], typs[5]), params(typs[5]))
typs[137] = newSig(params(typs[3], typs[5]), params(typs[5]))
typs[138] = newSig(params(typs[22], typs[22]), params(typs[22]))
typs[139] = newSig(params(typs[24], typs[24]), params(typs[24]))
typs[140] = newSig(params(typs[18]), params(typs[22]))
typs[141] = newSig(params(typs[18]), params(typs[24]))
typs[142] = newSig(params(typs[18]), params(typs[67]))
typs[143] = newSig(params(typs[22]), params(typs[18]))
typs[144] = newSig(params(typs[22]), params(typs[20]))
typs[145] = newSig(params(typs[24]), params(typs[18]))
typs[146] = newSig(params(typs[24]), params(typs[20]))
typs[147] = newSig(params(typs[67]), params(typs[18]))
typs[148] = newSig(params(typs[26], typs[26]), params(typs[26]))
typs[149] = newSig(params(typs[5], typs[5]), nil)
typs[150] = newSig(params(typs[5], typs[5], typs[5]), nil)
typs[151] = newSig(params(typs[7], typs[1], typs[5]), nil)
typs[152] = types.NewSlice(typs[7])
typs[153] = newSig(params(typs[7], typs[152]), nil)
typs[154] = newSig(params(typs[71], typs[71], typs[15]), nil)
typs[155] = newSig(params(typs[65], typs[65], typs[15]), nil)
typs[156] = newSig(params(typs[67], typs[67], typs[15]), nil)
typs[157] = newSig(params(typs[24], typs[24], typs[15]), nil)
typs[158] = newSig(params(typs[30], typs[30], typs[15]), nil)
typs[159] = types.NewArray(typs[0], 16)
typs[160] = newSig(params(typs[7], typs[67], typs[159], typs[30], typs[13], typs[71], typs[71]), params(typs[67]))
return typs[:]
}

View file

@ -714,10 +714,14 @@ func walkPrint(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
}
case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64:
on = typecheck.LookupRuntime("printint")
case types.TFLOAT32, types.TFLOAT64:
on = typecheck.LookupRuntime("printfloat")
case types.TCOMPLEX64, types.TCOMPLEX128:
on = typecheck.LookupRuntime("printcomplex")
case types.TFLOAT32:
on = typecheck.LookupRuntime("printfloat32")
case types.TFLOAT64:
on = typecheck.LookupRuntime("printfloat64")
case types.TCOMPLEX64:
on = typecheck.LookupRuntime("printcomplex64")
case types.TCOMPLEX128:
on = typecheck.LookupRuntime("printcomplex128")
case types.TBOOL:
on = typecheck.LookupRuntime("printbool")
case types.TSTRING:

View file

@ -35,11 +35,13 @@ var builtins = [...]struct {
{"runtime.goPanicSlice3CU", 1},
{"runtime.goPanicSliceConvert", 1},
{"runtime.printbool", 1},
{"runtime.printfloat", 1},
{"runtime.printfloat64", 1},
{"runtime.printfloat32", 1},
{"runtime.printint", 1},
{"runtime.printhex", 1},
{"runtime.printuint", 1},
{"runtime.printcomplex", 1},
{"runtime.printcomplex128", 1},
{"runtime.printcomplex64", 1},
{"runtime.printstring", 1},
{"runtime.printpointer", 1},
{"runtime.printuintptr", 1},
@ -109,13 +111,11 @@ var builtins = [...]struct {
{"runtime.mapassign_fast64", 1},
{"runtime.mapassign_fast64ptr", 1},
{"runtime.mapassign_faststr", 1},
{"runtime.mapiterinit", 1},
{"runtime.mapIterStart", 1},
{"runtime.mapdelete", 1},
{"runtime.mapdelete_fast32", 1},
{"runtime.mapdelete_fast64", 1},
{"runtime.mapdelete_faststr", 1},
{"runtime.mapiternext", 1},
{"runtime.mapIterNext", 1},
{"runtime.mapclear", 1},
{"runtime.makechan64", 1},

View file

@ -12,16 +12,29 @@ package strconv
// It rounds the result assuming that the original was obtained from a complex
// value of bitSize bits, which must be 64 for complex64 and 128 for complex128.
func FormatComplex(c complex128, fmt byte, prec, bitSize int) string {
var buf [64]byte
return string(AppendComplex(buf[:0], c, fmt, prec, bitSize))
}
// AppendComplex appends the result of FormatComplex to dst.
// It is here for the runtime.
// There is no public strconv.AppendComplex.
func AppendComplex(dst []byte, c complex128, fmt byte, prec, bitSize int) []byte {
if bitSize != 64 && bitSize != 128 {
panic("invalid bitSize")
}
bitSize >>= 1 // complex64 uses float32 internally
dst = append(dst, '(')
dst = AppendFloat(dst, real(c), fmt, prec, bitSize)
i := len(dst)
dst = AppendFloat(dst, imag(c), fmt, prec, bitSize)
// Check if imaginary part has a sign. If not, add one.
im := FormatFloat(imag(c), fmt, prec, bitSize)
if im[0] != '+' && im[0] != '-' {
im = "+" + im
if dst[i] != '+' && dst[i] != '-' {
dst = append(dst, 0)
copy(dst[i+1:], dst[i:])
dst[i] = '+'
}
return "(" + FormatFloat(real(c), fmt, prec, bitSize) + im + "i)"
dst = append(dst, "i)"...)
return dst
}

View file

@ -18,10 +18,10 @@ func TestPanicWithDirectlyPrintableCustomTypes(t *testing.T) {
wantPanicPrefix string
}{
{"panicCustomBool", `panic: main.MyBool(true)`},
{"panicCustomComplex128", `panic: main.MyComplex128(+3.210000e+001+1.000000e+001i)`},
{"panicCustomComplex64", `panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)`},
{"panicCustomFloat32", `panic: main.MyFloat32(-9.370000e+001)`},
{"panicCustomFloat64", `panic: main.MyFloat64(-9.370000e+001)`},
{"panicCustomComplex128", `panic: main.MyComplex128(32.1+10i)`},
{"panicCustomComplex64", `panic: main.MyComplex64(0.11+3i)`},
{"panicCustomFloat32", `panic: main.MyFloat32(-93.7)`},
{"panicCustomFloat64", `panic: main.MyFloat64(-93.7)`},
{"panicCustomInt", `panic: main.MyInt(93)`},
{"panicCustomInt8", `panic: main.MyInt8(93)`},
{"panicCustomInt16", `panic: main.MyInt16(93)`},

View file

@ -6,6 +6,7 @@ package runtime
import (
"internal/goarch"
"internal/strconv"
"unsafe"
)
@ -118,101 +119,34 @@ func printbool(v bool) {
}
}
func printfloat(v float64) {
switch {
case v != v:
printstring("NaN")
return
case v+v == v && v > 0:
printstring("+Inf")
return
case v+v == v && v < 0:
printstring("-Inf")
return
}
const n = 7 // digits printed
var buf [n + 7]byte
buf[0] = '+'
e := 0 // exp
if v == 0 {
if 1/v < 0 {
buf[0] = '-'
}
} else {
if v < 0 {
v = -v
buf[0] = '-'
}
// normalize
for v >= 10 {
e++
v /= 10
}
for v < 1 {
e--
v *= 10
}
// round
h := 5.0
for i := 0; i < n; i++ {
h /= 10
}
v += h
if v >= 10 {
e++
v /= 10
}
}
// format +d.dddd+edd
for i := 0; i < n; i++ {
s := int(v)
buf[i+2] = byte(s + '0')
v -= float64(s)
v *= 10
}
buf[1] = buf[2]
buf[2] = '.'
buf[n+2] = 'e'
buf[n+3] = '+'
if e < 0 {
e = -e
buf[n+3] = '-'
}
buf[n+4] = byte(e/100) + '0'
buf[n+5] = byte(e/10)%10 + '0'
buf[n+6] = byte(e%10) + '0'
gwrite(buf[:])
func printfloat64(v float64) {
var buf [20]byte
gwrite(strconv.AppendFloat(buf[:0], v, 'g', -1, 64))
}
func printcomplex(c complex128) {
print("(", real(c), imag(c), "i)")
func printfloat32(v float32) {
var buf [20]byte
gwrite(strconv.AppendFloat(buf[:0], float64(v), 'g', -1, 32))
}
func printcomplex128(c complex128) {
var buf [44]byte
gwrite(strconv.AppendComplex(buf[:0], c, 'g', -1, 128))
}
func printcomplex64(c complex64) {
var buf [44]byte
gwrite(strconv.AppendComplex(buf[:0], complex128(c), 'g', -1, 64))
}
func printuint(v uint64) {
var buf [100]byte
i := len(buf)
for i--; i > 0; i-- {
buf[i] = byte(v%10 + '0')
if v < 10 {
break
}
v /= 10
}
gwrite(buf[i:])
var buf [20]byte
gwrite(strconv.AppendUint(buf[:0], v, 10))
}
func printint(v int64) {
if v < 0 {
printstring("-")
v = -v
}
printuint(uint64(v))
var buf [20]byte
gwrite(strconv.AppendInt(buf[:0], v, 10))
}
var minhexdigits = 0 // protected by printlock

View file

@ -1,2 +1,2 @@
printing: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
42 true false true +1.500000e+000 world 0x0 [0/0]0x0 0x0 0x0 255
42 true false true 1.5 world 0x0 [0/0]0x0 0x0 0x0 255

View file

@ -1 +1 @@
+1.000000e+000 +2.000000e+000 +3.000000e+000 +4.000000e+000
1 2 3 4

View file

@ -64,8 +64,8 @@ func main() {
{"uint64", "8", "panic: 8"},
{"uintptr", "8", "panic: 8"},
{"bool", "true", "panic: true"},
{"complex64", "8 + 16i", "panic: (+8.000000e+000+1.600000e+001i)"},
{"complex128", "8+16i", "panic: (+8.000000e+000+1.600000e+001i)"},
{"complex64", "8 + 16i", "panic: (8+16i)"},
{"complex128", "8+16i", "panic: (8+16i)"},
{"string", `"test"`, "panic: test"}} {
b := bytes.Buffer{}

View file

@ -1 +1 @@
-42+4.200000e+001x-42 +4.200000e+001 x
-4242x-42 42 x

View file

@ -1 +1 @@
-0.000000e+000
-0

View file

@ -1 +1 @@
42 true false true +1.500000e+000 world 0x0 [0/0]0x0 0x0 0x0 255
42 true false true 1.5 world 0x0 [0/0]0x0 0x0 0x0 255

View file

@ -1,4 +1,4 @@
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(5+6i)
(5+6i)
(5+6i)
(5+6i)

View file

@ -9,8 +9,8 @@
7
7
7
+8.000000e+000
(+9.000000e+000+1.000000e+001i)
8
(9+10i)
true
false
hello
@ -19,8 +19,8 @@ one two
hello
false
true
(+1.400000e+001+1.500000e+001i)
+1.300000e+001
(14+15i)
13
12
12
12

View file

@ -1,4 +1,4 @@
fooer 6
other
other
fooer +9.000000e+000
fooer 9