aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/inlineasm/AsmParser.cpp
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2018-01-06 08:09:08 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2018-01-06 08:39:06 +0800
commitfcbdaa32b90cd7da8729411481d587151f484fa1 (patch)
treeb7a515f4e6519596ca79a0dc955bdae837155ea2 /libsolidity/inlineasm/AsmParser.cpp
parentbca01f8f680c4f7d3a2da56fa014f587c5645c6a (diff)
downloaddexon-solidity-fcbdaa32b90cd7da8729411481d587151f484fa1.tar.gz
dexon-solidity-fcbdaa32b90cd7da8729411481d587151f484fa1.tar.zst
dexon-solidity-fcbdaa32b90cd7da8729411481d587151f484fa1.zip
Simplify parseElementaryOperation in regards to special instructions
Diffstat (limited to 'libsolidity/inlineasm/AsmParser.cpp')
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp
index 9336e620..20c7b2a5 100644
--- a/libsolidity/inlineasm/AsmParser.cpp
+++ b/libsolidity/inlineasm/AsmParser.cpp
@@ -123,7 +123,7 @@ assembly::Statement Parser::parseStatement()
// Simple instruction (might turn into functional),
// literal,
// identifier (might turn into label or functional assignment)
- ElementaryOperation elementary(parseElementaryOperation(false));
+ ElementaryOperation elementary(parseElementaryOperation());
switch (currentToken())
{
case Token::LParen:
@@ -145,7 +145,7 @@ assembly::Statement Parser::parseStatement()
do
{
expectToken(Token::Comma);
- elementary = parseElementaryOperation(false);
+ elementary = parseElementaryOperation();
if (elementary.type() != typeid(assembly::Identifier))
fatalParserError("Variable name expected in multiple assignemnt.");
assignment.variableNames.emplace_back(boost::get<assembly::Identifier>(elementary));
@@ -247,10 +247,11 @@ assembly::ForLoop Parser::parseForLoop()
assembly::Expression Parser::parseExpression()
{
RecursionGuard recursionGuard(*this);
- ElementaryOperation operation = parseElementaryOperation(true);
+ ElementaryOperation operation = parseElementaryOperation();
if (operation.type() == typeid(Instruction))
{
Instruction const& instr = boost::get<Instruction>(operation);
+ // Enforce functional notation for instructions requiring multiple arguments.
int args = instructionInfo(instr.instruction).args;
if (args > 0 && currentToken() != Token::LParen)
fatalParserError(string(
@@ -260,11 +261,23 @@ assembly::Expression Parser::parseExpression()
boost::lexical_cast<string>(args) +
" arguments)"
));
+ // Disallow instructions returning multiple values (and DUP/SWAP) as expression.
+ if (
+ instructionInfo(instr.instruction).ret != 1 ||
+ isDupInstruction(instr.instruction) ||
+ isSwapInstruction(instr.instruction)
+ )
+ fatalParserError(
+ "Instruction \"" +
+ instructionNames().at(instr.instruction) +
+ "\" not allowed in this context."
+ );
}
if (currentToken() == Token::LParen)
return parseCall(std::move(operation));
else if (operation.type() == typeid(Instruction))
{
+ // Instructions not taking arguments are allowed as expressions.
Instruction& instr = boost::get<Instruction>(operation);
return FunctionalInstruction{std::move(instr.location), instr.instruction, {}};
}
@@ -317,7 +330,7 @@ std::map<dev::solidity::Instruction, string> const& Parser::instructionNames()
return s_instructionNames;
}
-Parser::ElementaryOperation Parser::parseElementaryOperation(bool _onlySinglePusher)
+Parser::ElementaryOperation Parser::parseElementaryOperation()
{
RecursionGuard recursionGuard(*this);
ElementaryOperation ret;
@@ -341,12 +354,6 @@ Parser::ElementaryOperation Parser::parseElementaryOperation(bool _onlySinglePus
if (!m_julia && instructions().count(literal))
{
dev::solidity::Instruction const& instr = instructions().at(literal);
- if (_onlySinglePusher)
- {
- InstructionInfo info = dev::solidity::instructionInfo(instr);
- if (info.ret != 1)
- fatalParserError("Instruction \"" + literal + "\" not allowed in this context.");
- }
ret = Instruction{location(), instr};
}
else