mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Type conversion specialities for storage references.
This commit is contained in:
parent
a5664d0535
commit
17efc42299
@ -274,10 +274,13 @@ void CompilerUtils::encodeToMemory(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
copyToStackTop(argSize - stackPos + dynPointers + 2, _givenTypes[i]->getSizeOnStack());
|
copyToStackTop(argSize - stackPos + dynPointers + 2, _givenTypes[i]->getSizeOnStack());
|
||||||
if (targetType->isValueType())
|
|
||||||
convertType(*_givenTypes[i], *targetType, true);
|
|
||||||
solAssert(!!targetType, "Externalable type expected.");
|
solAssert(!!targetType, "Externalable type expected.");
|
||||||
storeInMemoryDynamic(*targetType, _padToWordBoundaries);
|
TypePointer type = targetType;
|
||||||
|
if (_givenTypes[i]->isInStorage())
|
||||||
|
type = _givenTypes[i]; // delay conversion
|
||||||
|
else
|
||||||
|
convertType(*_givenTypes[i], *targetType, true);
|
||||||
|
storeInMemoryDynamic(*type, _padToWordBoundaries);
|
||||||
}
|
}
|
||||||
stackPos += _givenTypes[i]->getSizeOnStack();
|
stackPos += _givenTypes[i]->getSizeOnStack();
|
||||||
}
|
}
|
||||||
|
@ -146,10 +146,13 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
{
|
{
|
||||||
CompilerContext::LocationSetter locationSetter(m_context, _assignment);
|
CompilerContext::LocationSetter locationSetter(m_context, _assignment);
|
||||||
_assignment.getRightHandSide().accept(*this);
|
_assignment.getRightHandSide().accept(*this);
|
||||||
if (_assignment.getType()->isValueType())
|
TypePointer type = _assignment.getRightHandSide().getType();
|
||||||
utils().convertType(*_assignment.getRightHandSide().getType(), *_assignment.getType());
|
if (!_assignment.getType()->isInStorage())
|
||||||
// We need this conversion mostly in the case of compound assignments. For non-value types
|
{
|
||||||
// the conversion is done in LValue::storeValue.
|
utils().convertType(*type, *_assignment.getType());
|
||||||
|
type = _assignment.getType();
|
||||||
|
}
|
||||||
|
|
||||||
_assignment.getLeftHandSide().accept(*this);
|
_assignment.getLeftHandSide().accept(*this);
|
||||||
solAssert(!!m_currentLValue, "LValue not retrieved.");
|
solAssert(!!m_currentLValue, "LValue not retrieved.");
|
||||||
|
|
||||||
@ -175,7 +178,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
|
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
|
m_currentLValue->storeValue(*type, _assignment.getLocation());
|
||||||
m_currentLValue.reset();
|
m_currentLValue.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1119,14 +1122,10 @@ void ExpressionCompiler::appendExternalFunctionCall(
|
|||||||
|
|
||||||
void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression)
|
void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression)
|
||||||
{
|
{
|
||||||
|
solAssert(_expectedType.isValueType(), "Not implemented for non-value types.");
|
||||||
_expression.accept(*this);
|
_expression.accept(*this);
|
||||||
if (_expectedType.isValueType())
|
utils().convertType(*_expression.getType(), _expectedType, true);
|
||||||
{
|
utils().storeInMemoryDynamic(_expectedType);
|
||||||
utils().convertType(*_expression.getType(), _expectedType, true);
|
|
||||||
utils().storeInMemoryDynamic(_expectedType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
utils().storeInMemoryDynamic(*_expression.getType()->mobileType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression)
|
void ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression)
|
||||||
|
3
Types.h
3
Types.h
@ -202,6 +202,8 @@ public:
|
|||||||
/// This returns the corresponding integer type for IntegerConstantTypes and the pointer type
|
/// This returns the corresponding integer type for IntegerConstantTypes and the pointer type
|
||||||
/// for storage reference types.
|
/// for storage reference types.
|
||||||
virtual TypePointer mobileType() const { return shared_from_this(); }
|
virtual TypePointer mobileType() const { return shared_from_this(); }
|
||||||
|
/// @returns true if this type is a storage pointer or reference.
|
||||||
|
virtual bool isInStorage() const { return false; }
|
||||||
|
|
||||||
/// Returns the list of all members of this type. Default implementation: no members.
|
/// Returns the list of all members of this type. Default implementation: no members.
|
||||||
virtual MemberList const& getMembers() const { return EmptyMemberList; }
|
virtual MemberList const& getMembers() const { return EmptyMemberList; }
|
||||||
@ -374,6 +376,7 @@ public:
|
|||||||
virtual TypePointer copyForLocation(Location _location, bool _isPointer) const = 0;
|
virtual TypePointer copyForLocation(Location _location, bool _isPointer) const = 0;
|
||||||
|
|
||||||
virtual TypePointer mobileType() const override { return copyForLocation(m_location, true); }
|
virtual TypePointer mobileType() const override { return copyForLocation(m_location, true); }
|
||||||
|
virtual bool isInStorage() const override { return m_location == Location::Storage; }
|
||||||
|
|
||||||
/// Storage references can be pointers or bound references. In general, local variables are of
|
/// Storage references can be pointers or bound references. In general, local variables are of
|
||||||
/// pointer type, state variables are bound references. Assignments to pointers or deleting
|
/// pointer type, state variables are bound references. Assignments to pointers or deleting
|
||||||
|
Loading…
Reference in New Issue
Block a user