go/src/cmd/compile/internal/gc/init.go
Russ Cox 527a1895d6 [dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
	# Inline a few little-used constructors to avoid bringing them.
	ex {
		import "cmd/compile/internal/base"
		import "cmd/compile/internal/ir"
		import "cmd/compile/internal/types"
		import "cmd/internal/src"

		var typ *types.Type
		var sym *types.Sym
		var str string
		symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
		anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
		namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)

		var cp *ir.CallPartExpr
		callpartMethod(cp) -> cp.Method
		var n ir.Node
		callpartMethod(n) -> n.(*ir.CallPartExpr).Method

		var ns []ir.Node
		liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
	}
	rm symfield anonfield namedfield liststmt callpartMethod

	mv maxStackVarSize MaxStackVarSize
	mv maxImplicitStackVarSize MaxImplicitStackVarSize
	mv smallArrayBytes MaxSmallArraySize
	mv MaxStackVarSize cfg.go

	mv nodbool NewBool
	mv nodintconst NewInt
	mv nodstr NewString
	mv NewBool NewInt NewString const.go

	mv Mpprec ConstPrec
	mv bigFloatVal BigFloat
	mv doesoverflow ConstOverflow
	mv isGoConst IsConstNode
	mv smallintconst IsSmallIntConst

	mv isZero IsZero
	mv islvalue IsAssignable
	mv staticValue StaticValue
	mv samesafeexpr SameSafeExpr
	mv checkPtr ShouldCheckPtr
	mv isReflectHeaderDataField IsReflectHeaderDataField
	mv paramNnames ParamNames
	mv methodSym MethodSym
	mv methodSymSuffix MethodSymSuffix
	mv methodExprFunc MethodExprFunc
	mv methodExprName MethodExprName
	mv IsZero IsAssignable StaticValue staticValue1 reassigned \
		IsIntrinsicCall \
		SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
		ParamNames MethodSym MethodSymSuffix \
		MethodExprName MethodExprFunc \
		expr.go

	mv Curfn CurFunc
	mv funcsymname FuncSymName
	mv newFuncNameAt NewFuncNameAt
	mv setNodeNameFunc MarkFunc
	mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go

	mv isParamStackCopy IsParamStackCopy
	mv isParamHeapCopy IsParamHeapCopy
	mv nodfp RegFP
	mv IsParamStackCopy IsParamHeapCopy RegFP name.go

	mv hasUniquePos HasUniquePos
	mv setlineno SetPos
	mv initExpr InitExpr
	mv hasNamedResults HasNamedResults
	mv outervalue OuterValue
	mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go

	mv visitBottomUp VisitFuncsBottomUp # scc.go

	mv cfg.go \
		NewBool NewInt NewString \ # parts of const.go
		ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
		expr.go func.go name.go node.go scc.go \
		cmd/compile/internal/ir

'

Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 06:38:14 +00:00

119 lines
3.5 KiB
Go

// 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/base"
"cmd/compile/internal/ir"
"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
// Function collecting autotmps generated during typechecking,
// to be included in the package-level init function.
var initTodo = ir.NewFunc(base.Pos)
func renameinit() *types.Sym {
s := lookupN("init.", renameinitgen)
renameinitgen++
return s
}
// fninit makes and returns 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() *ir.Name {
nf := initOrder(Target.Decls)
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 _, pkg := range Target.Imports {
n := resolve(ir.NewIdent(base.Pos, pkg.Lookup(".inittask")))
if n.Op() == ir.ONONAME {
continue
}
if n.Op() != ir.ONAME || n.(*ir.Name).Class_ != ir.PEXTERN {
base.Fatalf("bad inittask: %v", n)
}
deps = append(deps, n.(*ir.Name).Sym().Linksym())
}
// Make a function that contains all the initialization statements.
if len(nf) > 0 {
base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt
initializers := lookup("init")
fn := dclfunc(initializers, ir.NewFuncType(base.Pos, nil, nil, nil))
for _, dcl := range initTodo.Dcl {
dcl.Curfn = fn
}
fn.Dcl = append(fn.Dcl, initTodo.Dcl...)
initTodo.Dcl = nil
fn.Body.Set(nf)
funcbody()
typecheckFunc(fn)
ir.CurFunc = fn
typecheckslice(nf, ctxStmt)
ir.CurFunc = nil
Target.Decls = append(Target.Decls, fn)
fns = append(fns, initializers.Linksym())
}
if initTodo.Dcl != nil {
// We only generate temps using initTodo if there
// are package-scope initialization statements, so
// something's weird if we get here.
base.Fatalf("initTodo still has declarations")
}
initTodo = nil
// Record user init functions.
for _, fn := range Target.Inits {
// Skip init functions with empty bodies.
if len(fn.Body) == 1 {
if stmt := fn.Body[0]; stmt.Op() == ir.OBLOCK && len(stmt.(*ir.BlockStmt).List) == 0 {
continue
}
}
fns = append(fns, fn.Nname.Sym().Linksym())
}
if len(deps) == 0 && len(fns) == 0 && types.LocalPkg.Name != "main" && types.LocalPkg.Name != "runtime" {
return nil // nothing to initialize
}
// Make an .inittask structure.
sym := lookup(".inittask")
task := NewName(sym)
task.SetType(types.Types[types.TUINT8]) // fake type
task.Class_ = ir.PEXTERN
sym.Def = task
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)
return task
}