Split external identifier access into resolving and code generation.

This commit is contained in:
chriseth authored and chriseth committed 2017-04-25 16:49:03 +02:00
1 parent 5d6747eb32
commit e0849f2f3b
9 files changed
+189 -144

No files matched your search

+15 -8
View File
@@ -265,31 +265,38 @@ void CompilerContext::appendInlineAssembly(
}
unsigned startStackHeight = stackHeight();
auto identifierAccess = [&](
assembly::ExternalIdentifierAccess identifierAccess;
identifierAccess.resolve = [&](
assembly::Identifier const& _identifier,
eth::Assembly& _assembly,
assembly::CodeGenerator::IdentifierContext _context
assembly::IdentifierContext
) {
auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name);
if (it == _localVariables.end())
return false;
return it == _localVariables.end() ? size_t(-1) : 1;
};
identifierAccess.generateCode = [&](
assembly::Identifier const& _identifier,
assembly::IdentifierContext _context,
eth::Assembly& _assembly
) {
auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name);
solAssert(it != _localVariables.end(), "");
unsigned stackDepth = _localVariables.end() - it;
int stackDiff = _assembly.deposit() - startStackHeight + stackDepth;
if (_context == assembly::CodeGenerator::IdentifierContext::LValue)
if (_context == assembly::IdentifierContext::LValue)
stackDiff -= 1;
if (stackDiff < 1 || stackDiff > 16)
BOOST_THROW_EXCEPTION(
CompilerError() <<
errinfo_comment("Stack too deep, try removing local variables.")
);
if (_context == assembly::CodeGenerator::IdentifierContext::RValue)
if (_context == assembly::IdentifierContext::RValue)
_assembly.append(dupInstruction(stackDiff));
else
{
_assembly.append(swapInstruction(stackDiff));
_assembly.append(Instruction::POP);
}
return true;
};
solAssert(assembly::InlineAssemblyStack().parseAndAssemble(*assembly, *m_asm, identifierAccess), "Failed to assemble inline assembly block.");