Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
0b978f91
Commit
0b978f91
authored
Aug 16, 2017
by
Péter Szilágyi
Committed by
GitHub
Aug 16, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14981 from karalabe/metropolis-returndata
core/vm: implement RETURNDATA metropolis opcodes
parents
76069eef
64d199ed
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
280 additions
and
195 deletions
+280
-195
evm.go
core/vm/evm.go
+3
-3
gas_table.go
core/vm/gas_table.go
+27
-1
instructions.go
core/vm/instructions.go
+52
-26
interpreter.go
core/vm/interpreter.go
+11
-6
jump_table.go
core/vm/jump_table.go
+25
-5
memory.go
core/vm/memory.go
+0
-1
memory_table.go
core/vm/memory_table.go
+5
-1
opcodes.go
core/vm/opcodes.go
+156
-151
testdata
tests/testdata
+1
-1
No files found.
core/vm/evm.go
View file @
0b978f91
...
@@ -261,9 +261,9 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
...
@@ -261,9 +261,9 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// Make sure the readonly is only set if we aren't in readonly yet
// Make sure the readonly is only set if we aren't in readonly yet
// this makes also sure that the readonly flag isn't removed for
// this makes also sure that the readonly flag isn't removed for
// child calls.
// child calls.
if
!
evm
.
interpreter
.
read
o
nly
{
if
!
evm
.
interpreter
.
read
O
nly
{
evm
.
interpreter
.
read
o
nly
=
true
evm
.
interpreter
.
read
O
nly
=
true
defer
func
()
{
evm
.
interpreter
.
read
o
nly
=
false
}()
defer
func
()
{
evm
.
interpreter
.
read
O
nly
=
false
}()
}
}
var
(
var
(
...
...
core/vm/gas_table.go
View file @
0b978f91
...
@@ -65,7 +65,33 @@ func constGasFunc(gas uint64) gasFunc {
...
@@ -65,7 +65,33 @@ func constGasFunc(gas uint64) gasFunc {
}
}
}
}
func
gasCalldataCopy
(
gt
params
.
GasTable
,
evm
*
EVM
,
contract
*
Contract
,
stack
*
Stack
,
mem
*
Memory
,
memorySize
uint64
)
(
uint64
,
error
)
{
func
gasCallDataCopy
(
gt
params
.
GasTable
,
evm
*
EVM
,
contract
*
Contract
,
stack
*
Stack
,
mem
*
Memory
,
memorySize
uint64
)
(
uint64
,
error
)
{
gas
,
err
:=
memoryGasCost
(
mem
,
memorySize
)
if
err
!=
nil
{
return
0
,
err
}
var
overflow
bool
if
gas
,
overflow
=
math
.
SafeAdd
(
gas
,
GasFastestStep
);
overflow
{
return
0
,
errGasUintOverflow
}
words
,
overflow
:=
bigUint64
(
stack
.
Back
(
2
))
if
overflow
{
return
0
,
errGasUintOverflow
}
if
words
,
overflow
=
math
.
SafeMul
(
toWordSize
(
words
),
params
.
CopyGas
);
overflow
{
return
0
,
errGasUintOverflow
}
if
gas
,
overflow
=
math
.
SafeAdd
(
gas
,
words
);
overflow
{
return
0
,
errGasUintOverflow
}
return
gas
,
nil
}
func
gasReturnDataCopy
(
gt
params
.
GasTable
,
evm
*
EVM
,
contract
*
Contract
,
stack
*
Stack
,
mem
*
Memory
,
memorySize
uint64
)
(
uint64
,
error
)
{
gas
,
err
:=
memoryGasCost
(
mem
,
memorySize
)
gas
,
err
:=
memoryGasCost
(
mem
,
memorySize
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
0
,
err
...
...
core/vm/instructions.go
View file @
0b978f91
...
@@ -29,8 +29,9 @@ import (
...
@@ -29,8 +29,9 @@ import (
)
)
var
(
var
(
bigZero
=
new
(
big
.
Int
)
bigZero
=
new
(
big
.
Int
)
errWriteProtection
=
errors
.
New
(
"evm: write protection"
)
errWriteProtection
=
errors
.
New
(
"evm: write protection"
)
errReturnDataOutOfBounds
=
errors
.
New
(
"evm: return data out of bounds"
)
)
)
func
opAdd
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opAdd
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
...
@@ -242,6 +243,7 @@ func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
...
@@ -242,6 +243,7 @@ func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
evm
.
interpreter
.
intPool
.
put
(
y
)
evm
.
interpreter
.
intPool
.
put
(
y
)
return
nil
,
nil
return
nil
,
nil
}
}
func
opOr
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opOr
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
x
,
y
:=
stack
.
pop
(),
stack
.
pop
()
x
,
y
:=
stack
.
pop
(),
stack
.
pop
()
stack
.
push
(
x
.
Or
(
x
,
y
))
stack
.
push
(
x
.
Or
(
x
,
y
))
...
@@ -249,6 +251,7 @@ func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack
...
@@ -249,6 +251,7 @@ func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack
evm
.
interpreter
.
intPool
.
put
(
y
)
evm
.
interpreter
.
intPool
.
put
(
y
)
return
nil
,
nil
return
nil
,
nil
}
}
func
opXor
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opXor
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
x
,
y
:=
stack
.
pop
(),
stack
.
pop
()
x
,
y
:=
stack
.
pop
(),
stack
.
pop
()
stack
.
push
(
x
.
Xor
(
x
,
y
))
stack
.
push
(
x
.
Xor
(
x
,
y
))
...
@@ -268,6 +271,7 @@ func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
...
@@ -268,6 +271,7 @@ func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
evm
.
interpreter
.
intPool
.
put
(
th
)
evm
.
interpreter
.
intPool
.
put
(
th
)
return
nil
,
nil
return
nil
,
nil
}
}
func
opAddmod
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opAddmod
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
x
,
y
,
z
:=
stack
.
pop
(),
stack
.
pop
(),
stack
.
pop
()
x
,
y
,
z
:=
stack
.
pop
(),
stack
.
pop
(),
stack
.
pop
()
if
z
.
Cmp
(
bigZero
)
>
0
{
if
z
.
Cmp
(
bigZero
)
>
0
{
...
@@ -281,6 +285,7 @@ func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S
...
@@ -281,6 +285,7 @@ func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S
evm
.
interpreter
.
intPool
.
put
(
y
,
z
)
evm
.
interpreter
.
intPool
.
put
(
y
,
z
)
return
nil
,
nil
return
nil
,
nil
}
}
func
opMulmod
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opMulmod
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
x
,
y
,
z
:=
stack
.
pop
(),
stack
.
pop
(),
stack
.
pop
()
x
,
y
,
z
:=
stack
.
pop
(),
stack
.
pop
(),
stack
.
pop
()
if
z
.
Cmp
(
bigZero
)
>
0
{
if
z
.
Cmp
(
bigZero
)
>
0
{
...
@@ -338,25 +343,47 @@ func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
...
@@ -338,25 +343,47 @@ func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
return
nil
,
nil
return
nil
,
nil
}
}
func
opCall
d
ataLoad
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opCall
D
ataLoad
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
stack
.
push
(
new
(
big
.
Int
)
.
SetBytes
(
getDataBig
(
contract
.
Input
,
stack
.
pop
(),
big32
)))
stack
.
push
(
new
(
big
.
Int
)
.
SetBytes
(
getDataBig
(
contract
.
Input
,
stack
.
pop
(),
big32
)))
return
nil
,
nil
return
nil
,
nil
}
}
func
opCall
d
ataSize
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opCall
D
ataSize
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
stack
.
push
(
evm
.
interpreter
.
intPool
.
get
()
.
SetInt64
(
int64
(
len
(
contract
.
Input
))))
stack
.
push
(
evm
.
interpreter
.
intPool
.
get
()
.
SetInt64
(
int64
(
len
(
contract
.
Input
))))
return
nil
,
nil
return
nil
,
nil
}
}
func
opCalldataCopy
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opCallDataCopy
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
var
(
memOffset
=
stack
.
pop
()
dataOffset
=
stack
.
pop
()
length
=
stack
.
pop
()
)
memory
.
Set
(
memOffset
.
Uint64
(),
length
.
Uint64
(),
getDataBig
(
contract
.
Input
,
dataOffset
,
length
))
evm
.
interpreter
.
intPool
.
put
(
memOffset
,
dataOffset
,
length
)
return
nil
,
nil
}
func
opReturnDataSize
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
stack
.
push
(
evm
.
interpreter
.
intPool
.
get
()
.
SetUint64
(
uint64
(
len
(
evm
.
interpreter
.
returnData
))))
return
nil
,
nil
}
func
opReturnDataCopy
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
var
(
var
(
m
Off
=
stack
.
pop
()
m
emOffset
=
stack
.
pop
()
cOff
=
stack
.
pop
()
dataOffset
=
stack
.
pop
()
l
=
stack
.
pop
()
l
ength
=
stack
.
pop
()
)
)
memory
.
Set
(
mOff
.
Uint64
(),
l
.
Uint64
(),
getDataBig
(
contract
.
Input
,
cOff
,
l
))
defer
evm
.
interpreter
.
intPool
.
put
(
memOffset
,
dataOffset
,
length
)
end
:=
new
(
big
.
Int
)
.
Add
(
dataOffset
,
length
)
if
end
.
BitLen
()
>
64
||
uint64
(
len
(
evm
.
interpreter
.
returnData
))
<
end
.
Uint64
()
{
return
nil
,
errReturnDataOutOfBounds
}
memory
.
Set
(
memOffset
.
Uint64
(),
length
.
Uint64
(),
evm
.
interpreter
.
returnData
[
dataOffset
.
Uint64
()
:
end
.
Uint64
()])
evm
.
interpreter
.
intPool
.
put
(
mOff
,
cOff
,
l
)
return
nil
,
nil
return
nil
,
nil
}
}
...
@@ -378,31 +405,28 @@ func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
...
@@ -378,31 +405,28 @@ func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
func
opCodeCopy
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opCodeCopy
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
var
(
var
(
m
Off
=
stack
.
pop
()
m
emOffset
=
stack
.
pop
()
c
Off
=
stack
.
pop
()
c
odeOffset
=
stack
.
pop
()
l
=
stack
.
pop
()
l
ength
=
stack
.
pop
()
)
)
codeCopy
:=
getDataBig
(
contract
.
Code
,
cOff
,
l
)
codeCopy
:=
getDataBig
(
contract
.
Code
,
codeOffset
,
length
)
memory
.
Set
(
memOffset
.
Uint64
(),
length
.
Uint64
(),
codeCopy
)
memory
.
Set
(
mOff
.
Uint64
(),
l
.
Uint64
(),
codeCopy
)
evm
.
interpreter
.
intPool
.
put
(
memOffset
,
codeOffset
,
length
)
evm
.
interpreter
.
intPool
.
put
(
mOff
,
cOff
,
l
)
return
nil
,
nil
return
nil
,
nil
}
}
func
opExtCodeCopy
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opExtCodeCopy
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
var
(
var
(
addr
=
common
.
BigToAddress
(
stack
.
pop
())
addr
=
common
.
BigToAddress
(
stack
.
pop
())
m
Off
=
stack
.
pop
()
m
emOffset
=
stack
.
pop
()
c
Off
=
stack
.
pop
()
c
odeOffset
=
stack
.
pop
()
l
=
stack
.
pop
()
l
ength
=
stack
.
pop
()
)
)
codeCopy
:=
getDataBig
(
evm
.
StateDB
.
GetCode
(
addr
),
cOff
,
l
)
codeCopy
:=
getDataBig
(
evm
.
StateDB
.
GetCode
(
addr
),
codeOffset
,
length
)
memory
.
Set
(
memOffset
.
Uint64
(),
length
.
Uint64
(),
codeCopy
)
memory
.
Set
(
mOff
.
Uint64
(),
l
.
Uint64
(),
codeCopy
)
evm
.
interpreter
.
intPool
.
put
(
mOff
,
cOff
,
l
)
evm
.
interpreter
.
intPool
.
put
(
memOffset
,
codeOffset
,
length
)
return
nil
,
nil
return
nil
,
nil
}
}
...
@@ -507,6 +531,7 @@ func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
...
@@ -507,6 +531,7 @@ func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
evm
.
interpreter
.
intPool
.
put
(
pos
)
evm
.
interpreter
.
intPool
.
put
(
pos
)
return
nil
,
nil
return
nil
,
nil
}
}
func
opJumpi
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opJumpi
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
pos
,
cond
:=
stack
.
pop
(),
stack
.
pop
()
pos
,
cond
:=
stack
.
pop
(),
stack
.
pop
()
if
cond
.
Sign
()
!=
0
{
if
cond
.
Sign
()
!=
0
{
...
@@ -522,6 +547,7 @@ func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St
...
@@ -522,6 +547,7 @@ func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St
evm
.
interpreter
.
intPool
.
put
(
pos
,
cond
)
evm
.
interpreter
.
intPool
.
put
(
pos
,
cond
)
return
nil
,
nil
return
nil
,
nil
}
}
func
opJumpdest
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
func
opJumpdest
(
pc
*
uint64
,
evm
*
EVM
,
contract
*
Contract
,
memory
*
Memory
,
stack
*
Stack
)
([]
byte
,
error
)
{
return
nil
,
nil
return
nil
,
nil
}
}
...
...
core/vm/interpreter.go
View file @
0b978f91
...
@@ -59,7 +59,8 @@ type Interpreter struct {
...
@@ -59,7 +59,8 @@ type Interpreter struct {
gasTable
params
.
GasTable
gasTable
params
.
GasTable
intPool
*
intPool
intPool
*
intPool
readonly
bool
readOnly
bool
// Whether to throw on stateful modifications
returnData
[]
byte
// Last CALL's return data for subsequent reuse
}
}
// NewInterpreter returns a new instance of the Interpreter.
// NewInterpreter returns a new instance of the Interpreter.
...
@@ -88,7 +89,7 @@ func NewInterpreter(evm *EVM, cfg Config) *Interpreter {
...
@@ -88,7 +89,7 @@ func NewInterpreter(evm *EVM, cfg Config) *Interpreter {
func
(
in
*
Interpreter
)
enforceRestrictions
(
op
OpCode
,
operation
operation
,
stack
*
Stack
)
error
{
func
(
in
*
Interpreter
)
enforceRestrictions
(
op
OpCode
,
operation
operation
,
stack
*
Stack
)
error
{
if
in
.
evm
.
chainRules
.
IsMetropolis
{
if
in
.
evm
.
chainRules
.
IsMetropolis
{
if
in
.
read
o
nly
{
if
in
.
read
O
nly
{
// If the interpreter is operating in readonly mode, make sure no
// If the interpreter is operating in readonly mode, make sure no
// state-modifying operation is performed. The 3rd stack item
// state-modifying operation is performed. The 3rd stack item
// for a call operation is the value. Transfering value from one
// for a call operation is the value. Transfering value from one
...
@@ -113,6 +114,10 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
...
@@ -113,6 +114,10 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
in
.
evm
.
depth
++
in
.
evm
.
depth
++
defer
func
()
{
in
.
evm
.
depth
--
}()
defer
func
()
{
in
.
evm
.
depth
--
}()
// Reset the previous call's return data. It's unimportant to preserve the old buffer
// as every returning call will return new data anyway.
in
.
returnData
=
nil
// Don't bother with the execution if there's no code.
// Don't bother with the execution if there's no code.
if
len
(
contract
.
Code
)
==
0
{
if
len
(
contract
.
Code
)
==
0
{
return
nil
,
nil
return
nil
,
nil
...
@@ -213,10 +218,10 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
...
@@ -213,10 +218,10 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
case
!
operation
.
jumps
:
case
!
operation
.
jumps
:
pc
++
pc
++
}
}
// if the operation
returned a value make sure that is also set
// if the operation
clears the return data (e.g. it has returning data)
//
the last return data
.
//
set the last return to the result of the operation
.
if
res
!=
nil
{
if
operation
.
returns
{
mem
.
lastReturn
=
ret
in
.
returnData
=
res
}
}
}
}
return
nil
,
nil
return
nil
,
nil
...
...
core/vm/jump_table.go
View file @
0b978f91
...
@@ -53,6 +53,8 @@ type operation struct {
...
@@ -53,6 +53,8 @@ type operation struct {
valid
bool
valid
bool
// reverts determined whether the operation reverts state
// reverts determined whether the operation reverts state
reverts
bool
reverts
bool
// returns determines whether the opertions sets the return data
returns
bool
}
}
var
(
var
(
...
@@ -72,6 +74,20 @@ func NewMetropolisInstructionSet() [256]operation {
...
@@ -72,6 +74,20 @@ func NewMetropolisInstructionSet() [256]operation {
validateStack
:
makeStackFunc
(
6
,
1
),
validateStack
:
makeStackFunc
(
6
,
1
),
memorySize
:
memoryStaticCall
,
memorySize
:
memoryStaticCall
,
valid
:
true
,
valid
:
true
,
returns
:
true
,
}
instructionSet
[
RETURNDATASIZE
]
=
operation
{
execute
:
opReturnDataSize
,
gasCost
:
constGasFunc
(
GasQuickStep
),
validateStack
:
makeStackFunc
(
0
,
1
),
valid
:
true
,
}
instructionSet
[
RETURNDATACOPY
]
=
operation
{
execute
:
opReturnDataCopy
,
gasCost
:
gasReturnDataCopy
,
validateStack
:
makeStackFunc
(
3
,
0
),
memorySize
:
memoryReturnDataCopy
,
valid
:
true
,
}
}
return
instructionSet
return
instructionSet
}
}
...
@@ -86,6 +102,7 @@ func NewHomesteadInstructionSet() [256]operation {
...
@@ -86,6 +102,7 @@ func NewHomesteadInstructionSet() [256]operation {
validateStack
:
makeStackFunc
(
6
,
1
),
validateStack
:
makeStackFunc
(
6
,
1
),
memorySize
:
memoryDelegateCall
,
memorySize
:
memoryDelegateCall
,
valid
:
true
,
valid
:
true
,
returns
:
true
,
}
}
return
instructionSet
return
instructionSet
}
}
...
@@ -271,22 +288,22 @@ func NewFrontierInstructionSet() [256]operation {
...
@@ -271,22 +288,22 @@ func NewFrontierInstructionSet() [256]operation {
valid
:
true
,
valid
:
true
,
},
},
CALLDATALOAD
:
{
CALLDATALOAD
:
{
execute
:
opCall
d
ataLoad
,
execute
:
opCall
D
ataLoad
,
gasCost
:
constGasFunc
(
GasFastestStep
),
gasCost
:
constGasFunc
(
GasFastestStep
),
validateStack
:
makeStackFunc
(
1
,
1
),
validateStack
:
makeStackFunc
(
1
,
1
),
valid
:
true
,
valid
:
true
,
},
},
CALLDATASIZE
:
{
CALLDATASIZE
:
{
execute
:
opCall
d
ataSize
,
execute
:
opCall
D
ataSize
,
gasCost
:
constGasFunc
(
GasQuickStep
),
gasCost
:
constGasFunc
(
GasQuickStep
),
validateStack
:
makeStackFunc
(
0
,
1
),
validateStack
:
makeStackFunc
(
0
,
1
),
valid
:
true
,
valid
:
true
,
},
},
CALLDATACOPY
:
{
CALLDATACOPY
:
{
execute
:
opCall
d
ataCopy
,
execute
:
opCall
D
ataCopy
,
gasCost
:
gasCall
d
ataCopy
,
gasCost
:
gasCall
D
ataCopy
,
validateStack
:
makeStackFunc
(
3
,
0
),
validateStack
:
makeStackFunc
(
3
,
0
),
memorySize
:
memoryCall
d
ataCopy
,
memorySize
:
memoryCall
D
ataCopy
,
valid
:
true
,
valid
:
true
,
},
},
CODESIZE
:
{
CODESIZE
:
{
...
@@ -867,6 +884,7 @@ func NewFrontierInstructionSet() [256]operation {
...
@@ -867,6 +884,7 @@ func NewFrontierInstructionSet() [256]operation {
memorySize
:
memoryCreate
,
memorySize
:
memoryCreate
,
valid
:
true
,
valid
:
true
,
writes
:
true
,
writes
:
true
,
returns
:
true
,
},
},
CALL
:
{
CALL
:
{
execute
:
opCall
,
execute
:
opCall
,
...
@@ -874,6 +892,7 @@ func NewFrontierInstructionSet() [256]operation {
...
@@ -874,6 +892,7 @@ func NewFrontierInstructionSet() [256]operation {
validateStack
:
makeStackFunc
(
7
,
1
),
validateStack
:
makeStackFunc
(
7
,
1
),
memorySize
:
memoryCall
,
memorySize
:
memoryCall
,
valid
:
true
,
valid
:
true
,
returns
:
true
,
},
},
CALLCODE
:
{
CALLCODE
:
{
execute
:
opCallCode
,
execute
:
opCallCode
,
...
@@ -881,6 +900,7 @@ func NewFrontierInstructionSet() [256]operation {
...
@@ -881,6 +900,7 @@ func NewFrontierInstructionSet() [256]operation {
validateStack
:
makeStackFunc
(
7
,
1
),
validateStack
:
makeStackFunc
(
7
,
1
),
memorySize
:
memoryCall
,
memorySize
:
memoryCall
,
valid
:
true
,
valid
:
true
,
returns
:
true
,
},
},
RETURN
:
{
RETURN
:
{
execute
:
opReturn
,
execute
:
opReturn
,
...
...
core/vm/memory.go
View file @
0b978f91
...
@@ -22,7 +22,6 @@ import "fmt"
...
@@ -22,7 +22,6 @@ import "fmt"
type
Memory
struct
{
type
Memory
struct
{
store
[]
byte
store
[]
byte
lastGasCost
uint64
lastGasCost
uint64
lastReturn
[]
byte
}
}
func
NewMemory
()
*
Memory
{
func
NewMemory
()
*
Memory
{
...
...
core/vm/memory_table.go
View file @
0b978f91
...
@@ -26,7 +26,11 @@ func memorySha3(stack *Stack) *big.Int {
...
@@ -26,7 +26,11 @@ func memorySha3(stack *Stack) *big.Int {
return
calcMemSize
(
stack
.
Back
(
0
),
stack
.
Back
(
1
))
return
calcMemSize
(
stack
.
Back
(
0
),
stack
.
Back
(
1
))
}
}
func
memoryCalldataCopy
(
stack
*
Stack
)
*
big
.
Int
{
func
memoryCallDataCopy
(
stack
*
Stack
)
*
big
.
Int
{
return
calcMemSize
(
stack
.
Back
(
0
),
stack
.
Back
(
2
))
}
func
memoryReturnDataCopy
(
stack
*
Stack
)
*
big
.
Int
{
return
calcMemSize
(
stack
.
Back
(
0
),
stack
.
Back
(
2
))
return
calcMemSize
(
stack
.
Back
(
0
),
stack
.
Back
(
2
))
}
}
...
...
core/vm/opcodes.go
View file @
0b978f91
...
@@ -82,10 +82,11 @@ const (
...
@@ -82,10 +82,11 @@ const (
GASPRICE
GASPRICE
EXTCODESIZE
EXTCODESIZE
EXTCODECOPY
EXTCODECOPY
RETURNDATASIZE
RETURNDATACOPY
)
)
const
(
const
(
// 0x40 range - block operations
// 0x40 range - block operations
BLOCKHASH
OpCode
=
0x40
+
iota
BLOCKHASH
OpCode
=
0x40
+
iota
COINBASE
COINBASE
...
@@ -239,27 +240,29 @@ var opCodeToString = map[OpCode]string{
...
@@ -239,27 +240,29 @@ var opCodeToString = map[OpCode]string{
SHA3
:
"SHA3"
,
SHA3
:
"SHA3"
,
// 0x30 range - closure state
// 0x30 range - closure state
ADDRESS
:
"ADDRESS"
,
ADDRESS
:
"ADDRESS"
,
BALANCE
:
"BALANCE"
,
BALANCE
:
"BALANCE"
,
ORIGIN
:
"ORIGIN"
,
ORIGIN
:
"ORIGIN"
,
CALLER
:
"CALLER"
,
CALLER
:
"CALLER"
,
CALLVALUE
:
"CALLVALUE"
,
CALLVALUE
:
"CALLVALUE"
,
CALLDATALOAD
:
"CALLDATALOAD"
,
CALLDATALOAD
:
"CALLDATALOAD"
,
CALLDATASIZE
:
"CALLDATASIZE"
,
CALLDATASIZE
:
"CALLDATASIZE"
,
CALLDATACOPY
:
"CALLDATACOPY"
,
CALLDATACOPY
:
"CALLDATACOPY"
,
CODESIZE
:
"CODESIZE"
,
CODESIZE
:
"CODESIZE"
,
CODECOPY
:
"CODECOPY"
,
CODECOPY
:
"CODECOPY"
,
GASPRICE
:
"GASPRICE"
,
GASPRICE
:
"GASPRICE"
,
EXTCODESIZE
:
"EXTCODESIZE"
,
EXTCODECOPY
:
"EXTCODECOPY"
,
RETURNDATASIZE
:
"RETURNDATASIZE"
,
RETURNDATACOPY
:
"RETURNDATACOPY"
,
// 0x40 range - block operations
// 0x40 range - block operations
BLOCKHASH
:
"BLOCKHASH"
,
BLOCKHASH
:
"BLOCKHASH"
,
COINBASE
:
"COINBASE"
,
COINBASE
:
"COINBASE"
,
TIMESTAMP
:
"TIMESTAMP"
,
TIMESTAMP
:
"TIMESTAMP"
,
NUMBER
:
"NUMBER"
,
NUMBER
:
"NUMBER"
,
DIFFICULTY
:
"DIFFICULTY"
,
DIFFICULTY
:
"DIFFICULTY"
,
GASLIMIT
:
"GASLIMIT"
,
GASLIMIT
:
"GASLIMIT"
,
EXTCODESIZE
:
"EXTCODESIZE"
,
EXTCODECOPY
:
"EXTCODECOPY"
,
// 0x50 range - 'storage' and execution
// 0x50 range - 'storage' and execution
POP
:
"POP"
,
POP
:
"POP"
,
...
@@ -374,137 +377,139 @@ func (o OpCode) String() string {
...
@@ -374,137 +377,139 @@ func (o OpCode) String() string {
}
}
var
stringToOp
=
map
[
string
]
OpCode
{
var
stringToOp
=
map
[
string
]
OpCode
{
"STOP"
:
STOP
,
"STOP"
:
STOP
,
"ADD"
:
ADD
,
"ADD"
:
ADD
,
"MUL"
:
MUL
,
"MUL"
:
MUL
,
"SUB"
:
SUB
,
"SUB"
:
SUB
,
"DIV"
:
DIV
,
"DIV"
:
DIV
,
"SDIV"
:
SDIV
,
"SDIV"
:
SDIV
,
"MOD"
:
MOD
,
"MOD"
:
MOD
,
"SMOD"
:
SMOD
,
"SMOD"
:
SMOD
,
"EXP"
:
EXP
,
"EXP"
:
EXP
,
"NOT"
:
NOT
,
"NOT"
:
NOT
,
"LT"
:
LT
,
"LT"
:
LT
,
"GT"
:
GT
,
"GT"
:
GT
,
"SLT"
:
SLT
,
"SLT"
:
SLT
,
"SGT"
:
SGT
,
"SGT"
:
SGT
,
"EQ"
:
EQ
,
"EQ"
:
EQ
,
"ISZERO"
:
ISZERO
,
"ISZERO"
:
ISZERO
,
"SIGNEXTEND"
:
SIGNEXTEND
,
"SIGNEXTEND"
:
SIGNEXTEND
,
"AND"
:
AND
,
"AND"
:
AND
,
"OR"
:
OR
,
"OR"
:
OR
,
"XOR"
:
XOR
,
"XOR"
:
XOR
,
"BYTE"
:
BYTE
,
"BYTE"
:
BYTE
,
"ADDMOD"
:
ADDMOD
,
"ADDMOD"
:
ADDMOD
,
"MULMOD"
:
MULMOD
,
"MULMOD"
:
MULMOD
,
"SHA3"
:
SHA3
,
"SHA3"
:
SHA3
,
"ADDRESS"
:
ADDRESS
,
"ADDRESS"
:
ADDRESS
,
"BALANCE"
:
BALANCE
,
"BALANCE"
:
BALANCE
,
"ORIGIN"
:
ORIGIN
,
"ORIGIN"
:
ORIGIN
,
"CALLER"
:
CALLER
,
"CALLER"
:
CALLER
,
"CALLVALUE"
:
CALLVALUE
,
"CALLVALUE"
:
CALLVALUE
,
"CALLDATALOAD"
:
CALLDATALOAD
,
"CALLDATALOAD"
:
CALLDATALOAD
,
"CALLDATASIZE"
:
CALLDATASIZE
,
"CALLDATASIZE"
:
CALLDATASIZE
,
"CALLDATACOPY"
:
CALLDATACOPY
,
"CALLDATACOPY"
:
CALLDATACOPY
,
"DELEGATECALL"
:
DELEGATECALL
,
"DELEGATECALL"
:
DELEGATECALL
,
"STATICCALL"
:
STATICCALL
,
"STATICCALL"
:
STATICCALL
,
"CODESIZE"
:
CODESIZE
,
"CODESIZE"
:
CODESIZE
,
"CODECOPY"
:
CODECOPY
,
"CODECOPY"
:
CODECOPY
,
"GASPRICE"
:
GASPRICE
,
"GASPRICE"
:
GASPRICE
,
"BLOCKHASH"
:
BLOCKHASH
,
"EXTCODESIZE"
:
EXTCODESIZE
,
"COINBASE"
:
COINBASE
,
"EXTCODECOPY"
:
EXTCODECOPY
,
"TIMESTAMP"
:
TIMESTAMP
,
"RETURNDATASIZE"
:
RETURNDATASIZE
,
"NUMBER"
:
NUMBER
,
"RETURNDATACOPY"
:
RETURNDATACOPY
,
"DIFFICULTY"
:
DIFFICULTY
,
"BLOCKHASH"
:
BLOCKHASH
,
"GASLIMIT"
:
GASLIMIT
,
"COINBASE"
:
COINBASE
,
"EXTCODESIZE"
:
EXTCODESIZE
,
"TIMESTAMP"
:
TIMESTAMP
,
"EXTCODECOPY"
:
EXTCODECOPY
,
"NUMBER"
:
NUMBER
,
"POP"
:
POP
,
"DIFFICULTY"
:
DIFFICULTY
,
"MLOAD"
:
MLOAD
,
"GASLIMIT"
:
GASLIMIT
,
"MSTORE"
:
MSTORE
,
"POP"
:
POP
,
"MSTORE8"
:
MSTORE8
,
"MLOAD"
:
MLOAD
,
"SLOAD"
:
SLOAD
,
"MSTORE"
:
MSTORE
,
"SSTORE"
:
SSTORE
,
"MSTORE8"
:
MSTORE8
,
"JUMP"
:
JUMP
,
"SLOAD"
:
SLOAD
,
"JUMPI"
:
JUMPI
,
"SSTORE"
:
SSTORE
,
"PC"
:
PC
,
"JUMP"
:
JUMP
,
"MSIZE"
:
MSIZE
,
"JUMPI"
:
JUMPI
,
"GAS"
:
GAS
,
"PC"
:
PC
,
"JUMPDEST"
:
JUMPDEST
,
"MSIZE"
:
MSIZE
,
"PUSH1"
:
PUSH1
,
"GAS"
:
GAS
,
"PUSH2"
:
PUSH2
,
"JUMPDEST"
:
JUMPDEST
,
"PUSH3"
:
PUSH3
,
"PUSH1"
:
PUSH1
,
"PUSH4"
:
PUSH4
,
"PUSH2"
:
PUSH2
,
"PUSH5"
:
PUSH5
,
"PUSH3"
:
PUSH3
,
"PUSH6"
:
PUSH6
,
"PUSH4"
:
PUSH4
,
"PUSH7"
:
PUSH7
,
"PUSH5"
:
PUSH5
,
"PUSH8"
:
PUSH8
,
"PUSH6"
:
PUSH6
,
"PUSH9"
:
PUSH9
,
"PUSH7"
:
PUSH7
,
"PUSH10"
:
PUSH10
,
"PUSH8"
:
PUSH8
,
"PUSH11"
:
PUSH11
,
"PUSH9"
:
PUSH9
,
"PUSH12"
:
PUSH12
,
"PUSH10"
:
PUSH10
,
"PUSH13"
:
PUSH13
,
"PUSH11"
:
PUSH11
,
"PUSH14"
:
PUSH14
,
"PUSH12"
:
PUSH12
,
"PUSH15"
:
PUSH15
,
"PUSH13"
:
PUSH13
,
"PUSH16"
:
PUSH16
,
"PUSH14"
:
PUSH14
,
"PUSH17"
:
PUSH17
,
"PUSH15"
:
PUSH15
,
"PUSH18"
:
PUSH18
,
"PUSH16"
:
PUSH16
,
"PUSH19"
:
PUSH19
,
"PUSH17"
:
PUSH17
,
"PUSH20"
:
PUSH20
,
"PUSH18"
:
PUSH18
,
"PUSH21"
:
PUSH21
,
"PUSH19"
:
PUSH19
,
"PUSH22"
:
PUSH22
,
"PUSH20"
:
PUSH20
,
"PUSH23"
:
PUSH23
,
"PUSH21"
:
PUSH21
,
"PUSH24"
:
PUSH24
,
"PUSH22"
:
PUSH22
,
"PUSH25"
:
PUSH25
,
"PUSH23"
:
PUSH23
,
"PUSH26"
:
PUSH26
,
"PUSH24"
:
PUSH24
,
"PUSH27"
:
PUSH27
,
"PUSH25"
:
PUSH25
,
"PUSH28"
:
PUSH28
,
"PUSH26"
:
PUSH26
,
"PUSH29"
:
PUSH29
,
"PUSH27"
:
PUSH27
,
"PUSH30"
:
PUSH30
,
"PUSH28"
:
PUSH28
,
"PUSH31"
:
PUSH31
,
"PUSH29"
:
PUSH29
,
"PUSH32"
:
PUSH32
,
"PUSH30"
:
PUSH30
,
"DUP1"
:
DUP1
,
"PUSH31"
:
PUSH31
,
"DUP2"
:
DUP2
,
"PUSH32"
:
PUSH32
,
"DUP3"
:
DUP3
,
"DUP1"
:
DUP1
,
"DUP4"
:
DUP4
,
"DUP2"
:
DUP2
,
"DUP5"
:
DUP5
,
"DUP3"
:
DUP3
,
"DUP6"
:
DUP6
,
"DUP4"
:
DUP4
,
"DUP7"
:
DUP7
,
"DUP5"
:
DUP5
,
"DUP8"
:
DUP8
,
"DUP6"
:
DUP6
,
"DUP9"
:
DUP9
,
"DUP7"
:
DUP7
,
"DUP10"
:
DUP10
,
"DUP8"
:
DUP8
,
"DUP11"
:
DUP11
,
"DUP9"
:
DUP9
,
"DUP12"
:
DUP12
,
"DUP10"
:
DUP10
,
"DUP13"
:
DUP13
,
"DUP11"
:
DUP11
,
"DUP14"
:
DUP14
,
"DUP12"
:
DUP12
,
"DUP15"
:
DUP15
,
"DUP13"
:
DUP13
,
"DUP16"
:
DUP16
,
"DUP14"
:
DUP14
,
"SWAP1"
:
SWAP1
,
"DUP15"
:
DUP15
,
"SWAP2"
:
SWAP2
,
"DUP16"
:
DUP16
,
"SWAP3"
:
SWAP3
,
"SWAP1"
:
SWAP1
,
"SWAP4"
:
SWAP4
,
"SWAP2"
:
SWAP2
,
"SWAP5"
:
SWAP5
,
"SWAP3"
:
SWAP3
,
"SWAP6"
:
SWAP6
,
"SWAP4"
:
SWAP4
,
"SWAP7"
:
SWAP7
,
"SWAP5"
:
SWAP5
,
"SWAP8"
:
SWAP8
,
"SWAP6"
:
SWAP6
,
"SWAP9"
:
SWAP9
,
"SWAP7"
:
SWAP7
,
"SWAP10"
:
SWAP10
,
"SWAP8"
:
SWAP8
,
"SWAP11"
:
SWAP11
,
"SWAP9"
:
SWAP9
,
"SWAP12"
:
SWAP12
,
"SWAP10"
:
SWAP10
,
"SWAP13"
:
SWAP13
,
"SWAP11"
:
SWAP11
,
"SWAP14"
:
SWAP14
,
"SWAP12"
:
SWAP12
,
"SWAP15"
:
SWAP15
,
"SWAP13"
:
SWAP13
,
"SWAP16"
:
SWAP16
,
"SWAP14"
:
SWAP14
,
"LOG0"
:
LOG0
,
"SWAP15"
:
SWAP15
,
"LOG1"
:
LOG1
,
"SWAP16"
:
SWAP16
,
"LOG2"
:
LOG2
,
"LOG0"
:
LOG0
,
"LOG3"
:
LOG3
,
"LOG1"
:
LOG1
,
"LOG4"
:
LOG4
,
"LOG2"
:
LOG2
,
"CREATE"
:
CREATE
,
"LOG3"
:
LOG3
,
"CALL"
:
CALL
,
"LOG4"
:
LOG4
,
"RETURN"
:
RETURN
,
"CREATE"
:
CREATE
,
"CALLCODE"
:
CALLCODE
,
"CALL"
:
CALL
,
"SELFDESTRUCT"
:
SELFDESTRUCT
,
"RETURN"
:
RETURN
,
"CALLCODE"
:
CALLCODE
,
"SELFDESTRUCT"
:
SELFDESTRUCT
,
}
}
func
StringToOp
(
str
string
)
OpCode
{
func
StringToOp
(
str
string
)
OpCode
{
...
...
testdata
@
85f6d7cc
Subproject commit 8
15151e4cea4e73328f8586b4e61c3d7e1e9e543
Subproject commit 8
5f6d7cc01b6bd04e071f5ba579fc675cfd2043b
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment