compiler: support exporting method variables in debug info

This commit is contained in:
Evgenii Stratonikov 2020-04-02 16:36:11 +03:00
parent 5bdee683e6
commit 457e7e006a
4 changed files with 31 additions and 0 deletions

View file

@ -286,6 +286,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
for _, spec := range n.Specs {
switch t := spec.(type) {
case *ast.ValueSpec:
for _, id := range t.Names {
c.registerDebugVariable(id.Name, t.Type)
}
if len(t.Values) != 0 {
for i, val := range t.Values {
ast.Walk(c, val)
@ -320,6 +323,11 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
c.convertToken(n.Tok)
l := c.scope.loadLocal(t.Name)
c.emitStoreLocal(l)
case token.DEFINE:
if !multiRet {
c.registerDebugVariable(t.Name, n.Rhs[i])
}
fallthrough
default:
if i == 0 || !multiRet {
ast.Walk(c, n.Rhs[i])

View file

@ -104,6 +104,11 @@ func (c *codegen) emitDebugInfo() *DebugInfo {
return d
}
func (c *codegen) registerDebugVariable(name string, expr ast.Expr) {
typ := c.scTypeFromExpr(expr)
c.scope.variables = append(c.scope.variables, name+","+typ)
}
func (c *codegen) methodInfoFromScope(name string, scope *funcScope) *MethodDebugInfo {
ps := scope.decl.Type.Params
params := make([]DebugParam, 0, ps.NumFields())
@ -122,6 +127,7 @@ func (c *codegen) methodInfoFromScope(name string, scope *funcScope) *MethodDebu
Parameters: params,
ReturnType: c.scReturnTypeFromScope(scope),
SeqPoints: c.sequencePoints[name],
Variables: scope.variables,
}
}

View file

@ -12,6 +12,8 @@ import (
func TestCodeGen_DebugInfo(t *testing.T) {
src := `package foo
func Main(op string) bool {
var s string
_ = s
res := methodInt(op)
_ = methodString()
_ = methodByteArray()
@ -56,6 +58,18 @@ func methodStruct() struct{} { return struct{}{} }
}
})
t.Run("variables", func(t *testing.T) {
vars := map[string][]string{
"Main": {"s,String", "res,Integer"},
}
for i := range d.Methods {
v, ok := vars[d.Methods[i].Name.Name]
if ok {
require.Equal(t, v, d.Methods[i].Variables)
}
}
})
// basic check that last instruction of every method is indeed RET
for i := range d.Methods {
index := d.Methods[i].Range.End

View file

@ -23,6 +23,8 @@ type funcScope struct {
// Range of opcodes corresponding to the function.
rng DebugRange
// Variables together with it's type in neo-vm.
variables []string
// Local variables
locals map[string]int
@ -46,6 +48,7 @@ func newFuncScope(decl *ast.FuncDecl, label uint16) *funcScope {
label: label,
locals: map[string]int{},
voidCalls: map[*ast.CallExpr]bool{},
variables: []string{},
i: -1,
}
}