Fix/bugs (CityOfZion/neo-storm#38)
* Fixed bug where void functions cleaned up their mess multiple times * Compiler improvements * Fixed Neo APIs naming convention * Added NOP after syscall for matching AVM files with neo-python. Imported from CityOfZion/neo-storm (f93a28ef87d272a74f821d45ae0c6735a8c610be).
This commit is contained in:
parent
f547708e10
commit
b97e5aafec
2 changed files with 39 additions and 48 deletions
|
@ -87,18 +87,13 @@ func (c *codegen) emitLoadLocal(name string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *codegen) emitLoadLocalPos(pos int) {
|
func (c *codegen) emitLoadLocalPos(pos int) {
|
||||||
emitOpcode(c.prog, vm.FROMALTSTACK)
|
emitOpcode(c.prog, vm.DUPFROMALTSTACK)
|
||||||
emitOpcode(c.prog, vm.DUP)
|
|
||||||
emitOpcode(c.prog, vm.TOALTSTACK)
|
|
||||||
|
|
||||||
emitInt(c.prog, int64(pos))
|
emitInt(c.prog, int64(pos))
|
||||||
emitOpcode(c.prog, vm.PICKITEM)
|
emitOpcode(c.prog, vm.PICKITEM)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *codegen) emitStoreLocal(pos int) {
|
func (c *codegen) emitStoreLocal(pos int) {
|
||||||
emitOpcode(c.prog, vm.FROMALTSTACK)
|
emitOpcode(c.prog, vm.DUPFROMALTSTACK)
|
||||||
emitOpcode(c.prog, vm.DUP)
|
|
||||||
emitOpcode(c.prog, vm.TOALTSTACK)
|
|
||||||
|
|
||||||
if pos < 0 {
|
if pos < 0 {
|
||||||
log.Fatalf("invalid position to store local: %d", pos)
|
log.Fatalf("invalid position to store local: %d", pos)
|
||||||
|
@ -144,6 +139,10 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl) {
|
||||||
|
|
||||||
f, ok = c.funcs[decl.Name.Name]
|
f, ok = c.funcs[decl.Name.Name]
|
||||||
if ok {
|
if ok {
|
||||||
|
// If this function is a syscall we will not convert it to bytecode.
|
||||||
|
if isSyscall(f) {
|
||||||
|
return
|
||||||
|
}
|
||||||
c.setLabel(f.label)
|
c.setLabel(f.label)
|
||||||
} else {
|
} else {
|
||||||
f = c.newFunc(decl)
|
f = c.newFunc(decl)
|
||||||
|
@ -262,14 +261,13 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
// To be backwards compatible we will put them them in.
|
// To be backwards compatible we will put them them in.
|
||||||
// See issue #65 (https://github.com/CityOfZion/neo-go/issues/65)
|
// See issue #65 (https://github.com/CityOfZion/neo-go/issues/65)
|
||||||
l := c.newLabel()
|
l := c.newLabel()
|
||||||
emitJmp(c.prog, vm.JMP, int16(l))
|
// emitJmp(c.prog, vm.JMP, int16(l))
|
||||||
c.setLabel(l)
|
c.setLabel(l)
|
||||||
|
|
||||||
if len(n.Results) > 0 {
|
if len(n.Results) > 0 {
|
||||||
ast.Walk(c, n.Results[0])
|
ast.Walk(c, n.Results[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
emitOpcode(c.prog, vm.NOP) // @OPTIMIZE
|
|
||||||
emitOpcode(c.prog, vm.FROMALTSTACK)
|
emitOpcode(c.prog, vm.FROMALTSTACK)
|
||||||
emitOpcode(c.prog, vm.DROP) // Cleanup the stack.
|
emitOpcode(c.prog, vm.DROP) // Cleanup the stack.
|
||||||
emitOpcode(c.prog, vm.RET)
|
emitOpcode(c.prog, vm.RET)
|
||||||
|
@ -425,11 +423,6 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// c# compiler adds a NOP (0x61) before every function call. Dont think its relevant
|
|
||||||
// and we could easily removed it, but to be consistent with the original compiler I
|
|
||||||
// will put them in. ^^
|
|
||||||
emitOpcode(c.prog, vm.NOP)
|
|
||||||
|
|
||||||
// Check builtin first to avoid nil pointer on funcScope!
|
// Check builtin first to avoid nil pointer on funcScope!
|
||||||
switch {
|
switch {
|
||||||
case isBuiltin:
|
case isBuiltin:
|
||||||
|
@ -442,11 +435,6 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
emitCall(c.prog, vm.CALL, int16(f.label))
|
emitCall(c.prog, vm.CALL, int16(f.label))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are not assigning this function to a variable we need to drop
|
|
||||||
// (cleanup) the top stack item. It's not a void but you get the point \o/.
|
|
||||||
if _, ok := c.scope.voidCalls[n]; ok {
|
|
||||||
emitOpcode(c.prog, vm.DROP)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
|
@ -540,7 +528,10 @@ func (c *codegen) convertSyscall(api, name string) {
|
||||||
log.Fatalf("unknown VM syscall api: %s", name)
|
log.Fatalf("unknown VM syscall api: %s", name)
|
||||||
}
|
}
|
||||||
emitSyscall(c.prog, api)
|
emitSyscall(c.prog, api)
|
||||||
emitOpcode(c.prog, vm.NOP) // @OPTIMIZE
|
|
||||||
|
// This NOP instruction is basically not needed, but if we do, we have a
|
||||||
|
// one to one matching avm file with neo-python which is very nice for debugging.
|
||||||
|
emitOpcode(c.prog, vm.NOP)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
||||||
|
|
|
@ -2,45 +2,45 @@ package compiler
|
||||||
|
|
||||||
var syscalls = map[string]map[string]string{
|
var syscalls = map[string]map[string]string{
|
||||||
"storage": {
|
"storage": {
|
||||||
"GetContext": "System.Storage.GetContext",
|
"GetContext": "Neo.Storage.GetContext",
|
||||||
"Put": "System.Storage.Put",
|
"Put": "Neo.Storage.Put",
|
||||||
"Get": "System.Storage.Get",
|
"Get": "Neo.Storage.Get",
|
||||||
"Delete": "System.Storage.Delete",
|
"Delete": "Neo.Storage.Delete",
|
||||||
"Find": "System.Storage.Find",
|
"Find": "Neo.Storage.Find",
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"GetTrigger": "System.Runtime.GetTrigger",
|
"GetTrigger": "Neo.Runtime.GetTrigger",
|
||||||
"CheckWitness": "System.Runtime.CheckWitness",
|
"CheckWitness": "Neo.Runtime.CheckWitness",
|
||||||
"Notify": "System.Runtime.Notify",
|
"Notify": "Neo.Runtime.Notify",
|
||||||
"Log": "System.Runtime.Log",
|
"Log": "Neo.Runtime.Log",
|
||||||
"GetTime": "System.Runtime.GetTime",
|
"GetTime": "Neo.Runtime.GetTime",
|
||||||
"Serialize": "System.Runtime.Serialize",
|
"Serialize": "Neo.Runtime.Serialize",
|
||||||
"Deserialize": "System.Runtime.Deserialize",
|
"Deserialize": "Neo.Runtime.Deserialize",
|
||||||
},
|
},
|
||||||
"blockchain": {
|
"blockchain": {
|
||||||
"GetHeight": "System.Blockchain.GetHeight",
|
"GetHeight": "Neo.Blockchain.GetHeight",
|
||||||
"GetHeader": "System.Blockchain.GetHeader",
|
"GetHeader": "Neo.Blockchain.GetHeader",
|
||||||
"GetBlock": "System.Blockchain.GetBlock",
|
"GetBlock": "Neo.Blockchain.GetBlock",
|
||||||
"GetTransaction": "System.Blockchain.GetTransaction",
|
"GetTransaction": "Neo.Blockchain.GetTransaction",
|
||||||
"GetContract": "System.Blockchain.GetContract",
|
"GetContract": "Neo.Blockchain.GetContract",
|
||||||
"GetAccount": "Neo.Blockchain.GetAccount",
|
"GetAccount": "Neo.Blockchain.GetAccount",
|
||||||
"GetValidators": "Neo.Blockchain.GetValidators",
|
"GetValidators": "Neo.Blockchain.GetValidators",
|
||||||
"GetAsset": "Neo.Blockchain.GetAsset",
|
"GetAsset": "Neo.Blockchain.GetAsset",
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"GetIndex": "System.Header.GetIndex",
|
"GetIndex": "Neo.Header.GetIndex",
|
||||||
"GetHash": "System.Header.GetHash",
|
"GetHash": "Neo.Header.GetHash",
|
||||||
"GetPrevHash": "System.Header.GetPrevHash",
|
"GetPrevHash": "Neo.Header.GetPrevHash",
|
||||||
"GetTimestamp": "System.Header.GetTimestamp",
|
"GetTimestamp": "Neo.Header.GetTimestamp",
|
||||||
"GetVersion": "Neo.Header.GetVersion",
|
"GetVersion": "Neo.Header.GetVersion",
|
||||||
"GetMerkleRoot": "Neo.Header.GetMerkleRoot",
|
"GetMerkleRoot": "Neo.Header.GetMerkleRoot",
|
||||||
"GetConsensusData": "Neo.Header.GetConsensusData",
|
"GetConsensusData": "Neo.Header.GetConsensusData",
|
||||||
"GetNextConsensus": "Neo.Header.GetNextConsensus",
|
"GetNextConsensus": "Neo.Header.GetNextConsensus",
|
||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"GetTransactionCount": "System.Block.GetTransactionCount",
|
"GetTransactionCount": "Neo.Block.GetTransactionCount",
|
||||||
"GetTransactions": "System.Block.GetTransactions",
|
"GetTransactions": "Neo.Block.GetTransactions",
|
||||||
"GetTransaction": "System.Block.GetTransaction",
|
"GetTransaction": "Neo.Block.GetTransaction",
|
||||||
},
|
},
|
||||||
"transaction": {
|
"transaction": {
|
||||||
"GetType": "Neo.Transaction.GetType",
|
"GetType": "Neo.Transaction.GetType",
|
||||||
|
@ -76,10 +76,10 @@ var syscalls = map[string]map[string]string{
|
||||||
"GetScriptHash": "Neo.Output.GetScriptHash",
|
"GetScriptHash": "Neo.Output.GetScriptHash",
|
||||||
},
|
},
|
||||||
"engine": {
|
"engine": {
|
||||||
"GetScriptContainer": "System.ExecutionEngine.GetScriptContainer",
|
"GetScriptContainer": "Neo.ExecutionEngine.GetScriptContainer",
|
||||||
"GetCallingScriptHash": "System.ExecutionEngine.GetCallingScriptHash",
|
"GetCallingScriptHash": "Neo.ExecutionEngine.GetCallingScriptHash",
|
||||||
"GetEntryScriptHash": "System.ExecutionEngine.GetEntryScriptHash",
|
"GetEntryScriptHash": "Neo.ExecutionEngine.GetEntryScriptHash",
|
||||||
"GetExecutingScriptHash": "System.ExecutionEngine.GetExecutingScriptHash",
|
"GetExecutingScriptHash": "Neo.ExecutionEngine.GetExecutingScriptHash",
|
||||||
},
|
},
|
||||||
"iterator": {
|
"iterator": {
|
||||||
"Create": "Neo.Iterator.Create",
|
"Create": "Neo.Iterator.Create",
|
||||||
|
|
Loading…
Reference in a new issue