Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 40 additions & 45 deletions test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ uint64_t popcnt(uint64_t _v)

}

using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;

u256 EwasmBuiltinInterpreter::evalBuiltin(
YulString _functionName,
vector<Expression> const& _arguments,
Expand Down Expand Up @@ -144,14 +142,14 @@ u256 EwasmBuiltinInterpreter::evalBuiltin(
else if (fun == "datacopy")
{
// This is identical to codecopy.
if (accessMemory(_evaluatedArguments.at(0), _evaluatedArguments.at(2)))
copyZeroExtended(
m_state.memory,
m_state.code,
static_cast<size_t>(_evaluatedArguments.at(0)),
static_cast<size_t>(_evaluatedArguments.at(1) & numeric_limits<size_t>::max()),
static_cast<size_t>(_evaluatedArguments.at(2))
);
accessMemory(_evaluatedArguments.at(0), _evaluatedArguments.at(2));
copyZeroExtended(
m_state.memory,
m_state.code,
static_cast<size_t>(_evaluatedArguments.at(0)),
static_cast<size_t>(_evaluatedArguments.at(1) & numeric_limits<size_t>::max()),
static_cast<size_t>(_evaluatedArguments.at(2))
);
return 0;
}
else if (fun == "i32.drop" || fun == "i64.drop" || fun == "nop")
Expand Down Expand Up @@ -324,11 +322,11 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
{
if (arg[1] + arg[2] < arg[1] || arg[1] + arg[2] > m_state.calldata.size())
throw ExplicitlyTerminated();
if (accessMemory(arg[0], arg[2]))
copyZeroExtended(
m_state.memory, m_state.calldata,
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
);
accessMemory(arg[0], arg[2]);
copyZeroExtended(
m_state.memory, m_state.calldata,
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
);
return {};
}
else if (_fun == "getCallDataSize")
Expand Down Expand Up @@ -377,11 +375,11 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
}
else if (_fun == "codeCopy")
{
if (accessMemory(arg[0], arg[2]))
copyZeroExtended(
m_state.memory, m_state.code,
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
);
accessMemory(arg[0], arg[2]);
copyZeroExtended(
m_state.memory, m_state.code,
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
);
return 0;
}
else if (_fun == "getCodeSize")
Expand All @@ -407,12 +405,12 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
else if (_fun == "externalCodeCopy")
{
readAddress(arg[0]);
if (accessMemory(arg[1], arg[3]))
// TODO this way extcodecopy and codecopy do the same thing.
copyZeroExtended(
m_state.memory, m_state.code,
size_t(arg[1]), size_t(arg[2]), size_t(arg[3])
);
accessMemory(arg[1], arg[3]);
// TODO this way extcodecopy and codecopy do the same thing.
copyZeroExtended(
m_state.memory, m_state.code,
size_t(arg[1]), size_t(arg[2]), size_t(arg[3])
);
return 0;
}
else if (_fun == "getExternalCodeSize")
Expand Down Expand Up @@ -454,16 +452,16 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
else if (_fun == "finish")
{
bytes data;
if (accessMemory(arg[0], arg[1]))
data = readMemory(arg[0], arg[1]);
accessMemory(arg[0], arg[1]);
data = readMemory(arg[0], arg[1]);
logTrace(evmasm::Instruction::RETURN, {}, data);
throw ExplicitlyTerminated();
}
else if (_fun == "revert")
{
bytes data;
if (accessMemory(arg[0], arg[1]))
data = readMemory(arg[0], arg[1]);
accessMemory(arg[0], arg[1]);
data = readMemory(arg[0], arg[1]);
logTrace(evmasm::Instruction::REVERT, {}, data);
throw ExplicitlyTerminated();
}
Expand All @@ -473,11 +471,11 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
{
if (arg[1] + arg[2] < arg[1] || arg[1] + arg[2] > m_state.returndata.size())
throw ExplicitlyTerminated();
if (accessMemory(arg[0], arg[2]))
copyZeroExtended(
m_state.memory, m_state.calldata,
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
);
accessMemory(arg[0], arg[2]);
copyZeroExtended(
m_state.memory, m_state.calldata,
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
);
return {};
}
else if (_fun == "selfDestruct")
Expand All @@ -494,18 +492,15 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector<uint64_t
return 0;
}

bool EwasmBuiltinInterpreter::accessMemory(u256 const& _offset, u256 const& _size)
void EwasmBuiltinInterpreter::accessMemory(u256 const& _offset, u256 const& _size)
{
if (((_offset + _size) >= _offset) && ((_offset + _size + 0x1f) >= (_offset + _size)))
{
u256 newSize = (_offset + _size + 0x1f) & ~u256(0x1f);
m_state.msize = max(m_state.msize, newSize);
return _size <= 0xffff;
}
else
m_state.msize = u256(-1);
// Single WebAssembly page.
// TODO: Support expansion in this interpreter.
m_state.msize = 65536;

return false;
if (((_offset + _size) < _offset) || ((_offset + _size) > m_state.msize))
// Ewasm throws out of bounds exception as opposed to the EVM.
throw ExplicitlyTerminated();
}

bytes EwasmBuiltinInterpreter::readMemory(uint64_t _offset, uint64_t _size)
Expand Down
3 changes: 1 addition & 2 deletions test/tools/yulInterpreter/EwasmBuiltinInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ class EwasmBuiltinInterpreter

/// Checks if the memory access is not too large for the interpreter and adjusts
/// msize accordingly.
/// @returns false if the amount of bytes read is lager than 0xffff
bool accessMemory(u256 const& _offset, u256 const& _size = 32);
void accessMemory(u256 const& _offset, u256 const& _size = 32);
/// @returns the memory contents at the provided address.
/// Does not adjust msize, use @a accessMemory for that
bytes readMemory(uint64_t _offset, uint64_t _size = 32);
Expand Down