mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[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>
119 lines
3.5 KiB
Go
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
|
|
}
|