From 2761aed1d391570cd919760c0e1b342eff2ff014 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 16 Apr 2019 19:45:25 +0200 Subject: [PATCH] Lazy-initialize string and bytes types. --- libsolidity/ast/TypeProvider.cpp | 44 ++++++++++++++++++++++++++++---- libsolidity/ast/TypeProvider.h | 19 ++++++++------ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/libsolidity/ast/TypeProvider.cpp b/libsolidity/ast/TypeProvider.cpp index 35adaf037..7e876039b 100644 --- a/libsolidity/ast/TypeProvider.cpp +++ b/libsolidity/ast/TypeProvider.cpp @@ -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 TypeProvider::m_bytesStorageType; +std::unique_ptr TypeProvider::m_bytesMemoryType; +std::unique_ptr TypeProvider::m_stringStorageType; +std::unique_ptr 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 inline void clearCache(unique_ptr const& type) { - type->clearCache(); + // Some lazy-initialized types might not exist yet. + if (type) + type->clearCache(); } template @@ -287,6 +293,34 @@ TypePointer TypeProvider::fromElementaryTypeName(string const& _name) } } +ArrayType const* TypeProvider::bytesType() +{ + if (!m_bytesStorageType) + m_bytesStorageType = make_unique(DataLocation::Storage, false); + return m_bytesStorageType.get(); +} + +ArrayType const* TypeProvider::bytesMemoryType() +{ + if (!m_bytesMemoryType) + m_bytesMemoryType = make_unique(DataLocation::Memory, false); + return m_bytesMemoryType.get(); +} + +ArrayType const* TypeProvider::stringType() +{ + if (!m_stringStorageType) + m_stringStorageType = make_unique(DataLocation::Storage, true); + return m_stringStorageType.get(); +} + +ArrayType const* TypeProvider::stringMemoryType() +{ + if (!m_stringMemoryType) + m_stringMemoryType = make_unique(DataLocation::Memory, true); + return m_stringMemoryType.get(); +} + TypePointer TypeProvider::forLiteral(Literal const& _literal) { switch (_literal.token()) diff --git a/libsolidity/ast/TypeProvider.h b/libsolidity/ast/TypeProvider.h index 5e52ba759..979ae8325 100644 --- a/libsolidity/ast/TypeProvider.h +++ b/libsolidity/ast/TypeProvider.h @@ -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 m_bytesStorageType; + static std::unique_ptr m_bytesMemoryType; + static std::unique_ptr m_stringStorageType; + static std::unique_ptr m_stringMemoryType; + static TupleType const m_emptyTupleType; static AddressType const m_payableAddressType; static AddressType const m_addressType;