mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #8046 from imapp-pl/ewasm-interpreter-improvements
Wasm dialect extension and EWasm interpreter improvements.
This commit is contained in:
commit
37ae229a4c
@ -56,10 +56,16 @@ WasmDialect::WasmDialect():
|
|||||||
addFunction("i64.eqz", 1, 1);
|
addFunction("i64.eqz", 1, 1);
|
||||||
m_functions["i64.eqz"_yulstring].returns.front() = "i32"_yulstring;
|
m_functions["i64.eqz"_yulstring].returns.front() = "i32"_yulstring;
|
||||||
|
|
||||||
|
addFunction("i64.clz", 1, 1);
|
||||||
|
|
||||||
addFunction("i64.store", 2, 0, false);
|
addFunction("i64.store", 2, 0, false);
|
||||||
m_functions["i64.store"_yulstring].parameters.front() = "i32"_yulstring;
|
m_functions["i64.store"_yulstring].parameters.front() = "i32"_yulstring;
|
||||||
m_functions["i64.store"_yulstring].sideEffects.invalidatesStorage = false;
|
m_functions["i64.store"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
|
||||||
|
addFunction("i64.store8", 2, 0, false);
|
||||||
|
m_functions["i64.store8"_yulstring].parameters.front() = "i32"_yulstring;
|
||||||
|
m_functions["i64.store8"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
|
||||||
addFunction("i64.load", 1, 1, false);
|
addFunction("i64.load", 1, 1, false);
|
||||||
m_functions["i64.load"_yulstring].parameters.front() = "i32"_yulstring;
|
m_functions["i64.load"_yulstring].parameters.front() = "i32"_yulstring;
|
||||||
m_functions["i64.load"_yulstring].sideEffects.invalidatesStorage = false;
|
m_functions["i64.load"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
@ -49,6 +49,21 @@ void copyZeroExtended(
|
|||||||
_target[_targetOffset + i] = _sourceOffset + i < _source.size() ? _source[_sourceOffset + i] : 0;
|
_target[_targetOffset + i] = _sourceOffset + i < _source.size() ? _source[_sourceOffset + i] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Count leading zeros for uint64
|
||||||
|
uint64_t clz(uint64_t _v)
|
||||||
|
{
|
||||||
|
if (_v == 0)
|
||||||
|
return 64;
|
||||||
|
|
||||||
|
uint64_t r = 0;
|
||||||
|
while (!(_v & 0x8000000000000000))
|
||||||
|
{
|
||||||
|
r += 1;
|
||||||
|
_v = _v << 1;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
@ -119,6 +134,8 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
return arg[0] != arg[1] ? 1 : 0;
|
return arg[0] != arg[1] ? 1 : 0;
|
||||||
else if (_fun == "i64.eqz"_yulstring)
|
else if (_fun == "i64.eqz"_yulstring)
|
||||||
return arg[0] == 0 ? 1 : 0;
|
return arg[0] == 0 ? 1 : 0;
|
||||||
|
else if (_fun == "i64.clz"_yulstring)
|
||||||
|
return clz(arg[0]);
|
||||||
else if (_fun == "i64.lt_u"_yulstring)
|
else if (_fun == "i64.lt_u"_yulstring)
|
||||||
return arg[0] < arg[1] ? 1 : 0;
|
return arg[0] < arg[1] ? 1 : 0;
|
||||||
else if (_fun == "i64.gt_u"_yulstring)
|
else if (_fun == "i64.gt_u"_yulstring)
|
||||||
@ -133,6 +150,12 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
writeMemoryWord(arg[0], arg[1]);
|
writeMemoryWord(arg[0], arg[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (_fun == "i64.store8"_yulstring)
|
||||||
|
{
|
||||||
|
accessMemory(arg[0], 1);
|
||||||
|
writeMemoryByte(arg[0], static_cast<uint8_t>(arg[1] & 0xff));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (_fun == "i64.load"_yulstring)
|
else if (_fun == "i64.load"_yulstring)
|
||||||
{
|
{
|
||||||
accessMemory(arg[0], 8);
|
accessMemory(arg[0], 8);
|
||||||
@ -148,7 +171,7 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
|||||||
// 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.
|
||||||
writeU128(arg[0], m_state.balance);
|
writeU128(arg[1], m_state.balance);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (_fun == "eth.getBlockHash"_yulstring)
|
else if (_fun == "eth.getBlockHash"_yulstring)
|
||||||
@ -368,6 +391,11 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EWasmBuiltinInterpreter::writeMemoryByte(uint64_t _offset, uint8_t _value)
|
||||||
|
{
|
||||||
|
m_state.memory[_offset] = _value;
|
||||||
|
}
|
||||||
|
|
||||||
void 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);
|
||||||
|
@ -86,6 +86,9 @@ private:
|
|||||||
/// Writes a word to memory (little-endian)
|
/// Writes a word to memory (little-endian)
|
||||||
/// Does not adjust msize, use @a accessMemory for that
|
/// Does not adjust msize, use @a accessMemory for that
|
||||||
void writeMemoryWord(uint64_t _offset, uint64_t _value);
|
void writeMemoryWord(uint64_t _offset, uint64_t _value);
|
||||||
|
/// Writes a byte to memory
|
||||||
|
/// Does not adjust msize, use @a accessMemory for that
|
||||||
|
void writeMemoryByte(uint64_t _offset, uint8_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.
|
||||||
void writeU256(uint64_t _offset, dev::u256 _value, size_t _croppedTo = 32);
|
void writeU256(uint64_t _offset, dev::u256 _value, size_t _croppedTo = 32);
|
||||||
|
Loading…
Reference in New Issue
Block a user