Merge pull request #2084 from chriseth/sol_computeConstants

Compute constants
This commit is contained in:
chriseth 2015-06-05 19:22:30 +02:00
commit 779e793d60
5 changed files with 26 additions and 12 deletions

View File

@ -69,6 +69,8 @@ void Compiler::compileContract(ContractDefinition const& _contract,
swap(m_context, m_runtimeContext);
initializeContext(_contract, _contracts);
packIntoContractCreator(_contract, m_runtimeContext);
if (m_optimize)
m_context.optimise(m_optimizeRuns);
}
eth::AssemblyItem Compiler::getFunctionEntryLabel(FunctionDefinition const& _function) const
@ -120,9 +122,11 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
else if (auto c = m_context.getNextConstructor(_contract))
appendBaseConstructor(*c);
eth::AssemblyItem sub = m_context.addSubroutine(_runtimeContext.getAssembly());
eth::AssemblyItem runtimeSub = m_context.addSubroutine(_runtimeContext.getAssembly());
solAssert(runtimeSub.data() < numeric_limits<size_t>::max(), "");
m_runtimeSub = size_t(runtimeSub.data());
// stack contains sub size
m_context << eth::Instruction::DUP1 << sub << u256(0) << eth::Instruction::CODECOPY;
m_context << eth::Instruction::DUP1 << runtimeSub << u256(0) << eth::Instruction::CODECOPY;
m_context << u256(0) << eth::Instruction::RETURN;
// note that we have to include the functions again because of absolute jump labels

View File

@ -34,13 +34,18 @@ namespace solidity {
class Compiler: private ASTConstVisitor
{
public:
explicit Compiler(bool _optimize = false): m_optimize(_optimize), m_context(),
m_returnTag(m_context.newTag()) {}
explicit Compiler(bool _optimize = false, unsigned _runs = 200):
m_optimize(_optimize),
m_optimizeRuns(_runs),
m_context(),
m_returnTag(m_context.newTag())
{
}
void compileContract(ContractDefinition const& _contract,
std::map<ContractDefinition const*, bytes const*> const& _contracts);
bytes getAssembledBytecode() { return m_context.getAssembledBytecode(m_optimize); }
bytes getRuntimeBytecode() { return m_runtimeContext.getAssembledBytecode(m_optimize);}
bytes getAssembledBytecode() { return m_context.getAssembledBytecode(); }
bytes getRuntimeBytecode() { return m_context.getAssembledRuntimeBytecode(m_runtimeSub); }
/// @arg _sourceCodes is the map of input files to source code strings
/// @arg _inJsonFromat shows whether the out should be in Json format
Json::Value streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const
@ -50,7 +55,7 @@ public:
/// @returns Assembly items of the normal compiler context
eth::AssemblyItems const& getAssemblyItems() const { return m_context.getAssembly().getItems(); }
/// @returns Assembly items of the runtime compiler context
eth::AssemblyItems const& getRuntimeAssemblyItems() const { return m_runtimeContext.getAssembly().getItems(); }
eth::AssemblyItems const& getRuntimeAssemblyItems() const { return m_context.getAssembly().getSub(m_runtimeSub).getItems(); }
/// @returns the entry label of the given function. Might return an AssemblyItem of type
/// UndefinedItem if it does not exist yet.
@ -93,7 +98,9 @@ private:
void compileExpression(Expression const& _expression, TypePointer const& _targetType = TypePointer());
bool const m_optimize;
unsigned const m_optimizeRuns;
CompilerContext m_context;
size_t m_runtimeSub = size_t(-1); ///< Identifier of the runtime sub-assembly
CompilerContext m_runtimeContext;
std::vector<eth::AssemblyItem> m_breakTags; ///< tag to jump to for a "break" statement
std::vector<eth::AssemblyItem> m_continueTags; ///< tag to jump to for a "continue" statement

View File

@ -126,6 +126,8 @@ public:
CompilerContext& operator<<(u256 const& _value) { m_asm.append(_value); return *this; }
CompilerContext& operator<<(bytes const& _data) { m_asm.append(_data); return *this; }
void optimise(unsigned _runs = 200) { m_asm.optimise(true, true, _runs); }
eth::Assembly const& getAssembly() const { return m_asm; }
/// @arg _sourceCodes is the map of input files to source code strings
/// @arg _inJsonFormat shows whether the out should be in Json format
@ -134,7 +136,8 @@ public:
return m_asm.stream(_stream, "", _sourceCodes, _inJsonFormat);
}
bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); }
bytes getAssembledBytecode() { return m_asm.assemble(); }
bytes getAssembledRuntimeBytecode(size_t _subIndex) { m_asm.assemble(); return m_asm.data(u256(_subIndex)); }
/**
* Helper class to pop the visited nodes stack when a scope closes

View File

@ -145,7 +145,7 @@ vector<string> CompilerStack::getContractNames() const
}
void CompilerStack::compile(bool _optimize)
void CompilerStack::compile(bool _optimize, unsigned _runs)
{
if (!m_parseSuccessful)
parse();
@ -157,9 +157,9 @@ void CompilerStack::compile(bool _optimize)
{
if (!contract->isFullyImplemented())
continue;
shared_ptr<Compiler> compiler = make_shared<Compiler>(_optimize);
shared_ptr<Compiler> compiler = make_shared<Compiler>(_optimize, _runs);
compiler->compileContract(*contract, contractBytecode);
Contract& compiledContract = m_contracts[contract->getName()];
Contract& compiledContract = m_contracts.at(contract->getName());
compiledContract.bytecode = compiler->getAssembledBytecode();
compiledContract.runtimeBytecode = compiler->getRuntimeBytecode();
compiledContract.compiler = move(compiler);

View File

@ -90,7 +90,7 @@ public:
std::string defaultContractName() const;
/// Compiles the source units that were previously added and parsed.
void compile(bool _optimize = false);
void compile(bool _optimize = false, unsigned _runs = 200);
/// Parses and compiles the given source code.
/// @returns the compiled bytecode
bytes const& compile(std::string const& _sourceCode, bool _optimize = false);