From f627dc77d01a9367b41d4a2e1654f045f9e4264a Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 14 May 2018 15:26:10 +0200 Subject: Fix continue inside do-while. --- libsolidity/codegen/ContractCompiler.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 0889ac7c..f195b416 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -666,32 +666,36 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement) { StackHeightChecker checker(m_context); CompilerContext::LocationSetter locationSetter(m_context, _whileStatement); + eth::AssemblyItem loopStart = m_context.newTag(); eth::AssemblyItem loopEnd = m_context.newTag(); - m_continueTags.push_back(loopStart); m_breakTags.push_back(loopEnd); m_context << loopStart; - // While loops have the condition prepended - if (!_whileStatement.isDoWhile()) + if (_whileStatement.isDoWhile()) { - compileExpression(_whileStatement.condition()); - m_context << Instruction::ISZERO; - m_context.appendConditionalJumpTo(loopEnd); - } + eth::AssemblyItem condition = m_context.newTag(); + m_continueTags.push_back(condition); - _whileStatement.body().accept(*this); + _whileStatement.body().accept(*this); - // Do-while loops have the condition appended - if (_whileStatement.isDoWhile()) + m_context << condition; + compileExpression(_whileStatement.condition()); + m_context << Instruction::ISZERO << Instruction::ISZERO; + m_context.appendConditionalJumpTo(loopStart); + } + else { + m_continueTags.push_back(loopStart); compileExpression(_whileStatement.condition()); m_context << Instruction::ISZERO; m_context.appendConditionalJumpTo(loopEnd); - } - m_context.appendJumpTo(loopStart); + _whileStatement.body().accept(*this); + + m_context.appendJumpTo(loopStart); + } m_context << loopEnd; m_continueTags.pop_back(); -- cgit v1.2.3 From 1d57d74e82ffc032da2ce3289d878f2eee29b1b2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 12 Jun 2018 00:46:23 +0100 Subject: Fail if break/continue statements are used outside for/while loops in ContractCompiler --- libsolidity/codegen/ContractCompiler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index f195b416..81aba21e 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -749,16 +749,16 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) bool ContractCompiler::visit(Continue const& _continueStatement) { CompilerContext::LocationSetter locationSetter(m_context, _continueStatement); - if (!m_continueTags.empty()) - m_context.appendJumpTo(m_continueTags.back()); + solAssert(!m_continueTags.empty(), ""); + m_context.appendJumpTo(m_continueTags.back()); return false; } bool ContractCompiler::visit(Break const& _breakStatement) { CompilerContext::LocationSetter locationSetter(m_context, _breakStatement); - if (!m_breakTags.empty()) - m_context.appendJumpTo(m_breakTags.back()); + solAssert(!m_breakTags.empty(), ""); + m_context.appendJumpTo(m_breakTags.back()); return false; } -- cgit v1.2.3 From 1f77deada1abc9ca1e635ab13d45707e852a5628 Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Thu, 3 May 2018 16:40:33 +0200 Subject: [050] Reserving and popping local vars in their scope --- libsolidity/codegen/ContractCompiler.cpp | 104 +++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 34 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 81aba21e..def4a878 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -427,7 +427,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) m_context.startFunction(_function); // stack upon entry: [return address] [arg0] [arg1] ... [argn] - // reserve additional slots: [retarg0] ... [retargm] [localvar0] ... [localvarp] + // reserve additional slots: [retarg0] ... [retargm] unsigned parametersSize = CompilerUtils::sizeOnStack(_function.parameters()); if (!_function.isConstructor()) @@ -441,22 +441,18 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) for (ASTPointer const& variable: _function.returnParameters()) appendStackVariableInitialisation(*variable); - for (VariableDeclaration const* localVariable: _function.localVariables()) - appendStackVariableInitialisation(*localVariable); if (_function.isConstructor()) if (auto c = m_context.nextConstructor(dynamic_cast(*_function.scope()))) appendBaseConstructor(*c); - solAssert(m_returnTags.empty(), ""); m_breakTags.clear(); m_continueTags.clear(); - m_stackCleanupForReturn = 0; m_currentFunction = &_function; m_modifierDepth = -1; + m_scopeStackHeight.clear(); appendModifierOrFunctionCode(); - solAssert(m_returnTags.empty(), ""); // Now we need to re-shuffle the stack. For this we keep a record of the stack layout @@ -467,14 +463,12 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) unsigned const c_argumentsSize = CompilerUtils::sizeOnStack(_function.parameters()); unsigned const c_returnValuesSize = CompilerUtils::sizeOnStack(_function.returnParameters()); - unsigned const c_localVariablesSize = CompilerUtils::sizeOnStack(_function.localVariables()); vector stackLayout; stackLayout.push_back(c_returnValuesSize); // target of return address stackLayout += vector(c_argumentsSize, -1); // discard all arguments for (unsigned i = 0; i < c_returnValuesSize; ++i) stackLayout.push_back(i); - stackLayout += vector(c_localVariablesSize, -1); if (stackLayout.size() > 17) BOOST_THROW_EXCEPTION( @@ -493,18 +487,19 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) m_context << swapInstruction(stackLayout.size() - stackLayout.back() - 1); swap(stackLayout[stackLayout.back()], stackLayout.back()); } - //@todo assert that everything is in place now + for (int i = 0; i < int(stackLayout.size()); ++i) + if (stackLayout[i] != i) + solAssert(false, "Invalid stack layout on cleanup."); for (ASTPointer const& variable: _function.parameters() + _function.returnParameters()) m_context.removeVariable(*variable); - for (VariableDeclaration const* localVariable: _function.localVariables()) - m_context.removeVariable(*localVariable); m_context.adjustStackOffset(-(int)c_returnValuesSize); /// The constructor and the fallback function doesn't to jump out. if (!_function.isConstructor() && !_function.isFallback()) m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); + return false; } @@ -669,14 +664,16 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement) eth::AssemblyItem loopStart = m_context.newTag(); eth::AssemblyItem loopEnd = m_context.newTag(); - m_breakTags.push_back(loopEnd); + m_breakTags.push_back({loopEnd, m_context.stackHeight()}); + + visitLoop(&_whileStatement); m_context << loopStart; if (_whileStatement.isDoWhile()) { eth::AssemblyItem condition = m_context.newTag(); - m_continueTags.push_back(condition); + m_continueTags.push_back({condition, m_context.stackHeight()}); _whileStatement.body().accept(*this); @@ -687,7 +684,7 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement) } else { - m_continueTags.push_back(loopStart); + m_continueTags.push_back({loopStart, m_context.stackHeight()}); compileExpression(_whileStatement.condition()); m_context << Instruction::ISZERO; m_context.appendConditionalJumpTo(loopEnd); @@ -712,12 +709,14 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) eth::AssemblyItem loopStart = m_context.newTag(); eth::AssemblyItem loopEnd = m_context.newTag(); eth::AssemblyItem loopNext = m_context.newTag(); - m_continueTags.push_back(loopNext); - m_breakTags.push_back(loopEnd); + + visitLoop(&_forStatement); if (_forStatement.initializationExpression()) _forStatement.initializationExpression()->accept(*this); + m_breakTags.push_back({loopEnd, m_context.stackHeight()}); + m_continueTags.push_back({loopNext, m_context.stackHeight()}); m_context << loopStart; // if there is no terminating condition in for, default is to always be true @@ -737,11 +736,16 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) _forStatement.loopExpression()->accept(*this); m_context.appendJumpTo(loopStart); + m_context << loopEnd; m_continueTags.pop_back(); m_breakTags.pop_back(); + // For the case where no break/return is executed: + // loop initialization variables have to be freed + popScopedVariables(&_forStatement); + checker.check(); return false; } @@ -750,7 +754,7 @@ bool ContractCompiler::visit(Continue const& _continueStatement) { CompilerContext::LocationSetter locationSetter(m_context, _continueStatement); solAssert(!m_continueTags.empty(), ""); - m_context.appendJumpTo(m_continueTags.back()); + popAndJump(m_context.stackHeight() - m_continueTags.back().second, m_continueTags.back().first); return false; } @@ -758,7 +762,7 @@ bool ContractCompiler::visit(Break const& _breakStatement) { CompilerContext::LocationSetter locationSetter(m_context, _breakStatement); solAssert(!m_breakTags.empty(), ""); - m_context.appendJumpTo(m_breakTags.back()); + popAndJump(m_context.stackHeight() - m_breakTags.back().second, m_breakTags.back().first); return false; } @@ -784,10 +788,8 @@ bool ContractCompiler::visit(Return const& _return) for (auto const& retVariable: boost::adaptors::reverse(returnParameters)) CompilerUtils(m_context).moveToStackVariable(*retVariable); } - for (unsigned i = 0; i < m_stackCleanupForReturn; ++i) - m_context << Instruction::POP; - m_context.appendJumpTo(m_returnTags.back()); - m_context.adjustStackOffset(m_stackCleanupForReturn); + + popAndJump(m_context.stackHeight() - m_returnTags.back().second, m_returnTags.back().first); return false; } @@ -810,8 +812,15 @@ bool ContractCompiler::visit(EmitStatement const& _emit) bool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement) { - StackHeightChecker checker(m_context); CompilerContext::LocationSetter locationSetter(m_context, _variableDeclarationStatement); + + // Local variable slots are reserved when their declaration is visited, + // and freed in the end of their scope. + for (auto _decl: _variableDeclarationStatement.declarations()) + if (_decl) + appendStackVariableInitialisation(*_decl); + + StackHeightChecker checker(m_context); if (Expression const* expression = _variableDeclarationStatement.initialValue()) { CompilerUtils utils(m_context); @@ -861,6 +870,18 @@ bool ContractCompiler::visit(PlaceholderStatement const& _placeholderStatement) return true; } +bool ContractCompiler::visit(Block const& _block) +{ + m_scopeStackHeight[m_modifierDepth][&_block] = m_context.stackHeight(); + return true; +} + +void ContractCompiler::endVisit(Block const& _block) +{ + // Frees local variables declared in the scope of this block. + popScopedVariables(&_block); +} + void ContractCompiler::appendMissingFunctions() { while (Declaration const* function = m_context.nextFunctionToCompile()) @@ -916,27 +937,19 @@ void ContractCompiler::appendModifierOrFunctionCode() modifier.parameters()[i]->annotation().type ); } - for (VariableDeclaration const* localVariable: modifier.localVariables()) - { - addedVariables.push_back(localVariable); - appendStackVariableInitialisation(*localVariable); - } - stackSurplus = - CompilerUtils::sizeOnStack(modifier.parameters()) + - CompilerUtils::sizeOnStack(modifier.localVariables()); + stackSurplus = CompilerUtils::sizeOnStack(modifier.parameters()); codeBlock = &modifier.body(); } } if (codeBlock) { - m_returnTags.push_back(m_context.newTag()); - + m_returnTags.push_back({m_context.newTag(), m_context.stackHeight()}); codeBlock->accept(*this); solAssert(!m_returnTags.empty(), ""); - m_context << m_returnTags.back(); + m_context << m_returnTags.back().first; m_returnTags.pop_back(); CompilerUtils(m_context).popStackSlots(stackSurplus); @@ -983,3 +996,26 @@ eth::AssemblyPointer ContractCompiler::cloneRuntime() const a << u256(0x20) << u256(0) << Instruction::RETURN; return make_shared(a); } + +void ContractCompiler::popScopedVariables(ASTNode const* _node) +{ + unsigned blockHeight = m_scopeStackHeight[m_modifierDepth][_node]; + unsigned stackDiff = m_context.stackHeight() - blockHeight; + CompilerUtils(m_context).popStackSlots(stackDiff); + m_context.removeVariablesAboveStackHeight(blockHeight); + m_scopeStackHeight[m_modifierDepth].erase(_node); + if (m_scopeStackHeight[m_modifierDepth].size() == 0) + m_scopeStackHeight.erase(m_modifierDepth); +} + +void ContractCompiler::visitLoop(BreakableStatement const* _loop) +{ + m_scopeStackHeight[m_modifierDepth][_loop] = m_context.stackHeight(); +} + +void ContractCompiler::popAndJump(unsigned _amount, eth::AssemblyItem const& _jumpTo) +{ + CompilerUtils(m_context).popStackSlots(_amount); + m_context.appendJumpTo(_jumpTo); + m_context.adjustStackOffset(_amount); +} -- cgit v1.2.3 From 9d895e002d0e5e1e3435d03ac82277caa397bbec Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Wed, 4 Jul 2018 14:14:41 +0200 Subject: Added tests and review suggestions --- libsolidity/codegen/ContractCompiler.cpp | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index def4a878..474d2b68 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -446,6 +446,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) if (auto c = m_context.nextConstructor(dynamic_cast(*_function.scope()))) appendBaseConstructor(*c); + solAssert(m_returnTags.empty(), ""); m_breakTags.clear(); m_continueTags.clear(); m_currentFunction = &_function; @@ -666,8 +667,6 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement) eth::AssemblyItem loopEnd = m_context.newTag(); m_breakTags.push_back({loopEnd, m_context.stackHeight()}); - visitLoop(&_whileStatement); - m_context << loopStart; if (_whileStatement.isDoWhile()) @@ -710,7 +709,7 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) eth::AssemblyItem loopEnd = m_context.newTag(); eth::AssemblyItem loopNext = m_context.newTag(); - visitLoop(&_forStatement); + storeStackHeight(&_forStatement); if (_forStatement.initializationExpression()) _forStatement.initializationExpression()->accept(*this); @@ -754,7 +753,7 @@ bool ContractCompiler::visit(Continue const& _continueStatement) { CompilerContext::LocationSetter locationSetter(m_context, _continueStatement); solAssert(!m_continueTags.empty(), ""); - popAndJump(m_context.stackHeight() - m_continueTags.back().second, m_continueTags.back().first); + CompilerUtils(m_context).popAndJump(m_continueTags.back().second, m_continueTags.back().first); return false; } @@ -762,7 +761,7 @@ bool ContractCompiler::visit(Break const& _breakStatement) { CompilerContext::LocationSetter locationSetter(m_context, _breakStatement); solAssert(!m_breakTags.empty(), ""); - popAndJump(m_context.stackHeight() - m_breakTags.back().second, m_breakTags.back().first); + CompilerUtils(m_context).popAndJump(m_breakTags.back().second, m_breakTags.back().first); return false; } @@ -789,7 +788,7 @@ bool ContractCompiler::visit(Return const& _return) CompilerUtils(m_context).moveToStackVariable(*retVariable); } - popAndJump(m_context.stackHeight() - m_returnTags.back().second, m_returnTags.back().first); + CompilerUtils(m_context).popAndJump(m_returnTags.back().second, m_returnTags.back().first); return false; } @@ -872,7 +871,7 @@ bool ContractCompiler::visit(PlaceholderStatement const& _placeholderStatement) bool ContractCompiler::visit(Block const& _block) { - m_scopeStackHeight[m_modifierDepth][&_block] = m_context.stackHeight(); + storeStackHeight(&_block); return true; } @@ -999,7 +998,7 @@ eth::AssemblyPointer ContractCompiler::cloneRuntime() const void ContractCompiler::popScopedVariables(ASTNode const* _node) { - unsigned blockHeight = m_scopeStackHeight[m_modifierDepth][_node]; + unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node); unsigned stackDiff = m_context.stackHeight() - blockHeight; CompilerUtils(m_context).popStackSlots(stackDiff); m_context.removeVariablesAboveStackHeight(blockHeight); @@ -1008,14 +1007,7 @@ void ContractCompiler::popScopedVariables(ASTNode const* _node) m_scopeStackHeight.erase(m_modifierDepth); } -void ContractCompiler::visitLoop(BreakableStatement const* _loop) -{ - m_scopeStackHeight[m_modifierDepth][_loop] = m_context.stackHeight(); -} - -void ContractCompiler::popAndJump(unsigned _amount, eth::AssemblyItem const& _jumpTo) +void ContractCompiler::storeStackHeight(ASTNode const* _node) { - CompilerUtils(m_context).popStackSlots(_amount); - m_context.appendJumpTo(_jumpTo); - m_context.adjustStackOffset(_amount); + m_scopeStackHeight[m_modifierDepth][_node] = m_context.stackHeight(); } -- cgit v1.2.3 From b750ca9741aba47cc8ba650a04dd620725ed4610 Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Fri, 6 Jul 2018 09:56:27 +0200 Subject: Add more tests and assertions --- libsolidity/codegen/ContractCompiler.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 474d2b68..207e0af7 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -999,6 +999,7 @@ eth::AssemblyPointer ContractCompiler::cloneRuntime() const void ContractCompiler::popScopedVariables(ASTNode const* _node) { unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node); + solAssert(m_context.stackHeight() >= blockHeight, ""); unsigned stackDiff = m_context.stackHeight() - blockHeight; CompilerUtils(m_context).popStackSlots(stackDiff); m_context.removeVariablesAboveStackHeight(blockHeight); -- cgit v1.2.3 From 0c5e0e0d59dc55fcfe5b95a8c649a7a769ad3400 Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Tue, 10 Jul 2018 18:39:26 +0200 Subject: Added assertion and tests suggestions --- libsolidity/codegen/ContractCompiler.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 207e0af7..93f698bc 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -498,8 +498,12 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) m_context.adjustStackOffset(-(int)c_returnValuesSize); /// The constructor and the fallback function doesn't to jump out. - if (!_function.isConstructor() && !_function.isFallback()) - m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); + if (!_function.isConstructor()) + { + solAssert(m_context.numberOfLocalVariables() == 0, ""); + if (!_function.isFallback()) + m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); + } return false; } @@ -999,10 +1003,10 @@ eth::AssemblyPointer ContractCompiler::cloneRuntime() const void ContractCompiler::popScopedVariables(ASTNode const* _node) { unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node); + m_context.removeVariablesAboveStackHeight(blockHeight); solAssert(m_context.stackHeight() >= blockHeight, ""); unsigned stackDiff = m_context.stackHeight() - blockHeight; CompilerUtils(m_context).popStackSlots(stackDiff); - m_context.removeVariablesAboveStackHeight(blockHeight); m_scopeStackHeight[m_modifierDepth].erase(_node); if (m_scopeStackHeight[m_modifierDepth].size() == 0) m_scopeStackHeight.erase(m_modifierDepth); -- cgit v1.2.3 From fc370591f02d2bcfe52b62776a871b33e933bd34 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 4 Jul 2018 18:34:24 +0200 Subject: Disallow multi variable declarations with mismatching number of values. --- libsolidity/codegen/ContractCompiler.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 93f698bc..bbb3db3d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -833,20 +833,19 @@ bool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclar valueTypes = tupleType->components(); else valueTypes = TypePointers{expression->annotation().type}; - auto const& assignments = _variableDeclarationStatement.annotation().assignments; - solAssert(assignments.size() == valueTypes.size(), ""); - for (size_t i = 0; i < assignments.size(); ++i) + auto const& declarations = _variableDeclarationStatement.declarations(); + solAssert(declarations.size() == valueTypes.size(), ""); + for (size_t i = 0; i < declarations.size(); ++i) { - size_t j = assignments.size() - i - 1; + size_t j = declarations.size() - i - 1; solAssert(!!valueTypes[j], ""); - VariableDeclaration const* varDecl = assignments[j]; - if (!varDecl) - utils.popStackElement(*valueTypes[j]); - else + if (VariableDeclaration const* varDecl = declarations[j].get()) { utils.convertType(*valueTypes[j], *varDecl->annotation().type); utils.moveToStackVariable(*varDecl); } + else + utils.popStackElement(*valueTypes[j]); } } checker.check(); -- cgit v1.2.3 From f74cff622dd0eb8d4e64c014731e00fb9ea1d078 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 19 Jun 2018 19:30:38 +0200 Subject: Properly explain all the analsys steps in CompilerStack --- libsolidity/codegen/ContractCompiler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index bbb3db3d..2f15a33d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -71,7 +71,11 @@ void ContractCompiler::compileContract( appendDelegatecallCheck(); initializeContext(_contract, _contracts); + // This generates the dispatch function for externally visible functions + // and adds the function to the compilation queue. Additionally internal functions, + // which are referenced directly or indirectly will be added. appendFunctionSelector(_contract); + // This processes the above populated queue until it is empty. appendMissingFunctions(); } -- cgit v1.2.3 From 71e26f6adb7d6b28400a6607570bb1e17da24feb Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 6 Aug 2018 18:32:18 +0200 Subject: Remove clone feature. --- libsolidity/codegen/ContractCompiler.cpp | 44 -------------------------------- 1 file changed, 44 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 2f15a33d..f9493d6d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -94,27 +94,6 @@ size_t ContractCompiler::compileConstructor( } } -size_t ContractCompiler::compileClone( - ContractDefinition const& _contract, - map const& _contracts -) -{ - initializeContext(_contract, _contracts); - - appendInitAndConstructorCode(_contract); - - //@todo determine largest return size of all runtime functions - auto runtimeSub = m_context.addSubroutine(cloneRuntime()); - - // stack contains sub size - m_context << Instruction::DUP1 << runtimeSub << u256(0) << Instruction::CODECOPY; - m_context << u256(0) << Instruction::RETURN; - - appendMissingFunctions(); - - return size_t(runtimeSub.data()); -} - void ContractCompiler::initializeContext( ContractDefinition const& _contract, map const& _compiledContracts @@ -980,29 +959,6 @@ void ContractCompiler::compileExpression(Expression const& _expression, TypePoin CompilerUtils(m_context).convertType(*_expression.annotation().type, *_targetType); } -eth::AssemblyPointer ContractCompiler::cloneRuntime() const -{ - eth::Assembly a; - a << Instruction::CALLDATASIZE; - a << u256(0) << Instruction::DUP1 << Instruction::CALLDATACOPY; - //@todo adjust for larger return values, make this dynamic. - a << u256(0x20) << u256(0) << Instruction::CALLDATASIZE; - a << u256(0); - // this is the address which has to be substituted by the linker. - //@todo implement as special "marker" AssemblyItem. - a << u256("0xcafecafecafecafecafecafecafecafecafecafe"); - a << u256(eth::GasCosts::callGas(m_context.evmVersion()) + 10) << Instruction::GAS << Instruction::SUB; - a << Instruction::DELEGATECALL; - //Propagate error condition (if DELEGATECALL pushes 0 on stack). - a << Instruction::ISZERO; - a << Instruction::ISZERO; - eth::AssemblyItem afterTag = a.appendJumpI().tag(); - a << Instruction::INVALID << afterTag; - //@todo adjust for larger return values, make this dynamic. - a << u256(0x20) << u256(0) << Instruction::RETURN; - return make_shared(a); -} - void ContractCompiler::popScopedVariables(ASTNode const* _node) { unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node); -- cgit v1.2.3 From e902ce1aa02dc5d19cc9dd231fa538646884826d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Aereal=20Ae=C3=B3n?= Date: Wed, 8 Aug 2018 11:26:30 -0300 Subject: Removing std:: from std::to_string and include for boost/lexical_cast --- libsolidity/codegen/ContractCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 2f15a33d..2fffcf76 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -50,7 +50,7 @@ class StackHeightChecker public: explicit StackHeightChecker(CompilerContext const& _context): m_context(_context), stackHeight(m_context.stackHeight()) {} - void check() { solAssert(m_context.stackHeight() == stackHeight, std::string("I sense a disturbance in the stack: ") + std::to_string(m_context.stackHeight()) + " vs " + std::to_string(stackHeight)); } + void check() { solAssert(m_context.stackHeight() == stackHeight, std::string("I sense a disturbance in the stack: ") + to_string(m_context.stackHeight()) + " vs " + to_string(stackHeight)); } private: CompilerContext const& m_context; unsigned stackHeight; -- cgit v1.2.3 From a9819aa8bc68a35414aaa280d829018669ec770f Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 7 Aug 2018 23:38:08 +0100 Subject: Remove code generation for Throw statement It is disallowed in the type system. --- libsolidity/codegen/ContractCompiler.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 02274d60..e26bc13a 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -779,11 +779,9 @@ bool ContractCompiler::visit(Return const& _return) return false; } -bool ContractCompiler::visit(Throw const& _throw) +bool ContractCompiler::visit(Throw const&) { - CompilerContext::LocationSetter locationSetter(m_context, _throw); - // Do not send back an error detail. - m_context.appendRevert(); + solAssert(false, "Throw statement is disallowed."); return false; } -- cgit v1.2.3 From fa0ce6a7e7abd5bbc9bad1dd15f54ea4e9b11f85 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 9 Oct 2018 04:29:37 +0100 Subject: Use empty() instead of size() == 0 --- libsolidity/codegen/ContractCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index e26bc13a..3a0fccfb 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -965,7 +965,7 @@ void ContractCompiler::popScopedVariables(ASTNode const* _node) unsigned stackDiff = m_context.stackHeight() - blockHeight; CompilerUtils(m_context).popStackSlots(stackDiff); m_scopeStackHeight[m_modifierDepth].erase(_node); - if (m_scopeStackHeight[m_modifierDepth].size() == 0) + if (m_scopeStackHeight[m_modifierDepth].empty()) m_scopeStackHeight.erase(m_modifierDepth); } -- cgit v1.2.3 From 1304361b9c48438d5c55903492b5f11c3dac73e5 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 15 Oct 2018 11:58:51 +0200 Subject: Renaming namespace dev::julia to dev::yul. --- libsolidity/codegen/ContractCompiler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 3a0fccfb..c845da8f 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -494,21 +494,21 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) { unsigned startStackHeight = m_context.stackHeight(); - julia::ExternalIdentifierAccess identifierAccess; - identifierAccess.resolve = [&](assembly::Identifier const& _identifier, julia::IdentifierContext, bool) + yul::ExternalIdentifierAccess identifierAccess; + identifierAccess.resolve = [&](assembly::Identifier const& _identifier, yul::IdentifierContext, bool) { auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier); if (ref == _inlineAssembly.annotation().externalReferences.end()) return size_t(-1); return ref->second.valueSize; }; - identifierAccess.generateCode = [&](assembly::Identifier const& _identifier, julia::IdentifierContext _context, julia::AbstractAssembly& _assembly) + identifierAccess.generateCode = [&](assembly::Identifier const& _identifier, yul::IdentifierContext _context, yul::AbstractAssembly& _assembly) { auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier); solAssert(ref != _inlineAssembly.annotation().externalReferences.end(), ""); Declaration const* decl = ref->second.declaration; solAssert(!!decl, ""); - if (_context == julia::IdentifierContext::RValue) + if (_context == yul::IdentifierContext::RValue) { int const depositBefore = _assembly.stackHeight(); solAssert(!!decl->type(), "Type of declaration required but not yet determined."); -- cgit v1.2.3 From 5e01d767d02d064a064a67dcf95ee299c46f741f Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 17 Jan 2018 12:05:43 +0100 Subject: Prevent externally used functions from being removed. --- libsolidity/codegen/ContractCompiler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index c845da8f..1fdf3483 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -874,9 +874,9 @@ void ContractCompiler::appendMissingFunctions() solAssert(m_context.nextFunctionToCompile() != function, "Compiled the wrong function?"); } m_context.appendMissingLowLevelFunctions(); - string abiFunctions = m_context.abiFunctions().requestedFunctions(); - if (!abiFunctions.empty()) - m_context.appendInlineAssembly("{" + move(abiFunctions) + "}", {}, true); + auto abiFunctions = m_context.abiFunctions().requestedFunctions(); + if (!abiFunctions.first.empty()) + m_context.appendInlineAssembly("{" + move(abiFunctions.first) + "}", {}, abiFunctions.second, true); } void ContractCompiler::appendModifierOrFunctionCode() -- cgit v1.2.3