mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Change interpreter memory to be non-contiguous.
This commit is contained in:
@@ -63,13 +63,11 @@ u256 readZeroExtended(bytes const& _data, u256 const& _offset)
|
||||
/// Copy @a _size bytes of @a _source at offset @a _sourceOffset to
|
||||
/// @a _target at offset @a _targetOffset. Behaves as if @a _source would
|
||||
/// continue with an infinite sequence of zero bytes beyond its end.
|
||||
/// Asserts the target is large enough to hold the copied segment.
|
||||
void copyZeroExtended(
|
||||
bytes& _target, bytes const& _source,
|
||||
map<u256, uint8_t>& _target, bytes const& _source,
|
||||
size_t _targetOffset, size_t _sourceOffset, size_t _size
|
||||
)
|
||||
{
|
||||
yulAssert(_targetOffset + _size <= _target.size(), "");
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
_target[_targetOffset + i] = _sourceOffset + i < _source.size() ? _source[_sourceOffset + i] : 0;
|
||||
}
|
||||
@@ -176,7 +174,7 @@ u256 EVMInstructionInterpreter::eval(
|
||||
return u256("0x1234cafe1234cafe1234cafe") + arg[0];
|
||||
uint64_t offset = uint64_t(arg[0] & uint64_t(-1));
|
||||
uint64_t size = uint64_t(arg[1] & uint64_t(-1));
|
||||
return u256(keccak256(bytesConstRef(m_state.memory.data() + offset, size)));
|
||||
return u256(keccak256(readMemory(offset, size)));
|
||||
}
|
||||
case Instruction::ADDRESS:
|
||||
return m_state.address;
|
||||
@@ -251,16 +249,16 @@ u256 EVMInstructionInterpreter::eval(
|
||||
// --------------- memory / storage / logs ---------------
|
||||
case Instruction::MLOAD:
|
||||
if (accessMemory(arg[0], 0x20))
|
||||
return u256(*reinterpret_cast<h256 const*>(m_state.memory.data() + size_t(arg[0])));
|
||||
return readMemoryWord(arg[0]);
|
||||
else
|
||||
return 0x1234 + arg[0];
|
||||
case Instruction::MSTORE:
|
||||
if (accessMemory(arg[0], 0x20))
|
||||
*reinterpret_cast<h256*>(m_state.memory.data() + size_t(arg[0])) = h256(arg[1]);
|
||||
writeMemoryWord(arg[0], arg[1]);
|
||||
return 0;
|
||||
case Instruction::MSTORE8:
|
||||
if (accessMemory(arg[0], 1))
|
||||
m_state.memory[size_t(arg[0])] = uint8_t(arg[1] & 0xff);
|
||||
m_state.memory[arg[0]] = uint8_t(arg[1] & 0xff);
|
||||
return 0;
|
||||
case Instruction::SLOAD:
|
||||
return m_state.storage[h256(arg[0])];
|
||||
@@ -319,7 +317,7 @@ u256 EVMInstructionInterpreter::eval(
|
||||
{
|
||||
bytes data;
|
||||
if (accessMemory(arg[0], arg[1]))
|
||||
data = bytesConstRef(m_state.memory.data() + size_t(arg[0]), size_t(arg[1])).toBytes();
|
||||
data = readMemory(arg[0], arg[1]);
|
||||
logTrace(_instruction, arg, data);
|
||||
throw ExplicitlyTerminated();
|
||||
}
|
||||
@@ -455,12 +453,7 @@ bool EVMInstructionInterpreter::accessMemory(u256 const& _offset, u256 const& _s
|
||||
{
|
||||
u256 newSize = (_offset + _size + 0x1f) & ~u256(0x1f);
|
||||
m_state.msize = max(m_state.msize, newSize);
|
||||
if (newSize < m_state.maxMemSize)
|
||||
{
|
||||
if (m_state.memory.size() < newSize)
|
||||
m_state.memory.resize(size_t(newSize));
|
||||
return true;
|
||||
}
|
||||
return _size <= 0xffff;
|
||||
}
|
||||
else
|
||||
m_state.msize = u256(-1);
|
||||
@@ -468,6 +461,27 @@ bool EVMInstructionInterpreter::accessMemory(u256 const& _offset, u256 const& _s
|
||||
return false;
|
||||
}
|
||||
|
||||
bytes EVMInstructionInterpreter::readMemory(u256 const& _offset, u256 const& _size)
|
||||
{
|
||||
yulAssert(_size <= 0xffff, "Too large read.");
|
||||
bytes data(size_t(_size), uint8_t(0));
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
data[i] = m_state.memory[_offset + i];
|
||||
return data;
|
||||
}
|
||||
|
||||
u256 EVMInstructionInterpreter::readMemoryWord(u256 const& _offset)
|
||||
{
|
||||
return u256(h256(readMemory(_offset, 32)));
|
||||
}
|
||||
|
||||
void EVMInstructionInterpreter::writeMemoryWord(u256 const& _offset, u256 const& _value)
|
||||
{
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
m_state.memory[_offset + i] = uint8_t((_value >> (8 * (31 - i))) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
void EVMInstructionInterpreter::logTrace(dev::eth::Instruction _instruction, std::vector<u256> const& _arguments, bytes const& _data)
|
||||
{
|
||||
logTrace(dev::eth::instructionInfo(_instruction).name, _arguments, _data);
|
||||
|
||||
Reference in New Issue
Block a user