mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Support true/false literals in inline assembly
This commit is contained in:
parent
cc9a99a63f
commit
edd0afa3c3
@ -72,7 +72,7 @@ bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
|
|||||||
bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
|
bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
|
||||||
{
|
{
|
||||||
++m_stackHeight;
|
++m_stackHeight;
|
||||||
if (!_literal.isNumber && _literal.value.size() > 32)
|
if (_literal.kind == assembly::LiteralKind::String && _literal.value.size() > 32)
|
||||||
{
|
{
|
||||||
m_errors.push_back(make_shared<Error>(
|
m_errors.push_back(make_shared<Error>(
|
||||||
Error::Type::TypeError,
|
Error::Type::TypeError,
|
||||||
|
@ -118,8 +118,15 @@ public:
|
|||||||
void operator()(assembly::Literal const& _literal)
|
void operator()(assembly::Literal const& _literal)
|
||||||
{
|
{
|
||||||
m_state.assembly.setSourceLocation(_literal.location);
|
m_state.assembly.setSourceLocation(_literal.location);
|
||||||
if (_literal.isNumber)
|
if (_literal.kind == assembly::LiteralKind::Number)
|
||||||
m_state.assembly.append(u256(_literal.value));
|
m_state.assembly.append(u256(_literal.value));
|
||||||
|
else if (_literal.kind == assembly::LiteralKind::Boolean)
|
||||||
|
{
|
||||||
|
if (_literal.value == "true")
|
||||||
|
m_state.assembly.append(u256(1));
|
||||||
|
else
|
||||||
|
m_state.assembly.append(u256(0));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
solAssert(_literal.value.size() <= 32, "");
|
solAssert(_literal.value.size() <= 32, "");
|
||||||
|
@ -43,7 +43,8 @@ using TypedNameList = std::vector<TypedName>;
|
|||||||
/// 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)
|
||||||
struct Literal { SourceLocation location; bool isNumber; std::string value; Type type; };
|
enum class LiteralKind { Number, Boolean, String };
|
||||||
|
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;
|
struct FunctionalInstruction;
|
||||||
|
@ -206,10 +206,29 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher)
|
|||||||
}
|
}
|
||||||
case Token::StringLiteral:
|
case Token::StringLiteral:
|
||||||
case Token::Number:
|
case Token::Number:
|
||||||
|
case Token::TrueLiteral:
|
||||||
|
case Token::FalseLiteral:
|
||||||
{
|
{
|
||||||
|
LiteralKind kind = LiteralKind::Number;
|
||||||
|
switch (m_scanner->currentToken())
|
||||||
|
{
|
||||||
|
case Token::StringLiteral:
|
||||||
|
kind = LiteralKind::String;
|
||||||
|
break;
|
||||||
|
case Token::Number:
|
||||||
|
kind = LiteralKind::Number;
|
||||||
|
break;
|
||||||
|
case Token::TrueLiteral:
|
||||||
|
case Token::FalseLiteral:
|
||||||
|
kind = LiteralKind::Boolean;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Literal literal{
|
Literal literal{
|
||||||
location(),
|
location(),
|
||||||
m_scanner->currentToken() == Token::Number,
|
kind,
|
||||||
m_scanner->currentLiteral(),
|
m_scanner->currentLiteral(),
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
@ -220,6 +239,8 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher)
|
|||||||
literal.location.end = endPosition();
|
literal.location.end = endPosition();
|
||||||
literal.type = expectAsmIdentifier();
|
literal.type = expectAsmIdentifier();
|
||||||
}
|
}
|
||||||
|
else if (kind == LiteralKind::Boolean)
|
||||||
|
fatalParserError("True and false are not valid literals.");
|
||||||
ret = std::move(literal);
|
ret = std::move(literal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,16 @@ string AsmPrinter::operator()(assembly::Instruction const& _instruction)
|
|||||||
|
|
||||||
string AsmPrinter::operator()(assembly::Literal const& _literal)
|
string AsmPrinter::operator()(assembly::Literal const& _literal)
|
||||||
{
|
{
|
||||||
if (_literal.isNumber)
|
switch (_literal.kind)
|
||||||
|
{
|
||||||
|
case LiteralKind::Number:
|
||||||
return _literal.value + appendTypeName(_literal.type);
|
return _literal.value + appendTypeName(_literal.type);
|
||||||
|
case LiteralKind::Boolean:
|
||||||
|
return ((_literal.value == "true") ? "true" : "false") + appendTypeName(_literal.type);
|
||||||
|
case LiteralKind::String:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
string out;
|
string out;
|
||||||
for (char c: _literal.value)
|
for (char c: _literal.value)
|
||||||
if (c == '\\')
|
if (c == '\\')
|
||||||
|
Loading…
Reference in New Issue
Block a user