ssa: interface equal

This commit is contained in:
visualfc
2024-06-11 10:24:30 +08:00
parent 439a69f413
commit bdf1c275c4
4 changed files with 150 additions and 6 deletions

View File

@@ -166,6 +166,9 @@ func (b *Builder) TypeName(t types.Type) (ret string, pub bool) {
// PathOf returns the package path of the specified package.
func PathOf(pkg *types.Package) string {
if pkg == nil {
return ""
}
if pkg.Name() == "main" {
return "main"
}
@@ -174,6 +177,9 @@ func PathOf(pkg *types.Package) string {
// FullName returns the full name of a package member.
func FullName(pkg *types.Package, name string) string {
if pkg == nil {
return name
}
return PathOf(pkg) + "." + name
}

View File

@@ -118,14 +118,12 @@ func (b Builder) abiMethods(t *types.Named) (ret, pret int) {
}
// Method{name string, typ *FuncType, ifn, tfn abi.Text}
func (b Builder) abiMethodOf(m *types.Func /*, bg Background = InGo */) (mthd, ptrMthd Expr) {
func (b Builder) abiMethodOf(mPkg *types.Package, mName string, mSig *types.Signature /*, bg Background = InGo */) (mthd, ptrMthd Expr) {
prog := b.Prog
mPkg, mName := m.Pkg(), m.Name()
mSig := m.Type().(*types.Signature)
name := b.Str(mName).impl
if !token.IsExported(mName) {
name = b.Str(abi.FullName(mPkg, m.Name())).impl
name = b.Str(abi.FullName(mPkg, mName)).impl
}
abiSigGo := types.NewSignatureType(nil, nil, nil, mSig.Params(), mSig.Results(), mSig.Variadic())
abiSig := prog.FuncDecl(abiSigGo, InGo).raw.Type
@@ -217,8 +215,8 @@ func (b Builder) abiInitNamed(ret Expr, t *types.Named) func() Expr {
var mthds []Expr
var ptrMthds = make([]Expr, 0, n)
for i := 0; i < n; i++ {
m := mset[i].Obj().(*types.Func)
mthd, ptrMthd := b.abiMethodOf(m)
sel := mset[i]
mthd, ptrMthd := b.abiMethodOf(sel.Obj().Pkg(), sel.Obj().Name(), sel.Type().(*types.Signature))
if !mthd.IsNil() {
mthds = append(mthds, mthd)
}

View File

@@ -425,6 +425,16 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
ret.impl = llvm.CreateNot(b.impl, ret.impl)
return ret
}
case vkIface, vkEface:
prog := b.Prog
switch op {
case token.EQL:
return b.InlineCall(b.Pkg.rtFunc("InterfaceEqual"), x, y, prog.BoolVal(x.kind == vkEface), prog.BoolVal(y.kind == vkEface))
case token.NEQ:
ret := b.InlineCall(b.Pkg.rtFunc("InterfaceEqual"), x, y, prog.BoolVal(x.kind == vkEface), prog.BoolVal(y.kind == vkEface))
ret.impl = llvm.CreateNot(b.impl, ret.impl)
return ret
}
}
}
panic("todo")