From 97350c88ed1c4e607691a7ec2afe7f17d226a0de Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Thu, 5 Mar 2015 15:51:26 +0100 Subject: [PATCH 1/4] Added JumpType indicator to AssemblyItem. --- libevmcore/Assembly.cpp | 16 +++++++++++++++- libevmcore/Assembly.h | 9 ++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index be35b62c2..c253ef68f 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -77,6 +77,20 @@ int AssemblyItem::deposit() const return 0; } +string AssemblyItem::getJumpTypeAsString() const +{ + switch (m_jumpType) + { + case JumpType::IntoFunction: + return "->"; + case JumpType::OutOfFunction: + return "<-"; + case JumpType::Ordinary: + default: + return "->"; + } +} + unsigned Assembly::bytesRequired() const { for (unsigned br = 1;; ++br) @@ -205,7 +219,7 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap con switch (i.m_type) { case Operation: - _out << " " << instructionInfo((Instruction)(byte)i.m_data).name; + _out << " " << instructionInfo((Instruction)(byte)i.m_data).name << " " << i.getJumpTypeAsString( ) << endl; break; case Push: _out << " PUSH " << i.m_data; diff --git a/libevmcore/Assembly.h b/libevmcore/Assembly.h index cd71db747..8952deffd 100644 --- a/libevmcore/Assembly.h +++ b/libevmcore/Assembly.h @@ -42,6 +42,8 @@ class AssemblyItem friend class Assembly; public: + enum class JumpType { Ordinary, IntoFunction, OutOfFunction }; + AssemblyItem(u256 _push): m_type(Push), m_data(_push) {} AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {} AssemblyItem(AssemblyItemType _type, u256 _data = 0): m_type(_type), m_data(_data) {} @@ -58,13 +60,18 @@ public: int deposit() const; bool match(AssemblyItem const& _i) const { return _i.m_type == UndefinedItem || (m_type == _i.m_type && (m_type != Operation || m_data == _i.m_data)); } - void setLocation(SourceLocation const& _location) { m_location = _location;} + void setLocation(SourceLocation const& _location) { m_location = _location; } SourceLocation const& getLocation() const { return m_location; } + void setJumpType(JumpType _jumpType) { m_jumpType = _jumpType; } + JumpType getJumpType() const { return m_jumpType; } + std::string getJumpTypeAsString() const; + private: AssemblyItemType m_type; u256 m_data; SourceLocation m_location; + JumpType m_jumpType; }; using AssemblyItems = std::vector; From f7841a9b49a42f0ead5786424e4372f75b354ed3 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 9 Mar 2015 13:15:59 +0100 Subject: [PATCH 2/4] fixed new line for user input from terminal. --- solc/CommandLineInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 08acb5ebd..01d8f8485 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -272,7 +272,7 @@ bool CommandLineInterface::processInput() while (!cin.eof()) { getline(cin, s); - m_sourceCodes[""].append(s); + m_sourceCodes[""].append(s + '\n'); } } else From 4323a0c65508a3dc72bc5264fc78ca127894ccc9 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 9 Mar 2015 19:22:24 +0100 Subject: [PATCH 3/4] added information about jump type for jump instructions Conflicts: libevmcore/Assembly.cpp libsolidity/Compiler.cpp --- libevmcore/Assembly.cpp | 10 +++++----- libsolidity/Compiler.cpp | 11 ++++++++--- libsolidity/CompilerContext.cpp | 7 +++++++ libsolidity/CompilerContext.h | 2 +- libsolidity/ExpressionCompiler.cpp | 5 +++-- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index c253ef68f..57e124fb8 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -82,12 +82,12 @@ string AssemblyItem::getJumpTypeAsString() const switch (m_jumpType) { case JumpType::IntoFunction: - return "->"; + return "in"; case JumpType::OutOfFunction: - return "<-"; + return "out"; case JumpType::Ordinary: default: - return "->"; + return ""; } } @@ -219,7 +219,7 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap con switch (i.m_type) { case Operation: - _out << " " << instructionInfo((Instruction)(byte)i.m_data).name << " " << i.getJumpTypeAsString( ) << endl; + _out << " " << instructionInfo((Instruction)(byte)i.m_data).name << "\t\t" << i.getJumpTypeAsString(); break; case Push: _out << " PUSH " << i.m_data; @@ -254,7 +254,7 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap con default: BOOST_THROW_EXCEPTION(InvalidOpcode()); } - _out << string("\t\t") << getLocationFromSources(_sourceCodes, i.getLocation()) << endl; + _out << "\t\t" << getLocationFromSources(_sourceCodes, i.getLocation()) << endl; } if (!m_data.empty() || !m_subs.empty()) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 7ff846bdb..46888683e 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -177,7 +177,9 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) { callDataUnpackerEntryPoints.insert(std::make_pair(it.first, m_context.newTag())); m_context << eth::dupInstruction(1) << u256(FixedHash<4>::Arith(it.first)) << eth::Instruction::EQ; - m_context.appendConditionalJumpTo(callDataUnpackerEntryPoints.at(it.first)); + auto assemblyItem = callDataUnpackerEntryPoints.at(it.first); + //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); + m_context.appendConditionalJumpTo(assemblyItem); } if (FunctionDefinition const* fallback = _contract.getFallbackFunction()) { @@ -197,7 +199,9 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) m_context << callDataUnpackerEntryPoints.at(it.first); eth::AssemblyItem returnTag = m_context.pushNewTag(); appendCalldataUnpacker(functionType->getParameterTypes()); - m_context.appendJumpTo(m_context.getFunctionEntryLabel(functionType->getDeclaration())); + auto assemblyItem = m_context.getFunctionEntryLabel(functionType->getDeclaration()); + //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); + m_context.appendJumpTo(assemblyItem); m_context << returnTag; appendReturnValuePacker(functionType->getReturnParameterTypes()); } @@ -378,8 +382,9 @@ bool Compiler::visit(FunctionDefinition const& _function) m_context.removeVariable(*localVariable); m_context.adjustStackOffset(-(int)c_returnValuesSize); + if (!_function.isConstructor()) - m_context << eth::Instruction::JUMP; + m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); return false; } diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index 1dea62e93..f2bb1de20 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -177,6 +177,13 @@ u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declarati return it->second; } +CompilerContext& CompilerContext::appendJump(eth::AssemblyItem::JumpType _jumpType) +{ + eth::AssemblyItem item(eth::Instruction::JUMP); + item.setJumpType(_jumpType); + return *this << item; +} + void CompilerContext::resetVisitedNodes(ASTNode const* _node) { stack newStack; diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h index 4d63d8ba0..f468d29c4 100644 --- a/libsolidity/CompilerContext.h +++ b/libsolidity/CompilerContext.h @@ -91,7 +91,7 @@ public: /// Appends a JUMP to a new tag and @returns the tag eth::AssemblyItem appendJumpToNew() { return m_asm.appendJump().tag(); } /// Appends a JUMP to a tag already on the stack - CompilerContext& appendJump() { return *this << eth::Instruction::JUMP; } + CompilerContext& appendJump(eth::AssemblyItem::JumpType _jumpType = eth::AssemblyItem::JumpType::Ordinary); /// Appends a JUMP to a specific tag CompilerContext& appendJumpTo(eth::AssemblyItem const& _tag) { m_asm.appendJump(_tag); return *this; } /// Appends pushing of a new tag and @returns the new tag. diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index d2457e676..129261120 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -108,7 +108,8 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& retSizeOnStack = returnType->getSizeOnStack(); } solAssert(retSizeOnStack <= 15, "Stack too deep."); - m_context << eth::dupInstruction(retSizeOnStack + 1) << eth::Instruction::JUMP; + m_context << eth::dupInstruction(retSizeOnStack + 1); + m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); } void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded) @@ -405,7 +406,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } _functionCall.getExpression().accept(*this); - m_context.appendJump(); + m_context.appendJump(eth::AssemblyItem::JumpType::IntoFunction); m_context << returnLabel; unsigned returnParametersSize = CompilerUtils::getSizeOnStack(function.getReturnParameterTypes()); From 035451db40a9630915dd27b20be23d450c0a1cf1 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Tue, 10 Mar 2015 12:00:23 +0100 Subject: [PATCH 4/4] added brackets for printing in/out cleaned up --- libevmcore/Assembly.cpp | 10 +++++----- libevmcore/Assembly.h | 6 +++--- libsolidity/Compiler.cpp | 8 ++------ libsolidity/CompilerContext.h | 2 +- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index 57e124fb8..0a0611292 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -82,9 +82,9 @@ string AssemblyItem::getJumpTypeAsString() const switch (m_jumpType) { case JumpType::IntoFunction: - return "in"; + return "[in]"; case JumpType::OutOfFunction: - return "out"; + return "[out]"; case JumpType::Ordinary: default: return ""; @@ -210,7 +210,7 @@ string Assembly::getLocationFromSources(StringMap const& _sourceCodes, SourceLoc return move(cut); } -ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const +ostream& Assembly::stream(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const { _out << _prefix << ".code:" << endl; for (AssemblyItem const& i: m_items) @@ -219,7 +219,7 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap con switch (i.m_type) { case Operation: - _out << " " << instructionInfo((Instruction)(byte)i.m_data).name << "\t\t" << i.getJumpTypeAsString(); + _out << " " << instructionInfo((Instruction)(byte)i.m_data).name << "\t" << i.getJumpTypeAsString(); break; case Push: _out << " PUSH " << i.m_data; @@ -266,7 +266,7 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap con for (size_t i = 0; i < m_subs.size(); ++i) { _out << _prefix << " " << hex << i << ": " << endl; - m_subs[i].streamRLP(_out, _prefix + " ", _sourceCodes); + m_subs[i].stream(_out, _prefix + " ", _sourceCodes); } } return _out; diff --git a/libevmcore/Assembly.h b/libevmcore/Assembly.h index 8952deffd..1cbb12e12 100644 --- a/libevmcore/Assembly.h +++ b/libevmcore/Assembly.h @@ -121,7 +121,7 @@ public: void popTo(int _deposit) { while (m_deposit > _deposit) append(Instruction::POP); } void injectStart(AssemblyItem const& _i); - std::string out() const { std::stringstream ret; streamRLP(ret); return ret.str(); } + std::string out() const { std::stringstream ret; stream(ret); return ret.str(); } int deposit() const { return m_deposit; } void adjustDeposit(int _adjustment) { m_deposit += _adjustment; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); } void setDeposit(int _deposit) { m_deposit = _deposit; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); } @@ -131,7 +131,7 @@ public: bytes assemble() const; Assembly& optimise(bool _enable); - std::ostream& streamRLP(std::ostream& _out, std::string const& _prefix = "", const StringMap &_sourceCodes = StringMap()) const; + std::ostream& stream(std::ostream& _out, std::string const& _prefix = "", const StringMap &_sourceCodes = StringMap()) const; protected: std::string getLocationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location) const; @@ -153,7 +153,7 @@ protected: inline std::ostream& operator<<(std::ostream& _out, Assembly const& _a) { - _a.streamRLP(_out); + _a.stream(_out); return _out; } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 46888683e..dc6e2c5a8 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -177,9 +177,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) { callDataUnpackerEntryPoints.insert(std::make_pair(it.first, m_context.newTag())); m_context << eth::dupInstruction(1) << u256(FixedHash<4>::Arith(it.first)) << eth::Instruction::EQ; - auto assemblyItem = callDataUnpackerEntryPoints.at(it.first); - //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); - m_context.appendConditionalJumpTo(assemblyItem); + m_context.appendConditionalJumpTo(callDataUnpackerEntryPoints.at(it.first)); } if (FunctionDefinition const* fallback = _contract.getFallbackFunction()) { @@ -199,9 +197,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) m_context << callDataUnpackerEntryPoints.at(it.first); eth::AssemblyItem returnTag = m_context.pushNewTag(); appendCalldataUnpacker(functionType->getParameterTypes()); - auto assemblyItem = m_context.getFunctionEntryLabel(functionType->getDeclaration()); - //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); - m_context.appendJumpTo(assemblyItem); + m_context.appendJumpTo(m_context.getFunctionEntryLabel(functionType->getDeclaration())); m_context << returnTag; appendReturnValuePacker(functionType->getReturnParameterTypes()); } diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h index f468d29c4..76923a77a 100644 --- a/libsolidity/CompilerContext.h +++ b/libsolidity/CompilerContext.h @@ -120,7 +120,7 @@ public: eth::Assembly const& getAssembly() const { return m_asm; } /// @arg _sourceCodes is the map of input files to source code strings - void streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { m_asm.streamRLP(_stream, "", _sourceCodes); } + void streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { m_asm.stream(_stream, "", _sourceCodes); } bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); }