Refactor IRLValue so that it does not require IRGenerationContext.

This commit is contained in:
chriseth 2019-08-08 17:27:35 +02:00
parent 9955c51769
commit 74f16ef186
3 changed files with 50 additions and 38 deletions

View File

@ -797,7 +797,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
break; break;
case DataLocation::Storage: case DataLocation::Storage:
setLValue(_memberAccess, make_unique<IRStorageArrayLength>( setLValue(_memberAccess, make_unique<IRStorageArrayLength>(
m_context, m_context.utils(),
m_context.variable(_memberAccess.expression()), m_context.variable(_memberAccess.expression()),
*_memberAccess.annotation().type, *_memberAccess.annotation().type,
type type
@ -863,7 +863,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
templ("key", ", " + m_context.variable(*_indexAccess.indexExpression())); templ("key", ", " + m_context.variable(*_indexAccess.indexExpression()));
m_code << templ.render(); m_code << templ.render();
setLValue(_indexAccess, make_unique<IRStorageItem>( setLValue(_indexAccess, make_unique<IRStorageItem>(
m_context, m_context.utils(),
slot, slot,
0, 0,
*_indexAccess.annotation().type *_indexAccess.annotation().type
@ -892,7 +892,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
.render(); .render();
setLValue(_indexAccess, make_unique<IRStorageItem>( setLValue(_indexAccess, make_unique<IRStorageItem>(
m_context, m_context.utils(),
slot, slot,
offset, offset,
*_indexAccess.annotation().type *_indexAccess.annotation().type
@ -911,7 +911,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
")"; ")";
setLValue(_indexAccess, make_unique<IRMemoryItem>( setLValue(_indexAccess, make_unique<IRMemoryItem>(
m_context, m_context.utils(),
memAddress, memAddress,
false, false,
*arrayType.baseType() *arrayType.baseType()

View File

@ -35,7 +35,7 @@ IRLocalVariable::IRLocalVariable(
IRGenerationContext& _context, IRGenerationContext& _context,
VariableDeclaration const& _varDecl VariableDeclaration const& _varDecl
): ):
IRLValue(_context, _varDecl.annotation().type), IRLValue(_context.utils(), _varDecl.annotation().type),
m_variableName(_context.localVariableName(_varDecl)) m_variableName(_context.localVariableName(_varDecl))
{ {
} }
@ -48,7 +48,7 @@ string IRLocalVariable::storeValue(string const& _value, Type const& _type) cons
string IRLocalVariable::setToZero() const string IRLocalVariable::setToZero() const
{ {
return storeValue(m_context.utils().zeroValueFunction(*m_type) + "()", *m_type); return storeValue(m_utils.zeroValueFunction(*m_type) + "()", *m_type);
} }
IRStorageItem::IRStorageItem( IRStorageItem::IRStorageItem(
@ -56,31 +56,31 @@ IRStorageItem::IRStorageItem(
VariableDeclaration const& _varDecl VariableDeclaration const& _varDecl
): ):
IRStorageItem( IRStorageItem(
_context, _context.utils(),
*_varDecl.annotation().type, *_varDecl.annotation().type,
_context.storageLocationOfVariable(_varDecl) _context.storageLocationOfVariable(_varDecl)
) )
{ } { }
IRStorageItem::IRStorageItem( IRStorageItem::IRStorageItem(
IRGenerationContext& _context, YulUtilFunctions _utils,
Type const& _type, Type const& _type,
std::pair<u256, unsigned> slot_offset std::pair<u256, unsigned> slot_offset
): ):
IRLValue(_context, &_type), IRLValue(std::move(_utils), &_type),
m_slot(toCompactHexWithPrefix(slot_offset.first)), m_slot(toCompactHexWithPrefix(slot_offset.first)),
m_offset(slot_offset.second) m_offset(slot_offset.second)
{ {
} }
IRStorageItem::IRStorageItem( IRStorageItem::IRStorageItem(
IRGenerationContext& _context, YulUtilFunctions _utils,
string _slot, string _slot,
boost::variant<string, unsigned> _offset, boost::variant<string, unsigned> _offset,
Type const& _type Type const& _type
): ):
IRLValue(_context, &_type), IRLValue(std::move(_utils), &_type),
m_slot(move(_slot)), m_slot(std::move(_slot)),
m_offset(std::move(_offset)) m_offset(std::move(_offset))
{ {
solAssert(!m_offset.empty(), ""); solAssert(!m_offset.empty(), "");
@ -94,7 +94,7 @@ string IRStorageItem::retrieveValue() const
solUnimplementedAssert(m_type->category() != Type::Category::Function, ""); solUnimplementedAssert(m_type->category() != Type::Category::Function, "");
if (m_offset.type() == typeid(string)) if (m_offset.type() == typeid(string))
return return
m_context.utils().readFromStorageDynamic(*m_type, false) + m_utils.readFromStorageDynamic(*m_type, false) +
"(" + "(" +
m_slot + m_slot +
", " + ", " +
@ -102,7 +102,7 @@ string IRStorageItem::retrieveValue() const
")"; ")";
else if (m_offset.type() == typeid(unsigned)) else if (m_offset.type() == typeid(unsigned))
return return
m_context.utils().readFromStorage(*m_type, boost::get<unsigned>(m_offset), false) + m_utils.readFromStorage(*m_type, boost::get<unsigned>(m_offset), false) +
"(" + "(" +
m_slot + m_slot +
")"; ")";
@ -121,7 +121,7 @@ string IRStorageItem::storeValue(string const& _value, Type const& _sourceType)
offset = get<unsigned>(m_offset); offset = get<unsigned>(m_offset);
return return
m_context.utils().updateStorageValueFunction(*m_type, offset) + m_utils.updateStorageValueFunction(*m_type, offset) +
"(" + "(" +
m_slot + m_slot +
(m_offset.type() == typeid(string) ? (m_offset.type() == typeid(string) ?
@ -136,7 +136,7 @@ string IRStorageItem::storeValue(string const& _value, Type const& _sourceType)
string IRStorageItem::setToZero() const string IRStorageItem::setToZero() const
{ {
return return
m_context.utils().storageSetToZeroFunction(*m_type) + m_utils.storageSetToZeroFunction(*m_type) +
"(" + "(" +
m_slot + m_slot +
", " + ", " +
@ -148,22 +148,27 @@ string IRStorageItem::setToZero() const
")\n"; ")\n";
} }
IRStorageArrayLength::IRStorageArrayLength(IRGenerationContext& _context, string _slot, Type const& _type, ArrayType const& _arrayType): IRStorageArrayLength::IRStorageArrayLength(
IRLValue(_context, &_type), m_arrayType(_arrayType), m_slot(move(_slot)) YulUtilFunctions _utils,
string _slot,
Type const& _type,
ArrayType const& _arrayType
):
IRLValue(std::move(_utils), &_type), m_arrayType(_arrayType), m_slot(move(_slot))
{ {
solAssert(*m_type == *TypeProvider::uint256(), "Must be uint256!"); solAssert(*m_type == *TypeProvider::uint256(), "Must be uint256!");
} }
string IRStorageArrayLength::retrieveValue() const string IRStorageArrayLength::retrieveValue() const
{ {
return m_context.utils().arrayLengthFunction(m_arrayType) + "(" + m_slot + ")"; return m_utils.arrayLengthFunction(m_arrayType) + "(" + m_slot + ")";
} }
string IRStorageArrayLength::storeValue(std::string const& _value, Type const& _type) const string IRStorageArrayLength::storeValue(std::string const& _value, Type const& _type) const
{ {
solAssert(_type == *m_type, "Different type, but might not be an error."); solAssert(_type == *m_type, "Different type, but might not be an error.");
return m_context.utils().resizeDynamicArrayFunction(m_arrayType) + return m_utils.resizeDynamicArrayFunction(m_arrayType) +
"(" + "(" +
m_slot + m_slot +
", " + ", " +
@ -177,12 +182,12 @@ string IRStorageArrayLength::setToZero() const
} }
IRMemoryItem::IRMemoryItem( IRMemoryItem::IRMemoryItem(
IRGenerationContext& _context, YulUtilFunctions _utils,
std::string _address, std::string _address,
bool _byteArrayElement, bool _byteArrayElement,
Type const& _type Type const& _type
): ):
IRLValue(_context, &_type), IRLValue(std::move(_utils), &_type),
m_address(move(_address)), m_address(move(_address)),
m_byteArrayElement(_byteArrayElement) m_byteArrayElement(_byteArrayElement)
{ } { }
@ -190,13 +195,13 @@ IRMemoryItem::IRMemoryItem(
string IRMemoryItem::retrieveValue() const string IRMemoryItem::retrieveValue() const
{ {
if (m_byteArrayElement) if (m_byteArrayElement)
return m_context.utils().cleanupFunction(*m_type) + return m_utils.cleanupFunction(*m_type) +
"(mload(" + "(mload(" +
m_address + m_address +
"))"; "))";
if (m_type->isValueType()) if (m_type->isValueType())
return m_context.utils().readFromMemory(*m_type) + return m_utils.readFromMemory(*m_type) +
"(" + "(" +
m_address + m_address +
")"; ")";
@ -225,13 +230,13 @@ string IRMemoryItem::storeValue(string const& _value, Type const& _type) const
if (_type != *m_type) if (_type != *m_type)
prepared = prepared =
m_context.utils().conversionFunction(_type, *m_type) + m_utils.conversionFunction(_type, *m_type) +
"(" + "(" +
_value + _value +
")"; ")";
else else
prepared = prepared =
m_context.utils().cleanupFunction(*m_type) + m_utils.cleanupFunction(*m_type) +
"(" + "(" +
_value + _value +
")"; ")";
@ -242,7 +247,7 @@ string IRMemoryItem::storeValue(string const& _value, Type const& _type) const
return "mstore8(" + m_address + ", byte(0, " + prepared + "))\n"; return "mstore8(" + m_address + ", byte(0, " + prepared + "))\n";
} }
else else
return m_context.utils().writeToMemoryFunction(*m_type) + return m_utils.writeToMemoryFunction(*m_type) +
"(" + "(" +
m_address + m_address +
", " + ", " +
@ -252,5 +257,5 @@ string IRMemoryItem::storeValue(string const& _value, Type const& _type) const
string IRMemoryItem::setToZero() const string IRMemoryItem::setToZero() const
{ {
return storeValue(m_context.utils().zeroValueFunction(*m_type) + "()", *m_type); return storeValue(m_utils.zeroValueFunction(*m_type) + "()", *m_type);
} }

View File

@ -20,6 +20,8 @@
#pragma once #pragma once
#include <libsolidity/codegen/YulUtilFunctions.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <string> #include <string>
@ -42,8 +44,8 @@ class ArrayType;
class IRLValue class IRLValue
{ {
protected: protected:
IRLValue(IRGenerationContext& _context, Type const* _type = nullptr): explicit IRLValue(YulUtilFunctions _utils, Type const* _type = nullptr):
m_context(_context), m_utils(std::move(_utils)),
m_type(_type) m_type(_type)
{} {}
@ -58,7 +60,7 @@ public:
/// Returns code that will reset the stored value to zero /// Returns code that will reset the stored value to zero
virtual std::string setToZero() const = 0; virtual std::string setToZero() const = 0;
protected: protected:
IRGenerationContext& m_context; YulUtilFunctions mutable m_utils;
Type const* m_type; Type const* m_type;
}; };
@ -85,7 +87,7 @@ public:
VariableDeclaration const& _varDecl VariableDeclaration const& _varDecl
); );
IRStorageItem( IRStorageItem(
IRGenerationContext& _context, YulUtilFunctions _utils,
std::string _slot, std::string _slot,
boost::variant<std::string, unsigned> _offset, boost::variant<std::string, unsigned> _offset,
Type const& _type Type const& _type
@ -96,7 +98,7 @@ public:
std::string setToZero() const override; std::string setToZero() const override;
private: private:
IRStorageItem( IRStorageItem(
IRGenerationContext& _context, YulUtilFunctions _utils,
Type const& _type, Type const& _type,
std::pair<u256, unsigned> slot_offset std::pair<u256, unsigned> slot_offset
); );
@ -116,7 +118,12 @@ private:
class IRStorageArrayLength: public IRLValue class IRStorageArrayLength: public IRLValue
{ {
public: public:
IRStorageArrayLength(IRGenerationContext& _context, std::string _slot, Type const& _type, ArrayType const& _arrayType); IRStorageArrayLength(
YulUtilFunctions _utils,
std::string _slot,
Type const& _type,
ArrayType const& _arrayType
);
std::string retrieveValue() const override; std::string retrieveValue() const override;
std::string storeValue(std::string const& _value, Type const& _type) const override; std::string storeValue(std::string const& _value, Type const& _type) const override;
@ -131,7 +138,7 @@ class IRMemoryItem: public IRLValue
{ {
public: public:
IRMemoryItem( IRMemoryItem(
IRGenerationContext& _context, YulUtilFunctions _utils,
std::string _address, std::string _address,
bool _byteArrayElement, bool _byteArrayElement,
Type const& _type Type const& _type