From 33c512032f289160cc74f0d1077faa9d82483ddd Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 14 Aug 2019 15:40:31 +0300 Subject: [PATCH] vm: switch from Opcode to Instruction Which matches the changes done in neo-storm and also make this codebase closer to the `dev` branch (that also uses Instruction). --- pkg/core/util.go | 8 +- pkg/smartcontract/contract.go | 2 +- pkg/smartcontract/contract_test.go | 6 +- pkg/vm/compiler/codegen.go | 132 +++++++++++------------ pkg/vm/compiler/compiler.go | 2 +- pkg/vm/compiler/emit.go | 36 +++---- pkg/vm/context.go | 12 +-- pkg/vm/emit.go | 48 ++++----- pkg/vm/emit_test.go | 12 +-- pkg/vm/instruction_string.go | 118 +++++++++++++++++++++ pkg/vm/instructions.go | 130 +++++++++++++++++++++++ pkg/vm/opcode.go | 131 ----------------------- pkg/vm/opcode_string.go | 118 --------------------- pkg/vm/vm.go | 164 ++++++++++++++--------------- pkg/vm/vm_test.go | 46 ++++---- 15 files changed, 482 insertions(+), 483 deletions(-) create mode 100644 pkg/vm/instruction_string.go create mode 100644 pkg/vm/instructions.go delete mode 100644 pkg/vm/opcode.go delete mode 100644 pkg/vm/opcode_string.go diff --git a/pkg/core/util.go b/pkg/core/util.go index 086f54e57..a5eab4b85 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -35,7 +35,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { NextConsensus: nextConsensus, Script: &transaction.Witness{ InvocationScript: []byte{}, - VerificationScript: []byte{byte(vm.Opusht)}, + VerificationScript: []byte{byte(vm.PUSHT)}, }, } @@ -82,7 +82,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { Scripts: []*transaction.Witness{ { InvocationScript: []byte{}, - VerificationScript: []byte{byte(vm.Opusht)}, + VerificationScript: []byte{byte(vm.PUSHT)}, }, }, }, @@ -97,7 +97,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { } func governingTokenTX() *transaction.Transaction { - admin, _ := util.Uint160FromScript([]byte{byte(vm.Opusht)}) + admin, _ := util.Uint160FromScript([]byte{byte(vm.PUSHT)}) registerTX := &transaction.RegisterTX{ AssetType: transaction.GoverningToken, Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]", @@ -120,7 +120,7 @@ func governingTokenTX() *transaction.Transaction { } func utilityTokenTX() *transaction.Transaction { - admin, _ := util.Uint160FromScript([]byte{byte(vm.Opushf)}) + admin, _ := util.Uint160FromScript([]byte{byte(vm.PUSHF)}) registerTX := &transaction.RegisterTX{ AssetType: transaction.UtilityToken, Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]", diff --git a/pkg/smartcontract/contract.go b/pkg/smartcontract/contract.go index a56562475..33214000f 100644 --- a/pkg/smartcontract/contract.go +++ b/pkg/smartcontract/contract.go @@ -34,7 +34,7 @@ func CreateMultiSigRedeemScript(m int, publicKeys crypto.PublicKeys) ([]byte, er if err := vm.EmitInt(buf, int64(len(publicKeys))); err != nil { return nil, err } - if err := vm.EmitOpcode(buf, vm.Ocheckmultisig); err != nil { + if err := vm.EmitOpcode(buf, vm.CHECKMULTISIG); err != nil { return nil, err } diff --git a/pkg/smartcontract/contract_test.go b/pkg/smartcontract/contract_test.go index d8760743c..3e1c4dcf9 100644 --- a/pkg/smartcontract/contract_test.go +++ b/pkg/smartcontract/contract_test.go @@ -24,7 +24,7 @@ func TestCreateMultiSigRedeemScript(t *testing.T) { buf := bytes.NewBuffer(out) b, _ := buf.ReadByte() - assert.Equal(t, vm.Opush3, vm.Opcode(b)) + assert.Equal(t, vm.PUSH3, vm.Instruction(b)) for i := 0; i < len(validators); i++ { b, err := util.ReadVarBytes(buf) @@ -35,7 +35,7 @@ func TestCreateMultiSigRedeemScript(t *testing.T) { } b, _ = buf.ReadByte() - assert.Equal(t, vm.Opush3, vm.Opcode(b)) + assert.Equal(t, vm.PUSH3, vm.Instruction(b)) b, _ = buf.ReadByte() - assert.Equal(t, vm.Ocheckmultisig, vm.Opcode(b)) + assert.Equal(t, vm.CHECKMULTISIG, vm.Instruction(b)) } diff --git a/pkg/vm/compiler/codegen.go b/pkg/vm/compiler/codegen.go index df77461e1..e88e3a861 100644 --- a/pkg/vm/compiler/codegen.go +++ b/pkg/vm/compiler/codegen.go @@ -87,18 +87,18 @@ func (c *codegen) emitLoadLocal(name string) { } func (c *codegen) emitLoadLocalPos(pos int) { - emitOpcode(c.prog, vm.Ofromaltstack) - emitOpcode(c.prog, vm.Odup) - emitOpcode(c.prog, vm.Otoaltstack) + emitOpcode(c.prog, vm.FROMALTSTACK) + emitOpcode(c.prog, vm.DUP) + emitOpcode(c.prog, vm.TOALTSTACK) emitInt(c.prog, int64(pos)) - emitOpcode(c.prog, vm.Opickitem) + emitOpcode(c.prog, vm.PICKITEM) } func (c *codegen) emitStoreLocal(pos int) { - emitOpcode(c.prog, vm.Ofromaltstack) - emitOpcode(c.prog, vm.Odup) - emitOpcode(c.prog, vm.Otoaltstack) + emitOpcode(c.prog, vm.FROMALTSTACK) + emitOpcode(c.prog, vm.DUP) + emitOpcode(c.prog, vm.TOALTSTACK) if pos < 0 { log.Fatalf("invalid position to store local: %d", pos) @@ -106,19 +106,19 @@ func (c *codegen) emitStoreLocal(pos int) { emitInt(c.prog, int64(pos)) emitInt(c.prog, 2) - emitOpcode(c.prog, vm.Oroll) - emitOpcode(c.prog, vm.Osetitem) + emitOpcode(c.prog, vm.ROLL) + emitOpcode(c.prog, vm.SETITEM) } func (c *codegen) emitLoadField(i int) { emitInt(c.prog, int64(i)) - emitOpcode(c.prog, vm.Opickitem) + emitOpcode(c.prog, vm.PICKITEM) } func (c *codegen) emitStoreStructField(i int) { emitInt(c.prog, int64(i)) - emitOpcode(c.prog, vm.Orot) - emitOpcode(c.prog, vm.Osetitem) + emitOpcode(c.prog, vm.ROT) + emitOpcode(c.prog, vm.SETITEM) } // convertGlobals will traverse the AST and only convert global declarations. @@ -155,8 +155,8 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl) { // All globals copied into the scope of the function need to be added // to the stack size of the function. emitInt(c.prog, f.stackSize()+countGlobals(file)) - emitOpcode(c.prog, vm.Onewarray) - emitOpcode(c.prog, vm.Otoaltstack) + emitOpcode(c.prog, vm.NEWARRAY) + emitOpcode(c.prog, vm.TOALTSTACK) // We need to handle methods, which in Go, is just syntactic sugar. // The method receiver will be passed in as first argument. @@ -193,9 +193,9 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl) { // If this function returns the void (no return stmt) we will cleanup its junk on the stack. if !hasReturnStmt(decl) { - emitOpcode(c.prog, vm.Ofromaltstack) - emitOpcode(c.prog, vm.Odrop) - emitOpcode(c.prog, vm.Oret) + emitOpcode(c.prog, vm.FROMALTSTACK) + emitOpcode(c.prog, vm.DROP) + emitOpcode(c.prog, vm.RET) } } @@ -262,17 +262,17 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { // To be backwards compatible we will put them them in. // See issue #65 (https://github.com/CityOfZion/neo-go/issues/65) l := c.newLabel() - emitJmp(c.prog, vm.Ojmp, int16(l)) + emitJmp(c.prog, vm.JMP, int16(l)) c.setLabel(l) if len(n.Results) > 0 { ast.Walk(c, n.Results[0]) } - emitOpcode(c.prog, vm.Onop) // @OPTIMIZE - emitOpcode(c.prog, vm.Ofromaltstack) - emitOpcode(c.prog, vm.Odrop) // Cleanup the stack. - emitOpcode(c.prog, vm.Oret) + emitOpcode(c.prog, vm.NOP) // @OPTIMIZE + emitOpcode(c.prog, vm.FROMALTSTACK) + emitOpcode(c.prog, vm.DROP) // Cleanup the stack. + emitOpcode(c.prog, vm.RET) return nil case *ast.IfStmt: @@ -280,7 +280,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { lElse := c.newLabel() if n.Cond != nil { ast.Walk(c, n.Cond) - emitJmp(c.prog, vm.Ojmpifnot, int16(lElse)) + emitJmp(c.prog, vm.JMPIFNOT, int16(lElse)) } c.setLabel(lIf) @@ -288,7 +288,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { if n.Else != nil { // TODO: handle else statements. - // emitJmp(c.prog, vm.Ojmp, int16(lEnd)) + // emitJmp(c.prog, vm.JMP, int16(lEnd)) } c.setLabel(lElse) if n.Else != nil { @@ -327,7 +327,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.emitLoadConst(c.typeInfo.Types[n.Elts[i]]) } emitInt(c.prog, int64(ln)) - emitOpcode(c.prog, vm.Opack) + emitOpcode(c.prog, vm.PACK) return nil } @@ -342,13 +342,13 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { switch n.Op { case token.LAND: ast.Walk(c, n.X) - emitJmp(c.prog, vm.Ojmpifnot, int16(len(c.l)-1)) + emitJmp(c.prog, vm.JMPIFNOT, int16(len(c.l)-1)) ast.Walk(c, n.Y) return nil case token.LOR: ast.Walk(c, n.X) - emitJmp(c.prog, vm.Ojmpif, int16(len(c.l)-2)) + emitJmp(c.prog, vm.JMPIF, int16(len(c.l)-2)) ast.Walk(c, n.Y) return nil @@ -414,18 +414,18 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { // Do not swap for builtin functions. if !isBuiltin { if numArgs == 2 { - emitOpcode(c.prog, vm.Oswap) + emitOpcode(c.prog, vm.SWAP) } if numArgs == 3 { emitInt(c.prog, 2) - emitOpcode(c.prog, vm.Oxswap) + emitOpcode(c.prog, vm.XSWAP) } } // 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.Onop) + emitOpcode(c.prog, vm.NOP) // Check builtin first to avoid nil pointer on funcScope! switch { @@ -436,13 +436,13 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { case isSyscall(f.name): c.convertSyscall(f.name) default: - emitCall(c.prog, vm.Ocall, 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.Odrop) + emitOpcode(c.prog, vm.DROP) } return nil @@ -490,7 +490,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.emitLoadField(int(val)) default: ast.Walk(c, n.Index) - emitOpcode(c.prog, vm.Opickitem) // just pickitem here + emitOpcode(c.prog, vm.PICKITEM) // just pickitem here } return nil @@ -508,14 +508,14 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { ast.Walk(c, n.Cond) // Jump if the condition is false - emitJmp(c.prog, vm.Ojmpifnot, int16(fend)) + emitJmp(c.prog, vm.JMPIFNOT, int16(fend)) // Walk body followed by the iterator (post stmt). ast.Walk(c, n.Body) ast.Walk(c, n.Post) // Jump back to condition. - emitJmp(c.prog, vm.Ojmp, int16(fstart)) + emitJmp(c.prog, vm.JMP, int16(fstart)) c.setLabel(fend) return nil @@ -537,7 +537,7 @@ func (c *codegen) convertSyscall(name string) { log.Fatalf("unknown VM syscall api: %s", name) } emitSyscall(c.prog, api) - emitOpcode(c.prog, vm.Onop) // @OPTIMIZE + emitOpcode(c.prog, vm.NOP) // @OPTIMIZE } func (c *codegen) convertBuiltin(expr *ast.CallExpr) { @@ -554,20 +554,20 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) { arg := expr.Args[0] typ := c.typeInfo.Types[arg].Type if isStringType(typ) { - emitOpcode(c.prog, vm.Osize) + emitOpcode(c.prog, vm.SIZE) } else { - emitOpcode(c.prog, vm.Oarraysize) + emitOpcode(c.prog, vm.ARRAYSIZE) } case "append": - emitOpcode(c.prog, vm.Oappend) + emitOpcode(c.prog, vm.APPEND) case "SHA256": - emitOpcode(c.prog, vm.Osha256) + emitOpcode(c.prog, vm.SHA256) case "SHA1": - emitOpcode(c.prog, vm.Osha1) + emitOpcode(c.prog, vm.SHA1) case "Hash256": - emitOpcode(c.prog, vm.Ohash256) + emitOpcode(c.prog, vm.HASH256) case "Hash160": - emitOpcode(c.prog, vm.Ohash160) + emitOpcode(c.prog, vm.HASH160) case "FromAddress": // We can be sure that this is a ast.BasicLit just containing a simple // address string. Note that the string returned from calling Value will @@ -601,10 +601,10 @@ func (c *codegen) convertStruct(lit *ast.CompositeLit) { log.Fatalf("the given literal is not of type struct: %v", lit) } - emitOpcode(c.prog, vm.Onop) + emitOpcode(c.prog, vm.NOP) emitInt(c.prog, int64(strct.NumFields())) - emitOpcode(c.prog, vm.Onewstruct) - emitOpcode(c.prog, vm.Otoaltstack) + emitOpcode(c.prog, vm.NEWSTRUCT) + emitOpcode(c.prog, vm.TOALTSTACK) // We need to locally store all the fields, even if they are not initialized. // We will initialize all fields to their "zero" value. @@ -633,45 +633,45 @@ func (c *codegen) convertStruct(lit *ast.CompositeLit) { c.emitLoadConst(typeAndVal) c.emitStoreLocal(i) } - emitOpcode(c.prog, vm.Ofromaltstack) + emitOpcode(c.prog, vm.FROMALTSTACK) } func (c *codegen) convertToken(tok token.Token) { switch tok { case token.ADD_ASSIGN: - emitOpcode(c.prog, vm.Oadd) + emitOpcode(c.prog, vm.ADD) case token.SUB_ASSIGN: - emitOpcode(c.prog, vm.Osub) + emitOpcode(c.prog, vm.SUB) case token.MUL_ASSIGN: - emitOpcode(c.prog, vm.Omul) + emitOpcode(c.prog, vm.MUL) case token.QUO_ASSIGN: - emitOpcode(c.prog, vm.Odiv) + emitOpcode(c.prog, vm.DIV) case token.ADD: - emitOpcode(c.prog, vm.Oadd) + emitOpcode(c.prog, vm.ADD) case token.SUB: - emitOpcode(c.prog, vm.Osub) + emitOpcode(c.prog, vm.SUB) case token.MUL: - emitOpcode(c.prog, vm.Omul) + emitOpcode(c.prog, vm.MUL) case token.QUO: - emitOpcode(c.prog, vm.Odiv) + emitOpcode(c.prog, vm.DIV) case token.LSS: - emitOpcode(c.prog, vm.Olt) + emitOpcode(c.prog, vm.LT) case token.LEQ: - emitOpcode(c.prog, vm.Olte) + emitOpcode(c.prog, vm.LTE) case token.GTR: - emitOpcode(c.prog, vm.Ogt) + emitOpcode(c.prog, vm.GT) case token.GEQ: - emitOpcode(c.prog, vm.Ogte) + emitOpcode(c.prog, vm.GTE) case token.EQL: - emitOpcode(c.prog, vm.Onumequal) + emitOpcode(c.prog, vm.NUMEQUAL) case token.NEQ: - emitOpcode(c.prog, vm.Onumnotequal) + emitOpcode(c.prog, vm.NUMNOTEQUAL) case token.DEC: - emitOpcode(c.prog, vm.Odec) + emitOpcode(c.prog, vm.DEC) case token.INC: - emitOpcode(c.prog, vm.Oinc) + emitOpcode(c.prog, vm.INC) case token.NOT: - emitOpcode(c.prog, vm.Onot) + emitOpcode(c.prog, vm.NOT) default: log.Fatalf("compiler could not convert token: %s", tok) } @@ -750,8 +750,8 @@ func (c *codegen) writeJumps() { b := c.prog.Bytes() for i, op := range b { j := i + 1 - switch vm.Opcode(op) { - case vm.Ojmp, vm.Ojmpifnot, vm.Ojmpif, vm.Ocall: + switch vm.Instruction(op) { + case vm.JMP, vm.JMPIFNOT, vm.JMPIF, vm.CALL: index := int16(binary.LittleEndian.Uint16(b[j : j+2])) if int(index) > len(c.l) || int(index) < 0 { continue diff --git a/pkg/vm/compiler/compiler.go b/pkg/vm/compiler/compiler.go index 28dfa0a3d..a4beb04ff 100644 --- a/pkg/vm/compiler/compiler.go +++ b/pkg/vm/compiler/compiler.go @@ -112,7 +112,7 @@ func DumpOpcode(src string) error { w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0) fmt.Fprintln(w, "INDEX\tOPCODE\tDESC\t") for i := 0; i < len(b); i++ { - fmt.Fprintf(w, "%d\t0x%2x\t%s\t\n", i, b[i], vm.Opcode(b[i])) + fmt.Fprintf(w, "%d\t0x%2x\t%s\t\n", i, b[i], vm.Instruction(b[i])) } w.Flush() return nil diff --git a/pkg/vm/compiler/emit.go b/pkg/vm/compiler/emit.go index 3221ac745..7805a88c9 100644 --- a/pkg/vm/compiler/emit.go +++ b/pkg/vm/compiler/emit.go @@ -12,7 +12,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/vm" ) -func emit(w *bytes.Buffer, op vm.Opcode, b []byte) error { +func emit(w *bytes.Buffer, op vm.Instruction, b []byte) error { if err := w.WriteByte(byte(op)); err != nil { return err } @@ -20,26 +20,26 @@ func emit(w *bytes.Buffer, op vm.Opcode, b []byte) error { return err } -func emitOpcode(w io.ByteWriter, op vm.Opcode) error { +func emitOpcode(w io.ByteWriter, op vm.Instruction) error { return w.WriteByte(byte(op)) } func emitBool(w io.ByteWriter, ok bool) error { if ok { - return emitOpcode(w, vm.Opusht) + return emitOpcode(w, vm.PUSHT) } - return emitOpcode(w, vm.Opushf) + return emitOpcode(w, vm.PUSHF) } func emitInt(w *bytes.Buffer, i int64) error { if i == -1 { - return emitOpcode(w, vm.Opushm1) + return emitOpcode(w, vm.PUSHM1) } if i == 0 { - return emitOpcode(w, vm.Opushf) + return emitOpcode(w, vm.PUSHF) } if i > 0 && i < 16 { - val := vm.Opcode(int(vm.Opush1) - 1 + int(i)) + val := vm.Instruction(int(vm.PUSH1) - 1 + int(i)) return emitOpcode(w, val) } @@ -59,18 +59,18 @@ func emitBytes(w *bytes.Buffer, b []byte) error { ) switch { - case n <= int(vm.Opushbytes75): - return emit(w, vm.Opcode(n), b) + case n <= int(vm.PUSHBYTES75): + return emit(w, vm.Instruction(n), b) case n < 0x100: - err = emit(w, vm.Opushdata1, []byte{byte(n)}) + err = emit(w, vm.PUSHDATA1, []byte{byte(n)}) case n < 0x10000: buf := make([]byte, 2) binary.LittleEndian.PutUint16(buf, uint16(n)) - err = emit(w, vm.Opushdata2, buf) + err = emit(w, vm.PUSHDATA2, buf) default: buf := make([]byte, 4) binary.LittleEndian.PutUint32(buf, uint32(n)) - err = emit(w, vm.Opushdata4, buf) + err = emit(w, vm.PUSHDATA4, buf) } if err != nil { return err @@ -86,15 +86,15 @@ func emitSyscall(w *bytes.Buffer, api string) error { buf := make([]byte, len(api)+1) buf[0] = byte(len(api)) copy(buf[1:], []byte(api)) - return emit(w, vm.Osyscall, buf) + return emit(w, vm.SYSCALL, buf) } -func emitCall(w *bytes.Buffer, op vm.Opcode, label int16) error { +func emitCall(w *bytes.Buffer, op vm.Instruction, label int16) error { return emitJmp(w, op, label) } -func emitJmp(w *bytes.Buffer, op vm.Opcode, label int16) error { - if !isOpcodeJmp(op) { +func emitJmp(w *bytes.Buffer, op vm.Instruction, label int16) error { + if !isInstructionJmp(op) { return fmt.Errorf("opcode %s is not a jump or call type", op) } buf := make([]byte, 2) @@ -102,8 +102,8 @@ func emitJmp(w *bytes.Buffer, op vm.Opcode, label int16) error { return emit(w, op, buf) } -func isOpcodeJmp(op vm.Opcode) bool { - if op == vm.Ojmp || op == vm.Ojmpifnot || op == vm.Ojmpif || op == vm.Ocall { +func isInstructionJmp(op vm.Instruction) bool { + if op == vm.JMP || op == vm.JMPIFNOT || op == vm.JMPIF || op == vm.CALL { return true } return false diff --git a/pkg/vm/context.go b/pkg/vm/context.go index ed4fef036..043c89acf 100644 --- a/pkg/vm/context.go +++ b/pkg/vm/context.go @@ -26,12 +26,12 @@ func NewContext(b []byte) *Context { } // Next return the next instruction to execute. -func (c *Context) Next() Opcode { +func (c *Context) Next() Instruction { c.ip++ if c.ip >= len(c.prog) { - return Oret + return RET } - return Opcode(c.prog[c.ip]) + return Instruction(c.prog[c.ip]) } // IP returns the absolute instruction without taking 0 into account. @@ -47,11 +47,11 @@ func (c *Context) LenInstr() int { } // CurrInstr returns the current instruction and opcode. -func (c *Context) CurrInstr() (int, Opcode) { +func (c *Context) CurrInstr() (int, Instruction) { if c.ip < 0 { - return c.ip, Opcode(0x00) + return c.ip, Instruction(0x00) } - return c.ip, Opcode(c.prog[c.ip]) + return c.ip, Instruction(c.prog[c.ip]) } // Copy returns an new exact copy of c. diff --git a/pkg/vm/emit.go b/pkg/vm/emit.go index 49b794e86..14556b039 100644 --- a/pkg/vm/emit.go +++ b/pkg/vm/emit.go @@ -11,8 +11,8 @@ import ( "github.com/CityOfZion/neo-go/pkg/util" ) -// Emit a VM Opcode with data to the given buffer. -func Emit(w *bytes.Buffer, op Opcode, b []byte) error { +// Emit a VM Instruction with data to the given buffer. +func Emit(w *bytes.Buffer, op Instruction, b []byte) error { if err := w.WriteByte(byte(op)); err != nil { return err } @@ -20,29 +20,29 @@ func Emit(w *bytes.Buffer, op Opcode, b []byte) error { return err } -// EmitOpcode emits a single VM Opcode the given buffer. -func EmitOpcode(w io.ByteWriter, op Opcode) error { +// EmitOpcode emits a single VM Instruction the given buffer. +func EmitOpcode(w io.ByteWriter, op Instruction) error { return w.WriteByte(byte(op)) } // EmitBool emits a bool type the given buffer. func EmitBool(w io.ByteWriter, ok bool) error { if ok { - return EmitOpcode(w, Opusht) + return EmitOpcode(w, PUSHT) } - return EmitOpcode(w, Opushf) + return EmitOpcode(w, PUSHF) } // EmitInt emits a int type to the given buffer. func EmitInt(w *bytes.Buffer, i int64) error { if i == -1 { - return EmitOpcode(w, Opushm1) + return EmitOpcode(w, PUSHM1) } if i == 0 { - return EmitOpcode(w, Opushf) + return EmitOpcode(w, PUSHF) } if i > 0 && i < 16 { - val := Opcode(int(Opush1) - 1 + int(i)) + val := Instruction(int(PUSH1) - 1 + int(i)) return EmitOpcode(w, val) } @@ -63,18 +63,18 @@ func EmitBytes(w *bytes.Buffer, b []byte) error { n = len(b) ) - if n <= int(Opushbytes75) { - return Emit(w, Opcode(n), b) + if n <= int(PUSHBYTES75) { + return Emit(w, Instruction(n), b) } else if n < 0x100 { - err = Emit(w, Opushdata1, []byte{byte(n)}) + err = Emit(w, PUSHDATA1, []byte{byte(n)}) } else if n < 0x10000 { buf := make([]byte, 2) binary.LittleEndian.PutUint16(buf, uint16(n)) - err = Emit(w, Opushdata2, buf) + err = Emit(w, PUSHDATA2, buf) } else { buf := make([]byte, 4) binary.LittleEndian.PutUint32(buf, uint32(n)) - err = Emit(w, Opushdata4, buf) + err = Emit(w, PUSHDATA4, buf) } if err != nil { return err @@ -92,17 +92,17 @@ func EmitSyscall(w *bytes.Buffer, api string) error { buf := make([]byte, len(api)+1) buf[0] = byte(len(api)) copy(buf[1:], []byte(api)) - return Emit(w, Osyscall, buf) + return Emit(w, SYSCALL, buf) } -// EmitCall emits a call Opcode with label to the given buffer. -func EmitCall(w *bytes.Buffer, op Opcode, label int16) error { +// EmitCall emits a call Instruction with label to the given buffer. +func EmitCall(w *bytes.Buffer, op Instruction, label int16) error { return EmitJmp(w, op, label) } -// EmitJmp emits a jump Opcode along with label to the given buffer. -func EmitJmp(w *bytes.Buffer, op Opcode, label int16) error { - if !isOpcodeJmp(op) { +// EmitJmp emits a jump Instruction along with label to the given buffer. +func EmitJmp(w *bytes.Buffer, op Instruction, label int16) error { + if !isInstructionJmp(op) { return fmt.Errorf("opcode %s is not a jump or call type", op.String()) } buf := make([]byte, 2) @@ -113,9 +113,9 @@ func EmitJmp(w *bytes.Buffer, op Opcode, label int16) error { // EmitAppCall emits an appcall, if tailCall is true, tailCall opcode will be // emitted instead. func EmitAppCall(w *bytes.Buffer, scriptHash util.Uint160, tailCall bool) error { - op := Oappcall + op := APPCALL if tailCall { - op = Otailcall + op = TAILCALL } return Emit(w, op, scriptHash.Bytes()) } @@ -142,8 +142,8 @@ func EmitAppCallWithOperation(w *bytes.Buffer, scriptHash util.Uint160, operatio return EmitAppCall(w, scriptHash, false) } -func isOpcodeJmp(op Opcode) bool { - if op == Ojmp || op == Ojmpifnot || op == Ojmpif || op == Ocall { +func isInstructionJmp(op Instruction) bool { + if op == JMP || op == JMPIFNOT || op == JMPIF || op == CALL { return true } return false diff --git a/pkg/vm/emit_test.go b/pkg/vm/emit_test.go index 2c127636c..0baf995bc 100644 --- a/pkg/vm/emit_test.go +++ b/pkg/vm/emit_test.go @@ -11,7 +11,7 @@ import ( func TestEmitInt(t *testing.T) { buf := new(bytes.Buffer) EmitInt(buf, 10) - assert.Equal(t, Opcode(buf.Bytes()[0]), Opush10) + assert.Equal(t, Instruction(buf.Bytes()[0]), PUSH10) buf.Reset() EmitInt(buf, 100) assert.Equal(t, buf.Bytes()[0], uint8(1)) @@ -26,8 +26,8 @@ func TestEmitBool(t *testing.T) { buf := new(bytes.Buffer) EmitBool(buf, true) EmitBool(buf, false) - assert.Equal(t, Opcode(buf.Bytes()[0]), Opush1) - assert.Equal(t, Opcode(buf.Bytes()[1]), Opush0) + assert.Equal(t, Instruction(buf.Bytes()[0]), PUSH1) + assert.Equal(t, Instruction(buf.Bytes()[1]), PUSH0) } func TestEmitString(t *testing.T) { @@ -48,7 +48,7 @@ func TestEmitSyscall(t *testing.T) { buf := new(bytes.Buffer) for _, syscall := range syscalls { EmitSyscall(buf, syscall) - assert.Equal(t, Opcode(buf.Bytes()[0]), Osyscall) + assert.Equal(t, Instruction(buf.Bytes()[0]), SYSCALL) assert.Equal(t, buf.Bytes()[1], uint8(len(syscall))) assert.Equal(t, buf.Bytes()[2:], []byte(syscall)) buf.Reset() @@ -57,8 +57,8 @@ func TestEmitSyscall(t *testing.T) { func TestEmitCall(t *testing.T) { buf := new(bytes.Buffer) - EmitCall(buf, Ojmp, 100) - assert.Equal(t, Opcode(buf.Bytes()[0]), Ojmp) + EmitCall(buf, JMP, 100) + assert.Equal(t, Instruction(buf.Bytes()[0]), JMP) label := binary.LittleEndian.Uint16(buf.Bytes()[1:3]) assert.Equal(t, label, uint16(100)) } diff --git a/pkg/vm/instruction_string.go b/pkg/vm/instruction_string.go new file mode 100644 index 000000000..da98524bb --- /dev/null +++ b/pkg/vm/instruction_string.go @@ -0,0 +1,118 @@ +// Code generated by "stringer -type=Instruction"; DO NOT EDIT. + +package vm + +import "strconv" + +const _Instruction_name = "PUSH0PUSHBYTES1PUSHBYTES75PUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPIFJMPIFNOTCALLRETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTSIZEINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGCHECKMULTISIGARRAYSIZEPACKUNPACKPICKITEMSETITEMNEWARRAYNEWSTRUCTAPPENDREVERSEREMOVETHROWTHROWIFNOT" + +var _Instruction_map = map[Instruction]string{ + 0: _Instruction_name[0:5], + 1: _Instruction_name[5:15], + 75: _Instruction_name[15:26], + 76: _Instruction_name[26:35], + 77: _Instruction_name[35:44], + 78: _Instruction_name[44:53], + 79: _Instruction_name[53:59], + 81: _Instruction_name[59:64], + 82: _Instruction_name[64:69], + 83: _Instruction_name[69:74], + 84: _Instruction_name[74:79], + 85: _Instruction_name[79:84], + 86: _Instruction_name[84:89], + 87: _Instruction_name[89:94], + 88: _Instruction_name[94:99], + 89: _Instruction_name[99:104], + 90: _Instruction_name[104:110], + 91: _Instruction_name[110:116], + 92: _Instruction_name[116:122], + 93: _Instruction_name[122:128], + 94: _Instruction_name[128:134], + 95: _Instruction_name[134:140], + 96: _Instruction_name[140:146], + 97: _Instruction_name[146:149], + 98: _Instruction_name[149:152], + 99: _Instruction_name[152:157], + 100: _Instruction_name[157:165], + 101: _Instruction_name[165:169], + 102: _Instruction_name[169:172], + 103: _Instruction_name[172:179], + 104: _Instruction_name[179:186], + 105: _Instruction_name[186:194], + 106: _Instruction_name[194:209], + 107: _Instruction_name[209:219], + 108: _Instruction_name[219:231], + 109: _Instruction_name[231:236], + 114: _Instruction_name[236:241], + 115: _Instruction_name[241:246], + 116: _Instruction_name[246:251], + 117: _Instruction_name[251:255], + 118: _Instruction_name[255:258], + 119: _Instruction_name[258:261], + 120: _Instruction_name[261:265], + 121: _Instruction_name[265:269], + 122: _Instruction_name[269:273], + 123: _Instruction_name[273:276], + 124: _Instruction_name[276:280], + 125: _Instruction_name[280:284], + 126: _Instruction_name[284:287], + 127: _Instruction_name[287:293], + 128: _Instruction_name[293:297], + 129: _Instruction_name[297:302], + 130: _Instruction_name[302:306], + 131: _Instruction_name[306:312], + 132: _Instruction_name[312:315], + 133: _Instruction_name[315:317], + 134: _Instruction_name[317:320], + 135: _Instruction_name[320:325], + 139: _Instruction_name[325:328], + 140: _Instruction_name[328:331], + 141: _Instruction_name[331:335], + 143: _Instruction_name[335:341], + 144: _Instruction_name[341:344], + 145: _Instruction_name[344:347], + 146: _Instruction_name[347:349], + 147: _Instruction_name[349:352], + 148: _Instruction_name[352:355], + 149: _Instruction_name[355:358], + 150: _Instruction_name[358:361], + 151: _Instruction_name[361:364], + 152: _Instruction_name[364:367], + 153: _Instruction_name[367:370], + 154: _Instruction_name[370:377], + 155: _Instruction_name[377:383], + 156: _Instruction_name[383:391], + 158: _Instruction_name[391:402], + 159: _Instruction_name[402:404], + 160: _Instruction_name[404:406], + 161: _Instruction_name[406:409], + 162: _Instruction_name[409:412], + 163: _Instruction_name[412:415], + 164: _Instruction_name[415:418], + 165: _Instruction_name[418:424], + 167: _Instruction_name[424:428], + 168: _Instruction_name[428:434], + 169: _Instruction_name[434:441], + 170: _Instruction_name[441:448], + 172: _Instruction_name[448:456], + 174: _Instruction_name[456:469], + 192: _Instruction_name[469:478], + 193: _Instruction_name[478:482], + 194: _Instruction_name[482:488], + 195: _Instruction_name[488:496], + 196: _Instruction_name[496:503], + 197: _Instruction_name[503:511], + 198: _Instruction_name[511:520], + 200: _Instruction_name[520:526], + 201: _Instruction_name[526:533], + 202: _Instruction_name[533:539], + 240: _Instruction_name[539:544], + 241: _Instruction_name[544:554], +} + +func (i Instruction) String() string { + if str, ok := _Instruction_map[i]; ok { + return str + } + return "Instruction(" + strconv.FormatInt(int64(i), 10) + ")" +} diff --git a/pkg/vm/instructions.go b/pkg/vm/instructions.go new file mode 100644 index 000000000..032c0a5c9 --- /dev/null +++ b/pkg/vm/instructions.go @@ -0,0 +1,130 @@ +package vm + +//go:generate stringer -type=Instruction + +// Instruction represents an single operation for the NEO virtual machine. +type Instruction byte + +// Viable list of supported instruction constants. +const ( + // Constants + PUSH0 Instruction = 0x00 + PUSHF Instruction = PUSH0 + PUSHBYTES1 Instruction = 0x01 + PUSHBYTES75 Instruction = 0x4B + PUSHDATA1 Instruction = 0x4C + PUSHDATA2 Instruction = 0x4D + PUSHDATA4 Instruction = 0x4E + PUSHM1 Instruction = 0x4F + PUSH1 Instruction = 0x51 + PUSHT Instruction = PUSH1 + PUSH2 Instruction = 0x52 + PUSH3 Instruction = 0x53 + PUSH4 Instruction = 0x54 + PUSH5 Instruction = 0x55 + PUSH6 Instruction = 0x56 + PUSH7 Instruction = 0x57 + PUSH8 Instruction = 0x58 + PUSH9 Instruction = 0x59 + PUSH10 Instruction = 0x5A + PUSH11 Instruction = 0x5B + PUSH12 Instruction = 0x5C + PUSH13 Instruction = 0x5D + PUSH14 Instruction = 0x5E + PUSH15 Instruction = 0x5F + PUSH16 Instruction = 0x60 + + // Flow control + NOP Instruction = 0x61 + JMP Instruction = 0x62 + JMPIF Instruction = 0x63 + JMPIFNOT Instruction = 0x64 + CALL Instruction = 0x65 + RET Instruction = 0x66 + APPCALL Instruction = 0x67 + SYSCALL Instruction = 0x68 + TAILCALL Instruction = 0x69 + + // Stack + DUPFROMALTSTACK Instruction = 0x6A + TOALTSTACK Instruction = 0x6B + FROMALTSTACK Instruction = 0x6C + XDROP Instruction = 0x6D + XSWAP Instruction = 0x72 + XTUCK Instruction = 0x73 + DEPTH Instruction = 0x74 + DROP Instruction = 0x75 + DUP Instruction = 0x76 + NIP Instruction = 0x77 + OVER Instruction = 0x78 + PICK Instruction = 0x79 + ROLL Instruction = 0x7A + ROT Instruction = 0x7B + SWAP Instruction = 0x7C + TUCK Instruction = 0x7D + + // Splice + CAT Instruction = 0x7E + SUBSTR Instruction = 0x7F + LEFT Instruction = 0x80 + RIGHT Instruction = 0x81 + SIZE Instruction = 0x82 + + // Bitwise logic + INVERT Instruction = 0x83 + AND Instruction = 0x84 + OR Instruction = 0x85 + XOR Instruction = 0x86 + EQUAL Instruction = 0x87 + + // Arithmetic + INC Instruction = 0x8B + DEC Instruction = 0x8C + SIGN Instruction = 0x8D + NEGATE Instruction = 0x8F + ABS Instruction = 0x90 + NOT Instruction = 0x91 + NZ Instruction = 0x92 + ADD Instruction = 0x93 + SUB Instruction = 0x94 + MUL Instruction = 0x95 + DIV Instruction = 0x96 + MOD Instruction = 0x97 + SHL Instruction = 0x98 + SHR Instruction = 0x99 + BOOLAND Instruction = 0x9A + BOOLOR Instruction = 0x9B + NUMEQUAL Instruction = 0x9C + NUMNOTEQUAL Instruction = 0x9E + LT Instruction = 0x9F + GT Instruction = 0xA0 + LTE Instruction = 0xA1 + GTE Instruction = 0xA2 + MIN Instruction = 0xA3 + MAX Instruction = 0xA4 + WITHIN Instruction = 0xA5 + + // Crypto + SHA1 Instruction = 0xA7 + SHA256 Instruction = 0xA8 + HASH160 Instruction = 0xA9 + HASH256 Instruction = 0xAA + CHECKSIG Instruction = 0xAC + CHECKMULTISIG Instruction = 0xAE + + // Array + ARRAYSIZE Instruction = 0xC0 + PACK Instruction = 0xC1 + UNPACK Instruction = 0xC2 + PICKITEM Instruction = 0xC3 + SETITEM Instruction = 0xC4 + NEWARRAY Instruction = 0xC5 + NEWSTRUCT Instruction = 0xC6 + APPEND Instruction = 0xC8 + REVERSE Instruction = 0xC9 + REMOVE Instruction = 0xCA + + // Exceptions + THROW Instruction = 0xF0 + THROWIFNOT Instruction = 0xF1 +) diff --git a/pkg/vm/opcode.go b/pkg/vm/opcode.go deleted file mode 100644 index 83cf6a6d7..000000000 --- a/pkg/vm/opcode.go +++ /dev/null @@ -1,131 +0,0 @@ -package vm - -//go:generate stringer -type=Opcode - -// Opcode is an single operational instruction for the GO NEO virtual machine. -type Opcode byte - -// List of supported opcodes. -const ( - // Constants - Opush0 Opcode = 0x00 // An empty array of bytes is pushed onto the stack. - Opushf = Opush0 - Opushbytes1 Opcode = 0x01 // 0x01-0x4B The next opcode bytes is data to be pushed onto the stack - Opushbytes75 Opcode = 0x4B - Opushdata1 Opcode = 0x4C // The next byte contains the number of bytes to be pushed onto the stack. - Opushdata2 Opcode = 0x4D // The next two bytes contain the number of bytes to be pushed onto the stack. - Opushdata4 Opcode = 0x4E // The next four bytes contain the number of bytes to be pushed onto the stack. - Opushm1 Opcode = 0x4F // The number -1 is pushed onto the stack. - Opush1 Opcode = 0x51 - Opusht = Opush1 - Opush2 Opcode = 0x52 // The number 2 is pushed onto the stack. - Opush3 Opcode = 0x53 // The number 3 is pushed onto the stack. - Opush4 Opcode = 0x54 // The number 4 is pushed onto the stack. - Opush5 Opcode = 0x55 // The number 5 is pushed onto the stack. - Opush6 Opcode = 0x56 // The number 6 is pushed onto the stack. - Opush7 Opcode = 0x57 // The number 7 is pushed onto the stack. - Opush8 Opcode = 0x58 // The number 8 is pushed onto the stack. - Opush9 Opcode = 0x59 // The number 9 is pushed onto the stack. - Opush10 Opcode = 0x5A // The number 10 is pushed onto the stack. - Opush11 Opcode = 0x5B // The number 11 is pushed onto the stack. - Opush12 Opcode = 0x5C // The number 12 is pushed onto the stack. - Opush13 Opcode = 0x5D // The number 13 is pushed onto the stack. - Opush14 Opcode = 0x5E // The number 14 is pushed onto the stack. - Opush15 Opcode = 0x5F // The number 15 is pushed onto the stack. - Opush16 Opcode = 0x60 // The number 16 is pushed onto the stack. - - // Flow control - Onop Opcode = 0x61 // No operation. - Ojmp Opcode = 0x62 - Ojmpif Opcode = 0x63 - Ojmpifnot Opcode = 0x64 - Ocall Opcode = 0x65 - Oret Opcode = 0x66 - Oappcall Opcode = 0x67 - Osyscall Opcode = 0x68 - Otailcall Opcode = 0x69 - - // The stack - Odupfromaltstack Opcode = 0x6A - Otoaltstack Opcode = 0x6B // Puts the input onto the top of the alt stack. Removes it from the main stack. - Ofromaltstack Opcode = 0x6C // Puts the input onto the top of the main stack. Removes it from the alt stack. - Oxdrop Opcode = 0x6D - Oxswap Opcode = 0x72 - Oxtuck Opcode = 0x73 - Odepth Opcode = 0x74 // Puts the number of stack items onto the stack. - Odrop Opcode = 0x75 // Removes the top stack item. - Odup Opcode = 0x76 // Duplicates the top stack item. - Onip Opcode = 0x77 // Removes the second-to-top stack item. - Oover Opcode = 0x78 // Copies the second-to-top stack item to the top. - Opick Opcode = 0x79 // The item n back in the stack is copied to the top. - Oroll Opcode = 0x7A // The item n back in the stack is moved to the top. - Orot Opcode = 0x7B // The top three items on the stack are rotated to the left. - Oswap Opcode = 0x7C // The top two items on the stack are swapped. - Otuck Opcode = 0x7D // The item at the top of the stack is copied and inserted before the second-to-top item. - - // Splice - Ocat Opcode = 0x7E // Concatenates two strings. - Osubstr Opcode = 0x7F // Returns a section of a string. - Oleft Opcode = 0x80 // Keeps only characters left of the specified point in a string. - Oright Opcode = 0x81 // Keeps only characters right of the specified point in a string. - Osize Opcode = 0x82 // Returns the length of the input string. - - // Bitwise logic - Oinvert Opcode = 0x83 // Flips all of the bits in the input. - Oand Opcode = 0x84 // Boolean and between each bit in the inputs. - Oor Opcode = 0x85 // Boolean or between each bit in the inputs. - Oxor Opcode = 0x86 // Boolean exclusive or between each bit in the inputs. - Oequal Opcode = 0x87 // Returns 1 if the inputs are exactly equal, 0 otherwise. - - // Arithmetic - // Note: Arithmetic inputs are limited to signed 32-bit integers, but may overflow their output. - Oinc Opcode = 0x8B // 1 is added to the input. - Odec Opcode = 0x8C // 1 is subtracted from the input. - Osign Opcode = 0x8D - Onegate Opcode = 0x8F // The sign of the input is flipped. - Oabs Opcode = 0x90 // The input is made positive. - Onot Opcode = 0x91 // If the input is 0 or 1, it is flipped. Otherwise the output will be 0. - Onz Opcode = 0x92 // Returns 0 if the input is 0. 1 otherwise. - Oadd Opcode = 0x93 // a is added to b. - Osub Opcode = 0x94 // b is subtracted from a. - Omul Opcode = 0x95 // a is multiplied by b. - Odiv Opcode = 0x96 // a is divided by b. - Omod Opcode = 0x97 // Returns the remainder after dividing a by b. - Oshl Opcode = 0x98 // Shifts a left b bits, preserving sign. - Oshr Opcode = 0x99 // Shifts a right b bits, preserving sign. - Obooland Opcode = 0x9A // If both a and b are not 0, the output is 1. Otherwise 0. - Oboolor Opcode = 0x9B // If a or b is not 0, the output is 1. Otherwise 0. - Onumequal Opcode = 0x9C // Returns 1 if the numbers are equal, 0 otherwise. - Onumnotequal Opcode = 0x9E // Returns 1 if the numbers are not equal, 0 otherwise. - Olt Opcode = 0x9F // Returns 1 if a is less than b, 0 otherwise. - Ogt Opcode = 0xA0 // Returns 1 if a is greater than b, 0 otherwise. - Olte Opcode = 0xA1 // Returns 1 if a is less than or equal to b, 0 otherwise. - Ogte Opcode = 0xA2 // Returns 1 if a is greater than or equal to b, 0 otherwise. - Omin Opcode = 0xA3 // Returns the smaller of a and b. - Omax Opcode = 0xA4 // Returns the larger of a and b. - Owithin Opcode = 0xA5 // Returns 1 if x is within the specified range (left-inclusive), 0 otherwise. - - // Crypto - Osha1 Opcode = 0xA7 // The input is hashed using SHA-1. - Osha256 Opcode = 0xA8 // The input is hashed using SHA-256. - Ohash160 Opcode = 0xA9 - Ohash256 Opcode = 0xAA - Ochecksig Opcode = 0xAC - Ocheckmultisig Opcode = 0xAE - - // array - Oarraysize Opcode = 0xC0 - Opack Opcode = 0xC1 - Ounpack Opcode = 0xC2 - Opickitem Opcode = 0xC3 - Osetitem Opcode = 0xC4 - Onewarray Opcode = 0xC5 // Pops size from stack and creates a new array with that size, and pushes the array into the stack - Onewstruct Opcode = 0xC6 - Oappend Opcode = 0xC8 - Oreverse Opcode = 0xC9 - Oremove Opcode = 0xCA - - // exceptions - Othrow Opcode = 0xF0 - Othrowifnot Opcode = 0xF1 -) diff --git a/pkg/vm/opcode_string.go b/pkg/vm/opcode_string.go deleted file mode 100644 index 84b34c5e3..000000000 --- a/pkg/vm/opcode_string.go +++ /dev/null @@ -1,118 +0,0 @@ -// Code generated by "stringer -type=Opcode"; DO NOT EDIT. - -package vm - -import "strconv" - -const _Opcode_name = "Opush0Opushbytes1Opushbytes75Opushdata1Opushdata2Opushdata4Opushm1Opush1Opush2Opush3Opush4Opush5Opush6Opush7Opush8Opush9Opush10Opush11Opush12Opush13Opush14Opush15Opush16OnopOjmpOjmpifOjmpifnotOcallOretOappcallOsyscallOtailcallOdupfromaltstackOtoaltstackOfromaltstackOxdropOxswapOxtuckOdepthOdropOdupOnipOoverOpickOrollOrotOswapOtuckOcatOsubstrOleftOrightOsizeOinvertOandOorOxorOequalOincOdecOsignOnegateOabsOnotOnzOaddOsubOmulOdivOmodOshlOshrOboolandOboolorOnumequalOnumnotequalOltOgtOlteOgteOminOmaxOwithinOsha1Osha256Ohash160Ohash256OchecksigOcheckmultisigOarraysizeOpackOunpackOpickitemOsetitemOnewarrayOnewstructOappendOreverseOremoveOthrowOthrowifnot" - -var _Opcode_map = map[Opcode]string{ - 0: _Opcode_name[0:6], - 1: _Opcode_name[6:17], - 75: _Opcode_name[17:29], - 76: _Opcode_name[29:39], - 77: _Opcode_name[39:49], - 78: _Opcode_name[49:59], - 79: _Opcode_name[59:66], - 81: _Opcode_name[66:72], - 82: _Opcode_name[72:78], - 83: _Opcode_name[78:84], - 84: _Opcode_name[84:90], - 85: _Opcode_name[90:96], - 86: _Opcode_name[96:102], - 87: _Opcode_name[102:108], - 88: _Opcode_name[108:114], - 89: _Opcode_name[114:120], - 90: _Opcode_name[120:127], - 91: _Opcode_name[127:134], - 92: _Opcode_name[134:141], - 93: _Opcode_name[141:148], - 94: _Opcode_name[148:155], - 95: _Opcode_name[155:162], - 96: _Opcode_name[162:169], - 97: _Opcode_name[169:173], - 98: _Opcode_name[173:177], - 99: _Opcode_name[177:183], - 100: _Opcode_name[183:192], - 101: _Opcode_name[192:197], - 102: _Opcode_name[197:201], - 103: _Opcode_name[201:209], - 104: _Opcode_name[209:217], - 105: _Opcode_name[217:226], - 106: _Opcode_name[226:242], - 107: _Opcode_name[242:253], - 108: _Opcode_name[253:266], - 109: _Opcode_name[266:272], - 114: _Opcode_name[272:278], - 115: _Opcode_name[278:284], - 116: _Opcode_name[284:290], - 117: _Opcode_name[290:295], - 118: _Opcode_name[295:299], - 119: _Opcode_name[299:303], - 120: _Opcode_name[303:308], - 121: _Opcode_name[308:313], - 122: _Opcode_name[313:318], - 123: _Opcode_name[318:322], - 124: _Opcode_name[322:327], - 125: _Opcode_name[327:332], - 126: _Opcode_name[332:336], - 127: _Opcode_name[336:343], - 128: _Opcode_name[343:348], - 129: _Opcode_name[348:354], - 130: _Opcode_name[354:359], - 131: _Opcode_name[359:366], - 132: _Opcode_name[366:370], - 133: _Opcode_name[370:373], - 134: _Opcode_name[373:377], - 135: _Opcode_name[377:383], - 139: _Opcode_name[383:387], - 140: _Opcode_name[387:391], - 141: _Opcode_name[391:396], - 143: _Opcode_name[396:403], - 144: _Opcode_name[403:407], - 145: _Opcode_name[407:411], - 146: _Opcode_name[411:414], - 147: _Opcode_name[414:418], - 148: _Opcode_name[418:422], - 149: _Opcode_name[422:426], - 150: _Opcode_name[426:430], - 151: _Opcode_name[430:434], - 152: _Opcode_name[434:438], - 153: _Opcode_name[438:442], - 154: _Opcode_name[442:450], - 155: _Opcode_name[450:457], - 156: _Opcode_name[457:466], - 158: _Opcode_name[466:478], - 159: _Opcode_name[478:481], - 160: _Opcode_name[481:484], - 161: _Opcode_name[484:488], - 162: _Opcode_name[488:492], - 163: _Opcode_name[492:496], - 164: _Opcode_name[496:500], - 165: _Opcode_name[500:507], - 167: _Opcode_name[507:512], - 168: _Opcode_name[512:519], - 169: _Opcode_name[519:527], - 170: _Opcode_name[527:535], - 172: _Opcode_name[535:544], - 174: _Opcode_name[544:558], - 192: _Opcode_name[558:568], - 193: _Opcode_name[568:573], - 194: _Opcode_name[573:580], - 195: _Opcode_name[580:589], - 196: _Opcode_name[589:597], - 197: _Opcode_name[597:606], - 198: _Opcode_name[606:616], - 200: _Opcode_name[616:623], - 201: _Opcode_name[623:631], - 202: _Opcode_name[631:638], - 240: _Opcode_name[638:644], - 241: _Opcode_name[644:655], -} - -func (i Opcode) String() string { - if str, ok := _Opcode_map[i]; ok { - return str - } - return "Opcode(" + strconv.FormatInt(int64(i), 10) + ")" -} diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index f201ae569..420becec2 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -104,7 +104,7 @@ func (v *VM) PrintOps() { } else { cursor = "" } - fmt.Fprintf(w, "%d\t0x%2x\t%s\t%s\n", i, prog[i], Opcode(prog[i]).String(), cursor) + fmt.Fprintf(w, "%d\t0x%2x\t%s\t%s\n", i, prog[i], Instruction(prog[i]).String(), cursor) } w.Flush() @@ -228,7 +228,7 @@ func (v *VM) Step() { } // execute performs an instruction cycle in the VM. Acting on the instruction (opcode). -func (v *VM) execute(ctx *Context, op Opcode) { +func (v *VM) execute(ctx *Context, op Instruction) { // Instead of polluting the whole VM logic with error handling, we will recover // each panic at a central point, putting the VM in a fault state. defer func() { @@ -239,57 +239,57 @@ func (v *VM) execute(ctx *Context, op Opcode) { } }() - if op >= Opushbytes1 && op <= Opushbytes75 { + if op >= PUSHBYTES1 && op <= PUSHBYTES75 { b := ctx.readBytes(int(op)) v.estack.PushVal(b) return } switch op { - case Opushm1, Opush1, Opush2, Opush3, Opush4, Opush5, - Opush6, Opush7, Opush8, Opush9, Opush10, Opush11, - Opush12, Opush13, Opush14, Opush15, Opush16: - val := int(op) - int(Opush1) + 1 + case PUSHM1, PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, + PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, + PUSH12, PUSH13, PUSH14, PUSH15, PUSH16: + val := int(op) - int(PUSH1) + 1 v.estack.PushVal(val) - case Opush0: + case PUSH0: v.estack.PushVal(0) - case Opushdata1: + case PUSHDATA1: n := ctx.readByte() b := ctx.readBytes(int(n)) v.estack.PushVal(b) - case Opushdata2: + case PUSHDATA2: n := ctx.readUint16() b := ctx.readBytes(int(n)) v.estack.PushVal(b) - case Opushdata4: + case PUSHDATA4: n := ctx.readUint32() b := ctx.readBytes(int(n)) v.estack.PushVal(b) // Stack operations. - case Otoaltstack: + case TOALTSTACK: v.astack.Push(v.estack.Pop()) - case Ofromaltstack: + case FROMALTSTACK: v.estack.Push(v.astack.Pop()) - case Odupfromaltstack: + case DUPFROMALTSTACK: v.estack.Push(v.astack.Dup(0)) - case Odup: + case DUP: v.estack.Push(v.estack.Dup(0)) - case Oswap: + case SWAP: a := v.estack.Pop() b := v.estack.Pop() v.estack.Push(a) v.estack.Push(b) - case Oxswap: + case XSWAP: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 { panic("XSWAP: invalid length") @@ -305,7 +305,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { b.value = aval } - case Otuck: + case TUCK: n := int(v.estack.Pop().BigInt().Int64()) if n <= 0 { panic("OTUCK: invalid length") @@ -313,7 +313,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { v.estack.InsertAt(v.estack.Peek(0), n) - case Orot: + case ROT: c := v.estack.Pop() b := v.estack.Pop() a := v.estack.Pop() @@ -322,21 +322,21 @@ func (v *VM) execute(ctx *Context, op Opcode) { v.estack.Push(c) v.estack.Push(a) - case Odepth: + case DEPTH: v.estack.PushVal(v.estack.Len()) - case Onip: + case NIP: elem := v.estack.Pop() _ = v.estack.Pop() v.estack.Push(elem) - case Oover: + case OVER: b := v.estack.Pop() a := v.estack.Peek(0) v.estack.Push(b) v.estack.Push(a) - case Oroll: + case ROLL: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 { panic("negative stack item returned") @@ -345,105 +345,105 @@ func (v *VM) execute(ctx *Context, op Opcode) { v.estack.Push(v.estack.RemoveAt(n)) } - case Odrop: + case DROP: v.estack.Pop() - case Oequal: + case EQUAL: panic("TODO EQUAL") // Bit operations. - case Oand: + case AND: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).And(b, a)) - case Oor: + case OR: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Or(b, a)) - case Oxor: + case XOR: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Xor(b, a)) // Numeric operations. - case Oadd: + case ADD: a := v.estack.Pop().BigInt() b := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Add(a, b)) - case Osub: + case SUB: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Sub(a, b)) - case Odiv: + case DIV: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Div(a, b)) - case Omul: + case MUL: a := v.estack.Pop().BigInt() b := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Mul(a, b)) - case Omod: + case MOD: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Mod(a, b)) - case Oshl: + case SHL: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Lsh(a, uint(b.Int64()))) - case Oshr: + case SHR: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Rsh(a, uint(b.Int64()))) - case Obooland: + case BOOLAND: b := v.estack.Pop().Bool() a := v.estack.Pop().Bool() v.estack.PushVal(a && b) - case Oboolor: + case BOOLOR: b := v.estack.Pop().Bool() a := v.estack.Pop().Bool() v.estack.PushVal(a || b) - case Onumequal: + case NUMEQUAL: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) == 0) - case Onumnotequal: + case NUMNOTEQUAL: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) != 0) - case Olt: + case LT: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) == -1) - case Ogt: + case GT: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) == 1) - case Olte: + case LTE: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) <= 0) - case Ogte: + case GTE: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) >= 0) - case Omin: + case MIN: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() val := a @@ -452,7 +452,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { } v.estack.PushVal(val) - case Omax: + case MAX: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() val := a @@ -461,52 +461,52 @@ func (v *VM) execute(ctx *Context, op Opcode) { } v.estack.PushVal(val) - case Owithin: + case WITHIN: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() x := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(x) <= 0 && x.Cmp(b) == -1) - case Oinc: + case INC: x := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Add(x, big.NewInt(1))) - case Odec: + case DEC: x := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Sub(x, big.NewInt(1))) - case Osign: + case SIGN: x := v.estack.Pop().BigInt() v.estack.PushVal(x.Sign()) - case Onegate: + case NEGATE: x := v.estack.Pop().BigInt() v.estack.PushVal(x.Neg(x)) - case Oabs: + case ABS: x := v.estack.Pop().BigInt() v.estack.PushVal(x.Abs(x)) - case Onot: + case NOT: x := v.estack.Pop().Bool() v.estack.PushVal(!x) - case Onz: + case NZ: panic("todo NZ") // x := v.estack.Pop().BigInt() // Object operations. - case Onewarray: + case NEWARRAY: n := v.estack.Pop().BigInt().Int64() items := make([]StackItem, n) v.estack.PushVal(&ArrayItem{items}) - case Onewstruct: + case NEWSTRUCT: n := v.estack.Pop().BigInt().Int64() items := make([]StackItem, n) v.estack.PushVal(&StructItem{items}) - case Oappend: + case APPEND: itemElem := v.estack.Pop() arrElem := v.estack.Pop() @@ -522,11 +522,11 @@ func (v *VM) execute(ctx *Context, op Opcode) { panic("APPEND: not of underlying type Array") } - case Oreverse: + case REVERSE: - case Oremove: + case REMOVE: - case Opack: + case PACK: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 || n > v.estack.Len() { panic("OPACK: invalid length") @@ -539,10 +539,10 @@ func (v *VM) execute(ctx *Context, op Opcode) { v.estack.PushVal(items) - case Ounpack: + case UNPACK: panic("TODO") - case Opickitem: + case PICKITEM: var ( key = v.estack.Pop() obj = v.estack.Pop() @@ -562,7 +562,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { panic("PICKITEM: unknown type") } - case Osetitem: + case SETITEM: var ( item = v.estack.Pop().value key = v.estack.Pop() @@ -582,7 +582,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { panic(fmt.Sprintf("SETITEM: invalid item type %s", t)) } - case Oarraysize: + case ARRAYSIZE: elem := v.estack.Pop() // Cause there is no native (byte) item type here, hence we need to check // the type of the item for array size operations. @@ -595,7 +595,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { panic("ARRAYSIZE: item not of type []StackItem") } - case Osize: + case SIZE: elem := v.estack.Pop() arr, ok := elem.value.Value().([]uint8) if !ok { @@ -603,7 +603,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { } v.estack.PushVal(len(arr)) - case Ojmp, Ojmpif, Ojmpifnot: + case JMP, JMPIF, JMPIFNOT: var ( rOffset = int16(ctx.readUint16()) offset = ctx.ip + int(rOffset) - 3 // sizeOf(int16 + uint8) @@ -612,9 +612,9 @@ func (v *VM) execute(ctx *Context, op Opcode) { panic(fmt.Sprintf("JMP: invalid offset %d ip at %d", offset, ctx.ip)) } cond := true - if op > Ojmp { + if op > JMP { cond = v.estack.Pop().Bool() - if op == Ojmpifnot { + if op == JMPIFNOT { cond = !cond } } @@ -622,12 +622,12 @@ func (v *VM) execute(ctx *Context, op Opcode) { ctx.ip = offset } - case Ocall: + case CALL: v.istack.PushVal(ctx.Copy()) ctx.ip += 2 - v.execute(v.Context(), Ojmp) + v.execute(v.Context(), JMP) - case Osyscall: + case SYSCALL: api := ctx.readVarBytes() ifunc, ok := v.interop[string(api)] if !ok { @@ -637,7 +637,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { panic(fmt.Sprintf("failed to invoke syscall: %s", err)) } - case Oappcall, Otailcall: + case APPCALL, TAILCALL: if len(v.scripts) == 0 { panic("script table is empty") } @@ -652,32 +652,32 @@ func (v *VM) execute(ctx *Context, op Opcode) { panic("could not find script") } - if op == Otailcall { + if op == TAILCALL { _ = v.istack.Pop() } v.LoadScript(script) - case Oret: + case RET: _ = v.istack.Pop() if v.istack.Len() == 0 { v.state = haltState } // Cryptographic operations. - case Osha1: + case SHA1: b := v.estack.Pop().Bytes() sha := sha1.New() sha.Write(b) v.estack.PushVal(sha.Sum(nil)) - case Osha256: + case SHA256: b := v.estack.Pop().Bytes() sha := sha256.New() sha.Write(b) v.estack.PushVal(sha.Sum(nil)) - case Ohash160: + case HASH160: b := v.estack.Pop().Bytes() sha := sha256.New() sha.Write(b) @@ -686,7 +686,7 @@ func (v *VM) execute(ctx *Context, op Opcode) { ripemd.Write(h) v.estack.PushVal(ripemd.Sum(nil)) - case Ohash256: + case HASH256: b := v.estack.Pop().Bytes() sha := sha256.New() sha.Write(b) @@ -695,19 +695,19 @@ func (v *VM) execute(ctx *Context, op Opcode) { sha.Write(h) v.estack.PushVal(sha.Sum(nil)) - case Ochecksig: + case CHECKSIG: // pubkey := v.estack.Pop().Bytes() // sig := v.estack.Pop().Bytes() - case Ocheckmultisig: + case CHECKMULTISIG: - case Onop: + case NOP: // unlucky ^^ - case Othrow: + case THROW: panic("THROW") - case Othrowifnot: + case THROWIFNOT: if !v.estack.Pop().Bool() { panic("THROWIFNOT") } diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index cc67101a8..257271056 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -20,7 +20,7 @@ func TestInteropHook(t *testing.T) { buf := new(bytes.Buffer) EmitSyscall(buf, "foo") - EmitOpcode(buf, Oret) + EmitOpcode(buf, RET) v.Load(buf.Bytes()) v.Run() assert.Equal(t, 1, v.estack.Len()) @@ -51,7 +51,7 @@ func TestPushBytes1to75(t *testing.T) { assert.IsType(t, elem.Bytes(), b) assert.Equal(t, 0, vm.estack.Len()) - vm.execute(nil, Oret) + vm.execute(nil, RET) assert.Equal(t, 0, vm.astack.Len()) assert.Equal(t, 0, vm.istack.Len()) @@ -61,7 +61,7 @@ func TestPushBytes1to75(t *testing.T) { func TestPushm1to16(t *testing.T) { var prog []byte - for i := int(Opushm1); i <= int(Opush16); i++ { + for i := int(PUSHM1); i <= int(PUSH16); i++ { if i == 80 { continue // opcode layout we got here. } @@ -69,7 +69,7 @@ func TestPushm1to16(t *testing.T) { } vm := load(prog) - for i := int(Opushm1); i <= int(Opush16); i++ { + for i := int(PUSHM1); i <= int(PUSH16); i++ { if i == 80 { continue // nice opcode layout we got here. } @@ -77,7 +77,7 @@ func TestPushm1to16(t *testing.T) { elem := vm.estack.Pop() assert.IsType(t, &BigIntegerItem{}, elem.value) - val := i - int(Opush1) + 1 + val := i - int(PUSH1) + 1 assert.Equal(t, elem.BigInt().Int64(), int64(val)) } } @@ -95,7 +95,7 @@ func TestPushData4(t *testing.T) { } func TestAdd(t *testing.T) { - prog := makeProgram(Oadd) + prog := makeProgram(ADD) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -104,7 +104,7 @@ func TestAdd(t *testing.T) { } func TestMul(t *testing.T) { - prog := makeProgram(Omul) + prog := makeProgram(MUL) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -113,7 +113,7 @@ func TestMul(t *testing.T) { } func TestDiv(t *testing.T) { - prog := makeProgram(Odiv) + prog := makeProgram(DIV) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -122,7 +122,7 @@ func TestDiv(t *testing.T) { } func TestSub(t *testing.T) { - prog := makeProgram(Osub) + prog := makeProgram(SUB) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -131,7 +131,7 @@ func TestSub(t *testing.T) { } func TestLT(t *testing.T) { - prog := makeProgram(Olt) + prog := makeProgram(LT) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(3) @@ -140,7 +140,7 @@ func TestLT(t *testing.T) { } func TestLTE(t *testing.T) { - prog := makeProgram(Olte) + prog := makeProgram(LTE) vm := load(prog) vm.estack.PushVal(2) vm.estack.PushVal(3) @@ -149,7 +149,7 @@ func TestLTE(t *testing.T) { } func TestGT(t *testing.T) { - prog := makeProgram(Ogt) + prog := makeProgram(GT) vm := load(prog) vm.estack.PushVal(9) vm.estack.PushVal(3) @@ -159,7 +159,7 @@ func TestGT(t *testing.T) { } func TestGTE(t *testing.T) { - prog := makeProgram(Ogte) + prog := makeProgram(GTE) vm := load(prog) vm.estack.PushVal(3) vm.estack.PushVal(3) @@ -168,7 +168,7 @@ func TestGTE(t *testing.T) { } func TestDepth(t *testing.T) { - prog := makeProgram(Odepth) + prog := makeProgram(DEPTH) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -178,7 +178,7 @@ func TestDepth(t *testing.T) { } func TestNumEqual(t *testing.T) { - prog := makeProgram(Onumequal) + prog := makeProgram(NUMEQUAL) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -187,7 +187,7 @@ func TestNumEqual(t *testing.T) { } func TestNumNotEqual(t *testing.T) { - prog := makeProgram(Onumnotequal) + prog := makeProgram(NUMNOTEQUAL) vm := load(prog) vm.estack.PushVal(2) vm.estack.PushVal(2) @@ -196,7 +196,7 @@ func TestNumNotEqual(t *testing.T) { } func TestINC(t *testing.T) { - prog := makeProgram(Oinc) + prog := makeProgram(INC) vm := load(prog) vm.estack.PushVal(1) vm.Run() @@ -204,13 +204,13 @@ func TestINC(t *testing.T) { } func TestAppCall(t *testing.T) { - prog := []byte{byte(Oappcall)} + prog := []byte{byte(APPCALL)} hash := util.Uint160{} prog = append(prog, hash.Bytes()...) - prog = append(prog, byte(Oret)) + prog = append(prog, byte(RET)) vm := load(prog) - vm.scripts[hash] = makeProgram(Odepth) + vm.scripts[hash] = makeProgram(DEPTH) vm.estack.PushVal(2) vm.Run() @@ -231,12 +231,12 @@ func TestSimpleCall(t *testing.T) { assert.Equal(t, result, int(vm.estack.Pop().BigInt().Int64())) } -func makeProgram(opcodes ...Opcode) []byte { - prog := make([]byte, len(opcodes)+1) // Oret +func makeProgram(opcodes ...Instruction) []byte { + prog := make([]byte, len(opcodes)+1) // RET for i := 0; i < len(opcodes); i++ { prog[i] = byte(opcodes[i]) } - prog[len(prog)-1] = byte(Oret) + prog[len(prog)-1] = byte(RET) return prog }