diff options
| author | Theresa Foley <10618364+tangent-vector@users.noreply.github.com> | 2025-05-12 10:28:05 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-12 17:28:05 +0000 |
| commit | 4c76b275907cf2d764f3fc51468d1c58635a10c1 (patch) | |
| tree | 201a353c2b64b258760c370e641821ec5f6eff85 /source/slang | |
| parent | 6b286bfbdf85e40cac1ee325384f535df969938a (diff) | |
Cleanups related to RIFF support (#7041)
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/slang-compiler.h | 14 | ||||
| -rw-r--r-- | source/slang/slang-emit-cuda.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 25 | ||||
| -rw-r--r-- | source/slang/slang-module-library.cpp | 32 | ||||
| -rw-r--r-- | source/slang/slang-repro.cpp | 99 | ||||
| -rw-r--r-- | source/slang/slang-repro.h | 13 | ||||
| -rw-r--r-- | source/slang/slang-serialize-ast.cpp | 43 | ||||
| -rw-r--r-- | source/slang/slang-serialize-ast.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-serialize-container.cpp | 284 | ||||
| -rw-r--r-- | source/slang/slang-serialize-container.h | 181 | ||||
| -rw-r--r-- | source/slang/slang-serialize-ir-types.h | 12 | ||||
| -rw-r--r-- | source/slang/slang-serialize-ir.cpp | 42 | ||||
| -rw-r--r-- | source/slang/slang-serialize-ir.h | 7 | ||||
| -rw-r--r-- | source/slang/slang-serialize-source-loc.cpp | 25 | ||||
| -rw-r--r-- | source/slang/slang-serialize-source-loc.h | 14 | ||||
| -rw-r--r-- | source/slang/slang-serialize-types.cpp | 25 | ||||
| -rw-r--r-- | source/slang/slang-serialize-types.h | 78 | ||||
| -rw-r--r-- | source/slang/slang-serialize.h | 154 | ||||
| -rw-r--r-- | source/slang/slang-type-layout.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 185 |
21 files changed, 600 insertions, 647 deletions
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 27c368738..0fc8e69dd 100644 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -34,7 +34,7 @@ namespace Slang struct PathInfo; struct IncludeHandler; struct SharedSemanticsContext; -struct ModuleChunkRef; +struct ModuleChunk; class ProgramLayout; class PtrType; @@ -2363,20 +2363,23 @@ public: /// Otherwise, return null. /// RefPtr<Module> findOrLoadSerializedModuleForModuleLibrary( - ModuleChunkRef moduleChunk, + ModuleChunk const* moduleChunk, + RIFF::ListChunk const* libraryChunk, DiagnosticSink* sink); RefPtr<Module> loadSerializedModule( Name* moduleName, const PathInfo& moduleFilePathInfo, - ModuleChunkRef moduleChunk, + ModuleChunk const* moduleChunk, + RIFF::ListChunk const* containerChunk, //< The outer container, if there is one. SourceLoc const& requestingLoc, DiagnosticSink* sink); SlangResult loadSerializedModuleContents( Module* module, const PathInfo& moduleFilePathInfo, - ModuleChunkRef moduleChunk, + ModuleChunk const* moduleChunk, + RIFF::ListChunk const* containerChunk, //< The outer container, if there is one. DiagnosticSink* sink); SourceFile* loadSourceFile(String pathFrom, String path); @@ -2387,8 +2390,7 @@ public: Name* name, PathInfo const& pathInfo); - bool isBinaryModuleUpToDate(String fromPath, RiffContainer* container); - bool isBinaryModuleUpToDate(String fromPath, ModuleChunkRef moduleChunk); + bool isBinaryModuleUpToDate(String fromPath, RIFF::ListChunk const* baseChunk); RefPtr<Module> findOrImportModule( Name* name, diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp index bb6941907..74133fcf0 100644 --- a/source/slang/slang-emit-cuda.cpp +++ b/source/slang/slang-emit-cuda.cpp @@ -947,8 +947,7 @@ void CUDASourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst) { if (auto smDecoration = as<IRRequireCUDASMVersionDecoration>(decoration)) { - SemanticVersion version; - version.setFromInteger(SemanticVersion::IntegerType(smDecoration->getCUDASMVersion())); + SemanticVersion version = smDecoration->getCUDASMVersion(); m_extensionTracker->requireSMVersion(version); } } diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 5e9fa7f70..850395d97 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -3074,11 +3074,8 @@ void GLSLSourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst) } case kIROp_RequireSPIRVVersionDecoration: { - auto intValue = - static_cast<IRRequireSPIRVVersionDecoration*>(decoration)->getSPIRVVersion(); - SemanticVersion version; - version.setFromInteger(SemanticVersion::IntegerType(intValue)); - _requireSPIRVVersion(version); + _requireSPIRVVersion( + static_cast<IRRequireSPIRVVersionDecoration*>(decoration)->getSPIRVVersion()); break; } } diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 4bef81f47..268929fb9 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -396,7 +396,10 @@ struct IRRequireSPIRVVersionDecoration : IRDecoration IR_LEAF_ISA(RequireGLSLVersionDecoration) IRConstant* getSPIRVVersionOperand() { return cast<IRConstant>(getOperand(0)); } - IntegerLiteralValue getSPIRVVersion() { return getSPIRVVersionOperand()->value.intVal; } + SemanticVersion getSPIRVVersion() + { + return SemanticVersion::fromRaw(getSPIRVVersionOperand()->value.intVal); + } }; struct IRRequireCapabilityAtomDecoration : IRDecoration @@ -420,7 +423,10 @@ struct IRRequireCUDASMVersionDecoration : IRDecoration IR_LEAF_ISA(RequireCUDASMVersionDecoration) IRConstant* getCUDASMVersionOperand() { return cast<IRConstant>(getOperand(0)); } - IntegerLiteralValue getCUDASMVersion() { return getCUDASMVersionOperand()->value.intVal; } + SemanticVersion getCUDASMVersion() + { + return SemanticVersion::fromRaw(getCUDASMVersionOperand()->value.intVal); + } }; struct IRRequireGLSLExtensionDecoration : IRDecoration @@ -5009,13 +5015,15 @@ public: getStringValue(prelude)); } + IRInst* getSemanticVersionValue(SemanticVersion const& value) + { + SemanticVersion::RawValue rawValue = value.getRawValue(); + return getIntValue(getBasicType(BaseType::UInt64), rawValue); + } + void addRequireSPIRVVersionDecoration(IRInst* value, const SemanticVersion& version) { - SemanticVersion::IntegerType intValue = version.toInteger(); - addDecoration( - value, - kIROp_RequireSPIRVVersionDecoration, - getIntValue(getBasicType(BaseType::UInt64), intValue)); + addDecoration(value, kIROp_RequireSPIRVVersionDecoration, getSemanticVersionValue(version)); } void addSPIRVNonUniformResourceDecoration(IRInst* value) @@ -5025,11 +5033,10 @@ public: void addRequireCUDASMVersionDecoration(IRInst* value, const SemanticVersion& version) { - SemanticVersion::IntegerType intValue = version.toInteger(); addDecoration( value, kIROp_RequireCUDASMVersionDecoration, - getIntValue(getBasicType(BaseType::UInt64), intValue)); + getSemanticVersionValue(version)); } void addRequireCapabilityAtomDecoration(IRInst* value, CapabilityName atom) diff --git a/source/slang/slang-module-library.cpp b/source/slang/slang-module-library.cpp index c03d5c2dd..c3f4a1349 100644 --- a/source/slang/slang-module-library.cpp +++ b/source/slang/slang-module-library.cpp @@ -39,8 +39,8 @@ void* ModuleLibrary::castAs(const Guid& guid) } SlangResult loadModuleLibrary( - const Byte* inBytes, - size_t bytesCount, + const Byte* inData, + size_t dataSize, String path, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outLibrary) @@ -51,32 +51,38 @@ SlangResult loadModuleLibrary( ComPtr<IModuleLibrary> scopeLibrary(library); // Load up the module - MemoryStreamBase memoryStream(FileAccess::Read, inBytes, bytesCount); - - RiffContainer riffContainer; - SLANG_RETURN_ON_FAIL(RiffUtil::read(&memoryStream, riffContainer)); + auto rootChunk = RIFF::RootChunk::getFromBlob(inData, dataSize); + if (!rootChunk) + { + return SLANG_FAIL; + } auto linkage = req->getLinkage(); auto sink = req->getSink(); auto namePool = req->getNamePool(); - auto container = ContainerChunkRef::find(&riffContainer); + auto container = ContainerChunk::find(rootChunk); + if (!container) + { + return SLANG_FAIL; + } - for (auto moduleChunk : container.getModules()) + for (auto moduleChunk : container->getModules()) { - auto loadedModule = linkage->findOrLoadSerializedModuleForModuleLibrary(moduleChunk, sink); + auto loadedModule = + linkage->findOrLoadSerializedModuleForModuleLibrary(moduleChunk, container, sink); if (!loadedModule) return SLANG_FAIL; library->m_modules.add(loadedModule); } - for (auto entryPointChunk : container.getEntryPoints()) + for (auto entryPointChunk : container->getEntryPoints()) { FrontEndCompileRequest::ExtraEntryPointInfo entryPointInfo; - entryPointInfo.mangledName = entryPointChunk.getMangledName(); - entryPointInfo.name = namePool->getName(entryPointChunk.getName()); - entryPointInfo.profile = entryPointChunk.getProfile(); + entryPointInfo.mangledName = entryPointChunk->getMangledName(); + entryPointInfo.name = namePool->getName(entryPointChunk->getName()); + entryPointInfo.profile = entryPointChunk->getProfile(); library->m_entryPoints.add(entryPointInfo); } diff --git a/source/slang/slang-repro.cpp b/source/slang/slang-repro.cpp index 9859ead52..0c4d7337d 100644 --- a/source/slang/slang-repro.cpp +++ b/source/slang/slang-repro.cpp @@ -14,10 +14,8 @@ namespace Slang { -/* static */ const RiffSemanticVersion ReproUtil::g_semanticVersion = RiffSemanticVersion::make( - ReproUtil::kMajorVersion, - ReproUtil::kMinorVersion, - ReproUtil::kPatchVersion); +/* static */ const SemanticVersion ReproUtil::g_semanticVersion = + SemanticVersion(ReproUtil::kMajorVersion, ReproUtil::kMinorVersion, ReproUtil::kPatchVersion); // We can't just use sizeof for the sizes of these types, because the hash will be dependent on the // ptr size, which isn't an issue for serialization (we turn all pointers into Offset32Ptr -> @@ -1173,17 +1171,20 @@ struct LoadContext Offset32Ptr<RequestState> requestState; SLANG_RETURN_ON_FAIL(store(request, container, requestState)); + RIFF::Builder riff; + RIFF::BuildCursor cursor(riff); + + SLANG_SCOPED_RIFF_BUILDER_LIST_CHUNK(cursor, kSlangStateFileFourCC); + SLANG_SCOPED_RIFF_BUILDER_DATA_CHUNK(cursor, kSlangStateDataFourCC); + Header header; - header.m_chunk.type = kSlangStateFourCC; header.m_semanticVersion = g_semanticVersion; header.m_typeHash = _getTypeHash(); - return RiffUtil::writeData( - &header.m_chunk, - sizeof(header), - container.getData(), - container.getDataCount(), - stream); + cursor.addData(header); + cursor.addUnownedData(container.getData(), container.getDataCount()); + + return riff.writeTo(stream); } /* static */ SlangResult ReproUtil::saveState( @@ -1210,29 +1211,63 @@ struct LoadContext /* static */ SlangResult ReproUtil::loadState( Stream* stream, DiagnosticSink* sink, - List<uint8_t>& buffer) + List<uint8_t>& outBuffer) { - Header header; - + List<Byte> streamData; { - Result res = RiffUtil::readData(stream, &header.m_chunk, sizeof(header), buffer); - if (SLANG_FAILED(res)) + auto result = StreamUtil::readAll(stream, streamData); + if (SLANG_FAILED(result)) { sink->diagnose(SourceLoc(), Diagnostics::unableToReadRiff); - return res; + return result; } } - if (header.m_chunk.type != kSlangStateFourCC) + + return loadState(streamData.getBuffer(), streamData.getCount(), sink, outBuffer); +} + +/* static */ SlangResult ReproUtil::loadState( + const uint8_t* data, + size_t dataSize, + DiagnosticSink* sink, + List<uint8_t>& outBuffer) +{ + auto rootChunk = RIFF::RootChunk::getFromBlob(data, dataSize); + if (!rootChunk) + { + sink->diagnose(SourceLoc(), Diagnostics::unableToReadRiff); + return SLANG_FAIL; + } + if (rootChunk->getType() != kSlangStateFileFourCC) + { + sink->diagnose(SourceLoc(), Diagnostics::expectingSlangRiffContainer); + return SLANG_FAIL; + } + + auto dataChunk = rootChunk->findDataChunk(kSlangStateDataFourCC); + if (!dataChunk) { sink->diagnose(SourceLoc(), Diagnostics::expectingSlangRiffContainer); return SLANG_FAIL; } - if (!RiffSemanticVersion::areCompatible(g_semanticVersion, header.m_semanticVersion)) + MemoryReader reader(dataChunk->getPayload(), dataChunk->getPayloadSize()); + + Header header; + { + auto result = reader.read(header); + if (SLANG_FAILED(result)) + { + sink->diagnose(SourceLoc(), Diagnostics::expectingSlangRiffContainer); + return result; + } + } + + if (!g_semanticVersion.isBackwardsCompatibleWith(header.m_semanticVersion)) { StringBuilder headerBuf, currentBuf; - header.m_semanticVersion.asSemanticVersion().append(headerBuf); - g_semanticVersion.asSemanticVersion().append(currentBuf); + header.m_semanticVersion.append(headerBuf); + g_semanticVersion.append(currentBuf); sink->diagnose( SourceLoc(), @@ -1248,17 +1283,19 @@ struct LoadContext return SLANG_FAIL; } - return SLANG_OK; -} + auto remainingSize = reader.getRemainingSize(); + outBuffer.setCount(remainingSize); -/* static */ SlangResult ReproUtil::loadState( - const uint8_t* data, - size_t size, - DiagnosticSink* sink, - List<uint8_t>& outBuffer) -{ - MemoryStreamBase stream(FileAccess::Read, data, size); - return loadState(&stream, sink, outBuffer); + { + auto result = reader.read(&outBuffer[0], remainingSize); + if (SLANG_FAILED(result)) + { + sink->diagnose(SourceLoc(), Diagnostics::expectingSlangRiffContainer); + return result; + } + } + + return SLANG_OK; } /* static */ ReproUtil::RequestState* ReproUtil::getRequest(const List<uint8_t>& buffer) diff --git a/source/slang/slang-repro.h b/source/slang/slang-repro.h index 0641c4ecc..b7a9a739b 100644 --- a/source/slang/slang-repro.h +++ b/source/slang/slang-repro.h @@ -29,14 +29,17 @@ struct ReproUtil 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; + static const FourCC::RawValue kSlangStateFileFourCC = + SLANG_FOUR_CC('S', 'L', 'S', 'T'); ///< Root chunk for repro state file. + + static const FourCC::RawValue kSlangStateDataFourCC = + SLANG_FOUR_CC('d', 'a', 't', 'a'); ///< Holds the actual binary data. + + static const SemanticVersion g_semanticVersion; struct Header { - RiffHeader m_chunk; ///< The chunk - RiffSemanticVersion m_semanticVersion; ///< The semantic version + SemanticVersion m_semanticVersion; ///< The semantic version StableHashCode32 m_typeHash; ///< A hash based on the binary representation. If doesn't match then not ///< binary compatible (extra check over semantic versioning) diff --git a/source/slang/slang-serialize-ast.cpp b/source/slang/slang-serialize-ast.cpp index 84278650f..1ef532ad1 100644 --- a/source/slang/slang-serialize-ast.cpp +++ b/source/slang/slang-serialize-ast.cpp @@ -59,9 +59,9 @@ public: { auto containerChunk = encoder->getRIFFChunk(); - RiffContainer::Chunk* declChunk = nullptr; - RiffContainer::Chunk* importedDeclChunk = nullptr; - RiffContainer::Chunk* valChunk = nullptr; + RIFF::ChunkBuilder* declChunk = nullptr; + RIFF::ChunkBuilder* importedDeclChunk = nullptr; + RIFF::ChunkBuilder* valChunk = nullptr; { Encoder::WithArray withList(encoder); declChunk = encoder->getRIFFChunk(); @@ -102,7 +102,6 @@ public: } } while (!done); - RiffContainer::calcAndSetSize(containerChunk); encoder->setRIFFChunk(containerChunk); } @@ -345,7 +344,7 @@ public: void encodeValue(NameLoc const& value) { encode(value.name); } - void encodeValue(SemanticVersion value) { encoder->encode(value.toInteger()); } + void encodeValue(SemanticVersion value) { encoder->encode(value.getRawValue()); } void encodeValue(CapabilitySet const& value) { @@ -668,13 +667,13 @@ public: Linkage* linkage, ASTBuilder* astBuilder, DiagnosticSink* sink, - RiffContainer::Chunk* rootChunk, + RIFF::Chunk const* baseChunk, SerialSourceLocReader* sourceLocReader, SourceLoc requestingSourceLoc) : _linkage(linkage) , _astBuilder(astBuilder) , _sink(sink) - , _rootChunk(static_cast<RiffContainer::ListChunk*>(rootChunk)) + , _baseChunk(as<RIFF::ListChunk>(baseChunk)) , _sourceLocReader(sourceLocReader) , _requestingSourceLoc(requestingSourceLoc) { @@ -687,7 +686,7 @@ public: SlangResult decodeAll() { - auto cursor = _rootChunk->getFirstContainedChunk(); + auto cursor = _baseChunk->getChildren().begin(); // There are a few different top-level chunks that // hold different arrays that we need in order @@ -705,23 +704,23 @@ public: // the `ModuleDecl` itself, which should be the // first entry in the list. // - auto declChunk = cursor; - cursor = cursor->m_next; + auto declChunk = *cursor; + ++cursor; // Next there is a list of all the declarations // referenced inside of the module that need to // be imported in from outside. // - auto importedDeclChunk = cursor; - cursor = cursor->m_next; + auto importedDeclChunk = *cursor; + ++cursor; // Then there are all the `Val`-derived nodes that // are needed by the module, which will need to be // deduplicated so that they are unique within the // current compilation context. // - auto valChunk = cursor; - cursor = cursor->m_next; + auto valChunk = *cursor; + ++cursor; // The process of decoding the module is then spread // over a number of steps. @@ -792,7 +791,7 @@ private: }; ASTBuilder* _astBuilder = nullptr; - RiffContainer::ListChunk* _rootChunk = nullptr; + RIFF::ListChunk const* _baseChunk = nullptr; List<Decl*> _decls; List<Decl*> _importedDecls; @@ -801,7 +800,7 @@ private: typedef Int ValID; Val* getValByID(ValID id) { return _vals[id]; } - SlangResult decodeImportedDecls(RiffContainer::Chunk* importedDeclChunk) + SlangResult decodeImportedDecls(RIFF::Chunk const* importedDeclChunk) { Decoder decoder(importedDeclChunk); @@ -849,7 +848,7 @@ private: return module->getModuleDecl(); } - SlangResult decodeVals(RiffContainer::Chunk* valChunk) + SlangResult decodeVals(RIFF::Chunk const* valChunk) { Decoder decoder(valChunk); @@ -862,7 +861,7 @@ private: return SLANG_OK; } - SlangResult createEmptyShells(RiffContainer::Chunk* declChunk) + SlangResult createEmptyShells(RIFF::Chunk const* declChunk) { Decoder decoder(declChunk); @@ -925,7 +924,7 @@ private: return SyntaxClass<NodeBase>(nodeType).createInstance(_astBuilder); } - SlangResult fillEmptyShells(RiffContainer::Chunk* declChunk) + SlangResult fillEmptyShells(RIFF::Chunk const* declChunk) { Index declIndex = 0; @@ -1190,8 +1189,8 @@ private: void decodeValue(SemanticVersion& value, Decoder& decoder) { - SemanticVersion::IntegerType rawValue = decoder.decode<SemanticVersion::IntegerType>(); - value.setFromInteger(rawValue); + SemanticVersion::RawValue rawValue = decoder.decode<SemanticVersion::RawValue>(); + value.setRawValue(rawValue); } void decodeValue(CapabilitySet& value, Decoder& decoder) @@ -1541,7 +1540,7 @@ ModuleDecl* readSerializedModuleAST( Linkage* linkage, ASTBuilder* astBuilder, DiagnosticSink* sink, - RiffContainer::Chunk* chunk, + RIFF::Chunk const* chunk, SerialSourceLocReader* sourceLocReader, SourceLoc requestingSourceLoc) { diff --git a/source/slang/slang-serialize-ast.h b/source/slang/slang-serialize-ast.h index 6adeae8dd..45c799e9c 100644 --- a/source/slang/slang-serialize-ast.h +++ b/source/slang/slang-serialize-ast.h @@ -20,7 +20,7 @@ ModuleDecl* readSerializedModuleAST( Linkage* linkage, ASTBuilder* astBuilder, DiagnosticSink* sink, - RiffContainer::Chunk* chunk, + RIFF::Chunk const* chunk, SerialSourceLocReader* sourceLocReader, SourceLoc requestingSourceLoc); diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp index c2253ed45..665775dc5 100644 --- a/source/slang/slang-serialize-container.cpp +++ b/source/slang/slang-serialize-container.cpp @@ -17,20 +17,34 @@ namespace Slang { struct ModuleEncodingContext { +private: + SerialContainerUtil::WriteOptions const& _options; + Stream* _stream = nullptr; + + // The string pool used across the whole of the container + StringSlicePool _containerStringPool; + RefPtr<SerialSourceLocWriter> _sourceLocWriter; + + RIFF::Builder _riff; + Encoder _encoder; + public: ModuleEncodingContext(SerialContainerUtil::WriteOptions const& options, Stream* stream) - : options(options), encoder(stream), containerStringPool(StringSlicePool::Style::Default) + : _options(options), _stream(stream), _containerStringPool(StringSlicePool::Style::Default) { if (options.optionFlags & SerialOptionFlag::SourceLocation) { - sourceLocWriter = new SerialSourceLocWriter(options.sourceManager); + _sourceLocWriter = new SerialSourceLocWriter(options.sourceManager); } + + _encoder = Encoder(_riff); } ~ModuleEncodingContext() { - encoder.setRIFFChunk(encoder.getRIFF()->getRoot()); + _encoder = Encoder(_riff.getRootChunk()); encodeFinalPieces(); + _riff.writeTo(_stream); } SlangResult encodeModuleList(FrontEndCompileRequest* frontEndReq) @@ -39,7 +53,7 @@ public: // is simply a matter of encoding the module for each // of the translation units that got compiled. // - Encoder::WithKeyValuePair withArray(&encoder, SerialBinary::kModuleListFourCc); + Encoder::WithKeyValuePair withArray(&_encoder, SerialBinary::kModuleListFourCc); for (TranslationUnitRequest* translationUnit : frontEndReq->translationUnits) { SLANG_RETURN_ON_FAIL(encode(translationUnit->module)); @@ -49,14 +63,14 @@ public: SlangResult encode(FrontEndCompileRequest* frontEndReq) { - Encoder::WithObject withObject(&encoder, SerialBinary::kContainerFourCc); + Encoder::WithObject withObject(&_encoder, SerialBinary::kContainerFourCc); SLANG_RETURN_ON_FAIL(encodeModuleList(frontEndReq)); return SLANG_OK; } SlangResult encode(EndToEndCompileRequest* request) { - Encoder::WithObject withObject(&encoder, SerialBinary::kContainerFourCc); + Encoder::WithObject withObject(&_encoder, SerialBinary::kContainerFourCc); // Encoding an end-to-end compile request starts with the same // work as for a front-end request: we encode each of @@ -85,7 +99,7 @@ public: auto sink = request->getSink(); auto program = request->getSpecializedGlobalAndEntryPointsComponentType(); { - Encoder::WithArray withArray(&encoder); // kContainerFourCc + Encoder::WithArray withArray(&_encoder); for (auto target : linkage->targets) { @@ -98,7 +112,7 @@ public: // and we need to encode information about each of them. // { - Encoder::WithArray withArray(&encoder, SerialBinary::kEntryPointListFourCc); + Encoder::WithArray withArray(&_encoder, SerialBinary::kEntryPointListFourCc); auto entryPointCount = program->getEntryPointCount(); for (Index ii = 0; ii < entryPointCount; ++ii) @@ -127,34 +141,34 @@ public: IRSerialWriter writer; SLANG_RETURN_ON_FAIL( - writer.write(irModule, sourceLocWriter, options.optionFlags, &serialData)); - SLANG_RETURN_ON_FAIL(IRSerialWriter::writeContainer(serialData, encoder.getRIFF())); + writer.write(irModule, _sourceLocWriter, _options.optionFlags, &serialData)); + SLANG_RETURN_ON_FAIL(IRSerialWriter::writeTo(serialData, _encoder)); return SLANG_OK; } - void encode(Name* name) { encoder.encode(name->text); } + void encode(Name* name) { _encoder.encode(name->text); } - void encode(String const& value) { encoder.encode(value); } + void encode(String const& value) { _encoder.encode(value); } - void encode(uint32_t value) { encoder.encode(UInt(value)); } + void encode(uint32_t value) { _encoder.encode(UInt(value)); } - void encodeData(void const* data, size_t size) { encoder.encodeData(data, size); } + void encodeData(void const* data, size_t size) { _encoder.encodeData(data, size); } SlangResult encode(EntryPoint* entryPoint, String const& entryPointMangledName) { - Encoder::WithObject withObject(&encoder, SerialBinary::kEntryPointFourCc); + Encoder::WithObject withObject(&_encoder, SerialBinary::kEntryPointFourCc); { - Encoder::WithObject withProperty(&encoder, SerialBinary::kNameFourCC); + Encoder::WithObject withProperty(&_encoder, SerialBinary::kNameFourCC); encode(entryPoint->getName()); } { - Encoder::WithObject withProperty(&encoder, SerialBinary::kProfileFourCC); + Encoder::WithObject withProperty(&_encoder, SerialBinary::kProfileFourCC); encode(entryPoint->getProfile().raw); } { - Encoder::WithObject withProperty(&encoder, SerialBinary::kMangledNameFourCC); + Encoder::WithObject withProperty(&_encoder, SerialBinary::kMangledNameFourCC); encode(entryPointMangledName); } @@ -164,10 +178,10 @@ public: SlangResult encode(Module* module) { - if (!(options.optionFlags & (SerialOptionFlag::IRModule | SerialOptionFlag::ASTModule))) + if (!(_options.optionFlags & (SerialOptionFlag::IRModule | SerialOptionFlag::ASTModule))) return SLANG_OK; - Encoder::WithObject withModule(&encoder, SerialBinary::kModuleFourCC); + Encoder::WithObject withModule(&_encoder, SerialBinary::kModuleFourCC); // The first piece that we write for a module is its header. // The header is intended to provide information that can be @@ -180,15 +194,15 @@ public: // sense to serialize it separately from all the rest. // { - Encoder::WithObject withProperty(&encoder, SerialBinary::kNameFourCC); - encoder.encodeString(module->getNameObj()->text); + Encoder::WithObject withProperty(&_encoder, SerialBinary::kNameFourCC); + _encoder.encodeString(module->getNameObj()->text); } // The header includes a digest of all the compile options and // the files that the compiled result depended on. // auto digest = module->computeDigest(); - encoder.encodeData(PropertyKeys<Module>::Digest, digest.data, sizeof(digest.data)); + _encoder.encodeData(PropertyKeys<Module>::Digest, digest.data, sizeof(digest.data)); // The header includes an array of the paths of all of the // files that the compiled result depended on. @@ -199,30 +213,28 @@ public: // If serialization of Slang IR modules is enabled, and there // is IR available for this module, then we we encode it. // - if ((options.optionFlags & SerialOptionFlag::IRModule)) + if ((_options.optionFlags & SerialOptionFlag::IRModule)) { if (auto irModule = module->getIRModule()) { - Encoder::WithKeyValuePair withKey(&encoder, PropertyKeys<Module>::IRModule); - IRSerialData serialData; IRSerialWriter writer; SLANG_RETURN_ON_FAIL( - writer.write(irModule, sourceLocWriter, options.optionFlags, &serialData)); - SLANG_RETURN_ON_FAIL(IRSerialWriter::writeContainer(serialData, encoder.getRIFF())); + writer.write(irModule, _sourceLocWriter, _options.optionFlags, &serialData)); + SLANG_RETURN_ON_FAIL(IRSerialWriter::writeTo(serialData, _encoder)); } } // If serialization of AST information is enabled, and we have AST // information available, then we serialize it here. // - if (options.optionFlags & SerialOptionFlag::ASTModule) + if (_options.optionFlags & SerialOptionFlag::ASTModule) { if (auto moduleDecl = module->getModuleDecl()) { - Encoder::WithKeyValuePair withKey(&encoder, PropertyKeys<Module>::ASTModule); + Encoder::WithKeyValuePair withKey(&_encoder, PropertyKeys<Module>::ASTModule); - writeSerializedModuleAST(&encoder, moduleDecl, sourceLocWriter); + writeSerializedModuleAST(&_encoder, moduleDecl, _sourceLocWriter); } } @@ -231,7 +243,7 @@ public: SlangResult encodeModuleDependencyPaths(Module* module) { - Encoder::WithObject withProperty(&encoder, PropertyKeys<Module>::FileDependencies); + Encoder::WithObject withProperty(&_encoder, PropertyKeys<Module>::FileDependencies); // TODO(tfoley): This is some of the most complicated logic // in the encoding system, because it tries to translate @@ -305,7 +317,7 @@ public: } Path::getCanonical(linkageRoot, linkageRoot); - Encoder::WithArray withArray(&encoder); + Encoder::WithArray withArray(&_encoder); for (auto file : fileDependencies) { if (file->getPathInfo().hasFoundPath()) @@ -322,26 +334,26 @@ public: auto relativeModulePath = Path::getRelativePath(linkageRoot, canonicalModulePath); - encoder.encodeString(relativeModulePath); + _encoder.encodeString(relativeModulePath); } else { // For all other dependnet files, store them as relative paths with respect // to the module's path. canonicalFilePath = Path::getRelativePath(moduleDir, canonicalFilePath); - encoder.encodeString(canonicalFilePath); + _encoder.encodeString(canonicalFilePath); } } else { // If the module is coming from string instead of an actual file, store it as // is. - encoder.encodeString(canonicalModulePath); + _encoder.encodeString(canonicalModulePath); } } else { - encoder.encodeString(file->getPathInfo().getMostUniqueIdentity()); + _encoder.encodeString(file->getPathInfo().getMostUniqueIdentity()); } } @@ -351,38 +363,28 @@ public: SlangResult encodeFinalPieces() { // We can now output the debug information. This is for all IR and AST - if (sourceLocWriter) + if (_sourceLocWriter) { // Write out the debug info SerialSourceLocData debugData; - sourceLocWriter->write(&debugData); + _sourceLocWriter->write(&debugData); - debugData.writeContainer(encoder.getRIFF()); + debugData.writeTo(_encoder); } // Write the container string table - if (containerStringPool.getAdded().getCount() > 0) + if (_containerStringPool.getAdded().getCount() > 0) { - Encoder::WithKeyValuePair withKey(&encoder, SerialBinary::kStringTableFourCc); + Encoder::WithKeyValuePair withKey(&_encoder, SerialBinary::kStringTableFourCc); List<char> encodedTable; - SerialStringTableUtil::encodeStringTable(containerStringPool, encodedTable); + SerialStringTableUtil::encodeStringTable(_containerStringPool, encodedTable); - encoder.encodeData(encodedTable.getBuffer(), encodedTable.getCount()); + _encoder.encodeData(encodedTable.getBuffer(), encodedTable.getCount()); } return SLANG_OK; } - - -private: - SerialContainerUtil::WriteOptions const& options; - RefPtr<SerialSourceLocWriter> sourceLocWriter; - - // The string pool used across the whole of the container - StringSlicePool containerStringPool; - - Encoder encoder; }; // @@ -421,123 +423,119 @@ private: return SLANG_OK; } -String StringChunkRef::getValue() +String StringChunk::getValue() const { - return Decoder(ptr()).decodeString(); + return Decoder(this).decodeString(); } -ChunkRefList<StringChunkRef> ModuleChunkRef::getFileDependencies() +RIFF::ChunkList<StringChunk> ModuleChunk::getFileDependencies() const { - Decoder decoder(ptr()); + Decoder decoder(this); Decoder::WithProperty withProperty(decoder, PropertyKeys<Module>::FileDependencies); - return ChunkRefList<StringChunkRef>(as<RiffContainer::ListChunk>(decoder.getCursor())); + return as<RIFF::ListChunk>(decoder.getCurrentChunk())->getChildren().cast<StringChunk>(); } -ModuleChunkRef ModuleChunkRef::find(RiffContainer* container) +ModuleChunk const* ModuleChunk::find(RIFF::ListChunk const* baseChunk) { - auto found = container->getRoot()->findListRec(SerialBinary::kModuleFourCC); - return ModuleChunkRef(found); + auto found = baseChunk->findListChunkRec(SerialBinary::kModuleFourCC); + return static_cast<ModuleChunk const*>(found); } -SHA1::Digest ModuleChunkRef::getDigest() +SHA1::Digest ModuleChunk::getDigest() const { - auto foundChunk = - static_cast<RiffContainer::DataChunk*>(ptr()->findContained(PropertyKeys<Module>::Digest)); + auto foundChunk = findDataChunk(PropertyKeys<Module>::Digest); if (!foundChunk) { SLANG_UNEXPECTED("module chunk had no digest"); } - if (foundChunk->calcPayloadSize() != sizeof(SHA1::Digest)) - { - SLANG_UNEXPECTED("module digest chunk had wrong size"); - } - - SHA1::Digest digest; - foundChunk->getPayload(&digest); - return digest; + return foundChunk->readPayloadAs<SHA1::Digest>(); } -String ModuleChunkRef::getName() +String ModuleChunk::getName() const { // TODO(tfoley): This kind of logic needs a way // to be greatly simplified, so that we don't // have to express such complicated logic for // simply extracting a single string property... // - Decoder decoder(ptr()); + Decoder decoder(this); Decoder::WithProperty withProperty(decoder, SerialBinary::kNameFourCC); return decoder.decodeString(); } -IRModuleChunkRef ModuleChunkRef::findIR() +IRModuleChunk const* ModuleChunk::findIR() const { - auto foundProperty = ptr()->findContainedList(PropertyKeys<Module>::IRModule); - if (!foundProperty) - return IRModuleChunkRef(nullptr); - return IRModuleChunkRef( - static_cast<RiffContainer::ListChunk*>(foundProperty->getFirstContainedChunk())); + auto foundChunk = findListChunk(IRSerialBinary::kIRModuleFourCc); + if (!foundChunk) + return nullptr; + + return static_cast<IRModuleChunk const*>(foundChunk); } -ASTModuleChunkRef ModuleChunkRef::findAST() +ASTModuleChunk const* ModuleChunk::findAST() const { - auto foundProperty = ptr()->findContainedList(PropertyKeys<Module>::ASTModule); + auto foundProperty = findListChunk(PropertyKeys<Module>::ASTModule); if (!foundProperty) - return ASTModuleChunkRef(nullptr); - return ASTModuleChunkRef( - static_cast<RiffContainer::ListChunk*>(foundProperty->getFirstContainedChunk())); + return nullptr; + + return static_cast<ASTModuleChunk const*>(foundProperty->getFirstChild().get()); } -ContainerChunkRef ContainerChunkRef::find(RiffContainer* container) +ContainerChunk const* ContainerChunk::find(RIFF::ListChunk const* baseChunk) { - auto found = container->getRoot()->findListRec(SerialBinary::kContainerFourCc); - return ContainerChunkRef(found); + auto found = baseChunk->findListChunkRec(SerialBinary::kContainerFourCc); + return static_cast<ContainerChunk const*>(found); } -ChunkRefList<ModuleChunkRef> ContainerChunkRef::getModules() +RIFF::ChunkList<ModuleChunk> ContainerChunk::getModules() const { - auto found = ptr()->findContainedList(SerialBinary::kModuleListFourCc); - return ChunkRefList<ModuleChunkRef>(found); + auto found = findListChunk(SerialBinary::kModuleListFourCc); + if (!found) + return RIFF::ChunkList<ModuleChunk>(); + return found->getChildren().cast<ModuleChunk>(); } -ChunkRefList<EntryPointChunkRef> ContainerChunkRef::getEntryPoints() +RIFF::ChunkList<EntryPointChunk> ContainerChunk::getEntryPoints() const { - auto found = ptr()->findContainedList(SerialBinary::kEntryPointListFourCc); - return ChunkRefList<EntryPointChunkRef>(found); + auto found = findListChunk(SerialBinary::kEntryPointListFourCc); + if (!found) + return RIFF::ChunkList<EntryPointChunk>(); + return found->getChildren().cast<EntryPointChunk>(); } -String EntryPointChunkRef::getMangledName() const +String EntryPointChunk::getMangledName() const { // TODO(tfoley): This kind of logic needs a way // to be greatly simplified, so that we don't // have to express such complicated logic for // simply extracting a single string property... // - Decoder decoder(ptr()); + Decoder decoder(this); Decoder::WithProperty withProperty(decoder, SerialBinary::kMangledNameFourCC); return decoder.decodeString(); } -String EntryPointChunkRef::getName() const +String EntryPointChunk::getName() const { // TODO(tfoley): This kind of logic needs a way // to be greatly simplified, so that we don't // have to express such complicated logic for // simply extracting a single string property... // - Decoder decoder(ptr()); + Decoder decoder(this); Decoder::WithProperty withProperty(decoder, SerialBinary::kNameFourCC); return decoder.decodeString(); } -Profile EntryPointChunkRef::getProfile() const +Profile EntryPointChunk::getProfile() const { // TODO(tfoley): This kind of logic needs a way // to be greatly simplified, so that we don't // have to express such complicated logic for // simply extracting a single string property... // - Decoder decoder(ptr()); + Decoder decoder(this); Decoder::WithProperty withProperty(decoder, SerialBinary::kProfileFourCC); Profile::RawVal rawVal; @@ -547,28 +545,25 @@ Profile EntryPointChunkRef::getProfile() const } -RiffContainer::ListChunk* findDebugChunk(RiffContainer::Chunk* startingChunk) +DebugChunk const* DebugChunk::find(RIFF::ListChunk const* baseChunk) { - if (!startingChunk) - return nullptr; - - RiffContainer::ListChunk* container = as<RiffContainer::ListChunk>(startingChunk); - if (!container) - container = startingChunk->m_parent; - - for (; container; container = container->m_parent) - { - if (auto debugChunk = container->findContainedList(SerialSourceLocData::kDebugFourCc)) - { - return debugChunk; - } - } + auto found = baseChunk->findListChunkRec(SerialSourceLocData::kDebugFourCc); + return static_cast<DebugChunk const*>(found); +} +DebugChunk const* DebugChunk::find( + RIFF::ListChunk const* baseChunk, + RIFF::ListChunk const* containerChunk) +{ + if (auto found = find(baseChunk)) + return found; + if (containerChunk) + return find(containerChunk); return nullptr; } SlangResult readSourceLocationsFromDebugChunk( - RiffContainer::ListChunk* debugChunk, + DebugChunk const* debugChunk, SourceManager* sourceManager, RefPtr<SerialSourceLocReader>& outReader) { @@ -585,7 +580,7 @@ SlangResult readSourceLocationsFromDebugChunk( // from the RIFF into the intermediate structure. // SerialSourceLocData intermediateData; - SLANG_RETURN_ON_FAIL(intermediateData.readContainer(debugChunk)); + SLANG_RETURN_ON_FAIL(intermediateData.readFrom(debugChunk)); // After reading the data into the intermediate representation, // we turn it into a `SerialSourceLocReader`, which vends source @@ -601,7 +596,7 @@ SlangResult readSourceLocationsFromDebugChunk( SlangResult decodeModuleIR( RefPtr<IRModule>& outIRModule, - RiffContainer::Chunk* chunk, + IRModuleChunk const* chunk, Session* session, SerialSourceLocReader* sourceLocReader) { @@ -617,11 +612,8 @@ SlangResult decodeModuleIR( // are deserializing IR nodes directly from the format written // into the RIFF. // - auto listChunk = as<RiffContainer::ListChunk>(chunk); - if (!listChunk) - return SLANG_FAIL; IRSerialData serialData; - SLANG_RETURN_ON_FAIL(IRSerialReader::readContainer(listChunk, &serialData)); + SLANG_RETURN_ON_FAIL(IRSerialReader::readFrom(chunk, &serialData)); // Next we read the actual IR representation out from the // `serialData`. This is the step that may pull source-location @@ -648,13 +640,11 @@ SlangResult decodeModuleIR( OwnedMemoryStream memoryStream(FileAccess::ReadWrite); { - RiffContainer riffContainer; + RIFF::Builder builder; + RIFF::BuildCursor cursor(builder); - // Need to put all of this in a container - RiffContainer::ScopeChunk containerScope( - &riffContainer, - RiffContainer::Chunk::Kind::List, - SerialBinary::kContainerFourCc); + // Need to put all of this in a module chunk + SLANG_SCOPED_RIFF_BUILDER_LIST_CHUNK(cursor, SerialBinary::kModuleFourCC); RefPtr<SerialSourceLocWriter> sourceLocWriter; @@ -669,7 +659,7 @@ SlangResult decodeModuleIR( SLANG_RETURN_ON_FAIL( writer.write(module, sourceLocWriter, options.optionFlags, &irData)); } - SLANG_RETURN_ON_FAIL(IRSerialWriter::writeContainer(irData, &riffContainer)); + SLANG_RETURN_ON_FAIL(IRSerialWriter::writeTo(irData, cursor)); // Write the debug info Riff container if (sourceLocWriter) @@ -677,10 +667,10 @@ SlangResult decodeModuleIR( SerialSourceLocData serialData; sourceLocWriter->write(&serialData); - SLANG_RETURN_ON_FAIL(serialData.writeContainer(&riffContainer)); + SLANG_RETURN_ON_FAIL(serialData.writeTo(cursor)); } - SLANG_RETURN_ON_FAIL(RiffUtil::write(&riffContainer, &memoryStream)); + SLANG_RETURN_ON_FAIL(builder.writeTo(&memoryStream)); } // Reset stream @@ -692,33 +682,41 @@ SlangResult decodeModuleIR( // The read ir module RefPtr<IRModule> irReadModule; { - RiffContainer riffContainer; - SLANG_RETURN_ON_FAIL(RiffUtil::read(&memoryStream, riffContainer)); + auto streamContents = memoryStream.getContents(); - RiffContainer::ListChunk* rootList = riffContainer.getRoot(); + auto rootChunk = + RIFF::RootChunk::getFromBlob(streamContents.getBuffer(), streamContents.getCount()); + if (!rootChunk) + { + return SLANG_FAIL; + } + + auto moduleChunk = ModuleChunk::find(rootChunk); + if (!moduleChunk) + { + return SLANG_FAIL; + } RefPtr<SerialSourceLocReader> sourceLocReader; // If we have debug info then find and read it if (options.optionFlags & SerialOptionFlag::SourceLocation) { - RiffContainer::ListChunk* debugList = - rootList->findContainedList(SerialSourceLocData::kDebugFourCc); - if (!debugList) + auto debugChunk = DebugChunk::find(moduleChunk); + if (!debugChunk) { return SLANG_FAIL; } SerialSourceLocData sourceLocData; - SLANG_RETURN_ON_FAIL(sourceLocData.readContainer(debugList)); + SLANG_RETURN_ON_FAIL(sourceLocData.readFrom(debugChunk)); sourceLocReader = new SerialSourceLocReader; SLANG_RETURN_ON_FAIL(sourceLocReader->read(&sourceLocData, &workSourceManager)); } { - RiffContainer::ListChunk* irList = - rootList->findContainedList(IRSerialBinary::kIRModuleFourCc); - if (!irList) + auto irChunk = moduleChunk->findIR(); + if (!irChunk) { return SLANG_FAIL; } @@ -726,7 +724,7 @@ SlangResult decodeModuleIR( { IRSerialData irReadData; IRSerialReader reader; - SLANG_RETURN_ON_FAIL(reader.readContainer(irList, &irReadData)); + SLANG_RETURN_ON_FAIL(reader.readFrom(irChunk, &irReadData)); // Check the stream read data is the same if (irData != irReadData) diff --git a/source/slang/slang-serialize-container.h b/source/slang/slang-serialize-container.h index 4c1053a6d..81d03251f 100644 --- a/source/slang/slang-serialize-container.h +++ b/source/slang/slang-serialize-container.h @@ -56,189 +56,76 @@ struct SerialContainerUtil static SlangResult write(Module* module, const WriteOptions& options, Stream* stream); }; - -struct ChunkRef +struct StringChunk : RIFF::DataChunk { public: - ChunkRef(RiffContainer::Chunk* chunk) - : _chunk(chunk) - { - } - - RiffContainer::Chunk* ptr() const { return _chunk; } - -protected: - RiffContainer::Chunk* _chunk = nullptr; + String getValue() const; }; -struct DataChunkRef : ChunkRef -{ -public: - DataChunkRef(RiffContainer::DataChunk* chunk) - : ChunkRef(chunk) - { - } - - RiffContainer::DataChunk* ptr() const { return static_cast<RiffContainer::DataChunk*>(_chunk); } +struct IRModuleChunk; - operator RiffContainer::DataChunk*() const { return ptr(); } -}; - - -template<typename T> -struct ChunkRefList +struct ASTModuleChunk : RIFF::ListChunk { -public: - struct Iterator - { - public: - Iterator(RiffContainer::Chunk* chunk) - : _chunk(chunk) - { - } - - bool operator!=(Iterator const& other) const { return _chunk != other._chunk; } - - void operator++() { _chunk = _chunk->m_next; } - - T operator*() - { - ChunkRef ref(_chunk); - return *(T*)&ref; - } - - private: - RiffContainer::Chunk* _chunk = nullptr; - }; - - Iterator begin() const { return _list ? _list->getFirstContainedChunk() : nullptr; } - Iterator end() const { return Iterator(nullptr); } - - Count getCount() - { - Count count = 0; - for (auto i : *this) - count++; - return count; - } - - T getFirst() { return *begin(); } - - ChunkRefList() {} - - ChunkRefList(RiffContainer::ListChunk* list) - : _list(list) - { - } - - operator RiffContainer::ListChunk*() const { return _list; } - -private: - RiffContainer::ListChunk* _list = nullptr; }; -struct ListChunkRef : ChunkRef +struct ModuleChunk : RIFF::ListChunk { public: - ListChunkRef(RiffContainer::Chunk* chunk) - : ChunkRef(chunk) - { - } - - RiffContainer::ListChunk* ptr() const { return static_cast<RiffContainer::ListChunk*>(_chunk); } + static ModuleChunk const* find(RIFF::ListChunk const* baseChunk); - operator RiffContainer::ListChunk*() const { return ptr(); } -}; - - -struct StringChunkRef : DataChunkRef -{ -public: - String getValue(); -}; - -struct IRModuleChunkRef : ListChunkRef -{ -public: - explicit IRModuleChunkRef(RiffContainer::ListChunk* chunk) - : ListChunkRef(chunk) - { - } -}; - -struct ASTModuleChunkRef : ListChunkRef -{ -public: - explicit ASTModuleChunkRef(RiffContainer::ListChunk* chunk) - : ListChunkRef(chunk) - { - } -}; - -struct ModuleChunkRef : ListChunkRef -{ -public: - static ModuleChunkRef find(RiffContainer* container); - - String getName(); - - IRModuleChunkRef findIR(); - ASTModuleChunkRef findAST(); + String getName() const; - SHA1::Digest getDigest(); + IRModuleChunk const* findIR() const; + ASTModuleChunk const* findAST() const; - ChunkRefList<StringChunkRef> getFileDependencies(); + SHA1::Digest getDigest() const; -protected: - ModuleChunkRef(RiffContainer::Chunk* chunk) - : ListChunkRef(chunk) - { - } + RIFF::ChunkList<StringChunk> getFileDependencies() const; }; -struct EntryPointChunkRef : ListChunkRef +struct EntryPointChunk : RIFF::ListChunk { public: String getMangledName() const; String getName() const; Profile getProfile() const; - -protected: - EntryPointChunkRef(RiffContainer::Chunk* chunk) - : ListChunkRef(chunk) - { - } }; -struct ContainerChunkRef : ListChunkRef +struct ContainerChunk : RIFF::ListChunk { public: - static ContainerChunkRef find(RiffContainer* container); + static ContainerChunk const* find(RIFF::ListChunk const* baseChunk); - ChunkRefList<ModuleChunkRef> getModules(); + RIFF::ChunkList<ModuleChunk> getModules() const; - ChunkRefList<EntryPointChunkRef> getEntryPoints(); - -protected: - ContainerChunkRef(RiffContainer::Chunk* chunk) - : ListChunkRef(chunk) - { - } + RIFF::ChunkList<EntryPointChunk> getEntryPoints() const; }; -/// Attempt to find a debug-info chunk relative to -/// the given `startingChunk`. -/// -RiffContainer::ListChunk* findDebugChunk(RiffContainer::Chunk* startingChunk); +struct DebugChunk : RIFF::ListChunk +{ +public: + /// Search for a debug information chunk. + static DebugChunk const* find(RIFF::ListChunk const* baseChunk); + + /// Search for a debug information chunk. + /// + /// The search will initially look in `baseChunk`, but + /// if that fails, it will fall back to the `containerChunk` + /// if that is non-null. + /// + static DebugChunk const* find( + RIFF::ListChunk const* baseChunk, + RIFF::ListChunk const* containerChunk); +}; SlangResult readSourceLocationsFromDebugChunk( - RiffContainer::ListChunk* debugChunk, + DebugChunk const* debugChunk, SourceManager* sourceManager, RefPtr<SerialSourceLocReader>& outReader); SlangResult decodeModuleIR( RefPtr<IRModule>& outIRModule, - RiffContainer::Chunk* chunk, + IRModuleChunk const* chunk, Session* session, SerialSourceLocReader* sourceLocReader); diff --git a/source/slang/slang-serialize-ir-types.h b/source/slang/slang-serialize-ir-types.h index b3daf1772..d4c9dd9d7 100644 --- a/source/slang/slang-serialize-ir-types.h +++ b/source/slang/slang-serialize-ir-types.h @@ -20,20 +20,20 @@ class Name; struct IRSerialBinary { /// IR module list - static const FourCC kIRModuleFourCc = SLANG_FOUR_CC('S', 'i', 'm', 'd'); + static const FourCC::RawValue kIRModuleFourCc = SLANG_FOUR_CC('S', 'i', 'm', 'd'); /* NOTE! All FourCC that can be compressed must start with capital 'S', because compressed version is the same FourCC with the 'S' replaced with 's' */ - static const FourCC kInstFourCc = SLANG_FOUR_CC('S', 'L', 'i', 'n'); - static const FourCC kChildRunFourCc = SLANG_FOUR_CC('S', 'L', 'c', 'r'); - static const FourCC kExternalOperandsFourCc = SLANG_FOUR_CC('S', 'L', 'e', 'o'); + static const FourCC::RawValue kInstFourCc = SLANG_FOUR_CC('S', 'L', 'i', 'n'); + static const FourCC::RawValue kChildRunFourCc = SLANG_FOUR_CC('S', 'L', 'c', 'r'); + static const FourCC::RawValue kExternalOperandsFourCc = SLANG_FOUR_CC('S', 'L', 'e', 'o'); - static const FourCC kUInt32RawSourceLocFourCc = SLANG_FOUR_CC('S', 'r', 's', '4'); + static const FourCC::RawValue kUInt32RawSourceLocFourCc = SLANG_FOUR_CC('S', 'r', 's', '4'); /// Debug information is held elsewhere, but if this optional section exists, it maps /// instructions to locs - static const FourCC kDebugSourceLocRunFourCc = SLANG_FOUR_CC('S', 'd', 's', 'r'); + static const FourCC::RawValue kDebugSourceLocRunFourCc = SLANG_FOUR_CC('S', 'd', 's', 'r'); }; struct IRSerialData diff --git a/source/slang/slang-serialize-ir.cpp b/source/slang/slang-serialize-ir.cpp index bdea2faaa..f03f46da8 100644 --- a/source/slang/slang-serialize-ir.cpp +++ b/source/slang/slang-serialize-ir.cpp @@ -334,51 +334,43 @@ Result IRSerialWriter::write( Result _writeInstArrayChunk( FourCC chunkId, const List<IRSerialData::Inst>& array, - RiffContainer* container) + RIFF::BuildCursor& cursor) { - typedef RiffContainer::Chunk Chunk; - typedef RiffContainer::ScopeChunk ScopeChunk; - if (array.getCount() == 0) { return SLANG_OK; } - return SerialRiffUtil::writeArrayChunk(chunkId, array, container); + return SerialRiffUtil::writeArrayChunk(chunkId, array, cursor); } -/* static */ Result IRSerialWriter::writeContainer( - const IRSerialData& data, - RiffContainer* container) +/* static */ Result IRSerialWriter::writeTo(const IRSerialData& data, RIFF::BuildCursor& cursor) { - typedef RiffContainer::Chunk Chunk; - typedef RiffContainer::ScopeChunk ScopeChunk; - - ScopeChunk scopeModule(container, Chunk::Kind::List, Bin::kIRModuleFourCc); + SLANG_SCOPED_RIFF_BUILDER_LIST_CHUNK(cursor, Bin::kIRModuleFourCc); - SLANG_RETURN_ON_FAIL(_writeInstArrayChunk(Bin::kInstFourCc, data.m_insts, container)); + SLANG_RETURN_ON_FAIL(_writeInstArrayChunk(Bin::kInstFourCc, data.m_insts, cursor)); SLANG_RETURN_ON_FAIL( - SerialRiffUtil::writeArrayChunk(Bin::kChildRunFourCc, data.m_childRuns, container)); + SerialRiffUtil::writeArrayChunk(Bin::kChildRunFourCc, data.m_childRuns, cursor)); SLANG_RETURN_ON_FAIL(SerialRiffUtil::writeArrayChunk( Bin::kExternalOperandsFourCc, data.m_externalOperands, - container)); + cursor)); SLANG_RETURN_ON_FAIL(SerialRiffUtil::writeArrayChunk( SerialBinary::kStringTableFourCc, data.m_stringTable, - container)); + cursor)); SLANG_RETURN_ON_FAIL(SerialRiffUtil::writeArrayChunk( Bin::kUInt32RawSourceLocFourCc, data.m_rawSourceLocs, - container)); + cursor)); if (data.m_debugSourceLocRuns.getCount()) { SerialRiffUtil::writeArrayChunk( Bin::kDebugSourceLocRunFourCc, data.m_debugSourceLocRuns, - container); + cursor); } return SLANG_OK; @@ -417,31 +409,29 @@ Result _writeInstArrayChunk( // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IRSerialReader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -static Result _readInstArrayChunk( - RiffContainer::DataChunk* chunk, - List<IRSerialData::Inst>& arrayOut) +static Result _readInstArrayChunk(RIFF::DataChunk const* chunk, List<IRSerialData::Inst>& arrayOut) { SerialRiffUtil::ListResizerForType<IRSerialData::Inst> resizer(arrayOut); return SerialRiffUtil::readArrayChunk(chunk, resizer); } -/* static */ Result IRSerialReader::readContainer( - RiffContainer::ListChunk* module, +/* static */ Result IRSerialReader::readFrom( + IRModuleChunk const* irModuleChunk, IRSerialData* outData) { typedef IRSerialBinary Bin; outData->clear(); - for (RiffContainer::Chunk* chunk = module->m_containedChunks; chunk; chunk = chunk->m_next) + for (auto chunk : irModuleChunk->getChildren()) { - RiffContainer::DataChunk* dataChunk = as<RiffContainer::DataChunk>(chunk); + auto dataChunk = as<RIFF::DataChunk>(chunk); if (!dataChunk) { continue; } - switch (dataChunk->m_fourCC) + switch (dataChunk->getType()) { case Bin::kInstFourCc: { diff --git a/source/slang/slang-serialize-ir.h b/source/slang/slang-serialize-ir.h index 96121516b..c9fb16c27 100644 --- a/source/slang/slang-serialize-ir.h +++ b/source/slang/slang-serialize-ir.h @@ -13,6 +13,9 @@ namespace Slang { +struct IRModuleChunk : RIFF::ListChunk +{ +}; struct IRSerialWriter { @@ -26,7 +29,7 @@ struct IRSerialWriter IRSerialData* serialData); /// Write to a container - static Result writeContainer(const IRSerialData& data, RiffContainer* container); + static Result writeTo(const IRSerialData& data, RIFF::BuildCursor& cursor); /// Get an instruction index from an instruction Ser::InstIndex getInstIndex(IRInst* inst) const @@ -93,7 +96,7 @@ struct IRSerialReader typedef IRSerialData Ser; /// Read a stream to fill in dataOut IRSerialData - static Result readContainer(RiffContainer::ListChunk* module, IRSerialData* outData); + static Result readFrom(IRModuleChunk const* irModuleChunk, IRSerialData* outData); /// Read a module from serial data Result read( diff --git a/source/slang/slang-serialize-source-loc.cpp b/source/slang/slang-serialize-source-loc.cpp index b24324048..f612a6fb3 100644 --- a/source/slang/slang-serialize-source-loc.cpp +++ b/source/slang/slang-serialize-source-loc.cpp @@ -385,47 +385,44 @@ SlangResult SerialSourceLocReader::read( /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DebugSerialData !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -/* static */ Result SerialSourceLocData::writeContainer(RiffContainer* container) +/* static */ Result SerialSourceLocData::writeTo(RIFF::BuildCursor& cursor) { - RiffContainer::ScopeChunk debugChunkScope( - container, - RiffContainer::Chunk::Kind::List, - SerialSourceLocData::kDebugFourCc); + SLANG_SCOPED_RIFF_BUILDER_LIST_CHUNK(cursor, SerialSourceLocData::kDebugFourCc); SLANG_RETURN_ON_FAIL(SerialRiffUtil::writeArrayChunk( SerialSourceLocData::kDebugStringFourCc, m_stringTable, - container)); + cursor)); SLANG_RETURN_ON_FAIL(SerialRiffUtil::writeArrayChunk( SerialSourceLocData::kDebugLineInfoFourCc, m_lineInfos, - container)); + cursor)); SLANG_RETURN_ON_FAIL(SerialRiffUtil::writeArrayChunk( SerialSourceLocData::kDebugAdjustedLineInfoFourCc, m_adjustedLineInfos, - container)); + cursor)); SLANG_RETURN_ON_FAIL(SerialRiffUtil::writeArrayChunk( SerialSourceLocData::kDebugSourceInfoFourCc, m_sourceInfos, - container)); + cursor)); return SLANG_OK; } -/* static */ Result SerialSourceLocData::readContainer(RiffContainer::ListChunk* listChunk) +/* static */ Result SerialSourceLocData::readFrom(RIFF::ListChunk const* listChunk) { - SLANG_ASSERT(listChunk->getSubType() == SerialSourceLocData::kDebugFourCc); + SLANG_ASSERT(listChunk->getType() == SerialSourceLocData::kDebugFourCc); clear(); - for (RiffContainer::Chunk* chunk = listChunk->m_containedChunks; chunk; chunk = chunk->m_next) + for (auto chunk : listChunk->getChildren()) { - RiffContainer::DataChunk* dataChunk = as<RiffContainer::DataChunk>(chunk); + auto dataChunk = as<RIFF::DataChunk>(chunk); if (!dataChunk) { continue; } - switch (dataChunk->m_fourCC) + switch (dataChunk->getType()) { case SerialSourceLocData::kDebugStringFourCc: { diff --git a/source/slang/slang-serialize-source-loc.h b/source/slang/slang-serialize-source-loc.h index 24e1813a4..c6ef982c1 100644 --- a/source/slang/slang-serialize-source-loc.h +++ b/source/slang/slang-serialize-source-loc.h @@ -21,12 +21,12 @@ public: typedef SerialStringData::StringIndex StringIndex; // The list that contains all the subsequent modules - static const FourCC kDebugFourCc = SLANG_FOUR_CC('S', 'd', 'e', 'b'); + static const FourCC::RawValue kDebugFourCc = SLANG_FOUR_CC('S', 'd', 'e', 'b'); - static const FourCC kDebugStringFourCc = SLANG_FOUR_CC('S', 'd', 's', 't'); - static const FourCC kDebugLineInfoFourCc = SLANG_FOUR_CC('S', 'd', 'l', 'n'); - static const FourCC kDebugAdjustedLineInfoFourCc = SLANG_FOUR_CC('S', 'd', 'a', 'l'); - static const FourCC kDebugSourceInfoFourCc = SLANG_FOUR_CC('S', 'd', 's', 'o'); + static const FourCC::RawValue kDebugStringFourCc = SLANG_FOUR_CC('S', 'd', 's', 't'); + static const FourCC::RawValue kDebugLineInfoFourCc = SLANG_FOUR_CC('S', 'd', 'l', 'n'); + static const FourCC::RawValue kDebugAdjustedLineInfoFourCc = SLANG_FOUR_CC('S', 'd', 'a', 'l'); + static const FourCC::RawValue kDebugSourceInfoFourCc = SLANG_FOUR_CC('S', 'd', 's', 'o'); struct SourceRange { @@ -135,8 +135,8 @@ public: bool operator==(const ThisType& rhs) const; - Result writeContainer(RiffContainer* container); - Result readContainer(RiffContainer::ListChunk* listChunk); + Result writeTo(RIFF::BuildCursor& cursor); + Result readFrom(RIFF::ListChunk const* chunk); List<char> m_stringTable; ///< String table for debug use only List<LineInfo> m_lineInfos; ///< Line information diff --git a/source/slang/slang-serialize-types.cpp b/source/slang/slang-serialize-types.cpp index 2e6e56bb4..ca3bde608 100644 --- a/source/slang/slang-serialize-types.cpp +++ b/source/slang/slang-serialize-types.cpp @@ -149,41 +149,38 @@ struct ByteReader const void* data, size_t numEntries, size_t typeSize, - RiffContainer* container) + RIFF::BuildCursor& cursor) { - typedef RiffContainer::Chunk Chunk; - typedef RiffContainer::ScopeChunk ScopeChunk; - if (numEntries == 0) { return SLANG_OK; } - ScopeChunk scope(container, Chunk::Kind::Data, chunkId); + SLANG_SCOPED_RIFF_BUILDER_DATA_CHUNK(cursor, chunkId); SerialBinary::ArrayHeader header; header.numEntries = uint32_t(numEntries); - container->write(&header, sizeof(header)); - container->write(data, typeSize * numEntries); + cursor.addData(&header, sizeof(header)); + cursor.addData(data, typeSize * numEntries); return SLANG_OK; } /* static */ Result SerialRiffUtil::readArrayChunk( - RiffContainer::DataChunk* dataChunk, + RIFF::DataChunk const* dataChunk, ListResizer& listOut) { typedef SerialBinary Bin; - RiffReadHelper read = dataChunk->asReadHelper(); - const size_t typeSize = listOut.getTypeSize(); + MemoryReader reader(dataChunk->getPayload(), dataChunk->getPayloadSize()); + const Size typeSize = listOut.getTypeSize(); Bin::ArrayHeader header; - SLANG_RETURN_ON_FAIL(read.read(header)); - const size_t payloadSize = header.numEntries * typeSize; - SLANG_ASSERT(payloadSize == read.getRemainingSize()); + SLANG_RETURN_ON_FAIL(reader.read(header)); + const Size payloadSize = header.numEntries * typeSize; + SLANG_ASSERT(payloadSize == reader.getRemainingSize()); void* dst = listOut.setSize(header.numEntries); - ::memcpy(dst, read.getData(), payloadSize); + ::memcpy(dst, reader.getRemainingData(), payloadSize); return SLANG_OK; } diff --git a/source/slang/slang-serialize-types.h b/source/slang/slang-serialize-types.h index cd2b4c99c..09de865db 100644 --- a/source/slang/slang-serialize-types.h +++ b/source/slang/slang-serialize-types.h @@ -123,66 +123,65 @@ struct PropertyKeys template<> struct PropertyKeys<Module> { - static const FourCC Digest = SLANG_FOUR_CC('S', 'H', 'A', '1'); - static const FourCC ASTModule = SLANG_FOUR_CC('a', 's', 't', ' '); - static const FourCC IRModule = SLANG_FOUR_CC('i', 'r', ' ', ' '); - static const FourCC FileDependencies = SLANG_FOUR_CC('f', 'd', 'e', 'p'); + static const FourCC::RawValue Digest = SLANG_FOUR_CC('S', 'H', 'A', '1'); + static const FourCC::RawValue ASTModule = SLANG_FOUR_CC('a', 's', 't', ' '); + static const FourCC::RawValue FileDependencies = SLANG_FOUR_CC('f', 'd', 'e', 'p'); }; // For types/FourCC that work for serializing in general (not just IR). struct SerialBinary { - static const FourCC kRiffFourCc = RiffFourCC::kRiff; + static const FourCC::RawValue kRiffFourCc = RIFF::RootChunk::kTag; /// Container - static const FourCC kContainerFourCc = SLANG_FOUR_CC('S', 'L', 'm', 'c'); + static const FourCC::RawValue kContainerFourCc = SLANG_FOUR_CC('S', 'L', 'm', 'c'); /// A string table - static const FourCC kStringTableFourCc = SLANG_FOUR_CC('S', 'L', 's', 't'); + static const FourCC::RawValue kStringTableFourCc = SLANG_FOUR_CC('S', 'L', 's', 't'); /// TranslationUnitList - static const FourCC kModuleListFourCc = SLANG_FOUR_CC('S', 'L', 'm', 'l'); + static const FourCC::RawValue kModuleListFourCc = SLANG_FOUR_CC('S', 'L', 'm', 'l'); /// An entry point - static const FourCC kEntryPointFourCc = SLANG_FOUR_CC('E', 'P', 'n', 't'); + static const FourCC::RawValue kEntryPointFourCc = SLANG_FOUR_CC('E', 'P', 'n', 't'); - static const FourCC kEntryPointListFourCc = SLANG_FOUR_CC('e', 'p', 't', 's'); + static const FourCC::RawValue kEntryPointListFourCc = SLANG_FOUR_CC('e', 'p', 't', 's'); // Module - static const FourCC kModuleFourCC = SLANG_FOUR_CC('s', 'm', 'o', 'd'); + static const FourCC::RawValue kModuleFourCC = SLANG_FOUR_CC('s', 'm', 'o', 'd'); // The following are "generic" codes, suitable for // use when serializing content using JSON-like structure. // - static const FourCC kObjectFourCC = SLANG_FOUR_CC('o', 'b', 'j', ' '); - static const FourCC kPairFourCC = SLANG_FOUR_CC('p', 'a', 'i', 'r'); - static const FourCC kArrayFourCC = SLANG_FOUR_CC('a', 'r', 'r', 'y'); - static const FourCC kDictionaryFourCC = SLANG_FOUR_CC('d', 'i', 'c', 't'); - static const FourCC kNullFourCC = SLANG_FOUR_CC('n', 'u', 'l', 'l'); - static const FourCC kStringFourCC = SLANG_FOUR_CC('s', 't', 'r', ' '); - static const FourCC kTrueFourCC = SLANG_FOUR_CC('t', 'r', 'u', 'e'); - static const FourCC kFalseFourCC = SLANG_FOUR_CC('f', 'a', 'l', 's'); - static const FourCC kInt32FourCC = SLANG_FOUR_CC('i', '3', '2', ' '); - static const FourCC kUInt32FourCC = SLANG_FOUR_CC('u', '3', '2', ' '); - static const FourCC kFloat32FourCC = SLANG_FOUR_CC('f', '3', '2', ' '); - static const FourCC kInt64FourCC = SLANG_FOUR_CC('i', '6', '4', ' '); - static const FourCC kUInt64FourCC = SLANG_FOUR_CC('u', '6', '4', ' '); - static const FourCC kFloat64FourCC = SLANG_FOUR_CC('f', '6', '4', ' '); + static const FourCC::RawValue kObjectFourCC = SLANG_FOUR_CC('o', 'b', 'j', ' '); + static const FourCC::RawValue kPairFourCC = SLANG_FOUR_CC('p', 'a', 'i', 'r'); + static const FourCC::RawValue kArrayFourCC = SLANG_FOUR_CC('a', 'r', 'r', 'y'); + static const FourCC::RawValue kDictionaryFourCC = SLANG_FOUR_CC('d', 'i', 'c', 't'); + static const FourCC::RawValue kNullFourCC = SLANG_FOUR_CC('n', 'u', 'l', 'l'); + static const FourCC::RawValue kStringFourCC = SLANG_FOUR_CC('s', 't', 'r', ' '); + static const FourCC::RawValue kTrueFourCC = SLANG_FOUR_CC('t', 'r', 'u', 'e'); + static const FourCC::RawValue kFalseFourCC = SLANG_FOUR_CC('f', 'a', 'l', 's'); + static const FourCC::RawValue kInt32FourCC = SLANG_FOUR_CC('i', '3', '2', ' '); + static const FourCC::RawValue kUInt32FourCC = SLANG_FOUR_CC('u', '3', '2', ' '); + static const FourCC::RawValue kFloat32FourCC = SLANG_FOUR_CC('f', '3', '2', ' '); + static const FourCC::RawValue kInt64FourCC = SLANG_FOUR_CC('i', '6', '4', ' '); + static const FourCC::RawValue kUInt64FourCC = SLANG_FOUR_CC('u', '6', '4', ' '); + static const FourCC::RawValue kFloat64FourCC = SLANG_FOUR_CC('f', '6', '4', ' '); // The following codes are suitable for use when serializing // content that represents a logical file system. // - static const FourCC kDirectoryFourCC = SLANG_FOUR_CC('d', 'i', 'r', ' '); - static const FourCC kFileFourCC = SLANG_FOUR_CC('f', 'i', 'l', 'e'); - static const FourCC kNameFourCC = SLANG_FOUR_CC('n', 'a', 'm', 'e'); - static const FourCC kPathFourCC = SLANG_FOUR_CC('p', 'a', 't', 'h'); - static const FourCC kDataFourCC = SLANG_FOUR_CC('d', 'a', 't', 'a'); + static const FourCC::RawValue kDirectoryFourCC = SLANG_FOUR_CC('d', 'i', 'r', ' '); + static const FourCC::RawValue kFileFourCC = SLANG_FOUR_CC('f', 'i', 'l', 'e'); + static const FourCC::RawValue kNameFourCC = SLANG_FOUR_CC('n', 'a', 'm', 'e'); + static const FourCC::RawValue kPathFourCC = SLANG_FOUR_CC('p', 'a', 't', 'h'); + static const FourCC::RawValue kDataFourCC = SLANG_FOUR_CC('d', 'a', 't', 'a'); // TODO(tfoley): Figure out where to put all of these so that // they can be more usefully addressed. // - static const FourCC kMangledNameFourCC = SLANG_FOUR_CC('m', 'g', 'n', 'm'); - static const FourCC kProfileFourCC = SLANG_FOUR_CC('p', 'r', 'o', 'f'); + static const FourCC::RawValue kMangledNameFourCC = SLANG_FOUR_CC('m', 'g', 'n', 'm'); + static const FourCC::RawValue kProfileFourCC = SLANG_FOUR_CC('p', 'r', 'o', 'f'); struct ArrayHeader @@ -233,23 +232,18 @@ struct SerialRiffUtil const void* data, size_t numEntries, size_t typeSize, - RiffContainer* container); + RIFF::BuildCursor& cursor); template<typename T> - static Result writeArrayChunk(FourCC chunkId, const List<T>& array, RiffContainer* container) + static Result writeArrayChunk(FourCC chunkId, const List<T>& array, RIFF::BuildCursor& cursor) { - return writeArrayChunk( - chunkId, - array.begin(), - size_t(array.getCount()), - sizeof(T), - container); + return writeArrayChunk(chunkId, array.begin(), size_t(array.getCount()), sizeof(T), cursor); } - static Result readArrayChunk(RiffContainer::DataChunk* dataChunk, ListResizer& listOut); + static Result readArrayChunk(RIFF::DataChunk const* dataChunk, ListResizer& listOut); template<typename T> - static Result readArrayChunk(RiffContainer::DataChunk* dataChunk, List<T>& arrayOut) + static Result readArrayChunk(RIFF::DataChunk const* dataChunk, List<T>& arrayOut) { ListResizerForType<T> resizer(arrayOut); return readArrayChunk(dataChunk, resizer); diff --git a/source/slang/slang-serialize.h b/source/slang/slang-serialize.h index b694850ea..4b864fc94 100644 --- a/source/slang/slang-serialize.h +++ b/source/slang/slang-serialize.h @@ -30,52 +30,39 @@ struct ValNodeDesc; struct Encoder { public: - Encoder(Stream* stream) - : _stream(stream) + Encoder() {} + + Encoder(RIFF::Builder& riff) + : _cursor(riff) { } - ~Encoder() { RiffUtil::write(&_riff, _stream); } - - void beginArray(FourCC typeCode) + Encoder(RIFF::ListChunkBuilder* chunk) + : _cursor(chunk) { - _riff.startChunk(RiffContainer::Chunk::Kind::List, typeCode); } + void beginArray(FourCC typeCode) { _cursor.beginListChunk(typeCode); } + void beginArray() { beginArray(SerialBinary::kArrayFourCC); } - void endArray() - { - _riff.endChunk(); - // TODO: maybe end key... - } + void endArray() { _cursor.endChunk(); } - void beginObject(FourCC typeCode) - { - _riff.startChunk(RiffContainer::Chunk::Kind::List, typeCode); - } + void beginObject(FourCC typeCode) { _cursor.beginListChunk(typeCode); } void beginObject() { beginObject(SerialBinary::kObjectFourCC); } - void endObject() { _riff.endChunk(); } + void endObject() { _cursor.endChunk(); } - void beginKeyValuePair() - { - _riff.startChunk(RiffContainer::Chunk::Kind::List, SerialBinary::kPairFourCC); - } + void beginKeyValuePair(FourCC keyCode) { _cursor.beginListChunk(keyCode); } - void endKeyValuePair() { _riff.endChunk(); } + void beginKeyValuePair() { beginKeyValuePair(SerialBinary::kPairFourCC); } - void beginKeyValuePair(FourCC keyCode) - { - _riff.startChunk(RiffContainer::Chunk::Kind::List, keyCode); - } + void endKeyValuePair() { _cursor.endChunk(); } void encodeData(FourCC typeCode, void const* data, size_t size) { - _riff.startChunk(RiffContainer::Chunk::Kind::Data, typeCode); - _riff.write(data, size); - _riff.endChunk(); + _cursor.addDataChunk(typeCode, data, size); } void encodeData(void const* data, size_t size) @@ -200,24 +187,21 @@ public: }; private: - Stream* _stream = nullptr; - - // Implementation details below... - RiffContainer _riff; + RIFF::BuildCursor _cursor; public: - RiffContainer* getRIFF() { return &_riff; } + operator RIFF::BuildCursor&() { return _cursor; } - RiffContainer::Chunk* getRIFFChunk() { return _riff.getCurrentChunk(); } + RIFF::ChunkBuilder* getRIFFChunk() { return _cursor.getCurrentChunk(); } - void setRIFFChunk(RiffContainer::Chunk* chunk) { _riff.setCurrentChunk(chunk); } + void setRIFFChunk(RIFF::ChunkBuilder* chunk) { _cursor.setCurrentChunk(chunk); } }; struct Decoder { public: - Decoder(RiffContainer::Chunk* chunk) - : _chunk(chunk) + Decoder(RIFF::Chunk const* chunk) + : _cursor(chunk) { } @@ -226,10 +210,10 @@ public: switch (getTag()) { case SerialBinary::kTrueFourCC: - _chunk = _chunk->m_next; + _advanceCursor(); return true; case SerialBinary::kFalseFourCC: - _chunk = _chunk->m_next; + _advanceCursor(); return false; default: @@ -246,20 +230,20 @@ public: UNREACHABLE_RETURN(""); } - auto dataChunk = as<RiffContainer::DataChunk>(_chunk); + auto dataChunk = as<RIFF::DataChunk>(_cursor); if (!dataChunk) { SLANG_UNEXPECTED("invalid format in RIFF"); UNREACHABLE_RETURN(""); } - auto size = dataChunk->calcPayloadSize(); + auto size = dataChunk->getPayloadSize(); String value; value.appendRepeatedChar(' ', size); - dataChunk->getPayload((char*)value.getBuffer()); + dataChunk->writePayloadInto((char*)value.getBuffer(), size); - _chunk = _chunk->m_next; + _advanceCursor(); return value; } @@ -267,13 +251,14 @@ public: { if (getTag() == typeTag) { - auto dataChunk = as<RiffContainer::DataChunk>(_chunk); + auto dataChunk = as<RIFF::DataChunk>(_cursor); if (dataChunk) { - if (dataChunk->calcPayloadSize() >= dataSize) + auto payloadSize = dataChunk->getPayloadSize(); + if (payloadSize >= dataSize) { - dataChunk->getPayload(outData); - _chunk = _chunk->m_next; + dataChunk->writePayloadInto(outData, dataSize); + _advanceCursor(); return; } } @@ -368,7 +353,7 @@ public: float decodeFloat32() { return float(decodeFloat()); } double decodeFloat64() { return decodeFloat(); } - FourCC getTag() { return _chunk ? _chunk->m_fourCC : 0; } + FourCC getTag() { return _cursor ? _cursor->getType() : FourCC(0); } Int32 _decodeImpl(Int32*) { return decodeInt32(); } UInt32 _decodeImpl(UInt32*) { return decodeUInt32(); } @@ -393,74 +378,74 @@ public: void beginArray(FourCC typeCode = SerialBinary::kArrayFourCC) { - auto listChunk = as<RiffContainer::ListChunk>(_chunk); + auto listChunk = as<RIFF::ListChunk>(_cursor); if (!listChunk) { SLANG_UNEXPECTED("invalid format in RIFF"); } - if (listChunk->m_fourCC != typeCode) + if (listChunk->getType() != typeCode) { SLANG_UNEXPECTED("invalid format in RIFF"); } - _chunk = listChunk->getFirstContainedChunk(); + _cursor = listChunk->getFirstChild(); } void beginObject(FourCC typeCode = SerialBinary::kObjectFourCC) { - auto listChunk = as<RiffContainer::ListChunk>(_chunk); + auto listChunk = as<RIFF::ListChunk>(_cursor); if (!listChunk) { SLANG_UNEXPECTED("invalid format in RIFF"); } - if (listChunk->m_fourCC != typeCode) + if (listChunk->getType() != typeCode) { SLANG_UNEXPECTED("invalid format in RIFF"); } - _chunk = listChunk->getFirstContainedChunk(); + _cursor = listChunk->getFirstChild(); } void beginKeyValuePair(FourCC typeCode = SerialBinary::kPairFourCC) { - auto listChunk = as<RiffContainer::ListChunk>(_chunk); + auto listChunk = as<RIFF::ListChunk>(_cursor); if (!listChunk) { SLANG_UNEXPECTED("invalid format in RIFF"); } - if (listChunk->m_fourCC != typeCode) + if (listChunk->getType() != typeCode) { SLANG_UNEXPECTED("invalid format in RIFF"); } - _chunk = listChunk->getFirstContainedChunk(); + _cursor = listChunk->getFirstChild(); } void beginProperty(FourCC propertyCode) { - auto listChunk = as<RiffContainer::ListChunk>(_chunk); + auto listChunk = as<RIFF::ListChunk>(_cursor); if (!listChunk) { SLANG_UNEXPECTED("invalid format in RIFF"); } - auto found = listChunk->findContainedList(propertyCode); + auto found = listChunk->findListChunk(propertyCode); if (!found) { SLANG_UNEXPECTED("invalid format in RIFF"); } - _chunk = found->getFirstContainedChunk(); + _cursor = found->getFirstChild(); } - bool hasElements() { return _chunk != nullptr; } + bool hasElements() { return _cursor != nullptr; } bool isNull() { - if (_chunk == nullptr) + if (_cursor == nullptr) return true; if (getTag() == SerialBinary::kNullFourCC) return true; @@ -472,34 +457,36 @@ public: if (!isNull()) return false; - if (_chunk != nullptr) + if (_cursor != nullptr) { - _chunk = _chunk->m_next; + _advanceCursor(); } return true; } + using Cursor = RIFF::BoundsCheckedChunkPtr; + struct WithArray { public: WithArray(Decoder& decoder) : _decoder(decoder) { - _saved = decoder._chunk; + _saved = decoder._cursor; decoder.beginArray(); } WithArray(Decoder& decoder, FourCC typeCode) : _decoder(decoder) { - _saved = decoder._chunk; + _saved = decoder._cursor; decoder.beginArray(typeCode); } - ~WithArray() { _decoder._chunk = _saved->m_next; } + ~WithArray() { _decoder._cursor = _saved.getNextSibling(); } private: - RiffContainer::Chunk* _saved; + Cursor _saved; Decoder& _decoder; }; @@ -509,21 +496,21 @@ public: WithObject(Decoder& decoder) : _decoder(decoder) { - _saved = decoder._chunk; + _saved = decoder._cursor; decoder.beginObject(); } WithObject(Decoder& decoder, FourCC typeCode) : _decoder(decoder) { - _saved = decoder._chunk; + _saved = decoder._cursor; decoder.beginObject(typeCode); } - ~WithObject() { _decoder._chunk = _saved->m_next; } + ~WithObject() { _decoder._cursor = _saved.getNextSibling(); } private: - RiffContainer::Chunk* _saved; + Cursor _saved; Decoder& _decoder; }; @@ -533,21 +520,21 @@ public: WithKeyValuePair(Decoder& decoder) : _decoder(decoder) { - _saved = decoder._chunk; + _saved = decoder._cursor; decoder.beginKeyValuePair(); } WithKeyValuePair(Decoder& decoder, FourCC typeCode) : _decoder(decoder) { - _saved = decoder._chunk; + _saved = decoder._cursor; _decoder.beginKeyValuePair(typeCode); } - ~WithKeyValuePair() { _decoder._chunk = _saved->m_next; } + ~WithKeyValuePair() { _decoder._cursor = _saved.getNextSibling(); } private: - RiffContainer::Chunk* _saved; + Cursor _saved; Decoder& _decoder; }; @@ -557,23 +544,26 @@ public: WithProperty(Decoder& decoder, FourCC typeCode) : _decoder(decoder) { - _saved = decoder._chunk; + _saved = decoder._cursor; _decoder.beginProperty(typeCode); } - ~WithProperty() { _decoder._chunk = _saved->m_next; } + ~WithProperty() { _decoder._cursor = _saved.getNextSibling(); } private: - RiffContainer::Chunk* _saved; + Cursor _saved; Decoder& _decoder; }; + Cursor getCursor() const { return _cursor; } + void setCursor(Cursor const& cursor) { _cursor = cursor; } - RiffContainer::Chunk* getCursor() { return _chunk; } - void setCursor(RiffContainer::Chunk* chunk) { _chunk = chunk; } + RIFF::Chunk const* getCurrentChunk() const { return getCursor(); } private: - RiffContainer::Chunk* _chunk = nullptr; + void _advanceCursor() { _cursor = _cursor.getNextSibling(); } + + Cursor _cursor; }; diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index 68df665d4..9dea0f167 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -4582,7 +4582,7 @@ static TypeLayoutResult _updateLayout( if (layoutResultPtr) { // Check the layout is the same! - SLANG_ASSERT(layoutResultPtr->layout.get() == result.layout); + SLANG_ASSERT(layoutResultPtr->layout == result.layout); // Update the info layoutResultPtr->info = result.info; } diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 613fb7090..602446cda 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -687,34 +687,31 @@ SlangResult Session::_readBuiltinModule( StringBuilder moduleFilename; moduleFilename << moduleName << ".slang-module"; - RiffContainer riffContainer; - { - // Load it - ComPtr<ISlangBlob> blob; - SLANG_RETURN_ON_FAIL(fileSystem->loadFile(moduleFilename.getBuffer(), blob.writeRef())); - - // Set up a stream - MemoryStreamBase stream(FileAccess::Read, blob->getBufferPointer(), blob->getBufferSize()); + // Load it + ComPtr<ISlangBlob> fileContents; + SLANG_RETURN_ON_FAIL(fileSystem->loadFile(moduleFilename.getBuffer(), fileContents.writeRef())); - // Load the riff container - SLANG_RETURN_ON_FAIL(RiffUtil::read(&stream, riffContainer)); + RIFF::RootChunk const* rootChunk = RIFF::RootChunk::getFromBlob(fileContents); + if (!rootChunk) + { + return SLANG_FAIL; } Linkage* linkage = getBuiltinLinkage(); SourceManager* sourceManager = getBuiltinSourceManager(); NamePool* sessionNamePool = &namePool; - auto moduleChunk = ModuleChunkRef::find(&riffContainer); + auto moduleChunk = ModuleChunk::find(rootChunk); if (!moduleChunk) return SLANG_FAIL; - SHA1::Digest moduleDigest = moduleChunk.getDigest(); + SHA1::Digest moduleDigest = moduleChunk->getDigest(); - auto irChunk = moduleChunk.findIR(); + auto irChunk = moduleChunk->findIR(); if (!irChunk) return SLANG_FAIL; - auto astChunk = moduleChunk.findAST(); + auto astChunk = moduleChunk->findAST(); if (!astChunk) return SLANG_FAIL; @@ -724,7 +721,7 @@ SlangResult Session::_readBuiltinModule( // in the IR and AST deserialization (if we find anything). // RefPtr<SerialSourceLocReader> sourceLocReader; - if (auto debugChunk = findDebugChunk(moduleChunk.ptr())) + if (auto debugChunk = DebugChunk::find(moduleChunk)) { SLANG_RETURN_ON_FAIL( readSourceLocationsFromDebugChunk(debugChunk, sourceManager, sourceLocReader)); @@ -4134,7 +4131,8 @@ void Linkage::loadParsedModule( } RefPtr<Module> Linkage::findOrLoadSerializedModuleForModuleLibrary( - ModuleChunkRef moduleChunk, + ModuleChunk const* moduleChunk, + RIFF::ListChunk const* libraryChunk, DiagnosticSink* sink) { RefPtr<Module> resultModule; @@ -4147,7 +4145,7 @@ RefPtr<Module> Linkage::findOrLoadSerializedModuleForModuleLibrary( // The first step is to simply decode the module name, and // see if we have a already loaded a matching module. - auto moduleName = getNamePool()->getName(moduleChunk.getName()); + auto moduleName = getNamePool()->getName(moduleChunk->getName()); if (mapNameToLoadedModules.tryGetValue(moduleName, resultModule)) return resultModule; @@ -4163,12 +4161,12 @@ RefPtr<Module> Linkage::findOrLoadSerializedModuleForModuleLibrary( // already. It isn't something that can be fixed in just one // place at this point. - auto fileDependenciesChunk = moduleChunk.getFileDependencies(); - auto firstFileDependencyChunk = fileDependenciesChunk.getFirst(); + auto fileDependenciesList = moduleChunk->getFileDependencies(); + auto firstFileDependencyChunk = fileDependenciesList.getFirst(); if (!firstFileDependencyChunk) return nullptr; - auto modulePathInfo = PathInfo::makePath(firstFileDependencyChunk.getValue()); + auto modulePathInfo = PathInfo::makePath(firstFileDependencyChunk->getValue()); if (mapPathToLoadedModule.tryGetValue(modulePathInfo.getMostUniqueIdentity(), resultModule)) return resultModule; @@ -4176,13 +4174,20 @@ RefPtr<Module> Linkage::findOrLoadSerializedModuleForModuleLibrary( // will go ahead and load the module from the serialized form. // PathInfo filePathInfo; - return loadSerializedModule(moduleName, modulePathInfo, moduleChunk, SourceLoc(), sink); + return loadSerializedModule( + moduleName, + modulePathInfo, + moduleChunk, + libraryChunk, + SourceLoc(), + sink); } RefPtr<Module> Linkage::loadSerializedModule( Name* moduleName, const PathInfo& moduleFilePathInfo, - ModuleChunkRef moduleChunk, + ModuleChunk const* moduleChunk, + RIFF::ListChunk const* containerChunk, SourceLoc const& requestingLoc, DiagnosticSink* sink) { @@ -4211,8 +4216,12 @@ RefPtr<Module> Linkage::loadSerializedModule( mapNameToLoadedModules.add(moduleName, module); try { - if (SLANG_FAILED( - loadSerializedModuleContents(module, moduleFilePathInfo, moduleChunk, sink))) + if (SLANG_FAILED(loadSerializedModuleContents( + module, + moduleFilePathInfo, + moduleChunk, + containerChunk, + sink))) { mapPathToLoadedModule.remove(mostUniqueIdentity); mapNameToLoadedModules.remove(moduleName); @@ -4240,24 +4249,17 @@ RefPtr<Module> Linkage::loadBinaryModuleImpl( auto astBuilder = getASTBuilder(); SLANG_AST_BUILDER_RAII(astBuilder); - // We start by reading the content of the file into + // We start by reading the content of the file as // an in-memory RIFF container. // - // TODO(tfoley): this is an unnecessary copy step, since - // we can simply use the contents of the blob directly - // and navigate it in-memory. - // - RiffContainer riffContainer; + auto rootChunk = RIFF::RootChunk::getFromBlob(moduleFileContents); + if (!rootChunk) { - MemoryStreamBase readStream( - FileAccess::Read, - moduleFileContents->getBufferPointer(), - moduleFileContents->getBufferSize()); - SLANG_RETURN_NULL_ON_FAIL(RiffUtil::read(&readStream, riffContainer)); + return nullptr; } - auto moduleChunkRef = ModuleChunkRef::find(&riffContainer); - if (!moduleChunkRef) + auto moduleChunk = ModuleChunk::find(rootChunk); + if (!moduleChunk) { return nullptr; } @@ -4271,7 +4273,7 @@ RefPtr<Module> Linkage::loadBinaryModuleImpl( SLANG_ASSERT(mostUniqueIdentity.getLength() > 0); if (m_optionSet.getBoolOption(CompilerOptionName::UseUpToDateBinaryModule)) { - if (!isBinaryModuleUpToDate(moduleFilePathInfo.foundPath, moduleChunkRef)) + if (!isBinaryModuleUpToDate(moduleFilePathInfo.foundPath, moduleChunk)) { return nullptr; } @@ -4280,8 +4282,13 @@ RefPtr<Module> Linkage::loadBinaryModuleImpl( // If everything seems reasonable, then we will go ahead and load // the module more completely from that serialized representation. // - RefPtr<Module> module = - loadSerializedModule(moduleName, moduleFilePathInfo, moduleChunkRef, requestingLoc, sink); + RefPtr<Module> module = loadSerializedModule( + moduleName, + moduleFilePathInfo, + moduleChunk, + rootChunk, + requestingLoc, + sink); return module; } @@ -4744,18 +4751,13 @@ SourceFile* Linkage::loadSourceFile(String pathFrom, String path) } // Check if a serialized module is up-to-date with current compiler options and source files. -bool Linkage::isBinaryModuleUpToDate(String fromPath, RiffContainer* riffContainer) +bool Linkage::isBinaryModuleUpToDate(String fromPath, RIFF::ListChunk const* baseChunk) { - auto moduleChunk = ModuleChunkRef::find(riffContainer); + auto moduleChunk = ModuleChunk::find(baseChunk); if (!moduleChunk) return false; - return isBinaryModuleUpToDate(fromPath, moduleChunk); -} - -bool Linkage::isBinaryModuleUpToDate(String fromPath, ModuleChunkRef moduleChunk) -{ - SHA1::Digest existingDigest = moduleChunk.getDigest(); + SHA1::Digest existingDigest = moduleChunk->getDigest(); DigestBuilder<SHA1> digestBuilder; auto version = String(getBuildTagString()); @@ -4765,10 +4767,10 @@ bool Linkage::isBinaryModuleUpToDate(String fromPath, ModuleChunkRef moduleChunk // Find the canonical path of the directory containing the module source file. String moduleSrcPath = ""; - auto dependencyChunks = moduleChunk.getFileDependencies(); + auto dependencyChunks = moduleChunk->getFileDependencies(); if (auto firstDependencyChunk = dependencyChunks.getFirst()) { - moduleSrcPath = firstDependencyChunk.getValue(); + moduleSrcPath = firstDependencyChunk->getValue(); IncludeSystem includeSystem( &getSearchDirectories(), @@ -4784,7 +4786,7 @@ bool Linkage::isBinaryModuleUpToDate(String fromPath, ModuleChunkRef moduleChunk for (auto dependencyChunk : dependencyChunks) { - auto file = dependencyChunk.getValue(); + auto file = dependencyChunk->getValue(); auto sourceFile = loadSourceFile(fromPath, file); if (!sourceFile) { @@ -4803,14 +4805,10 @@ bool Linkage::isBinaryModuleUpToDate(String fromPath, ModuleChunkRef moduleChunk SLANG_NO_THROW bool SLANG_MCALL Linkage::isBinaryModuleUpToDate(const char* modulePath, slang::IBlob* binaryModuleBlob) { - RiffContainer container; - MemoryStreamBase readStream( - FileAccess::Read, - binaryModuleBlob->getBufferPointer(), - binaryModuleBlob->getBufferSize()); - if (SLANG_FAILED(RiffUtil::read(&readStream, container))) + auto rootChunk = RIFF::RootChunk::getFromBlob(binaryModuleBlob); + if (!rootChunk) return false; - return isBinaryModuleUpToDate(modulePath, &container); + return isBinaryModuleUpToDate(modulePath, rootChunk); } SourceFile* Linkage::findFile(Name* name, SourceLoc loc, IncludeSystem& outIncludeSystem) @@ -6534,7 +6532,8 @@ void Linkage::setFileSystem(ISlangFileSystem* inFileSystem) SlangResult Linkage::loadSerializedModuleContents( Module* module, const PathInfo& moduleFilePathInfo, - ModuleChunkRef moduleChunk, + ModuleChunk const* moduleChunk, + RIFF::ListChunk const* containerChunk, DiagnosticSink* sink) { // At this point we've dealt with basically all of @@ -6542,19 +6541,49 @@ SlangResult Linkage::loadSerializedModuleContents( // to the real work of decoding the information // in the `moduleChunk`. + // + // TODO(tfoley): The fact that a separate `containerChunk` is getting + // passed in here is entirely byproduct of the support for "module libraries" + // that can (in principle) contain multiple serialized modules. When + // things are serialized in the "container" representation used for + // a module library, there is a single `DebugChunk` as a child of + // the container, with all of the `ModuleChunk`s sharing that debug info. + // + // In contrast, the more typical kind of serialized module that the compiler + // produces serializes a single `ModuleChunk`, and the `DebugChunk` is + // one of its direct children. Thus there are currently two different + // locations where debug information might be found. + // + // Prior to the change where we navigate the serialized RIFF hierarchy + // in memory without copying it, this issue was addressed by having + // the subroutine that looked for a `DebugChunk` start at the `ModuleChunk` + // and work its way up through the hierarchy using parent pointers that + // were created as part of RIFF loading. When navigating the RIFF in-place + // we don't have such parent pointers. + // + // As a short-term solution, we should deprecate and remove the support + // for "module libraries" so that the code doesn't have to handle two + // different layouts. + // + // In the longer term, we should be making some conscious design decisions + // around how we want to organize the top-level structure of our serialized + // intermediate/output formats, since there's quite a mix of different + // approaches currently in use. + // + auto sourceManager = getSourceManager(); RefPtr<SerialSourceLocReader> sourceLocReader; - if (auto debugChunk = findDebugChunk(moduleChunk.ptr())) + if (auto debugChunk = DebugChunk::find(moduleChunk, containerChunk)) { SLANG_RETURN_ON_FAIL( readSourceLocationsFromDebugChunk(debugChunk, sourceManager, sourceLocReader)); } - auto astChunk = moduleChunk.findAST(); + auto astChunk = moduleChunk->findAST(); if (!astChunk) return SLANG_FAIL; - auto irChunk = moduleChunk.findIR(); + auto irChunk = moduleChunk->findIR(); if (!irChunk) return SLANG_FAIL; @@ -6620,9 +6649,9 @@ SlangResult Linkage::loadSerializedModuleContents( module->clearFileDependency(); String moduleSourcePath = moduleFilePathInfo.foundPath; bool isFirst = true; - for (auto depenencyFileChunk : moduleChunk.getFileDependencies()) + for (auto depenencyFileChunk : moduleChunk->getFileDependencies()) { - auto encodedDependencyFilePath = depenencyFileChunk.getValue(); + auto encodedDependencyFilePath = depenencyFileChunk->getValue(); auto sourceFile = loadSourceFile(moduleFilePathInfo.foundPath, encodedDependencyFilePath); if (isFirst) @@ -6646,7 +6675,7 @@ SlangResult Linkage::loadSerializedModuleContents( } } module->setPathInfo(moduleFilePathInfo); - module->setDigest(moduleChunk.getDigest()); + module->setDigest(moduleChunk->getDigest()); module->_collectShaderParams(); module->_discoverEntryPoints(sink, targets); @@ -7159,8 +7188,8 @@ SlangResult _addLibraryReference( SourceMap::getTypeGuid(), ArtifactKeep::Yes, castable.writeRef())); - auto sourceMap = asBoxValue<SourceMap>(castable); - SLANG_ASSERT(sourceMap); + auto sourceMapBox = asBoxValue<SourceMap>(castable); + SLANG_ASSERT(sourceMapBox); // TODO(JS): // There is perhaps (?) a risk here that we might copy the obfuscated map @@ -7175,7 +7204,7 @@ SlangResult _addLibraryReference( // unit(s). for (auto module : library->m_modules) { - module->getIRModule()->setObfuscatedSourceMap(sourceMap); + module->getIRModule()->setObfuscatedSourceMap(sourceMapBox); } // Look up the source file @@ -7185,8 +7214,26 @@ SlangResult _addLibraryReference( if (name.getLength()) { + // Note(tfoley): There is a subtle requirement here, that any + // source file `name` that might be searched for here *must* + // have been added to the `sourceManager` already, as a + // byproduct of debug source location information getting + // deserialized as part of the call to `loadModuleLibrary()` above. + // + // The implicit dependency is frustrating, and could potentially + // break if somehow the debug info chunk was stripped from a binary, + // while the source map was left in (which should be valid, even if + // it is unlikely to be what a user wants). + // + // Ideally the source map would either be made an integral part of + // the debug source location chunk, so they are loaded together, + // or the `SourceManager` would be adapted so that it can store + // registered source maps independent of whether or not the + // corresponding source file(s) have been loaded. + auto sourceFile = sourceManager->findSourceFileByPathRecursively(name); - sourceFile->setSourceMap(sourceMap, SourceMapKind::Obfuscated); + SLANG_ASSERT(sourceFile); + sourceFile->setSourceMap(sourceMapBox, SourceMapKind::Obfuscated); } } } |
