...

Source file src/pkg/cmd/compile/internal/gc/init.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package gc
     6	
     7	import (
     8		"cmd/compile/internal/types"
     9		"cmd/internal/obj"
    10	)
    11	
    12	// A function named init is a special case.
    13	// It is called by the initialization before main is run.
    14	// To make it unique within a package and also uncallable,
    15	// the name, normally "pkg.init", is altered to "pkg.init.0".
    16	var renameinitgen int
    17	
    18	// Dummy function for autotmps generated during typechecking.
    19	var dummyInitFn = nod(ODCLFUNC, nil, nil)
    20	
    21	func renameinit() *types.Sym {
    22		s := lookupN("init.", renameinitgen)
    23		renameinitgen++
    24		return s
    25	}
    26	
    27	// fninit makes an initialization record for the package.
    28	// See runtime/proc.go:initTask for its layout.
    29	// The 3 tasks for initialization are:
    30	//   1) Initialize all of the packages the current package depends on.
    31	//   2) Initialize all the variables that have initializers.
    32	//   3) Run any init functions.
    33	func fninit(n []*Node) {
    34		nf := initOrder(n)
    35	
    36		var deps []*obj.LSym // initTask records for packages the current package depends on
    37		var fns []*obj.LSym  // functions to call for package initialization
    38	
    39		// Find imported packages with init tasks.
    40		for _, s := range types.InitSyms {
    41			deps = append(deps, s.Linksym())
    42		}
    43	
    44		// Make a function that contains all the initialization statements.
    45		if len(nf) > 0 {
    46			lineno = nf[0].Pos // prolog/epilog gets line number of first init stmt
    47			initializers := lookup("init")
    48			disableExport(initializers)
    49			fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
    50			for _, dcl := range dummyInitFn.Func.Dcl {
    51				dcl.Name.Curfn = fn
    52			}
    53			fn.Func.Dcl = append(fn.Func.Dcl, dummyInitFn.Func.Dcl...)
    54			dummyInitFn.Func.Dcl = nil
    55	
    56			fn.Nbody.Set(nf)
    57			funcbody()
    58	
    59			fn = typecheck(fn, ctxStmt)
    60			Curfn = fn
    61			typecheckslice(nf, ctxStmt)
    62			Curfn = nil
    63			funccompile(fn)
    64			fns = append(fns, initializers.Linksym())
    65		}
    66		if dummyInitFn.Func.Dcl != nil {
    67			// We only generate temps using dummyInitFn if there
    68			// are package-scope initialization statements, so
    69			// something's weird if we get here.
    70			Fatalf("dummyInitFn still has declarations")
    71		}
    72	
    73		// Record user init functions.
    74		for i := 0; i < renameinitgen; i++ {
    75			s := lookupN("init.", i)
    76			fns = append(fns, s.Linksym())
    77		}
    78	
    79		if len(deps) == 0 && len(fns) == 0 && localpkg.Name != "main" && localpkg.Name != "runtime" {
    80			return // nothing to initialize
    81		}
    82	
    83		// Make an .inittask structure.
    84		sym := lookup(".inittask")
    85		nn := newname(sym)
    86		nn.Type = types.Types[TUINT8] // dummy type
    87		nn.SetClass(PEXTERN)
    88		sym.Def = asTypesNode(nn)
    89		exportsym(nn)
    90		lsym := sym.Linksym()
    91		ot := 0
    92		ot = duintptr(lsym, ot, 0) // state: not initialized yet
    93		ot = duintptr(lsym, ot, uint64(len(deps)))
    94		ot = duintptr(lsym, ot, uint64(len(fns)))
    95		for _, d := range deps {
    96			ot = dsymptr(lsym, ot, d, 0)
    97		}
    98		for _, f := range fns {
    99			ot = dsymptr(lsym, ot, f, 0)
   100		}
   101		// An initTask has pointers, but none into the Go heap.
   102		// It's not quite read only, the state field must be modifiable.
   103		ggloblsym(lsym, int32(ot), obj.NOPTR)
   104	}
   105	
   106	func (n *Node) checkInitFuncSignature() {
   107		if n.Type.NumRecvs()+n.Type.NumParams()+n.Type.NumResults() > 0 {
   108			Fatalf("init function cannot have receiver, params, or results: %v (%v)", n, n.Type)
   109		}
   110	}
   111	

View as plain text