summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-compiler.cpp175
-rwxr-xr-xsource/slang/slang-compiler.h7
-rw-r--r--source/slang/slang-ir-obfuscate-loc.cpp28
-rw-r--r--source/slang/slang.cpp24
4 files changed, 202 insertions, 32 deletions
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index f2ebefb9d..8cbe12ef0 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -1844,46 +1844,185 @@ namespace Slang
return SLANG_OK;
}
- SlangResult EndToEndCompileRequest::maybeCreateContainer()
+ SlangResult EndToEndCompileRequest::_createContainer()
{
switch (m_containerFormat)
{
- case ContainerFormat::SlangModule:
+ case ContainerFormat::SlangModule:
+ {
+
+ OwnedMemoryStream stream(FileAccess::Write);
+ SlangResult res = writeContainerToStream(&stream);
+ if (SLANG_FAILED(res))
{
- m_containerBlob.setNull();
+ getSink()->diagnose(SourceLoc(), Diagnostics::unableToCreateModuleContainer);
+ return res;
+ }
+
+ // Need to turn into a blob
+ List<uint8_t> blobData;
+ stream.swapContents(blobData);
+
+ auto containerBlob = ListBlob::moveCreate(blobData);
+
+ m_containerArtifact = Artifact::create(ArtifactDesc::make(Artifact::Kind::CompileBinary, ArtifactPayload::SlangIR, ArtifactStyle::Unknown));
+
+ m_containerArtifact->addRepresentationUnknown(containerBlob);
+
+ return res;
+ }
+ default: break;
+ }
+ return SLANG_OK;
+ }
+
+ SlangResult EndToEndCompileRequest::_completeContainer()
+ {
+ SLANG_ASSERT(m_containerArtifact);
+ if (!m_containerArtifact)
+ {
+ return SLANG_FAIL;
+ }
+
+ auto frontEndReq = getFrontEndReq();
- OwnedMemoryStream stream(FileAccess::Write);
- SlangResult res = writeContainerToStream(&stream);
- if (SLANG_FAILED(res))
+ auto sourceManager = frontEndReq->getSourceManager();
+ auto sink = getSink();
+
+ for (auto translationUnit : frontEndReq->translationUnits)
+ {
+ // Hmmm do I have to therefore add a map for all translation units(!)
+ // I guess this is okay in so far as an association can always be looked up by name
+
+ auto sourceMap = translationUnit->getModule()->getIRModule()->getObfuscatedSourceMap();
+
+ if (sourceMap)
+ {
+ // Write it out
+ String json;
{
- getSink()->diagnose(SourceLoc(), Diagnostics::unableToCreateModuleContainer);
- return res;
+ RefPtr<JSONContainer> jsonContainer(new JSONContainer(sourceManager));
+
+ JSONValue jsonValue;
+
+ SLANG_RETURN_ON_FAIL(sourceMap->encode(jsonContainer, sink, jsonValue));
+
+ // Convert into a string
+ JSONWriter writer(JSONWriter::IndentationStyle::Allman);
+ jsonContainer->traverseRecursively(jsonValue, &writer);
+
+ json = writer.getBuilder();
}
- // Need to turn into a blob
- List<uint8_t> blobData;
- stream.swapContents(blobData);
+ auto jsonSourceMapBlob = StringBlob::moveCreate(json);
- m_containerBlob = ListBlob::moveCreate(blobData);
+ auto artifactDesc = ArtifactDesc::make(ArtifactKind::Json, ArtifactPayload::SourceMap, ArtifactStyle::Obfuscated);
- return res;
+ // Create the source map artifact
+ auto sourceMapArtifact = Artifact::create(artifactDesc, sourceMap->m_file.getUnownedSlice());
+ sourceMapArtifact->addRepresentationUnknown(jsonSourceMapBlob);
+
+ // Associate with the container
+ m_containerArtifact->addAssociated(sourceMapArtifact);
}
- default: break;
}
+
+ return SLANG_OK;
+ }
+
+ SlangResult EndToEndCompileRequest::maybeCreateContainer()
+ {
+ m_containerArtifact.setNull();
+
+ if (m_containerFormat == ContainerFormat::None)
+ {
+ return SLANG_OK;
+ }
+
+ // Create the container
+ SLANG_RETURN_ON_FAIL(_createContainer());
+
+ // Associate any other stuff with the container artifact
+ SLANG_RETURN_ON_FAIL(_completeContainer());
+
return SLANG_OK;
}
SlangResult EndToEndCompileRequest::maybeWriteContainer(const String& fileName)
{
// If there is no container, or filename, don't write anything
- if (fileName.getLength() == 0 || !m_containerBlob)
+ if (fileName.getLength() == 0 || !m_containerArtifact)
{
return SLANG_OK;
}
- FileStream stream;
- SLANG_RETURN_ON_FAIL(stream.init(fileName, FileMode::Create, FileAccess::Write, FileShare::ReadWrite));
- SLANG_RETURN_ON_FAIL(stream.write(m_containerBlob->getBufferPointer(), m_containerBlob->getBufferSize()));
+ ComPtr<ISlangBlob> containerBlob;
+ SLANG_RETURN_ON_FAIL(m_containerArtifact->loadBlob(ArtifactKeep::Yes, containerBlob.writeRef()));
+
+ {
+ FileStream stream;
+ SLANG_RETURN_ON_FAIL(stream.init(fileName, FileMode::Create, FileAccess::Write, FileShare::ReadWrite));
+ SLANG_RETURN_ON_FAIL(stream.write(containerBlob->getBufferPointer(), containerBlob->getBufferSize()));
+ }
+
+ auto parentPath = Path::getParentDirectory(fileName);
+
+ // Lets look to see if we have any maps
+ {
+ Index nameCount = 0;
+
+ auto associated = m_containerArtifact->getAssociated();
+ const Count count = associated->getCount();
+ for (Index i = 0; i < count; ++i)
+ {
+ IArtifact* artifact = as<IArtifact>(associated->getAt(i));
+ auto desc = artifact->getDesc();
+
+ if (isDerivedFrom(desc.payload, ArtifactPayload::SourceMap))
+ {
+ StringBuilder artifactFilename;
+
+ // Dump out
+ const char* artifactName = artifact->getName();
+ if (artifactName && artifactName[0] != 0)
+ {
+ SLANG_RETURN_ON_FAIL(ArtifactUtil::calcName(artifact, UnownedStringSlice(artifactName), artifactFilename));
+ }
+ else
+ {
+ // Perhaps we can generate the name from the output basename
+ StringBuilder baseName;
+
+ baseName << Path::getFileNameWithoutExt(m_containerOutputPath);
+
+ if (nameCount != 0)
+ {
+ baseName.appendChar('-');
+ baseName.append(nameCount);
+ }
+
+ SLANG_RETURN_ON_FAIL(ArtifactUtil::calcName(artifact, baseName.getUnownedSlice(), artifactFilename));
+
+ nameCount ++;
+ }
+
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()));
+
+ // Try to write it out
+ {
+ // Work out the path to the artifact
+ auto artifactPath = Path::combine(parentPath, artifactFilename);
+
+ // Write out the map
+ FileStream stream;
+ SLANG_RETURN_ON_FAIL(stream.init(artifactPath, FileMode::Create, FileAccess::Write, FileShare::ReadWrite));
+ SLANG_RETURN_ON_FAIL(stream.write(blob->getBufferPointer(), blob->getBufferSize()));
+ }
+ }
+ }
+ }
+
return SLANG_OK;
}
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index fcf62d826..b287b21eb 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -2625,9 +2625,9 @@ namespace Slang
// If it's set to a format, the container blob will be calculated during compile
ContainerFormat m_containerFormat = ContainerFormat::None;
- /// Where the container blob is stored. This is calculated as part of compile if m_containerFormat is set to
+ /// Where the container is stored. This is calculated as part of compile if m_containerFormat is set to
/// a supported format.
- ComPtr<ISlangBlob> m_containerBlob;
+ ComPtr<IArtifact> m_containerArtifact;
// Path to output container to
String m_containerOutputPath;
@@ -2775,6 +2775,9 @@ namespace Slang
void init();
+ SlangResult _createContainer();
+ SlangResult _completeContainer();
+
Session* m_session = nullptr;
RefPtr<Linkage> m_linkage;
DiagnosticSink m_sink;
diff --git a/source/slang/slang-ir-obfuscate-loc.cpp b/source/slang/slang-ir-obfuscate-loc.cpp
index b3f5d5cd3..79e855633 100644
--- a/source/slang/slang-ir-obfuscate-loc.cpp
+++ b/source/slang/slang-ir-obfuscate-loc.cpp
@@ -72,13 +72,14 @@ SlangResult obfuscateModuleLocs(IRModule* module, SourceManager* sourceManager)
List<LocPair> locPairs;
+ // We want the hash to be stable. One problem is the source locs depend on their order of inclusion.
+ // To work around this we are going
{
+ SourceView* sourceView = nullptr;
+
SourceLoc curLoc;
for (const auto& instWithLoc : instWithLocs)
{
- hash = combineHash(hash, getHashCode(instWithLoc.inst));
- hash = combineHash(hash, getHashCode(instWithLoc.loc.getRaw()));
-
if (instWithLoc.loc != curLoc)
{
LocPair locPair;
@@ -87,6 +88,21 @@ SlangResult obfuscateModuleLocs(IRModule* module, SourceManager* sourceManager)
// This is the current loc
curLoc = instWithLoc.loc;
+
+ // If the loc isn't in the view, lookup the view it is in
+ if (sourceView == nullptr ||
+ !sourceView->getRange().contains(curLoc))
+ {
+ sourceView = sourceManager->findSourceViewRecursively(curLoc);
+ SLANG_ASSERT(sourceView);
+
+ // Combine the name
+ hash = combineHash(hash, getHashCode(sourceView->getViewPathInfo().getName().getUnownedSlice()));
+ }
+ SLANG_ASSERT(sourceView);
+
+ // We combine the *offset* which is stable
+ hash = combineHash(hash, getHashCode(sourceView->getRange().getOffset(curLoc)));
}
}
}
@@ -128,6 +144,12 @@ SlangResult obfuscateModuleLocs(IRModule* module, SourceManager* sourceManager)
SourceFile* obfuscatedFile = sourceManager->createSourceFileWithSize(obfusctatedPathInfo, uniqueLocCount);
+ // We have only one line for all locs, just set up that way...
+ {
+ const uint32_t offsets[2] = { 0, uint32_t(uniqueLocCount) };
+ obfuscatedFile->setLineBreakOffsets(offsets, SLANG_COUNT_OF(offsets));
+ }
+
// Create the view we are going to use from the obfusctated "file".
SourceView* obfuscatedView = sourceManager->createSourceView(obfuscatedFile, nullptr, SourceLoc());
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index bd19670d9..79f9e56ba 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -2647,6 +2647,7 @@ SlangResult EndToEndCompileRequest::executeActionsInner()
m_specializedEntryPoints = getFrontEndReq()->getUnspecializedEntryPoints();
SLANG_RETURN_ON_FAIL(maybeCreateContainer());
+
SLANG_RETURN_ON_FAIL(maybeWriteContainer(m_containerOutputPath));
return SLANG_OK;
@@ -5231,10 +5232,14 @@ char const* EndToEndCompileRequest::getEntryPointSource(int entryPointIndex)
void const* EndToEndCompileRequest::getCompileRequestCode(size_t* outSize)
{
- if (m_containerBlob)
+ if (m_containerArtifact)
{
- *outSize = m_containerBlob->getBufferSize();
- return m_containerBlob->getBufferPointer();
+ ComPtr<ISlangBlob> containerBlob;
+ if (SLANG_SUCCEEDED(m_containerArtifact->loadBlob(ArtifactKeep::Yes, containerBlob.writeRef())))
+ {
+ *outSize = containerBlob->getBufferSize();
+ return containerBlob->getBufferPointer();
+ }
}
// Container blob does not have any contents
@@ -5244,14 +5249,15 @@ void const* EndToEndCompileRequest::getCompileRequestCode(size_t* outSize)
SlangResult EndToEndCompileRequest::getContainerCode(ISlangBlob** outBlob)
{
- ISlangBlob* containerBlob = m_containerBlob;
- if (containerBlob)
+ if (m_containerArtifact)
{
- containerBlob->addRef();
- *outBlob = containerBlob;
- return SLANG_OK;
+ ComPtr<ISlangBlob> containerBlob;
+ if (SLANG_SUCCEEDED(m_containerArtifact->loadBlob(ArtifactKeep::Yes, containerBlob.writeRef())))
+ {
+ *outBlob = containerBlob.detach();
+ return SLANG_OK;
+ }
}
-
return SLANG_FAIL;
}