本文整理汇总了Golang中code/google/com/p/go/tools/go/ssa.Function.Pos方法的典型用法代码示例。如果您正苦于以下问题:Golang Function.Pos方法的具体用法?Golang Function.Pos怎么用?Golang Function.Pos使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类code/google/com/p/go/tools/go/ssa.Function
的用法示例。
在下文中一共展示了Function.Pos方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: callSSA
// callSSA interprets a call to function fn with arguments args,
// and lexical environment env, returning its result.
// callpos is the position of the callsite.
//
func callSSA(i *interpreter, caller *frame, callpos token.Pos, fn *ssa.Function, args []value, env []value) value {
if i.mode&EnableTracing != 0 {
fset := fn.Prog.Fset
// TODO(adonovan): fix: loc() lies for external functions.
fmt.Fprintf(os.Stderr, "Entering %s%s.\n", fn, loc(fset, fn.Pos()))
suffix := ""
if caller != nil {
suffix = ", resuming " + caller.fn.String() + loc(fset, callpos)
}
defer fmt.Fprintf(os.Stderr, "Leaving %s%s.\n", fn, suffix)
}
fr := &frame{
i: i,
caller: caller, // for panic/recover
fn: fn,
}
if fn.Enclosing == nil {
name := fn.String()
if ext := externals[name]; ext != nil {
if i.mode&EnableTracing != 0 {
fmt.Fprintln(os.Stderr, "\t(external)")
}
return ext(fr, args)
}
if fn.Blocks == nil {
panic("no code for function: " + name)
}
}
fr.env = make(map[ssa.Value]value)
fr.block = fn.Blocks[0]
fr.locals = make([]value, len(fn.Locals))
for i, l := range fn.Locals {
fr.locals[i] = zero(deref(l.Type()))
fr.env[l] = &fr.locals[i]
}
for i, p := range fn.Params {
fr.env[p] = args[i]
}
for i, fv := range fn.FreeVars {
fr.env[fv] = env[i]
}
for fr.block != nil {
runFrame(fr)
}
// Destroy the locals to avoid accidental use after return.
for i := range fn.Locals {
fr.locals[i] = bad{}
}
return fr.result
}
示例2: emitFuncStart
// Emit the start of a function.
func emitFuncStart(fn *ssa.Function, trackPhi bool, canOptMap map[string]bool) {
posStr := CodePosition(fn.Pos())
pName := "unknown" // TODO review why this code appears to duplicate that at the start of emitFunctions()
if fn.Pkg != nil {
if fn.Pkg.Object != nil {
pName = fn.Pkg.Object.Name()
}
}
mName := fn.Name()
if fn.Signature.Recv() != nil { // we have a method
pName = fn.Signature.Recv().Type().String() // note no underlying()
}
isPublic := unicode.IsUpper(rune(mName[0])) // TODO check rules for non-ASCII 1st characters and fix
l := TargetLang
fmt.Fprintln(&LanguageList[l].buffer,
LanguageList[l].FuncStart(pName, mName, fn, posStr, isPublic, trackPhi, canOptMap))
}
示例3: defineFunction
func (u *unit) defineFunction(f *ssa.Function) {
// Nothing to do for functions without bodies.
if len(f.Blocks) == 0 {
return
}
// Only define functions from this package.
if f.Pkg == nil {
if r := f.Signature.Recv(); r != nil {
if r.Pkg() != nil && r.Pkg() != u.pkg.Object {
return
} else if named, ok := r.Type().(*types.Named); ok && named.Obj().Parent() == types.Universe {
// This condition is true iff f is error.Error.
if u.pkg.Object.Path() != "runtime" {
return
}
}
}
} else if f.Pkg != u.pkg {
return
}
fr := frame{
unit: u,
blocks: make([]llvm.BasicBlock, len(f.Blocks)),
env: make(map[ssa.Value]*LLVMValue),
}
fr.logf("Define function: %s", f.String())
llvmFunction := fr.resolveFunction(f).LLVMValue()
delete(u.undefinedFuncs, f)
// Push the function onto the debug context.
// TODO(axw) create a fake CU for synthetic functions
if u.GenerateDebug && f.Synthetic == "" {
u.debug.pushFunctionContext(llvmFunction, f.Signature, f.Pos())
defer u.debug.popFunctionContext()
u.debug.setLocation(u.builder, f.Pos())
}
// Functions that call recover must not be inlined, or we
// can't tell whether the recover call is valid at runtime.
if f.Recover != nil {
llvmFunction.AddFunctionAttr(llvm.NoInlineAttribute)
}
for i, block := range f.Blocks {
fr.blocks[i] = llvm.AddBasicBlock(llvmFunction, fmt.Sprintf(".%d.%s", i, block.Comment))
}
fr.builder.SetInsertPointAtEnd(fr.blocks[0])
var paramOffset int
if len(f.FreeVars) > 0 {
// Extract captures from the first implicit parameter.
arg0 := llvmFunction.Param(0)
for i, fv := range f.FreeVars {
addressPtr := fr.builder.CreateStructGEP(arg0, i, "")
address := fr.builder.CreateLoad(addressPtr, "")
fr.env[fv] = fr.NewValue(address, fv.Type())
}
paramOffset++
}
// Map parameter positions to indices. We use this
// when processing locals to map back to parameters
// when generating debug metadata.
paramPos := make(map[token.Pos]int)
for i, param := range f.Params {
paramPos[param.Pos()] = i + paramOffset
llparam := llvmFunction.Param(i + paramOffset)
fr.env[param] = fr.NewValue(llparam, param.Type())
}
// Allocate stack space for locals in the prologue block.
prologueBlock := llvm.InsertBasicBlock(fr.blocks[0], "prologue")
fr.builder.SetInsertPointAtEnd(prologueBlock)
for _, local := range f.Locals {
typ := fr.llvmtypes.ToLLVM(deref(local.Type()))
alloca := fr.builder.CreateAlloca(typ, local.Comment)
u.memsetZero(alloca, llvm.SizeOf(typ))
value := fr.NewValue(alloca, local.Type())
fr.env[local] = value
if fr.GenerateDebug {
paramIndex, ok := paramPos[local.Pos()]
if !ok {
paramIndex = -1
}
fr.debug.declare(fr.builder, local, alloca, paramIndex)
}
}
// Move any allocs relating to named results from the entry block
// to the prologue block, so they dominate the rundefers and recover
// blocks.
//
// TODO(axw) ask adonovan for a cleaner way of doing this, e.g.
// have ssa generate an entry block that defines Allocs and related
// stores, and then a separate block for function body instructions.
if f.Synthetic == "" {
if results := f.Signature.Results(); results != nil {
for i := 0; i < results.Len(); i++ {
//.........这里部分代码省略.........
示例4: emitFunc
// Emit a particular function.
func emitFunc(fn *ssa.Function) {
/* TODO research if the ssautil.Switches() function can be incorporated to provide any run-time improvement to the code
sw := ssautil.Switches(fn)
if len(sw) > 0 {
fmt.Printf("DEBUG Switches: %s = %+v\n", fn, sw)
}
*/
subFnList := make([]subFnInstrs, 0)
canOptMap := make(map[string]bool) // TODO review use of this mechanism
//println("DEBUG processing function: ", fn.Name())
MakePosHash(fn.Pos()) // mark that we have entered a function
trackPhi := true
switch len(fn.Blocks) {
case 0: // NoOp - only output a function if it has a body... so ignore pure definitions (target language may generate an error, if truely undef)
//fmt.Printf("DEBUG function has no body, ignored: %v %v \n", fn.Name(), fn.String())
case 1: // Only one block, so no Phi tracking required
trackPhi = false
fallthrough
default:
if trackPhi {
// check that there actually are Phi instructions to track
trackPhi = false
phiSearch:
for b := range fn.Blocks {
for i := range fn.Blocks[b].Instrs {
_, trackPhi = fn.Blocks[b].Instrs[i].(*ssa.Phi)
if trackPhi {
break phiSearch
}
}
}
}
instrCount := 0
for b := range fn.Blocks {
instrCount += len(fn.Blocks[b].Instrs)
}
mustSplitCode := false
if instrCount > LanguageList[TargetLang].InstructionLimit {
//println("DEBUG mustSplitCode => large function length:", instrCount, " in ", fn.Name())
mustSplitCode = true
}
for b := range fn.Blocks { // go though the blocks looking for sub-functions
instrsEmitted := 0
inSubFn := false
for i := range fn.Blocks[b].Instrs {
canPutInSubFn := true
in := fn.Blocks[b].Instrs[i]
switch in.(type) {
case *ssa.Phi: // phi uses self-referential temp vars that must be pre-initialised
canPutInSubFn = false
case *ssa.Return:
canPutInSubFn = false
case *ssa.Call:
switch in.(*ssa.Call).Call.Value.(type) {
case *ssa.Builtin:
//NoOp
default:
canPutInSubFn = false
}
case *ssa.Select, *ssa.Send, *ssa.Defer, *ssa.RunDefers, *ssa.Panic:
canPutInSubFn = false
case *ssa.UnOp:
if in.(*ssa.UnOp).Op == token.ARROW {
canPutInSubFn = false
}
}
if canPutInSubFn {
if inSubFn {
if instrsEmitted > LanguageList[TargetLang].SubFnInstructionLimit {
subFnList[len(subFnList)-1].end = i
subFnList = append(subFnList, subFnInstrs{b, i, 0})
instrsEmitted = 0
}
} else {
subFnList = append(subFnList, subFnInstrs{b, i, 0})
inSubFn = true
}
} else {
if inSubFn {
subFnList[len(subFnList)-1].end = i
inSubFn = false
}
}
instrsEmitted++
}
if inSubFn {
subFnList[len(subFnList)-1].end = len(fn.Blocks[b].Instrs)
}
}
for sf := range subFnList { // go though the sub-functions looking for optimisable temp vars
var instrMap = make(map[ssa.Instruction]bool)
for ii := subFnList[sf].start; ii < subFnList[sf].end; ii++ {
instrMap[fn.Blocks[subFnList[sf].block].Instrs[ii]] = true
}
for i := subFnList[sf].start; i < subFnList[sf].end; i++ {
//.........这里部分代码省略.........