summaryrefslogtreecommitdiff
path: root/source/slang
diff options
context:
space:
mode:
authorTheresa Foley <10618364+tangent-vector@users.noreply.github.com>2025-05-12 10:28:05 -0700
committerGitHub <noreply@github.com>2025-05-12 17:28:05 +0000
commit4c76b275907cf2d764f3fc51468d1c58635a10c1 (patch)
tree201a353c2b64b258760c370e641821ec5f6eff85 /source/slang
parent6b286bfbdf85e40cac1ee325384f535df969938a (diff)
Cleanups related to RIFF support (#7041)
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-compiler.h14
-rw-r--r--source/slang/slang-emit-cuda.cpp3
-rw-r--r--source/slang/slang-emit-glsl.cpp7
-rw-r--r--source/slang/slang-ir-insts.h25
-rw-r--r--source/slang/slang-module-library.cpp32
-rw-r--r--source/slang/slang-repro.cpp99
-rw-r--r--source/slang/slang-repro.h13
-rw-r--r--source/slang/slang-serialize-ast.cpp43
-rw-r--r--source/slang/slang-serialize-ast.h2
-rw-r--r--source/slang/slang-serialize-container.cpp284
-rw-r--r--source/slang/slang-serialize-container.h181
-rw-r--r--source/slang/slang-serialize-ir-types.h12
-rw-r--r--source/slang/slang-serialize-ir.cpp42
-rw-r--r--source/slang/slang-serialize-ir.h7
-rw-r--r--source/slang/slang-serialize-source-loc.cpp25
-rw-r--r--source/slang/slang-serialize-source-loc.h14
-rw-r--r--source/slang/slang-serialize-types.cpp25
-rw-r--r--source/slang/slang-serialize-types.h78
-rw-r--r--source/slang/slang-serialize.h154
-rw-r--r--source/slang/slang-type-layout.cpp2
-rw-r--r--source/slang/slang.cpp185
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);
}
}
}