ssa: ChangeInterface
This commit is contained in:
@@ -69,11 +69,11 @@ func (b Builder) Imethod(intf Expr, method *types.Func) Expr {
|
||||
rawIntf := intf.raw.Type.Underlying().(*types.Interface)
|
||||
tclosure := prog.Type(method.Type(), InGo)
|
||||
i := iMethodOf(rawIntf, method.Name())
|
||||
data := b.InlineCall(b.Pkg.rtFunc("IfacePtrData"), intf)
|
||||
impl := intf.impl
|
||||
itab := Expr{b.faceItab(impl), prog.VoidPtrPtr()}
|
||||
pfn := b.Advance(itab, prog.IntVal(uint64(i+3), prog.Int()))
|
||||
fn := b.Load(pfn)
|
||||
data := b.InlineCall(b.Pkg.rtFunc("IfaceData"), intf)
|
||||
ret := b.aggregateValue(tclosure, fn.impl, data.impl)
|
||||
return ret
|
||||
}
|
||||
@@ -269,6 +269,25 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
|
||||
return b.valFromData(assertedTyp, b.faceData(x.impl))
|
||||
}
|
||||
|
||||
// ChangeInterface constructs a value of one interface type from a
|
||||
// value of another interface type known to be assignable to it.
|
||||
// This operation cannot fail.
|
||||
//
|
||||
// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
|
||||
// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
|
||||
// instruction arose from an explicit e.(T) operation; or token.NoPos
|
||||
// otherwise.
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t1 = change interface interface{} <- I (t0)
|
||||
func (b Builder) ChangeInterface(typ Type, x Expr) (ret Expr) {
|
||||
rawIntf := typ.raw.Type.Underlying().(*types.Interface)
|
||||
tabi := b.faceAbiType(x)
|
||||
data := b.faceData(x.impl)
|
||||
return Expr{b.unsafeInterface(rawIntf, tabi, data), typ}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@@ -291,7 +310,7 @@ func (b Builder) faceItab(x llvm.Value) llvm.Value {
|
||||
|
||||
func (b Builder) faceAbiType(x Expr) Expr {
|
||||
if x.kind == vkIface {
|
||||
panic("todo")
|
||||
return b.InlineCall(b.Pkg.rtFunc("IfaceType"), x)
|
||||
}
|
||||
typ := llvm.CreateExtractValue(b.impl, x.impl, 0)
|
||||
return Expr{typ, b.Prog.AbiTypePtr()}
|
||||
|
||||
Reference in New Issue
Block a user