Allow access to functions in inline assembly.

This commit is contained in:
chriseth committed 2016-05-12 12:30:48 +02:00
1 parent 1ab0f25dff
commit 67ca3bb4b9
6 files changed
+62 -21

No files matched your search

+9 -12
View File
@@ -502,8 +502,9 @@ bool Compiler::visit(InlineAssembly const& _inlineAssembly)
{
ErrorList errors;
assembly::CodeGenerator codeGen(_inlineAssembly.operations(), errors);
int startStackHeight = m_context.stackHeight();
m_context.appendInlineAssembly(codeGen.assemble(
unsigned startStackHeight = m_context.stackHeight();
codeGen.assemble(
m_context.nonConstAssembly(),
[&](assembly::Identifier const& _identifier, eth::Assembly& _assembly, assembly::CodeGenerator::IdentifierContext _context) {
auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);
if (ref == _inlineAssembly.annotation().externalReferences.end())
@@ -513,19 +514,14 @@ bool Compiler::visit(InlineAssembly const& _inlineAssembly)
if (_context == assembly::CodeGenerator::IdentifierContext::RValue)
{
solAssert(!!decl->type(), "Type of declaration required but not yet determined.");
if (/*FunctionDefinition const* functionDef = */dynamic_cast<FunctionDefinition const*>(decl))
{
solAssert(false, "Referencing local functions in inline assembly not yet implemented.");
// This does not work directly, because the label does not exist in _assembly
// (it is a fresh assembly object).
// _assembly.append(m_context.virtualFunctionEntryLabel(*functionDef).pushTag());
}
if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(decl))
_assembly.append(m_context.virtualFunctionEntryLabel(*functionDef).pushTag());
else if (auto variable = dynamic_cast<VariableDeclaration const*>(decl))
{
solAssert(!variable->isConstant(), "");
if (m_context.isLocalVariable(variable))
{
int stackDiff = _assembly.deposit() + startStackHeight - m_context.baseStackOffsetOfVariable(*variable);
int stackDiff = _assembly.deposit() - m_context.baseStackOffsetOfVariable(*variable);
if (stackDiff < 1 || stackDiff > 16)
BOOST_THROW_EXCEPTION(
CompilerError() <<
@@ -565,7 +561,7 @@ bool Compiler::visit(InlineAssembly const& _inlineAssembly)
"Can only assign to stack variables in inline assembly."
);
unsigned size = variable->type()->sizeOnStack();
int stackDiff = _assembly.deposit() + startStackHeight - m_context.baseStackOffsetOfVariable(*variable) - size;
int stackDiff = _assembly.deposit() - m_context.baseStackOffsetOfVariable(*variable) - size;
if (stackDiff > 16 || stackDiff < 1)
BOOST_THROW_EXCEPTION(
CompilerError() <<
@@ -578,8 +574,9 @@ bool Compiler::visit(InlineAssembly const& _inlineAssembly)
}
return true;
}
));
);
solAssert(errors.empty(), "Code generation for inline assembly with errors requested.");
m_context.setStackOffset(startStackHeight);
return false;
}