aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/inlineasm
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/inlineasm')
-rw-r--r--libsolidity/inlineasm/AsmCodeGen.cpp1
-rw-r--r--libsolidity/inlineasm/AsmData.h4
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp32
-rw-r--r--libsolidity/inlineasm/AsmPrinter.cpp6
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)