aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Compiler.cpp32
-rw-r--r--CompilerContext.cpp36
-rw-r--r--CompilerContext.h19
-rw-r--r--ExpressionCompiler.cpp18
4 files changed, 45 insertions, 60 deletions
diff --git a/Compiler.cpp b/Compiler.cpp
index 5eeb0c3e..7ff846bd 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -132,7 +132,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
void Compiler::appendBaseConstructor(FunctionDefinition const& _constructor)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_constructor);
+ CompilerContext::LocationSetter locationSetter(m_context, _constructor);
FunctionType constructorType(_constructor);
if (!constructorType.getParameterTypes().empty())
{
@@ -146,7 +146,7 @@ void Compiler::appendBaseConstructor(FunctionDefinition const& _constructor)
void Compiler::appendConstructor(FunctionDefinition const& _constructor)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_constructor);
+ CompilerContext::LocationSetter locationSetter(m_context, _constructor);
// copy constructor arguments from code to memory and then to stack, they are supplied after the actual program
unsigned argumentSize = 0;
for (ASTPointer<VariableDeclaration> const& var: _constructor.getParameters())
@@ -192,10 +192,12 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
for (auto const& it: interfaceFunctions)
{
FunctionTypePointer const& functionType = it.second;
+ solAssert(functionType->hasDeclaration(), "");
+ CompilerContext::LocationSetter locationSetter(m_context, functionType->getDeclaration());
m_context << callDataUnpackerEntryPoints.at(it.first);
eth::AssemblyItem returnTag = m_context.pushNewTag();
appendCalldataUnpacker(functionType->getParameterTypes());
- m_context.appendJumpTo(m_context.getFunctionEntryLabel(it.second->getDeclaration()));
+ m_context.appendJumpTo(m_context.getFunctionEntryLabel(functionType->getDeclaration()));
m_context << returnTag;
appendReturnValuePacker(functionType->getReturnParameterTypes());
}
@@ -286,7 +288,7 @@ void Compiler::initializeStateVariables(ContractDefinition const& _contract)
bool Compiler::visit(VariableDeclaration const& _variableDeclaration)
{
solAssert(_variableDeclaration.isStateVariable(), "Compiler visit to non-state variable declaration.");
- CompilerContext::LocationSetter locationSetter(m_context, &_variableDeclaration);
+ CompilerContext::LocationSetter locationSetter(m_context, _variableDeclaration);
m_context.startFunction(_variableDeclaration);
m_breakTags.clear();
@@ -300,7 +302,7 @@ bool Compiler::visit(VariableDeclaration const& _variableDeclaration)
bool Compiler::visit(FunctionDefinition const& _function)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_function);
+ CompilerContext::LocationSetter locationSetter(m_context, _function);
//@todo to simplify this, the calling convention could by changed such that
// caller puts: [retarg0] ... [retargm] [return address] [arg0] ... [argn]
// although note that this reduces the size of the visible stack
@@ -384,7 +386,7 @@ bool Compiler::visit(FunctionDefinition const& _function)
bool Compiler::visit(IfStatement const& _ifStatement)
{
StackHeightChecker checker(m_context);
- CompilerContext::LocationSetter locationSetter(m_context, &_ifStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _ifStatement);
compileExpression(_ifStatement.getCondition());
eth::AssemblyItem trueTag = m_context.appendConditionalJump();
if (_ifStatement.getFalseStatement())
@@ -401,7 +403,7 @@ bool Compiler::visit(IfStatement const& _ifStatement)
bool Compiler::visit(WhileStatement const& _whileStatement)
{
StackHeightChecker checker(m_context);
- CompilerContext::LocationSetter locationSetter(m_context, &_whileStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _whileStatement);
eth::AssemblyItem loopStart = m_context.newTag();
eth::AssemblyItem loopEnd = m_context.newTag();
m_continueTags.push_back(loopStart);
@@ -427,7 +429,7 @@ bool Compiler::visit(WhileStatement const& _whileStatement)
bool Compiler::visit(ForStatement const& _forStatement)
{
StackHeightChecker checker(m_context);
- CompilerContext::LocationSetter locationSetter(m_context, &_forStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _forStatement);
eth::AssemblyItem loopStart = m_context.newTag();
eth::AssemblyItem loopEnd = m_context.newTag();
m_continueTags.push_back(loopStart);
@@ -464,7 +466,7 @@ bool Compiler::visit(ForStatement const& _forStatement)
bool Compiler::visit(Continue const& _continueStatement)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_continueStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _continueStatement);
if (!m_continueTags.empty())
m_context.appendJumpTo(m_continueTags.back());
return false;
@@ -472,7 +474,7 @@ bool Compiler::visit(Continue const& _continueStatement)
bool Compiler::visit(Break const& _breakStatement)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_breakStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _breakStatement);
if (!m_breakTags.empty())
m_context.appendJumpTo(m_breakTags.back());
return false;
@@ -480,7 +482,7 @@ bool Compiler::visit(Break const& _breakStatement)
bool Compiler::visit(Return const& _return)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_return);
+ CompilerContext::LocationSetter locationSetter(m_context, _return);
//@todo modifications are needed to make this work with functions returning multiple values
if (Expression const* expression = _return.getExpression())
{
@@ -499,7 +501,7 @@ bool Compiler::visit(Return const& _return)
bool Compiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement)
{
StackHeightChecker checker(m_context);
- CompilerContext::LocationSetter locationSetter(m_context, &_variableDeclarationStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _variableDeclarationStatement);
if (Expression const* expression = _variableDeclarationStatement.getExpression())
{
compileExpression(*expression, _variableDeclarationStatement.getDeclaration().getType());
@@ -512,7 +514,7 @@ bool Compiler::visit(VariableDeclarationStatement const& _variableDeclarationSta
bool Compiler::visit(ExpressionStatement const& _expressionStatement)
{
StackHeightChecker checker(m_context);
- CompilerContext::LocationSetter locationSetter(m_context, &_expressionStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _expressionStatement);
Expression const& expression = _expressionStatement.getExpression();
compileExpression(expression);
CompilerUtils(m_context).popStackElement(*expression.getType());
@@ -523,7 +525,7 @@ bool Compiler::visit(ExpressionStatement const& _expressionStatement)
bool Compiler::visit(PlaceholderStatement const& _placeholderStatement)
{
StackHeightChecker checker(m_context);
- CompilerContext::LocationSetter locationSetter(m_context, &_placeholderStatement);
+ CompilerContext::LocationSetter locationSetter(m_context, _placeholderStatement);
++m_modifierDepth;
appendModifierOrFunctionCode();
--m_modifierDepth;
@@ -550,7 +552,7 @@ void Compiler::appendModifierOrFunctionCode()
}
ModifierDefinition const& modifier = m_context.getFunctionModifier(modifierInvocation->getName()->getName());
- CompilerContext::LocationSetter locationSetter(m_context, &modifier);
+ CompilerContext::LocationSetter locationSetter(m_context, modifier);
solAssert(modifier.getParameters().size() == modifierInvocation->getArguments().size(), "");
for (unsigned i = 0; i < modifier.getParameters().size(); ++i)
{
diff --git a/CompilerContext.cpp b/CompilerContext.cpp
index ee8d3e00..1dea62e9 100644
--- a/CompilerContext.cpp
+++ b/CompilerContext.cpp
@@ -69,7 +69,7 @@ void CompilerContext::removeVariable(VariableDeclaration const& _declaration)
void CompilerContext::addAndInitializeVariable(VariableDeclaration const& _declaration)
{
- LocationSetter locationSetter(*this, &_declaration);
+ LocationSetter locationSetter(*this, _declaration);
addVariable(_declaration);
int const size = _declaration.getType()->getSizeOnStack();
for (int i = 0; i < size; ++i)
@@ -182,34 +182,7 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node)
stack<ASTNode const*> newStack;
newStack.push(_node);
std::swap(m_visitedNodes, newStack);
-}
-
-CompilerContext& CompilerContext::operator<<(eth::AssemblyItem const& _item)
-{
- solAssert(!m_visitedNodes.empty(), "No node on the visited stack");
- m_asm.append(_item, m_visitedNodes.top()->getLocation());
- return *this;
-}
-
-CompilerContext& CompilerContext::operator<<(eth::Instruction _instruction)
-{
- solAssert(!m_visitedNodes.empty(), "No node on the visited stack");
- m_asm.append(_instruction, m_visitedNodes.top()->getLocation());
- return *this;
-}
-
-CompilerContext& CompilerContext::operator<<(u256 const& _value)
-{
- solAssert(!m_visitedNodes.empty(), "No node on the visited stack");
- m_asm.append(_value, m_visitedNodes.top()->getLocation());
- return *this;
-}
-
-CompilerContext& CompilerContext::operator<<(bytes const& _data)
-{
- solAssert(!m_visitedNodes.empty(), "No node on the visited stack");
- m_asm.append(_data, m_visitedNodes.top()->getLocation());
- return *this;
+ updateSourceLocation();
}
vector<ContractDefinition const*>::const_iterator CompilerContext::getSuperContract(ContractDefinition const& _contract) const
@@ -220,5 +193,10 @@ vector<ContractDefinition const*>::const_iterator CompilerContext::getSuperContr
return ++it;
}
+void CompilerContext::updateSourceLocation()
+{
+ m_asm.setSourceLocation(m_visitedNodes.empty() ? SourceLocation() : m_visitedNodes.top()->getLocation());
+}
+
}
}
diff --git a/CompilerContext.h b/CompilerContext.h
index e42e7c76..3f31a160 100644
--- a/CompilerContext.h
+++ b/CompilerContext.h
@@ -108,15 +108,15 @@ public:
/// Resets the stack of visited nodes with a new stack having only @c _node
void resetVisitedNodes(ASTNode const* _node);
/// Pops the stack of visited nodes
- void popVisitedNodes() { m_visitedNodes.pop(); }
+ void popVisitedNodes() { m_visitedNodes.pop(); updateSourceLocation(); }
/// Pushes an ASTNode to the stack of visited nodes
- void pushVisitedNodes(ASTNode const* _node) { m_visitedNodes.push(_node); }
+ void pushVisitedNodes(ASTNode const* _node) { m_visitedNodes.push(_node); updateSourceLocation(); }
/// Append elements to the current instruction list and adjust @a m_stackOffset.
- CompilerContext& operator<<(eth::AssemblyItem const& _item);
- CompilerContext& operator<<(eth::Instruction _instruction);
- CompilerContext& operator<<(u256 const& _value);
- CompilerContext& operator<<(bytes const& _data);
+ CompilerContext& operator<<(eth::AssemblyItem const& _item) { m_asm.append(_item); return *this; }
+ CompilerContext& operator<<(eth::Instruction _instruction) { m_asm.append(_instruction); return *this; }
+ CompilerContext& operator<<(u256 const& _value) { m_asm.append(_value); return *this; }
+ CompilerContext& operator<<(bytes const& _data) { m_asm.append(_data); return *this; }
eth::Assembly const& getAssembly() const { return m_asm; }
/// @arg _sourceCodes is the map of input files to source code strings
@@ -130,12 +130,15 @@ public:
class LocationSetter: public ScopeGuard
{
public:
- LocationSetter(CompilerContext& _compilerContext, ASTNode const* _node):
- ScopeGuard(std::bind(&CompilerContext::popVisitedNodes, _compilerContext)) { _compilerContext.pushVisitedNodes(_node); }
+ LocationSetter(CompilerContext& _compilerContext, ASTNode const& _node):
+ ScopeGuard([&]{ _compilerContext.popVisitedNodes(); })
+ { _compilerContext.pushVisitedNodes(&_node); }
};
private:
std::vector<ContractDefinition const*>::const_iterator getSuperContract(const ContractDefinition &_contract) const;
+ /// Updates source location set in the assembly.
+ void updateSourceLocation();
eth::Assembly m_asm;
/// Magic global variables like msg, tx or this, distinguished by type.
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 3d7a2531..b02aecf5 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -48,7 +48,7 @@ void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration c
if (!_varDecl.getValue())
return;
solAssert(!!_varDecl.getValue()->getType(), "Type information not available.");
- CompilerContext::LocationSetter locationSetter(m_context, &_varDecl);
+ CompilerContext::LocationSetter locationSetter(m_context, _varDecl);
_varDecl.getValue()->accept(*this);
appendTypeConversion(*_varDecl.getValue()->getType(), *_varDecl.getType(), true);
@@ -57,7 +57,7 @@ void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration c
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_varDecl);
+ CompilerContext::LocationSetter locationSetter(m_context, _varDecl);
FunctionType accessorType(_varDecl);
unsigned length = 0;
@@ -204,7 +204,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
bool ExpressionCompiler::visit(Assignment const& _assignment)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_assignment);
+ CompilerContext::LocationSetter locationSetter(m_context, _assignment);
_assignment.getRightHandSide().accept(*this);
if (_assignment.getType()->isValueType())
appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType());
@@ -237,7 +237,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_unaryOperation);
+ CompilerContext::LocationSetter locationSetter(m_context, _unaryOperation);
//@todo type checking and creating code for an operator should be in the same place:
// the operator should know how to convert itself and to which types it applies, so
// put this code together with "Type::acceptsBinary/UnaryOperator" into a class that
@@ -307,7 +307,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_binaryOperation);
+ CompilerContext::LocationSetter locationSetter(m_context, _binaryOperation);
Expression const& leftExpression = _binaryOperation.getLeftExpression();
Expression const& rightExpression = _binaryOperation.getRightExpression();
Type const& commonType = _binaryOperation.getCommonType();
@@ -354,7 +354,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_functionCall);
+ CompilerContext::LocationSetter locationSetter(m_context, _functionCall);
using Location = FunctionType::Location;
if (_functionCall.isTypeConversion())
{
@@ -572,7 +572,7 @@ bool ExpressionCompiler::visit(NewExpression const&)
void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_memberAccess);
+ CompilerContext::LocationSetter locationSetter(m_context, _memberAccess);
ASTString const& member = _memberAccess.getMemberName();
switch (_memberAccess.getExpression().getType()->getCategory())
{
@@ -707,7 +707,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
{
- CompilerContext::LocationSetter locationSetter(m_context, &_indexAccess);
+ CompilerContext::LocationSetter locationSetter(m_context, _indexAccess);
_indexAccess.getBaseExpression().accept(*this);
Type const& baseType = *_indexAccess.getBaseExpression().getType();
@@ -821,6 +821,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
void ExpressionCompiler::endVisit(Identifier const& _identifier)
{
+ CompilerContext::LocationSetter locationSetter(m_context, _identifier);
Declaration const* declaration = _identifier.getReferencedDeclaration();
if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
{
@@ -853,6 +854,7 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
void ExpressionCompiler::endVisit(Literal const& _literal)
{
+ CompilerContext::LocationSetter locationSetter(m_context, _literal);
switch (_literal.getType()->getCategory())
{
case Type::Category::IntegerConstant: