Godeps
_data
accounts
build
cmd
common
compression
core
state
types
vm
runtime
analysis.go
asm.go
common.go
contract.go
contracts.go
disasm.go
doc.go
environment.go
errors.go
gas.go
instructions.go
jit.go
jit_optimiser.go
jit_test.go
jit_util.go
jit_util_test.go
jump_table.go
log.go
logger.go
memory.go
opcodes.go
segments.go
stack.go
virtual_machine.go
vm.go
vm_jit.go
vm_jit_fake.go
.gitignore
asm.go
bad_block.go
bench_test.go
block_validator.go
block_validator_test.go
blockchain.go
blockchain_test.go
blocks.go
canary.go
chain_makers.go
chain_makers_test.go
chain_pow.go
chain_pow_test.go
database_util.go
database_util_test.go
default_genesis.go
error.go
events.go
execution.go
fees.go
filter_test.go
gaspool.go
genesis.go
helper_test.go
state_processor.go
state_transition.go
transaction_pool.go
transaction_pool_test.go
types.go
vm_env.go
crypto
docker
errs
eth
ethdb
event
generators
jsre
logger
metrics
miner
p2p
params
pow
rlp
rpc
tests
trie
whisper
xeth
.gitattributes
.gitignore
.gitmodules
.mailmap
.travis.yml
AUTHORS
CONTRIBUTING.md
COPYING
COPYING.LESSER
Makefile
README.md
VERSION
* Renamed ChainManager to BlockChain * Checkpointing is no longer required and never really properly worked when the state was corrupted.
104 lines
2.6 KiB
Go
104 lines
2.6 KiB
Go
// Copyright 2015 The go-ethereum Authors
|
|
// This file is part of the go-ethereum library.
|
|
//
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package vm
|
|
|
|
import "fmt"
|
|
|
|
// Memory implements a simple memory model for the ethereum virtual machine.
|
|
type Memory struct {
|
|
store []byte
|
|
}
|
|
|
|
func NewMemory() *Memory {
|
|
return &Memory{nil}
|
|
}
|
|
|
|
// Set sets offset + size to value
|
|
func (m *Memory) Set(offset, size uint64, value []byte) {
|
|
// length of store may never be less than offset + size.
|
|
// The store should be resized PRIOR to setting the memory
|
|
if size > uint64(len(m.store)) {
|
|
panic("INVALID memory: store empty")
|
|
}
|
|
|
|
// It's possible the offset is greater than 0 and size equals 0. This is because
|
|
// the calcMemSize (common.go) could potentially return 0 when size is zero (NO-OP)
|
|
if size > 0 {
|
|
copy(m.store[offset:offset+size], value)
|
|
}
|
|
}
|
|
|
|
// Resize resizes the memory to size
|
|
func (m *Memory) Resize(size uint64) {
|
|
if uint64(m.Len()) < size {
|
|
m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)
|
|
}
|
|
}
|
|
|
|
// Get returns offset + size as a new slice
|
|
func (self *Memory) Get(offset, size int64) (cpy []byte) {
|
|
if size == 0 {
|
|
return nil
|
|
}
|
|
|
|
if len(self.store) > int(offset) {
|
|
cpy = make([]byte, size)
|
|
copy(cpy, self.store[offset:offset+size])
|
|
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// GetPtr returns the offset + size
|
|
func (self *Memory) GetPtr(offset, size int64) []byte {
|
|
if size == 0 {
|
|
return nil
|
|
}
|
|
|
|
if len(self.store) > int(offset) {
|
|
return self.store[offset : offset+size]
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Len returns the length of the backing slice
|
|
func (m *Memory) Len() int {
|
|
return len(m.store)
|
|
}
|
|
|
|
// Data returns the backing slice
|
|
func (m *Memory) Data() []byte {
|
|
return m.store
|
|
}
|
|
|
|
func (m *Memory) Print() {
|
|
fmt.Printf("### mem %d bytes ###\n", len(m.store))
|
|
if len(m.store) > 0 {
|
|
addr := 0
|
|
for i := 0; i+32 <= len(m.store); i += 32 {
|
|
fmt.Printf("%03d: % x\n", addr, m.store[i:i+32])
|
|
addr++
|
|
}
|
|
} else {
|
|
fmt.Println("-- empty --")
|
|
}
|
|
fmt.Println("####################")
|
|
}
|