aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/stack.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-03-21 05:51:20 +0800
committerobscuren <geffobscura@gmail.com>2014-03-21 05:51:20 +0800
commitf3d27bf5d878120346f8cdd0744e7f1f8e1ee631 (patch)
tree8b265236e4707a5260a7bf365cf103499c0c5767 /ethchain/stack.go
parentc68ff9886bdd59294bc2bf0a6b8bf9b83645cc9a (diff)
downloaddexon-f3d27bf5d878120346f8cdd0744e7f1f8e1ee631.tar
dexon-f3d27bf5d878120346f8cdd0744e7f1f8e1ee631.tar.gz
dexon-f3d27bf5d878120346f8cdd0744e7f1f8e1ee631.tar.bz2
dexon-f3d27bf5d878120346f8cdd0744e7f1f8e1ee631.tar.lz
dexon-f3d27bf5d878120346f8cdd0744e7f1f8e1ee631.tar.xz
dexon-f3d27bf5d878120346f8cdd0744e7f1f8e1ee631.tar.zst
dexon-f3d27bf5d878120346f8cdd0744e7f1f8e1ee631.zip
Rewrote opcodes again
Diffstat (limited to 'ethchain/stack.go')
-rw-r--r--ethchain/stack.go303
1 files changed, 144 insertions, 159 deletions
diff --git a/ethchain/stack.go b/ethchain/stack.go
index bfb19614e..429c31d08 100644
--- a/ethchain/stack.go
+++ b/ethchain/stack.go
@@ -2,7 +2,7 @@ package ethchain
import (
"fmt"
- "github.com/ethereum/eth-go/ethutil"
+ _ "github.com/ethereum/eth-go/ethutil"
"math/big"
)
@@ -10,116 +10,136 @@ type OpCode int
// Op codes
const (
- oSTOP = 0x00
- oADD = 0x01
- oMUL = 0x02
- oSUB = 0x03
- oDIV = 0x04
- oSDIV = 0x05
- oMOD = 0x06
- oSMOD = 0x07
- oEXP = 0x08
- oNEG = 0x09
- oLT = 0x0a
- oLE = 0x0b
- oGT = 0x0c
- oGE = 0x0d
- oEQ = 0x0e
- oNOT = 0x0f
- oMYADDRESS = 0x10
- oTXSENDER = 0x11
- oTXVALUE = 0x12
- oTXDATAN = 0x13
- oTXDATA = 0x14
- oBLK_PREVHASH = 0x15
- oBLK_COINBASE = 0x16
- oBLK_TIMESTAMP = 0x17
- oBLK_NUMBER = 0x18
- oBLK_DIFFICULTY = 0x19
- oBLK_NONCE = 0x1a
- oBASEFEE = 0x1b
- oSHA256 = 0x20
- oRIPEMD160 = 0x21
- oECMUL = 0x22
- oECADD = 0x23
- oECSIGN = 0x24
- oECRECOVER = 0x25
- oECVALID = 0x26
- oSHA3 = 0x27
- oPUSH = 0x30
- oPOP = 0x31
- oDUP = 0x32
- oSWAP = 0x33
- oMLOAD = 0x34
- oMSTORE = 0x35
- oSLOAD = 0x36
- oSSTORE = 0x37
- oJMP = 0x38
- oJMPI = 0x39
- oIND = 0x3a
- oEXTRO = 0x3b
- oBALANCE = 0x3c
- oMKTX = 0x3d
- oSUICIDE = 0x3f
-
- // TODO FIX OPCODES
- oCALL = 0x40
- oRETURN = 0x41
+ // 0x0 range - arithmetic ops
+ oSTOP = 0x00
+ oADD = 0x01
+ oMUL = 0x02
+ oSUB = 0x03
+ oDIV = 0x04
+ oSDIV = 0x05
+ oMOD = 0x06
+ oSMOD = 0x07
+ oEXP = 0x08
+ oNEG = 0x09
+ oLT = 0x0a
+ oGT = 0x0b
+ oEQ = 0x0c
+ oNOT = 0x0d
+
+ // 0x10 range - bit ops
+ oAND = 0x10
+ oOR = 0x11
+ oXOR = 0x12
+ oBYTE = 0x13
+
+ // 0x20 range - crypto
+ oSHA3 = 0x20
+
+ // 0x30 range - closure state
+ oADDRESS = 0x30
+ oBALANCE = 0x31
+ oORIGIN = 0x32
+ oCALLER = 0x33
+ oCALLVALUE = 0x34
+ oCALLDATA = 0x35
+ oCALLDATASIZE = 0x36
+ oRETURNDATASIZE = 0x37
+ oTXGASPRICE = 0x38
+
+ // 0x40 range - block operations
+ oPREVHASH = 0x40
+ oPREVNONCE = 0x41
+ oCOINBASE = 0x42
+ oTIMESTAMP = 0x43
+ oNUMBER = 0x44
+ oDIFFICULTY = 0x45
+ oGASLIMIT = 0x46
+
+ // 0x50 range - 'storage' and execution
+ oPUSH = 0x50
+ oPOP = 0x51
+ oDUP = 0x52
+ oSWAP = 0x53
+ oMLOAD = 0x54
+ oMSTORE = 0x55
+ oMSTORE8 = 0x56
+ oSLOAD = 0x57
+ oSSTORE = 0x58
+ oJUMP = 0x59
+ oJUMPI = 0x5a
+ oPC = 0x5b
+ oMEMSIZE = 0x5c
+
+ // 0x60 range - closures
+ oCREATE = 0x60
+ oCALL = 0x61
+ oRETURN = 0x62
)
// Since the opcodes aren't all in order we can't use a regular slice
var opCodeToString = map[OpCode]string{
- oSTOP: "STOP",
- oADD: "ADD",
- oMUL: "MUL",
- oSUB: "SUB",
- oDIV: "DIV",
- oSDIV: "SDIV",
- oMOD: "MOD",
- oSMOD: "SMOD",
- oEXP: "EXP",
- oNEG: "NEG",
- oLT: "LT",
- oLE: "LE",
- oGT: "GT",
- oGE: "GE",
- oEQ: "EQ",
- oNOT: "NOT",
- oMYADDRESS: "MYADDRESS",
- oTXSENDER: "TXSENDER",
- oTXVALUE: "TXVALUE",
- oTXDATAN: "TXDATAN",
- oTXDATA: "TXDATA",
- oBLK_PREVHASH: "BLK_PREVHASH",
- oBLK_COINBASE: "BLK_COINBASE",
- oBLK_TIMESTAMP: "BLK_TIMESTAMP",
- oBLK_NUMBER: "BLK_NUMBER",
- oBLK_DIFFICULTY: "BLK_DIFFICULTY",
- oBASEFEE: "BASEFEE",
- oSHA256: "SHA256",
- oRIPEMD160: "RIPEMD160",
- oECMUL: "ECMUL",
- oECADD: "ECADD",
- oECSIGN: "ECSIGN",
- oECRECOVER: "ECRECOVER",
- oECVALID: "ECVALID",
- oSHA3: "SHA3",
- oPUSH: "PUSH",
- oPOP: "POP",
- oDUP: "DUP",
- oSWAP: "SWAP",
- oMLOAD: "MLOAD",
- oMSTORE: "MSTORE",
- oSLOAD: "SLOAD",
- oSSTORE: "SSTORE",
- oJMP: "JMP",
- oJMPI: "JMPI",
- oIND: "IND",
- oEXTRO: "EXTRO",
+ // 0x0 range - arithmetic ops
+ oSTOP: "STOP",
+ oADD: "ADD",
+ oMUL: "MUL",
+ oSUB: "SUB",
+ oDIV: "DIV",
+ oSDIV: "SDIV",
+ oMOD: "MOD",
+ oSMOD: "SMOD",
+ oEXP: "EXP",
+ oNEG: "NEG",
+ oLT: "LT",
+ oGT: "GT",
+ oEQ: "EQ",
+ oNOT: "NOT",
+
+ // 0x10 range - bit ops
+ oAND: "AND",
+ oOR: "OR",
+ oXOR: "XOR",
+ oBYTE: "BYTE",
+
+ // 0x20 range - crypto
+ oSHA3: "SHA3",
+
+ // 0x30 range - closure state
+ oADDRESS: "ADDRESS",
oBALANCE: "BALANCE",
- oMKTX: "MKTX",
- oSUICIDE: "SUICIDE",
-
+ oORIGIN: "ORIGIN",
+ oCALLER: "CALLER",
+ oCALLVALUE: "CALLVALUE",
+ oCALLDATA: "CALLDATA",
+ oCALLDATASIZE: "CALLDATASIZE",
+ oRETURNDATASIZE: "RETURNDATASIZE",
+ oTXGASPRICE: "TXGASPRICE",
+
+ // 0x40 range - block operations
+ oPREVHASH: "PREVHASH",
+ oPREVNONCE: "PREVNONCE",
+ oCOINBASE: "COINBASE",
+ oTIMESTAMP: "TIMESTAMP",
+ oNUMBER: "NUMBER",
+ oDIFFICULTY: "DIFFICULTY",
+ oGASLIMIT: "GASLIMIT",
+
+ // 0x50 range - 'storage' and execution
+ oPUSH: "PUSH",
+ oPOP: "POP",
+ oDUP: "DUP",
+ oSWAP: "SWAP",
+ oMLOAD: "MLOAD",
+ oMSTORE: "MSTORE",
+ oMSTORE8: "MSTORE8",
+ oSLOAD: "SLOAD",
+ oSSTORE: "SSTORE",
+ oJUMP: "JUMP",
+ oJUMPI: "JUMPI",
+ oPC: "PC",
+ oMEMSIZE: "MEMSIZE",
+
+ // 0x60 range - closures
+ oCREATE: "CREATE",
oCALL: "CALL",
oRETURN: "RETURN",
}
@@ -189,61 +209,26 @@ func (st *Stack) Print() {
fmt.Println("#############")
}
-////////////// TODO this will eventually become the main stack once the big ints are removed from the VM
-type ValueStack struct {
- data []*ethutil.Value
-}
-
-func NewValueStack() *ValueStack {
- return &ValueStack{}
-}
-
-func (st *ValueStack) Pop() *ethutil.Value {
- s := len(st.data)
-
- str := st.data[s-1]
- st.data = st.data[:s-1]
-
- return str
-}
-
-func (st *ValueStack) Popn() (*ethutil.Value, *ethutil.Value) {
- s := len(st.data)
-
- ints := st.data[s-2:]
- st.data = st.data[:s-2]
-
- return ints[0], ints[1]
-}
-
-func (st *ValueStack) Peek() *ethutil.Value {
- s := len(st.data)
-
- str := st.data[s-1]
-
- return str
+type Memory struct {
+ store []byte
}
-func (st *ValueStack) Peekn() (*ethutil.Value, *ethutil.Value) {
- s := len(st.data)
-
- ints := st.data[s-2:]
-
- return ints[0], ints[1]
-}
-
-func (st *ValueStack) Push(d *ethutil.Value) {
- st.data = append(st.data, d)
-}
-
-func (st *ValueStack) Print() {
- fmt.Println("### STACK ###")
- if len(st.data) > 0 {
- for i, val := range st.data {
- fmt.Printf("%-3d %v\n", i, val)
+func (m *Memory) Set(offset, size int64, value []byte) {
+ totSize := offset + size
+ lenSize := int64(len(m.store))
+ if totSize > lenSize {
+ // Calculate the diff between the sizes
+ diff := totSize - lenSize
+ if diff > 0 {
+ // Create a new empty slice and append it
+ newSlice := make([]byte, diff+1)
+ // Resize slice
+ m.store = append(m.store, newSlice...)
}
- } else {
- fmt.Println("-- empty --")
}
- fmt.Println("#############")
+ copy(m.store[offset:offset+size+1], value)
+}
+
+func (m *Memory) Get(offset, size int64) []byte {
+ return m.store[offset : offset+size]
}