diff options
Diffstat (limited to 'source/slang/slang-repro.h')
| -rw-r--r-- | source/slang/slang-repro.h | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/source/slang/slang-repro.h b/source/slang/slang-repro.h new file mode 100644 index 000000000..bd35d3ee9 --- /dev/null +++ b/source/slang/slang-repro.h @@ -0,0 +1,200 @@ +// slang-repro.h +#ifndef SLANG_REPRO_H_INCLUDED +#define SLANG_REPRO_H_INCLUDED + +#include "../core/slang-riff.h" +#include "../core/slang-string.h" + +// For TranslationUnitRequest +#include "slang-compiler.h" + +#include "../core/slang-offset-container.h" + +#include "slang-file-system.h" + +namespace Slang { + +/* Facilities to be able to save and load the full state of a compilation, including source files, +and all compilation options into 'slang-repro' files. Repro is short for 'reproducible' and it's +main purposes is to make compilations easily reproducible as everything that is needed from +a compilation environment is packaged up into a single file. The single file can be used to +repeat the compilation, or extracted such that everything that was specified in the compilation +can be inspected and modified. */ +struct ReproUtil +{ + enum + { + kMajorVersion = 0, + kMinorVersion = 0, + kPatchVersion = 0, + }; + + static const uint32_t kSlangStateFourCC = SLANG_FOUR_CC('S', 'L', 'S', 'T'); ///< Holds all the slang specific chunks + static const RiffSemanticVersion g_semanticVersion; + + struct Header + { + RiffHeader m_chunk; ///< The chunk + RiffSemanticVersion m_semanticVersion; ///< The semantic version + uint32_t m_typeHash; ///< A hash based on the binary representation. If doesn't match then not binary compatible (extra check over semantic versioning) + }; + + struct FileState + { + Offset32Ptr<OffsetString> uniqueIdentity; ///< The unique identity for the file (from ISlangFileSystem), or nullptr + Offset32Ptr<OffsetString> contents; ///< The contents of this file + Offset32Ptr<OffsetString> canonicalPath; ///< The canonical name of this file (or nullptr) + Offset32Ptr<OffsetString> foundPath; ///< The 'found' path + + Offset32Ptr<OffsetString> uniqueName; ///< A generated unique name (not used by slang, but used as mechanism to replace files) + }; + + struct PathInfoState + { + typedef CacheFileSystem::CompressedResult CompressedResult; + + SlangPathType pathType = SLANG_PATH_TYPE_FILE; + CompressedResult loadFileResult = CompressedResult::Uninitialized; + CompressedResult getPathTypeResult = CompressedResult::Uninitialized; + CompressedResult getCanonicalPathResult = CompressedResult::Uninitialized; + + Offset32Ptr<FileState> file; ///< File contents + }; + + struct PathAndPathInfo + { + Offset32Ptr<OffsetString> path; + Offset32Ptr<PathInfoState> pathInfo; + }; + + struct OutputState + { + int32_t entryPointIndex; + Offset32Ptr<OffsetString> outputPath; + }; + + // spSetCodeGenTarget/spAddCodeGenTarget + // spSetTargetProfile + // spSetTargetFlags + // spSetTargetFloatingPointMode + // spSetTargetMatrixLayoutMode + struct TargetRequestState + { + Profile profile; + CodeGenTarget target; + SlangTargetFlags targetFlags; + FloatingPointMode floatingPointMode; + + Offset32Array<OutputState> outputStates; + }; + + struct StringPair + { + Offset32Ptr<OffsetString> first; + Offset32Ptr<OffsetString> second; + }; + + struct SourceFileState + { + PathInfo::Type type; ///< The type of this file + Offset32Ptr<OffsetString> foundPath; ///< The Path this was found along + Offset32Ptr<FileState> file; ///< The file contents + }; + + // spAddTranslationUnit + struct TranslationUnitRequestState + { + SourceLanguage language; + + Offset32Ptr<OffsetString> moduleName; + + // spTranslationUnit_addPreprocessorDefine + Offset32Array<StringPair> preprocessorDefinitions; + + Offset32Array<Offset32Ptr<SourceFileState> > sourceFiles; + }; + + struct EntryPointState + { + Offset32Ptr<OffsetString> name; + Profile profile; + uint32_t translationUnitIndex; + Offset32Array<Offset32Ptr<OffsetString>> specializationArgStrings; + }; + + struct RequestState + { + Offset32Array<Offset32Ptr<FileState>> files; ///< All of the files + Offset32Array<Offset32Ptr<SourceFileState>> sourceFiles; ///< All of the source files (from source manager) + + // spSetCompileFlags + SlangCompileFlags compileFlags; + // spSetDumpIntermediates + bool shouldDumpIntermediates; + // spSetLineDirectiveMode + LineDirectiveMode lineDirectiveMode; + + Offset32Array<TargetRequestState> targetRequests; + + // spSetDebugInfoLevel + DebugInfoLevel debugInfoLevel; + // spSetOptimizationLevel + OptimizationLevel optimizationLevel; + // spSetOutputContainerFormat + ContainerFormat containerFormat; + // spSetPassThrough + PassThroughMode passThroughMode; + + // spAddSearchPath + Offset32Array<Offset32Ptr<OffsetString> > searchPaths; + + // spAddPreprocessorDefine + Offset32Array<StringPair> preprocessorDefinitions; + + bool useUnknownImageFormatAsDefault = false; + bool obfuscateCode = false; + + Offset32Array<PathAndPathInfo> pathInfoMap; ///< Stores all the accesses to the file system + + Offset32Array<TranslationUnitRequestState> translationUnits; + + Offset32Array<EntryPointState> entryPoints; + + SlangMatrixLayoutMode defaultMatrixLayoutMode; + }; + + static SlangResult store(EndToEndCompileRequest* request, OffsetContainer& inOutContainer, Offset32Ptr<RequestState>& outRequest); + + static SlangResult saveState(EndToEndCompileRequest* request, const String& filename); + + static SlangResult saveState(EndToEndCompileRequest* request, Stream* stream); + + /// Create a cache file system that uses contents of the request state. + /// The passed in fileSystem is used for accessing any file accesses not found in the cache + static SlangResult loadFileSystem(OffsetBase& base, RequestState* requestState, ISlangFileSystem* fileSystem, RefPtr<CacheFileSystem>& outFileSystem); + + /// Load the requestState into request + /// The fileSystem is optional and can be passed as nullptr. If set, as each file is loaded + /// it will attempt to load from fileSystem the *uniqueName* + static SlangResult load(OffsetBase& base, RequestState* requestState, ISlangFileSystem* fileSystem, EndToEndCompileRequest* request); + + static SlangResult loadState(const String& filename, List<uint8_t>& outBuffer); + static SlangResult loadState(Stream* stream, List<uint8_t>& outBuffer); + static SlangResult loadState(const uint8_t* data, size_t size, List<uint8_t>& outBuffer); + + static RequestState* getRequest(const List<uint8_t>& inBuffer); + + static SlangResult extractFilesToDirectory(const String& file); + + static SlangResult extractFiles(OffsetBase& base, RequestState* requestState, ISlangFileSystemExt* fileSystem); + + /// Given the repo file work out a suitable path + static SlangResult calcDirectoryPathFromFilename(const String& filename, String& outPath); + + /// Given a request trys to determine a suitable dump file name, that is unique. + static SlangResult findUniqueReproDumpStream(EndToEndCompileRequest* request, String& outFileName, RefPtr<Stream>& outStream); +}; + +} // namespace Slang + +#endif |
