mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[ewasm] Overhaul memory handling in EwasmInterpreter
Introduce writeMemory and read/writeBytes32/Address helpers. Fix read/writeU128/U256 to be little-endian. Update each instruction to follow the specification.
This commit is contained in:
@@ -35,6 +35,7 @@ using namespace solidity;
|
||||
using namespace solidity::yul;
|
||||
using namespace solidity::yul::test;
|
||||
|
||||
using solidity::util::h160;
|
||||
using solidity::util::h256;
|
||||
|
||||
namespace
|
||||
@@ -309,7 +310,7 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
writeU256(arg[1], 0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256));
|
||||
writeBytes32(arg[1], h256(0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -356,17 +357,16 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
}
|
||||
else if (_fun == "storageStore")
|
||||
{
|
||||
m_state.storage[h256(readU256(arg[0]))] = readU256((arg[1]));
|
||||
m_state.storage[readBytes32(arg[0])] = readBytes32(arg[1]);
|
||||
return 0;
|
||||
}
|
||||
else if (_fun == "storageLoad")
|
||||
{
|
||||
writeU256(arg[1], m_state.storage[h256(readU256(arg[0]))]);
|
||||
writeBytes32(arg[1], m_state.storage[readBytes32(arg[0])]);
|
||||
return 0;
|
||||
}
|
||||
else if (_fun == "getCaller")
|
||||
{
|
||||
// TODO should this only write 20 bytes?
|
||||
writeAddress(arg[0], m_state.caller);
|
||||
return 0;
|
||||
}
|
||||
@@ -415,8 +415,8 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
|
||||
return 0;
|
||||
}
|
||||
else if (_fun == "getExternalCodeSize")
|
||||
// Generate "random" code length. Make sure it fits the page size.
|
||||
return u256(keccak256(h256(readAddress(arg[0])))) & 0xfff;
|
||||
// Generate "random" code length.
|
||||
return uint32_t(u256(keccak256(h256(readAddress(arg[0])))) & 0xfff);
|
||||
else if (_fun == "getGasLeft")
|
||||
return 0x99;
|
||||
else if (_fun == "getBlockGasLimit")
|
||||
@@ -523,6 +523,12 @@ uint32_t EwasmBuiltinInterpreter::readMemoryHalfWord(uint64_t _offset)
|
||||
return r;
|
||||
}
|
||||
|
||||
void EwasmBuiltinInterpreter::writeMemory(uint64_t _offset, bytes const& _value)
|
||||
{
|
||||
for (size_t i = 0; i < _value.size(); i++)
|
||||
m_state.memory[_offset + i] = _value[i];
|
||||
}
|
||||
|
||||
void EwasmBuiltinInterpreter::writeMemoryWord(uint64_t _offset, uint64_t _value)
|
||||
{
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
@@ -545,7 +551,7 @@ void EwasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _c
|
||||
accessMemory(_offset, _croppedTo);
|
||||
for (size_t i = 0; i < _croppedTo; i++)
|
||||
{
|
||||
m_state.memory[_offset + _croppedTo - 1 - i] = uint8_t(_value & 0xff);
|
||||
m_state.memory[_offset + i] = uint8_t(_value & 0xff);
|
||||
_value >>= 8;
|
||||
}
|
||||
}
|
||||
@@ -553,9 +559,9 @@ void EwasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _c
|
||||
u256 EwasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo)
|
||||
{
|
||||
accessMemory(_offset, _croppedTo);
|
||||
u256 value;
|
||||
u256 value{0};
|
||||
for (size_t i = 0; i < _croppedTo; i++)
|
||||
value = (value << 8) | m_state.memory[_offset + i];
|
||||
value = (value << 8) | m_state.memory[_offset + _croppedTo - 1 - i];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user