mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Store stack height in analysis phase.
This commit is contained in:
		
							parent
							
								
									a46a059e3a
								
							
						
					
					
						commit
						68218387cf
					
				| @ -41,9 +41,10 @@ using namespace dev::solidity::assembly; | |||||||
| AsmAnalyzer::AsmAnalyzer( | AsmAnalyzer::AsmAnalyzer( | ||||||
| 	AsmAnalyzer::Scopes& _scopes, | 	AsmAnalyzer::Scopes& _scopes, | ||||||
| 	ErrorList& _errors, | 	ErrorList& _errors, | ||||||
| 	ExternalIdentifierAccess::Resolver const& _resolver | 	ExternalIdentifierAccess::Resolver const& _resolver, | ||||||
|  | 	StackHeightInfo* _stackHeightInfo | ||||||
| ): | ): | ||||||
| 	m_resolver(_resolver), m_scopes(_scopes), m_errors(_errors) | 	m_resolver(_resolver), m_scopes(_scopes), m_errors(_errors), m_stackHeightInfo(_stackHeightInfo) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -55,10 +56,16 @@ bool AsmAnalyzer::analyze(Block const& _block) | |||||||
| 	return (*this)(_block); | 	return (*this)(_block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool AsmAnalyzer::operator()(const Label& _label) | ||||||
|  | { | ||||||
|  | 	storeStackHeight(_label); return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) | bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) | ||||||
| { | { | ||||||
| 	auto const& info = instructionInfo(_instruction.instruction); | 	auto const& info = instructionInfo(_instruction.instruction); | ||||||
| 	m_stackHeight += info.ret - info.args; | 	m_stackHeight += info.ret - info.args; | ||||||
|  | 	storeStackHeight(_instruction); | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -74,6 +81,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal) | |||||||
| 		)); | 		)); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  | 	storeStackHeight(_literal); | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -129,6 +137,7 @@ bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier) | |||||||
| 		} | 		} | ||||||
| 		m_stackHeight += stackSize == size_t(-1) ? 1 : stackSize; | 		m_stackHeight += stackSize == size_t(-1) ? 1 : stackSize; | ||||||
| 	} | 	} | ||||||
|  | 	storeStackHeight(_identifier); | ||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -147,14 +156,18 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) | |||||||
| 	solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), ""); | 	solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), ""); | ||||||
| 	if (!(*this)(_instr.instruction)) | 	if (!(*this)(_instr.instruction)) | ||||||
| 		success = false; | 		success = false; | ||||||
|  | 	storeStackHeight(_instr); | ||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment) | bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment) | ||||||
| { | { | ||||||
| 	return checkAssignment(_assignment.variableName, size_t(-1)); | 	bool success = checkAssignment(_assignment.variableName, size_t(-1)); | ||||||
|  | 	storeStackHeight(_assignment); | ||||||
|  | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment) | bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment) | ||||||
| { | { | ||||||
| 	int const stackHeight = m_stackHeight; | 	int const stackHeight = m_stackHeight; | ||||||
| @ -162,6 +175,7 @@ bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment) | |||||||
| 	solAssert(m_stackHeight >= stackHeight, "Negative value size."); | 	solAssert(m_stackHeight >= stackHeight, "Negative value size."); | ||||||
| 	if (!checkAssignment(_assignment.variableName, m_stackHeight - stackHeight)) | 	if (!checkAssignment(_assignment.variableName, m_stackHeight - stackHeight)) | ||||||
| 		success = false; | 		success = false; | ||||||
|  | 	storeStackHeight(_assignment); | ||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -171,6 +185,7 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl) | |||||||
| 	bool success = boost::apply_visitor(*this, *_varDecl.value); | 	bool success = boost::apply_visitor(*this, *_varDecl.value); | ||||||
| 	solAssert(m_stackHeight - stackHeight == 1, "Invalid value size."); | 	solAssert(m_stackHeight - stackHeight == 1, "Invalid value size."); | ||||||
| 	boost::get<Scope::Variable>(m_currentScope->identifiers.at(_varDecl.name)).active = true; | 	boost::get<Scope::Variable>(m_currentScope->identifiers.at(_varDecl.name)).active = true; | ||||||
|  | 	storeStackHeight(_varDecl); | ||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -187,6 +202,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef) | |||||||
| 	bool success = (*this)(_funDef.body); | 	bool success = (*this)(_funDef.body); | ||||||
| 
 | 
 | ||||||
