mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Code generation for mapping state variable accessor
- Work in progress
This commit is contained in:
parent
ec7a9bf919
commit
82bcb7e33a
@ -240,10 +240,6 @@ bool Compiler::visit(VariableDeclaration const& _variableDeclaration)
|
||||
m_context << m_context.getFunctionEntryLabel(_variableDeclaration);
|
||||
ExpressionCompiler::appendStateVariableAccessor(m_context, _variableDeclaration);
|
||||
|
||||
unsigned sizeOnStack = _variableDeclaration.getType()->getSizeOnStack();
|
||||
solAssert(sizeOnStack <= 15, "Stack too deep.");
|
||||
m_context << eth::dupInstruction(sizeOnStack + 1) << eth::Instruction::JUMP;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -823,26 +823,85 @@ unsigned ExpressionCompiler::appendArgumentCopyToMemory(TypePointers const& _typ
|
||||
return length;
|
||||
}
|
||||
|
||||
unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType,
|
||||
Expression const& _expression, unsigned _memoryOffset)
|
||||
unsigned ExpressionCompiler::appendTypeCopyToMemory(Type const& _expectedType, TypePointer const& _type,
|
||||
Location const& _location, unsigned _memoryOffset)
|
||||
{
|
||||
_expression.accept(*this);
|
||||
appendTypeConversion(*_expression.getType(), _expectedType, true);
|
||||
appendTypeConversion(*_type, _expectedType, true);
|
||||
unsigned const c_numBytes = CompilerUtils::getPaddedSize(_expectedType.getCalldataEncodedSize());
|
||||
if (c_numBytes == 0 || c_numBytes > 32)
|
||||
BOOST_THROW_EXCEPTION(CompilerError()
|
||||
<< errinfo_sourceLocation(_expression.getLocation())
|
||||
<< errinfo_sourceLocation(_location)
|
||||
<< errinfo_comment("Type " + _expectedType.toString() + " not yet supported."));
|
||||
bool const c_leftAligned = _expectedType.getCategory() == Type::Category::STRING;
|
||||
bool const c_padToWords = true;
|
||||
return CompilerUtils(m_context).storeInMemory(_memoryOffset, c_numBytes, c_leftAligned, c_padToWords);
|
||||
}
|
||||
|
||||
unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType,
|
||||
Expression const& _expression,
|
||||
unsigned _memoryOffset)
|
||||
{
|
||||
_expression.accept(*this);
|
||||
return appendTypeCopyToMemory(_expectedType, _expression.getType(), _expression.getLocation(), _memoryOffset);
|
||||
}
|
||||
|
||||
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
m_currentLValue.fromStateVariable(_varDecl, _varDecl.getType());
|
||||
solAssert(m_currentLValue.isInStorage(), "");
|
||||
m_currentLValue.retrieveValue(_varDecl.getType(), Location(), true);
|
||||
auto mappingType = dynamic_cast<const MappingType*>(_varDecl.getType().get());
|
||||
unsigned sizeOnStack;
|
||||
if (mappingType != nullptr)
|
||||
{
|
||||
// this copies from Compiler::visit(FunctionDefinition..) for argument reading
|
||||
unsigned parameterSize = mappingType->getKeyType()->getSizeOnStack();
|
||||
m_context.adjustStackOffset(parameterSize);
|
||||
m_context.addVariable(_varDecl, parameterSize);
|
||||
// this copies from ExpressionCompiler::visit(IndexAccess .. ) for mapping access
|
||||
TypePointer const& keyType = mappingType->getKeyType();
|
||||
unsigned length = appendTypeCopyToMemory(*keyType, mappingType->getValueType(), Location());
|
||||
solAssert(length == 32, "Mapping key has to take 32 bytes in memory (for now).");
|
||||
// @todo move this once we actually use memory
|
||||
length += CompilerUtils(m_context).storeInMemory(length);
|
||||
m_context << u256(length) << u256(0) << eth::Instruction::SHA3;
|
||||
|
||||
m_currentLValue = LValue(m_context, LValue::STORAGE, *mappingType->getValueType());
|
||||
m_currentLValue.retrieveValue(mappingType->getValueType(), Location(), true);
|
||||
|
||||
unsigned const c_argumentsSize = keyType->getSizeOnStack();
|
||||
unsigned const c_returnValuesSize = mappingType->getValueType()->getSizeOnStack();
|
||||
unsigned const c_localVariablesSize = 0;
|
||||
|
||||
vector<int> stackLayout;
|
||||
stackLayout.push_back(c_returnValuesSize); // target of return address
|
||||
stackLayout += vector<int>(c_argumentsSize, -1); // discard all arguments
|
||||
for (unsigned i = 0; i < c_returnValuesSize; ++i)
|
||||
stackLayout.push_back(i);
|
||||
stackLayout += vector<int>(c_localVariablesSize, -1);
|
||||
|
||||
while (stackLayout.back() != int(stackLayout.size() - 1))
|
||||
if (stackLayout.back() < 0)
|
||||
{
|
||||
m_context << eth::Instruction::POP;
|
||||
stackLayout.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_context << eth::swapInstruction(stackLayout.size() - stackLayout.back() - 1);
|
||||
swap(stackLayout[stackLayout.back()], stackLayout.back());
|
||||
}
|
||||
//@todo assert that everything is in place now
|
||||
|
||||
m_context << eth::Instruction::JUMP;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentLValue.fromStateVariable(_varDecl, _varDecl.getType());
|
||||
solAssert(m_currentLValue.isInStorage(), "");
|
||||
m_currentLValue.retrieveValue(_varDecl.getType(), Location(), true);
|
||||
sizeOnStack = _varDecl.getType()->getSizeOnStack();
|
||||
solAssert(sizeOnStack <= 15, "Stack too deep.");
|
||||
m_context << eth::dupInstruction(sizeOnStack + 1) << eth::Instruction::JUMP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType,
|
||||
|
@ -97,6 +97,10 @@ private:
|
||||
unsigned appendArgumentCopyToMemory(TypePointers const& _types,
|
||||
std::vector<ASTPointer<Expression const>> const& _arguments,
|
||||
unsigned _memoryOffset = 0);
|
||||
/// Appends code that copies a type to memory.
|
||||
/// @returns the number of bytes copied to memory
|
||||
unsigned appendTypeCopyToMemory(Type const& _expectedType, TypePointer const& _type,
|
||||
Location const& _location, unsigned _memoryOffset = 0);
|
||||
/// Appends code that evaluates a single expression and copies it to memory (with optional offset).
|
||||
/// @returns the number of bytes copied to memory
|
||||
unsigned appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression,
|
||||
|
Loading…
Reference in New Issue
Block a user