diff options
Diffstat (limited to 'source/slang/slang.cpp')
| -rw-r--r-- | source/slang/slang.cpp | 185 |
1 files changed, 116 insertions, 69 deletions
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); } } } |
