summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-serialize-container.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-serialize-container.cpp')
-rw-r--r--source/slang/slang-serialize-container.cpp98
1 files changed, 96 insertions, 2 deletions
diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp
index 7dd2c15a1..8c4edb9a0 100644
--- a/source/slang/slang-serialize-container.cpp
+++ b/source/slang/slang-serialize-container.cpp
@@ -12,6 +12,8 @@
#include "slang-serialize-source-loc.h"
#include "slang-serialize-factory.h"
+#include "slang-mangled-lexer.h"
+
namespace Slang {
/* static */SlangResult SerialContainerUtil::requestToData(EndToEndCompileRequest* request, const WriteOptions& options, SerialContainerData& out)
@@ -142,6 +144,9 @@ namespace Slang {
{
if (ModuleDecl* moduleDecl = as<ModuleDecl>(module.astRootNode))
{
+ // Put in AST module
+ RiffContainer::ScopeChunk scopeASTModule(container, RiffContainer::Chunk::Kind::List, ASTSerialBinary::kSlangASTModuleFourCC);
+
if (!serialClasses)
{
SLANG_RETURN_ON_FAIL(SerialClassesUtil::create(serialClasses));
@@ -155,8 +160,9 @@ namespace Slang {
// Add the module and everything that isn't filtered out in the filter.
writer.addPointer(moduleDecl);
+
// We can now serialize it into the riff container.
- SLANG_RETURN_ON_FAIL(writer.writeIntoContainer(ASTSerialBinary::kSlangASTModuleFourCC, container));
+ SLANG_RETURN_ON_FAIL(writer.writeIntoContainer(ASTSerialBinary::kSlangASTModuleDataFourCC, container));
}
}
}
@@ -312,9 +318,97 @@ namespace Slang {
SerialReader reader(serialClasses, &objectFactory);
+ // Sets up the entry table - one entry for each 'object'.
+ // No native objects are constructed. No objects are deserialized.
+ SLANG_RETURN_ON_FAIL(reader.loadEntries((const uint8_t*)astData->getPayload(), astData->getSize()));
+
+ // Construct a native object for each table entry (where appropriate).
+ // Note that this *doesn't* set all object pointers - some are special cased and created on demand (strings)
+ // and imported symbols will have their object pointers unset (they are resolved in next step)
+ SLANG_RETURN_ON_FAIL(reader.constructObjects(options.namePool));
+
+ // Resolve external references if the linkage is specified
+ if (options.linkage)
+ {
+ const auto& entries = reader.getEntries();
+ auto& objects = reader.getObjects();
+ const Index entriesCount = entries.getCount();
+
+ String currentModuleName;
+ Module* currentModule = nullptr;
+
+ // Index from 1 (0 is null)
+ for (Index i = 1; i < entriesCount; ++i)
+ {
+ const SerialInfo::Entry* entry = entries[i];
+ if (entry->typeKind == SerialTypeKind::ImportSymbol)
+ {
+ UnownedStringSlice mangledName = reader.getStringSlice(SerialIndex(i));
+
+ UnownedStringSlice moduleName;
+ SLANG_RETURN_ON_FAIL(MangledNameParser::parseModuleName(mangledName, moduleName));
+
+ // If we already have looked up this module and it has the same name just use what we have
+ Module* readModule = nullptr;
+ if (currentModule && moduleName == currentModuleName.getUnownedSlice())
+ {
+ readModule = currentModule;
+ }
+ else
+ {
+ // The modules are loaded on the linkage.
+ Linkage* linkage = options.linkage;
+
+ NamePool* namePool = linkage->getNamePool();
+ Name* moduleNameName = namePool->getName(moduleName);
+
+ readModule = linkage->findOrImportModule(moduleNameName, SourceLoc::fromRaw(0), options.sink);
+ if (!readModule)
+ {
+ return SLANG_FAIL;
+ }
+
+ // Set the current module and name
+ currentModule = readModule;
+ currentModuleName = moduleName;
+ }
+
+ // Look up the symbol
+ NodeBase* nodeBase = readModule->findExportFromMangledName(mangledName);
+
+ if (!nodeBase)
+ {
+ if (options.sink)
+ {
+ options.sink->diagnose(SourceLoc::fromRaw(0), Diagnostics::unableToFindSymbolInModule, mangledName, moduleName);
+ }
+
+ // If didn't find the export then we are done
+ return SLANG_FAIL;
+ }
+
+ // set the result
+ objects[i] = nodeBase;
+ }
+ }
+ }
+
+ // Set the sourceLocReader before doing de-serialize, such can lookup the remapped sourceLocs
reader.getExtraObjects().set(sourceLocReader);
- SLANG_RETURN_ON_FAIL(reader.load((const uint8_t*)astData->getPayload(), astData->getSize(), options.namePool));
+ // TODO(JS):
+ // If modules can have more complicated relationships (like a two modules can refer to symbols
+ // from each other), then we can make this work by
+ // 1) deserialize *without* the external symbols being set up
+ // 2) calculate the symbols
+ // 3) deserialize the other module (in the same way)
+ // 4) run deserializeObjects *again* on each module
+ // This is less efficient than it might be (because deserialize phase is done twice) so if this is necessary
+ // may want a mechanism that *just* does reference lookups.
+ //
+ // For now if we assume a module can only access symbols from another module, and not the reverse.
+ // So we just need to deserialize and we are done
+ SLANG_RETURN_ON_FAIL(reader.deserializeObjects());
// Get the root node. It's at index 1 (0 is the null value).
astRootNode = reader.getPointer(SerialIndex(1)).dynamicCast<NodeBase>();