From 124190336b0a70ea32d5f8ca0c4b364f1fc774d0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 13 Dec 2017 14:40:54 +0100 Subject: Split inline assembly into loose and strict flavours. --- libsolidity/inlineasm/AsmAnalysis.cpp | 17 +++++++++-------- libsolidity/inlineasm/AsmAnalysis.h | 6 +++--- libsolidity/inlineasm/AsmDataForward.h | 7 +++++++ libsolidity/inlineasm/AsmParser.cpp | 31 ++++++++++++++++++------------- libsolidity/inlineasm/AsmParser.h | 8 ++++++-- 5 files changed, 43 insertions(+), 26 deletions(-) (limited to 'libsolidity/inlineasm') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 17b7cce0..2d6e58de 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -54,7 +54,7 @@ bool AsmAnalyzer::analyze(Block const& _block) bool AsmAnalyzer::operator()(Label const& _label) { - solAssert(!m_julia, ""); + solAssert(m_flavour == AsmFlavour::Loose, ""); m_info.stackHeightInfo[&_label] = m_stackHeight; warnOnInstructions(solidity::Instruction::JUMPDEST, _label.location); return true; @@ -62,7 +62,7 @@ bool AsmAnalyzer::operator()(Label const& _label) bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) { - solAssert(!m_julia, ""); + solAssert(m_flavour == AsmFlavour::Loose, ""); auto const& info = instructionInfo(_instruction.instruction); m_stackHeight += info.ret - info.args; m_info.stackHeightInfo[&_instruction] = m_stackHeight; @@ -141,7 +141,7 @@ bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier) bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) { - solAssert(!m_julia, ""); + solAssert(m_flavour != AsmFlavour::IULIA, ""); bool success = true; for (auto const& arg: _instr.arguments | boost::adaptors::reversed) if (!expectExpression(arg)) @@ -157,17 +157,18 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) bool AsmAnalyzer::operator()(assembly::ExpressionStatement const& _statement) { -// size_t initialStackHeight = m_stackHeight; + size_t initialStackHeight = m_stackHeight; bool success = boost::apply_visitor(*this, _statement.expression); -// if (!expectDeposit(0, initialStackHeight, _statement.location)) -// success = false; + if (m_flavour != AsmFlavour::Loose) + if (!expectDeposit(0, initialStackHeight, _statement.location)) + success = false; m_info.stackHeightInfo[&_statement] = m_stackHeight; return success; } bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment) { - solAssert(!m_julia, ""); + solAssert(m_flavour == AsmFlavour::Loose, ""); bool success = checkAssignment(_assignment.variableName, size_t(-1)); m_info.stackHeightInfo[&_assignment] = m_stackHeight; return success; @@ -507,7 +508,7 @@ Scope& AsmAnalyzer::scope(Block const* _block) } void AsmAnalyzer::expectValidType(string const& type, SourceLocation const& _location) { - if (!m_julia) + if (m_flavour != AsmFlavour::IULIA) return; if (!builtinTypes.count(type)) diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index 00a33db3..7a81dbf8 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -54,9 +54,9 @@ public: explicit AsmAnalyzer( AsmAnalysisInfo& _analysisInfo, ErrorReporter& _errorReporter, - bool _julia = false, + AsmFlavour _flavour = AsmFlavour::Loose, julia::ExternalIdentifierAccess::Resolver const& _resolver = julia::ExternalIdentifierAccess::Resolver() - ): m_resolver(_resolver), m_info(_analysisInfo), m_errorReporter(_errorReporter), m_julia(_julia) {} + ): m_resolver(_resolver), m_info(_analysisInfo), m_errorReporter(_errorReporter), m_flavour(_flavour) {} bool analyze(assembly::Block const& _block); @@ -97,7 +97,7 @@ private: std::set m_activeVariables; AsmAnalysisInfo& m_info; ErrorReporter& m_errorReporter; - bool m_julia = false; + AsmFlavour m_flavour = AsmFlavour::Loose; }; } diff --git a/libsolidity/inlineasm/AsmDataForward.h b/libsolidity/inlineasm/AsmDataForward.h index 317e257c..3a9600fe 100644 --- a/libsolidity/inlineasm/AsmDataForward.h +++ b/libsolidity/inlineasm/AsmDataForward.h @@ -53,6 +53,13 @@ struct TypedName; using Expression = boost::variant; using Statement = boost::variant; +enum class AsmFlavour +{ + Loose, // no types, EVM instructions as function, jumps and direct stack manipulations + Strict, // no types, EVM instructions as functions, but no jumps and no direct stack manipulations + IULIA // same as Strict mode with types +}; + } } } diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 20c7b2a5..5983d7ff 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -103,14 +103,14 @@ assembly::Statement Parser::parseStatement() return parseForLoop(); case Token::Assign: { - if (m_julia) + if (m_flavour != AsmFlavour::Loose) break; assembly::StackAssignment assignment = createWithLocation(); advance(); expectToken(Token::Colon); assignment.variableName.location = location(); assignment.variableName.name = currentLiteral(); - if (!m_julia && instructions().count(assignment.variableName.name)) + if (instructions().count(assignment.variableName.name)) fatalParserError("Identifier expected, got instruction name."); assignment.location.end = endPosition(); expectToken(Token::Identifier); @@ -170,7 +170,7 @@ assembly::Statement Parser::parseStatement() if (currentToken() == Token::Assign && peekNextToken() != Token::Colon) { assembly::Assignment assignment = createWithLocation(identifier.location); - if (!m_julia && instructions().count(identifier.name)) + if (m_flavour != AsmFlavour::IULIA && instructions().count(identifier.name)) fatalParserError("Cannot use instruction names for identifier names."); advance(); assignment.variableNames.emplace_back(identifier); @@ -181,7 +181,7 @@ assembly::Statement Parser::parseStatement() else { // label - if (m_julia) + if (m_flavour != AsmFlavour::Loose) fatalParserError("Labels are not supported."); Label label = createWithLocation