Merge pull request #352 from xushiwei/q
cl: fn.SetRecover; patch library: call init
This commit is contained in:
8
cl/_testlibgo/_errors/in.go
Normal file
8
cl/_testlibgo/_errors/in.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := errors.New("error")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
@@ -100,12 +100,23 @@ type context struct {
|
|||||||
inits []func()
|
inits []func()
|
||||||
phis []func()
|
phis []func()
|
||||||
|
|
||||||
|
state pkgState
|
||||||
inCFunc bool
|
inCFunc bool
|
||||||
skipall bool
|
skipall bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type pkgState byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
pkgNormal pkgState = iota
|
||||||
|
pkgHasPatch
|
||||||
|
pkgInPatch
|
||||||
|
|
||||||
|
pkgFNoOldInit = 0x80 // flag if no initFnNameOld
|
||||||
|
)
|
||||||
|
|
||||||
func (p *context) inMain(instr ssa.Instruction) bool {
|
func (p *context) inMain(instr ssa.Instruction) bool {
|
||||||
return instr.Parent().Name() == "main"
|
return p.fn.Name() == "main"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
|
func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
|
||||||
@@ -184,6 +195,8 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
|
|||||||
return fn, nil, goFunc
|
return fn, nil, goFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isInit bool
|
||||||
|
var state = p.state
|
||||||
var sig = f.Signature
|
var sig = f.Signature
|
||||||
var hasCtx = len(f.FreeVars) > 0
|
var hasCtx = len(f.FreeVars) > 0
|
||||||
if hasCtx {
|
if hasCtx {
|
||||||
@@ -196,6 +209,7 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
|
|||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig, "ftype:", ftype)
|
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig, "ftype:", ftype)
|
||||||
}
|
}
|
||||||
|
isInit = (f.Name() == "init" && sig.Recv() == nil)
|
||||||
}
|
}
|
||||||
if fn == nil {
|
if fn == nil {
|
||||||
if name == "main" {
|
if name == "main" {
|
||||||
@@ -205,14 +219,20 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
|
|||||||
ret := types.NewParam(token.NoPos, pkgTypes, "", p.prog.CInt().RawType())
|
ret := types.NewParam(token.NoPos, pkgTypes, "", p.prog.CInt().RawType())
|
||||||
results := types.NewTuple(ret)
|
results := types.NewTuple(ret)
|
||||||
sig = types.NewSignatureType(nil, nil, nil, params, results, false)
|
sig = types.NewSignatureType(nil, nil, nil, params, results, false)
|
||||||
|
} else if isInit && state == pkgHasPatch {
|
||||||
|
name = initFnNameOfHasPatch(name)
|
||||||
}
|
}
|
||||||
fn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), hasCtx)
|
fn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), hasCtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if nblk := len(f.Blocks); nblk > 0 {
|
if nblk := len(f.Blocks); nblk > 0 {
|
||||||
fn.MakeBlocks(nblk) // to set fn.HasBody() = true
|
fn.MakeBlocks(nblk) // to set fn.HasBody() = true
|
||||||
|
if f.Recover != nil { // set recover block
|
||||||
|
fn.SetRecover(fn.Block(f.Recover.Index))
|
||||||
|
}
|
||||||
p.inits = append(p.inits, func() {
|
p.inits = append(p.inits, func() {
|
||||||
p.fn = fn
|
p.fn = fn
|
||||||
|
p.state = state // restore pkgState when compiling funcBody
|
||||||
defer func() {
|
defer func() {
|
||||||
p.fn = nil
|
p.fn = nil
|
||||||
}()
|
}()
|
||||||
@@ -234,7 +254,7 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
|
|||||||
for {
|
for {
|
||||||
block := f.Blocks[i]
|
block := f.Blocks[i]
|
||||||
doMainInit := (i == 0 && name == "main")
|
doMainInit := (i == 0 && name == "main")
|
||||||
doModInit := (i == 1 && f.Name() == "init" && sig.Recv() == nil)
|
doModInit := (i == 1 && isInit)
|
||||||
p.compileBlock(b, block, off[i], doMainInit, doModInit)
|
p.compileBlock(b, block, off[i], doMainInit, doModInit)
|
||||||
if i = p.blkInfos[i].Next; i < 0 {
|
if i = p.blkInfos[i].Next; i < 0 {
|
||||||
break
|
break
|
||||||
@@ -257,8 +277,9 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
|
|||||||
var pyModInit bool
|
var pyModInit bool
|
||||||
var prog = p.prog
|
var prog = p.prog
|
||||||
var pkg = p.pkg
|
var pkg = p.pkg
|
||||||
|
var fn = p.fn
|
||||||
var instrs = block.Instrs[n:]
|
var instrs = block.Instrs[n:]
|
||||||
var ret = p.fn.Block(block.Index)
|
var ret = fn.Block(block.Index)
|
||||||
b.SetBlock(ret)
|
b.SetBlock(ret)
|
||||||
if doModInit {
|
if doModInit {
|
||||||
if pyModInit = p.pyMod != ""; pyModInit {
|
if pyModInit = p.pyMod != ""; pyModInit {
|
||||||
@@ -271,7 +292,6 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if doMainInit {
|
} else if doMainInit {
|
||||||
fn := p.fn
|
|
||||||
argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC)
|
argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC)
|
||||||
argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC)
|
argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC)
|
||||||
argc.InitNil()
|
argc.InitNil()
|
||||||
@@ -281,7 +301,12 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
|
|||||||
callRuntimeInit(b, pkg)
|
callRuntimeInit(b, pkg)
|
||||||
b.Call(pkg.FuncOf("main.init").Expr)
|
b.Call(pkg.FuncOf("main.init").Expr)
|
||||||
}
|
}
|
||||||
for _, instr := range instrs {
|
for i, instr := range instrs {
|
||||||
|
if i == 1 && doModInit && p.state == pkgInPatch {
|
||||||
|
initFnNameOld := initFnNameOfHasPatch(p.fn.Name())
|
||||||
|
fnOld := pkg.NewFunc(initFnNameOld, llssa.NoArgsNoRet, llssa.InC)
|
||||||
|
b.Call(fnOld.Expr)
|
||||||
|
}
|
||||||
p.compileInstr(b, instr)
|
p.compileInstr(b, instr)
|
||||||
}
|
}
|
||||||
if pyModInit {
|
if pyModInit {
|
||||||
@@ -292,7 +317,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
|
|||||||
modPtr := pkg.PyNewModVar(modName, true).Expr
|
modPtr := pkg.PyNewModVar(modName, true).Expr
|
||||||
mod := b.Load(modPtr)
|
mod := b.Load(modPtr)
|
||||||
cond := b.BinOp(token.NEQ, mod, prog.Nil(mod.Type))
|
cond := b.BinOp(token.NEQ, mod, prog.Nil(mod.Type))
|
||||||
newBlk := p.fn.MakeBlock()
|
newBlk := fn.MakeBlock()
|
||||||
b.If(cond, jumpTo, newBlk)
|
b.If(cond, jumpTo, newBlk)
|
||||||
b.SetBlockEx(newBlk, llssa.AtEnd, false)
|
b.SetBlockEx(newBlk, llssa.AtEnd, false)
|
||||||
b.Store(modPtr, b.PyImportMod(modPath))
|
b.Store(modPtr, b.PyImportMod(modPath))
|
||||||
@@ -377,9 +402,6 @@ func isPhi(i ssa.Instruction) bool {
|
|||||||
func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
|
func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
|
||||||
fn := p.fn
|
fn := p.fn
|
||||||
ret := fn.Block(block.Index)
|
ret := fn.Block(block.Index)
|
||||||
if block.Comment == "recover" { // set recover block
|
|
||||||
fn.SetRecover(ret)
|
|
||||||
}
|
|
||||||
b.SetBlockEx(ret, llssa.AtEnd, false)
|
b.SetBlockEx(ret, llssa.AtEnd, false)
|
||||||
if ninstr := len(block.Instrs); ninstr > 0 {
|
if ninstr := len(block.Instrs); ninstr > 0 {
|
||||||
if isPhi(block.Instrs[0]) {
|
if isPhi(block.Instrs[0]) {
|
||||||
@@ -752,7 +774,12 @@ func NewPackageEx(prog llssa.Program, patches Patches, pkg *ssa.Package, files [
|
|||||||
if hasPatch {
|
if hasPatch {
|
||||||
skips := ctx.skips
|
skips := ctx.skips
|
||||||
ctx.skips = nil
|
ctx.skips = nil
|
||||||
|
ctx.state = pkgInPatch
|
||||||
|
if _, ok := skips["init"]; ok || ctx.skipall {
|
||||||
|
ctx.state |= pkgFNoOldInit
|
||||||
|
}
|
||||||
processPkg(ctx, ret, alt)
|
processPkg(ctx, ret, alt)
|
||||||
|
ctx.state = pkgHasPatch
|
||||||
ctx.skips = skips
|
ctx.skips = skips
|
||||||
}
|
}
|
||||||
if !ctx.skipall {
|
if !ctx.skipall {
|
||||||
@@ -768,6 +795,10 @@ func NewPackageEx(prog llssa.Program, patches Patches, pkg *ssa.Package, files [
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initFnNameOfHasPatch(name string) string {
|
||||||
|
return name + "$hasPatch"
|
||||||
|
}
|
||||||
|
|
||||||
func processPkg(ctx *context, ret llssa.Package, pkg *ssa.Package) {
|
func processPkg(ctx *context, ret llssa.Package, pkg *ssa.Package) {
|
||||||
type namedMember struct {
|
type namedMember struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -507,8 +507,7 @@ func ignoreName(name string) bool {
|
|||||||
strings.HasPrefix(name, "arena.") || strings.HasPrefix(name, "maps.") ||
|
strings.HasPrefix(name, "arena.") || strings.HasPrefix(name, "maps.") ||
|
||||||
strings.HasPrefix(name, "time.") || strings.HasPrefix(name, "syscall.") ||
|
strings.HasPrefix(name, "time.") || strings.HasPrefix(name, "syscall.") ||
|
||||||
strings.HasPrefix(name, "os.") || strings.HasPrefix(name, "plugin.") ||
|
strings.HasPrefix(name, "os.") || strings.HasPrefix(name, "plugin.") ||
|
||||||
strings.HasPrefix(name, "reflect.") || strings.HasPrefix(name, "errors.") ||
|
strings.HasPrefix(name, "reflect.") || strings.HasPrefix(name, "runtime/")
|
||||||
strings.HasPrefix(name, "runtime/")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -706,7 +706,7 @@ func decodeFile(outFile string, zipf *zip.File) (err error) {
|
|||||||
|
|
||||||
func canSkipToBuild(pkgPath string) bool {
|
func canSkipToBuild(pkgPath string) bool {
|
||||||
switch pkgPath {
|
switch pkgPath {
|
||||||
case "unsafe", "errors": // TODO(xsw): remove it
|
case "unsafe":
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return strings.HasPrefix(pkgPath, "internal/") ||
|
return strings.HasPrefix(pkgPath, "internal/") ||
|
||||||
@@ -717,6 +717,7 @@ func canSkipToBuild(pkgPath string) bool {
|
|||||||
type none struct{}
|
type none struct{}
|
||||||
|
|
||||||
var hasAltPkg = map[string]none{
|
var hasAltPkg = map[string]none{
|
||||||
|
"errors": {},
|
||||||
"math": {},
|
"math": {},
|
||||||
"sync": {},
|
"sync": {},
|
||||||
"sync/atomic": {},
|
"sync/atomic": {},
|
||||||
|
|||||||
17
internal/lib/errors/errors.go
Normal file
17
internal/lib/errors/errors.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package errors
|
||||||
@@ -234,12 +234,10 @@ func newParams(fn Type, prog Program) (params []Type, hasVArg bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Name returns the function's name.
|
// Name returns the function's name.
|
||||||
func (p Function) Name() string {
|
func (p Function) Name() string {
|
||||||
return p.impl.Name()
|
return p.impl.Name()
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Params returns the function's ith parameter.
|
// Params returns the function's ith parameter.
|
||||||
func (p Function) Param(i int) Expr {
|
func (p Function) Param(i int) Expr {
|
||||||
|
|||||||
Reference in New Issue
Block a user