*: support _initialize
method in contracts
Invoke `_initialize` method on every call if present. In NEO3 there is no entrypoint and methods are invoked by offset, thus `Main` function is no longer required. We still have special `Main` method in tests to simplify them.
This commit is contained in:
parent
466af55dea
commit
685d44dbc1
9 changed files with 156 additions and 40 deletions
|
@ -21,9 +21,6 @@ import (
|
|||
"golang.org/x/tools/go/loader"
|
||||
)
|
||||
|
||||
// The identifier of the entry function. Default set to Main.
|
||||
const mainIdent = "Main"
|
||||
|
||||
type codegen struct {
|
||||
// Information about the program with all its dependencies.
|
||||
buildInfo *buildInfo
|
||||
|
@ -62,6 +59,12 @@ type codegen struct {
|
|||
// to a text span in the source file.
|
||||
sequencePoints map[string][]DebugSeqPoint
|
||||
|
||||
// initEndOffset specifies the end of the initialization method.
|
||||
initEndOffset int
|
||||
|
||||
// mainPkg is a main package metadata.
|
||||
mainPkg *loader.PackageInfo
|
||||
|
||||
// Label table for recording jump destinations.
|
||||
l []int
|
||||
}
|
||||
|
@ -1412,13 +1415,6 @@ func (c *codegen) newLambda(u uint16, lit *ast.FuncLit) {
|
|||
}
|
||||
|
||||
func (c *codegen) compile(info *buildInfo, pkg *loader.PackageInfo) error {
|
||||
// Resolve the entrypoint of the program.
|
||||
main, mainFile := resolveEntryPoint(mainIdent, pkg)
|
||||
if main == nil {
|
||||
c.prog.Err = fmt.Errorf("could not find func main. Did you forget to declare it? ")
|
||||
return c.prog.Err
|
||||
}
|
||||
|
||||
funUsage := analyzeFuncUsage(pkg, info.program.AllPackages)
|
||||
|
||||
// Bring all imported functions into scope.
|
||||
|
@ -1428,10 +1424,12 @@ func (c *codegen) compile(info *buildInfo, pkg *loader.PackageInfo) error {
|
|||
}
|
||||
}
|
||||
|
||||
c.traverseGlobals(mainFile)
|
||||
|
||||
// convert the entry point first.
|
||||
c.convertFuncDecl(mainFile, main, pkg.Pkg)
|
||||
c.mainPkg = pkg
|
||||
n := c.traverseGlobals(pkg.Files...)
|
||||
if n > 0 {
|
||||
emit.Opcode(c.prog.BinWriter, opcode.RET)
|
||||
c.initEndOffset = c.prog.Len()
|
||||
}
|
||||
|
||||
// sort map keys to generate code deterministically.
|
||||
keys := make([]*types.Package, 0, len(info.program.AllPackages))
|
||||
|
@ -1451,7 +1449,7 @@ func (c *codegen) compile(info *buildInfo, pkg *loader.PackageInfo) error {
|
|||
case *ast.FuncDecl:
|
||||
// Don't convert the function if it's not used. This will save a lot
|
||||
// of bytecode space.
|
||||
if n.Name.Name != mainIdent && funUsage.funcUsed(n.Name.Name) {
|
||||
if funUsage.funcUsed(n.Name.Name) {
|
||||
c.convertFuncDecl(f, n, k)
|
||||
}
|
||||
}
|
||||
|
@ -1497,10 +1495,8 @@ func (c *codegen) resolveFuncDecls(f *ast.File, pkg *types.Package) {
|
|||
for _, decl := range f.Decls {
|
||||
switch n := decl.(type) {
|
||||
case *ast.FuncDecl:
|
||||
if n.Name.Name != mainIdent {
|
||||
c.newFunc(n)
|
||||
c.funcs[n.Name.Name].pkg = pkg
|
||||
}
|
||||
c.newFunc(n)
|
||||
c.funcs[n.Name.Name].pkg = pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue