// 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 (
	"cmd/compile/internal/types"
	"cmd/internal/obj"
)

// 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.0".
var renameinitgen int

// Dummy function for autotmps generated during typechecking.
var dummyInitFn = nod(ODCLFUNC, nil, nil)

func renameinit() *types.Sym {
	s := lookupN("init.", renameinitgen)
	renameinitgen++
	return s
}

// fninit makes an initialization record for the package.
// See runtime/proc.go:initTask for its layout.
// The 3 tasks for initialization are:
//   1) Initialize all of the packages the current package depends on.
//   2) Initialize all the variables that have initializers.
//   3) Run any init functions.
func fninit(n []*Node) {
	nf := initfix(n)

	var deps []*obj.LSym // initTask records for packages the current package depends on
	var fns []*obj.LSym  // functions to call for package initialization

	// Find imported packages with init tasks.
	for _, s := range types.InitSyms {
		deps = append(deps, s.Linksym())
	}

	// Make a function that contains all the initialization statements.
	if len(nf) > 0 {
		lineno = nf[0].Pos // prolog/epilog gets line number of first init stmt
		initializers := lookup("init")
		disableExport(initializers)
		fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
		for _, dcl := range dummyInitFn.Func.Dcl {
			dcl.Name.Curfn = fn
		}
		fn.Func.Dcl = append(fn.Func.Dcl, dummyInitFn.Func.Dcl...)
		dummyInitFn.Func.Dcl = nil

		fn.Nbody.Set(nf)
		funcbody()

		fn = typecheck(fn, ctxStmt)
		Curfn = fn
		typecheckslice(nf, ctxStmt)
		Curfn = nil
		funccompile(fn)
		fns = append(fns, initializers.Linksym())
	}
	if dummyInitFn.Func.Dcl != nil {
		// We only generate temps using dummyInitFn if there
		// are package-scope initialization statements, so
		// something's weird if we get here.
		Fatalf("dummyInitFn still has declarations")
	}

	// Record user init functions.
	for i := 0; i < renameinitgen; i++ {
		s := lookupN("init.", i)
		fns = append(fns, s.Linksym())
	}

	if len(deps) == 0 && len(fns) == 0 && localpkg.Name != "main" && localpkg.Name != "runtime" {
		return // nothing to initialize
	}

	// Make an .inittask structure.
	sym := lookup(".inittask")
	nn := newname(sym)
	nn.Type = types.Types[TUINT8] // dummy type
	nn.SetClass(PEXTERN)
	sym.Def = asTypesNode(nn)
	exportsym(nn)
	lsym := sym.Linksym()
	ot := 0
	ot = duintptr(lsym, ot, 0) // state: not initialized yet
	ot = duintptr(lsym, ot, uint64(len(deps)))
	ot = duintptr(lsym, ot, uint64(len(fns)))
	for _, d := range deps {
		ot = dsymptr(lsym, ot, d, 0)
	}
	for _, f := range fns {
		ot = dsymptr(lsym, ot, f, 0)
	}
	// An initTask has pointers, but none into the Go heap.
	// It's not quite read only, the state field must be modifiable.
	ggloblsym(lsym, int32(ot), obj.NOPTR)
}

func (n *Node) checkInitFuncSignature() {
	if n.Type.NumRecvs()+n.Type.NumParams()+n.Type.NumResults() > 0 {
		Fatalf("init function cannot have receiver, params, or results: %v (%v)", n, n.Type)
	}
}
