summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-artifact-desc-util.cpp4
-rw-r--r--source/compiler-core/slang-artifact-impl.cpp515
-rw-r--r--source/compiler-core/slang-artifact-impl.h103
-rw-r--r--source/compiler-core/slang-artifact-util.cpp10
-rw-r--r--source/compiler-core/slang-artifact.h100
-rw-r--r--source/compiler-core/slang-downstream-compiler.cpp2
-rw-r--r--source/compiler-core/slang-glslang-compiler.cpp2
-rw-r--r--source/compiler-core/slang-nvrtc-compiler.cpp2
-rw-r--r--source/core/slang-blob.cpp65
-rw-r--r--source/core/slang-blob.h98
-rw-r--r--source/core/slang-destroyable.h13
-rw-r--r--source/core/slang-file-system.cpp24
-rw-r--r--source/core/slang-file-system.h11
-rw-r--r--source/core/slang-riff-file-system.cpp10
-rw-r--r--source/core/slang-shared-library.cpp46
-rw-r--r--source/core/slang-shared-library.h10
-rw-r--r--source/core/slang-string-util.cpp2
-rw-r--r--source/core/slang-zip-file-system.cpp4
-rw-r--r--source/slang/slang-compiler.cpp76
-rw-r--r--source/slang/slang-ir-link.cpp3
-rw-r--r--source/slang/slang-module-library.cpp4
-rw-r--r--source/slang/slang-options.cpp2
-rw-r--r--source/slang/slang-repro.cpp27
-rw-r--r--source/slang/slang-workspace-version.cpp8
-rw-r--r--source/slang/slang.cpp11
25 files changed, 882 insertions, 270 deletions
diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp
index e382ca08c..413858c32 100644
--- a/source/compiler-core/slang-artifact-desc-util.cpp
+++ b/source/compiler-core/slang-artifact-desc-util.cpp
@@ -618,7 +618,7 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des
/* static */String ArtifactDescUtil::getBaseName(IArtifact* artifact)
{
- if (auto fileRep = findItem<IFileArtifactRepresentation>(artifact))
+ if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
{
return getBaseName(artifact->getDesc(), fileRep);
}
@@ -634,7 +634,7 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des
/* static */String ArtifactDescUtil::getParentPath(IArtifact* artifact)
{
- if (auto fileRep = findItem<IFileArtifactRepresentation>(artifact))
+ if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
{
return getParentPath(fileRep);
}
diff --git a/source/compiler-core/slang-artifact-impl.cpp b/source/compiler-core/slang-artifact-impl.cpp
index 8dbae063b..d57edd2c8 100644
--- a/source/compiler-core/slang-artifact-impl.cpp
+++ b/source/compiler-core/slang-artifact-impl.cpp
@@ -7,6 +7,367 @@
namespace Slang {
+/*
+If we use LazyCastableList for Items, it means we'll have to use the
+UnknownCastableAdapter for ISharedLibrary, IBlob etc.
+
+That means when we look for an item in the list, we will always do a query interface on those types,
+although it will always fail (so no atomic ref count).
+
+That doesn't seem wholey unreasonable.
+
+Note that we *can* derive from ICastable for *our* implementations of ISlangBlob, ISharedLibrary. So the
+kludge is only needed for types that really do require adaption. For Blob we'll require multiple interface inheritance.
+*/
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! LazyCastableList !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void LazyCastableList::removeAt(Index index)
+{
+ SLANG_ASSERT(index >= 0 && index < getCount());
+
+ if (auto list = as<ICastableList>(m_castable))
+ {
+ list->removeAt(index);
+ }
+ else
+ {
+ SLANG_ASSERT(index == 0);
+ m_castable.setNull();
+ }
+}
+
+void LazyCastableList::clear()
+{
+ if (m_castable)
+ {
+ if (auto list = as<ICastableList>(m_castable))
+ {
+ list->clear();
+ }
+ else
+ {
+ m_castable.setNull();
+ }
+ }
+}
+
+void LazyCastableList::clearAndDeallocate()
+{
+ m_castable.setNull();
+}
+
+Count LazyCastableList::getCount() const
+{
+ if (m_castable)
+ {
+ if (auto list = as<ICastableList>(m_castable))
+ {
+ return list->getCount();
+ }
+ return 1;
+ }
+ return 0;
+}
+
+void LazyCastableList::add(ICastable* castable)
+{
+ SLANG_ASSERT(castable);
+ SLANG_ASSERT(castable != m_castable);
+
+ if (m_castable)
+ {
+ if (auto list = as<ICastableList>(m_castable))
+ {
+ // Shouldn't be in the list
+ SLANG_ASSERT(list->indexOf(castable) < 0);
+ list->add(castable);
+ }
+ else
+ {
+ list = new CastableList;
+ list->add(m_castable);
+ m_castable = list;
+ list->add(castable);
+ }
+ }
+ else
+ {
+ m_castable = castable;
+ }
+}
+
+ICastableList* LazyCastableList::requireList()
+{
+ if (m_castable)
+ {
+ if (auto list = as<ICastableList>(m_castable))
+ {
+ return list;
+ }
+ else
+ {
+ // Promote to a list with the element in it
+ list = new CastableList;
+ list->add(m_castable);
+ m_castable = list;
+ return list;
+ }
+ }
+ else
+ {
+ // Create an empty list
+ ICastableList* list = new CastableList;
+ m_castable = list;
+ return list;
+ }
+}
+
+ICastableList* LazyCastableList::getList()
+{
+ return (m_castable == nullptr) ? nullptr : requireList();
+}
+
+void* LazyCastableList::find(const Guid& guid)
+{
+ if (!m_castable)
+ {
+ return nullptr;
+ }
+ if (auto list = as<ICastableList>(m_castable))
+ {
+ return list->find(guid);
+ }
+ else
+ {
+ return m_castable->castAs(guid);
+ }
+}
+
+ConstArrayView<ICastable*> LazyCastableList::getView() const
+{
+ if (!m_castable)
+ {
+ // Empty
+ return ConstArrayView<ICastable*>();
+ }
+
+ if (auto list = as<ICastableList>(m_castable))
+ {
+ const auto count = list->getCount();
+ const auto buffer = list->getBuffer();
+
+ return ConstArrayView<ICastable*>(buffer, count);
+ }
+ else
+ {
+ return ConstArrayView<ICastable*>((ICastable*const*)&m_castable, 1);
+ }
+}
+
+Index LazyCastableList::indexOf(ICastable* castable) const
+{
+ return getView().indexOf(castable);
+}
+
+Index LazyCastableList::indexOfUnknown(ISlangUnknown* unk) const
+{
+ {
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ {
+ return indexOf(castable);
+ }
+ }
+
+ // It's not derived from ICastable, so can only be in list via an adapter
+ const auto view = getView();
+
+ const Count count = view.getCount();
+ for (Index i = 0; i < count; ++i)
+ {
+ auto adapter = as<IUnknownCastableAdapter>(view[i]);
+ if (adapter && adapter->getContained() == unk)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnknownCastableAdapter !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* UnknownCastableAdapter::castAs(const Guid& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ if (auto obj = getObject(guid))
+ {
+ return obj;
+ }
+
+ if (m_found && guid == m_foundGuid)
+ {
+ return m_found;
+ }
+
+ ComPtr<ISlangUnknown> cast;
+ if (SLANG_SUCCEEDED(m_contained->queryInterface(guid, (void**)cast.writeRef())) && cast)
+ {
+ // Save the interface in the cache
+ m_found = cast;
+ m_foundGuid = guid;
+
+ return cast;
+ }
+ return nullptr;
+}
+
+void* UnknownCastableAdapter::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid())
+ {
+ return static_cast<ICastable*>(this);
+ }
+ return nullptr;
+}
+
+void* UnknownCastableAdapter::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CastableList !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+CastableList::~CastableList()
+{
+ for (auto castable : m_list)
+ {
+ castable->release();
+ }
+}
+
+void* CastableList::castAs(const Guid& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+void* CastableList::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == ICastableList::getTypeGuid())
+ {
+ return static_cast<ICastableList*>(this);
+ }
+ return nullptr;
+}
+
+void* CastableList::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+void* CastableList::find(const Guid& guid)
+{
+ for (ICastable* castable : m_list)
+ {
+ if (auto ptr = castable->castAs(guid))
+ {
+ return ptr;
+ }
+ }
+ return nullptr;
+}
+
+Index CastableList::indexOf(ICastable* castable)
+{
+ const Count count = m_list.getCount();
+ for (Index i = 0; i < count; ++i)
+ {
+ ICastable* cur = m_list[i];
+ if (cur == castable)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void CastableList::add(ICastable* castable)
+{
+ SLANG_ASSERT(castable);
+ castable->addRef();
+ m_list.add(castable);
+}
+
+void CastableList::removeAt(Index i)
+{
+ auto castable = m_list[i];
+ m_list.removeAt(i);
+ castable->release();
+}
+
+void CastableList::clear()
+{
+ for (auto castable : m_list)
+ {
+ castable->release();
+ }
+ m_list.clear();
+}
+
+void CastableList::addUnknown(ISlangUnknown* unk)
+{
+ // If it has ICastable interface we can just add as that
+ {
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ {
+ return add(castable);
+ }
+ }
+
+ // Wrap it in an adapter
+ IUnknownCastableAdapter* adapter = new UnknownCastableAdapter(unk);
+ add(adapter);
+}
+
+Index CastableList::indexOfUnknown(ISlangUnknown* unk)
+{
+ SLANG_ASSERT(unk);
+ // If it has a castable interface we can just look for that
+ {
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ {
+ return indexOf(castable);
+ }
+ }
+
+ // It's not derived from ICastable, so can only be in list via an adapter
+ const Count count = m_list.getCount();
+ for (Index i = 0; i < count; ++i)
+ {
+ auto adapter = as<IUnknownCastableAdapter>(m_list[i]);
+ if (adapter && adapter->getContained() == unk)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactList !!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* ArtifactList::getInterface(const Guid& guid)
@@ -91,86 +452,24 @@ void* Artifact::getInterface(const Guid& uuid)
bool Artifact::exists()
{
- for (ISlangUnknown* item : m_items)
+ for (auto rep : m_representations.getView())
{
- ComPtr<ICastable> castable;
-
- if (SLANG_SUCCEEDED(item->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ if (auto artifactRep = as<IArtifactRepresentation>(rep))
{
- auto rep = as<IArtifactRepresentation>(castable);
- if (rep)
+ // It is an artifact rep and it exists, we are done
+ if (artifactRep->exists())
{
- // It is a rep and it exists
- if (rep->exists())
- {
- return true;
- }
- continue;
- }
- // Associated types don't encapsulate an artifact representation, so don't signal existance
- if (as<IArtifactAssociated>(castable))
- {
- continue;
+ return true;
}
}
-
- // It can't be IArtifactRepresentation or IArtifactAssociated, so we assume means it exists
- return true;
- }
-
- return false;
-}
-
-void Artifact::addItem(ISlangUnknown* intf)
-{
- SLANG_ASSERT(intf);
- // Can't already be in there
- SLANG_ASSERT(m_items.indexOf(intf) < 0);
- // Add it
- m_items.add(ComPtr<ISlangUnknown>(intf));
-}
-
-void Artifact::removeItemAt(Index i)
-{
- m_items.removeAt(i);
-}
-
-void* Artifact::findItemInterface(const Guid& guid)
-{
- for (ISlangUnknown* intf : m_items)
- {
- ISlangUnknown* cast = nullptr;
- if (SLANG_SUCCEEDED(intf->queryInterface(guid, (void**)&cast)) && cast)
+ else
{
- // NOTE! This assumes we *DONT* need to ref count to keep an interface in scope
- // (as strict COM requires so as to allow on demand interfaces).
- cast->release();
- return cast;
+ // If it's *not* IArtifactRepresentation derived, it's existance *is* a representation
+ return true;
}
}
- return nullptr;
-}
-
-void* Artifact::findItemObject(const Guid& classGuid)
-{
- for (ISlangUnknown* intf : m_items)
- {
- ComPtr<ICastable> castable;
- if (SLANG_SUCCEEDED(intf->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
- {
- void* obj = castable->castAs(classGuid);
- // NOTE! This assumes we *DONT* need to ref count to keep an interface in scope
- // (as strict COM requires so as to allow on demand interfaces).
-
- // If could cast return the result
- if (obj)
- {
- return obj;
- }
- }
- }
- return nullptr;
+ return false;
}
SlangResult Artifact::requireFile(Keep keep, IFileArtifactRepresentation** outFileRep)
@@ -182,7 +481,7 @@ SlangResult Artifact::requireFile(Keep keep, IFileArtifactRepresentation** outFi
SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob)
{
// If we have a blob just return it
- if (auto blob = findItem<ISlangBlob>(this))
+ if (auto blob = (ISlangBlob*)findRepresentation(ISlangBlob::getTypeGuid()))
{
blob->addRef();
*outBlob = blob;
@@ -192,12 +491,11 @@ SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob)
ComPtr<ISlangBlob> blob;
// Look for a representation that we can serialize into a blob
- for (ISlangUnknown* intf : m_items)
+ for (auto rep : m_representations.getView())
{
- ComPtr<IArtifactRepresentation> rep;
- if (SLANG_SUCCEEDED(intf->queryInterface(IArtifactRepresentation::getTypeGuid(), (void**)rep.writeRef())) && rep)
+ if (auto artifactRep = as<IArtifactRepresentation>(rep))
{
- SlangResult res = rep->writeToBlob(blob.writeRef());
+ SlangResult res = artifactRep->writeToBlob(blob.writeRef());
if (SLANG_SUCCEEDED(res) && blob)
{
break;
@@ -214,11 +512,74 @@ SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob)
// Put in cache
if (canKeep(keep))
{
- addItem(blob);
+ addRepresentationUnknown(blob);
}
*outBlob = blob.detach();
return SLANG_OK;
}
+void Artifact::addAssociated(ICastable* castable)
+{
+ SLANG_ASSERT(castable);
+ m_associated.add(castable);
+}
+
+void* Artifact::findAssociated(const Guid& guid)
+{
+ return m_associated.find(guid);
+}
+
+ICastableList* Artifact::getAssociated()
+{
+ return m_associated.requireList();
+}
+
+void Artifact::addRepresentation(IArtifactRepresentation* rep)
+{
+ SLANG_ASSERT(rep);
+ if (m_representations.indexOf(rep) >= 0)
+ {
+ SLANG_ASSERT_FAILURE("Already have this representation");
+ return;
+ }
+ m_representations.add(rep);
+}
+
+void Artifact::addRepresentationUnknown(ISlangUnknown* unk)
+{
+ SLANG_ASSERT(unk);
+ if (m_representations.indexOfUnknown(unk) >= 0)
+ {
+ SLANG_ASSERT_FAILURE("Already have this representation");
+ return;
+ }
+
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ {
+ if (m_representations.indexOf(castable) >= 0)
+ {
+ SLANG_ASSERT_FAILURE("Already have this representation");
+ return;
+ }
+ m_representations.add(castable);
+ }
+ else
+ {
+ UnknownCastableAdapter* adapter = new UnknownCastableAdapter(unk);
+ m_representations.add(adapter);
+ }
+}
+
+void* Artifact::findRepresentation(const Guid& guid)
+{
+ return m_representations.find(guid);
+}
+
+ICastableList* Artifact::getRepresentations()
+{
+ return m_representations.requireList();
+}
+
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-impl.h b/source/compiler-core/slang-artifact-impl.h
index 35dbe5f98..79aad3b64 100644
--- a/source/compiler-core/slang-artifact-impl.h
+++ b/source/compiler-core/slang-artifact-impl.h
@@ -12,6 +12,89 @@
namespace Slang
{
+/* An adapter such that types which aren't derived from ICastable, can be used as such.
+
+With the following caveats.
+* the interfaces/objects of the adapter are checked *first*, so IUnknown will always be for the adapter
+* assumes when doing a queryInterface on the contained item
+*/
+class UnknownCastableAdapter : public ComBaseObject, public IUnknownCastableAdapter
+{
+public:
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IUnknownCastableAdapter
+ virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() SLANG_OVERRIDE { return m_contained; }
+
+ UnknownCastableAdapter(ISlangUnknown* unk):
+ m_contained(unk)
+ {
+ SLANG_ASSERT(unk);
+ }
+
+protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
+ ComPtr<ISlangUnknown> m_contained;
+
+ // We hold a cache for a single lookup to make things a little faster
+ void* m_found = nullptr;
+ Guid m_foundGuid;
+};
+
+class CastableList : public ComBaseObject, public ICastableList
+{
+public:
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // ICastableList
+ virtual Count SLANG_MCALL getCount() SLANG_OVERRIDE { return m_list.getCount(); }
+ virtual ICastable* SLANG_MCALL getAt(Index i) SLANG_OVERRIDE { return m_list[i]; }
+ virtual void SLANG_MCALL add(ICastable* castable) SLANG_OVERRIDE;
+ virtual void SLANG_MCALL addUnknown(ISlangUnknown* unk) SLANG_OVERRIDE;
+ virtual void SLANG_MCALL removeAt(Index i) SLANG_OVERRIDE;
+ virtual void SLANG_MCALL clear() SLANG_OVERRIDE;
+ virtual Index SLANG_MCALL indexOf(ICastable* castable) SLANG_OVERRIDE;
+ virtual Index SLANG_MCALL indexOfUnknown(ISlangUnknown* unk) SLANG_OVERRIDE;
+ virtual void* SLANG_MCALL find(const Guid& guid) SLANG_OVERRIDE;
+ virtual ICastable* const* SLANG_MCALL getBuffer() SLANG_OVERRIDE { return m_list.getBuffer(); }
+
+ virtual ~CastableList();
+
+protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
+ List<ICastable*> m_list;
+};
+
+class LazyCastableList
+{
+public:
+ void add(ICastable* castable);
+ Count getCount() const;
+ void removeAt(Index index);
+ void clear();
+ void clearAndDeallocate();
+ void* find(const Guid& guid);
+ ConstArrayView<ICastable*> getView() const;
+ Index indexOf(ICastable* castable) const;
+ Index indexOfUnknown(ISlangUnknown* unk) const;
+
+ ICastableList* requireList();
+ ICastableList* getList();
+
+protected:
+ ComPtr<ICastable> m_castable;
+};
+
class ArtifactList : public ComBaseObject, public IArtifactList
{
public:
@@ -86,12 +169,15 @@ public:
virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadBlob(Keep keep, ISlangBlob** outBlob) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFile(Keep keep, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
virtual SLANG_NO_THROW const char* SLANG_MCALL getName() SLANG_OVERRIDE { return m_name.getBuffer(); }
- virtual SLANG_NO_THROW void* SLANG_MCALL findItemInterface(const Guid& uuid) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW void* SLANG_MCALL findItemObject(const Guid& classGuid) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW void SLANG_MCALL addItem(ISlangUnknown* intf) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getItemAt(Index i) SLANG_OVERRIDE { return m_items[i]; }
- virtual SLANG_NO_THROW void SLANG_MCALL removeItemAt(Index i) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW Index SLANG_MCALL getItemCount() SLANG_OVERRIDE { return m_items.getCount(); }
+
+ virtual SLANG_NO_THROW void SLANG_MCALL addAssociated(ICastable* castable) SLANG_OVERRIDE;
+ virtual void* SLANG_MCALL SLANG_MCALL findAssociated(const Guid& unk) SLANG_OVERRIDE;
+ virtual ICastableList* SLANG_MCALL getAssociated() SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW void SLANG_MCALL addRepresentation(IArtifactRepresentation* rep) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void SLANG_MCALL addRepresentationUnknown(ISlangUnknown* rep) SLANG_OVERRIDE;
+ virtual void* SLANG_MCALL SLANG_MCALL findRepresentation(const Guid& guid) SLANG_OVERRIDE;
+ virtual ICastableList* SLANG_MCALL getRepresentations() SLANG_OVERRIDE;
/// Ctor
Artifact(const Desc& desc, const String& name) :
@@ -108,7 +194,10 @@ protected:
String m_name; ///< Name of this artifact
- List<ComPtr<ISlangUnknown>> m_items; ///< Associated items
+ LazyCastableList m_associated; ///< Associated items
+ LazyCastableList m_representations; ///< Representations
+
+ ComPtr<IArtifactList> m_children; ///< The children to this artifact
};
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp
index 9a8194969..7f69a0464 100644
--- a/source/compiler-core/slang-artifact-util.cpp
+++ b/source/compiler-core/slang-artifact-util.cpp
@@ -93,20 +93,16 @@ SlangResult ArtifactUtilImpl::createLockFile(const char* inNameBase, ISlangMutab
SlangResult ArtifactUtilImpl::calcArtifactPath(const ArtifactDesc& desc, const char* inBasePath, ISlangBlob** outPath)
{
UnownedStringSlice basePath(inBasePath);
-
StringBuilder path;
SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, basePath, path));
-
- auto blob = new StringBlob(path);
- blob->addRef();
- *outPath = blob;
+ *outPath = StringBlob::create(path).detach();
return SLANG_OK;
}
SlangResult ArtifactUtilImpl::requireFileDefaultImpl(IArtifact* artifact, ArtifactKeep keep, IFileArtifactRepresentation** outFile)
{
// See if we already have it
- if (auto fileRep = findItem<IFileArtifactRepresentation>(artifact))
+ if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
{
fileRep->addRef();
*outFile = fileRep;
@@ -143,7 +139,7 @@ SlangResult ArtifactUtilImpl::requireFileDefaultImpl(IArtifact* artifact, Artifa
IFileArtifactRepresentation* fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, nullptr);
if (canKeep(keep))
{
- artifact->addItem(fileRep);
+ artifact->addRepresentation(fileRep);
}
// Return it
diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h
index 86b08dbb9..3c991b7b6 100644
--- a/source/compiler-core/slang-artifact.h
+++ b/source/compiler-core/slang-artifact.h
@@ -201,6 +201,7 @@ inline /* static */ArtifactDesc ArtifactDesc::make(Packed inPacked)
// Forward declare
class IFileArtifactRepresentation;
+class IArtifactRepresentation;
// Controls what items can be kept.
enum class ArtifactKeep
@@ -217,6 +218,40 @@ SLANG_INLINE bool canKeep(ArtifactKeep keep) { return Index(keep) >= Index(Artif
/// Returns the keep type for an intermediate
SLANG_INLINE ArtifactKeep getIntermediateKeep(ArtifactKeep keep) { return (keep == ArtifactKeep::All) ? ArtifactKeep::All : ArtifactKeep::No; }
+/* A useful interface for handling lists of castable interfaces. Cannot hold nullptr */
+class ICastableList : public ICastable
+{
+ SLANG_COM_INTERFACE(0x335f3d40, 0x934c, 0x40dc, { 0xb5, 0xe1, 0xf7, 0x6e, 0x40, 0x3, 0x62, 0x5 })
+
+ /// Get the count of all interfaces held in the list
+ virtual Count SLANG_MCALL getCount() = 0;
+ /// Get the interface at the specified index
+ virtual ICastable* SLANG_MCALL getAt(Index i) = 0;
+ /// Add an item to the list
+ virtual void SLANG_MCALL add(ICastable* unk) = 0;
+ /// Add IUnknown, will cast to ICastable and if that's not possible will wrap
+ virtual void SLANG_MCALL addUnknown(ISlangUnknown* unk) = 0;
+ /// Remove item at index, remaining items stay in the same order
+ virtual void SLANG_MCALL removeAt(Index i) = 0;
+ /// Clear the list
+ virtual void SLANG_MCALL clear() = 0;
+ /// Find the first index of castable, or -1 if not found
+ virtual Index SLANG_MCALL indexOf(ICastable* castable) = 0;
+ /// Find the index interface (handling wrapping if necessary)
+ virtual Index SLANG_MCALL indexOfUnknown(ISlangUnknown* unk) = 0;
+ /// Find the first item that casts to non null
+ virtual void* SLANG_MCALL find(const Guid& guid) = 0;
+ /// Access the internal buffer (any mutation can invalidate this value)
+ virtual ICastable*const* SLANG_MCALL getBuffer() = 0;
+};
+
+// Simply finding things in a ICastableList
+template <typename T>
+SLANG_FORCE_INLINE T* find(ICastableList* list)
+{
+ return reinterpret_cast<T*>(list->find(T::getTypeGuid()));
+}
+
/* The IArtifact interface is designed to represent some Artifact of compilation. It could be input to or output from a compilation.
An abstraction is desirable here, because depending on the compiler the artifact/s could be
@@ -286,19 +321,22 @@ public:
/// Get the name of the artifact. This can be empty.
virtual SLANG_NO_THROW const char* SLANG_MCALL getName() = 0;
- /// Find an item by casting it's interface
- virtual SLANG_NO_THROW void* SLANG_MCALL findItemInterface(const Guid& uuid) = 0;
- /// Only works on ICastable derived items. Can find interfaces or objects.
- virtual SLANG_NO_THROW void* SLANG_MCALL findItemObject(const Guid& classGuid) = 0;
-
- /// Add a representation
- virtual SLANG_NO_THROW void SLANG_MCALL addItem(ISlangUnknown* item) = 0;
- /// Get the item at the index
- virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getItemAt(Index i) = 0;
- /// Remove the element at the specified index.
- virtual SLANG_NO_THROW void SLANG_MCALL removeItemAt(Index i) = 0;
- /// Get the amount of elements
- virtual SLANG_NO_THROW Index SLANG_MCALL getItemCount() = 0;
+ /// Add data associated with this artifact
+ virtual SLANG_NO_THROW void SLANG_MCALL addAssociated(ICastable* castable) = 0;
+ /// Find an associated item
+ virtual void* SLANG_MCALL SLANG_MCALL findAssociated(const Guid& unk) = 0;
+ /// TODO(JS): We may want this to return nullptr if it's empty.
+ /// Get the list of associated items
+ virtual ICastableList* SLANG_MCALL getAssociated() = 0;
+
+ /// Add a representation that derives from IArtifactRepresentation
+ virtual SLANG_NO_THROW void SLANG_MCALL addRepresentation(IArtifactRepresentation* rep) = 0;
+ /// Add a representation that doesn't derive from IArtifactRepresentation
+ virtual SLANG_NO_THROW void SLANG_MCALL addRepresentationUnknown(ISlangUnknown* rep) = 0;
+ /// Find representation
+ virtual void* SLANG_MCALL SLANG_MCALL findRepresentation(const Guid& guid) = 0;
+ /// Get the list of all representations
+ virtual ICastableList* SLANG_MCALL getRepresentations() = 0;
};
/* A list of artifacts. */
@@ -336,44 +374,16 @@ class IArtifactRepresentation : public ICastable
/// Convert the instance into a serializable blob.
/// Returns SLANG_E_NOT_IMPLEMENTED if an implementation doesn't implement
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) = 0;
- /// Returns true if this representation exists and is available for use.
+ /// Returns true if this representation exists and is available for use.
virtual SLANG_NO_THROW bool SLANG_MCALL exists() = 0;
};
-/* Interface for types that are associated with an artifact, but aren't a representation, or are
-only part of a representation. */
-class IArtifactAssociated : public ICastable
-{
- SLANG_COM_INTERFACE(0xafc0e4db, 0x16d4, 0x4d7a, { 0x93, 0x5f, 0x3e, 0x47, 0x7a, 0x23, 0x2a, 0x7f })
-};
-
-
-// Helper template to make finding an item more simple
-// There isn't a problem if we only have a forward declaration, because in that case T::getTypeGuid can't work.
-SLANG_FORCE_INLINE void* _findItemImpl(IArtifact* artifact, const Guid& guid, const ISlangUnknown* intf)
-{
- SLANG_UNUSED(intf);
- return artifact->findItemInterface(guid);
-}
-
-SLANG_FORCE_INLINE void* _findItemImpl(IArtifact* artifact, const Guid& guid, const ICastable* castable)
-{
- SLANG_UNUSED(castable);
- return artifact->findItemObject(guid);
-}
-
-SLANG_FORCE_INLINE void* _findItemImpl(IArtifact* artifact, const Guid& guid, const void* other)
-{
- SLANG_UNUSED(other);
- return artifact->findItemObject(guid);
-}
-
template <typename T>
-SLANG_FORCE_INLINE T* findItem(IArtifact* artifact)
+SLANG_FORCE_INLINE T* findRepresentation(IArtifact* artifact)
{
- return (T*)_findItemImpl(artifact, T::getTypeGuid(), (T*)nullptr);
+ return reinterpret_cast<T*>(artifact->findRepresentation(T::getTypeGuid()));
}
} // namespace Slang
diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp
index 2e30c23bc..c492b6dd7 100644
--- a/source/compiler-core/slang-downstream-compiler.cpp
+++ b/source/compiler-core/slang-downstream-compiler.cpp
@@ -387,7 +387,7 @@ SlangResult CommandLineDownstreamCompileResult::getBinary(ComPtr<ISlangBlob>& ou
// Read the contents of the binary
SLANG_RETURN_ON_FAIL(File::readAllBytes(m_moduleFilePath, contents));
- m_binaryBlob = new ScopeRefObjectBlob(ListBlob::moveCreate(contents), m_temporaryFiles);
+ m_binaryBlob = ScopeRefObjectBlob::create(ListBlob::moveCreate(contents), m_temporaryFiles);
outBlob = m_binaryBlob;
return SLANG_OK;
}
diff --git a/source/compiler-core/slang-glslang-compiler.cpp b/source/compiler-core/slang-glslang-compiler.cpp
index fc8beaa48..70743f9d9 100644
--- a/source/compiler-core/slang-glslang-compiler.cpp
+++ b/source/compiler-core/slang-glslang-compiler.cpp
@@ -205,7 +205,7 @@ SlangResult GlslangDownstreamCompiler::compile(const CompileOptions& options, Re
return SLANG_OK;
}
- RefPtr<ListBlob> spirvBlob = ListBlob::moveCreate(spirv);
+ ComPtr<ISlangBlob> spirvBlob = ListBlob::moveCreate(spirv);
outResult = new BlobDownstreamCompileResult(diagnostics, spirvBlob);
return SLANG_OK;
diff --git a/source/compiler-core/slang-nvrtc-compiler.cpp b/source/compiler-core/slang-nvrtc-compiler.cpp
index 11ef746f6..3f285ada2 100644
--- a/source/compiler-core/slang-nvrtc-compiler.cpp
+++ b/source/compiler-core/slang-nvrtc-compiler.cpp
@@ -833,7 +833,7 @@ SlangResult NVRTCDownstreamCompiler::compile(const CompileOptions& options, RefP
res = m_nvrtcCompileProgram(program, int(dstOptions.getCount()), dstOptions.getBuffer());
- RefPtr<ListBlob> blob;
+ ComPtr<ISlangBlob> blob;
DownstreamDiagnostics diagnostics;
diagnostics.result = _asResult(res);
diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp
index 569991508..0da8f6292 100644
--- a/source/core/slang-blob.cpp
+++ b/source/core/slang-blob.cpp
@@ -2,19 +2,76 @@
namespace Slang {
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BlobBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
ISlangUnknown* BlobBase::getInterface(const Guid& guid)
{
- return (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid()) ? static_cast<ISlangBlob*>(this) : nullptr;
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ISlangBlob::getTypeGuid())
+ {
+ return static_cast<ISlangBlob*>(this);
+ }
+ if (guid == ICastable::getTypeGuid())
+ {
+ return static_cast<ICastable*>(this);
+ }
+ return nullptr;
+}
+
+void* BlobBase::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
}
+void* BlobBase::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StaticBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject)
{
- if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid())
+ if (auto intf = getInterface(guid))
{
- *outObject = static_cast<ISlangBlob*>(this);
+ *outObject = intf;
return SLANG_OK;
}
return SLANG_E_NO_INTERFACE;
}
-
+
+void* StaticBlob::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+ISlangUnknown* StaticBlob::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ISlangBlob::getTypeGuid())
+ {
+ return static_cast<ISlangBlob*>(this);
+ }
+ if (guid == ICastable::getTypeGuid())
+ {
+ return static_cast<ICastable*>(this);
+ }
+ return nullptr;
+}
+
+void* StaticBlob::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
} // namespace Slang
diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h
index 58984471f..b1384bb2c 100644
--- a/source/core/slang-blob.h
+++ b/source/core/slang-blob.h
@@ -11,22 +11,31 @@
#include "../../slang-com-helper.h"
#include "../../slang-com-ptr.h"
+#include "../core/slang-com-object.h"
+
namespace Slang {
/** Base class for simple blobs.
*/
-class BlobBase : public ISlangBlob, public RefObject
+class BlobBase : public ISlangBlob, public ICastable, public ComBaseObject
{
public:
// ISlangUnknown
- SLANG_REF_OBJECT_IUNKNOWN_ALL
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
protected:
ISlangUnknown* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
};
/** A blob that uses a `String` for its storage.
NOTE! Returns length *WITHOUT* terminating 0, even though there is one.
+
+NOTE! Whilst BobBase is atomic ref counted, the contained string *is not*.
+There is a reasonable argument that StringBlob should contain it's own copy of the string contents.
*/
class StringBlob : public BlobBase
{
@@ -35,14 +44,16 @@ public:
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_string.getBuffer(); }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_string.getLength(); }
- /// Get the contained string
- SLANG_FORCE_INLINE const String& getString() const { return m_string; }
+ static ComPtr<ISlangBlob> create(const String& in) { return ComPtr<ISlangBlob>(new StringBlob(in)); }
+protected:
explicit StringBlob(String const& string)
: m_string(string)
{}
-protected:
+ /// Get the contained string
+ SLANG_FORCE_INLINE const String& getString() const { return m_string; }
+
String m_string;
};
@@ -56,21 +67,20 @@ public:
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getBuffer(); }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getCount(); }
- ListBlob() {}
+ static ComPtr<ISlangBlob> create(const List<uint8_t>& data) { return ComPtr<ISlangBlob>(new ListBlob(data)); }
+
+ static ComPtr<ISlangBlob> moveCreate(List<uint8_t>& data) { return ComPtr<ISlangBlob>(new ListBlob(_Move(data))); }
- ListBlob(const List<uint8_t>& data): m_data(data) {}
+protected:
+ explicit ListBlob(const List<uint8_t>& data) : m_data(data) {}
// Move ctor
- ListBlob(List<uint8_t>&& data): m_data(data) {}
+ explicit ListBlob(List<uint8_t>&& data) : m_data(data) {}
- static RefPtr<ListBlob> moveCreate(List<uint8_t>& data) { return new ListBlob(_Move(data)); }
+ void operator=(const ThisType& rhs) = delete;
List<uint8_t> m_data;
-
-protected:
- void operator=(const ThisType& rhs) = delete;
};
-
class ScopedAllocation
{
public:
@@ -172,29 +182,35 @@ public:
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getData(); }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getSizeInBytes(); }
- // Ctor
- // NOTE! Takes a copy of the input data
- RawBlob(const void* data, size_t size)
- {
- memcpy(m_data.allocate(size), data, size);
- }
-
/// Moves ownership of data and dataCount to the blob
/// data must be a pointer returned by ::malloc.
- static RefPtr<RawBlob> moveCreate(uint8_t* data, size_t dataCount)
+ static ComPtr<ISlangBlob> moveCreate(uint8_t* data, size_t dataCount)
{
RawBlob* blob = new RawBlob;
blob->m_data.attach(data, dataCount);
- return blob;
+ return ComPtr<ISlangBlob>(blob);
}
- static RefPtr<RawBlob> moveCreate(ScopedAllocation& alloc)
+ static ComPtr<ISlangBlob> moveCreate(ScopedAllocation& alloc)
{
RawBlob* blob = new RawBlob;
blob->m_data.swap(alloc);
- return blob;
+ return ComPtr<ISlangBlob>(blob);
+ }
+
+ /// Create a blob that will retain (a copy of) raw data.
+ static inline ComPtr<ISlangBlob> create(void const* inData, size_t size)
+ {
+ return ComPtr<ISlangBlob>(new RawBlob(inData, size));
}
protected:
+ // Ctor
+ // NOTE! Takes a copy of the input data
+ RawBlob(const void* data, size_t size)
+ {
+ memcpy(m_data.allocate(size), data, size);
+ }
+
RawBlob() = default;
ScopedAllocation m_data;
@@ -208,14 +224,19 @@ public:
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data; }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_dataSizeInBytes; }
+ static inline ComPtr<ISlangBlob> create(void const* inData, size_t size)
+ {
+ return ComPtr<ISlangBlob>(new UnownedRawBlob(inData, size));
+ }
+
+protected:
// Ctor
- UnownedRawBlob(const void* data, size_t size):
+ UnownedRawBlob(const void* data, size_t size) :
m_data(data),
m_dataSizeInBytes(size)
{
}
-protected:
UnownedRawBlob() = default;
const void* m_data;
@@ -226,7 +247,7 @@ protected:
The memory it references is *not* owned by the blob.
This is useful when a Blob is useful to represent some global immutable chunk of memory.
*/
-class StaticBlob : public ISlangBlob
+class StaticBlob : public ISlangBlob, public ICastable
{
public:
@@ -235,6 +256,9 @@ public:
SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
+
// ISlangBlob
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data; }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_dataCount; }
@@ -246,17 +270,13 @@ public:
}
protected:
+ ISlangUnknown* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
const void* m_data;
size_t m_dataCount;
};
-/// Create a blob that will retain (a copy of) raw data.
-///
-inline ComPtr<ISlangBlob> createRawBlob(void const* inData, size_t size)
-{
- return ComPtr<ISlangBlob>(new RawBlob(inData, size));
-}
-
class ScopeRefObjectBlob : public BlobBase
{
public:
@@ -264,14 +284,22 @@ public:
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_blob->getBufferPointer(); }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_blob->getBufferSize(); }
+ static inline ComPtr<ISlangBlob> create(ISlangBlob* blob, RefObject* scope)
+ {
+ return ComPtr<ISlangBlob>(new ScopeRefObjectBlob(blob, scope));
+ }
+
+protected:
+
// Ctor
+
ScopeRefObjectBlob(ISlangBlob* blob, RefObject* scope) :
m_blob(blob),
m_scope(scope)
{
}
-protected:
+
RefPtr<RefObject> m_scope;
ComPtr<ISlangBlob> m_blob;
};
diff --git a/source/core/slang-destroyable.h b/source/core/slang-destroyable.h
index 343cc2484..bf373ba33 100644
--- a/source/core/slang-destroyable.h
+++ b/source/core/slang-destroyable.h
@@ -9,16 +9,13 @@
namespace Slang
{
-/* An interface to provide a mechanism to cast, that doesn't require ref counting
-and doesn't have to return a pointer to a ISlangUnknown derived class */
-class ICastable : public ISlangUnknown
+/* Adapter interface to make a non castable type work as ICastable */
+class IUnknownCastableAdapter : public ICastable
{
- SLANG_COM_INTERFACE(0x87ede0e1, 0x4852, 0x44b0, { 0x8b, 0xf2, 0xcb, 0x31, 0x87, 0x4d, 0xe2, 0x39 } );
+ SLANG_COM_INTERFACE(0x8b4aad81, 0x4934, 0x4a67, { 0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54 } );
- /// Can be used to cast to interfaces without reference counting.
- /// Also provides access to internal implementations, when they provide a guid
- /// Can simulate a 'generated' interface as long as kept in scope by cast from.
- virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) = 0;
+ /// When using the adapter, this provides a way to directly get the internal no ICastable type
+ virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() = 0;
};
/* An interface that allows for an object to implement 'destruction'. A destroyed
diff --git a/source/core/slang-file-system.cpp b/source/core/slang-file-system.cpp
index 52ec40c07..6d9ad4324 100644
--- a/source/core/slang-file-system.cpp
+++ b/source/core/slang-file-system.cpp
@@ -608,13 +608,14 @@ SlangResult CacheFileSystem::loadFile(char const* pathIn, ISlangBlob** blobOut)
SlangResult CacheFileSystem::getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity)
{
+ *outUniqueIdentity = nullptr;
PathInfo* info = _resolvePathCacheInfo(path);
- if (!info)
+ if (!info || info->m_uniqueIdentity.getLength() <= 0)
{
return SLANG_E_NOT_FOUND;
}
- info->m_uniqueIdentity->addRef();
- *outUniqueIdentity = info->m_uniqueIdentity;
+
+ *outUniqueIdentity = StringBlob::create(info->m_uniqueIdentity).detach();
return SLANG_OK;
}
@@ -694,6 +695,8 @@ SlangResult CacheFileSystem::getSimplifiedPath(const char* path, ISlangBlob** ou
SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath)
{
+ *outCanonicalPath = nullptr;
+
// A file must exist to get a canonical path...
PathInfo* info = _resolvePathCacheInfo(path);
if (!info)
@@ -716,12 +719,8 @@ SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** out
if (SLANG_SUCCEEDED(res))
{
// Get the path as a string
- String canonicalPath = StringUtil::getString(canonicalPathBlob);
- if (canonicalPath.getLength() > 0)
- {
- info->m_canonicalPath = new StringBlob(canonicalPath);
- }
- else
+ info->m_canonicalPath = StringUtil::getString(canonicalPathBlob);
+ if (info->m_canonicalPath.getLength() <= 0)
{
res = SLANG_FAIL;
}
@@ -731,11 +730,12 @@ SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** out
info->m_getCanonicalPathResult = toCompressedResult(res);
}
- if (info->m_canonicalPath)
+ // Create the blob
+ if (info->m_canonicalPath.getLength())
{
- info->m_canonicalPath->addRef();
+ *outCanonicalPath = StringBlob::create(info->m_canonicalPath).detach();
}
- *outCanonicalPath = info->m_canonicalPath;
+
return SLANG_OK;
}
diff --git a/source/core/slang-file-system.h b/source/core/slang-file-system.h
index 8a9cfb811..3df05b6e1 100644
--- a/source/core/slang-file-system.h
+++ b/source/core/slang-file-system.h
@@ -113,10 +113,9 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
struct PathInfo
{
- PathInfo(const String& uniqueIdentity)
+ PathInfo(const String& uniqueIdentity):
+ m_uniqueIdentity(uniqueIdentity)
{
- m_uniqueIdentity = new StringBlob(uniqueIdentity);
-
m_loadFileResult = CompressedResult::Uninitialized;
m_getPathTypeResult = CompressedResult::Uninitialized;
m_getCanonicalPathResult = CompressedResult::Uninitialized;
@@ -125,16 +124,16 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject
}
/// Get the unique identity path as a string
- const String& getUniqueIdentity() const { SLANG_ASSERT(m_uniqueIdentity); return m_uniqueIdentity->getString(); }
+ const String& getUniqueIdentity() const { return m_uniqueIdentity; }
- RefPtr<StringBlob> m_uniqueIdentity;
+ String m_uniqueIdentity;
CompressedResult m_loadFileResult;
CompressedResult m_getPathTypeResult;
CompressedResult m_getCanonicalPathResult;
SlangPathType m_pathType;
ComPtr<ISlangBlob> m_fileBlob;
- RefPtr<StringBlob> m_canonicalPath;
+ String m_canonicalPath;
};
Dictionary<String, PathInfo*>& getPathMap() { return m_pathMap; }
diff --git a/source/core/slang-riff-file-system.cpp b/source/core/slang-riff-file-system.cpp
index d52015fb3..186650ed3 100644
--- a/source/core/slang-riff-file-system.cpp
+++ b/source/core/slang-riff-file-system.cpp
@@ -215,7 +215,7 @@ SlangResult RiffFileSystem::saveFile(const char* path, const void* data, size_t
else
{
// Just store the data directly.
- contents = new RawBlob(data, size);
+ contents = RawBlob::create(data, size);
}
Entry* entry = _getEntryFromCanonicalPath(canonicalPath);
@@ -376,7 +376,7 @@ SlangResult RiffFileSystem::loadArchive(const void* archive, size_t archiveSizeI
}
// Get the compressed data
- dstEntry->m_contents = new RawBlob(srcData, srcEntry->compressedSize);
+ dstEntry->m_contents = RawBlob::create(srcData, srcEntry->compressedSize);
break;
}
case SLANG_PATH_TYPE_DIRECTORY: break;
@@ -444,10 +444,10 @@ SlangResult RiffFileSystem::storeArchive(bool blobOwnsContent, ISlangBlob** outB
// We now write the RiffContainer to the stream
SLANG_RETURN_ON_FAIL(RiffUtil::write(container.getRoot(), true, &stream));
- RefPtr<ListBlob> blob = new ListBlob;
- stream.swapContents(blob->m_data);
+ List<uint8_t> data;
+ stream.swapContents(data);
- *outBlob = blob.detach();
+ *outBlob = ListBlob::moveCreate(data).detach();
return SLANG_OK;
}
diff --git a/source/core/slang-shared-library.cpp b/source/core/slang-shared-library.cpp
index 6ce10ad9e..0e4f0ee73 100644
--- a/source/core/slang-shared-library.cpp
+++ b/source/core/slang-shared-library.cpp
@@ -62,7 +62,7 @@ SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(const char* pa
}
}
-/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+/* !!!!!!!!!!!!!!!!!!!!!!!!!! TemporarySharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
TemporarySharedLibrary::~TemporarySharedLibrary()
{
@@ -76,38 +76,50 @@ TemporarySharedLibrary::~TemporarySharedLibrary()
/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-SLANG_NO_THROW SlangResult SLANG_MCALL DefaultSharedLibrary::queryInterface(SlangUUID const& uuid, void** outObject)
+DefaultSharedLibrary::~DefaultSharedLibrary()
{
- // Mechanism to cast to underlying type.
- // NOTE! Purposefully does not ref count
- if (uuid == DefaultSharedLibrary::getTypeGuid())
+ if (m_sharedLibraryHandle)
{
- *outObject = this;
- return SLANG_OK;
+ SharedLibrary::unload(m_sharedLibraryHandle);
}
+}
+
+void* DefaultSharedLibrary::findSymbolAddressByName(char const* name)
+{
+ return SharedLibrary::findSymbolAddressByName(m_sharedLibraryHandle, name);
+}
- if (uuid == ISlangUnknown::getTypeGuid() || uuid == ISlangSharedLibrary::getTypeGuid())
+void* DefaultSharedLibrary::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
{
- ++m_refCount;
- *outObject = static_cast<ISlangSharedLibrary*>(this);
- return SLANG_OK;
+ return intf;
}
- return SLANG_E_NO_INTERFACE;
+ return getObject(guid);
}
-DefaultSharedLibrary::~DefaultSharedLibrary()
+void* DefaultSharedLibrary::getInterface(const Guid& guid)
{
- if (m_sharedLibraryHandle)
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == ISlangSharedLibrary::getTypeGuid())
{
- SharedLibrary::unload(m_sharedLibraryHandle);
+ return static_cast<ISlangSharedLibrary*>(this);
}
+ return nullptr;
}
-void* DefaultSharedLibrary::findSymbolAddressByName(char const* name)
+void* DefaultSharedLibrary::getObject(const Guid& guid)
{
- return SharedLibrary::findSymbolAddressByName(m_sharedLibraryHandle, name);
+ if (guid == DefaultSharedLibrary::getTypeGuid())
+ {
+ return this;
+ }
+ return nullptr;
}
+/* !!!!!!!!!!!!!!!!!!!!!!!!!! SharedLibraryUtils !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+
String SharedLibraryUtils::getSharedLibraryFileName(void* symbolInLib)
{
#if defined(_WIN32)
diff --git a/source/core/slang-shared-library.h b/source/core/slang-shared-library.h
index 44adb1ac6..c0074bad3 100644
--- a/source/core/slang-shared-library.h
+++ b/source/core/slang-shared-library.h
@@ -52,10 +52,9 @@ class DefaultSharedLibrary : public ISlangSharedLibrary, public ComBaseObject
SLANG_CLASS_GUID(0xe7f2597b, 0xf803, 0x4b6e, { 0xaf, 0x8b, 0xcb, 0xe3, 0xa2, 0x21, 0xfd, 0x5a })
// ISlangUnknown
- SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
- SLANG_COM_BASE_IUNKNOWN_ADD_REF
- SLANG_COM_BASE_IUNKNOWN_RELEASE
-
+ SLANG_COM_BASE_IUNKNOWN_ALL
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangSharedLibrary
virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE;
@@ -71,6 +70,9 @@ class DefaultSharedLibrary : public ISlangSharedLibrary, public ComBaseObject
protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
SharedLibrary::Handle m_sharedLibraryHandle = nullptr;
};
diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp
index c4b654072..a1f310401 100644
--- a/source/core/slang-string-util.cpp
+++ b/source/core/slang-string-util.cpp
@@ -319,7 +319,7 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
ComPtr<ISlangBlob> StringUtil::createStringBlob(const String& string)
{
- return ComPtr<ISlangBlob>(new StringBlob(string));
+ return StringBlob::create(string);
}
/* static */String StringUtil::calcCharReplaced(const UnownedStringSlice& slice, char fromChar, char toChar)
diff --git a/source/core/slang-zip-file-system.cpp b/source/core/slang-zip-file-system.cpp
index 1ed003d55..ce25066df 100644
--- a/source/core/slang-zip-file-system.cpp
+++ b/source/core/slang-zip-file-system.cpp
@@ -709,12 +709,12 @@ SlangResult ZipFileSystemImpl::storeArchive(bool blobOwnsContent, ISlangBlob** o
if (blobOwnsContent)
{
// Takes a copy
- blob = new RawBlob(m_data.getData(), Index(m_data.getSizeInBytes()));
+ blob = RawBlob::create(m_data.getData(), Index(m_data.getSizeInBytes()));
}
else
{
// Doesn't take a copy... Must use with care(!)
- blob = new UnownedRawBlob(m_data.getData(), Index(m_data.getSizeInBytes()));
+ blob = UnownedRawBlob::create(m_data.getData(), Index(m_data.getSizeInBytes()));
}
*outBlob = blob.detach();
return SLANG_OK;
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 361f92525..17785bdc6 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -55,6 +55,52 @@
namespace Slang
{
+ // A temporary class that adapts `ISlangSharedLibrary_Dep1` to ISlangSharedLibrary
+
+ class SharedLibraryDep1Adapter : public ComBaseObject, public ISlangSharedLibrary
+ {
+ public:
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
+
+ // ISlangSharedLibrary
+ virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE { return m_contained->findSymbolAddressByName(name); }
+
+ SharedLibraryDep1Adapter(ISlangSharedLibrary_Dep1* dep1):
+ m_contained(dep1)
+ {
+ }
+
+ protected:
+ void* getInterface(const Guid& guid)
+ {
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == ISlangSharedLibrary::getTypeGuid())
+ {
+ return static_cast<ISlangSharedLibrary*>(this);
+ }
+ return nullptr;
+ }
+ void* getObject(const Guid& guid)
+ {
+ SLANG_UNUSED(guid);
+ return nullptr;
+ }
+
+ ComPtr<ISlangSharedLibrary_Dep1> m_contained;
+ };
+
+ void* SharedLibraryDep1Adapter::castAs(const SlangUUID& guid)
+ {
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+ }
// !!!!!!!!!!!!!!!!!!!!!! free functions for DiagnosicSink !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -81,7 +127,24 @@ namespace Slang
{
if (downstreamResult)
{
- return downstreamResult->getHostCallableSharedLibrary(outSharedLibrary);
+ // TODO(JS): Work around for not knowing actual interface this is returning,
+ // and needing to support deps interface
+
+ ComPtr<ISlangSharedLibrary> lib;
+ SLANG_RETURN_ON_FAIL(downstreamResult->getHostCallableSharedLibrary(lib));
+
+ if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary::getTypeGuid(), (void**)outSharedLibrary.writeRef())))
+ {
+ return SLANG_OK;
+ }
+
+ ComPtr<ISlangSharedLibrary_Dep1> libDep1;
+ if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary_Dep1::getTypeGuid(), (void**)libDep1.writeRef())))
+ {
+ // Okay, we need to adapt for now
+ outSharedLibrary = new SharedLibraryDep1Adapter(libDep1);
+ return SLANG_OK;
+ }
}
return SLANG_FAIL;
}
@@ -1304,8 +1367,9 @@ namespace Slang
// Set up the library artifact
ComPtr<IArtifact> artifact(new Artifact(ArtifactDesc::make(ArtifactKind::Library, Artifact::Payload::HostCPU), "slang-rt"));
+
ComPtr<IFileArtifactRepresentation> fileRep(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, "slang-rt", nullptr, nullptr));
- artifact->addItem(fileRep);
+ artifact->addRepresentation(fileRep);
options.libraries.add(artifact);
}
@@ -2122,10 +2186,10 @@ namespace Slang
}
// Need to turn into a blob
- RefPtr<ListBlob> blob(new ListBlob);
- // Swap the streams contents into the blob
- stream.swapContents(blob->m_data);
- m_containerBlob = blob;
+ List<uint8_t> blobData;
+ stream.swapContents(blobData);
+
+ m_containerBlob = ListBlob::moveCreate(blobData);
return res;
}
diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp
index 636a32a4d..6667a6d9d 100644
--- a/source/slang/slang-ir-link.cpp
+++ b/source/slang/slang-ir-link.cpp
@@ -1411,8 +1411,7 @@ LinkedIR linkIR(
});
for (IArtifact* artifact : linkage->m_libModules)
{
- ModuleLibrary* library = (ModuleLibrary*)artifact->findItemObject(ModuleLibrary::getTypeGuid());
- if (library)
+ if (auto library = findRepresentation<ModuleLibrary>(artifact))
{
irModules.addRange(library->m_modules.getBuffer()->readRef(), library->m_modules.getCount());
}
diff --git a/source/slang/slang-module-library.cpp b/source/slang/slang-module-library.cpp
index b60555766..75450d7b3 100644
--- a/source/slang/slang-module-library.cpp
+++ b/source/slang/slang-module-library.cpp
@@ -91,7 +91,7 @@ SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCo
SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCompileRequest* req, RefPtr<ModuleLibrary>& outLibrary)
{
- if (auto foundLibrary = (ModuleLibrary*)artifact->findItemObject(ModuleLibrary::getTypeGuid()))
+ if (auto foundLibrary = findRepresentation<ModuleLibrary>(artifact))
{
outLibrary = foundLibrary;
return SLANG_OK;
@@ -107,7 +107,7 @@ SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCo
if (canKeep(keep))
{
- artifact->addItem(library);
+ artifact->addRepresentation(library);
}
outLibrary = library;
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index 5b14ca24f..6351ffbd4 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -1506,7 +1506,7 @@ struct OptionsParser
return SLANG_FAIL;
}
}
- artifact->addItem(fileRep);
+ artifact->addRepresentation(fileRep);
SLANG_RETURN_ON_FAIL(_addLibraryReference(requestImpl, artifact));
}
diff --git a/source/slang/slang-repro.cpp b/source/slang/slang-repro.cpp
index ad275ee7b..ad1bc25fc 100644
--- a/source/slang/slang-repro.cpp
+++ b/source/slang/slang-repro.cpp
@@ -249,15 +249,15 @@ struct StoreContext
base[fileState]->contents = offsetContents;
}
- if (srcPathInfo->m_canonicalPath && base[fileState]->canonicalPath.isNull())
+ if (srcPathInfo->m_canonicalPath.getLength() && base[fileState]->canonicalPath.isNull())
{
- auto offsetCanonicalPath = fromString(srcPathInfo->m_canonicalPath->getString());
+ auto offsetCanonicalPath = fromString(srcPathInfo->m_canonicalPath);
base[fileState]->canonicalPath = offsetCanonicalPath;
}
- if (srcPathInfo->m_uniqueIdentity && base[fileState]->uniqueIdentity.isNull())
+ if (srcPathInfo->m_uniqueIdentity.getLength() && base[fileState]->uniqueIdentity.isNull())
{
- auto offsetUniqueIdentity = fromString(srcPathInfo->m_uniqueIdentity->getString());
+ auto offsetUniqueIdentity = fromString(srcPathInfo->m_uniqueIdentity);
base[fileState]->uniqueIdentity = offsetUniqueIdentity;
}
}
@@ -668,20 +668,19 @@ struct LoadContext
// If wasn't loaded, and has contents, use that
if (!blob && file->contents)
{
- blob = new StringBlob(m_base->asRaw(file->contents)->getSlice());
+ blob = StringBlob::create(m_base->asRaw(file->contents)->getSlice());
}
dstInfo = new CacheFileSystem::PathInfo(String());
if (file->uniqueIdentity)
{
- String uniqueIdentity = m_base->asRaw(file->uniqueIdentity)->getSlice();
- dstInfo->m_uniqueIdentity = new StringBlob(uniqueIdentity);
+ dstInfo->m_uniqueIdentity = m_base->asRaw(file->uniqueIdentity)->getSlice();
}
if (file->canonicalPath)
{
- dstInfo->m_canonicalPath = new StringBlob(m_base->asRaw(file->canonicalPath)->getSlice());
+ dstInfo->m_canonicalPath = m_base->asRaw(file->canonicalPath)->getSlice();
}
if (blob)
@@ -865,13 +864,13 @@ struct LoadContext
for (const auto& pair : context.m_fileToPathInfoMap)
{
CacheFileSystem::PathInfo* pathInfo = pair.Value;
- SLANG_ASSERT(pathInfo->m_uniqueIdentity);
- dstUniqueMap.Add(pathInfo->m_uniqueIdentity->getString(), pathInfo);
+ SLANG_ASSERT(pathInfo->m_uniqueIdentity.getLength());
+ dstUniqueMap.Add(pathInfo->m_uniqueIdentity, pathInfo);
// Add canonical paths too..
- if (pathInfo->m_canonicalPath)
+ if (pathInfo->m_canonicalPath.getLength())
{
- String canonicalPath = pathInfo->m_canonicalPath->getString();
+ String canonicalPath = pathInfo->m_canonicalPath;
dstPathMap.AddIfNotExists(canonicalPath, pathInfo);
}
@@ -1050,8 +1049,8 @@ struct LoadContext
for (const auto& pair : context.m_fileToPathInfoMap)
{
CacheFileSystem::PathInfo* pathInfo = pair.Value;
- SLANG_ASSERT(pathInfo->m_uniqueIdentity);
- dstUniqueMap.Add(pathInfo->m_uniqueIdentity->getString(), pathInfo);
+ SLANG_ASSERT(pathInfo->m_uniqueIdentity.getLength());
+ dstUniqueMap.Add(pathInfo->m_uniqueIdentity, pathInfo);
}
}
diff --git a/source/slang/slang-workspace-version.cpp b/source/slang/slang-workspace-version.cpp
index 2451290f5..ebfe9218a 100644
--- a/source/slang/slang-workspace-version.cpp
+++ b/source/slang/slang-workspace-version.cpp
@@ -330,8 +330,7 @@ SlangResult Workspace::loadFile(const char* path, ISlangBlob** outBlob)
RefPtr<DocumentVersion> doc;
if (openedDocuments.TryGetValue(canonnicalPath, doc))
{
- RefPtr<StringBlob> stringBlob = new StringBlob(doc->getText());
- *outBlob = stringBlob.detach();
+ *outBlob = StringBlob::create(doc->getText()).detach();
return SLANG_OK;
}
return Slang::OSFileSystem::getExtSingleton()->loadFile(path, outBlob);
@@ -479,7 +478,8 @@ Module* WorkspaceVersion::getOrLoadModule(String path)
if (!doc)
return nullptr;
ComPtr<ISlangBlob> diagnosticBlob;
- RefPtr<StringBlob> sourceBlob = new StringBlob((*doc)->getText());
+ auto sourceBlob = StringBlob::create((*doc)->getText());
+
auto moduleName = getMangledNameFromNameString(path.getUnownedSlice());
linkage->contentAssistInfo.primaryModuleName = linkage->getNamePool()->getName(moduleName);
linkage->contentAssistInfo.primaryModulePath = path;
@@ -494,7 +494,7 @@ Module* WorkspaceVersion::getOrLoadModule(String path)
auto parsedModule = linkage->loadModuleFromSource(
moduleName.getBuffer(),
path.getBuffer(),
- sourceBlob.Ptr(),
+ sourceBlob,
diagnosticBlob.writeRef());
if (parsedModule)
{
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index f74a4a5d6..684b0660d 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -4515,8 +4515,7 @@ SlangResult EndToEndCompileRequest::addLibraryReference(const void* libData, siz
// Create an artifact without any name (as one is not provided)
ComPtr<IArtifact> artifact(new Artifact(desc, String()));
-
- artifact->addItem(library);
+ artifact->addRepresentation(library);
return _addLibraryReference(this, artifact);
}
@@ -4929,12 +4928,12 @@ SlangResult EndToEndCompileRequest::saveRepro(ISlangBlob** outBlob)
SLANG_RETURN_ON_FAIL(ReproUtil::saveState(this, &stream));
- RefPtr<ListBlob> listBlob(new ListBlob);
-
// Put the content of the stream in the blob
- stream.swapContents(listBlob->m_data);
- *outBlob = listBlob.detach();
+ List<uint8_t> data;
+ stream.swapContents(data);
+
+ *outBlob = ListBlob::moveCreate(data).detach();
return SLANG_OK;
}