diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/inlineasm/AsmCodeGen.cpp | 1 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmData.h | 4 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 32 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmPrinter.cpp | 6 |
4 files changed, 40 insertions, 3 deletions
diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index faa7dabd..abc0ca01 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -91,6 +91,7 @@ public: void operator()(T const& /*_item*/) { } void operator()(Label const& _item) { + solAssert(_item.stackInfo.empty(), "Labels with stack info not yet supported."); if (m_state.labels.count(_item.name)) //@TODO secondary location m_state.addError( diff --git a/libsolidity/inlineasm/AsmData.h b/libsolidity/inlineasm/AsmData.h index d61b5803..5969bf96 100644 --- a/libsolidity/inlineasm/AsmData.h +++ b/libsolidity/inlineasm/AsmData.h @@ -42,8 +42,8 @@ struct Literal { SourceLocation location; bool isNumber; std::string value; }; /// External / internal identifier or label reference struct Identifier { SourceLocation location; std::string name; }; struct FunctionalInstruction; -/// Jump label ("name:") -struct Label { SourceLocation location; std::string name; }; +/// Jump label ("name:" or "name [x, y, z]:" or "name [-3]:") +struct Label { SourceLocation location; std::string name; std::vector<std::string> stackInfo; }; /// Assignemnt (":= x", moves stack top into x, potentially multiple slots) struct Assignment { SourceLocation location; Identifier variableName; }; struct FunctionalAssignment; diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 0fc0a34f..5d439b2f 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -121,6 +121,38 @@ assembly::Statement Parser::parseStatement() return label; } } + case Token::LBrack: + { + if (statement.type() != typeid(assembly::Identifier)) + fatalParserError("Label name must precede \"[\"."); + assembly::Identifier const& identifier = boost::get<assembly::Identifier>(statement); + Label label = createWithLocation<Label>(identifier.location); + label.name = identifier.name; + m_scanner->next(); + if (m_scanner->currentToken() == Token::Number) + { + label.stackInfo.push_back(m_scanner->currentLiteral()); + m_scanner->next(); + } + else if (m_scanner->currentToken() == Token::Sub) + { + m_scanner->next(); + label.stackInfo.push_back("-" + m_scanner->currentLiteral()); + expectToken(Token::Number); + } + else + while (true) + { + label.stackInfo.push_back(expectAsmIdentifier()); + if (m_scanner->currentToken() == Token::RBrack) + break; + expectToken(Token::Comma); + } + expectToken(Token::RBrack); + label.location.end = endPosition(); + expectToken(Token::Colon); + return label; + } default: break; } diff --git a/libsolidity/inlineasm/AsmPrinter.cpp b/libsolidity/inlineasm/AsmPrinter.cpp index a70b0b78..5ec83281 100644 --- a/libsolidity/inlineasm/AsmPrinter.cpp +++ b/libsolidity/inlineasm/AsmPrinter.cpp @@ -94,7 +94,11 @@ string AsmPrinter::operator()(assembly::FunctionalInstruction const& _functional string AsmPrinter::operator()(assembly::Label const& _label) { - return _label.name + ":"; + return _label.name + ( + !_label.stackInfo.empty() ? + "[" + boost::algorithm::join(_label.stackInfo, ", ") + "]" : + string() + ) + ":"; } string AsmPrinter::operator()(assembly::Assignment const& _assignment) |