diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2017-05-20 00:06:26 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2017-09-20 17:16:23 +0800 |
commit | 3b813ed29569dde02b965c97c9fdd60469876f66 (patch) | |
tree | 20a5ea09ab0bc99d48acabb0e567affb6c381ca4 /libjulia/backends | |
parent | c0b3e5b0785efd1b601cff470d3e3d4a71b2c283 (diff) | |
download | dexon-solidity-3b813ed29569dde02b965c97c9fdd60469876f66.tar.gz dexon-solidity-3b813ed29569dde02b965c97c9fdd60469876f66.tar.zst dexon-solidity-3b813ed29569dde02b965c97c9fdd60469876f66.zip |
Support multiple assignment in inline assembly
Diffstat (limited to 'libjulia/backends')
-rw-r--r-- | libjulia/backends/evm/EVMCodeTransform.cpp | 42 | ||||
-rw-r--r-- | libjulia/backends/evm/EVMCodeTransform.h | 2 |
2 files changed, 25 insertions, 19 deletions
diff --git a/libjulia/backends/evm/EVMCodeTransform.cpp b/libjulia/backends/evm/EVMCodeTransform.cpp index e0b11cf3..e80903d5 100644 --- a/libjulia/backends/evm/EVMCodeTransform.cpp +++ b/libjulia/backends/evm/EVMCodeTransform.cpp @@ -60,16 +60,19 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl) void CodeTransform::operator()(Assignment const& _assignment) { - visitExpression(*_assignment.value); + int height = m_assembly.stackHeight(); + boost::apply_visitor(*this, *_assignment.value); + expectDeposit(_assignment.variableNames.size(), height); + m_assembly.setSourceLocation(_assignment.location); - generateAssignment(_assignment.variableName); + generateAssignment(_assignment.variableNames); checkStackHeight(&_assignment); } void CodeTransform::operator()(StackAssignment const& _assignment) { m_assembly.setSourceLocation(_assignment.location); - generateAssignment(_assignment.variableName); + generateAssignment({_assignment.variableName}); checkStackHeight(&_assignment); } @@ -469,24 +472,27 @@ void CodeTransform::finalizeBlock(Block const& _block, int blockStartStackHeight checkStackHeight(&_block); } -void CodeTransform::generateAssignment(Identifier const& _variableName) +void CodeTransform::generateAssignment(vector<Identifier> const& _variableNames) { solAssert(m_scope, ""); - auto var = m_scope->lookup(_variableName.name); - if (var) - { - Scope::Variable const& _var = boost::get<Scope::Variable>(*var); - if (int heightDiff = variableHeightDiff(_var, true)) - m_assembly.appendInstruction(solidity::swapInstruction(heightDiff - 1)); - m_assembly.appendInstruction(solidity::Instruction::POP); - } - else + for (auto const& variableName: _variableNames | boost::adaptors::reversed) { - solAssert( - m_identifierAccess.generateCode, - "Identifier not found and no external access available." - ); - m_identifierAccess.generateCode(_variableName, IdentifierContext::LValue, m_assembly); + auto var = m_scope->lookup(variableName.name); + if (var) + { + Scope::Variable const& _var = boost::get<Scope::Variable>(*var); + if (int heightDiff = variableHeightDiff(_var, true)) + m_assembly.appendInstruction(solidity::swapInstruction(heightDiff - 1)); + m_assembly.appendInstruction(solidity::Instruction::POP); + } + else + { + solAssert( + m_identifierAccess.generateCode, + "Identifier not found and no external access available." + ); + m_identifierAccess.generateCode(variableName, IdentifierContext::LValue, m_assembly); + } } } diff --git a/libjulia/backends/evm/EVMCodeTransform.h b/libjulia/backends/evm/EVMCodeTransform.h index 2c0fd10c..bb2be786 100644 --- a/libjulia/backends/evm/EVMCodeTransform.h +++ b/libjulia/backends/evm/EVMCodeTransform.h @@ -124,7 +124,7 @@ private: /// to @a _blackStartStackHeight. void finalizeBlock(solidity::assembly::Block const& _block, int _blockStartStackHeight); - void generateAssignment(solidity::assembly::Identifier const& _variableName); + void generateAssignment(std::vector<solidity::assembly::Identifier> const& _variableNames); /// Determines the stack height difference to the given variables. Throws /// if it is not yet in scope or the height difference is too large. Returns |