[dev.cc] cmd/internal/gc, cmd/new6g etc: convert from cmd/gc, cmd/6g etc
First draft of converted Go compiler, using rsc.io/c2go rev 83d795a.
Change-Id: I29f4c7010de07d2ff1947bbca9865879d83c32c3
Reviewed-on: https://go-review.googlesource.com/4851
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/src/cmd/internal/gc/init.go b/src/cmd/internal/gc/init.go
new file mode 100644
index 0000000..e738dba
--- /dev/null
+++ b/src/cmd/internal/gc/init.go
@@ -0,0 +1,232 @@
+// Copyright 2009 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.
+
+package gc
+
+import "fmt"
+
+// case OADD:
+// if(n->right->op == OLITERAL) {
+// v = n->right->vconst;
+// naddr(n->left, a, canemitcode);
+// } else
+// if(n->left->op == OLITERAL) {
+// v = n->left->vconst;
+// naddr(n->right, a, canemitcode);
+// } else
+// goto bad;
+// a->offset += v;
+// break;
+
+/*
+ * a function named init is a special case.
+ * it is called by the initialization before
+ * main is run. to make it unique within a
+ * package and also uncallable, the name,
+ * normally "pkg.init", is altered to "pkg.init·1".
+ */
+
+var renameinit_initgen int
+
+func renameinit() *Sym {
+ renameinit_initgen++
+ namebuf = fmt.Sprintf("init·%d", renameinit_initgen)
+ return Lookup(namebuf)
+}
+
+/*
+ * hand-craft the following initialization code
+ * var initdone· uint8 (1)
+ * func init() (2)
+ * if initdone· != 0 { (3)
+ * if initdone· == 2 (4)
+ * return
+ * throw(); (5)
+ * }
+ * initdone· = 1; (6)
+ * // over all matching imported symbols
+ * <pkg>.init() (7)
+ * { <init stmts> } (8)
+ * init·<n>() // if any (9)
+ * initdone· = 2; (10)
+ * return (11)
+ * }
+ */
+func anyinit(n *NodeList) int {
+ var h uint32
+ var s *Sym
+ var l *NodeList
+
+ // are there any interesting init statements
+ for l = n; l != nil; l = l.Next {
+ switch l.N.Op {
+ case ODCLFUNC,
+ ODCLCONST,
+ ODCLTYPE,
+ OEMPTY:
+ break
+
+ case OAS:
+ if isblank(l.N.Left) && candiscard(l.N.Right) != 0 {
+ break
+ }
+ fallthrough
+
+ // fall through
+ default:
+ return 1
+ }
+ }
+
+ // is this main
+ if localpkg.Name == "main" {
+ return 1
+ }
+
+ // is there an explicit init function
+ namebuf = fmt.Sprintf("init·1")
+
+ s = Lookup(namebuf)
+ if s.Def != nil {
+ return 1
+ }
+
+ // are there any imported init functions
+ for h = 0; h < NHASH; h++ {
+ for s = hash[h]; s != nil; s = s.Link {
+ if s.Name[0] != 'i' || s.Name != "init" {
+ continue
+ }
+ if s.Def == nil {
+ continue
+ }
+ return 1
+ }
+ }
+
+ // then none
+ return 0
+}
+
+func fninit(n *NodeList) {
+ var i int
+ var gatevar *Node
+ var a *Node
+ var b *Node
+ var fn *Node
+ var r *NodeList
+ var h uint32
+ var s *Sym
+ var initsym *Sym
+
+ if Debug['A'] != 0 {
+ // sys.go or unsafe.go during compiler build
+ return
+ }
+
+ n = initfix(n)
+ if !(anyinit(n) != 0) {
+ return
+ }
+
+ r = nil
+
+ // (1)
+ namebuf = fmt.Sprintf("initdone·")
+
+ gatevar = newname(Lookup(namebuf))
+ addvar(gatevar, Types[TUINT8], PEXTERN)
+
+ // (2)
+ Maxarg = 0
+
+ namebuf = fmt.Sprintf("init")
+
+ fn = Nod(ODCLFUNC, nil, nil)
+ initsym = Lookup(namebuf)
+ fn.Nname = newname(initsym)
+ fn.Nname.Defn = fn
+ fn.Nname.Ntype = Nod(OTFUNC, nil, nil)
+ declare(fn.Nname, PFUNC)
+ funchdr(fn)
+
+ // (3)
+ a = Nod(OIF, nil, nil)
+
+ a.Ntest = Nod(ONE, gatevar, Nodintconst(0))
+ r = list(r, a)
+
+ // (4)
+ b = Nod(OIF, nil, nil)
+
+ b.Ntest = Nod(OEQ, gatevar, Nodintconst(2))
+ b.Nbody = list1(Nod(ORETURN, nil, nil))
+ a.Nbody = list1(b)
+
+ // (5)
+ b = syslook("throwinit", 0)
+
+ b = Nod(OCALL, b, nil)
+ a.Nbody = list(a.Nbody, b)
+
+ // (6)
+ a = Nod(OAS, gatevar, Nodintconst(1))
+
+ r = list(r, a)
+
+ // (7)
+ for h = 0; h < NHASH; h++ {
+ for s = hash[h]; s != nil; s = s.Link {
+ if s.Name[0] != 'i' || s.Name != "init" {
+ continue
+ }
+ if s.Def == nil {
+ continue
+ }
+ if s == initsym {
+ continue
+ }
+
+ // could check that it is fn of no args/returns
+ a = Nod(OCALL, s.Def, nil)
+
+ r = list(r, a)
+ }
+ }
+
+ // (8)
+ r = concat(r, n)
+
+ // (9)
+ // could check that it is fn of no args/returns
+ for i = 1; ; i++ {
+ namebuf = fmt.Sprintf("init·%d", i)
+ s = Lookup(namebuf)
+ if s.Def == nil {
+ break
+ }
+ a = Nod(OCALL, s.Def, nil)
+ r = list(r, a)
+ }
+
+ // (10)
+ a = Nod(OAS, gatevar, Nodintconst(2))
+
+ r = list(r, a)
+
+ // (11)
+ a = Nod(ORETURN, nil, nil)
+
+ r = list(r, a)
+ exportsym(fn.Nname)
+
+ fn.Nbody = r
+ funcbody(fn)
+
+ Curfn = fn
+ typecheck(&fn, Etop)
+ typechecklist(r, Etop)
+ Curfn = nil
+ funccompile(fn)
+}