diff options
Diffstat (limited to 'source/slang/slang-state-serialize.cpp')
| -rw-r--r-- | source/slang/slang-state-serialize.cpp | 71 |
1 files changed, 67 insertions, 4 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; } |
