compiler: support exporting method variables in debug info
This commit is contained in:
parent
5bdee683e6
commit
457e7e006a
4 changed files with 31 additions and 0 deletions
|
@ -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])
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue