本文整理汇总了Golang中code/google/com/p/go/tools/ssa.Instruction类的典型用法代码示例。如果您正苦于以下问题:Golang Instruction类的具体用法?Golang Instruction怎么用?Golang Instruction使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Instruction类的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: chanOps
// chanOps returns a slice of all the channel operations in the instruction.
func chanOps(instr ssa.Instruction) []chanOp {
// TODO(adonovan): handle calls to reflect.{Select,Recv,Send} too.
var ops []chanOp
switch instr := instr.(type) {
case *ssa.UnOp:
if instr.Op == token.ARROW {
ops = append(ops, chanOp{instr.X, types.RecvOnly, instr.Pos()})
}
case *ssa.Send:
ops = append(ops, chanOp{instr.Chan, types.SendOnly, instr.Pos()})
case *ssa.Select:
for _, st := range instr.States {
ops = append(ops, chanOp{st.Chan, st.Dir, st.Pos})
}
}
return ops
}
示例2: instruction
func (fr *frame) instruction(instr ssa.Instruction) {
fr.logf("[%T] %v @ %s\n", instr, instr, fr.pkg.Prog.Fset.Position(instr.Pos()))
// Check if we'll need to backpatch; see comment
// in fr.value().
if v, ok := instr.(ssa.Value); ok {
if b := fr.backpatcher(v); b != nil {
defer b()
}
}
switch instr := instr.(type) {
case *ssa.Alloc:
typ := fr.llvmtypes.ToLLVM(deref(instr.Type()))
var value llvm.Value
if instr.Heap {
value = fr.createTypeMalloc(typ)
value.SetName(instr.Comment)
fr.env[instr] = fr.NewValue(value, instr.Type())
} else {
value = fr.env[instr].LLVMValue()
}
fr.memsetZero(value, llvm.SizeOf(typ))
case *ssa.BinOp:
lhs, rhs := fr.value(instr.X), fr.value(instr.Y)
fr.env[instr] = lhs.BinaryOp(instr.Op, rhs).(*LLVMValue)
case *ssa.Call:
fn, args, result := fr.prepareCall(instr)
// Some builtins may only be used immediately, and not
// deferred; in this case, "fn" will be nil, and result
// may be non-nil (it will be nil for builtins without
// results.)
if fn == nil {
if result != nil {
fr.env[instr] = result
}
} else {
result = fr.createCall(fn, args)
fr.env[instr] = result
}
case *ssa.ChangeInterface:
x := fr.value(instr.X)
// The source type must be a non-empty interface,
// as ChangeInterface cannot fail (E2I may fail).
if instr.Type().Underlying().(*types.Interface).NumMethods() > 0 {
// TODO(axw) optimisation for I2I case where we
// know statically the methods to carry over.
x = x.convertI2E()
x, _ = x.convertE2I(instr.Type())
} else {
x = x.convertI2E()
x = fr.NewValue(x.LLVMValue(), instr.Type())
}
fr.env[instr] = x
case *ssa.ChangeType:
value := fr.value(instr.X).LLVMValue()
if _, ok := instr.Type().Underlying().(*types.Pointer); ok {
value = fr.builder.CreateBitCast(value, fr.llvmtypes.ToLLVM(instr.Type()), "")
}
v := fr.NewValue(value, instr.Type())
if _, ok := instr.X.(*ssa.Phi); ok {
v = phiValue(fr.compiler, v)
}
fr.env[instr] = v
case *ssa.Convert:
v := fr.value(instr.X)
if _, ok := instr.X.(*ssa.Phi); ok {
v = phiValue(fr.compiler, v)
}
fr.env[instr] = v.Convert(instr.Type()).(*LLVMValue)
//case *ssa.DebugRef:
case *ssa.Defer:
fn, args, result := fr.prepareCall(instr)
if result != nil {
panic("illegal use of builtin in defer statement")
}
fn = fr.indirectFunction(fn, args)
fr.createCall(fr.runtime.pushdefer, []*LLVMValue{fn})
case *ssa.Extract:
tuple := fr.value(instr.Tuple).LLVMValue()
elem := fr.builder.CreateExtractValue(tuple, instr.Index, instr.Name())
elemtyp := instr.Type()
fr.env[instr] = fr.NewValue(elem, elemtyp)
case *ssa.Field:
value := fr.value(instr.X).LLVMValue()
field := fr.builder.CreateExtractValue(value, instr.Field, instr.Name())
fieldtyp := instr.Type()
fr.env[instr] = fr.NewValue(field, fieldtyp)
case *ssa.FieldAddr:
// TODO: implement nil check and panic.
//.........这里部分代码省略.........
示例3: genInstr
// genInstr generates contraints for instruction instr in context cgn.
func (a *analysis) genInstr(cgn *cgnode, instr ssa.Instruction) {
if a.log != nil {
var prefix string
if val, ok := instr.(ssa.Value); ok {
prefix = val.Name() + " = "
}
fmt.Fprintf(a.log, "; %s%s\n", prefix, instr)
}
switch instr := instr.(type) {
case *ssa.DebugRef:
// no-op.
case *ssa.UnOp:
switch instr.Op {
case token.ARROW: // <-x
// We can ignore instr.CommaOk because the node we're
// altering is always at zero offset relative to instr
a.genLoad(cgn, a.valueNode(instr), instr.X, 0, a.sizeof(instr.Type()))
case token.MUL: // *x
a.genLoad(cgn, a.valueNode(instr), instr.X, 0, a.sizeof(instr.Type()))
default:
// NOT, SUB, XOR: no-op.
}
case *ssa.BinOp:
// All no-ops.
case ssa.CallInstruction: // *ssa.Call, *ssa.Go, *ssa.Defer
a.genCall(cgn, instr)
case *ssa.ChangeType:
a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
case *ssa.Convert:
a.genConv(instr, cgn)
case *ssa.Extract:
a.copy(a.valueNode(instr),
a.valueOffsetNode(instr.Tuple, instr.Index),
a.sizeof(instr.Type()))
case *ssa.FieldAddr:
a.genOffsetAddr(cgn, instr, a.valueNode(instr.X),
a.offsetOf(mustDeref(instr.X.Type()), instr.Field))
case *ssa.IndexAddr:
a.genOffsetAddr(cgn, instr, a.valueNode(instr.X), 1)
case *ssa.Field:
a.copy(a.valueNode(instr),
a.valueOffsetNode(instr.X, instr.Field),
a.sizeof(instr.Type()))
case *ssa.Index:
a.copy(a.valueNode(instr), 1+a.valueNode(instr.X), a.sizeof(instr.Type()))
case *ssa.Select:
recv := a.valueOffsetNode(instr, 2) // instr : (index, recvOk, recv0, ... recv_n-1)
for _, st := range instr.States {
elemSize := a.sizeof(st.Chan.Type().Underlying().(*types.Chan).Elem())
switch st.Dir {
case ast.RECV:
a.genLoad(cgn, recv, st.Chan, 0, elemSize)
recv += nodeid(elemSize)
case ast.SEND:
a.genStore(cgn, st.Chan, a.valueNode(st.Send), 0, elemSize)
}
}
case *ssa.Return:
results := a.funcResults(cgn.obj)
for _, r := range instr.Results {
sz := a.sizeof(r.Type())
a.copy(results, a.valueNode(r), sz)
results += nodeid(sz)
}
case *ssa.Send:
a.genStore(cgn, instr.Chan, a.valueNode(instr.X), 0, a.sizeof(instr.X.Type()))
case *ssa.Store:
a.genStore(cgn, instr.Addr, a.valueNode(instr.Val), 0, a.sizeof(instr.Val.Type()))
case *ssa.Alloc, *ssa.MakeSlice, *ssa.MakeChan, *ssa.MakeMap, *ssa.MakeInterface:
v := instr.(ssa.Value)
a.addressOf(a.valueNode(v), a.objectNode(cgn, v))
case *ssa.ChangeInterface:
a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
case *ssa.TypeAssert:
a.typeAssert(instr.AssertedType, a.valueNode(instr), a.valueNode(instr.X), true)
case *ssa.Slice:
a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
//.........这里部分代码省略.........
示例4: visitInstr
// visitInstr interprets a single ssa.Instruction within the activation
// record frame. It returns a continuation value indicating where to
// read the next instruction from.
func visitInstr(fr *frame, instr ssa.Instruction) continuation {
switch instr := instr.(type) {
case *ssa.DebugRef:
// no-op
case *ssa.UnOp:
fr.env[instr] = unop(instr, fr.get(instr.X))
case *ssa.BinOp:
fr.env[instr] = binop(instr.Op, instr.X.Type(), fr.get(instr.X), fr.get(instr.Y))
case *ssa.Call:
fn, args := prepareCall(fr, &instr.Call)
fr.env[instr] = call(fr.i, fr, instr.Pos(), fn, args)
case *ssa.ChangeInterface:
fr.env[instr] = fr.get(instr.X)
case *ssa.ChangeType:
fr.env[instr] = fr.get(instr.X) // (can't fail)
case *ssa.Convert:
fr.env[instr] = conv(instr.Type(), instr.X.Type(), fr.get(instr.X))
case *ssa.MakeInterface:
fr.env[instr] = iface{t: instr.X.Type(), v: fr.get(instr.X)}
case *ssa.Extract:
fr.env[instr] = fr.get(instr.Tuple).(tuple)[instr.Index]
case *ssa.Slice:
fr.env[instr] = slice(fr.get(instr.X), fr.get(instr.Low), fr.get(instr.High))
case *ssa.Return:
switch len(instr.Results) {
case 0:
case 1:
fr.result = fr.get(instr.Results[0])
default:
var res []value
for _, r := range instr.Results {
res = append(res, fr.get(r))
}
fr.result = tuple(res)
}
fr.block = nil
return kReturn
case *ssa.RunDefers:
fr.runDefers()
case *ssa.Panic:
panic(targetPanic{fr.get(instr.X)})
case *ssa.Send:
fr.get(instr.Chan).(chan value) <- copyVal(fr.get(instr.X))
case *ssa.Store:
*fr.get(instr.Addr).(*value) = copyVal(fr.get(instr.Val))
case *ssa.If:
succ := 1
if fr.get(instr.Cond).(bool) {
succ = 0
}
fr.prevBlock, fr.block = fr.block, fr.block.Succs[succ]
return kJump
case *ssa.Jump:
fr.prevBlock, fr.block = fr.block, fr.block.Succs[0]
return kJump
case *ssa.Defer:
fn, args := prepareCall(fr, &instr.Call)
fr.defers = &deferred{
fn: fn,
args: args,
instr: instr,
tail: fr.defers,
}
case *ssa.Go:
fn, args := prepareCall(fr, &instr.Call)
go call(fr.i, nil, instr.Pos(), fn, args)
case *ssa.MakeChan:
fr.env[instr] = make(chan value, asInt(fr.get(instr.Size)))
case *ssa.Alloc:
var addr *value
if instr.Heap {
// new
addr = new(value)
fr.env[instr] = addr
} else {
// local
addr = fr.env[instr].(*value)
//.........这里部分代码省略.........
示例5: genInstr
// genInstr generates contraints for instruction instr in context cgn.
func (a *analysis) genInstr(cgn *cgnode, instr ssa.Instruction) {
if a.log != nil {
var prefix string
if val, ok := instr.(ssa.Value); ok {
prefix = val.Name() + " = "
}
fmt.Fprintf(a.log, "; %s%s\n", prefix, instr)
}
switch instr := instr.(type) {
case *ssa.DebugRef:
// no-op.
case *ssa.UnOp:
switch instr.Op {
case token.ARROW: // <-x
// We can ignore instr.CommaOk because the node we're
// altering is always at zero offset relative to instr.
a.load(a.valueNode(instr), a.valueNode(instr.X), a.sizeof(instr.Type()))
case token.MUL: // *x
a.load(a.valueNode(instr), a.valueNode(instr.X), a.sizeof(instr.Type()))
default:
// NOT, SUB, XOR: no-op.
}
case *ssa.BinOp:
// All no-ops.
case ssa.CallInstruction: // *ssa.Call, *ssa.Go, *ssa.Defer
a.genCall(cgn, instr)
case *ssa.ChangeType:
a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
case *ssa.Convert:
a.genConv(instr, cgn)
case *ssa.Extract:
a.copy(a.valueNode(instr),
a.valueOffsetNode(instr.Tuple, instr.Index),
a.sizeof(instr.Type()))
case *ssa.FieldAddr:
a.offsetAddr(a.valueNode(instr), a.valueNode(instr.X),
a.offsetOf(mustDeref(instr.X.Type()), instr.Field))
case *ssa.IndexAddr:
a.offsetAddr(a.valueNode(instr), a.valueNode(instr.X), 1)
case *ssa.Field:
a.copy(a.valueNode(instr),
a.valueOffsetNode(instr.X, instr.Field),
a.sizeof(instr.Type()))
case *ssa.Index:
a.copy(a.valueNode(instr), 1+a.valueNode(instr.X), a.sizeof(instr.Type()))
case *ssa.Select:
recv := a.valueOffsetNode(instr, 2) // instr : (index, recvOk, recv0, ... recv_n-1)
for _, st := range instr.States {
elemSize := a.sizeof(st.Chan.Type().Underlying().(*types.Chan).Elem())
switch st.Dir {
case ast.RECV:
a.load(recv, a.valueNode(st.Chan), elemSize)
recv++
case ast.SEND:
a.store(a.valueNode(st.Chan), a.valueNode(st.Send), elemSize)
}
}
case *ssa.Ret:
results := a.funcResults(cgn.obj)
for _, r := range instr.Results {
sz := a.sizeof(r.Type())
a.copy(results, a.valueNode(r), sz)
results += nodeid(sz)
}
case *ssa.Send:
a.store(a.valueNode(instr.Chan), a.valueNode(instr.X), a.sizeof(instr.X.Type()))
case *ssa.Store:
a.store(a.valueNode(instr.Addr), a.valueNode(instr.Val), a.sizeof(instr.Val.Type()))
case *ssa.Alloc:
obj := a.nextNode()
a.addNodes(mustDeref(instr.Type()), "alloc")
a.endObject(obj, cgn, instr)
a.addressOf(a.valueNode(instr), obj)
case *ssa.MakeSlice:
obj := a.nextNode()
a.addNodes(sliceToArray(instr.Type()), "makeslice")
a.endObject(obj, cgn, instr)
a.addressOf(a.valueNode(instr), obj)
//.........这里部分代码省略.........