Lazy-initialize string and bytes types.

This commit is contained in:
chriseth 2019-04-16 19:45:25 +02:00
parent 4656d7ca7d
commit 2761aed1d3
2 changed files with 50 additions and 13 deletions

View File

@ -26,10 +26,14 @@ using namespace solidity;
BoolType const TypeProvider::m_boolType{};
InaccessibleDynamicType const TypeProvider::m_inaccessibleDynamicType{};
ArrayType const TypeProvider::m_bytesStorageType{DataLocation::Storage, false};
ArrayType const TypeProvider::m_bytesMemoryType{DataLocation::Memory, false};
ArrayType const TypeProvider::m_stringStorageType{DataLocation::Storage, true};
ArrayType const TypeProvider::m_stringMemoryType{DataLocation::Memory, true};
/// The string and bytes unique_ptrs are initialized when they are first used because
/// they rely on `byte` being available which we cannot guarantee in the static init context.
std::unique_ptr<ArrayType> TypeProvider::m_bytesStorageType;
std::unique_ptr<ArrayType> TypeProvider::m_bytesMemoryType;
std::unique_ptr<ArrayType> TypeProvider::m_stringStorageType;
std::unique_ptr<ArrayType> TypeProvider::m_stringMemoryType;
TupleType const TypeProvider::m_emptyTupleType{};
AddressType const TypeProvider::m_payableAddressType{StateMutability::Payable};
AddressType const TypeProvider::m_addressType{StateMutability::NonPayable};
@ -155,7 +159,9 @@ inline void clearCache(Type const& type)
template <typename T>
inline void clearCache(unique_ptr<T> const& type)
{
type->clearCache();
// Some lazy-initialized types might not exist yet.
if (type)
type->clearCache();
}
template <typename Container>
@ -287,6 +293,34 @@ TypePointer TypeProvider::fromElementaryTypeName(string const& _name)
}
}
ArrayType const* TypeProvider::bytesType()
{
if (!m_bytesStorageType)
m_bytesStorageType = make_unique<ArrayType>(DataLocation::Storage, false);
return m_bytesStorageType.get();
}
ArrayType const* TypeProvider::bytesMemoryType()
{
if (!m_bytesMemoryType)
m_bytesMemoryType = make_unique<ArrayType>(DataLocation::Memory, false);
return m_bytesMemoryType.get();
}
ArrayType const* TypeProvider::stringType()
{
if (!m_stringStorageType)
m_stringStorageType = make_unique<ArrayType>(DataLocation::Storage, true);
return m_stringStorageType.get();
}
ArrayType const* TypeProvider::stringMemoryType()
{
if (!m_stringMemoryType)
m_stringMemoryType = make_unique<ArrayType>(DataLocation::Memory, true);
return m_stringMemoryType.get();
}
TypePointer TypeProvider::forLiteral(Literal const& _literal)
{
switch (_literal.token())

View File

@ -66,10 +66,10 @@ public:
static FixedBytesType const* byteType() { return fixedBytesType(1); }
static FixedBytesType const* fixedBytesType(unsigned m) { return m_bytesM.at(m - 1).get(); }
static ArrayType const* bytesType() noexcept { return &m_bytesStorageType; }
static ArrayType const* bytesMemoryType() noexcept { return &m_bytesMemoryType; }
static ArrayType const* stringType() noexcept { return &m_stringStorageType; }
static ArrayType const* stringMemoryType() noexcept { return &m_stringMemoryType; }
static ArrayType const* bytesType();
static ArrayType const* bytesMemoryType();
static ArrayType const* stringType();
static ArrayType const* stringMemoryType();
/// Constructor for a byte array ("bytes") and string.
static ArrayType const* arrayType(DataLocation _location, bool _isString = false);
@ -199,10 +199,13 @@ private:
static BoolType const m_boolType;
static InaccessibleDynamicType const m_inaccessibleDynamicType;
static ArrayType const m_bytesStorageType;
static ArrayType const m_bytesMemoryType;
static ArrayType const m_stringStorageType;
static ArrayType const m_stringMemoryType;
/// These are lazy-initialized because they depend on `byte` being available.
static std::unique_ptr<ArrayType> m_bytesStorageType;
static std::unique_ptr<ArrayType> m_bytesMemoryType;
static std::unique_ptr<ArrayType> m_stringStorageType;
static std::unique_ptr<ArrayType> m_stringMemoryType;
static TupleType const m_emptyTupleType;
static AddressType const m_payableAddressType;
static AddressType const m_addressType;