diff options
author | chriseth <c@ethdev.com> | 2016-05-08 22:24:47 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-05-12 18:30:48 +0800 |
commit | 67ca3bb4b9b43faadb1d6a07f868c94bae146c1e (patch) | |
tree | 9ca400548764845c9d9977ed0ac3dc6ac4ffde9c /libsolidity/codegen/Compiler.cpp | |
parent | 1ab0f25dffe19f2cc9e1a0e2fa03a1091679f5a0 (diff) | |
download | dexon-solidity-67ca3bb4b9b43faadb1d6a07f868c94bae146c1e.tar.gz dexon-solidity-67ca3bb4b9b43faadb1d6a07f868c94bae146c1e.tar.zst dexon-solidity-67ca3bb4b9b43faadb1d6a07f868c94bae146c1e.zip |
Allow access to functions in inline assembly.
Diffstat (limited to 'libsolidity/codegen/Compiler.cpp')
-rw-r--r-- | libsolidity/codegen/Compiler.cpp | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp index 1675f659..ebf61266 100644 --- a/libsolidity/codegen/Compiler.cpp +++ b/libsolidity/codegen/Compiler.cpp @@ -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; } |