Merge pull request #433 from xushiwei/q

abitype: support Patch (Clone + Merge); patch: os.File
This commit is contained in:
xushiwei
2024-07-01 19:09:32 +08:00
committed by GitHub
15 changed files with 567 additions and 202 deletions

View File

@@ -227,7 +227,7 @@ func TestErrImport(t *testing.T) {
alt.Scope().Insert(
types.NewConst(0, alt, "LLGoPackage", types.Typ[types.String], constant.MakeString("noinit")),
)
ctx.patches = Patches{"foo": &ssa.Package{Pkg: alt}}
ctx.patches = Patches{"foo": Patch{Alt: &ssa.Package{Pkg: alt}, Types: alt}}
ctx.importPkg(pkg, &pkgInfo{})
}

View File

@@ -77,7 +77,7 @@ type pkgInfo struct {
kind int
}
type none struct{}
type none = struct{}
type context struct {
prog llssa.Program
@@ -539,7 +539,8 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
}
}
}
t := p.prog.Type(v.Type(), llssa.InGo)
prog := p.prog
t := prog.Type(v.Type(), llssa.InGo)
x := p.compileValue(b, v.X)
ret = b.MakeInterface(t, x)
case *ssa.MakeSlice:
@@ -734,8 +735,14 @@ func (p *context) compileValues(b llssa.Builder, vals []ssa.Value, hasVArg int)
// -----------------------------------------------------------------------------
// Patch is a patch of some package.
type Patch struct {
Alt *ssa.Package
Types *types.Package
}
// Patches is patches of some packages.
type Patches = map[string]*ssa.Package
type Patches = map[string]Patch
// NewPackage compiles a Go package to LLVM IR package.
func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret llssa.Package, err error) {
@@ -746,12 +753,13 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
func NewPackageEx(prog llssa.Program, patches Patches, pkg *ssa.Package, files []*ast.File) (ret llssa.Package, err error) {
pkgProg := pkg.Prog
pkgTypes := pkg.Pkg
oldTypes := pkgTypes
pkgName, pkgPath := pkgTypes.Name(), llssa.PathOf(pkgTypes)
alt, hasPatch := patches[pkgPath]
patch, hasPatch := patches[pkgPath]
if hasPatch {
pkgTypes = typepatch.Pkg(pkgTypes, alt.Pkg)
pkgTypes = patch.Types
pkg.Pkg = pkgTypes
alt.Pkg = pkgTypes
patch.Alt.Pkg = pkgTypes
}
if pkgPath == llssa.PkgRuntime {
prog.SetRuntime(pkgTypes)
@@ -775,15 +783,17 @@ func NewPackageEx(prog llssa.Program, patches Patches, pkg *ssa.Package, files [
}
ctx.initPyModule()
ctx.initFiles(pkgPath, files)
ret.SetPatch(ctx.patchType)
if hasPatch {
skips := ctx.skips
typepatch.Merge(pkgTypes, oldTypes, skips, ctx.skipall)
ctx.skips = nil
ctx.state = pkgInPatch
if _, ok := skips["init"]; ok || ctx.skipall {
ctx.state |= pkgFNoOldInit
}
processPkg(ctx, ret, alt)
processPkg(ctx, ret, patch.Alt)
ctx.state = pkgHasPatch
ctx.skips = skips
}
@@ -844,10 +854,26 @@ func globalType(gbl *ssa.Global) types.Type {
if t, ok := t.(*types.Named); ok {
o := t.Obj()
if pkg := o.Pkg(); typepatch.IsPatched(pkg) {
return gbl.Pkg.Pkg.Scope().Lookup(o.Name()).Type()
if patch := gbl.Pkg.Pkg.Scope().Lookup(o.Name()); patch != nil {
return patch.Type()
}
}
}
return t
}
func (p *context) patchType(typ types.Type) types.Type {
if t, ok := typ.(*types.Named); ok {
o := t.Obj()
if pkg := o.Pkg(); typepatch.IsPatched(pkg) {
if patch, ok := p.patches[pkg.Path()]; ok {
if obj := patch.Types.Scope().Lookup(o.Name()); obj != nil {
return p.prog.Type(obj.Type(), llssa.InGo).RawType()
}
}
}
}
return typ
}
// -----------------------------------------------------------------------------

View File

@@ -132,8 +132,8 @@ func (p *context) importPkg(pkg *types.Package, i *pkgInfo) {
scope := pkg.Scope()
kind, _ := pkgKindByScope(scope)
if kind == PkgNormal {
if alt, ok := p.patches[pkgPath]; ok {
pkg = alt.Pkg
if patch, ok := p.patches[pkgPath]; ok {
pkg = patch.Alt.Pkg
scope = pkg.Scope()
if kind, _ = pkgKindByScope(scope); kind != PkgNormal {
goto start