diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/compiler-core/slang-source-loc.cpp | 100 | ||||
| -rw-r--r-- | source/compiler-core/slang-source-loc.h | 20 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 30 | ||||
| -rw-r--r-- | source/slang/slang-emit-source-writer.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-obfuscate-loc.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 102 |
6 files changed, 228 insertions, 30 deletions
diff --git a/source/compiler-core/slang-source-loc.cpp b/source/compiler-core/slang-source-loc.cpp index 8710cf91f..f9014e0d8 100644 --- a/source/compiler-core/slang-source-loc.cpp +++ b/source/compiler-core/slang-source-loc.cpp @@ -190,12 +190,41 @@ void SourceView::addDefaultLineDirective(SourceLoc directiveLoc) m_entries.add(entry); } -SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView* sourceView, SourceLoc loc, HandleSourceLoc& outLoc) +// Nominal-like types take into account line directives, and potentially source maps +static bool _isNominalLike(SourceLocType type) +{ + return type == SourceLocType::Nominal || type == SourceLocType::Emit; +} + +static bool _canFollowSourceMap(SourceFile* sourceFile, SourceLocType type) +{ + // If we don't have a source map we have nothing to follow + if (!sourceFile->getSourceMap()) + { + return false; + } + + // If it's obfuscated we can't follow if we are emitting + if (sourceFile->getSourceMapKind() == SourceMapKind::Obfuscated && + type == SourceLocType::Emit) + { + return false; + } + + return _isNominalLike(type); +} + +static SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView* sourceView, SourceLoc loc, SourceLocType type, HandleSourceLoc& outLoc) { auto sourceFile = sourceView->getSourceFile(); + if (!_canFollowSourceMap(sourceFile, type)) + { + return SLANG_E_NOT_FOUND; + } + // Hold a list of sourceFiles visited so we can't end up in a loop of lookups - List<SourceFile*> sourceFiles; + ShortList<SourceFile*, 8> sourceFiles; sourceFiles.add(sourceFile); Index entryIndex = -1; @@ -240,8 +269,10 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView sourceFiles.add(foundSourceFile); // If it has a source map, we try and look up the current location in it's source map - if (auto foundSourceMap = foundSourceFile->getSourceMap()) + if (_canFollowSourceMap(foundSourceFile, type)) { + auto foundSourceMap = foundSourceFile->getSourceMap(); + const auto foundEntryIndex = foundSourceMap->get().findEntry(entry.sourceLine, entry.sourceColumn); // If we found the entry repeat the lookup @@ -273,18 +304,30 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView return SLANG_OK; } -HandleSourceLoc SourceView::getHandleLoc(SourceLoc loc, SourceLocType type) + +SlangResult SourceView::_findSourceMapLoc(SourceLoc loc, SourceLocType type, HandleSourceLoc& outLoc) { - // If it's nominal - if (type == SourceLocType::Nominal && m_sourceFile->getSourceMap()) + // We only do source map lookups with nominal + if (!_isNominalLike(type)) { - // TODO(JS): - // Ideally we'd do the lookup on the "current" source manager rather than the source manager on this - // view, which may be a parent to the current one. - auto lookupSourceManager = m_sourceFile->getSourceManager(); + return SLANG_E_NOT_FOUND; + } - HandleSourceLoc handleLoc; - if (SLANG_SUCCEEDED(_findLocWithSourceMap(lookupSourceManager, this, loc, handleLoc))) + // TODO(JS): + // Ideally we'd do the lookup on the "current" source manager rather than the source manager on this + // view, which may be a parent to the current one. + auto lookupSourceManager = m_sourceFile->getSourceManager(); + + HandleSourceLoc handleLoc; + SLANG_RETURN_ON_FAIL(_findLocWithSourceMap(lookupSourceManager, this, loc, type, outLoc)); + + return SLANG_OK; +} + +HandleSourceLoc SourceView::getHandleLoc(SourceLoc loc, SourceLocType type) +{ + { HandleSourceLoc handleLoc; + if (SLANG_SUCCEEDED(_findSourceMapLoc(loc, type, handleLoc))) { return handleLoc; } @@ -307,22 +350,21 @@ HandleSourceLoc SourceView::getHandleLoc(SourceLoc loc, SourceLocType type) HandleSourceLoc handleLoc; handleLoc.column = columnIndex + 1; handleLoc.line = lineIndex + 1; - - // Make up a default entry - StringSlicePool::Handle pathHandle = StringSlicePool::Handle(0); - - // Only bother looking up the entry information if we want a 'Normal' lookup - const int entryIndex = (type == SourceLocType::Nominal) ? findEntryIndex(loc) : -1; - if (entryIndex >= 0) + + // Only bother looking up the entry information if we want a 'Norminal'-like lookup + if (_isNominalLike(type)) { - const Entry& entry = m_entries[entryIndex]; - // Adjust the line - handleLoc.line += entry.m_lineAdjust; - // Get the pathHandle.. - pathHandle = entry.m_pathHandle; + const int entryIndex = findEntryIndex(loc); + if (entryIndex >= 0) + { + const Entry& entry = m_entries[entryIndex]; + // Adjust the line + handleLoc.line += entry.m_lineAdjust; + // Get the pathHandle.. + handleLoc.pathHandle = entry.m_pathHandle; + } } - handleLoc.pathHandle = pathHandle; return handleLoc; } @@ -371,6 +413,14 @@ PathInfo SourceView::getPathInfo(SourceLoc loc, SourceLocType type) return getViewPathInfo(); } + { + HandleSourceLoc handleLoc; + if (SLANG_SUCCEEDED(_findSourceMapLoc(loc, type, handleLoc))) + { + return _getPathInfoFromHandle(handleLoc.pathHandle); + } + } + const int entryIndex = findEntryIndex(loc); return _getPathInfoFromHandle((entryIndex >= 0) ? m_entries[entryIndex].m_pathHandle : StringSlicePool::Handle(0)); } diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h index fafff7de6..5c78c4293 100644 --- a/source/compiler-core/slang-source-loc.h +++ b/source/compiler-core/slang-source-loc.h @@ -164,6 +164,16 @@ struct SourceRange SourceLoc end; }; +/// Source maps associated with files are could be of different uses. We use the SourceMapKind +/// to indicate the usage. +/// +/// If the source map is obfuscated reasonable/desirable to ignore them on emit (if we didn't we leak information, +/// and we don't emit into the locations in the obfuscated intermediate "file"). +enum class SourceMapKind +{ + Normal, ///< A regular source map + Obfuscated, ///< Obfuscated source map +}; // Pre-declare struct SourceManager; @@ -256,8 +266,11 @@ public: /// Get the source map associated with this file. If it's set when doing /// lookup for source locations, the source map will be used IBoxValue<SourceMap>* getSourceMap() const { return m_sourceMap; } + /// Get the source map kind + SourceMapKind getSourceMapKind() const { return m_sourceMapKind; } + /// Set a source map - void setSourceMap(IBoxValue<SourceMap>* sourceMap) { m_sourceMap = sourceMap; } + void setSourceMap(IBoxValue<SourceMap>* sourceMap, SourceMapKind sourceMapKind) { m_sourceMap = sourceMap; m_sourceMapKind = sourceMapKind; } /// Ctor SourceFile(SourceManager* sourceManager, const PathInfo& pathInfo, size_t contentSize); @@ -281,12 +294,15 @@ public: // If set then the locations in this file are really from locations from elsewhere, // where the SourceMap specifies that mapping ComPtr<IBoxValue<SourceMap>> m_sourceMap; + // What kind of source map it is (if there is one) + SourceMapKind m_sourceMapKind = SourceMapKind::Normal; }; enum class SourceLocType { Nominal, ///< The normal interpretation which takes into account #line directives and source maps Actual, ///< Ignores #line directives/source maps - and is the location as seen in the actual file + Emit, ///< Behaves the same as `Nominal` but ignores source maps. Used for Emit source locations. }; // A source location in a format a human might like to see @@ -395,6 +411,8 @@ class SourceView /// Get the pathInfo from a string handle. If it's 0, it will return the _getPathInfo PathInfo _getPathInfoFromHandle(StringSlicePool::Handle pathHandle) const; + SlangResult _findSourceMapLoc(SourceLoc loc, SourceLocType type, HandleSourceLoc& outLoc); + String m_viewPath; ///< Path to this view. If empty the path is the path to the SourceView SourceLoc m_initiatingSourceLoc; ///< An optional source loc that defines where this view was initiated from. SourceLoc(0) if not defined. diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index ca16bfb94..7d73599ba 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -297,6 +297,12 @@ namespace Slang SlangInt targetIndex, slang::IBlob** outCode, slang::IBlob** outDiagnostics) SLANG_OVERRIDE; + + SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE; + SLANG_NO_THROW SlangResult SLANG_MCALL specialize( slang::SpecializationArg const* specializationArgs, SlangInt specializationArgCount, @@ -851,6 +857,14 @@ namespace Slang return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); } + SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE + { + return Super::getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + } + SLANG_NO_THROW SlangResult SLANG_MCALL specialize( slang::SpecializationArg const* specializationArgs, SlangInt specializationArgCount, @@ -1067,6 +1081,14 @@ namespace Slang return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); } + SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE + { + return Super::getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + } + SLANG_NO_THROW SlangResult SLANG_MCALL specialize( slang::SpecializationArg const* specializationArgs, SlangInt specializationArgCount, @@ -1221,6 +1243,14 @@ namespace Slang return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics); } + SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem( + SlangInt entryPointIndex, + SlangInt targetIndex, + ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE + { + return Super::getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem); + } + SLANG_NO_THROW SlangResult SLANG_MCALL specialize( slang::SpecializationArg const* specializationArgs, SlangInt specializationArgCount, diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp index 72696c94a..4ff547119 100644 --- a/source/slang/slang-emit-source-writer.cpp +++ b/source/slang/slang-emit-source-writer.cpp @@ -311,7 +311,7 @@ void SourceWriter::advanceToSourceLocation(const SourceLoc& sourceLocation) } // Workout the humane source location. - const HumaneSourceLoc humaneSourceLoc = getSourceManager()->getHumaneLoc(sourceLocation); + const HumaneSourceLoc humaneSourceLoc = getSourceManager()->getHumaneLoc(sourceLocation, SourceLocType::Emit); // If the location is valid, mark need to update, and the new location if (humaneSourceLoc.line > 0) diff --git a/source/slang/slang-ir-obfuscate-loc.cpp b/source/slang/slang-ir-obfuscate-loc.cpp index ecc16d2b2..860633106 100644 --- a/source/slang/slang-ir-obfuscate-loc.cpp +++ b/source/slang/slang-ir-obfuscate-loc.cpp @@ -362,8 +362,8 @@ SlangResult obfuscateModuleLocs(IRModule* module, SourceManager* sourceManager) sourceMap->addEntry(entries[i]); } - // Associate the sourceMap with the obfuscated file - obfuscatedFile->setSourceMap(boxedSourceMap); + // Associate the sourceMap with the obfuscated file. + obfuscatedFile->setSourceMap(boxedSourceMap, SourceMapKind::Obfuscated); // Set the obfuscated map onto the module module->setObfuscatedSourceMap(boxedSourceMap); diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 760a119d1..e08bb2a62 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -3464,6 +3464,106 @@ SLANG_NO_THROW slang::ProgramLayout* SLANG_MCALL ComponentType::getLayout( return asExternal(programLayout); } +static ICastable* _findDiagnosticRepresentation(IArtifact* artifact) +{ + if (auto rep = findAssociatedRepresentation<IArtifactDiagnostics>(artifact)) + { + return rep; + } + + for (auto associated : artifact->getAssociated()) + { + if (isDerivedFrom(associated->getDesc().payload, ArtifactPayload::Diagnostics)) + { + return associated; + } + } + return nullptr; +} + +static IArtifact* _findObfuscatedSourceMap(IArtifact* artifact) +{ + // If we find any obfuscated source maps, we are done + for (auto associated : artifact->getAssociated()) + { + const auto desc = associated->getDesc(); + + if (isDerivedFrom(desc.payload, ArtifactPayload::SourceMap) && + isDerivedFrom(desc.style, ArtifactStyle::Obfuscated)) + { + return associated; + } + } + return nullptr; +} + +SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getResultAsFileSystem( + SlangInt entryPointIndex, + Int targetIndex, + ISlangMutableFileSystem** outFileSystem) +{ + ComPtr<ISlangBlob> diagnostics; + ComPtr<ISlangBlob> code; + + SLANG_RETURN_ON_FAIL(getEntryPointCode(entryPointIndex, targetIndex, diagnostics.writeRef(), code.writeRef())); + + auto linkage = getLinkage(); + + auto target = linkage->targets[targetIndex]; + + auto targetProgram = getTargetProgram(target); + + IArtifact* artifact = targetProgram->getExistingEntryPointResult(entryPointIndex); + + // Add diagnostics id needs be... + if (diagnostics && !_findDiagnosticRepresentation(artifact)) + { + // Add as an associated + + auto diagnosticsArtifact = Artifact::create(ArtifactDesc::make(Artifact::Kind::HumanText, ArtifactPayload::Diagnostics)); + diagnosticsArtifact->addRepresentationUnknown(diagnostics); + + artifact->addAssociated(diagnosticsArtifact); + + SLANG_ASSERT(diagnosticsArtifact == _findDiagnosticRepresentation(artifact)); + } + + // Add obfuscated source maps + if (!_findObfuscatedSourceMap(artifact)) + { + List<IRModule*> irModules; + enumerateIRModules([&](IRModule* irModule) -> void { irModules.add(irModule); }); + + for (auto irModule : irModules) + { + if (auto obfuscatedSourceMap = irModule->getObfuscatedSourceMap()) + { + auto artifactDesc = ArtifactDesc::make(ArtifactKind::Json, ArtifactPayload::SourceMap, ArtifactStyle::Obfuscated); + + // Create the source map artifact + auto sourceMapArtifact = Artifact::create(artifactDesc, obfuscatedSourceMap->get().m_file.getUnownedSlice()); + + sourceMapArtifact->addRepresentation(obfuscatedSourceMap); + + // associate with the artifact + artifact->addAssociated(sourceMapArtifact); + } + } + } + + // Turn into a file system and return + ComPtr<ISlangMutableFileSystem> fileSystem(new MemoryFileSystem); + + // Filter the containerArtifact into things that can be written + ComPtr<IArtifact> writeArtifact; + SLANG_RETURN_ON_FAIL(ArtifactContainerUtil::filter(artifact, writeArtifact)); + SLANG_RETURN_ON_FAIL(ArtifactContainerUtil::writeContainer(writeArtifact, "", fileSystem)); + + *outFileSystem = fileSystem.detach(); + + return SLANG_OK; +} + SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointCode( SlangInt entryPointIndex, Int targetIndex, @@ -4983,7 +5083,7 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac if (name.getLength()) { auto sourceFile = sourceManager->findSourceFileByPathRecursively(name); - sourceFile->setSourceMap(sourceMap); + sourceFile->setSourceMap(sourceMap, SourceMapKind::Obfuscated); } } } |
