From 225fc8e1b31860ab002c38fb9ff326f20b76965f Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 6 Nov 2014 16:30:50 +0100 Subject: [PATCH 1/2] Option to activate the optimizer for solidity. --- Compiler.cpp | 4 ++-- Compiler.h | 4 ++-- CompilerContext.h | 2 +- CompilerStack.cpp | 5 +++-- CompilerStack.h | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Compiler.cpp b/Compiler.cpp index d05552b9e..571a62d72 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -30,11 +30,11 @@ using namespace std; namespace dev { namespace solidity { -bytes Compiler::compile(ContractDefinition& _contract) +bytes Compiler::compile(ContractDefinition& _contract, bool _optimize) { Compiler compiler; compiler.compileContract(_contract); - return compiler.m_context.getAssembledBytecode(); + return compiler.m_context.getAssembledBytecode(_optimize); } void Compiler::compileContract(ContractDefinition& _contract) diff --git a/Compiler.h b/Compiler.h index 4e4d90d45..d931f5359 100644 --- a/Compiler.h +++ b/Compiler.h @@ -33,11 +33,11 @@ public: Compiler(): m_returnTag(m_context.newTag()) {} void compileContract(ContractDefinition& _contract); - bytes getAssembledBytecode() { return m_context.getAssembledBytecode(); } + bytes getAssembledBytecode(bool _optimize = false) { return m_context.getAssembledBytecode(_optimize); } void streamAssembly(std::ostream& _stream) const { m_context.streamAssembly(_stream); } /// Compile the given contract and return the EVM bytecode. - static bytes compile(ContractDefinition& _contract); + static bytes compile(ContractDefinition& _contract, bool _optimize); private: /// Creates a new compiler context / assembly and packs the current code into the data part. diff --git a/CompilerContext.h b/CompilerContext.h index 088ef43bc..866c621db 100644 --- a/CompilerContext.h +++ b/CompilerContext.h @@ -75,7 +75,7 @@ public: eth::Assembly const& getAssembly() const { return m_asm; } void streamAssembly(std::ostream& _stream) const { _stream << m_asm; } - bytes getAssembledBytecode() const { return m_asm.assemble(); } + bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); } private: eth::Assembly m_asm; diff --git a/CompilerStack.cpp b/CompilerStack.cpp index bbd693ae5..c991171a5 100644 --- a/CompilerStack.cpp +++ b/CompilerStack.cpp @@ -34,7 +34,8 @@ namespace dev namespace solidity { -bytes CompilerStack::compile(std::string const& _sourceCode, shared_ptr _scanner) +bytes CompilerStack::compile(std::string const& _sourceCode, shared_ptr _scanner, + bool _optimize) { if (!_scanner) _scanner = make_shared(); @@ -42,7 +43,7 @@ bytes CompilerStack::compile(std::string const& _sourceCode, shared_ptr ASTPointer contract = Parser().parse(_scanner); NameAndTypeResolver().resolveNamesAndTypes(*contract); - return Compiler::compile(*contract); + return Compiler::compile(*contract, _optimize); } } diff --git a/CompilerStack.h b/CompilerStack.h index 9f3f81c04..b003745d2 100644 --- a/CompilerStack.h +++ b/CompilerStack.h @@ -36,7 +36,7 @@ class CompilerStack public: /// Compile the given @a _sourceCode to bytecode. If a scanner is provided, it is used for /// scanning the source code - this is useful for printing exception information. - static bytes compile(std::string const& _sourceCode, std::shared_ptr _scanner = std::shared_ptr()); + static bytes compile(std::string const& _sourceCode, std::shared_ptr _scanner = std::shared_ptr(), bool _optimize = false); }; } From b66e58d6c9cb1684bac548406f6a950bf0eb65e3 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 6 Nov 2014 16:43:20 +0100 Subject: [PATCH 2/2] Prevent optimizer from changing certain parts of the code. --- Compiler.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Compiler.cpp b/Compiler.cpp index 571a62d72..93cb172d8 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -89,10 +89,11 @@ void Compiler::appendFunctionSelector(vector> con eth::AssemblyItem jumpTableStart = m_context.pushNewTag(); m_context << eth::Instruction::ADD << eth::Instruction::JUMP; - // jump table @todo it could be that the optimizer destroys this - m_context << jumpTableStart; + // jump table, tell the optimizer not to remove the JUMPDESTs + m_context << eth::AssemblyItem(eth::NoOptimizeBegin) << jumpTableStart; for (pair> const& f: publicFunctions) m_context.appendJumpTo(f.second.second) << eth::Instruction::JUMPDEST; + m_context << eth::AssemblyItem(eth::NoOptimizeEnd); m_context << returnTag << eth::Instruction::STOP;