Split block code generation into main and finalize.

This commit is contained in:
chriseth 2017-06-09 13:59:16 +02:00 committed by Alex Beregszaszi
parent 1b3ba7bc57
commit 868b5ad3aa
4 changed files with 29 additions and 25 deletions

View File

@ -33,24 +33,6 @@ using namespace dev::julia;
using namespace dev::solidity; using namespace dev::solidity;
using namespace dev::solidity::assembly; using namespace dev::solidity::assembly;
void CodeTransform::run(Block const& _block)
{
m_scope = m_info.scopes.at(&_block).get();
int blockStartStackHeight = m_assembly.stackHeight();
std::for_each(_block.statements.begin(), _block.statements.end(), boost::apply_visitor(*this));
m_assembly.setSourceLocation(_block.location);
// pop variables
for (size_t i = 0; i < m_scope->numberOfVariables(); ++i)
m_assembly.appendInstruction(solidity::Instruction::POP);
int deposit = m_assembly.stackHeight() - blockStartStackHeight;
solAssert(deposit == 0, "Invalid stack height at end of block.");
checkStackHeight(&_block);
}
void CodeTransform::operator()(ForLoop const&) void CodeTransform::operator()(ForLoop const&)
{ {
@ -319,7 +301,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
} }
CodeTransform(m_assembly, m_info, m_evm15, m_identifierAccess, localStackAdjustment, m_context) CodeTransform(m_assembly, m_info, m_evm15, m_identifierAccess, localStackAdjustment, m_context)
.run(_function.body); (_function.body);
{ {
// The stack layout here is: // The stack layout here is:
@ -364,7 +346,14 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
void CodeTransform::operator()(Block const& _block) void CodeTransform::operator()(Block const& _block)
{ {
CodeTransform(m_assembly, m_info, m_evm15, m_identifierAccess, m_stackAdjustment, m_context).run(_block); Scope* originalScope = m_scope;
m_scope = m_info.scopes.at(&_block).get();
int blockStartStackHeight = m_assembly.stackHeight();
std::for_each(_block.statements.begin(), _block.statements.end(), boost::apply_visitor(*this));
finalizeBlock(_block, blockStartStackHeight);
m_scope = originalScope;
} }
AbstractAssembly::LabelID CodeTransform::labelFromIdentifier(Identifier const& _identifier) AbstractAssembly::LabelID CodeTransform::labelFromIdentifier(Identifier const& _identifier)
@ -405,6 +394,20 @@ void CodeTransform::visitExpression(Statement const& _expression)
expectDeposit(1, height); expectDeposit(1, height);
} }
void CodeTransform::finalizeBlock(Block const& _block, int blockStartStackHeight)
{
m_assembly.setSourceLocation(_block.location);
// pop variables
solAssert(m_info.scopes.at(&_block).get() == m_scope, "");
for (size_t i = 0; i < m_scope->numberOfVariables(); ++i)
m_assembly.appendInstruction(solidity::Instruction::POP);
int deposit = m_assembly.stackHeight() - blockStartStackHeight;
solAssert(deposit == 0, "Invalid stack height at end of block.");
checkStackHeight(&_block);
}
void CodeTransform::generateAssignment(Identifier const& _variableName) void CodeTransform::generateAssignment(Identifier const& _variableName)
{ {
solAssert(m_scope, ""); solAssert(m_scope, "");

View File

@ -61,9 +61,6 @@ public:
{ {
} }
/// Processes the block and appends the resulting code to the assembly.
void run(solidity::assembly::Block const& _block);
protected: protected:
struct Context struct Context
{ {
@ -113,6 +110,10 @@ private:
/// Generates code for an expression that is supposed to return a single value. /// Generates code for an expression that is supposed to return a single value.
void visitExpression(solidity::assembly::Statement const& _expression); void visitExpression(solidity::assembly::Statement const& _expression);
/// 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 generateAssignment(solidity::assembly::Identifier const& _variableName); void generateAssignment(solidity::assembly::Identifier const& _variableName);
/// Determines the stack height difference to the given variables. Throws /// Determines the stack height difference to the given variables. Throws

View File

@ -141,5 +141,5 @@ void assembly::CodeGenerator::assemble(
) )
{ {
EthAssemblyAdapter assemblyAdapter(_assembly); EthAssemblyAdapter assemblyAdapter(_assembly);
julia::CodeTransform(assemblyAdapter, _analysisInfo, false, _identifierAccess).run(_parsedData); julia::CodeTransform(assemblyAdapter, _analysisInfo, false, _identifierAccess)(_parsedData);
} }

View File

@ -100,7 +100,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
{ {
MachineAssemblyObject object; MachineAssemblyObject object;
julia::EVMAssembly assembly(true); julia::EVMAssembly assembly(true);
julia::CodeTransform(assembly, *m_analysisInfo, true).run(*m_parserResult); julia::CodeTransform(assembly, *m_analysisInfo, true)(*m_parserResult);
object.bytecode = make_shared<eth::LinkerObject>(assembly.finalize()); object.bytecode = make_shared<eth::LinkerObject>(assembly.finalize());
/// TOOD: fill out text representation /// TOOD: fill out text representation
return object; return object;