mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move code to loadFromMemory.
This commit is contained in:
parent
f7ba85e0ec
commit
1f6e365136
26
Compiler.cpp
26
Compiler.cpp
@ -147,7 +147,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
|
||||
|
||||
// retrieve the function signature hash from the calldata
|
||||
if (!interfaceFunctions.empty())
|
||||
CompilerUtils(m_context).loadFromMemory(0, 4, false, true);
|
||||
CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true);
|
||||
|
||||
// stack now is: 1 0 <funhash>
|
||||
for (auto const& it: interfaceFunctions)
|
||||
@ -182,18 +182,10 @@ unsigned Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, b
|
||||
{
|
||||
// We do not check the calldata size, everything is zero-padded.
|
||||
unsigned dataOffset = CompilerUtils::dataStartOffset; // the 4 bytes of the function hash signature
|
||||
//@todo this can be done more efficiently, saving some CALLDATALOAD calls
|
||||
for (TypePointer const& type: _typeParameters)
|
||||
{
|
||||
unsigned const c_numBytes = type->getCalldataEncodedSize();
|
||||
if (c_numBytes > 32)
|
||||
BOOST_THROW_EXCEPTION(CompilerError()
|
||||
<< errinfo_comment("Type " + type->toString() + " not yet supported."));
|
||||
bool const c_leftAligned = type->getCategory() == Type::Category::String;
|
||||
|
||||
bool const c_padToWords = true;
|
||||
dataOffset += CompilerUtils(m_context).loadFromMemory(dataOffset, c_numBytes, c_leftAligned,
|
||||
!_fromMemory, c_padToWords);
|
||||
}
|
||||
for (TypePointer const& type: _typeParameters)
|
||||
dataOffset += CompilerUtils(m_context).loadFromMemory(dataOffset, *type, !_fromMemory, c_padToWords);
|
||||
return dataOffset;
|
||||
}
|
||||
|
||||
@ -255,8 +247,6 @@ bool Compiler::visit(FunctionDefinition const& _function)
|
||||
// stack upon entry: [return address] [arg0] [arg1] ... [argn]
|
||||
// reserve additional slots: [retarg0] ... [retargm] [localvar0] ... [localvarp]
|
||||
|
||||
if (_function.getVisibility() != Declaration::Visibility::External)
|
||||
{
|
||||
unsigned parametersSize = CompilerUtils::getSizeOnStack(_function.getParameters());
|
||||
m_context.adjustStackOffset(parametersSize);
|
||||
for (ASTPointer<VariableDeclaration const> const& variable: _function.getParameters())
|
||||
@ -264,14 +254,6 @@ bool Compiler::visit(FunctionDefinition const& _function)
|
||||
m_context.addVariable(*variable, parametersSize);
|
||||
parametersSize -= variable->getType()->getSizeOnStack();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned calldataPos = CompilerUtils::dataStartOffset;
|
||||
// calldatapos is _always_ dynamic.
|
||||
for (ASTPointer<VariableDeclaration const> const& variable: _function.getParameters())
|
||||
m_context.addCalldataVariable(*variable, calldataPos);
|
||||
}
|
||||
for (ASTPointer<VariableDeclaration const> const& variable: _function.getReturnParameters())
|
||||
m_context.addAndInitializeVariable(*variable);
|
||||
for (VariableDeclaration const* localVariable: _function.getLocalVariables())
|
||||
|
@ -33,33 +33,34 @@ namespace solidity
|
||||
|
||||
const unsigned int CompilerUtils::dataStartOffset = 4;
|
||||
|
||||
unsigned CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _leftAligned,
|
||||
unsigned CompilerUtils::loadFromMemory(unsigned _offset, Type const& _type,
|
||||
bool _fromCalldata, bool _padToWordBoundaries)
|
||||
{
|
||||
if (_bytes == 0)
|
||||
{
|
||||
solAssert(_type.getCategory() != Type::Category::ByteArray, "Unable to statically load dynamic type.");
|
||||
unsigned _encodedSize = _type.getCalldataEncodedSize();
|
||||
unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize;
|
||||
bool leftAligned = _type.getCategory() == Type::Category::String;
|
||||
if (numBytes == 0)
|
||||
m_context << u256(0);
|
||||
return 0;
|
||||
}
|
||||
eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD;
|
||||
solAssert(_bytes <= 32, "Memory load of more than 32 bytes requested.");
|
||||
if (_bytes == 32 || _padToWordBoundaries)
|
||||
else
|
||||
{
|
||||
eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD;
|
||||
solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested.");
|
||||
if (numBytes == 32)
|
||||
m_context << u256(_offset) << load;
|
||||
return 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
// load data and add leading or trailing zeros by dividing/multiplying depending on alignment
|
||||
u256 shiftFactor = u256(1) << ((32 - _bytes) * 8);
|
||||
u256 shiftFactor = u256(1) << ((32 - numBytes) * 8);
|
||||
m_context << shiftFactor;
|
||||
if (_leftAligned)
|
||||
if (leftAligned)
|
||||
m_context << eth::Instruction::DUP1;
|
||||
m_context << u256(_offset) << load << eth::Instruction::DIV;
|
||||
if (_leftAligned)
|
||||
if (leftAligned)
|
||||
m_context << eth::Instruction::MUL;
|
||||
return _bytes;
|
||||
}
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
unsigned CompilerUtils::storeInMemory(unsigned _offset, Type const& _type, bool _padToWordBoundaries)
|
||||
|
@ -37,13 +37,12 @@ public:
|
||||
|
||||
/// Loads data from memory to the stack.
|
||||
/// @param _offset offset in memory (or calldata)
|
||||
/// @param _bytes number of bytes to load
|
||||
/// @param _leftAligned if true, store left aligned on stack (otherwise right aligned)
|
||||
/// @param _type data type to load
|
||||
/// @param _fromCalldata if true, load from calldata, not from memory
|
||||
/// @param _padToWordBoundaries if true, assume the data is padded to word (32 byte) boundaries
|
||||
/// @returns the number of bytes consumed in memory (can be different from _bytes if
|
||||
/// _padToWordBoundaries is true)
|
||||
unsigned loadFromMemory(unsigned _offset, unsigned _bytes = 32, bool _leftAligned = false,
|
||||
unsigned loadFromMemory(unsigned _offset, Type const& _type = IntegerType(256),
|
||||
bool _fromCalldata = false, bool _padToWordBoundaries = false);
|
||||
/// Stores data from stack in memory.
|
||||
/// @param _offset offset in memory
|
||||
|
@ -885,11 +885,8 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
|
||||
m_context << eth::Instruction::POP;
|
||||
m_context << eth::Instruction::POP; // pop contract address
|
||||
|
||||
if (retSize > 0)
|
||||
{
|
||||
bool const c_leftAligned = firstType->getCategory() == Type::Category::String;
|
||||
CompilerUtils(m_context).loadFromMemory(0, retSize, c_leftAligned, false, true);
|
||||
}
|
||||
if (firstType)
|
||||
CompilerUtils(m_context).loadFromMemory(0, *firstType, false, true);
|
||||
}
|
||||
|
||||
void ExpressionCompiler::appendArgumentsCopyToMemory(vector<ASTPointer<Expression const>> const& _arguments,
|
||||
|
Loading…
Reference in New Issue
Block a user