Refactor.

This commit is contained in:
chriseth 2019-09-05 23:35:31 +02:00
parent 51cde26fb1
commit 9ecd51c54d
3 changed files with 25 additions and 18 deletions

View File

@ -95,6 +95,26 @@ void CompilerUtils::revertWithStringData(Type const& _argumentType)
m_context << Instruction::REVERT; m_context << Instruction::REVERT;
} }
void CompilerUtils::returnDataToArray()
{
if (m_context.evmVersion().supportsReturndata())
{
m_context << Instruction::RETURNDATASIZE;
m_context.appendInlineAssembly(R"({
switch v case 0 {
v := 0x60
} default {
v := mload(0x40)
mstore(0x40, add(v, and(add(returndatasize(), 0x3f), not(0x1f))))
mstore(v, returndatasize())
returndatacopy(add(v, 0x20), 0, returndatasize())
}
})", {"v"});
}
else
pushZeroPointer();
}
void CompilerUtils::accessCalldataTail(Type const& _type) void CompilerUtils::accessCalldataTail(Type const& _type)
{ {
solAssert(_type.dataStoredIn(DataLocation::CallData), ""); solAssert(_type.dataStoredIn(DataLocation::CallData), "");

View File

@ -67,6 +67,10 @@ public:
/// Stack post: /// Stack post:
void revertWithStringData(Type const& _argumentType); void revertWithStringData(Type const& _argumentType);
/// Allocates a new array and copies the return data to it.
/// If the EVM does not support return data, creates an empty array.
void returnDataToArray();
/// Computes the absolute calldata offset of a tail given a base reference and the (absolute) /// Computes the absolute calldata offset of a tail given a base reference and the (absolute)
/// offset of the tail pointer. Performs bounds checks. If @a _type is a dynamically sized array it also /// offset of the tail pointer. Performs bounds checks. If @a _type is a dynamically sized array it also
/// returns the array length on the stack. /// returns the array length on the stack.

View File

@ -2189,24 +2189,7 @@ void ExpressionCompiler::appendExternalFunctionCall(
// an internal helper function e.g. for ``send`` and ``transfer``. In that // an internal helper function e.g. for ``send`` and ``transfer``. In that
// case we're only interested in the success condition, not the return data. // case we're only interested in the success condition, not the return data.
if (!_functionType.returnParameterTypes().empty()) if (!_functionType.returnParameterTypes().empty())
{ utils().returnDataToArray();
if (haveReturndatacopy)
{
m_context << Instruction::RETURNDATASIZE;
m_context.appendInlineAssembly(R"({
switch v case 0 {
v := 0x60
} default {
v := mload(0x40)
mstore(0x40, add(v, and(add(returndatasize(), 0x3f), not(0x1f))))
mstore(v, returndatasize())
returndatacopy(add(v, 0x20), 0, returndatasize())
}
})", {"v"});
}
else
utils().pushZeroPointer();
}
} }
else if (funKind == FunctionType::Kind::RIPEMD160) else if (funKind == FunctionType::Kind::RIPEMD160)
{ {