mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6193 from ethereum/yul-opt-different-types-6181
YulOpt: Extend StructuralSimplifier to work with all types
This commit is contained in:
commit
4740dc62df
@ -24,6 +24,7 @@
|
|||||||
#include <libyul/Exceptions.h>
|
#include <libyul/Exceptions.h>
|
||||||
|
|
||||||
#include <libdevcore/CommonData.h>
|
#include <libdevcore/CommonData.h>
|
||||||
|
#include <libdevcore/FixedHash.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
@ -31,12 +32,48 @@ using namespace yul;
|
|||||||
|
|
||||||
u256 yul::valueOfNumberLiteral(Literal const& _literal)
|
u256 yul::valueOfNumberLiteral(Literal const& _literal)
|
||||||
{
|
{
|
||||||
assertThrow(_literal.kind == LiteralKind::Number, OptimizerException, "");
|
yulAssert(_literal.kind == LiteralKind::Number, "Expected number literal!");
|
||||||
|
|
||||||
std::string const& literalString = _literal.value.str();
|
std::string const& literalString = _literal.value.str();
|
||||||
assertThrow(isValidDecimal(literalString) || isValidHex(literalString), OptimizerException, "");
|
yulAssert(isValidDecimal(literalString) || isValidHex(literalString), "Invalid number literal!");
|
||||||
return u256(literalString);
|
return u256(literalString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u256 yul::valueOfStringLiteral(Literal const& _literal)
|
||||||
|
{
|
||||||
|
yulAssert(_literal.kind == LiteralKind::String, "Expected string literal!");
|
||||||
|
yulAssert(_literal.value.str().size() <= 32, "Literal string too long!");
|
||||||
|
|
||||||
|
return u256(h256(_literal.value.str(), h256::FromBinary, h256::AlignLeft));
|
||||||
|
}
|
||||||
|
|
||||||
|
u256 yul::valueOfBoolLiteral(Literal const& _literal)
|
||||||
|
{
|
||||||
|
yulAssert(_literal.kind == LiteralKind::Boolean, "Expected bool literal!");
|
||||||
|
|
||||||
|
if (_literal.value == "true"_yulstring)
|
||||||
|
return u256(1);
|
||||||
|
else if (_literal.value == "false"_yulstring)
|
||||||
|
return u256(0);
|
||||||
|
|
||||||
|
yulAssert(false, "Unexpected bool literal value!");
|
||||||
|
}
|
||||||
|
|
||||||
|
u256 yul::valueOfLiteral(Literal const& _literal)
|
||||||
|
{
|
||||||
|
switch(_literal.kind)
|
||||||
|
{
|
||||||
|
case LiteralKind::Number:
|
||||||
|
return valueOfNumberLiteral(_literal);
|
||||||
|
case LiteralKind::Boolean:
|
||||||
|
return valueOfBoolLiteral(_literal);
|
||||||
|
case LiteralKind::String:
|
||||||
|
return valueOfStringLiteral(_literal);
|
||||||
|
default:
|
||||||
|
yulAssert(false, "Unexpected literal kind!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
bool Less<Literal>::operator()(Literal const& _lhs, Literal const& _rhs) const
|
bool Less<Literal>::operator()(Literal const& _lhs, Literal const& _rhs) const
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,9 @@ namespace yul
|
|||||||
{
|
{
|
||||||
|
|
||||||
dev::u256 valueOfNumberLiteral(Literal const& _literal);
|
dev::u256 valueOfNumberLiteral(Literal const& _literal);
|
||||||
|
dev::u256 valueOfStringLiteral(Literal const& _literal);
|
||||||
|
dev::u256 valueOfBoolLiteral(Literal const& _literal);
|
||||||
|
dev::u256 valueOfLiteral(Literal const& _literal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linear order on Yul AST nodes.
|
* Linear order on Yul AST nodes.
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <libyul/optimiser/NameCollector.h>
|
#include <libyul/optimiser/NameCollector.h>
|
||||||
#include <libyul/AsmAnalysisInfo.h>
|
#include <libyul/AsmAnalysisInfo.h>
|
||||||
#include <libyul/AsmData.h>
|
#include <libyul/AsmData.h>
|
||||||
|
#include <libyul/Utilities.h>
|
||||||
|
|
||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
|
|
||||||
@ -396,20 +397,8 @@ void CodeTransform::operator()(Identifier const& _identifier)
|
|||||||
void CodeTransform::operator()(Literal const& _literal)
|
void CodeTransform::operator()(Literal const& _literal)
|
||||||
{
|
{
|
||||||
m_assembly.setSourceLocation(_literal.location);
|
m_assembly.setSourceLocation(_literal.location);
|
||||||
if (_literal.kind == LiteralKind::Number)
|
m_assembly.appendConstant(valueOfLiteral(_literal));
|
||||||
m_assembly.appendConstant(u256(_literal.value.str()));
|
|
||||||
else if (_literal.kind == LiteralKind::Boolean)
|
|
||||||
{
|
|
||||||
if (_literal.value == "true"_yulstring)
|
|
||||||
m_assembly.appendConstant(u256(1));
|
|
||||||
else
|
|
||||||
m_assembly.appendConstant(u256(0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
solAssert(_literal.value.str().size() <= 32, "");
|
|
||||||
m_assembly.appendConstant(u256(h256(_literal.value.str(), h256::FromBinary, h256::AlignLeft)));
|
|
||||||
}
|
|
||||||
checkStackHeight(&_literal);
|
checkStackHeight(&_literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ boost::optional<dev::u256> StructuralSimplifier::hasLiteralValue(Expression cons
|
|||||||
if (expr && expr->type() == typeid(Literal))
|
if (expr && expr->type() == typeid(Literal))
|
||||||
{
|
{
|
||||||
Literal const& literal = boost::get<Literal>(*expr);
|
Literal const& literal = boost::get<Literal>(*expr);
|
||||||
return valueOfNumberLiteral(literal);
|
return valueOfLiteral(literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::optional<u256>();
|
return boost::optional<u256>();
|
||||||
@ -114,7 +114,7 @@ void StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)
|
|||||||
|
|
||||||
for (auto& _case: _switchStmt.cases)
|
for (auto& _case: _switchStmt.cases)
|
||||||
{
|
{
|
||||||
if (_case.value && valueOfNumberLiteral(*_case.value) == constExprVal)
|
if (_case.value && valueOfLiteral(*_case.value) == constExprVal)
|
||||||
{
|
{
|
||||||
matchingCaseBlock = &_case.body;
|
matchingCaseBlock = &_case.body;
|
||||||
break;
|
break;
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
// Used to cause assert error
|
||||||
|
let y := 200
|
||||||
|
switch 3
|
||||||
|
case "" { y := 8 }
|
||||||
|
case 1 { y := 9 }
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// structuralSimplifier
|
||||||
|
// {
|
||||||
|
// let y := 200
|
||||||
|
// }
|
@ -155,20 +155,7 @@ void ExpressionEvaluator::operator()(Literal const& _literal)
|
|||||||
static YulString const trueString("true");
|
static YulString const trueString("true");
|
||||||
static YulString const falseString("false");
|
static YulString const falseString("false");
|
||||||
|
|
||||||
switch (_literal.kind)
|
setValue(valueOfLiteral(_literal));
|
||||||
{
|
|
||||||
case LiteralKind::Boolean:
|
|
||||||
solAssert(_literal.value == trueString || _literal.value == falseString, "");
|
|
||||||
setValue(_literal.value == trueString ? 1 : 0);
|
|
||||||
break;
|
|
||||||
case LiteralKind::Number:
|
|
||||||
setValue(valueOfNumberLiteral(_literal));
|
|
||||||
break;
|
|
||||||
case LiteralKind::String:
|
|
||||||
solAssert(_literal.value.str().size() <= 32, "");
|
|
||||||
setValue(u256(h256(_literal.value.str(), h256::FromBinary, h256::AlignLeft)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionEvaluator::operator()(Identifier const& _identifier)
|
void ExpressionEvaluator::operator()(Identifier const& _identifier)
|
||||||
|
Loading…
Reference in New Issue
Block a user