mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2295 from ethereum/asm-cleanup
Cleanup the assembly AST
This commit is contained in:
commit
cf639f48f2
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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; };
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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; }
|
||||||
|
Loading…
Reference in New Issue
Block a user