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
 | 
			
		||||
		{
 | 
			
		||||
			copyToStackTop(argSize - stackPos + dynPointers + 2, _givenTypes[i]->getSizeOnStack());
 | 
			
		||||
			if (targetType->isValueType())
 | 
			
		||||
				convertType(*_givenTypes[i], *targetType, true);
 | 
			
		||||
			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();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -146,10 +146,13 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
 | 
			
		||||
{
 | 
			
		||||
	CompilerContext::LocationSetter locationSetter(m_context, _assignment);
 | 
			
		||||
	_assignment.getRightHandSide().accept(*this);
 | 
			
		||||
	if (_assignment.getType()->isValueType())
 | 
			
		||||
		utils().convertType(*_assignment.getRightHandSide().getType(), *_assignment.getType());
 | 
			
		||||
	// We need this conversion mostly in the case of compound assignments. For non-value types
 | 
			
		||||
	// the conversion is done in LValue::storeValue.
 | 
			
		||||
	TypePointer type = _assignment.getRightHandSide().getType();
 | 
			
		||||
	if (!_assignment.getType()->isInStorage())
 | 
			
		||||
	{
 | 
			
		||||
		utils().convertType(*type, *_assignment.getType());
 | 
			
		||||
		type = _assignment.getType();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_assignment.getLeftHandSide().accept(*this);
 | 
			
		||||
	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_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
 | 
			
		||||
	m_currentLValue->storeValue(*type, _assignment.getLocation());
 | 
			
		||||
	m_currentLValue.reset();
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
@ -1119,14 +1122,10 @@ void ExpressionCompiler::appendExternalFunctionCall(
 | 
			
		||||
 | 
			
		||||
void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression)
 | 
			
		||||
{
 | 
			
		||||
	solAssert(_expectedType.isValueType(), "Not implemented for non-value types.");
 | 
			
		||||
	_expression.accept(*this);
 | 
			
		||||
	if (_expectedType.isValueType())
 | 
			
		||||
	{
 | 
			
		||||
		utils().convertType(*_expression.getType(), _expectedType, true);
 | 
			
		||||
		utils().storeInMemoryDynamic(_expectedType);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		utils().storeInMemoryDynamic(*_expression.getType()->mobileType());
 | 
			
		||||
	utils().convertType(*_expression.getType(), _expectedType, true);
 | 
			
		||||
	utils().storeInMemoryDynamic(_expectedType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
	/// for storage reference types.
 | 
			
		||||
	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.
 | 
			
		||||
	virtual MemberList const& getMembers() const { return EmptyMemberList; }
 | 
			
		||||
@ -374,6 +376,7 @@ public:
 | 
			
		||||
	virtual TypePointer copyForLocation(Location _location, bool _isPointer) const = 0;
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	/// pointer type, state variables are bound references. Assignments to pointers or deleting
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user