llgo/ssa: rtType, rtFunc
This commit is contained in:
68
ssa/expr.go
68
ssa/expr.go
@@ -407,8 +407,76 @@ func (b Builder) ChangeType(t Type, x Expr) (ret Expr) {
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// The TypeAssert instruction tests whether interface value X has type
|
||||
// AssertedType.
|
||||
//
|
||||
// If !CommaOk, on success it returns v, the result of the conversion
|
||||
// (defined below); on failure it panics.
|
||||
//
|
||||
// If CommaOk: on success it returns a pair (v, true) where v is the
|
||||
// result of the conversion; on failure it returns (z, false) where z
|
||||
// is AssertedType's zero value. The components of the pair must be
|
||||
// accessed using the Extract instruction.
|
||||
//
|
||||
// If Underlying: tests whether interface value X has the underlying
|
||||
// type AssertedType.
|
||||
//
|
||||
// If AssertedType is a concrete type, TypeAssert checks whether the
|
||||
// dynamic type in interface X is equal to it, and if so, the result
|
||||
// of the conversion is a copy of the value in the interface.
|
||||
//
|
||||
// If AssertedType is an interface, TypeAssert checks whether the
|
||||
// dynamic type of the interface is assignable to it, and if so, the
|
||||
// result of the conversion is a copy of the interface value X.
|
||||
// If AssertedType is a superinterface of X.Type(), the operation will
|
||||
// fail iff the operand is nil. (Contrast with ChangeInterface, which
|
||||
// performs no nil-check.)
|
||||
//
|
||||
// Type() reflects the actual type of the result, possibly a
|
||||
// 2-types.Tuple; AssertedType is the asserted type.
|
||||
//
|
||||
// Depending on the TypeAssert's purpose, Pos may return:
|
||||
// - the ast.CallExpr.Lparen of an explicit T(e) conversion;
|
||||
// - the ast.TypeAssertExpr.Lparen of an explicit e.(T) operation;
|
||||
// - the ast.CaseClause.Case of a case of a type-switch statement;
|
||||
// - the Ident(m).NamePos of an interface method value i.m
|
||||
// (for which TypeAssert may be used to effect the nil check).
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t1 = typeassert t0.(int)
|
||||
// t3 = typeassert,ok t2.(T)
|
||||
func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
|
||||
if debugInstr {
|
||||
log.Printf("TypeAssert %v, %v, %v\n", x.impl, assertedTyp.t, commaOk)
|
||||
}
|
||||
switch assertedTyp.kind {
|
||||
case vkSigned, vkUnsigned:
|
||||
pkg := b.fn.pkg
|
||||
fnName := "I2Int"
|
||||
if commaOk {
|
||||
fnName = "CheckI2Int"
|
||||
}
|
||||
fn := pkg.rtFunc(fnName)
|
||||
var kind types.BasicKind
|
||||
switch t := assertedTyp.t.(type) {
|
||||
case *types.Basic:
|
||||
kind = t.Kind()
|
||||
default:
|
||||
panic("todo")
|
||||
}
|
||||
typ := b.InlineCall(pkg.rtFunc("Basic"), b.prog.Val(int(kind)))
|
||||
return b.InlineCall(fn, x, typ)
|
||||
}
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
func (b Builder) InlineCall(fn Expr, args ...Expr) (ret Expr) {
|
||||
return b.Call(fn, args...)
|
||||
}
|
||||
|
||||
// The Call instruction represents a function or method call.
|
||||
//
|
||||
// The Call instruction yields the function result if there is exactly
|
||||
|
||||
Reference in New Issue
Block a user