mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simple mapping accessors working
This commit is contained in:
parent
82bcb7e33a
commit
5a374afe62
@ -823,10 +823,10 @@ unsigned ExpressionCompiler::appendArgumentCopyToMemory(TypePointers const& _typ
|
||||
return length;
|
||||
}
|
||||
|
||||
unsigned ExpressionCompiler::appendTypeCopyToMemory(Type const& _expectedType, TypePointer const& _type,
|
||||
unsigned ExpressionCompiler::appendTypeConversionAndMoveToMemory(Type const& _expectedType, Type const& _type,
|
||||
Location const& _location, unsigned _memoryOffset)
|
||||
{
|
||||
appendTypeConversion(*_type, _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()
|
||||
@ -842,65 +842,40 @@ unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedT
|
||||
unsigned _memoryOffset)
|
||||
{
|
||||
_expression.accept(*this);
|
||||
return appendTypeCopyToMemory(_expectedType, _expression.getType(), _expression.getLocation(), _memoryOffset);
|
||||
return appendTypeConversionAndMoveToMemory(_expectedType, *_expression.getType(), _expression.getLocation(), _memoryOffset);
|
||||
}
|
||||
|
||||
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
auto mappingType = dynamic_cast<const MappingType*>(_varDecl.getType().get());
|
||||
TypePointer resultType = _varDecl.getType();
|
||||
auto mappingType = dynamic_cast<const MappingType*>(resultType.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());
|
||||
unsigned length = appendTypeConversionAndMoveToMemory(*keyType, *keyType, Location());
|
||||
solAssert(length == 32, "Mapping key has to take 32 bytes in memory (for now).");
|
||||
// @todo move this once we actually use memory
|
||||
m_context << m_context.getStorageLocationOfVariable(_varDecl);
|
||||
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);
|
||||
m_currentLValue.reset();
|
||||
|
||||
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;
|
||||
resultType = mappingType->getValueType();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ private:
|
||||
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,
|
||||
unsigned appendTypeConversionAndMoveToMemory(Type const& _expectedType, Type 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
|
||||
|
Loading…
Reference in New Issue
Block a user