]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: rework mkbuiltin.go to generate code
authorMatthew Dempsky <mdempsky@google.com>
Tue, 18 Oct 2016 23:11:50 +0000 (16:11 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 19 Oct 2016 19:58:00 +0000 (19:58 +0000)
Generating binary export data requires a working Go compiler. Even
trickier to change the export data format itself requires a careful
bootstrapping procedure.

Instead, simply generate normal Go code that lets us directly
construct the builtin runtime declarations.

Passes toolstash -cmp.

Fixes #17508.

Change-Id: I4f6078a3c7507ba40072580695d57c87a5604baf
Reviewed-on: https://go-review.googlesource.com/31493
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/builtin.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/mkbuiltin.go

index c016bedc8a97fbd30de84b816cccb30070130839..c2c6128e3b76e57cc8bf18f00fcd0f65888d7f9f 100644 (file)
 
 package gc
 
-const runtimeimport = "" +
-       "version 2\n\n\x00\x00\x01\rruntime\x00\t\x11newobject\x00\x02\x17\"\vt" +
-       "yp·2\x00\x00\x01\x17:\x00\t\x13panicindex\x00\x00\x00\t\x13panicslice\x00\x00" +
-       "\x00\t\x15panicdivide\x00\x00\x00\t\x11throwinit\x00\x00\x00\t\x11panicwr" +
-       "ap\x00\x05 \x00 \x00 \x00\x00\t\rgopanic\x00\x01\x1b\x00\x00\x00\x00\t\x11gorecover\x00\x01" +
-       "\x17\b\x00\x01\x1b\x00\x00\x00\t\x11printbool\x00\x01\x00\x00\x00\t\x13printfloat\x00\x01\x1a\x00" +
-       "\x00\t\x0fprintint\x00\x01\n\x00\x00\t\x0fprinthex\x00\x01\x14\x00\x00\t\x11printui" +
-       "nt\x00\x01\x14\x00\x00\t\x17printcomplex\x00\x01\x1e\x00\x00\t\x15printstring\x00" +
-       "\x01 \x00\x00\t\x17printpointer\x00\x01:\x00\x00\t\x13printiface\x00\x01:\x00\x00" +
-       "\t\x13printeface\x00\x01:\x00\x00\t\x13printslice\x00\x01:\x00\x00\t\rprin" +
-       "tnl\x00\x00\x00\t\rprintsp\x00\x00\x00\t\x11printlock\x00\x00\x00\t\x15printu" +
-       "nlock\x00\x00\x00\t\x19concatstring2\x00\x05\x17\x0f@\"\x00 \x00 \x00\x01 \x00\t\x19c" +
-       "oncatstring3\x00\a\x17\x0f@\"\x00 \x00 \x00 \x00\x01 \x00\t\x19concatstri" +
-       "ng4\x00\t\x17\x0f@\"\x00 \x00 \x00 \x00 \x00\x01 \x00\t\x19concatstring5\x00\v\x17\x0f" +
-       "@\"\x00 \x00 \x00 \x00 \x00 \x00\x01 \x00\t\x19concatstrings\x00\x03\x17\x0f@\"\x00\x11 " +
-       "\x00\x01 \x00\t\x11cmpstring\x00\x03 \x00 \x00\x01\x02\x00\t\x0feqstring\x00\x03 \x00 \x00" +
-       "\x01\x00\x00\t\x11intstring\x00\x03\x17\x0f\b\"\x00\n\x00\x01 \x00\t!slicebytetos" +
-       "tring\x00\x03\x17\x0f@\"\x00\x11\"\x00\x01 \x00\t'slicebytetostringtmp" +
-       "\x00\x01\x11\"\x00\x01 \x00\t!slicerunetostring\x00\x03\x17\x0f@\"\x00\x11|S\x00\x01 " +
-       "\x00\t!stringtoslicebyte\x00\x03\x17\x0f@\"\x00 \x00\x01\x11\"\x00\t'strin" +
-       "gtoslicebytetmp\x00\x01 \x00\x01\x11\"\x00\t!stringtosliceru" +
-       "ne\x00\x03\x17\x0f@|S\x00 \x00\x01\x11|S\x00\t\x13decoderune\x00\x03 \x00\x02\x00\x04|S\rr" +
-       "etv·1\x00\x00\x02\rretk·2\x00\x00\t\x11slicecopy\x00\x06:\tto·2\x00" +
-       "\x00:\tfr·3\x00\x00\x16\vwid·4\x00\x1bunsafe-uintptr\x01\x02\x00\t\x1ds" +
-       "licestringcopy\x00\x04:X\x00\x00:Z\x00\x00\x01\x02\x00\t\rconvI2E\x00\x02:\r" +
-       "elem·2\x00\x00\x02:\vret·1\x00\x00\t\rconvI2I\x00\x04\x17\"\x06\x00\x00:\rel" +
-       "em·3\x00\x00\x02:f\x00\x00\t\rconvT2E\x00\x04\x17\"\x06\x00\x00\x17:j\x00\x00\x02:f\x00\x00\t\r" +
-       "convT2I\x00\x04\x17\"\vtab·2\x00\x00\x17:j\x00\x00\x02:f\x00\x00\t\x11assertE2" +
-       "E\x00\x06\x17\"\vtyp·1\x00\x00:\x0fiface·2\x00\x00\x17:\vret·3\x00\x00\x00\t\x13" +
-       "assertE2E2\x00\x06\x17\"\x06\x00\x00:\x0fiface·3\x00\x00\x17:\vret·4\x00\x00" +
-       "\x01\x00\x00\t\x11assertE2I\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertE" +
-       "2I2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x11assertE2T\x00\x06\x17\"t\x00" +
-       "\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertE2T2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00" +
-       "\x01\x00\x00\t\x11assertI2E\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertI" +
-       "2E2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x11assertI2I\x00\x06\x17\"t\x00" +
-       "\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertI2I2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00" +
-       "\x01\x00\x00\t\x11assertI2T\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertI" +
-       "2T2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x17panicdottype\x00\x06\x17" +
-       "\"\rhave·1\x00\x00\x17\"\rwant·2\x00\x00\x17\"||\x00\x00\x00\t\rifaceeq\x00" +
-       "\x04:\ti1·2\x00\x00:\ti2·3\x00\x00\x02\x00f\x00\x00\t\refaceeq\x00\x04:\x9c\x01\x00\x00" +
-       ":\x9e\x01\x00\x00\x02\x00f\x00\x00\t\rmakemap\x00\b\x17\"\x13mapType·2\x00\x00\n\rhi" +
-       "nt·3\x00\x00\x17:\x11mapbuf·4\x00\x00\x17:\x17bucketbuf·5\x00\x00\x02\x1d" +
-       "::\rhmap·1\x00\x00\t\x13mapaccess1\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\rhmap" +
-       "·3\x00\x00\x17:\vkey·4\x00\x00\x02\x17:\vval·1\x00\x00\t!mapaccess1" +
-       "_fast32\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00\x00\x02\x17:\xb4\x01\x00\x00\t!mapa" +
-       "ccess1_fast64\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00\x00\x02\x17:\xb4\x01\x00\x00" +
-       "\t#mapaccess1_faststr\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00\x00" +
-       "\x02\x17:\xb4\x01\x00\x00\t\x1bmapaccess1_fat\x00\b\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00\x17:" +
-       "\xb2\x01\x00\x00\x17\"\rzero·5\x00\x00\x02\x17:\xb4\x01\x00\x00\t\x13mapaccess2\x00\x06\x17\"\x13" +
-       "mapType·3\x00\x00\x1d::\rhmap·4\x00\x00\x17:\vkey·5\x00\x00\x04\x17:\xb4" +
-       "\x01\x00\x00\x00\rpres·2\x00\x00\t!mapaccess2_fast32\x00\x06\x17\"\xc2\x01\x00" +
-       "\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t!mapaccess2_fa" +
-       "st64\x00\x06\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t#ma" +
-       "paccess2_faststr\x00\x06\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:\xb4" +
-       "\x01\x00\x00\x00\xc8\x01\x00\x00\t\x1bmapaccess2_fat\x00\b\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00\x17" +
-       ":\xc6\x01\x00\x00\x17\"\rzero·6\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t\x11mapassign" +
-       "\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00\x17:\xb2\x01\x00\x00\x02\x17:\xb4\x01\x00\x00\t\x15mapiterini" +
-       "t\x00\x06\x17\"\x13mapType·1\x00\x00\x1d::\rhmap·2\x00\x00\x17:\x0fhiter\xc2" +
-       "\xb73\x00\x00\x00\t\x11mapdelete\x00\x06\x17\"\xd8\x01\x00\x00\x1d::\xda\x01\x00\x00\x17:\vkey·3" +
-       "\x00\x00\x00\t\x15mapiternext\x00\x02\x17:\x0fhiter·1\x00\x00\x00\t\x0fmakech" +
-       "an\x00\x04\x17\"\x15chanType·2\x00\x00\n\xa6\x01\x00\x00\x02\x1f\x06:\x0fhchan·1\x00\x00" +
-       "\t\x11chanrecv1\x00\x06\x17\"\x15chanType·1\x00\x00\x1f\x02:\x0fhchan·" +
-       "2\x00\x00\x17:j\x00\x00\x00\t\x11chanrecv2\x00\x06\x17\"\xe8\x01\x00\x00\x1f\x02:\x0fhchan·3" +
-       "\x00\x00\x17:\relem·4\x00\x00\x01\x00\x00\t\x11chansend1\x00\x06\x17\"\xee\x01\x00\x00\x1f\x04:\xf0" +
-       "\x01\x00\x00\x17:j\x00\x00\x00\t\x11closechan\x00\x02:\xea\x01\x00\x00\x00\a\x17writeBarri" +
-       "er\x00\x15\x06\renabled\x00\x00\x00\vneeded\x00\x00\x00\x05cgo\x00\x00\x00\t\x1dwrite" +
-       "barrierptr\x00\x04\x17:\vdst·1\x00\x00:\vsrc·2\x00\x00\x00\t\x17type" +
-       "dmemmove\x00\x06\x17\"t\x00\x00\x17:\vdst·2\x00\x00\x17:\vsrc·3\x00\x00\x00\t\x1b" +
-       "typedslicecopy\x00\x06\x17\"\x06\x00\x00:\vdst·3\x00\x00:\vsrc·4\x00" +
-       "\x00\x01\x02\x00\t\x17selectnbsend\x00\x06\x17\"\xe8\x01\x00\x00\x1f\x04:\xf4\x01\x00\x00\x17:\xf6\x01\x00\x00\x01" +
-       "\x00\x00\t\x17selectnbrecv\x00\x06\x17\"\xe8\x01\x00\x00\x17:j\x00\x00\x1f\x02:\x0fhchan·" +
-       "4\x00\x00\x01\x00\x00\t\x19selectnbrecv2\x00\b\x17\"\xe8\x01\x00\x00\x17:j\x00\x00\x17\x00\x15rec" +
-       "eived·4\x00\x00\x1f\x02:\x0fhchan·5\x00\x00\x01\x00\x00\t\x11newselect\x00\x06" +
-       "\x17\"\vsel·1\x00\x00\n\x13selsize·2\x00\x00\b\rsize·3\x00\x00\x00\t\x13s" +
-       "electsend\x00\x06\x17\"\vsel·2\x00\x00\x1f\x04:\xf4\x01\x00\x00\x17:\xf6\x01\x00\x00\x02\x00\x15se" +
-       "lected·1\x00\x00\t\x13selectrecv\x00\x06\x17\"\xac\x02\x00\x00\x1f\x02:\xf4\x01\x00\x00\x17:" +
-       "\xf6\x01\x00\x00\x02\x00\xae\x02\x00\x00\t\x15selectrecv2\x00\b\x17\"\xac\x02\x00\x00\x1f\x02:\xf4\x01\x00\x00\x17:" +
-       "\xf6\x01\x00\x00\x17\x00\x15received·5\x00\x00\x02\x00\xae\x02\x00\x00\t\x19selectdefaul" +
-       "t\x00\x02\x17\"\xac\x02\x00\x00\x02\x00\xae\x02\x00\x00\t\x0fselectgo\x00\x02\x17\"\xa4\x02\x00\x00\x00\t\tbloc" +
-       "k\x00\x00\x00\t\x11makeslice\x00\x06\x17\"\x06\x00\x00\x02\vlen·3\x00\x00\x02\vcap·4" +
-       "\x00\x00\x02\x11:\vary·1\x00\x00\t\x15makeslice64\x00\x06\x17\"\x06\x00\x00\n\xbe\x02\x00\x00\n" +
-       "\xc0\x02\x00\x00\x02\x11:\xc2\x02\x00\x00\t\x11growslice\x00\x06\x17\"\x06\x00\x00\x11:\vold·3\x00\x00" +
-       "\x02\xc0\x02\x00\x00\x02\x11:\xc2\x02\x00\x00\t\rmemmove\x00\x06\x17:\tto·1\x00\x00\x17:\vfrm\xc2" +
-       "\xb72\x00\x00\x16\x11length·3\x00^\x00\t\vmemclr\x00\x04\x17\"\vptr·1\x00\x00\x16" +
-       "\x11length·2\x00^\x00\t\x0fmemequal\x00\x06\x17:\ax·2\x00\x00\x17:\ay·" +
-       "3\x00\x00\x16\rsize·4\x00^\x01\x00\x00\t\x11memequal8\x00\x04\x17:\xda\x02\x00\x00\x17:\xdc\x02" +
-       "\x00\x00\x01\x00\x00\t\x13memequal16\x00\x04\x17:\xda\x02\x00\x00\x17:\xdc\x02\x00\x00\x01\x00\x00\t\x13meme" +
-       "qual32\x00\x04\x17:\xda\x02\x00\x00\x17:\xdc\x02\x00\x00\x01\x00\x00\t\x13memequal64\x00\x04\x17:\xda" +
-       "\x02\x00\x00\x17:\xdc\x02\x00\x00\x01\x00\x00\t\x15memequal128\x00\x04\x17:\xda\x02\x00\x00\x17:\xdc\x02\x00\x00\x01" +
-       "\x00\x00\t\x0fint64div\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64div\x00\x03\x14\x00\x14\x00\x01\x14" +
-       "\x00\t\x0fint64mod\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64mod\x00\x03\x14\x00\x14\x00\x01\x14\x00" +
-       "\t\x1bfloat64toint64\x00\x01\x1a\x00\x01\n\x00\t\x1dfloat64touint64" +
-       "\x00\x01\x1a\x00\x01\x14\x00\t\x1dfloat64touint32\x00\x01\x1a\x00\x01\x12\x00\t\x1bint64to" +
-       "float64\x00\x01\n\x00\x01\x1a\x00\t\x1duint64tofloat64\x00\x01\x14\x00\x01\x1a\x00\t\x1d" +
-       "uint32tofloat64\x00\x01\x12\x00\x01\x1a\x00\t\x19complex128div\x00\x04\x1e" +
-       "\vnum·2\x00\x00\x1e\vden·3\x00\x00\x02\x1e\vquo·1\x00\x00\t\x19racefunc" +
-       "enter\x00\x01\x16^\x00\t\x17racefuncexit\x00\x00\x00\t\x0fraceread\x00\x01\x16" +
-       "^\x00\t\x11racewrite\x00\x01\x16^\x00\t\x19racereadrange\x00\x04\x16\radd" +
-       "r·1\x00^\x16\rsize·2\x00^\x00\t\x1bracewriterange\x00\x04\x16\x90\x03\x00" +
-       "^\x16\x92\x03\x00^\x00\t\x0fmsanread\x00\x04\x16\x90\x03\x00^\x16\x92\x03\x00^\x00\t\x11msanwrit" +
-       "e\x00\x04\x16\x90\x03\x00^\x16\x92\x03\x00^\x00\v\xf6\x01\v\x00\x01\x00\n$$\n"
+var runtimeDecls = [...]struct {
+       name string
+       tag  int
+       typ  int
+}{
+       {"newobject", funcTag, 4},
+       {"panicindex", funcTag, 5},
+       {"panicslice", funcTag, 5},
+       {"panicdivide", funcTag, 5},
+       {"throwinit", funcTag, 5},
+       {"panicwrap", funcTag, 7},
+       {"gopanic", funcTag, 9},
+       {"gorecover", funcTag, 12},
+       {"printbool", funcTag, 14},
+       {"printfloat", funcTag, 16},
+       {"printint", funcTag, 18},
+       {"printhex", funcTag, 20},
+       {"printuint", funcTag, 20},
+       {"printcomplex", funcTag, 22},
+       {"printstring", funcTag, 23},
+       {"printpointer", funcTag, 24},
+       {"printiface", funcTag, 24},
+       {"printeface", funcTag, 24},
+       {"printslice", funcTag, 24},
+       {"printnl", funcTag, 5},
+       {"printsp", funcTag, 5},
+       {"printlock", funcTag, 5},
+       {"printunlock", funcTag, 5},
+       {"concatstring2", funcTag, 27},
+       {"concatstring3", funcTag, 28},
+       {"concatstring4", funcTag, 29},
+       {"concatstring5", funcTag, 30},
+       {"concatstrings", funcTag, 32},
+       {"cmpstring", funcTag, 34},
+       {"eqstring", funcTag, 35},
+       {"intstring", funcTag, 38},
+       {"slicebytetostring", funcTag, 40},
+       {"slicebytetostringtmp", funcTag, 41},
+       {"slicerunetostring", funcTag, 44},
+       {"stringtoslicebyte", funcTag, 45},
+       {"stringtoslicebytetmp", funcTag, 46},
+       {"stringtoslicerune", funcTag, 49},
+       {"decoderune", funcTag, 50},
+       {"slicecopy", funcTag, 52},
+       {"slicestringcopy", funcTag, 53},
+       {"convI2E", funcTag, 54},
+       {"convI2I", funcTag, 55},
+       {"convT2E", funcTag, 56},
+       {"convT2I", funcTag, 56},
+       {"assertE2E", funcTag, 57},
+       {"assertE2E2", funcTag, 58},
+       {"assertE2I", funcTag, 57},
+       {"assertE2I2", funcTag, 58},
+       {"assertE2T", funcTag, 57},
+       {"assertE2T2", funcTag, 58},
+       {"assertI2E", funcTag, 57},
+       {"assertI2E2", funcTag, 58},
+       {"assertI2I", funcTag, 57},
+       {"assertI2I2", funcTag, 58},
+       {"assertI2T", funcTag, 57},
+       {"assertI2T2", funcTag, 58},
+       {"panicdottype", funcTag, 59},
+       {"ifaceeq", funcTag, 60},
+       {"efaceeq", funcTag, 60},
+       {"makemap", funcTag, 62},
+       {"mapaccess1", funcTag, 63},
+       {"mapaccess1_fast32", funcTag, 64},
+       {"mapaccess1_fast64", funcTag, 64},
+       {"mapaccess1_faststr", funcTag, 64},
+       {"mapaccess1_fat", funcTag, 65},
+       {"mapaccess2", funcTag, 66},
+       {"mapaccess2_fast32", funcTag, 67},
+       {"mapaccess2_fast64", funcTag, 67},
+       {"mapaccess2_faststr", funcTag, 67},
+       {"mapaccess2_fat", funcTag, 68},
+       {"mapassign", funcTag, 63},
+       {"mapiterinit", funcTag, 69},
+       {"mapdelete", funcTag, 69},
+       {"mapiternext", funcTag, 70},
+       {"makechan", funcTag, 72},
+       {"chanrecv1", funcTag, 74},
+       {"chanrecv2", funcTag, 75},
+       {"chansend1", funcTag, 77},
+       {"closechan", funcTag, 24},
+       {"writeBarrier", varTag, 78},
+       {"writebarrierptr", funcTag, 79},
+       {"typedmemmove", funcTag, 80},
+       {"typedslicecopy", funcTag, 81},
+       {"selectnbsend", funcTag, 82},
+       {"selectnbrecv", funcTag, 83},
+       {"selectnbrecv2", funcTag, 85},
+       {"newselect", funcTag, 86},
+       {"selectsend", funcTag, 82},
+       {"selectrecv", funcTag, 75},
+       {"selectrecv2", funcTag, 87},
+       {"selectdefault", funcTag, 88},
+       {"selectgo", funcTag, 89},
+       {"block", funcTag, 5},
+       {"makeslice", funcTag, 91},
+       {"makeslice64", funcTag, 92},
+       {"growslice", funcTag, 93},
+       {"memmove", funcTag, 94},
+       {"memclr", funcTag, 95},
+       {"memequal", funcTag, 96},
+       {"memequal8", funcTag, 97},
+       {"memequal16", funcTag, 97},
+       {"memequal32", funcTag, 97},
+       {"memequal64", funcTag, 97},
+       {"memequal128", funcTag, 97},
+       {"int64div", funcTag, 98},
+       {"uint64div", funcTag, 99},
+       {"int64mod", funcTag, 98},
+       {"uint64mod", funcTag, 99},
+       {"float64toint64", funcTag, 100},
+       {"float64touint64", funcTag, 101},
+       {"float64touint32", funcTag, 103},
+       {"int64tofloat64", funcTag, 104},
+       {"uint64tofloat64", funcTag, 105},
+       {"uint32tofloat64", funcTag, 106},
+       {"complex128div", funcTag, 107},
+       {"racefuncenter", funcTag, 108},
+       {"racefuncexit", funcTag, 5},
+       {"raceread", funcTag, 108},
+       {"racewrite", funcTag, 108},
+       {"racereadrange", funcTag, 109},
+       {"racewriterange", funcTag, 109},
+       {"msanread", funcTag, 109},
+       {"msanwrite", funcTag, 109},
+}
+
+func runtimeTypes() []*Type {
+       var typs [110]*Type
+       typs[0] = bytetype
+       typs[1] = typPtr(typs[0])
+       typs[2] = Types[TANY]
+       typs[3] = typPtr(typs[2])
+       typs[4] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[3])})
+       typs[5] = functype(nil, nil, nil)
+       typs[6] = Types[TSTRING]
+       typs[7] = functype(nil, []*Node{anonfield(typs[6]), anonfield(typs[6]), anonfield(typs[6])}, nil)
+       typs[8] = Types[TINTER]
+       typs[9] = functype(nil, []*Node{anonfield(typs[8])}, nil)
+       typs[10] = Types[TINT32]
+       typs[11] = typPtr(typs[10])
+       typs[12] = functype(nil, []*Node{anonfield(typs[11])}, []*Node{anonfield(typs[8])})
+       typs[13] = Types[TBOOL]
+       typs[14] = functype(nil, []*Node{anonfield(typs[13])}, nil)
+       typs[15] = Types[TFLOAT64]
+       typs[16] = functype(nil, []*Node{anonfield(typs[15])}, nil)
+       typs[17] = Types[TINT64]
+       typs[18] = functype(nil, []*Node{anonfield(typs[17])}, nil)
+       typs[19] = Types[TUINT64]
+       typs[20] = functype(nil, []*Node{anonfield(typs[19])}, nil)
+       typs[21] = Types[TCOMPLEX128]
+       typs[22] = functype(nil, []*Node{anonfield(typs[21])}, nil)
+       typs[23] = functype(nil, []*Node{anonfield(typs[6])}, nil)
+       typs[24] = functype(nil, []*Node{anonfield(typs[2])}, nil)
+       typs[25] = typArray(typs[0], 32)
+       typs[26] = typPtr(typs[25])
+       typs[27] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[6]), anonfield(typs[6])}, []*Node{anonfield(typs[6])})
+       typs[28] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[6]), anonfield(typs[6]), anonfield(typs[6])}, []*Node{anonfield(typs[6])})
+       typs[29] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[6]), anonfield(typs[6]), anonfield(typs[6]), anonfield(typs[6])}, []*Node{anonfield(typs[6])})
+       typs[30] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[6]), anonfield(typs[6]), anonfield(typs[6]), anonfield(typs[6]), anonfield(typs[6])}, []*Node{anonfield(typs[6])})
+       typs[31] = typSlice(typs[6])
+       typs[32] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[31])}, []*Node{anonfield(typs[6])})
+       typs[33] = Types[TINT]
+       typs[34] = functype(nil, []*Node{anonfield(typs[6]), anonfield(typs[6])}, []*Node{anonfield(typs[33])})
+       typs[35] = functype(nil, []*Node{anonfield(typs[6]), anonfield(typs[6])}, []*Node{anonfield(typs[13])})
+       typs[36] = typArray(typs[0], 4)
+       typs[37] = typPtr(typs[36])
+       typs[38] = functype(nil, []*Node{anonfield(typs[37]), anonfield(typs[17])}, []*Node{anonfield(typs[6])})
+       typs[39] = typSlice(typs[0])
+       typs[40] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[39])}, []*Node{anonfield(typs[6])})
+       typs[41] = functype(nil, []*Node{anonfield(typs[39])}, []*Node{anonfield(typs[6])})
+       typs[42] = runetype
+       typs[43] = typSlice(typs[42])
+       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[46] = functype(nil, []*Node{anonfield(typs[6])}, []*Node{anonfield(typs[39])})
+       typs[47] = typArray(typs[42], 32)
+       typs[48] = typPtr(typs[47])
+       typs[49] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[6])}, []*Node{anonfield(typs[43])})
+       typs[50] = functype(nil, []*Node{anonfield(typs[6]), anonfield(typs[33])}, []*Node{anonfield(typs[42]), anonfield(typs[33])})
+       typs[51] = Types[TUINTPTR]
+       typs[52] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[51])}, []*Node{anonfield(typs[33])})
+       typs[53] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[33])})
+       typs[54] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[2])})
+       typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
+       typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
+       typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, nil)
+       typs[58] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
+       typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
+       typs[60] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[13])})
+       typs[61] = typMap(typs[2], typs[2])
+       typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[61])})
+       typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
+       typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
+       typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
+       typs[66] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[13])})
+       typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[13])})
+       typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[13])})
+       typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[61]), anonfield(typs[3])}, nil)
+       typs[70] = functype(nil, []*Node{anonfield(typs[3])}, nil)
+       typs[71] = typChan(typs[2], Cboth)
+       typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17])}, []*Node{anonfield(typs[71])})
+       typs[73] = typChan(typs[2], Crecv)
+       typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[73]), anonfield(typs[3])}, nil)
+       typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[73]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
+       typs[76] = typChan(typs[2], Csend)
+       typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[76]), anonfield(typs[3])}, nil)
+       typs[78] = tostruct([]*Node{namedfield("enabled", typs[13]), namedfield("needed", typs[13]), namedfield("cgo", typs[13])})
+       typs[79] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil)
+       typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
+       typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[33])})
+       typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[76]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
+       typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[73])}, []*Node{anonfield(typs[13])})
+       typs[84] = typPtr(typs[13])
+       typs[85] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[84]), anonfield(typs[73])}, []*Node{anonfield(typs[13])})
+       typs[86] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[10])}, nil)
+       typs[87] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[73]), anonfield(typs[3]), anonfield(typs[84])}, []*Node{anonfield(typs[13])})
+       typs[88] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[13])})
+       typs[89] = functype(nil, []*Node{anonfield(typs[1])}, nil)
+       typs[90] = typSlice(typs[2])
+       typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[33]), anonfield(typs[33])}, []*Node{anonfield(typs[90])})
+       typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[90])})
+       typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[90]), anonfield(typs[33])}, []*Node{anonfield(typs[90])})
+       typs[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[51])}, nil)
+       typs[95] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[51])}, nil)
+       typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[51])}, []*Node{anonfield(typs[13])})
+       typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
+       typs[98] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
+       typs[99] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
+       typs[100] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[17])})
+       typs[101] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[19])})
+       typs[102] = Types[TUINT32]
+       typs[103] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[102])})
+       typs[104] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[15])})
+       typs[105] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[15])})
+       typs[106] = functype(nil, []*Node{anonfield(typs[102])}, []*Node{anonfield(typs[15])})
+       typs[107] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
+       typs[108] = functype(nil, []*Node{anonfield(typs[51])}, nil)
+       typs[109] = functype(nil, []*Node{anonfield(typs[51]), anonfield(typs[51])}, nil)
+       return typs[:]
+}
index 70f3d3c6679f035d9acfab6684c87308b8aa9617..ad5c1b0ab77caa2b4231a74245a83a547c66fde8 100644 (file)
@@ -372,6 +372,14 @@ func typenod(t *Type) *Node {
        return t.nod
 }
 
