diff options
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/slang-state-serialize.cpp | 71 | ||||
| -rw-r--r-- | source/slang/slang-state-serialize.h | 21 |
2 files changed, 79 insertions, 13 deletions
diff --git a/source/slang/slang-state-serialize.cpp b/source/slang/slang-state-serialize.cpp index cbcce6c3a..13dd8b132 100644 --- a/source/slang/slang-state-serialize.cpp +++ b/source/slang/slang-state-serialize.cpp @@ -9,6 +9,53 @@ namespace Slang { +/* static */const RiffSemanticVersion StateSerializeUtil::g_semanticVersion = + RiffSemanticVersion::make(StateSerializeUtil::kMajorVersion, StateSerializeUtil::kMinorVersion, StateSerializeUtil::kPatchVersion); + +// A function to calculate the hash related in list in part to how the types used are sized. Can catch crude breaking binary differences. +static uint32_t _calcTypeHash() +{ + typedef StateSerializeUtil Util; + + const size_t sizes[] = + { + sizeof(Util::FileState), + sizeof(Util::PathInfoState), + sizeof(Util::PathInfoState::CompressedResult), + sizeof(SlangPathType), + sizeof(Util::PathAndPathInfo), + sizeof(Util::TargetRequestState), + sizeof(Profile), + sizeof(CodeGenTarget), + sizeof(SlangTargetFlags), + sizeof(FloatingPointMode), + sizeof(Util::StringPair), + sizeof(Util::SourceFileState), + sizeof(PathInfo::Type), + sizeof(Util::TranslationUnitRequestState), + sizeof(SourceLanguage), + sizeof(Util::EntryPointState), + sizeof(Profile), + sizeof(Util::RequestState), + sizeof(SlangCompileFlags), + sizeof(bool), //< Unfortunately bools size can change across compilers/versions + sizeof(LineDirectiveMode), + sizeof(DebugInfoLevel), + sizeof(OptimizationLevel), + sizeof(ContainerFormat), + sizeof(PassThroughMode), + sizeof(SlangMatrixLayoutMode), + }; + + return uint32_t(GetHashCode((const char*)&sizes, sizeof(sizes))); +} + +static uint32_t _getTypeHash() +{ + static uint32_t s_hash = _calcTypeHash(); + return s_hash; +} + namespace { // anonymous @@ -866,7 +913,13 @@ static void _loadDefines(const Relative32Array<StateSerializeUtil::StringPair>& RelativeContainer container; Safe32Ptr<RequestState> requestState; SLANG_RETURN_ON_FAIL(store(request, container, requestState)); - return RiffUtil::writeData(kSlangStateFourCC, container.getData(), container.getDataCount(), stream); + + Header header; + header.m_chunk.m_type = kSlangStateFourCC; + header.m_semanticVersion = g_semanticVersion; + header.m_typeHash = _getTypeHash(); + + return RiffUtil::writeData(&header.m_chunk, sizeof(header),container.getData(), container.getDataCount(), stream); } /* static */SlangResult StateSerializeUtil::saveState(EndToEndCompileRequest* request, const String& filename) @@ -892,10 +945,20 @@ static void _loadDefines(const Relative32Array<StateSerializeUtil::StringPair>& /* static */ SlangResult StateSerializeUtil::loadState(Stream* stream, List<uint8_t>& buffer) { - RiffChunk chunk; - SLANG_RETURN_ON_FAIL(RiffUtil::readData(stream, chunk, buffer)); + Header header; + + SLANG_RETURN_ON_FAIL(RiffUtil::readData(stream, &header.m_chunk, sizeof(header), buffer)); + if (header.m_chunk.m_type != kSlangStateFourCC) + { + return SLANG_FAIL; + } + + if (!RiffSemanticVersion::areCompatible(g_semanticVersion, header.m_semanticVersion)) + { + return SLANG_FAIL; + } - if (chunk.m_type != kSlangStateFourCC) + if (header.m_typeHash != _getTypeHash()) { return SLANG_FAIL; } diff --git a/source/slang/slang-state-serialize.h b/source/slang/slang-state-serialize.h index dbd1e3992..42edd4080 100644 --- a/source/slang/slang-state-serialize.h +++ b/source/slang/slang-state-serialize.h @@ -16,12 +16,21 @@ namespace Slang { struct StateSerializeUtil { + enum + { + kMajorVersion = 0, + kMinorVersion = 0, + kPatchVersion = 0, + }; + static const uint32_t kSlangStateFourCC = SLANG_FOUR_CC('S', 'L', 'S', 'T'); ///< Holds all the slang specific chunks - + static const RiffSemanticVersion g_semanticVersion; + struct Header { - RiffChunk m_chunk; - uint32_t m_compressionType; ///< Holds the compression type used (if used at all) + RiffChunk m_chunk; ///< The chunk + RiffSemanticVersion m_semanticVersion; ///< The semantic version + uint32_t m_typeHash; ///< A hash based on the binary representation. If doesn't match then not binary compatible (extra check over semantic versioning) }; struct FileState @@ -73,12 +82,6 @@ struct StateSerializeUtil Relative32Array<OutputState> outputStates; }; - struct FileReference - { - Relative32Ptr<RelativeString> name; - Relative32Ptr<FileState> file; - }; - struct StringPair { Relative32Ptr<RelativeString> first; |
