Remove m_code from IRValue

Only one place to append to m_code avoids confusion and bugs
This commit is contained in:
Mathias Baumann 2019-05-13 19:04:22 +02:00 committed by chriseth
parent 1d75770700
commit f5980f08cc
3 changed files with 16 additions and 27 deletions

View File

@ -131,7 +131,7 @@ bool IRGeneratorForStatements::visit(Assignment const& _assignment)
_assignment.leftHandSide().accept(*this); _assignment.leftHandSide().accept(*this);
solAssert(!!m_currentLValue, "LValue not retrieved."); solAssert(!!m_currentLValue, "LValue not retrieved.");
m_currentLValue->storeValue(intermediateValue, *intermediateType); m_code << m_currentLValue->storeValue(intermediateValue, *intermediateType);
m_currentLValue.reset(); m_currentLValue.reset();
defineExpression(_assignment) << intermediateValue << "\n"; defineExpression(_assignment) << intermediateValue << "\n";
@ -672,7 +672,6 @@ 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_code,
m_context, m_context,
slot, slot,
0, 0,
@ -728,9 +727,9 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
solUnimplementedAssert(!varDecl->isConstant(), ""); solUnimplementedAssert(!varDecl->isConstant(), "");
unique_ptr<IRLValue> lvalue; unique_ptr<IRLValue> lvalue;
if (m_context.isLocalVariable(*varDecl)) if (m_context.isLocalVariable(*varDecl))
lvalue = make_unique<IRLocalVariable>(m_code, m_context, *varDecl); lvalue = make_unique<IRLocalVariable>(m_context, *varDecl);
else if (m_context.isStateVariable(*varDecl)) else if (m_context.isStateVariable(*varDecl))
lvalue = make_unique<IRStorageItem>(m_code, m_context, *varDecl); lvalue = make_unique<IRStorageItem>(m_context, *varDecl);
else else
solAssert(false, "Invalid variable kind."); solAssert(false, "Invalid variable kind.");

View File