| 	m_stackHeight = stackHeight; | 	m_stackHeight = stackHeight; | ||||||
|  | 	storeStackHeight(_funDef); | ||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -253,6 +269,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall) | |||||||
| 			success = false; | 			success = false; | ||||||
| 	} | 	} | ||||||
| 	m_stackHeight += int(returns) - int(arguments); | 	m_stackHeight += int(returns) - int(arguments); | ||||||
|  | 	storeStackHeight(_funCall); | ||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -289,6 +306,7 @@ bool AsmAnalyzer::operator()(Block const& _block) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	m_currentScope = m_currentScope->superScope; | 	m_currentScope = m_currentScope->superScope; | ||||||
|  | 	storeStackHeight(_block); | ||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -354,6 +372,12 @@ bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t | |||||||
| 	return success; | 	return success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void AsmAnalyzer::storeStackHeight(const assembly::Statement& _statement) | ||||||
|  | { | ||||||
|  | 	if (m_stackHeightInfo) | ||||||
|  | 		(*m_stackHeightInfo)[&_statement] = m_stackHeight; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, SourceLocation const& _location) | bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, SourceLocation const& _location) | ||||||
| { | { | ||||||
| 	int stackDiff = m_stackHeight - _oldHeight; | 	int stackDiff = m_stackHeight - _oldHeight; | ||||||
|  | |||||||
| @ -50,6 +50,9 @@ struct FunctionCall; | |||||||
| 
 | 
 | ||||||
| struct Scope; | struct Scope; | ||||||
| 
 | 
 | ||||||
|  | using Statement = boost::variant<Instruction, Literal, Label, Assignment, Identifier, FunctionalAssignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>; | ||||||
|  | using StackHeightInfo = std::map<assembly::Statement const*, int>; | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Performs the full analysis stage, calls the ScopeFiller internally, then resolves |  * Performs the full analysis stage, calls the ScopeFiller internally, then resolves | ||||||
|  * references and performs other checks. |  * references and performs other checks. | ||||||
| @ -62,7 +65,8 @@ public: | |||||||
| 	AsmAnalyzer( | 	AsmAnalyzer( | ||||||
| 		Scopes& _scopes, | 		Scopes& _scopes, | ||||||
| 		ErrorList& _errors, | 		ErrorList& _errors, | ||||||
| 		ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver() | 		ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver(), | ||||||
|  | 		StackHeightInfo* _stackHeightInfo = nullptr | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	bool analyze(assembly::Block const& _block); | 	bool analyze(assembly::Block const& _block); | ||||||
| @ -71,7 +75,7 @@ public: | |||||||
| 	bool operator()(assembly::Literal const& _literal); | 	bool operator()(assembly::Literal const& _literal); | ||||||
| 	bool operator()(assembly::Identifier const&); | 	bool operator()(assembly::Identifier const&); | ||||||
| 	bool operator()(assembly::FunctionalInstruction const& _functionalInstruction); | 	bool operator()(assembly::FunctionalInstruction const& _functionalInstruction); | ||||||
| 	bool operator()(assembly::Label const&) { return true; } | 	bool operator()(assembly::Label const& _label); | ||||||
| 	bool operator()(assembly::Assignment const&); | 	bool operator()(assembly::Assignment const&); | ||||||
| 	bool operator()(assembly::FunctionalAssignment const& _functionalAssignment); | 	bool operator()(assembly::FunctionalAssignment const& _functionalAssignment); | ||||||
| 	bool operator()(assembly::VariableDeclaration const& _variableDeclaration); | 	bool operator()(assembly::VariableDeclaration const& _variableDeclaration); | ||||||
| @ -84,6 +88,7 @@ private: | |||||||
| 	/// as the value, @a _valueSize, unless that is equal to -1.
 | 	/// as the value, @a _valueSize, unless that is equal to -1.
 | ||||||
| 	bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1)); | 	bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1)); | ||||||
| 	bool expectDeposit(int _deposit, int _oldHeight, SourceLocation const& _location); | 	bool expectDeposit(int _deposit, int _oldHeight, SourceLocation const& _location); | ||||||
|  | 	void storeStackHeight(assembly::Statement const& _statement); | ||||||
| 	Scope& scope(assembly::Block const* _block); | 	Scope& scope(assembly::Block const* _block); | ||||||
| 
 | 
 | ||||||
| 	/// This is used when we enter the body of a function definition. There, the parameters
 | 	/// This is used when we enter the body of a function definition. There, the parameters
 | ||||||
| @ -95,6 +100,7 @@ private: | |||||||
| 	Scope* m_currentScope = nullptr; | 	Scope* m_currentScope = nullptr; | ||||||
| 	Scopes& m_scopes; | 	Scopes& m_scopes; | ||||||
| 	ErrorList& m_errors; | 	ErrorList& m_errors; | ||||||
|  | 	StackHeightInfo* m_stackHeightInfo; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user