+func anonfield(typ *Type) *Node {
+       return nod(ODCLFIELD, nil, typenod(typ))
+}
+
+func namedfield(s string, typ *Type) *Node {
+       return nod(ODCLFIELD, newname(lookup(s)), typenod(typ))
+}
+
 // oldname returns the Node that declares symbol s in the current scope.
 // If no such Node currently exists, an ONONAME Node is returned instead.
 func oldname(s *Sym) *Node {
index d66b5ee2d646068a22f2002b60cbfd760e44f928..b19319963ab94138d61c472ee9a90e29a68738fb 100644 (file)
@@ -673,9 +673,9 @@ func findpkg(name string) (file string, ok bool) {
        return "", false
 }
 
-// loadsys loads the definitions for the low-level runtime and unsafe functions,
+// loadsys loads the definitions for the low-level runtime functions,
 // so that the compiler can generate calls to them,
-// but does not make the names "runtime" or "unsafe" visible as packages.
+// but does not make them visible to user code.
 func loadsys() {
        if Debug['A'] != 0 {
                return
@@ -685,7 +685,28 @@ func loadsys() {
        iota_ = -1000000
 
        importpkg = Runtimepkg
-       Import(bufio.NewReader(strings.NewReader(runtimeimport)))
+       typecheckok = true
+       defercheckwidth()
+
+       typs := runtimeTypes()
+       for _, d := range runtimeDecls {
+               sym := Pkglookup(d.name, importpkg)
+               typ := typs[d.typ]
+               switch d.tag {
+               case funcTag:
+                       importsym(sym, ONAME)
+                       n := newfuncname(sym)
+                       n.Type = typ
+                       declare(n, PFUNC)
+               case varTag:
+                       importvar(sym, typ)
+               default:
+                       Fatalf("unhandled declaration tag %v", d.tag)
+               }
+       }
+
+       typecheckok = false
+       resumecheckwidth()
        importpkg = nil
 }
 
index 0a54b837e4f8f418fbab642ade7c41011738b883..995f5be1df1e3c8dc5963615edf7cbce0329f25b 100644 (file)
@@ -1,25 +1,28 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2016 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 ignore
 
 // Generate builtin.go from builtin/runtime.go.
-// Run this after changing builtin/runtime.go
-// or after changing the export metadata format in the compiler.
-// Either way, you need to have a working compiler binary first.
-// See bexport.go for how to make an export metadata format change.
+
 package main
 
 import (
        "bytes"
        "flag"
        "fmt"
+       "go/ast"
+       "go/format"
+       "go/parser"
+       "go/token"
        "io"
        "io/ioutil"
        "log"
        "os"
-       "os/exec"
+       "path/filepath"
+       "strconv"
+       "strings"
 )
 
 var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")
@@ -29,65 +32,181 @@ func main() {
 
        var b bytes.Buffer
        fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
-       fmt.Fprintln(&b, "")
+       fmt.Fprintln(&b)
        fmt.Fprintln(&b, "package gc")
 
        mkbuiltin(&b, "runtime")
 
-       var err error
+       out, err := format.Source(b.Bytes())
+       if err != nil {
+               log.Fatal(err)
+       }
        if *stdout {
-               _, err = os.Stdout.Write(b.Bytes())
+               _, err = os.Stdout.Write(out)
        } else {
-               err = ioutil.WriteFile("builtin.go", b.Bytes(), 0666)
+               err = ioutil.WriteFile("builtin.go", out, 0666)
        }
        if err != nil {
                log.Fatal(err)
        }
 }
 
-// Compile .go file, import data from .o file, and write Go string version.
 func mkbuiltin(w io.Writer, name string) {
-       args := []string{"tool", "compile", "-A"}
-       if name == "runtime" {
-               args = append(args, "-u")
+       fset := token.NewFileSet()
+       f, err := parser.ParseFile(fset, filepath.Join("builtin", name+".go"), nil, 0)
+       if err != nil {
+               log.Fatal(err)
        }
-       args = append(args, "builtin/"+name+".go")
 
-       if err := exec.Command("go", args...).Run(); err != nil {
-               log.Fatal(err)
+       var interner typeInterner
+
+       fmt.Fprintf(w, "var %sDecls = [...]struct { name string; tag int; typ int }{\n", name)
+       for _, decl := range f.Decls {
+               switch decl := decl.(type) {
+               case *ast.FuncDecl:
+                       if decl.Recv != nil {
+                               log.Fatal("methods unsupported")
+                       }
+                       if decl.Body != nil {
+                               log.Fatal("unexpected function body")
+                       }
+                       fmt.Fprintf(w, "{%q, funcTag, %d},\n", decl.Name.Name, interner.intern(decl.Type))
+               case *ast.GenDecl:
+                       if decl.Tok != token.VAR {
+                               log.Fatal("unhandled declaration kind", decl.Tok)
+                       }
+                       for _, spec := range decl.Specs {
+                               spec := spec.(*ast.ValueSpec)
+                               if len(spec.Values) != 0 {
+                                       log.Fatal("unexpected values")
+                               }
+                               typ := interner.intern(spec.Type)
+                               for _, name := range spec.Names {
+                                       fmt.Fprintf(w, "{%q, varTag, %d},\n", name.Name, typ)
+                               }
+                       }
+               default:
+                       log.Fatal("unhandled decl type", decl)
+               }
        }
-       obj := name + ".o"
-       defer os.Remove(obj)
+       fmt.Fprintln(w, "}")
 
-       b, err := ioutil.ReadFile(obj)
-       if err != nil {
-               log.Fatal(err)
+       fmt.Fprintln(w)
+       fmt.Fprintf(w, "func %sTypes() []*Type {\n", name)
+       fmt.Fprintf(w, "var typs [%d]*Type\n", len(interner.typs))
+       for i, typ := range interner.typs {
+               fmt.Fprintf(w, "typs[%d] = %s\n", i, typ)
+       }
+       fmt.Fprintln(w, "return typs[:]")
+       fmt.Fprintln(w, "}")
+}
+
+// typeInterner maps Go type expressions to compiler code that
+// constructs the denoted type. It recognizes and reuses common
+// subtype expressions.
+type typeInterner struct {
+       typs []string
+       hash map[string]int
+}
+
+func (i *typeInterner) intern(t ast.Expr) int {
+       x := i.mktype(t)
+       v, ok := i.hash[x]
+       if !ok {
+               v = len(i.typs)
+               if i.hash == nil {
+                       i.hash = make(map[string]int)
+               }
+               i.hash[x] = v
+               i.typs = append(i.typs, x)
        }
+       return v
+}
+
+func (i *typeInterner) subtype(t ast.Expr) string {
+       return fmt.Sprintf("typs[%d]", i.intern(t))
+}
+
+func (i *typeInterner) mktype(t ast.Expr) string {
+       switch t := t.(type) {
+       case *ast.Ident:
+               switch t.Name {
+               case "byte":
+                       return "bytetype"
+               case "rune":
+                       return "runetype"
+               }
+               return fmt.Sprintf("Types[T%s]", strings.ToUpper(t.Name))
+
+       case *ast.ArrayType:
+               if t.Len == nil {
+                       return fmt.Sprintf("typSlice(%s)", i.subtype(t.Elt))
+               }
+               return fmt.Sprintf("typArray(%s, %d)", i.subtype(t.Elt), intconst(t.Len))
+       case *ast.ChanType:
+               dir := "Cboth"
+               switch t.Dir {
+               case ast.SEND:
+                       dir = "Csend"
+               case ast.RECV:
+                       dir = "Crecv"
+               }
+               return fmt.Sprintf("typChan(%s, %s)", i.subtype(t.Value), dir)
+       case *ast.FuncType:
+               return fmt.Sprintf("functype(nil, %s, %s)", i.fields(t.Params, false), i.fields(t.Results, false))
+       case *ast.InterfaceType:
+               if len(t.Methods.List) != 0 {
+                       log.Fatal("non-empty interfaces unsupported")
+               }
+               return "Types[TINTER]"
+       case *ast.MapType:
+               return fmt.Sprintf("typMap(%s, %s)", i.subtype(t.Key), i.subtype(t.Value))
+       case *ast.StarExpr:
+               return fmt.Sprintf("typPtr(%s)", i.subtype(t.X))
+       case *ast.StructType:
+               return fmt.Sprintf("tostruct(%s)", i.fields(t.Fields, true))
 
-       // Look for $$B that introduces binary export data.
-       i := bytes.Index(b, []byte("\n$$B\n"))
-       if i < 0 {
-               log.Fatal("did not find beginning of export data")
+       default:
+               log.Fatalf("unhandled type: %#v", t)
+               panic("unreachable")
        }
-       b = b[i+5:]
+}
 
-       // Look for $$ that closes export data.
-       i = bytes.Index(b, []byte("\n$$\n"))
-       if i < 0 {
-               log.Fatal("did not find end of export data")
+func (i *typeInterner) fields(fl *ast.FieldList, keepNames bool) string {
+       if fl == nil || len(fl.List) == 0 {
+               return "nil"
+       }
+       var res []string
+       for _, f := range fl.List {
+               typ := i.subtype(f.Type)
+               if len(f.Names) == 0 {
+                       res = append(res, fmt.Sprintf("anonfield(%s)", typ))
+               } else {
+                       for _, name := range f.Names {
+                               if keepNames {
+                                       res = append(res, fmt.Sprintf("namedfield(%q, %s)", name.Name, typ))
+                               } else {
+                                       res = append(res, fmt.Sprintf("anonfield(%s)", typ))
+                               }
+                       }
+               }
        }
-       b = b[:i+4]
-
-       // Process and reformat export data.
-       const n = 40 // number of bytes per line
-       fmt.Fprintf(w, "\nconst %simport = \"\"", name)
-       for len(b) > 0 {
-               i := len(b)
-               if i > n {
-                       i = n
+       return fmt.Sprintf("[]*Node{%s}", strings.Join(res, ", "))
+}
+
+func intconst(e ast.Expr) int64 {
+       switch e := e.(type) {
+       case *ast.BasicLit:
+               if e.Kind != token.INT {
+                       log.Fatalf("expected INT, got %v", e.Kind)
+               }
+               x, err := strconv.ParseInt(e.Value, 0, 64)
+               if err != nil {
+                       log.Fatal(err)
                }
-               fmt.Fprintf(w, " +\n\t%q", b[:i])
-               b = b[i:]
+               return x
+       default:
+               log.Fatalf("unhandled expr: %#v", e)
+               panic("unreachable")
        }
-       fmt.Fprintf(w, "\n")
 }