mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
core/vm: apply suggestions, make ReturnStack an object
This commit is contained in:
parent
6549a87202
commit
ddb9907a7a
2 changed files with 29 additions and 23 deletions
|
|
@ -790,19 +790,19 @@ func opRjumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
|
||||||
func opRjumpv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
func opRjumpv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
code = scope.Contract.CodeAt(scope.CodeSection)
|
code = scope.Contract.CodeAt(scope.CodeSection)
|
||||||
count = uint64(code[*pc+1]) + 1
|
maxIndex = uint64(code[*pc+1]) + 1
|
||||||
idx = scope.Stack.pop()
|
idx = scope.Stack.pop()
|
||||||
)
|
)
|
||||||
if idx, overflow := idx.Uint64WithOverflow(); overflow || idx >= count {
|
if idx, overflow := idx.Uint64WithOverflow(); overflow || idx >= maxIndex {
|
||||||
// Index out-of-bounds, don't branch, just skip over immediate
|
// Index out-of-bounds, don't branch, just skip over immediate
|
||||||
// argument.
|
// argument.
|
||||||
*pc += 1 + count*2
|
*pc += 1 + maxIndex*2
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
offset := parseInt16(code[*pc+2+2*idx.Uint64():])
|
offset := parseInt16(code[*pc+2+2*idx.Uint64():])
|
||||||
// move pc past op and count byte (2), move past count number of 16bit offsets (count*2), add relative offset, subtract 1 to
|
// move pc past op and count byte (2), move past count number of 16bit offsets (count*2), add relative offset, subtract 1 to
|
||||||
// account for interpreter loop.
|
// account for interpreter loop.
|
||||||
*pc = uint64(int64(*pc+2+count*2) + int64(offset) - 1)
|
*pc = uint64(int64(*pc+2+maxIndex*2) + int64(offset) - 1)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -816,7 +816,7 @@ func opCallf(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
|
||||||
if scope.Stack.len()+int(typ.MaxStackHeight)-int(typ.Input) > 1024 {
|
if scope.Stack.len()+int(typ.MaxStackHeight)-int(typ.Input) > 1024 {
|
||||||
return nil, fmt.Errorf("stack overflow")
|
return nil, fmt.Errorf("stack overflow")
|
||||||
}
|
}
|
||||||
if len(scope.ReturnStack) > 1024 {
|
if scope.ReturnStack.Len() > 1024 {
|
||||||
return nil, fmt.Errorf("return stack overflow")
|
return nil, fmt.Errorf("return stack overflow")
|
||||||
}
|
}
|
||||||
retCtx := &ReturnContext{
|
retCtx := &ReturnContext{
|
||||||
|
|
@ -826,23 +826,18 @@ func opCallf(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
|
||||||
}
|
}
|
||||||
scope.ReturnStack = append(scope.ReturnStack, retCtx)
|
scope.ReturnStack = append(scope.ReturnStack, retCtx)
|
||||||
scope.CodeSection = uint64(idx)
|
scope.CodeSection = uint64(idx)
|
||||||
*pc = 0
|
*pc = uint64(math.MaxUint64)
|
||||||
*pc -= 1 // hacks xD (interpreter loop)
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// opRetf implements the RETF opcode
|
// opRetf implements the RETF opcode
|
||||||
func opRetf(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
func opRetf(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||||
var (
|
retCtx := scope.ReturnStack.Pop()
|
||||||
last = len(scope.ReturnStack) - 1
|
|
||||||
retCtx = scope.ReturnStack[last]
|
|
||||||
)
|
|
||||||
scope.ReturnStack = scope.ReturnStack[:last]
|
|
||||||
scope.CodeSection = retCtx.Section
|
scope.CodeSection = retCtx.Section
|
||||||
*pc = retCtx.Pc - 1
|
*pc = retCtx.Pc - 1
|
||||||
|
|
||||||
// If returning from top frame, exit cleanly.
|
// If returning from top frame, exit cleanly.
|
||||||
if len(scope.ReturnStack) == 0 {
|
if scope.ReturnStack.Len() == 0 {
|
||||||
return nil, errStopToken
|
return nil, errStopToken
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -858,8 +853,7 @@ func opJumpf(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
|
||||||
return nil, fmt.Errorf("stack overflow")
|
return nil, fmt.Errorf("stack overflow")
|
||||||
}
|
}
|
||||||
scope.CodeSection = uint64(idx)
|
scope.CodeSection = uint64(idx)
|
||||||
*pc = 0
|
*pc = uint64(math.MaxUint64)
|
||||||
*pc -= 1 // hacks xD (interpreter loop)
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -947,11 +941,7 @@ func opReturnContract(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte
|
||||||
}
|
}
|
||||||
c.DataSize = len(c.Data)
|
c.DataSize = len(c.Data)
|
||||||
// Restore context
|
// Restore context
|
||||||
var (
|
retCtx := scope.ReturnStack.Pop()
|
||||||
last = len(scope.ReturnStack) - 1
|
|
||||||
retCtx = scope.ReturnStack[last]
|
|
||||||
)
|
|
||||||
scope.ReturnStack = scope.ReturnStack[:last]
|
|
||||||
scope.CodeSection = retCtx.Section
|
scope.CodeSection = retCtx.Section
|
||||||
*pc = retCtx.Pc - 1 // account for interpreter loop
|
*pc = retCtx.Pc - 1 // account for interpreter loop
|
||||||
return c.MarshalBinary(), errStopToken
|
return c.MarshalBinary(), errStopToken
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,26 @@ type ScopeContext struct {
|
||||||
Contract *Contract
|
Contract *Contract
|
||||||
|
|
||||||
CodeSection uint64
|
CodeSection uint64
|
||||||
ReturnStack []*ReturnContext
|
ReturnStack ReturnStack
|
||||||
InitCodeMode bool
|
InitCodeMode bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReturnStack []*ReturnContext
|
||||||
|
|
||||||
|
// Pop removes an element from the return stack
|
||||||
|
// Panics if the return stack is empty, which should
|
||||||
|
// never happen, since EOF code is verified for that.
|
||||||
|
func (ctx *ReturnStack) Pop() *ReturnContext {
|
||||||
|
item := (*ctx)[ctx.Len()-1]
|
||||||
|
*ctx = (*ctx)[:ctx.Len()-1]
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of the return stack
|
||||||
|
func (ctx *ReturnStack) Len() int {
|
||||||
|
return len(*ctx)
|
||||||
|
}
|
||||||
|
|
||||||
type ReturnContext struct {
|
type ReturnContext struct {
|
||||||
Section uint64
|
Section uint64
|
||||||
Pc uint64
|
Pc uint64
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue