summaryrefslogtreecommitdiffstats
path: root/source/slang/slang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang.cpp')
-rw-r--r--source/slang/slang.cpp101
1 files changed, 91 insertions, 10 deletions
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 62fb3cbdb..c0f89b0dc 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -3165,12 +3165,19 @@ RefPtr<Module> Linkage::loadModuleFromIRBlobImpl(
String mostUniqueIdentity = filePathInfo.getMostUniqueIdentity();
SLANG_ASSERT(mostUniqueIdentity.getLength() > 0);
- mapPathToLoadedModule.add(mostUniqueIdentity, resultModule);
- mapNameToLoadedModules.add(name, resultModule);
-
RiffContainer container;
MemoryStreamBase readStream(FileAccess::Read, fileContentsBlob->getBufferPointer(), fileContentsBlob->getBufferSize());
SLANG_RETURN_NULL_ON_FAIL(RiffUtil::read(&readStream, container));
+
+ if (m_optionSet.getBoolOption(CompilerOptionName::UseUpToDateBinaryModule))
+ {
+ if (!isBinaryModuleUpToDate(filePathInfo.foundPath, &container))
+ return nullptr;
+ }
+
+ mapPathToLoadedModule.add(mostUniqueIdentity, resultModule);
+ mapNameToLoadedModules.add(name, resultModule);
+
SerialContainerUtil::ReadOptions readOptions;
readOptions.linkage = this;
readOptions.astBuilder = getASTBuilder();
@@ -3180,12 +3187,25 @@ RefPtr<Module> Linkage::loadModuleFromIRBlobImpl(
readOptions.sourceManager = getSourceManager();
readOptions.namePool = getNamePool();
SerialContainerData containerData;
- SLANG_RETURN_NULL_ON_FAIL(SerialContainerUtil::read(&container, readOptions, additionalLoadedModules, containerData));
- if (containerData.modules.getCount() != 1)
+ if (SLANG_FAILED(SerialContainerUtil::read(&container, readOptions, additionalLoadedModules, containerData)) ||
+ containerData.modules.getCount() != 1)
+ {
+ mapPathToLoadedModule.remove(mostUniqueIdentity);
+ mapNameToLoadedModules.remove(name);
return nullptr;
+ }
auto moduleEntry = containerData.modules.getFirst();
resultModule->setIRModule(moduleEntry.irModule);
resultModule->setModuleDecl(as<ModuleDecl>(moduleEntry.astRootNode));
+ resultModule->clearFileDependency();
+ for (auto file : moduleEntry.dependentFiles)
+ {
+ auto sourceFile = loadSourceFile(filePathInfo.foundPath, file);
+ if (sourceFile)
+ {
+ resultModule->addFileDependency(sourceFile);
+ }
+ }
prepareDeserializedModule(resultModule, sink);
@@ -3463,7 +3483,7 @@ RefPtr<Module> Linkage::findOrImportModule(
// We've found a file that we can load for the given module, so
// go ahead and perform the module-load action
- return loadModule(
+ auto resultModule = loadModule(
name,
filePathInfo,
fileContents,
@@ -3471,6 +3491,8 @@ RefPtr<Module> Linkage::findOrImportModule(
sink,
loadedModules,
(checkBinaryModule == 1 ? ModuleBlobType::IR : ModuleBlobType::Source));
+ if (resultModule)
+ return resultModule;
}
// Error: we cannot find the file.
@@ -3479,6 +3501,67 @@ RefPtr<Module> Linkage::findOrImportModule(
return nullptr;
}
+SourceFile* Linkage::loadSourceFile(String pathFrom, String path)
+{
+ IncludeSystem includeSystem(&getSearchDirectories(), getFileSystemExt(), getSourceManager());
+ ComPtr<slang::IBlob> blob;
+ PathInfo pathInfo;
+ SLANG_RETURN_NULL_ON_FAIL(includeSystem.findFile(path, pathFrom, pathInfo));
+ SourceFile* sourceFile = nullptr;
+ SLANG_RETURN_NULL_ON_FAIL(includeSystem.loadFile(pathInfo, blob, sourceFile));
+ return sourceFile;
+}
+
+ // Check if a serialized module is up-to-date with current compiler options and source files.
+bool Linkage::isBinaryModuleUpToDate(String fromPath, RiffContainer* container)
+{
+ DiagnosticSink sink;
+ SerialContainerUtil::ReadOptions readOptions;
+ readOptions.linkage = this;
+ readOptions.astBuilder = getASTBuilder();
+ readOptions.session = getSessionImpl();
+ readOptions.sharedASTBuilder = getASTBuilder()->getSharedASTBuilder();
+ readOptions.sink = &sink;
+ readOptions.sourceManager = getSourceManager();
+ readOptions.namePool = getNamePool();
+ readOptions.readHeaderOnly = true;
+
+ SerialContainerData containerData;
+ if (SLANG_FAILED(SerialContainerUtil::read(container, readOptions, nullptr, containerData)))
+ return false;
+
+ if (containerData.modules.getCount() != 1)
+ return false;
+
+ auto& moduleHeader = containerData.modules[0];
+ DigestBuilder<SHA1> digestBuilder;
+ m_optionSet.buildHash(digestBuilder);
+ for (auto file : moduleHeader.dependentFiles)
+ {
+ auto sourceFile = loadSourceFile(fromPath, file);
+ if (!sourceFile)
+ {
+ // If we cannot find the source file from `fromPath`,
+ // try again from the module's source file path.
+ if (moduleHeader.dependentFiles.getCount() != 0)
+ sourceFile = loadSourceFile(moduleHeader.dependentFiles.getFirst(), file);
+ }
+ if (!sourceFile)
+ return false;
+ digestBuilder.append(sourceFile->getDigest());
+ }
+ return digestBuilder.finalize() == moduleHeader.digest;
+}
+
+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)))
+ return false;
+ return isBinaryModuleUpToDate(modulePath, &container);
+}
+
SourceFile* Linkage::findFile(Name* name, SourceLoc loc, IncludeSystem& outIncludeSystem)
{
auto fileName = getFileNameFromModuleName(name);
@@ -3665,7 +3748,7 @@ Module::Module(Linkage* linkage, ASTBuilder* astBuilder)
{
m_astBuilder = linkage->getASTBuilder();
}
-
+ getOptionSet() = linkage->m_optionSet;
addModuleDependency(this);
}
@@ -4004,9 +4087,7 @@ SLANG_NO_THROW void SLANG_MCALL ComponentType::getEntryPointHash(
// Enumerate all file dependencies and add them to the hash.
for (SourceFile* sourceFile : getFileDependencies())
{
- // TODO: We want to lazily evaluate & cache the source file digest
- SHA1::Digest digest = SHA1::compute(sourceFile->getContent().begin(), sourceFile->getContent().getLength());
- builder.append(digest);
+ builder.append(sourceFile->getDigest());
}
buildHash(builder);