cl: compile async functions

This commit is contained in:
Li Jie
2024-08-04 09:54:34 +08:00
parent 806193fc6e
commit efa771f3ff
18 changed files with 1127 additions and 1103 deletions

View File

@@ -214,6 +214,7 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig, "ftype:", ftype)
}
}
async := isAsyncFunc(f.Signature)
if fn == nil {
if name == "main" {
argc := types.NewParam(token.NoPos, pkgTypes, "", types.Typ[types.Int32])
@@ -223,13 +224,20 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
results := types.NewTuple(ret)
sig = types.NewSignatureType(nil, nil, nil, params, results, false)
}
fn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), hasCtx)
fn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), hasCtx, async)
}
nBlkOff := 0
if nblk := len(f.Blocks); nblk > 0 {
if async {
nBlkOff = 4
fn.MakeBlock("entry")
fn.MakeBlock("alloc")
fn.MakeBlock("clean")
fn.MakeBlock("suspend")
}
fn.MakeBlocks(nblk) // to set fn.HasBody() = true
if f.Recover != nil { // set recover block
fn.SetRecover(fn.Block(f.Recover.Index))
fn.SetRecover(fn.Block(f.Recover.Index + nBlkOff))
}
p.inits = append(p.inits, func() {
p.fn = fn
@@ -245,6 +253,10 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
log.Println("==> FuncBody", name)
}
b := fn.NewBuilder()
b.SetBlockOffset(nBlkOff)
if async {
b.BeginAsync(fn)
}
p.bvals = make(map[ssa.Value]llssa.Expr)
off := make([]int, len(f.Blocks))
for i, block := range f.Blocks {
@@ -280,7 +292,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
var pkg = p.pkg
var fn = p.fn
var instrs = block.Instrs[n:]
var ret = fn.Block(block.Index)
var ret = fn.Block(block.Index + b.BlockOffset())
b.SetBlock(ret)
if doModInit {
if pyModInit = p.pyMod != ""; pyModInit {
@@ -650,7 +662,11 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
results = make([]llssa.Expr, 1)
results[0] = p.prog.IntVal(0, p.prog.CInt())
}
b.Return(results...)
if b.Async() {
b.EndAsync()
} else {
b.Return(results...)
}
case *ssa.If:
fn := p.fn
cond := p.compileValue(b, v.Cond)