diff options
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/slang-compiler.cpp | 175 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 7 | ||||
| -rw-r--r-- | source/slang/slang-ir-obfuscate-loc.cpp | 28 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 24 |
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; } |
