mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #8052 from ethereum/yul-interp
Fix implementation of getCodeSize in Ewasm
This commit is contained in:
commit
f9a76f8c9b
@ -401,8 +401,7 @@ function calldatacopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
|
|||||||
|
|
||||||
// Needed?
|
// Needed?
|
||||||
function codesize() -> z1, z2, z3, z4 {
|
function codesize() -> z1, z2, z3, z4 {
|
||||||
eth.getCodeSize(0)
|
z4 := eth.getCodeSize()
|
||||||
z1, z2, z3, z4 := mload_internal(0)
|
|
||||||
}
|
}
|
||||||
function codecopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
|
function codecopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
|
||||||
eth.codeCopy(
|
eth.codeCopy(
|
||||||
|
@ -120,7 +120,7 @@ void WasmDialect::addEthereumExternals()
|
|||||||
{"getCaller", {i32ptr}, {}},
|
{"getCaller", {i32ptr}, {}},
|
||||||
{"getCallValue", {i32ptr}, {}},
|
{"getCallValue", {i32ptr}, {}},
|
||||||
{"codeCopy", {i32ptr, i32, i32}, {}},
|
{"codeCopy", {i32ptr, i32, i32}, {}},
|
||||||
{"getCodeSize", {i32ptr}, {}},
|
{"getCodeSize", {}, {i32}},
|
||||||
{"getBlockCoinbase", {i32ptr}, {}},
|
{"getBlockCoinbase", {i32ptr}, {}},
|
||||||
{"create", {i32ptr, i32ptr, i32, i32ptr}, {i32}},
|
{"create", {i32ptr, i32ptr, i32, i32ptr}, {i32}},
|
||||||
{"getBlockDifficulty", {i32ptr}, {}},
|
{"getBlockDifficulty", {i32ptr}, {}},
|
||||||
|
@ -7,6 +7,5 @@
|
|||||||
// Trace:
|
// Trace:
|
||||||
// INVALID()
|
// INVALID()
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000014
|
|
||||||
// 40: 636f6465636f6465636f6465636f6465636f6465000000000000000000000000
|
// 40: 636f6465636f6465636f6465636f6465636f6465000000000000000000000000
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
|
@ -9,6 +9,5 @@
|
|||||||
// Trace:
|
// Trace:
|
||||||
// INVALID()
|
// INVALID()
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000014
|
|
||||||
// 80: 636f6465636f6465636f6465636f6465636f6465000000000000000000000000
|
// 80: 636f6465636f6465636f6465636f6465636f6465000000000000000000000000
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
|
@ -139,18 +139,27 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
return readMemoryWord(arg[0]);
|
return readMemoryWord(arg[0]);
|
||||||
}
|
}
|
||||||
else if (_fun == "eth.getAddress"_yulstring)
|
else if (_fun == "eth.getAddress"_yulstring)
|
||||||
return writeAddress(arg[0], m_state.address);
|
{
|
||||||
|
writeAddress(arg[0], m_state.address);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.getExternalBalance"_yulstring)
|
else if (_fun == "eth.getExternalBalance"_yulstring)
|
||||||
|
{
|
||||||
// TODO this does not read the address, but is consistent with
|
// TODO this does not read the address, but is consistent with
|
||||||
// EVM interpreter implementation.
|
// EVM interpreter implementation.
|
||||||
// If we take the address into account, this needs to use readAddress.
|
// If we take the address into account, this needs to use readAddress.
|
||||||
return writeU128(arg[0], m_state.balance);
|
writeU128(arg[0], m_state.balance);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.getBlockHash"_yulstring)
|
else if (_fun == "eth.getBlockHash"_yulstring)
|
||||||
{
|
{
|
||||||
if (arg[0] >= m_state.blockNumber || arg[0] + 256 < m_state.blockNumber)
|
if (arg[0] >= m_state.blockNumber || arg[0] + 256 < m_state.blockNumber)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return writeU256(arg[1], 0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256));
|
{
|
||||||
|
writeU256(arg[1], 0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (_fun == "eth.call"_yulstring)
|
else if (_fun == "eth.call"_yulstring)
|
||||||
{
|
{
|
||||||
@ -199,12 +208,21 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (_fun == "eth.storageLoad"_yulstring)
|
else if (_fun == "eth.storageLoad"_yulstring)
|
||||||
return writeU256(arg[1], m_state.storage[h256(readU256(arg[0]))]);
|
{
|
||||||
|
writeU256(arg[1], m_state.storage[h256(readU256(arg[0]))]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.getCaller"_yulstring)
|
else if (_fun == "eth.getCaller"_yulstring)
|
||||||
|
{
|
||||||
// TODO should this only write 20 bytes?
|
// TODO should this only write 20 bytes?
|
||||||
return writeAddress(arg[0], m_state.caller);
|
writeAddress(arg[0], m_state.caller);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.getCallValue"_yulstring)
|
else if (_fun == "eth.getCallValue"_yulstring)
|
||||||
return writeU128(arg[0], m_state.callvalue);
|
{
|
||||||
|
writeU128(arg[0], m_state.callvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.codeCopy"_yulstring)
|
else if (_fun == "eth.codeCopy"_yulstring)
|
||||||
{
|
{
|
||||||
if (accessMemory(arg[0], arg[2]))
|
if (accessMemory(arg[0], arg[2]))
|
||||||
@ -215,9 +233,12 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (_fun == "eth.getCodeSize"_yulstring)
|
else if (_fun == "eth.getCodeSize"_yulstring)
|
||||||
return writeU256(arg[0], m_state.code.size());
|
return m_state.code.size();
|
||||||
else if (_fun == "eth.getBlockCoinbase"_yulstring)
|
else if (_fun == "eth.getBlockCoinbase"_yulstring)
|
||||||
return writeAddress(arg[0], m_state.coinbase);
|
{
|
||||||
|
writeAddress(arg[0], m_state.coinbase);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.create"_yulstring)
|
else if (_fun == "eth.create"_yulstring)
|
||||||
{
|
{
|
||||||
// TODO access memory
|
// TODO access memory
|
||||||
@ -226,7 +247,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
return 0xcccccc + arg[1];
|
return 0xcccccc + arg[1];
|
||||||
}
|
}
|
||||||
else if (_fun == "eth.getBlockDifficulty"_yulstring)
|
else if (_fun == "eth.getBlockDifficulty"_yulstring)
|
||||||
return writeU256(arg[0], m_state.difficulty);
|
{
|
||||||
|
writeU256(arg[0], m_state.difficulty);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.externalCodeCopy"_yulstring)
|
else if (_fun == "eth.externalCodeCopy"_yulstring)
|
||||||
{
|
{
|
||||||
// TODO use readAddress to read address.
|
// TODO use readAddress to read address.
|
||||||
@ -245,7 +269,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
else if (_fun == "eth.getBlockGasLimit"_yulstring)
|
else if (_fun == "eth.getBlockGasLimit"_yulstring)
|
||||||
return uint64_t(m_state.gaslimit);
|
return uint64_t(m_state.gaslimit);
|
||||||
else if (_fun == "eth.getTxGasPrice"_yulstring)
|
else if (_fun == "eth.getTxGasPrice"_yulstring)
|
||||||
return writeU128(arg[0], m_state.gasprice);
|
{
|
||||||
|
writeU128(arg[0], m_state.gasprice);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.log"_yulstring)
|
else if (_fun == "eth.log"_yulstring)
|
||||||
{
|
{
|
||||||
uint64_t numberOfTopics = arg[2];
|
uint64_t numberOfTopics = arg[2];
|
||||||
@ -257,7 +284,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
else if (_fun == "eth.getBlockNumber"_yulstring)
|
else if (_fun == "eth.getBlockNumber"_yulstring)
|
||||||
return m_state.blockNumber;
|
return m_state.blockNumber;
|
||||||
else if (_fun == "eth.getTxOrigin"_yulstring)
|
else if (_fun == "eth.getTxOrigin"_yulstring)
|
||||||
return writeAddress(arg[0], m_state.origin);
|
{
|
||||||
|
writeAddress(arg[0], m_state.origin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "eth.finish"_yulstring)
|
else if (_fun == "eth.finish"_yulstring)
|
||||||
{
|
{
|
||||||
bytes data;
|
bytes data;
|
||||||
@ -338,7 +368,7 @@ void EWasmBuiltinInterpreter::writeMemoryWord(uint64_t _offset, uint64_t _value)
|
|||||||
m_state.memory[_offset + i] = uint8_t((_value >> (i * 8)) & 0xff);
|
m_state.memory[_offset + i] = uint8_t((_value >> (i * 8)) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
u256 EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _croppedTo)
|
void EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _croppedTo)
|
||||||
{
|
{
|
||||||
accessMemory(_offset, _croppedTo);
|
accessMemory(_offset, _croppedTo);
|
||||||
for (size_t i = 0; i < _croppedTo; i++)
|
for (size_t i = 0; i < _croppedTo; i++)
|
||||||
@ -346,8 +376,6 @@ u256 EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _c
|
|||||||
m_state.memory[_offset + _croppedTo - 1 - i] = uint8_t(_value & 0xff);
|
m_state.memory[_offset + _croppedTo - 1 - i] = uint8_t(_value & 0xff);
|
||||||
_value >>= 8;
|
_value >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u256 EWasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo)
|
u256 EWasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo)
|
||||||
|
@ -88,9 +88,9 @@ private:
|
|||||||
void writeMemoryWord(uint64_t _offset, uint64_t _value);
|
void writeMemoryWord(uint64_t _offset, uint64_t _value);
|
||||||
|
|
||||||
/// Helper for eth.* builtins. Writes to memory (big-endian) and always returns zero.
|
/// Helper for eth.* builtins. Writes to memory (big-endian) and always returns zero.
|
||||||
dev::u256 writeU256(uint64_t _offset, dev::u256 _value, size_t _croppedTo = 32);
|
void writeU256(uint64_t _offset, dev::u256 _value, size_t _croppedTo = 32);
|
||||||
dev::u256 writeU128(uint64_t _offset, dev::u256 _value) { return writeU256(_offset, std::move(_value), 16); }
|
void writeU128(uint64_t _offset, dev::u256 _value) { writeU256(_offset, std::move(_value), 16); }
|
||||||
dev::u256 writeAddress(uint64_t _offset, dev::u256 _value) { return writeU256(_offset, std::move(_value), 20); }
|
void writeAddress(uint64_t _offset, dev::u256 _value) { writeU256(_offset, std::move(_value), 20); }
|
||||||
/// Helper for eth.* builtins. Reads from memory (big-endian) and returns the value;
|
/// Helper for eth.* builtins. Reads from memory (big-endian) and returns the value;
|
||||||
dev::u256 readU256(uint64_t _offset, size_t _croppedTo = 32);
|
dev::u256 readU256(uint64_t _offset, size_t _croppedTo = 32);
|
||||||
dev::u256 readU128(uint64_t _offset) { return readU256(_offset, 16); }
|
dev::u256 readU128(uint64_t _offset) { return readU256(_offset, 16); }
|
||||||
|
Loading…
Reference in New Issue
Block a user