diff options
25 files changed, 246 insertions, 155 deletions
diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp index 1a8e8374d..5d2a74036 100644 --- a/source/compiler-core/slang-artifact-handler-impl.cpp +++ b/source/compiler-core/slang-artifact-handler-impl.cpp @@ -130,7 +130,7 @@ SlangResult DefaultArtifactHandler::expandChildren(IArtifact* container) return SLANG_OK; } -static SlangResult _loadSourceMap(IArtifact* artifact, ArtifactKeep intermediateKeep, RefPtr<SourceMap>& outSourceMap) +static SlangResult _loadSourceMap(IArtifact* artifact, ArtifactKeep intermediateKeep, SourceMap& outSourceMap) { const auto desc = artifact->getDesc(); if (isDerivedFrom(desc.kind, ArtifactKind::Json) && @@ -139,10 +139,7 @@ static SlangResult _loadSourceMap(IArtifact* artifact, ArtifactKeep intermediate ComPtr<ISlangBlob> blob; SLANG_RETURN_ON_FAIL(artifact->loadBlob(intermediateKeep, blob.writeRef())); - RefPtr<SourceMap> sourceMap; - SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::read(blob, sourceMap)); - - outSourceMap = sourceMap; + SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::read(blob, outSourceMap)); return SLANG_OK; } @@ -183,10 +180,9 @@ SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifac if (guid == SourceMap::getTypeGuid()) { // Blob -> SourceMap - RefPtr<SourceMap> sourceMap; - SLANG_RETURN_ON_FAIL(_loadSourceMap(artifact, getIntermediateKeep(keep), sourceMap)); - ComPtr<IObjectCastableAdapter> castable(new ObjectCastableAdapter(sourceMap)); - return _addRepresentation(artifact, keep, castable, outCastable); + ComPtr<IBoxValue<SourceMap>> sourceMap(new BoxValue<SourceMap>); + SLANG_RETURN_ON_FAIL(_loadSourceMap(artifact, getIntermediateKeep(keep), sourceMap->get())); + return _addRepresentation(artifact, keep, sourceMap, outCastable); } else if (guid == ISlangSharedLibrary::getTypeGuid()) { @@ -200,18 +196,17 @@ SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifac SLANG_RETURN_ON_FAIL(_createOSFile(artifact, getIntermediateKeep(keep), fileRep.writeRef())); return _addRepresentation(artifact, keep, fileRep, outCastable); } - else if (guid == ISlangBlob::getTypeGuid()) + + // Handle known conversion to blobs + if (guid == ISlangBlob::getTypeGuid()) { - for (ICastable* rep : reps) - { - if (SourceMap* sourceMap = as<SourceMap>(rep)) - { - // SourceMap -> Blob - ComPtr<ISlangBlob> blob; - SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::write(sourceMap, blob)); - // Add the rep - return _addRepresentation(artifact, keep, blob, outCastable); - } + if (auto sourceMap = findRepresentation<SourceMap>(artifact)) + { + // SourceMap -> Blob + ComPtr<ISlangBlob> blob; + SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::write(*sourceMap, blob)); + // Add the rep + return _addRepresentation(artifact, keep, blob, outCastable); } } diff --git a/source/compiler-core/slang-json-source-map-util.cpp b/source/compiler-core/slang-json-source-map-util.cpp index 4ef6ee3d6..193c812b7 100644 --- a/source/compiler-core/slang-json-source-map-util.cpp +++ b/source/compiler-core/slang-json-source-map-util.cpp @@ -172,9 +172,9 @@ void _encode(Index v, StringBuilder& out) out.append(dst, cur); } -/* static */SlangResult JSONSourceMapUtil::decode(JSONContainer* container, JSONValue root, DiagnosticSink* sink, RefPtr<SourceMap>& out) +/* static */SlangResult JSONSourceMapUtil::decode(JSONContainer* container, JSONValue root, DiagnosticSink* sink, SourceMap& outSourceMap) { - RefPtr<SourceMap> sourceMap(new SourceMap); + outSourceMap.clear(); // Let's try and decode the JSON into native types to make this easier... RttiTypeFuncsMap typeMap = JSONNativeUtil::getTypeFuncsMap(); @@ -188,23 +188,23 @@ void _encode(Index v, StringBuilder& out) SLANG_RETURN_ON_FAIL(converter.convert(root, GetRttiInfo<JSONSourceMap>::get(), &native)); } - sourceMap->m_file = native.file; - sourceMap->m_sourceRoot = native.sourceRoot; + outSourceMap.m_file = native.file; + outSourceMap.m_sourceRoot = native.sourceRoot; const Count sourcesCount = native.sources.getCount(); // These should all be unique, but for simplicity, we build a table - sourceMap->m_sources.setCount(sourcesCount); + outSourceMap.m_sources.setCount(sourcesCount); for (Index i = 0; i < sourcesCount; ++i) { - sourceMap->m_sources[i] = sourceMap->m_slicePool.add(native.sources[i]); + outSourceMap.m_sources[i] = outSourceMap.m_slicePool.add(native.sources[i]); } Count sourcesContentCount = native.sourcesContent.getCount(); sourcesContentCount = std::min(sourcesContentCount, sourcesCount); - sourceMap->m_sourcesContent.setCount(sourcesContentCount); - for (auto& cur : sourceMap->m_sourcesContent) + outSourceMap.m_sourcesContent.setCount(sourcesContentCount); + for (auto& cur : outSourceMap.m_sourcesContent) { cur = StringSlicePool::kNullHandle; } @@ -218,7 +218,7 @@ void _encode(Index v, StringBuilder& out) if (value.getKind() == JSONValue::Kind::String) { auto stringValue = container->getString(value); - sourceMap->m_sourcesContent[i] = sourceMap->m_slicePool.add(stringValue); + outSourceMap.m_sourcesContent[i] = outSourceMap.m_slicePool.add(stringValue); } } } @@ -237,13 +237,13 @@ void _encode(Index v, StringBuilder& out) const Count linesCount = lines.getCount(); - sourceMap->m_lineStarts.setCount(linesCount + 1); + outSourceMap.m_lineStarts.setCount(linesCount + 1); for (Index generatedLine = 0; generatedLine < linesCount; ++generatedLine) { const auto line = lines[generatedLine]; - sourceMap->m_lineStarts[generatedLine] = sourceMap->m_lineEntries.getCount(); + outSourceMap.m_lineStarts[generatedLine] = outSourceMap.m_lineEntries.getCount(); // If it's empty move to next line if (line.getLength() == 0) @@ -312,47 +312,45 @@ void _encode(Index v, StringBuilder& out) entry.sourceFileIndex = sourceFileIndex; entry.nameIndex = nameIndex; - sourceMap->m_lineEntries.add(entry); + outSourceMap.m_lineEntries.add(entry); } } // Mark the end - sourceMap->m_lineStarts[linesCount] = sourceMap->m_lineEntries.getCount(); - - out.swapWith(sourceMap); + outSourceMap.m_lineStarts[linesCount] = outSourceMap.m_lineEntries.getCount(); return SLANG_OK; } -SlangResult JSONSourceMapUtil::encode(SourceMap* sourceMap, JSONContainer* container, DiagnosticSink* sink, JSONValue& outValue) +SlangResult JSONSourceMapUtil::encode(const SourceMap& sourceMap, JSONContainer* container, DiagnosticSink* sink, JSONValue& outValue) { // Convert to native JSONSourceMap native; - native.file = sourceMap->m_file; - native.sourceRoot = sourceMap->m_sourceRoot; + native.file = sourceMap.m_file; + native.sourceRoot = sourceMap.m_sourceRoot; // Copy over the sources { - const auto count = sourceMap->m_sources.getCount(); + const auto count = sourceMap.m_sources.getCount(); native.sources.setCount(count); for (Index i = 0; i < count; ++i) { - native.sources[i] = sourceMap->m_slicePool.getSlice(sourceMap->m_sources[i]); + native.sources[i] = sourceMap.m_slicePool.getSlice(sourceMap.m_sources[i]); } } // Copy out the sourcesContent, care is needed around handling null { - const auto count = sourceMap->m_sourcesContent.getCount(); + const auto count = sourceMap.m_sourcesContent.getCount(); native.sourcesContent.setCount(count); for (Index i = 0; i < count; ++i) { - const auto srcValue = sourceMap->m_sourcesContent[i]; + const auto srcValue = sourceMap.m_sourcesContent[i]; const JSONValue dstValue = (srcValue == StringSlicePool::kNullHandle) ? native.sourcesContent[i] = JSONValue::makeNull() : - container->createString(sourceMap->m_slicePool.getSlice(srcValue)); + container->createString(sourceMap.m_slicePool.getSlice(srcValue)); native.sourcesContent[i] = dstValue; } @@ -360,11 +358,11 @@ SlangResult JSONSourceMapUtil::encode(SourceMap* sourceMap, JSONContainer* conta // Copy out the names { - const auto count = sourceMap->m_names.getCount(); + const auto count = sourceMap.m_names.getCount(); native.names.setCount(count); for (Index i = 0; i < count; ++i) { - native.names[i] = sourceMap->m_slicePool.getSlice(sourceMap->m_names[i]); + native.names[i] = sourceMap.m_slicePool.getSlice(sourceMap.m_names[i]); } } @@ -372,7 +370,7 @@ SlangResult JSONSourceMapUtil::encode(SourceMap* sourceMap, JSONContainer* conta // Do the encoding! { - const Count linesCount = sourceMap->getGeneratedLineCount(); + const Count linesCount = sourceMap.getGeneratedLineCount(); Index sourceFileIndex = 0; @@ -388,7 +386,7 @@ SlangResult JSONSourceMapUtil::encode(SourceMap* sourceMap, JSONContainer* conta mappings.appendChar(';'); } - const auto entries = sourceMap->getEntriesForLine(i); + const auto entries = sourceMap.getEntriesForLine(i); const auto entriesCount = entries.getCount(); if (entriesCount == 0) @@ -455,13 +453,15 @@ SlangResult JSONSourceMapUtil::encode(SourceMap* sourceMap, JSONContainer* conta return SLANG_OK; } -/* static */SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, RefPtr<SourceMap>& outSourceMap) +/* static */SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, SourceMap& outSourceMap) { return read(blob, nullptr, outSourceMap); } -SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, DiagnosticSink* parentSink, RefPtr<SourceMap>& outSourceMap) +SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, DiagnosticSink* parentSink, SourceMap& outSourceMap) { + outSourceMap.clear(); + SourceManager sourceManager; sourceManager.initialize(nullptr, nullptr); DiagnosticSink sink(&sourceManager, nullptr); @@ -487,16 +487,13 @@ SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, DiagnosticSink* parentSink rootValue = builder.getRootValue(); } - RefPtr<SourceMap> sourceMap; - - SLANG_RETURN_ON_FAIL(decode(container, rootValue, &sink, sourceMap)); + SLANG_RETURN_ON_FAIL(decode(container, rootValue, &sink, outSourceMap)); - outSourceMap = sourceMap; return SLANG_OK; } -/* static */SlangResult JSONSourceMapUtil::write(SourceMap* sourceMap, ComPtr<ISlangBlob>& outBlob) +/* static */SlangResult JSONSourceMapUtil::write(const SourceMap& sourceMap, ComPtr<ISlangBlob>& outBlob) { SourceManager sourceMapSourceManager; sourceMapSourceManager.initialize(nullptr, nullptr); @@ -508,7 +505,7 @@ SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, DiagnosticSink* parentSink return SLANG_OK; } -/* static */ SlangResult JSONSourceMapUtil::write(SourceMap* sourceMap, DiagnosticSink* sink, ComPtr<ISlangBlob>& outBlob) +/* static */ SlangResult JSONSourceMapUtil::write(const SourceMap& sourceMap, DiagnosticSink* sink, ComPtr<ISlangBlob>& outBlob) { auto sourceManager = sink->getSourceManager(); diff --git a/source/compiler-core/slang-json-source-map-util.h b/source/compiler-core/slang-json-source-map-util.h index 8d5071d4e..d61936ce4 100644 --- a/source/compiler-core/slang-json-source-map-util.h +++ b/source/compiler-core/slang-json-source-map-util.h @@ -10,20 +10,20 @@ namespace Slang { struct JSONSourceMapUtil { /// Decode from root into the source map - static SlangResult decode(JSONContainer* container, JSONValue root, DiagnosticSink* sink, RefPtr<SourceMap>& out); + static SlangResult decode(JSONContainer* container, JSONValue root, DiagnosticSink* sink, SourceMap& out); /// Converts the source map contents into JSON - static SlangResult encode(SourceMap* sourceMap, JSONContainer* container, DiagnosticSink* sink, JSONValue& outValue); + static SlangResult encode(const SourceMap& sourceMap, JSONContainer* container, DiagnosticSink* sink, JSONValue& outValue); /// Read the blob (encoded as JSON) as a source map. /// Sink is optional, and can be passed as nullptr - static SlangResult read(ISlangBlob* blob, DiagnosticSink* sink, RefPtr<SourceMap>& outSourceMap); - static SlangResult read(ISlangBlob* blob, RefPtr<SourceMap>& outSourceMap); + static SlangResult read(ISlangBlob* blob, DiagnosticSink* sink, SourceMap& outSourceMap); + static SlangResult read(ISlangBlob* blob, SourceMap& outSourceMap); /// Write source map to outBlob JSON - static SlangResult write(SourceMap* sourceMap, ComPtr<ISlangBlob>& outBlob); + static SlangResult write(const SourceMap& sourceMap, ComPtr<ISlangBlob>& outBlob); /// Write out the source map into a blob - static SlangResult write(SourceMap* sourceMap, DiagnosticSink* sink, ComPtr<ISlangBlob>& outBlob); + static SlangResult write(const SourceMap& sourceMap, DiagnosticSink* sink, ComPtr<ISlangBlob>& outBlob); }; } // namespace Slang diff --git a/source/compiler-core/slang-source-loc.cpp b/source/compiler-core/slang-source-loc.cpp index 23cbdf839..3d992ee8d 100644 --- a/source/compiler-core/slang-source-loc.cpp +++ b/source/compiler-core/slang-source-loc.cpp @@ -211,7 +211,7 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView auto sourceMap = sourceFile->getSourceMap(); SLANG_ASSERT(sourceMap); - entryIndex = sourceMap->findEntry(lineIndex, colIndex); + entryIndex = sourceMap->get().findEntry(lineIndex, colIndex); } if (entryIndex < 0) @@ -222,7 +222,7 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView // Keep searching through source maps do { - auto sourceMap = sourceFile->getSourceMap(); + auto sourceMap = sourceFile->getSourceMap()->getPtr(); // Find the entry const auto& entry = sourceMap->getEntryByIndex(entryIndex); @@ -242,7 +242,7 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView // If it has a source map, we try and look up the current location in it's source map if (auto foundSourceMap = foundSourceFile->getSourceMap()) { - const auto foundEntryIndex = foundSourceMap->findEntry(entry.sourceLine, entry.sourceColumn); + const auto foundEntryIndex = foundSourceMap->get().findEntry(entry.sourceLine, entry.sourceColumn); // If we found the entry repeat the lookup if (foundEntryIndex >= 0) @@ -258,7 +258,7 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView } while (false); // Generate the HandleSourceLoc - auto sourceMap = sourceFile->getSourceMap(); + auto sourceMap = sourceFile->getSourceMap()->getPtr(); const auto& entry = sourceMap->getEntryByIndex(entryIndex); // We need to add the pool of the originating source view/file diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h index 98b1bdbbd..fafff7de6 100644 --- a/source/compiler-core/slang-source-loc.h +++ b/source/compiler-core/slang-source-loc.h @@ -5,6 +5,7 @@ #include "../core/slang-basic.h" #include "../core/slang-memory-arena.h" #include "../core/slang-string-slice-pool.h" +#include "../core/slang-castable.h" #include "slang-source-map.h" @@ -254,9 +255,9 @@ 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 - SourceMap* getSourceMap() const { return m_sourceMap; } + IBoxValue<SourceMap>* getSourceMap() const { return m_sourceMap; } /// Set a source map - void setSourceMap(SourceMap* sourceMap) { m_sourceMap = sourceMap; } + void setSourceMap(IBoxValue<SourceMap>* sourceMap) { m_sourceMap = sourceMap; } /// Ctor SourceFile(SourceManager* sourceManager, const PathInfo& pathInfo, size_t contentSize); @@ -279,7 +280,7 @@ public: // If set then the locations in this file are really from locations from elsewhere, // where the SourceMap specifies that mapping - RefPtr<SourceMap> m_sourceMap; + ComPtr<IBoxValue<SourceMap>> m_sourceMap; }; enum class SourceLocType diff --git a/source/compiler-core/slang-source-map.cpp b/source/compiler-core/slang-source-map.cpp index 4ea50eb3f..7a6e368a4 100644 --- a/source/compiler-core/slang-source-map.cpp +++ b/source/compiler-core/slang-source-map.cpp @@ -4,7 +4,7 @@ namespace Slang { void SourceMap::clear() { - String empty; + const String empty; m_file = empty; m_sourceRoot = empty; @@ -23,6 +23,18 @@ void SourceMap::clear() m_slicePool.clear(); } +void SourceMap::swapWith(ThisType& rhs) +{ + m_file.swapWith(rhs.m_file); + m_sourceRoot.swapWith(rhs.m_sourceRoot); + m_sources.swapWith(rhs.m_sources); + m_names.swapWith(rhs.m_names); + m_sourcesContent.swapWith(rhs.m_sourcesContent); + m_lineStarts.swapWith(rhs.m_lineStarts); + m_lineEntries.swapWith(rhs.m_lineEntries); + m_slicePool.swapWith(rhs.m_slicePool); +} + void SourceMap::advanceToLine(Index nextLineIndex) { const Count currentLineIndex = getGeneratedLineCount() - 1; diff --git a/source/compiler-core/slang-source-map.h b/source/compiler-core/slang-source-map.h index f1338508f..e0c8d065a 100644 --- a/source/compiler-core/slang-source-map.h +++ b/source/compiler-core/slang-source-map.h @@ -10,9 +10,11 @@ namespace Slang { -class SourceMap : public RefObject +class SourceMap { public: + typedef SourceMap ThisType; + SLANG_CLASS_GUID(0x731383ea, 0xe516, 0x4cc3, { 0xa6, 0xcf, 0x37, 0xd2, 0x8c, 0x24, 0x5c, 0x5e }); struct Entry @@ -66,6 +68,9 @@ public: /// Clear the contents of the source map void clear(); + /// Swap this with rhs + void swapWith(ThisType& rhs); + /// Ctor SourceMap(): m_slicePool(StringSlicePool::Style::Default) diff --git a/source/core/slang-castable.cpp b/source/core/slang-castable.cpp index 6b7644bf2..f3c6541dd 100644 --- a/source/core/slang-castable.cpp +++ b/source/core/slang-castable.cpp @@ -20,37 +20,6 @@ namespace Slang { return castable; } -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ObjectCastableAdapter !!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -void* ObjectCastableAdapter::castAs(const Guid& guid) -{ - if (auto intf = getInterface(guid)) - { - return intf; - } - return getObject(guid); -} - -void* ObjectCastableAdapter::getInterface(const Guid& guid) -{ - if (guid == ISlangUnknown::getTypeGuid() || - guid == ICastable::getTypeGuid() || - guid == IObjectCastableAdapter::getTypeGuid()) - { - return static_cast<IObjectCastableAdapter*>(this); - } - return nullptr; -} - -void* ObjectCastableAdapter::getObject(const Guid& guid) -{ - if (guid == m_containedGuid) - { - return m_contained; - } - return nullptr; -} - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnknownCastableAdapter !!!!!!!!!!!!!!!!!!!!!!!!!!! */ void* UnknownCastableAdapter::castAs(const Guid& guid) diff --git a/source/core/slang-castable.h b/source/core/slang-castable.h index 4f4fdc940..dc6c49a89 100644 --- a/source/core/slang-castable.h +++ b/source/core/slang-castable.h @@ -35,18 +35,36 @@ SLANG_FORCE_INLINE T* as(ICastable* castable) return nullptr; } -/* Adapter interface to make non castable ref counted object usable as ICastable */ -class IObjectCastableAdapter : public ICastable +/* An interface for boxing values */ +class IBoxValueBase: public ICastable { SLANG_COM_INTERFACE(0x8b4aad81, 0x4934, 0x4a67, { 0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54 }); /// Get the contained object - virtual SLANG_NO_THROW RefObject* SLANG_MCALL getContained() = 0; + virtual SLANG_NO_THROW void* SLANG_MCALL getValuePtr() = 0; /// Get the guid that represents the contained ref object - virtual SLANG_NO_THROW SlangUUID getContainedGuid() = 0; + virtual SLANG_NO_THROW SlangUUID SLANG_MCALL getValueTypeGuid() = 0; }; -class ObjectCastableAdapter : public ComBaseObject, public IObjectCastableAdapter +template <typename T> +class IBoxValue : public IBoxValueBase +{ + public: + + SLANG_FORCE_INLINE T& get() { return *reinterpret_cast<T*>(getValuePtr()); } + SLANG_FORCE_INLINE T* getPtr() { return reinterpret_cast<T*>(getValuePtr()); } +}; + +// Cast into a boxed value type +template <typename T> +SLANG_FORCE_INLINE IBoxValue<T>* asBoxValue(ICastable* castable) +{ + IBoxValueBase* base = as<IBoxValueBase>(castable); + return (base && base->getValueTypeGuid() == T::getTypeGuid()) ? static_cast<IBoxValue<T>*>(base) : nullptr; +} + +template <typename T> +class BoxValue : public ComBaseObject, public IBoxValue<T> { public: SLANG_COM_BASE_IUNKNOWN_ALL @@ -54,39 +72,59 @@ public: // ICastable SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; - // IObjectCastableAdapter - virtual SLANG_NO_THROW RefObject* SLANG_MCALL getContained() SLANG_OVERRIDE { return m_contained; } - virtual SlangUUID getContainedGuid() SLANG_OVERRIDE { return m_containedGuid; } + // IBoxValue + virtual SLANG_NO_THROW void* SLANG_MCALL getValuePtr() SLANG_OVERRIDE { return &m_value; } + virtual SlangUUID SLANG_MCALL getValueTypeGuid() SLANG_OVERRIDE { return T::getTypeGuid(); } - template <typename T> - explicit ObjectCastableAdapter(T* ptr) - { - m_containedGuid = T::getTypeGuid(); - m_contained = ptr; - } - template <typename T> - explicit ObjectCastableAdapter(const RefPtr<T>& ptr) - { - m_containedGuid = T::getTypeGuid(); - m_contained = ptr; - } + BoxValue() {} - ObjectCastableAdapter(RefObject* obj, const Guid& containedGuid) : - m_contained(obj), - m_containedGuid(containedGuid) + explicit BoxValue(const T& rhs): + m_value(rhs) { - SLANG_ASSERT(obj); } protected: - void* getInterface(const Guid& guid); + void* getInterface(const Guid& guid); void* getObject(const Guid& guid); - - RefPtr<RefObject> m_contained; - SlangUUID m_containedGuid; + + T m_value; }; +// ------------------------------------------------------------ +template <typename T> +void* BoxValue<T>::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == IBoxValueBase::getTypeGuid()) + { + return static_cast<IBoxValueBase*>(this); + } + return nullptr; +} + +// ------------------------------------------------------------ +template <typename T> +void* BoxValue<T>::getObject(const Guid& guid) +{ + if (guid == T::getTypeGuid()) + { + return &m_value; + } + return nullptr; +} +// ------------------------------------------------------------ +template <typename T> +void* BoxValue<T>::castAs(const Guid& guid) +{ + if (auto ptr = getObject(guid)) + { + return ptr; + } + return getInterface(guid); +} + /* Adapter interface to make a non castable types work as ICastable */ class IUnknownCastableAdapter : public ICastable { diff --git a/source/core/slang-dictionary.h b/source/core/slang-dictionary.h index fffec9640..0839a649c 100644 --- a/source/core/slang-dictionary.h +++ b/source/core/slang-dictionary.h @@ -83,6 +83,7 @@ namespace Slang public: typedef TValue ValueType; typedef TKey KeyType; + typedef Dictionary ThisType; private: inline int GetProbeOffset(int /*probeId*/) const { @@ -481,6 +482,10 @@ namespace Slang { return _count; } + + /// Swap this with rhs + void swapWith(ThisType& rhs); + private: template<typename... Args> void Init(const KeyValuePair<TKey, TValue> & kvPair, Args... args) @@ -543,6 +548,16 @@ namespace Slang } }; + // --------------------------------------------------------- + template<typename TKey, typename TValue> + void Dictionary<TKey, TValue>::swapWith(ThisType& rhs) + { + Swap(bucketSizeMinusOne, rhs.bucketSizeMinusOne); + Swap(_count, rhs._count); + marks.swapWith(rhs.marks); + Swap(hashMap, rhs.hashMap); + } + class _DummyClass {}; diff --git a/source/core/slang-free-list.cpp b/source/core/slang-free-list.cpp index 4bada9434..d364b548c 100644 --- a/source/core/slang-free-list.cpp +++ b/source/core/slang-free-list.cpp @@ -63,6 +63,22 @@ void FreeList::init(size_t elementSize, size_t alignment, size_t elemsPerBlock) _init(elementSize, alignment, elemsPerBlock); } +void FreeList::swapWith(ThisType& rhs) +{ + Swap(m_top, rhs.m_top); + Swap(m_end, rhs.m_end); + + Swap(m_activeBlocks, rhs.m_activeBlocks); + Swap(m_freeBlocks, rhs.m_freeBlocks); + + Swap(m_freeElements, rhs.m_freeElements); + + Swap(m_elementSize, rhs.m_elementSize); + Swap(m_alignment, rhs.m_alignment); + Swap(m_blockSize, rhs.m_blockSize); + Swap(m_blockAllocationSize, rhs.m_blockAllocationSize); +} + void FreeList::_deallocateBlocks(Block* block) { while (block) diff --git a/source/core/slang-free-list.h b/source/core/slang-free-list.h index ee0158279..090c13613 100644 --- a/source/core/slang-free-list.h +++ b/source/core/slang-free-list.h @@ -69,6 +69,9 @@ class FreeList /// Initialize. If called on an already initialized heap, the heap will be deallocated. void init(size_t elementSize, size_t alignment, size_t elemsPerBlock); + /// Swap this with rhs + void swapWith(ThisType& rhs); + /// Default Ctor FreeList() { _init(); } /// Ctor diff --git a/source/core/slang-memory-arena.cpp b/source/core/slang-memory-arena.cpp index 6fc6c0c3f..6a13addb6 100644 --- a/source/core/slang-memory-arena.cpp +++ b/source/core/slang-memory-arena.cpp @@ -23,6 +23,7 @@ MemoryArena::~MemoryArena() reset(); } + MemoryArena::MemoryArena(size_t blockPayloadSize, size_t blockAlignment) { _initialize(blockPayloadSize, blockAlignment); @@ -62,6 +63,22 @@ void MemoryArena::_initialize(size_t blockPayloadSize, size_t alignment) _resetCurrentBlock(); } +void MemoryArena::swapWith(ThisType& rhs) +{ + Swap(m_start, rhs.m_start); + Swap(m_end, rhs.m_end); + Swap(m_current, rhs.m_current); + + Swap(m_blockPayloadSize, rhs.m_blockPayloadSize); + Swap(m_blockAllocSize, rhs.m_blockAllocSize); + Swap(m_blockAlignment, rhs.m_blockAlignment); + + Swap(m_availableBlocks, rhs.m_availableBlocks); + Swap(m_usedBlocks, rhs.m_usedBlocks); + + m_blockFreeList.swapWith(rhs.m_blockFreeList); +} + void MemoryArena::_resetCurrentBlock() { m_start = nullptr; diff --git a/source/core/slang-memory-arena.h b/source/core/slang-memory-arena.h index f63a48413..a947de5a2 100644 --- a/source/core/slang-memory-arena.h +++ b/source/core/slang-memory-arena.h @@ -149,6 +149,9 @@ public: /// Add a block such that it will be freed when everything else is freed. void addExternalBlock(void* data, size_t size); + // Swap this with rhs + void swapWith(ThisType& rhs); + /// Default Ctor MemoryArena(); /// Construct with block size and alignment. Block alignment must be a power of 2. diff --git a/source/core/slang-string-slice-pool.cpp b/source/core/slang-string-slice-pool.cpp index a0af3ba68..45cc811a3 100644 --- a/source/core/slang-string-slice-pool.cpp +++ b/source/core/slang-string-slice-pool.cpp @@ -41,6 +41,14 @@ void StringSlicePool::clear() } } +void StringSlicePool::swapWith(ThisType& rhs) +{ + Swap(m_style, rhs.m_style); + m_slices.swapWith(rhs.m_slices); + m_map.swapWith(rhs.m_map); + m_arena.swapWith(rhs.m_arena); +} + StringSlicePool::Handle StringSlicePool::add(const Slice& slice) { const Handle* handlePtr = m_map.TryGetValue(slice); diff --git a/source/core/slang-string-slice-pool.h b/source/core/slang-string-slice-pool.h index 15d204468..90586a527 100644 --- a/source/core/slang-string-slice-pool.h +++ b/source/core/slang-string-slice-pool.h @@ -99,6 +99,9 @@ public: /// Get the index of the first added handle Index getFirstAddedIndex() const { return m_style == Style::Default ? kDefaultHandlesCount : 0; } + /// Swap this with rhs + void swapWith(ThisType& rhs); + /// Ctor explicit StringSlicePool(Style style); diff --git a/source/core/slang-uint-set.h b/source/core/slang-uint-set.h index 334e7ebe8..f2c573865 100644 --- a/source/core/slang-uint-set.h +++ b/source/core/slang-uint-set.h @@ -15,6 +15,7 @@ namespace Slang class UIntSet { public: + typedef UIntSet ThisType; typedef uint32_t Element; ///< Type that holds the bits to say if value is present UIntSet() {} @@ -64,6 +65,9 @@ public: /// bool isEmpty() const; + /// Swap this with rhs + void swapWith(ThisType& rhs) { m_buffer.swapWith(rhs.m_buffer); } + /// Store the union of set1 and set2 in outRs static void calcUnion(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2); /// Store the intersection of set1 and set2 in outRs diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 907f39f48..b5fd27d55 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -1913,11 +1913,10 @@ namespace Slang auto artifactDesc = ArtifactDesc::make(ArtifactKind::Json, ArtifactPayload::SourceMap, ArtifactStyle::Obfuscated); // Create the source map artifact - auto sourceMapArtifact = Artifact::create(artifactDesc, sourceMap->m_file.getUnownedSlice()); + auto sourceMapArtifact = Artifact::create(artifactDesc, sourceMap->get().m_file.getUnownedSlice()); // Add the repesentation - ComPtr<IObjectCastableAdapter> castableAdapter(new ObjectCastableAdapter(sourceMap)); - sourceMapArtifact->addRepresentation(castableAdapter); + sourceMapArtifact->addRepresentation(sourceMap); // Associate with the container m_containerArtifact->addAssociated(sourceMapArtifact); diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp index f66f36758..985d0a0bf 100644 --- a/source/slang/slang-emit-source-writer.cpp +++ b/source/slang/slang-emit-source-writer.cpp @@ -18,7 +18,7 @@ namespace Slang { -SourceWriter::SourceWriter(SourceManager* sourceManager, LineDirectiveMode lineDirectiveMode, SourceMap* sourceMap) +SourceWriter::SourceWriter(SourceManager* sourceManager, LineDirectiveMode lineDirectiveMode, IBoxValue<SourceMap>* sourceMap) { m_sourceMap = sourceMap; m_lineDirectiveMode = lineDirectiveMode; @@ -360,23 +360,25 @@ void SourceWriter::_updateSourceMap(const HumaneSourceLoc& sourceLocation) if (sourceLocation.line <= 0) return; + auto sourceMap = m_sourceMap->getPtr(); + // We need to work out the current column in the generated (ie being written) output Index generatedLineIndex, generatedColumnIndex; _calcLocation(generatedLineIndex, generatedColumnIndex); // Advance to the current output line - m_sourceMap->advanceToLine(generatedLineIndex); + sourceMap->advanceToLine(generatedLineIndex); // Add the entry into the map, mapping back to the original source SourceMap::Entry entry; entry.init(); - entry.sourceFileIndex = m_sourceMap->getSourceFileIndex(sourceLocation.pathInfo.getName().getUnownedSlice()); + entry.sourceFileIndex = sourceMap->getSourceFileIndex(sourceLocation.pathInfo.getName().getUnownedSlice()); entry.sourceLine = sourceLocation.line - 1; entry.sourceColumn = sourceLocation.column - 1; entry.generatedColumn = generatedColumnIndex; - m_sourceMap->addEntry(entry); + sourceMap->addEntry(entry); } void SourceWriter::_emitLineDirectiveIfNeeded(const HumaneSourceLoc& sourceLocation) diff --git a/source/slang/slang-emit-source-writer.h b/source/slang/slang-emit-source-writer.h index c47b5f5fa..b64eb052a 100644 --- a/source/slang/slang-emit-source-writer.h +++ b/source/slang/slang-emit-source-writer.h @@ -6,7 +6,7 @@ #include "slang-compiler.h" #include "../compiler-core/slang-source-map.h" - +#include "../core/slang-castable.h" namespace Slang { @@ -75,10 +75,10 @@ public: SourceManager* getSourceManager() const { return m_sourceManager; } /// Get the associated source map. If source map tracking is not required, can return nullptr. - SourceMap* getSourceMap() const { return m_sourceMap; } + IBoxValue<SourceMap>* getSourceMap() const { return m_sourceMap; } /// Ctor - SourceWriter(SourceManager* sourceManager, LineDirectiveMode lineDirectiveMode, SourceMap* sourceMap); + SourceWriter(SourceManager* sourceManager, LineDirectiveMode lineDirectiveMode, IBoxValue<SourceMap>* sourceMap); protected: void _emitTextSpan(char const* textBegin, char const* textEnd); @@ -140,7 +140,7 @@ protected: Dictionary<String, int> m_mapGLSLSourcePathToID; int m_glslSourceIDCount = 0; - RefPtr<SourceMap> m_sourceMap; + ComPtr<IBoxValue<SourceMap>> m_sourceMap; LineDirectiveMode m_lineDirectiveMode; }; diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 67a4c4610..f9284d001 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -969,12 +969,12 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr lineDirectiveMode = LineDirectiveMode::GLSL; } - RefPtr<SourceMap> sourceMap; + ComPtr<IBoxValue<SourceMap>> sourceMap; // If SourceMap is enabled, we create one and associate it with the sourceWriter if (targetRequest->getLinkage()->m_generateSourceMap) { - sourceMap = new SourceMap; + sourceMap = new BoxValue<SourceMap>; } SourceWriter sourceWriter(sourceManager, lineDirectiveMode, sourceMap ); @@ -1154,8 +1154,7 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr { auto sourceMapArtifact = ArtifactUtil::createArtifact(ArtifactDesc::make(ArtifactKind::Json, ArtifactPayload::SourceMap, ArtifactStyle::None)); - ComPtr<IObjectCastableAdapter> castableAdapter(new ObjectCastableAdapter(sourceMap)); - sourceMapArtifact->addRepresentation(castableAdapter); + sourceMapArtifact->addRepresentation(sourceMap); artifact->addAssociated(sourceMapArtifact); } diff --git a/source/slang/slang-ir-obfuscate-loc.cpp b/source/slang/slang-ir-obfuscate-loc.cpp index 9a2f15fa4..7bb4bef7d 100644 --- a/source/slang/slang-ir-obfuscate-loc.cpp +++ b/source/slang/slang-ir-obfuscate-loc.cpp @@ -7,6 +7,8 @@ #include "../core/slang-hash.h" #include "../core/slang-char-util.h" +#include "../core/slang-castable.h" + namespace Slang { @@ -247,7 +249,10 @@ SlangResult obfuscateModuleLocs(IRModule* module, SourceManager* sourceManager) // We can now create a map. The locs are in order in entries, so that should make lookup easier. // This doesn't "leak" anything as the obfuscated loc map is not distributed. - RefPtr<SourceMap> sourceMap = new SourceMap; + ComPtr<IBoxValue<SourceMap>> boxedSourceMap(new BoxValue<SourceMap>); + + auto sourceMap = boxedSourceMap->getPtr(); + sourceMap->m_file = obfusctatedPathInfo.getName(); // Set up entries one per line @@ -349,10 +354,10 @@ SlangResult obfuscateModuleLocs(IRModule* module, SourceManager* sourceManager) } // Associate the sourceMap with the obfuscated file - obfuscatedFile->setSourceMap(sourceMap); + obfuscatedFile->setSourceMap(boxedSourceMap); // Set the obfuscated map onto the module - module->setObfuscatedSourceMap(sourceMap); + module->setObfuscatedSourceMap(boxedSourceMap); return SLANG_OK; } diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h index 78069a122..a53fe0092 100644 --- a/source/slang/slang-ir.h +++ b/source/slang/slang-ir.h @@ -2034,8 +2034,8 @@ public: SLANG_FORCE_INLINE IRModuleInst* getModuleInst() const { return m_moduleInst; } SLANG_FORCE_INLINE MemoryArena& getMemoryArena() { return m_memoryArena; } - SLANG_FORCE_INLINE SourceMap* getObfuscatedSourceMap() const { return m_obfuscatedSourceMap; } - SLANG_FORCE_INLINE void setObfuscatedSourceMap(SourceMap* sourceMap) { m_obfuscatedSourceMap = sourceMap; } + SLANG_FORCE_INLINE IBoxValue<SourceMap>* getObfuscatedSourceMap() const { return m_obfuscatedSourceMap; } + SLANG_FORCE_INLINE void setObfuscatedSourceMap(IBoxValue<SourceMap>* sourceMap) { m_obfuscatedSourceMap = sourceMap; } IRDeduplicationContext* getDeduplicationContext() const { return &m_deduplicationContext; } @@ -2105,7 +2105,7 @@ private: mutable IRDeduplicationContext m_deduplicationContext; /// Holds the obfuscated source map for this module if applicable - RefPtr<SourceMap> m_obfuscatedSourceMap; + ComPtr<IBoxValue<SourceMap>> m_obfuscatedSourceMap; }; struct IRSpecializationDictionaryItem : public IRInst diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index bedfb1161..6b2814ca7 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -2385,7 +2385,7 @@ void FrontEndCompileRequest::generateIR() if (useSerialIRBottleneck) { // Keep the obfuscated source map (if there is one) - RefPtr<SourceMap> obfuscatedSourceMap = irModule->getObfuscatedSourceMap(); + ComPtr<IBoxValue<SourceMap>> obfuscatedSourceMap(irModule->getObfuscatedSourceMap()); IRSerialData serialData; { @@ -4884,9 +4884,9 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac { ComPtr<ICastable> castable; SLANG_RETURN_ON_FAIL(associated->getOrCreateRepresentation(SourceMap::getTypeGuid(), ArtifactKeep::Yes, castable.writeRef())); - - auto sourceMap = as<SourceMap>(castable); - + auto sourceMap = asBoxValue<SourceMap>(castable); + SLANG_ASSERT(sourceMap); + // I guess we add to all ir modules? for (auto irModule : library->m_modules) diff --git a/tools/slang-unit-test/unit-test-source-map.cpp b/tools/slang-unit-test/unit-test-source-map.cpp index bf97096e9..125c4eccc 100644 --- a/tools/slang-unit-test/unit-test-source-map.cpp +++ b/tools/slang-unit-test/unit-test-source-map.cpp @@ -53,7 +53,7 @@ static SlangResult _check() rootValue = builder.getRootValue(); } - RefPtr<SourceMap> sourceMap; + SourceMap sourceMap; SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::decode(container, rootValue, &sink, sourceMap)); |
