TestAny, TestDelayExpr
This commit is contained in:
@@ -418,9 +418,6 @@ func (p *context) compileVArg(ret []llssa.Expr, b llssa.Builder, v ssa.Value) []
|
||||
switch v := v.(type) {
|
||||
case *ssa.Slice: // varargs: this is a varargs slice
|
||||
if args, ok := p.isVArgs(v.X); ok {
|
||||
for i, arg := range args {
|
||||
args[i] = arg.Do(true)
|
||||
}
|
||||
return append(ret, args...)
|
||||
}
|
||||
case *ssa.Const:
|
||||
@@ -435,7 +432,7 @@ func (p *context) compileValues(b llssa.Builder, vals []ssa.Value, hasVArg int)
|
||||
n := len(vals) - hasVArg
|
||||
ret := make([]llssa.Expr, n)
|
||||
for i := 0; i < n; i++ {
|
||||
ret[i] = p.compileValue(b, vals[i]).Do(false)
|
||||
ret[i] = p.compileValue(b, vals[i]).Do()
|
||||
}
|
||||
if hasVArg > 0 {
|
||||
ret = p.compileVArg(ret, b, vals[n])
|
||||
|
||||
29
ssa/expr.go
29
ssa/expr.go
@@ -42,33 +42,25 @@ func (v Expr) TypeOf() types.Type {
|
||||
*/
|
||||
|
||||
// Do evaluates the delay expression and returns the result.
|
||||
func (v Expr) Do(isVArg bool) Expr {
|
||||
func (v Expr) Do() Expr {
|
||||
if vt := v.Type; vt.kind == vkDelayExpr {
|
||||
delay := vt.t.(*delayExprTy)
|
||||
if f := delay.f; f != nil {
|
||||
delay.f = nil
|
||||
delay.val = f(isVArg)
|
||||
}
|
||||
return delay.val
|
||||
return vt.t.(delayExprTy)()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// DelayExpr returns a delay expression.
|
||||
func DelayExpr(f func(isVArg bool) Expr) Expr {
|
||||
return Expr{Type: &aType{t: &delayExprTy{f: f}, kind: vkDelayExpr}}
|
||||
func DelayExpr(f func() Expr) Expr {
|
||||
return Expr{Type: &aType{t: delayExprTy(f), kind: vkDelayExpr}}
|
||||
}
|
||||
|
||||
type delayExprTy struct {
|
||||
f func(isVArg bool) Expr
|
||||
val Expr
|
||||
}
|
||||
type delayExprTy func() Expr
|
||||
|
||||
func (p *delayExprTy) Underlying() types.Type {
|
||||
func (p delayExprTy) Underlying() types.Type {
|
||||
panic("don't call")
|
||||
}
|
||||
|
||||
func (p *delayExprTy) String() string {
|
||||
func (p delayExprTy) String() string {
|
||||
return "delayExpr"
|
||||
}
|
||||
|
||||
@@ -461,10 +453,7 @@ func (b Builder) MakeInterface(inter types.Type, x Expr, mayDelay bool) (ret Exp
|
||||
}
|
||||
t := inter.Underlying().(*types.Interface)
|
||||
isAny := t.Empty()
|
||||
fnDo := func(isVArg bool) Expr {
|
||||
if isVArg { // don't need make interface
|
||||
return x
|
||||
}
|
||||
fnDo := func() Expr {
|
||||
pkg := b.fn.pkg
|
||||
switch x.kind {
|
||||
case vkSigned, vkUnsigned, vkFloat:
|
||||
@@ -476,7 +465,7 @@ func (b Builder) MakeInterface(inter types.Type, x Expr, mayDelay bool) (ret Exp
|
||||
if mayDelay && isAny {
|
||||
return DelayExpr(fnDo)
|
||||
}
|
||||
return fnDo(false)
|
||||
return fnDo()
|
||||
}
|
||||
|
||||
// The TypeAssert instruction tests whether interface value X has type
|
||||
|
||||
@@ -195,6 +195,7 @@ func (p Program) Bool() Type {
|
||||
return p.boolTy
|
||||
}
|
||||
|
||||
// Any returns any type.
|
||||
func (p Program) Any() Type {
|
||||
if p.anyTy == nil {
|
||||
p.anyTy = p.Type(tyAny)
|
||||
|
||||
@@ -23,6 +23,37 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
/*
|
||||
func TestMakeInterface(t *testing.T) {
|
||||
var b Builder
|
||||
b.MakeInterface(types.NewInterfaceType(nil, nil), Expr{}, true).Do(true)
|
||||
}
|
||||
*/
|
||||
|
||||
func TestDelayExpr(t *testing.T) {
|
||||
a := delayExprTy(nil)
|
||||
_ = a.String()
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Log("TestDelayExpr: no error?")
|
||||
}
|
||||
}()
|
||||
a.Underlying()
|
||||
}
|
||||
|
||||
func TestAny(t *testing.T) {
|
||||
prog := NewProgram(nil)
|
||||
prog.SetRuntime(func() *types.Package {
|
||||
ret := types.NewPackage("runtime", "runtime")
|
||||
scope := ret.Scope()
|
||||
name := types.NewTypeName(0, ret, "Interface", nil)
|
||||
types.NewNamed(name, types.NewStruct(nil, nil), nil)
|
||||
scope.Insert(name)
|
||||
return ret
|
||||
})
|
||||
prog.Any()
|
||||
}
|
||||
|
||||
func assertPkg(t *testing.T, p Package, expected string) {
|
||||
t.Helper()
|
||||
if v := p.String(); v != expected {
|
||||
|
||||
Reference in New Issue
Block a user