llgo/ssa: abiMethodOf; AfterInit bugfix
This commit is contained in:
@@ -26,7 +26,7 @@ import (
|
||||
)
|
||||
|
||||
func TestFromTestgo(t *testing.T) {
|
||||
cltest.FromDir(t, "", "../cl/_testgo", false)
|
||||
cltest.FromDir(t, "errors", "../cl/_testgo", false)
|
||||
}
|
||||
|
||||
func TestFromTestpy(t *testing.T) {
|
||||
|
||||
@@ -93,6 +93,21 @@ func (b Builder) abiImethodOf(m *types.Func) Expr {
|
||||
return b.aggregateValue(prog.rtType("Imethod"), name.impl, typ.impl)
|
||||
}
|
||||
|
||||
// Method{name string, typ *FuncType, ifn, tfn abi.Text}
|
||||
func (b Builder) abiMethodOf(m *types.Func) Expr {
|
||||
prog := b.Prog
|
||||
mName := m.Name()
|
||||
mSig := m.Type().(*types.Signature)
|
||||
fullName := FuncName(m.Pkg(), mName, mSig.Recv())
|
||||
name := b.Str(mName)
|
||||
fn := b.Pkg.NewFunc(fullName, mSig, InGo)
|
||||
sig := fn.raw.Type.(*types.Signature)
|
||||
sig = types.NewSignatureType(nil, nil, nil, sig.Params(), sig.Results(), sig.Variadic())
|
||||
typ := b.abiType(sig)
|
||||
// TODO(xsw): ifn, tfn
|
||||
return b.aggregateValue(prog.rtType("Method"), name.impl, typ.impl, fn.impl, fn.impl)
|
||||
}
|
||||
|
||||
// func Interface(pkgPath string, methods []abi.Imethod)
|
||||
func (b Builder) abiInterfaceOf(t *types.Interface) Expr {
|
||||
prog := b.Prog
|
||||
@@ -112,21 +127,32 @@ func (b Builder) abiInterfaceOf(t *types.Interface) Expr {
|
||||
|
||||
// func Named(pkgPath, name string, underlying *Type, methods []abi.Method)
|
||||
func (b Builder) abiNamedOf(t *types.Named) Expr {
|
||||
under := b.abiTypeOf(t.Underlying())
|
||||
tunder := t.Underlying()
|
||||
under := b.abiType(tunder)
|
||||
path := abi.PathOf(t.Obj().Pkg())
|
||||
name := NameOf(t)
|
||||
|
||||
prog := b.Prog
|
||||
pkg := b.Pkg
|
||||
fn := pkg.rtFunc("Named")
|
||||
tSlice := lastParamType(prog, fn)
|
||||
// TODO(xsw): methods
|
||||
methods := prog.Zero(tSlice)
|
||||
|
||||
var fn = pkg.rtFunc("Named")
|
||||
var tSlice = lastParamType(prog, fn)
|
||||
var methods Expr
|
||||
if _, ok := tunder.(*types.Interface); ok {
|
||||
methods = prog.Zero(tSlice)
|
||||
} else {
|
||||
n := t.NumMethods()
|
||||
mths := make([]Expr, n)
|
||||
for i := 0; i < n; i++ {
|
||||
m := t.Method(i)
|
||||
mths[i] = b.abiMethodOf(m)
|
||||
}
|
||||
methods = b.SliceLit(tSlice, mths...)
|
||||
}
|
||||
return b.Call(fn, b.Str(path), b.Str(name), under, methods)
|
||||
}
|
||||
|
||||
func (b Builder) abiPointerOf(t *types.Pointer) Expr {
|
||||
elem := b.abiTypeOf(t.Elem())
|
||||
elem := b.abiType(t.Elem())
|
||||
return b.Call(b.Pkg.rtFunc("PointerTo"), elem)
|
||||
}
|
||||
|
||||
@@ -226,8 +252,7 @@ func (b Builder) unsafeInterface(rawIntf *types.Interface, t Expr, data llvm.Val
|
||||
return b.unsafeIface(itab.impl, data)
|
||||
}
|
||||
|
||||
func iMethodOf(rawIntf *types.Interface, method *types.Func) int {
|
||||
name := method.Name()
|
||||
func iMethodOf(rawIntf *types.Interface, name string) int {
|
||||
n := rawIntf.NumMethods()
|
||||
for i := 0; i < n; i++ {
|
||||
m := rawIntf.Method(i)
|
||||
@@ -243,11 +268,11 @@ func iMethodOf(rawIntf *types.Interface, method *types.Func) int {
|
||||
func (b Builder) Imethod(intf Expr, method *types.Func) Expr {
|
||||
prog := b.Prog
|
||||
rawIntf := intf.raw.Type.Underlying().(*types.Interface)
|
||||
i := iMethodOf(rawIntf, method)
|
||||
tclosure := prog.Type(method.Type(), InGo)
|
||||
i := iMethodOf(rawIntf, method.Name())
|
||||
impl := intf.impl
|
||||
itab := Expr{b.faceItab(impl), prog.VoidPtrPtr()}
|
||||
pfn := b.Advance(itab, prog.IntVal(uint64(i+3), prog.Int()))
|
||||
tclosure := prog.Type(method.Type(), InGo)
|
||||
return b.aggregateValue(tclosure, b.Load(pfn).impl, b.faceData(impl))
|
||||
}
|
||||
|
||||
|
||||
@@ -585,12 +585,24 @@ func (p Package) AfterInit(b Builder, ret BasicBlock) {
|
||||
b.SetBlockEx(ret, afterInit, false)
|
||||
if doAbiInit {
|
||||
sigAbiInit := types.NewSignatureType(nil, nil, nil, nil, nil, false)
|
||||
fn := p.NewFunc(p.Path()+".init$abi", sigAbiInit, InC)
|
||||
fnb := fn.MakeBody(1)
|
||||
for _, abiInit := range p.abiini {
|
||||
abiInit(unsafe.Pointer(fnb))
|
||||
baseName := p.Path() + ".init$abi"
|
||||
name := baseName
|
||||
idx := 1
|
||||
fn := p.NewFunc(name, sigAbiInit, InC)
|
||||
for {
|
||||
fnb := fn.MakeBody(1)
|
||||
first := fnb.blk
|
||||
p.callAbiInit(fnb)
|
||||
fnb.Return()
|
||||
if len(p.abiini) == 0 {
|
||||
break
|
||||
}
|
||||
idx++
|
||||
name = baseName + strconv.Itoa(idx)
|
||||
fn = p.NewFunc(name, sigAbiInit, InC)
|
||||
fnb.SetBlockEx(first, AtStart, false)
|
||||
fnb.Call(fn.Expr)
|
||||
}
|
||||
fnb.Return()
|
||||
b.Call(fn.Expr)
|
||||
}
|
||||
if doPyLoadModSyms {
|
||||
@@ -599,6 +611,14 @@ func (p Package) AfterInit(b Builder, ret BasicBlock) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p Package) callAbiInit(fnb Builder) {
|
||||
abiini := p.abiini
|
||||
p.abiini = nil
|
||||
for _, abiInit := range abiini {
|
||||
abiInit(unsafe.Pointer(fnb))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
type CodeGenFileType = llvm.CodeGenFileType
|
||||
|
||||
|
||||
20
ssa/type.go
20
ssa/type.go
@@ -417,4 +417,24 @@ func PathOf(pkg *types.Package) string {
|
||||
return abi.PathOf(pkg)
|
||||
}
|
||||
|
||||
// FuncName:
|
||||
// - func: pkg.name
|
||||
// - method: (pkg.T).name, (*pkg.T).name
|
||||
func FuncName(pkg *types.Package, name string, recv *types.Var) string {
|
||||
if recv != nil {
|
||||
var tName string
|
||||
t := recv.Type()
|
||||
if tp, ok := t.(*types.Pointer); ok {
|
||||
t, tName = tp.Elem(), "*"
|
||||
}
|
||||
tName += NameOf(t.(*types.Named))
|
||||
return "(" + tName + ")." + name
|
||||
}
|
||||
ret := FullName(pkg, name)
|
||||
if ret == "main.main" {
|
||||
ret = "main"
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -125,7 +125,14 @@ func (p goTypes) cvtNamed(t *types.Named) (raw *types.Named, cvt bool) {
|
||||
if named, ok := p.named[id]; ok {
|
||||
return named, false
|
||||
}
|
||||
named := types.NewNamed(t.Obj(), types.Typ[types.Int], nil)
|
||||
|
||||
n := t.NumMethods()
|
||||
methods := make([]*types.Func, n)
|
||||
for i := 0; i < n; i++ {
|
||||
m := t.Method(i) // don't need to convert method signature
|
||||
methods[i] = m
|
||||
}
|
||||
named := types.NewNamed(t.Obj(), types.Typ[types.Int], methods)
|
||||
p.named[id] = named
|
||||
defer delete(p.named, id)
|
||||
if tund, cvt := p.cvtType(t.Underlying()); cvt {
|
||||
|
||||
Reference in New Issue
Block a user