compiler: support recover()

This commit is contained in:
Evgenii Stratonikov 2020-08-21 15:37:46 +03:00
parent 14ea3c2228
commit 5d82b82efb
4 changed files with 153 additions and 9 deletions

View file

@ -32,6 +32,9 @@ type funcScope struct {
// deferStack is a stack containing encountered `defer` statements.
deferStack []deferInfo
// finallyProcessed is a index of static slot with boolean flag determining
// if `defer` statement was already processed.
finallyProcessedIndex int
// Local variables
vars varScope
@ -49,6 +52,7 @@ type funcScope struct {
}
type deferInfo struct {
catchLabel uint16
finallyLabel uint16
expr *ast.CallExpr
}
@ -123,6 +127,7 @@ func (c *funcScope) analyzeVoidCalls(node ast.Node) bool {
func (c *funcScope) countLocals() int {
size := 0
hasDefer := false
ast.Inspect(c.decl, func(n ast.Node) bool {
switch n := n.(type) {
case *ast.FuncType:
@ -134,6 +139,9 @@ func (c *funcScope) countLocals() int {
if n.Tok == token.DEFINE {
size += len(n.Lhs)
}
case *ast.DeferStmt:
hasDefer = true
return false
case *ast.ReturnStmt, *ast.IfStmt:
size++
// This handles the inline GenDecl like "var x = 2"
@ -151,6 +159,10 @@ func (c *funcScope) countLocals() int {
}
return true
})
if hasDefer {
c.finallyProcessedIndex = size
size++
}
return size
}