summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-04-18 12:36:06 -0400
committerGitHub <noreply@github.com>2023-04-18 12:36:06 -0400
commit181fd1f3c9c4b047c1947096e7b3f8e5bc2314c3 (patch)
tree308cbadae2f68d43ca20f92755b08db08e8b2283
parent90a9f43573ec0777c2ae4fa20c8fdc51a4ae7b3a (diff)
On demand SourceMap JSON serialization (#2811)
* #include an absolute path didn't work - because paths were taken to always be relative. * Moved JSON source map writing logic to JSONSourceMapUtil. * Use ArtifactHandler to read/write SourceMaps. Use ObjectCastableAdapter to hold SourceMap Only serialize SourceMap <-> JSON on demand.
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.cpp49
-rw-r--r--source/compiler-core/slang-json-source-map-util.cpp43
-rw-r--r--source/compiler-core/slang-json-source-map-util.h6
-rw-r--r--source/compiler-core/slang-source-map.h2
-rw-r--r--source/core/slang-castable.cpp31
-rw-r--r--source/core/slang-castable.h53
-rw-r--r--source/slang/slang-compiler.cpp28
-rw-r--r--source/slang/slang-emit.cpp26
-rw-r--r--source/slang/slang.cpp11
9 files changed, 194 insertions, 55 deletions
diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp
index 985aa2337..1a8e8374d 100644
--- a/source/compiler-core/slang-artifact-handler-impl.cpp
+++ b/source/compiler-core/slang-artifact-handler-impl.cpp
@@ -17,6 +17,10 @@
#include "../core/slang-io.h"
#include "../core/slang-shared-library.h"
+#include "slang-source-map.h"
+
+#include "slang-json-source-map-util.h"
+
namespace Slang {
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -126,6 +130,25 @@ SlangResult DefaultArtifactHandler::expandChildren(IArtifact* container)
return SLANG_OK;
}
+static SlangResult _loadSourceMap(IArtifact* artifact, ArtifactKeep intermediateKeep, RefPtr<SourceMap>& outSourceMap)
+{
+ const auto desc = artifact->getDesc();
+ if (isDerivedFrom(desc.kind, ArtifactKind::Json) &&
+ isDerivedFrom(desc.payload, ArtifactPayload::SourceMap))
+ {
+ 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;
+ return SLANG_OK;
+ }
+
+ return SLANG_FAIL;
+}
+
SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable)
{
const auto reps = artifact->getRepresentations();
@@ -156,8 +179,16 @@ SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifac
}
}
- // Special case shared library
- if (guid == ISlangSharedLibrary::getTypeGuid())
+ // Special cases
+ 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);
+ }
+ else if (guid == ISlangSharedLibrary::getTypeGuid())
{
ComPtr<ISlangSharedLibrary> sharedLib;
SLANG_RETURN_ON_FAIL(_loadSharedLibrary(artifact, sharedLib.writeRef()));
@@ -169,6 +200,20 @@ 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())
+ {
+ 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);
+ }
+ }
+ }
return SLANG_E_NOT_AVAILABLE;
}
diff --git a/source/compiler-core/slang-json-source-map-util.cpp b/source/compiler-core/slang-json-source-map-util.cpp
index 3929a3387..4ef6ee3d6 100644
--- a/source/compiler-core/slang-json-source-map-util.cpp
+++ b/source/compiler-core/slang-json-source-map-util.cpp
@@ -3,6 +3,7 @@
#include "../../slang-com-helper.h"
#include "../core/slang-string-util.h"
+#include "../core/slang-blob.h"
#include "slang-json-native.h"
@@ -454,6 +455,11 @@ SlangResult JSONSourceMapUtil::encode(SourceMap* sourceMap, JSONContainer* conta
return SLANG_OK;
}
+/* static */SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, RefPtr<SourceMap>& outSourceMap)
+{
+ return read(blob, nullptr, outSourceMap);
+}
+
SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, DiagnosticSink* parentSink, RefPtr<SourceMap>& outSourceMap)
{
SourceManager sourceManager;
@@ -489,4 +495,41 @@ SlangResult JSONSourceMapUtil::read(ISlangBlob* blob, DiagnosticSink* parentSink
return SLANG_OK;
}
+
+/* static */SlangResult JSONSourceMapUtil::write(SourceMap* sourceMap, ComPtr<ISlangBlob>& outBlob)
+{
+ SourceManager sourceMapSourceManager;
+ sourceMapSourceManager.initialize(nullptr, nullptr);
+
+ // Create a sink
+ DiagnosticSink sourceMapSink(&sourceMapSourceManager, nullptr);
+
+ SLANG_RETURN_ON_FAIL(write(sourceMap, &sourceMapSink, outBlob));
+ return SLANG_OK;
+}
+
+/* static */ SlangResult JSONSourceMapUtil::write(SourceMap* sourceMap, DiagnosticSink* sink, ComPtr<ISlangBlob>& outBlob)
+{
+ auto sourceManager = sink->getSourceManager();
+
+ // Write it out
+ String json;
+ {
+ RefPtr<JSONContainer> jsonContainer(new JSONContainer(sourceManager));
+
+ JSONValue jsonValue;
+
+ SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::encode(sourceMap, jsonContainer, sink, jsonValue));
+
+ // Convert into a string
+ JSONWriter writer(JSONWriter::IndentationStyle::Allman);
+ jsonContainer->traverseRecursively(jsonValue, &writer);
+
+ json = writer.getBuilder();
+ }
+
+ outBlob = StringBlob::moveCreate(json);
+ return SLANG_OK;
+}
+
} // namespace Slang
diff --git a/source/compiler-core/slang-json-source-map-util.h b/source/compiler-core/slang-json-source-map-util.h
index ba417dd7c..8d5071d4e 100644
--- a/source/compiler-core/slang-json-source-map-util.h
+++ b/source/compiler-core/slang-json-source-map-util.h
@@ -18,6 +18,12 @@ struct JSONSourceMapUtil
/// 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);
+
+ /// Write source map to outBlob JSON
+ static SlangResult write(SourceMap* sourceMap, ComPtr<ISlangBlob>& outBlob);
+ /// Write out the source map into a blob
+ static SlangResult write(SourceMap* sourceMap, DiagnosticSink* sink, ComPtr<ISlangBlob>& outBlob);
};
} // namespace Slang
diff --git a/source/compiler-core/slang-source-map.h b/source/compiler-core/slang-source-map.h
index 1ccc87e90..f1338508f 100644
--- a/source/compiler-core/slang-source-map.h
+++ b/source/compiler-core/slang-source-map.h
@@ -13,6 +13,8 @@ namespace Slang {
class SourceMap : public RefObject
{
public:
+ SLANG_CLASS_GUID(0x731383ea, 0xe516, 0x4cc3, { 0xa6, 0xcf, 0x37, 0xd2, 0x8c, 0x24, 0x5c, 0x5e });
+
struct Entry
{
void init()
diff --git a/source/core/slang-castable.cpp b/source/core/slang-castable.cpp
index f3c6541dd..6b7644bf2 100644
--- a/source/core/slang-castable.cpp
+++ b/source/core/slang-castable.cpp
@@ -20,6 +20,37 @@ 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 a72822f05..4f4fdc940 100644
--- a/source/core/slang-castable.h
+++ b/source/core/slang-castable.h
@@ -35,6 +35,58 @@ 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
+{
+ 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;
+ /// Get the guid that represents the contained ref object
+ virtual SLANG_NO_THROW SlangUUID getContainedGuid() = 0;
+};
+
+class ObjectCastableAdapter : public ComBaseObject, public IObjectCastableAdapter
+{
+public:
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // 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; }
+
+ 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;
+ }
+
+ ObjectCastableAdapter(RefObject* obj, const Guid& containedGuid) :
+ m_contained(obj),
+ m_containedGuid(containedGuid)
+ {
+ SLANG_ASSERT(obj);
+ }
+
+protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
+ RefPtr<RefObject> m_contained;
+ SlangUUID m_containedGuid;
+};
+
+
/* Adapter interface to make a non castable types work as ICastable */
class IUnknownCastableAdapter : public ICastable
{
@@ -44,6 +96,7 @@ class IUnknownCastableAdapter : public ICastable
virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() = 0;
};
+
/* An adapter such that types which aren't derived from ICastable, can be used as such.
With the following caveats.
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index becd65596..907f39f48 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -15,8 +15,6 @@
#include "../compiler-core/slang-lexer.h"
-#include "../compiler-core/slang-json-source-map-util.h"
-
// Artifact
#include "../compiler-core/slang-artifact-desc-util.h"
#include "../compiler-core/slang-artifact-representation-impl.h"
@@ -1902,9 +1900,6 @@ namespace Slang
auto frontEndReq = getFrontEndReq();
- 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(!)
@@ -1915,29 +1910,14 @@ namespace Slang
// If we have a source map *and* we want to generate them for output add to the container
if (sourceMap && getLinkage()->m_generateSourceMap)
{
- // Write it out
- String json;
- {
- RefPtr<JSONContainer> jsonContainer(new JSONContainer(sourceManager));
-
- JSONValue jsonValue;
-
- SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::encode(sourceMap, jsonContainer, sink, jsonValue));
-
- // Convert into a string
- JSONWriter writer(JSONWriter::IndentationStyle::Allman);
- jsonContainer->traverseRecursively(jsonValue, &writer);
-
- json = writer.getBuilder();
- }
-
- auto jsonSourceMapBlob = StringBlob::moveCreate(json);
-
auto artifactDesc = ArtifactDesc::make(ArtifactKind::Json, ArtifactPayload::SourceMap, ArtifactStyle::Obfuscated);
// Create the source map artifact
auto sourceMapArtifact = Artifact::create(artifactDesc, sourceMap->m_file.getUnownedSlice());
- sourceMapArtifact->addRepresentationUnknown(jsonSourceMapBlob);
+
+ // Add the repesentation
+ ComPtr<IObjectCastableAdapter> castableAdapter(new ObjectCastableAdapter(sourceMap));
+ sourceMapArtifact->addRepresentation(castableAdapter);
// Associate with the container
m_containerArtifact->addAssociated(sourceMapArtifact);
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index e2948561c..67a4c4610 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -82,7 +82,7 @@
#include "../compiler-core/slang-artifact-impl.h"
#include "../compiler-core/slang-artifact-associated-impl.h"
-#include "../compiler-core/slang-json-source-map-util.h"
+#include "../core/slang-castable.h"
#include <assert.h>
@@ -1152,28 +1152,10 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr
if (sourceMap)
{
- SourceManager sourceMapSourceManager;
- sourceMapSourceManager.initialize(nullptr, nullptr);
-
- // Create a sink
- DiagnosticSink sourceMapSink(&sourceMapSourceManager, nullptr);
-
- // Turn into JSON
- RefPtr<JSONContainer> jsonContainer(new JSONContainer(&sourceMapSourceManager));
-
- JSONValue jsonValue;
- SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::encode(sourceMap, jsonContainer, &sourceMapSink, jsonValue));
-
- // Okay now convert this into a text file and then a blob
-
- // Convert into a string
- JSONWriter writer(JSONWriter::IndentationStyle::KNR);
- jsonContainer->traverseRecursively(jsonValue, &writer);
-
- auto sourceMapBlob = StringBlob::moveCreate(writer.getBuilder());
-
auto sourceMapArtifact = ArtifactUtil::createArtifact(ArtifactDesc::make(ArtifactKind::Json, ArtifactPayload::SourceMap, ArtifactStyle::None));
- sourceMapArtifact->addRepresentationUnknown(sourceMapBlob);
+
+ ComPtr<IObjectCastableAdapter> castableAdapter(new ObjectCastableAdapter(sourceMap));
+ sourceMapArtifact->addRepresentation(castableAdapter);
artifact->addAssociated(sourceMapArtifact);
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index c8cda0dca..bedfb1161 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -15,8 +15,6 @@
#include "../compiler-core/slang-artifact-associated-impl.h"
#include "../compiler-core/slang-artifact-container-util.h"
-#include "../compiler-core/slang-json-source-map-util.h"
-
#include "../core/slang-memory-file-system.h"
#include "slang-module-library.h"
@@ -4884,12 +4882,11 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac
isDerivedFrom(assocDesc.payload, ArtifactPayload::SourceMap) &&
isDerivedFrom(assocDesc.style, ArtifactStyle::Obfuscated))
{
- ComPtr<ISlangBlob> sourceMapBlob;
- SLANG_RETURN_ON_FAIL(associated->loadBlob(ArtifactKeep::No, sourceMapBlob.writeRef()));
+ ComPtr<ICastable> castable;
+ SLANG_RETURN_ON_FAIL(associated->getOrCreateRepresentation(SourceMap::getTypeGuid(), ArtifactKeep::Yes, castable.writeRef()));
+
+ auto sourceMap = as<SourceMap>(castable);
- RefPtr<SourceMap> sourceMap;
- SLANG_RETURN_ON_FAIL(JSONSourceMapUtil::read(sourceMapBlob, nullptr, sourceMap));
-
// I guess we add to all ir modules?
for (auto irModule : library->m_modules)