Merge pull request #2295 from ethereum/asm-cleanup

Cleanup the assembly AST
This commit is contained in:
Alex Beregszaszi 2017-05-24 11:55:43 +01:00 committed by GitHub
commit cf639f48f2
10 changed files with 47 additions and 41 deletions

View File

@ -160,7 +160,7 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
return success; return success;
} }
bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment) bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment)
{ {
bool success = checkAssignment(_assignment.variableName, size_t(-1)); bool success = checkAssignment(_assignment.variableName, size_t(-1));
m_info.stackHeightInfo[&_assignment] = m_stackHeight; m_info.stackHeightInfo[&_assignment] = m_stackHeight;
@ -168,7 +168,7 @@ bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
} }
bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment) bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
{ {
int const stackHeight = m_stackHeight; int const stackHeight = m_stackHeight;
bool success = boost::apply_visitor(*this, *_assignment.value); bool success = boost::apply_visitor(*this, *_assignment.value);

View File

@ -40,11 +40,11 @@ struct Literal;
struct Block; struct Block;
struct Label; struct Label;
struct FunctionalInstruction; struct FunctionalInstruction;
struct FunctionalAssignment; struct Assignment;
struct VariableDeclaration; struct VariableDeclaration;
struct Instruction; struct Instruction;
struct Identifier; struct Identifier;
struct Assignment; struct StackAssignment;
struct FunctionDefinition; struct FunctionDefinition;
struct FunctionCall; struct FunctionCall;
@ -73,8 +73,8 @@ public:
bool operator()(assembly::Identifier const&); bool operator()(assembly::Identifier const&);
bool operator()(assembly::FunctionalInstruction const& _functionalInstruction); bool operator()(assembly::FunctionalInstruction const& _functionalInstruction);
bool operator()(assembly::Label const& _label); bool operator()(assembly::Label const& _label);
bool operator()(assembly::Assignment const&); bool operator()(assembly::StackAssignment const&);
bool operator()(assembly::FunctionalAssignment const& _functionalAssignment); bool operator()(assembly::Assignment const& _assignment);
bool operator()(assembly::VariableDeclaration const& _variableDeclaration); bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
bool operator()(assembly::FunctionDefinition const& _functionDefinition); bool operator()(assembly::FunctionDefinition const& _functionDefinition);
bool operator()(assembly::FunctionCall const& _functionCall); bool operator()(assembly::FunctionCall const& _functionCall);

View File

@ -36,17 +36,17 @@ struct Literal;
struct Block; struct Block;
struct Label; struct Label;
struct FunctionalInstruction; struct FunctionalInstruction;
struct FunctionalAssignment; struct Assignment;
struct VariableDeclaration; struct VariableDeclaration;
struct Instruction; struct Instruction;
struct Identifier; struct Identifier;
struct Assignment; struct StackAssignment;
struct FunctionDefinition; struct FunctionDefinition;
struct FunctionCall; struct FunctionCall;
struct Scope; struct Scope;
using Statement = boost::variant<Instruction, Literal, Label, Assignment, Identifier, FunctionalAssignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>; using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>;
struct AsmAnalysisInfo struct AsmAnalysisInfo
{ {

View File

@ -233,13 +233,13 @@ public:
m_assembly.appendLabel(*label.id); m_assembly.appendLabel(*label.id);
checkStackHeight(&_label); checkStackHeight(&_label);
} }
void operator()(assembly::Assignment const& _assignment) void operator()(assembly::StackAssignment const& _assignment)
{ {
m_assembly.setSourceLocation(_assignment.location); m_assembly.setSourceLocation(_assignment.location);
generateAssignment(_assignment.variableName, _assignment.location); generateAssignment(_assignment.variableName, _assignment.location);
checkStackHeight(&_assignment); checkStackHeight(&_assignment);
} }
void operator()(FunctionalAssignment const& _assignment) void operator()(assembly::Assignment const& _assignment)
{ {
int height = m_assembly.stackHeight(); int height = m_assembly.stackHeight();
boost::apply_visitor(*this, *_assignment.value); boost::apply_visitor(*this, *_assignment.value);

View File

@ -40,6 +40,20 @@ using TypedNameList = std::vector<TypedName>;
/// What follows are the AST nodes for assembly. /// What follows are the AST nodes for assembly.
struct Instruction;
struct Literal;
struct Label;
struct StackAssignment;
struct Identifier;
struct Assignment;
struct VariableDeclaration;
struct FunctionalInstruction;
struct FunctionDefinition;
struct FunctionCall;
struct Block;
using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>;
/// Direct EVM instruction (except PUSHi and JUMPDEST) /// Direct EVM instruction (except PUSHi and JUMPDEST)
struct Instruction { SourceLocation location; solidity::Instruction instruction; }; struct Instruction { SourceLocation location; solidity::Instruction instruction; };
/// Literal number or string (up to 32 bytes) /// Literal number or string (up to 32 bytes)
@ -47,20 +61,13 @@ enum class LiteralKind { Number, Boolean, String };
struct Literal { SourceLocation location; LiteralKind kind; std::string value; Type type; }; struct Literal { SourceLocation location; LiteralKind kind; std::string value; Type type; };
/// External / internal identifier or label reference /// External / internal identifier or label reference
struct Identifier { SourceLocation location; std::string name; }; struct Identifier { SourceLocation location; std::string name; };
struct FunctionalInstruction;
/// Jump label ("name:") /// Jump label ("name:")
struct Label { SourceLocation location; std::string name; }; struct Label { SourceLocation location; std::string name; };
/// Assignemnt (":= x", moves stack top into x, potentially multiple slots) /// Assignment from stack (":= x", moves stack top into x, potentially multiple slots)
struct Assignment { SourceLocation location; Identifier variableName; }; struct StackAssignment { SourceLocation location; Identifier variableName; };
struct FunctionalAssignment; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand
struct VariableDeclaration;
struct FunctionDefinition;
struct FunctionCall;
struct Block;
using Statement = boost::variant<Instruction, Literal, Label, Assignment, Identifier, FunctionalAssignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>;
/// Functional assignment ("x := mload(20:u256)", expects push-1-expression on the right hand
/// side and requires x to occupy exactly one stack slot. /// side and requires x to occupy exactly one stack slot.
struct FunctionalAssignment { SourceLocation location; Identifier variableName; std::shared_ptr<Statement> value; }; struct Assignment { SourceLocation location; Identifier variableName; std::shared_ptr<Statement> value; };
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))" /// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
struct FunctionalInstruction { SourceLocation location; Instruction instruction; std::vector<Statement> arguments; }; struct FunctionalInstruction { SourceLocation location; Instruction instruction; std::vector<Statement> arguments; };
struct FunctionCall { SourceLocation location; Identifier functionName; std::vector<Statement> arguments; }; struct FunctionCall { SourceLocation location; Identifier functionName; std::vector<Statement> arguments; };

View File

@ -71,7 +71,7 @@ assembly::Statement Parser::parseStatement()
{ {
if (m_julia) if (m_julia)
break; break;
assembly::Assignment assignment = createWithLocation<assembly::Assignment>(); assembly::StackAssignment assignment = createWithLocation<assembly::StackAssignment>();
m_scanner->next(); m_scanner->next();
expectToken(Token::Colon); expectToken(Token::Colon);
assignment.variableName.location = location(); assignment.variableName.location = location();
@ -96,7 +96,7 @@ assembly::Statement Parser::parseStatement()
switch (m_scanner->currentToken()) switch (m_scanner->currentToken())
{ {
case Token::LParen: case Token::LParen:
return parseFunctionalInstruction(std::move(statement)); return parseCall(std::move(statement));
case Token::Colon: case Token::Colon:
{ {
if (statement.type() != typeid(assembly::Identifier)) if (statement.type() != typeid(assembly::Identifier))
@ -107,15 +107,14 @@ assembly::Statement Parser::parseStatement()
// while identifier:= (being followed by a non-colon) as identifier := (assignment). // while identifier:= (being followed by a non-colon) as identifier := (assignment).
if (m_scanner->currentToken() == Token::Assign && m_scanner->peekNextToken() != Token::Colon) if (m_scanner->currentToken() == Token::Assign && m_scanner->peekNextToken() != Token::Colon)
{ {
// functional assignment assembly::Assignment assignment = createWithLocation<assembly::Assignment>(identifier.location);
FunctionalAssignment funAss = createWithLocation<FunctionalAssignment>(identifier.location);
if (!m_julia && instructions().count(identifier.name)) if (!m_julia && instructions().count(identifier.name))
fatalParserError("Cannot use instruction names for identifier names."); fatalParserError("Cannot use instruction names for identifier names.");
m_scanner->next(); m_scanner->next();
funAss.variableName = identifier; assignment.variableName = identifier;
funAss.value.reset(new Statement(parseExpression())); assignment.value.reset(new Statement(parseExpression()));
funAss.location.end = locationOf(*funAss.value).end; assignment.location.end = locationOf(*assignment.value).end;
return funAss; return assignment;
} }
else else
{ {
@ -139,7 +138,7 @@ assembly::Statement Parser::parseExpression()
{ {
Statement operation = parseElementaryOperation(true); Statement operation = parseElementaryOperation(true);
if (m_scanner->currentToken() == Token::LParen) if (m_scanner->currentToken() == Token::LParen)
return parseFunctionalInstruction(std::move(operation)); return parseCall(std::move(operation));
else else
return operation; return operation;
} }
@ -304,7 +303,7 @@ assembly::FunctionDefinition Parser::parseFunctionDefinition()
return funDef; return funDef;
} }
assembly::Statement Parser::parseFunctionalInstruction(assembly::Statement&& _instruction) assembly::Statement Parser::parseCall(assembly::Statement&& _instruction)
{ {
if (_instruction.type() == typeid(Instruction)) if (_instruction.type() == typeid(Instruction))
{ {

View File

@ -68,7 +68,7 @@ protected:
Statement parseElementaryOperation(bool _onlySinglePusher = false); Statement parseElementaryOperation(bool _onlySinglePusher = false);
VariableDeclaration parseVariableDeclaration(); VariableDeclaration parseVariableDeclaration();
FunctionDefinition parseFunctionDefinition(); FunctionDefinition parseFunctionDefinition();
Statement parseFunctionalInstruction(Statement&& _instruction); Statement parseCall(Statement&& _instruction);
TypedName parseTypedName(); TypedName parseTypedName();
std::string expectAsmIdentifier(); std::string expectAsmIdentifier();

View File

@ -108,15 +108,15 @@ string AsmPrinter::operator()(assembly::Label const& _label)
return _label.name + ":"; return _label.name + ":";
} }
string AsmPrinter::operator()(assembly::Assignment const& _assignment) string AsmPrinter::operator()(assembly::StackAssignment const& _assignment)
{ {
solAssert(!m_julia, ""); solAssert(!m_julia, "");
return "=: " + (*this)(_assignment.variableName); return "=: " + (*this)(_assignment.variableName);
} }
string AsmPrinter::operator()(assembly::FunctionalAssignment const& _functionalAssignment) string AsmPrinter::operator()(assembly::Assignment const& _assignment)
{ {
return (*this)(_functionalAssignment.variableName) + " := " + boost::apply_visitor(*this, *_functionalAssignment.value); return (*this)(_assignment.variableName) + " := " + boost::apply_visitor(*this, *_assignment.value);
} }
string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDeclaration) string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDeclaration)

View File

@ -35,8 +35,8 @@ struct Literal;
struct Identifier; struct Identifier;
struct FunctionalInstruction; struct FunctionalInstruction;
struct Label; struct Label;
struct StackAssignment;
struct Assignment; struct Assignment;
struct FunctionalAssignment;
struct VariableDeclaration; struct VariableDeclaration;
struct FunctionDefinition; struct FunctionDefinition;
struct FunctionCall; struct FunctionCall;
@ -52,8 +52,8 @@ public:
std::string operator()(assembly::Identifier const& _identifier); std::string operator()(assembly::Identifier const& _identifier);
std::string operator()(assembly::FunctionalInstruction const& _functionalInstruction); std::string operator()(assembly::FunctionalInstruction const& _functionalInstruction);
std::string operator()(assembly::Label const& _label); std::string operator()(assembly::Label const& _label);
std::string operator()(assembly::StackAssignment const& _assignment);
std::string operator()(assembly::Assignment const& _assignment); std::string operator()(assembly::Assignment const& _assignment);
std::string operator()(assembly::FunctionalAssignment const& _functionalAssignment);
std::string operator()(assembly::VariableDeclaration const& _variableDeclaration); std::string operator()(assembly::VariableDeclaration const& _variableDeclaration);
std::string operator()(assembly::FunctionDefinition const& _functionDefinition); std::string operator()(assembly::FunctionDefinition const& _functionDefinition);
std::string operator()(assembly::FunctionCall const& _functionCall); std::string operator()(assembly::FunctionCall const& _functionCall);

View File

@ -39,11 +39,11 @@ struct Literal;
struct Block; struct Block;
struct Label; struct Label;
struct FunctionalInstruction; struct FunctionalInstruction;
struct FunctionalAssignment; struct Assignment;
struct VariableDeclaration; struct VariableDeclaration;
struct Instruction; struct Instruction;
struct Identifier; struct Identifier;
struct Assignment; struct StackAssignment;
struct FunctionDefinition; struct FunctionDefinition;
struct FunctionCall; struct FunctionCall;
@ -64,8 +64,8 @@ public:
bool operator()(assembly::Identifier const&) { return true; } bool operator()(assembly::Identifier const&) { return true; }
bool operator()(assembly::FunctionalInstruction const&) { return true; } bool operator()(assembly::FunctionalInstruction const&) { return true; }
bool operator()(assembly::Label const& _label); bool operator()(assembly::Label const& _label);
bool operator()(assembly::StackAssignment const&) { return true; }
bool operator()(assembly::Assignment const&) { return true; } bool operator()(assembly::Assignment const&) { return true; }
bool operator()(assembly::FunctionalAssignment const&) { return true; }
bool operator()(assembly::VariableDeclaration const& _variableDeclaration); bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
bool operator()(assembly::FunctionDefinition const& _functionDefinition); bool operator()(assembly::FunctionDefinition const& _functionDefinition);
bool operator()(assembly::FunctionCall const&) { return true; } bool operator()(assembly::FunctionCall const&) { return true; }