mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	added implementation to append code for State variable accessor
fixed tests
This commit is contained in:
		
							parent
							
								
									df3ce3ad8f
								
							
						
					
					
						commit
						fb1cf35f3b
					
				| @ -157,8 +157,12 @@ void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize) | ||||
| 
 | ||||
| void CompilerUtils::popStackElement(Type const& _type) | ||||
| { | ||||
| 	unsigned const size = _type.getSizeOnStack(); | ||||
| 	for (unsigned i = 0; i < size; ++i) | ||||
| 	popStackSlots(_type.getSizeOnStack()); | ||||
| } | ||||
| 
 | ||||
| void CompilerUtils::popStackSlots(size_t _amount) | ||||
| { | ||||
| 	for (size_t i = 0; i < _amount; ++i) | ||||
| 		m_context << eth::Instruction::POP; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -79,6 +79,8 @@ public: | ||||
| 	void copyToStackTop(unsigned _stackDepth, unsigned _itemSize); | ||||
| 	/// Removes the current value from the top of the stack.
 | ||||
| 	void popStackElement(Type const& _type); | ||||
| 	/// Removes element from the top of the stack _amount times.
 | ||||
| 	void popStackSlots(size_t _amount); | ||||
| 
 | ||||
| 	template <class T> | ||||
| 	static unsigned getSizeOnStack(std::vector<T> const& _variables); | ||||
|  | ||||
| @ -60,43 +60,37 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& | ||||
| 	CompilerContext::LocationSetter locationSetter(m_context, _varDecl); | ||||
| 	FunctionType accessorType(_varDecl); | ||||
| 
 | ||||
| 	unsigned length = 0; | ||||
| 	TypePointers const& paramTypes = accessorType.getParameterTypes(); | ||||
| 
 | ||||
| 	// to exclude the last key if it is an array
 | ||||
| 	TypePointer finalMappingValueType = _varDecl.getType(); | ||||
| 	while (finalMappingValueType->getCategory() == Type::Category::Mapping) | ||||
| 		finalMappingValueType = dynamic_cast<MappingType const&>(*finalMappingValueType).getValueType(); | ||||
| 
 | ||||
| 	bool finalIsArrayType = finalMappingValueType->getCategory() == Type::Category::Array; | ||||
| 	TypePointers mappingKeys(paramTypes); | ||||
| 	if (finalIsArrayType) | ||||
| 		mappingKeys.pop_back(); | ||||
| 
 | ||||
| 	// move mapping arguments to memory
 | ||||
| 	for (TypePointer const& paramType: boost::adaptors::reverse(mappingKeys)) | ||||
| 		length += CompilerUtils(m_context).storeInMemory(length, *paramType, true); | ||||
| 
 | ||||
| 	// retrieve the position of the variable
 | ||||
| 	auto const& location = m_context.getStorageLocationOfVariable(_varDecl); | ||||
| 	m_context << location.first; | ||||
| 
 | ||||
| 	TypePointer returnType = _varDecl.getType(); | ||||
| 
 | ||||
| 	for (TypePointer const& paramType: mappingKeys) | ||||
| 	for (size_t i = 0; i < paramTypes.size(); ++i) | ||||
| 	{ | ||||
| 		// move offset to memory
 | ||||
| 		CompilerUtils(m_context).storeInMemory(length); | ||||
| 		unsigned argLen = paramType->getCalldataEncodedSize(); | ||||
| 		length -= argLen; | ||||
| 		m_context << u256(argLen + 32) << u256(length) << eth::Instruction::SHA3; | ||||
| 
 | ||||
| 		returnType = dynamic_cast<MappingType const&>(*returnType).getValueType(); | ||||
| 	} | ||||
| 	if (finalMappingValueType->isDynamicallySized()) | ||||
| 	{ | ||||
| 
 | ||||
| 		if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get())) | ||||
| 		{ | ||||
| 			// move storage offset to memory.
 | ||||
| 			CompilerUtils(m_context).storeInMemory(32); | ||||
| 			//move key to memory.
 | ||||
| 			CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i, 1); | ||||
| 			CompilerUtils(m_context).storeInMemory(0); | ||||
| 			m_context << u256(64) << u256(0) << eth::Instruction::SHA3; | ||||
| 			returnType = mappingType->getValueType(); | ||||
| 		} | ||||
| 		else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get())) | ||||
| 		{ | ||||
| 			CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i + 1, 1); | ||||
| 			ArrayUtils(m_context).accessIndex(*arrayType); | ||||
| 			returnType = arrayType->getBaseType(); | ||||
| 		} | ||||
| 		else | ||||
| 			solAssert(false, "Index access is allowed only for \"mapping\" and \"array\" types."); | ||||
| 	} | ||||
| 	//remove index arguments.
 | ||||
| 	CompilerUtils(m_context).popStackSlots(paramTypes.size()); | ||||
| 
 | ||||
| 	unsigned retSizeOnStack = 0; | ||||
| 	solAssert(accessorType.getReturnParameterTypes().size() >= 1, ""); | ||||
|  | ||||
							
								
								
									
										25
									
								
								Types.cpp
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								Types.cpp
									
									
									
									
									
								
							| @ -985,11 +985,23 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): | ||||
| 	vector<string> paramNames; | ||||
| 	auto returnType = _varDecl.getType(); | ||||
| 
 | ||||
| 	while (auto mappingType = dynamic_cast<MappingType const*>(returnType.get())) | ||||
| 	while (true) | ||||
| 	{ | ||||
| 		params.push_back(mappingType->getKeyType()); | ||||
| 		paramNames.push_back(""); | ||||
| 		returnType = mappingType->getValueType(); | ||||
| 		auto mappingType = dynamic_cast<MappingType const*>(returnType.get()); | ||||
| 		auto arrayType = dynamic_cast<ArrayType const*>(returnType.get()); | ||||
| 		if (mappingType) | ||||
| 		{ | ||||
| 			params.push_back(mappingType->getKeyType()); | ||||
| 			paramNames.push_back(""); | ||||
| 			returnType = mappingType->getValueType(); | ||||
| 		} | ||||
| 		else if (arrayType) | ||||
| 		{ | ||||
| 			returnType = arrayType->getBaseType(); | ||||
| 			params.push_back(make_shared<IntegerType>(256)); | ||||
| 		} | ||||
| 		else | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	TypePointers retParams; | ||||
| @ -1002,11 +1014,6 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): | ||||
| 				retParamNames.push_back(member.first); | ||||
| 				retParams.push_back(member.second); | ||||
| 			} | ||||
| 	} else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get())) | ||||
| 	{ | ||||
| 		params.push_back(make_shared<IntegerType>(256)); | ||||
| 		paramNames.push_back(""); | ||||
| 		returnType = arrayType->getBaseType(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user