cli,compiler: support emitting debug info in a file

This commit is contained in:
Evgenii Stratonikov 2020-04-02 15:38:53 +03:00
parent 5d3da26e1e
commit 5bdee683e6
3 changed files with 40 additions and 13 deletions

View file

@ -92,6 +92,10 @@ func NewCommands() []cli.Command {
Name: "debug, d",
Usage: "Debug mode will print out additional information after a compiling",
},
cli.StringFlag{
Name: "emitdebug",
Usage: "Emit debug info in a separate file",
},
},
},
{
@ -348,6 +352,8 @@ func contractCompile(ctx *cli.Context) error {
o := &compiler.Options{
Outfile: ctx.String("out"),
Debug: ctx.Bool("debug"),
DebugInfo: ctx.String("emitdebug"),
}
result, err := compiler.CompileAndSave(src, o)

View file

@ -1313,19 +1313,19 @@ func newCodegen(info *buildInfo, pkg *loader.PackageInfo) *codegen {
}
// CodeGen compiles the program to bytecode.
func CodeGen(info *buildInfo) ([]byte, error) {
func CodeGen(info *buildInfo) ([]byte, *DebugInfo, error) {
pkg := info.program.Package(info.initialPackage)
c := newCodegen(info, pkg)
if err := c.compile(info, pkg); err != nil {
return nil, err
return nil, nil, err
}
buf := c.prog.Bytes()
if err := c.writeJumps(buf); err != nil {
return nil, err
return nil, nil, err
}
return buf, nil
return buf, c.emitDebugInfo(), nil
}
func (c *codegen) resolveFuncDecls(f *ast.File) {

View file

@ -2,11 +2,13 @@ package compiler
import (
"bytes"
"encoding/json"
"fmt"
"go/parser"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"golang.org/x/tools/go/loader"
@ -22,6 +24,9 @@ type Options struct {
// The name of the output file.
Outfile string
// The name of the output for debug info.
DebugInfo string
// Debug outputs a hex encoded string of the generated bytecode.
Debug bool
}
@ -52,12 +57,7 @@ func getBuildInfo(src interface{}) (*buildInfo, error) {
// Compile compiles a Go program into bytecode that can run on the NEO virtual machine.
func Compile(r io.Reader) ([]byte, error) {
ctx, err := getBuildInfo(r)
if err != nil {
return nil, err
}
buf, err := CodeGen(ctx)
buf, _, err := CompileWithDebugInfo(r)
if err != nil {
return nil, err
}
@ -65,6 +65,15 @@ func Compile(r io.Reader) ([]byte, error) {
return buf, nil
}
// CompileWithDebugInfo compiles a Go program into bytecode and emits debug info.
func CompileWithDebugInfo(r io.Reader) ([]byte, *DebugInfo, error) {
ctx, err := getBuildInfo(r)
if err != nil {
return nil, nil, err
}
return CodeGen(ctx)
}
// CompileAndSave will compile and save the file to disk.
func CompileAndSave(src string, o *Options) ([]byte, error) {
if !strings.HasSuffix(src, ".go") {
@ -81,11 +90,23 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
if err != nil {
return nil, err
}
b, err = Compile(bytes.NewReader(b))
b, di, err := CompileWithDebugInfo(bytes.NewReader(b))
if err != nil {
return nil, fmt.Errorf("error while trying to compile smart contract file: %v", err)
}
out := fmt.Sprintf("%s.%s", o.Outfile, o.Ext)
return b, ioutil.WriteFile(out, b, os.ModePerm)
err = ioutil.WriteFile(out, b, os.ModePerm)
if o.DebugInfo == "" {
return b, err
}
p, err := filepath.Abs(src)
if err != nil {
return b, err
}
di.Documents = append(di.Documents, p)
data, err := json.Marshal(di)
if err != nil {
return b, err
}
return b, ioutil.WriteFile(o.DebugInfo, data, os.ModePerm)
}