aboutsummaryrefslogtreecommitdiffstats
path: root/libjulia/backends/evm
diff options
context:
space:
mode:
Diffstat (limited to 'libjulia/backends/evm')
-rw-r--r--libjulia/backends/evm/EVMAssembly.cpp2
-rw-r--r--libjulia/backends/evm/EVMCodeTransform.cpp41
-rw-r--r--libjulia/backends/evm/EVMCodeTransform.h42
3 files changed, 51 insertions, 34 deletions
diff --git a/libjulia/backends/evm/EVMAssembly.cpp b/libjulia/backends/evm/EVMAssembly.cpp
index 1d499b20..07ad05c9 100644
--- a/libjulia/backends/evm/EVMAssembly.cpp
+++ b/libjulia/backends/evm/EVMAssembly.cpp
@@ -26,7 +26,7 @@
using namespace std;
using namespace dev;
-using namespace julia;
+using namespace dev::julia;
namespace
{
diff --git a/libjulia/backends/evm/EVMCodeTransform.cpp b/libjulia/backends/evm/EVMCodeTransform.cpp
index 66f593e8..f92939be 100644
--- a/libjulia/backends/evm/EVMCodeTransform.cpp
+++ b/libjulia/backends/evm/EVMCodeTransform.cpp
@@ -31,7 +31,8 @@ using namespace std;
using namespace dev;
using namespace dev::julia;
using namespace dev::solidity;
-using namespace dev::solidity::assembly;
+
+using Scope = dev::solidity::assembly::Scope;
void CodeTransform::operator()(VariableDeclaration const& _varDecl)
{
@@ -124,11 +125,11 @@ void CodeTransform::operator()(FunctionCall const& _call)
void CodeTransform::operator()(FunctionalInstruction const& _instruction)
{
if (m_evm15 && (
- _instruction.instruction.instruction == solidity::Instruction::JUMP ||
- _instruction.instruction.instruction == solidity::Instruction::JUMPI
+ _instruction.instruction == solidity::Instruction::JUMP ||
+ _instruction.instruction == solidity::Instruction::JUMPI
))
{
- bool const isJumpI = _instruction.instruction.instruction == solidity::Instruction::JUMPI;
+ bool const isJumpI = _instruction.instruction == solidity::Instruction::JUMPI;
if (isJumpI)
{
solAssert(_instruction.arguments.size() == 2, "");
@@ -149,7 +150,8 @@ void CodeTransform::operator()(FunctionalInstruction const& _instruction)
{
for (auto const& arg: _instruction.arguments | boost::adaptors::reversed)
visitExpression(arg);
- (*this)(_instruction.instruction);
+ m_assembly.setSourceLocation(_instruction.location);
+ m_assembly.appendInstruction(_instruction.instruction);
}
checkStackHeight(&_instruction);
}
@@ -217,6 +219,19 @@ void CodeTransform::operator()(assembly::Instruction const& _instruction)
checkStackHeight(&_instruction);
}
+void CodeTransform::operator()(If const& _if)
+{
+ visitExpression(*_if.condition);
+ m_assembly.setSourceLocation(_if.location);
+ m_assembly.appendInstruction(solidity::Instruction::ISZERO);
+ AbstractAssembly::LabelID end = m_assembly.newLabelId();
+ m_assembly.appendJumpToIf(end);
+ (*this)(_if.body);
+ m_assembly.setSourceLocation(_if.location);
+ m_assembly.appendLabel(end);
+ checkStackHeight(&_if);
+}
+
void CodeTransform::operator()(Switch const& _switch)
{
//@TODO use JUMPV in EVM1.5?
@@ -276,7 +291,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
solAssert(m_info.scopes.at(&_function.body), "");
Scope* varScope = m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()).get();
solAssert(varScope, "");
- for (auto const& v: _function.arguments | boost::adaptors::reversed)
+ for (auto const& v: _function.parameters | boost::adaptors::reversed)
{
auto& var = boost::get<Scope::Variable>(varScope->identifiers.at(v.name));
m_context->variableStackHeights[&var] = height++;
@@ -289,7 +304,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
if (m_evm15)
{
m_assembly.appendJumpTo(afterFunction, -stackHeightBefore);
- m_assembly.appendBeginsub(functionEntryID(_function.name, function), _function.arguments.size());
+ m_assembly.appendBeginsub(functionEntryID(_function.name, function), _function.parameters.size());
}
else
{
@@ -298,7 +313,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
}
m_stackAdjustment += localStackAdjustment;
- for (auto const& v: _function.returns)
+ for (auto const& v: _function.returnVariables)
{
auto& var = boost::get<Scope::Variable>(varScope->identifiers.at(v.name));
m_context->variableStackHeights[&var] = height++;
@@ -328,9 +343,9 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
// modified parallel to the actual stack.
vector<int> stackLayout;
if (!m_evm15)
- stackLayout.push_back(_function.returns.size()); // Move return label to the top
- stackLayout += vector<int>(_function.arguments.size(), -1); // discard all arguments
- for (size_t i = 0; i < _function.returns.size(); ++i)
+ stackLayout.push_back(_function.returnVariables.size()); // Move return label to the top
+ stackLayout += vector<int>(_function.parameters.size(), -1); // discard all arguments
+ for (size_t i = 0; i < _function.returnVariables.size(); ++i)
stackLayout.push_back(i); // Move return values down, but keep order.
solAssert(stackLayout.size() <= 17, "Stack too deep");
@@ -350,9 +365,9 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
}
if (m_evm15)
- m_assembly.appendReturnsub(_function.returns.size(), stackHeightBefore);
+ m_assembly.appendReturnsub(_function.returnVariables.size(), stackHeightBefore);
else
- m_assembly.appendJump(stackHeightBefore - _function.returns.size());
+ m_assembly.appendJump(stackHeightBefore - _function.returnVariables.size());
m_stackAdjustment -= localStackAdjustment;
m_assembly.appendLabel(afterFunction);
checkStackHeight(&_function);
diff --git a/libjulia/backends/evm/EVMCodeTransform.h b/libjulia/backends/evm/EVMCodeTransform.h
index 951c8a50..577cc8ba 100644
--- a/libjulia/backends/evm/EVMCodeTransform.h
+++ b/libjulia/backends/evm/EVMCodeTransform.h
@@ -20,8 +20,9 @@
#include <libjulia/backends/evm/EVMAssembly.h>
+#include <libjulia/ASTDataForward.h>
+
#include <libsolidity/inlineasm/AsmScope.h>
-#include <libsolidity/inlineasm/AsmDataForward.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
@@ -95,37 +96,38 @@ protected:
{}
public:
- void operator()(solidity::assembly::Instruction const& _instruction);
- void operator()(solidity::assembly::Literal const& _literal);
- void operator()(solidity::assembly::Identifier const& _identifier);
- void operator()(solidity::assembly::FunctionalInstruction const& _instr);
- void operator()(solidity::assembly::FunctionCall const&);
- void operator()(solidity::assembly::Label const& _label);
- void operator()(solidity::assembly::StackAssignment const& _assignment);
- void operator()(solidity::assembly::Assignment const& _assignment);
- void operator()(solidity::assembly::VariableDeclaration const& _varDecl);
- void operator()(solidity::assembly::Switch const& _switch);
- void operator()(solidity::assembly::FunctionDefinition const&);
- void operator()(solidity::assembly::ForLoop const&);
- void operator()(solidity::assembly::Block const& _block);
+ void operator()(Instruction const& _instruction);
+ void operator()(Literal const& _literal);
+ void operator()(Identifier const& _identifier);
+ void operator()(FunctionalInstruction const& _instr);
+ void operator()(FunctionCall const&);
+ void operator()(Label const& _label);
+ void operator()(StackAssignment const& _assignment);
+ void operator()(Assignment const& _assignment);
+ void operator()(VariableDeclaration const& _varDecl);
+ void operator()(If const& _if);
+ void operator()(Switch const& _switch);
+ void operator()(FunctionDefinition const&);
+ void operator()(ForLoop const&);
+ void operator()(Block const& _block);
private:
- AbstractAssembly::LabelID labelFromIdentifier(solidity::assembly::Identifier const& _identifier);
+ AbstractAssembly::LabelID labelFromIdentifier(Identifier const& _identifier);
/// @returns the label ID corresponding to the given label, allocating a new one if
/// necessary.
AbstractAssembly::LabelID labelID(solidity::assembly::Scope::Label const& _label);
AbstractAssembly::LabelID functionEntryID(std::string const& _name, solidity::assembly::Scope::Function const& _function);
/// Generates code for an expression that is supposed to return a single value.
- void visitExpression(solidity::assembly::Statement const& _expression);
+ void visitExpression(Statement const& _expression);
- void visitStatements(std::vector<solidity::assembly::Statement> const& _statements);
+ void visitStatements(std::vector<Statement> const& _statements);
/// Pops all variables declared in the block and checks that the stack height is equal
/// to @a _blackStartStackHeight.
- void finalizeBlock(solidity::assembly::Block const& _block, int _blockStartStackHeight);
+ void finalizeBlock(Block const& _block, int _blockStartStackHeight);
- void generateMultiAssignment(std::vector<solidity::assembly::Identifier> const& _variableNames);
- void generateAssignment(solidity::assembly::Identifier const& _variableName);
+ void generateMultiAssignment(std::vector<Identifier> const& _variableNames);
+ void generateAssignment(Identifier const& _variableName);
/// 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