@ -31,27 +31,25 @@ using namespace dev;
using namespace dev::solidity; using namespace dev::solidity;
IRLocalVariable::IRLocalVariable( IRLocalVariable::IRLocalVariable(
ostream& _code,
IRGenerationContext& _context, IRGenerationContext& _context,
VariableDeclaration const& _varDecl VariableDeclaration const& _varDecl
): ):
IRLValue(_code, _context, _varDecl.annotation().type), IRLValue(_context, _varDecl.annotation().type),
m_variableName(_context.localVariableName(_varDecl)) m_variableName(_context.localVariableName(_varDecl))
{ {
} }
void IRLocalVariable::storeValue(string const& _value, Type const& _type) const string IRLocalVariable::storeValue(string const& _value, Type const& _type) const
{ {
solAssert(_type == *m_type, "Storing different types - not necessarily a problem."); solAssert(_type == *m_type, "Storing different types - not necessarily a problem.");
m_code << m_variableName << " := " << _value << "\n"; return m_variableName + " := " + _value + "\n";
} }
IRStorageItem::IRStorageItem( IRStorageItem::IRStorageItem(
ostream& _code,
IRGenerationContext& _context, IRGenerationContext& _context,
VariableDeclaration const& _varDecl VariableDeclaration const& _varDecl
): ):
IRLValue(_code, _context, _varDecl.annotation().type) IRLValue(_context, _varDecl.annotation().type)
{ {
u256 slot; u256 slot;
unsigned offset; unsigned offset;
@ -61,13 +59,12 @@ IRStorageItem::IRStorageItem(
} }
IRStorageItem::IRStorageItem( IRStorageItem::IRStorageItem(
ostream& _code,
IRGenerationContext& _context, IRGenerationContext& _context,
string _slot, string _slot,
unsigned _offset, unsigned _offset,
Type const& _type Type const& _type
): ):
IRLValue(_code, _context, &_type), IRLValue(_context, &_type),
m_slot(move(_slot)), m_slot(move(_slot)),
m_offset(_offset) m_offset(_offset)
{ {
@ -81,7 +78,7 @@ string IRStorageItem::retrieveValue() const
return m_context.utils().readFromStorage(*m_type, m_offset, false) + "(" + m_slot + ")"; return m_context.utils().readFromStorage(*m_type, m_offset, false) + "(" + m_slot + ")";
} }
void IRStorageItem::storeValue(string const& _value, Type const& _sourceType) const string IRStorageItem::storeValue(string const& _value, Type const& _sourceType) const
{ {
if (m_type->isValueType()) if (m_type->isValueType())
{ {
@ -91,8 +88,7 @@ void IRStorageItem::storeValue(string const& _value, Type const& _sourceType) co
solAssert(_sourceType == *m_type, "Different type, but might not be an error."); solAssert(_sourceType == *m_type, "Different type, but might not be an error.");
m_code << return Whiskers("sstore(<slot>, <update>(sload(<slot>), <prepare>(<value>)))\n")
Whiskers("sstore(<slot>, <update>(sload(<slot>), <prepare>(<value>)))\n")
("slot", m_slot) ("slot", m_slot)
("update", m_context.utils().updateByteSliceFunction(m_type->storageBytes(), m_offset)) ("update", m_context.utils().updateByteSliceFunction(m_type->storageBytes(), m_offset))
("prepare", m_context.utils().prepareStoreFunction(*m_type)) ("prepare", m_context.utils().prepareStoreFunction(*m_type))

View File

@ -38,23 +38,20 @@ class Type;
class IRLValue class IRLValue
{ {
protected: protected:
IRLValue(std::ostream& _code, IRGenerationContext& _context, Type const* _type = nullptr): IRLValue(IRGenerationContext& _context, Type const* _type = nullptr):
m_code(_code),
m_context(_context), m_context(_context),
m_type(_type) m_type(_type)
{} {}
public: public:
virtual ~IRLValue() = default; virtual ~IRLValue() = default;
/// @returns an expression to retrieve the value of the lvalue. This might also emit /// @returns an expression to retrieve the value of the lvalue.
/// code to m_code.
virtual std::string retrieveValue() const = 0; virtual std::string retrieveValue() const = 0;
/// Appends code to m_code to store the value of @a _value (should be an identifier) /// Returns code that stores the value of @a _value (should be an identifier)
/// of type @a _type in the lvalue. Might perform type conversion. /// of type @a _type in the lvalue. Might perform type conversion.
virtual void storeValue(std::string const& _value, Type const& _type) const = 0; virtual std::string storeValue(std::string const& _value, Type const& _type) const = 0;
protected: protected:
std::ostream& m_code;
IRGenerationContext& m_context; IRGenerationContext& m_context;
Type const* m_type; Type const* m_type;
}; };
@ -63,12 +60,11 @@ class IRLocalVariable: public IRLValue
{ {
public: public:
IRLocalVariable( IRLocalVariable(
std::ostream& _code,
IRGenerationContext& _context, IRGenerationContext& _context,
VariableDeclaration const& _varDecl VariableDeclaration const& _varDecl
); );
std::string retrieveValue() const override { return m_variableName; } std::string retrieveValue() const override { return m_variableName; }
void storeValue(std::string const& _value, Type const& _type) const override; std::string storeValue(std::string const& _value, Type const& _type) const override;
private: private:
std::string m_variableName; std::string m_variableName;
@ -78,19 +74,17 @@ class IRStorageItem: public IRLValue
{ {
public: public:
IRStorageItem( IRStorageItem(
std::ostream& _code,
IRGenerationContext& _context, IRGenerationContext& _context,
VariableDeclaration const& _varDecl VariableDeclaration const& _varDecl
); );
IRStorageItem( IRStorageItem(
std::ostream& _code,
IRGenerationContext& _context, IRGenerationContext& _context,
std::string _slot, std::string _slot,
unsigned _offset, unsigned _offset,
Type const& _type Type const& _type
); );
std::string retrieveValue() const override; std::string retrieveValue() const override;
void storeValue(std::string const& _value, Type const& _type) const override; std::string storeValue(std::string const& _value, Type const& _type) const override;
private: private:
std::string m_slot; std::string m_slot;