fix(ssa): use empty PkgPath for anonymous interfaces
Based on meeting discussion, this commit reverts the previous approach of extracting PkgPath from interface methods. Instead, anonymous interfaces now use an empty PkgPath string, and the runtime's methods() function handles empty PkgPath by returning all methods. Changes: - Reverted unsafeInterface() to remove originType parameter - Set anonymous interface PkgPath to empty string in abitype.go:202 - Added early return in methods() in z_face.go for empty PkgPath - All call sites of unsafeInterface() updated to pass rawIntf directly This approach is cleaner because anonymous interfaces don't belong to any package, and the compiler already guarantees safety for cross-package private method access. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> Co-authored-by: luoliwoshang <51194195+luoliwoshang@users.noreply.github.com>
This commit is contained in:
@@ -396,6 +396,9 @@ func findMethod(mthds []abi.Method, im abi.Imethod) abi.Text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func methods(u *abi.UncommonType, from string) []abi.Method {
|
func methods(u *abi.UncommonType, from string) []abi.Method {
|
||||||
|
if from == "" {
|
||||||
|
return u.Methods()
|
||||||
|
}
|
||||||
if u.PkgPath_ == from {
|
if u.PkgPath_ == from {
|
||||||
return u.Methods()
|
return u.Methods()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ func (b Builder) abiInterfaceOf(t *types.Interface) func() Expr {
|
|||||||
fn := pkg.rtFunc("Interface")
|
fn := pkg.rtFunc("Interface")
|
||||||
tSlice := lastParamType(prog, fn)
|
tSlice := lastParamType(prog, fn)
|
||||||
methodSlice := b.SliceLit(tSlice, methods...)
|
methodSlice := b.SliceLit(tSlice, methods...)
|
||||||
return b.Call(fn, b.Str(pkg.Path()), methodSlice)
|
return b.Call(fn, b.Str(""), methodSlice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ func (b Builder) newItab(tintf, typ Expr) Expr {
|
|||||||
return b.Call(b.Pkg.rtFunc("NewItab"), tintf, typ)
|
return b.Call(b.Pkg.rtFunc("NewItab"), tintf, typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Builder) unsafeInterface(rawIntf *types.Interface, originType types.Type, t Expr, data llvm.Value) llvm.Value {
|
func (b Builder) unsafeInterface(rawIntf *types.Interface, t Expr, data llvm.Value) llvm.Value {
|
||||||
if rawIntf.Empty() {
|
if rawIntf.Empty() {
|
||||||
return b.unsafeEface(t.impl, data)
|
return b.unsafeEface(t.impl, data)
|
||||||
}
|
}
|
||||||
tintf := b.abiType(originType)
|
tintf := b.abiType(rawIntf)
|
||||||
itab := b.newItab(tintf, t)
|
itab := b.newItab(tintf, t)
|
||||||
return b.unsafeIface(itab.impl, data)
|
return b.unsafeIface(itab.impl, data)
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) {
|
|||||||
case abi.Indirect:
|
case abi.Indirect:
|
||||||
vptr := b.AllocU(typ)
|
vptr := b.AllocU(typ)
|
||||||
b.Store(vptr, x)
|
b.Store(vptr, x)
|
||||||
return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, vptr.impl), tinter}
|
return Expr{b.unsafeInterface(rawIntf, tabi, vptr.impl), tinter}
|
||||||
}
|
}
|
||||||
ximpl := x.impl
|
ximpl := x.impl
|
||||||
if lvl > 0 {
|
if lvl > 0 {
|
||||||
@@ -121,7 +121,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) {
|
|||||||
var u llvm.Value
|
var u llvm.Value
|
||||||
switch kind {
|
switch kind {
|
||||||
case abi.Pointer:
|
case abi.Pointer:
|
||||||
return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, ximpl), tinter}
|
return Expr{b.unsafeInterface(rawIntf, tabi, ximpl), tinter}
|
||||||
case abi.Integer:
|
case abi.Integer:
|
||||||
tu := prog.Uintptr()
|
tu := prog.Uintptr()
|
||||||
u = llvm.CreateIntCast(b.impl, ximpl, tu.ll)
|
u = llvm.CreateIntCast(b.impl, ximpl, tu.ll)
|
||||||
@@ -136,7 +136,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) {
|
|||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
data := llvm.CreateIntToPtr(b.impl, u, prog.tyVoidPtr())
|
data := llvm.CreateIntToPtr(b.impl, u, prog.tyVoidPtr())
|
||||||
return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, data), tinter}
|
return Expr{b.unsafeInterface(rawIntf, tabi, data), tinter}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Builder) valFromData(typ Type, data llvm.Value) Expr {
|
func (b Builder) valFromData(typ Type, data llvm.Value) Expr {
|
||||||
@@ -250,7 +250,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
|
|||||||
if rawIntf, ok := assertedTyp.raw.Type.Underlying().(*types.Interface); ok {
|
if rawIntf, ok := assertedTyp.raw.Type.Underlying().(*types.Interface); ok {
|
||||||
eq = b.InlineCall(b.Pkg.rtFunc("Implements"), tabi, tx)
|
eq = b.InlineCall(b.Pkg.rtFunc("Implements"), tabi, tx)
|
||||||
val = func() Expr {
|
val = func() Expr {
|
||||||
return Expr{b.unsafeInterface(rawIntf, assertedTyp.raw.Type, tx, b.faceData(x.impl)), assertedTyp}
|
return Expr{b.unsafeInterface(rawIntf, tx, b.faceData(x.impl)), assertedTyp}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eq = b.BinOp(token.EQL, tx, tabi)
|
eq = b.BinOp(token.EQL, tx, tabi)
|
||||||
@@ -307,7 +307,7 @@ func (b Builder) ChangeInterface(typ Type, x Expr) (ret Expr) {
|
|||||||
rawIntf := typ.raw.Type.Underlying().(*types.Interface)
|
rawIntf := typ.raw.Type.Underlying().(*types.Interface)
|
||||||
tabi := b.faceAbiType(x)
|
tabi := b.faceAbiType(x)
|
||||||
data := b.faceData(x.impl)
|
data := b.faceData(x.impl)
|
||||||
return Expr{b.unsafeInterface(rawIntf, typ.raw.Type, tabi, data), typ}
|
return Expr{b.unsafeInterface(rawIntf, tabi, data), typ}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user