summaryrefslogtreecommitdiffstats
path: root/source/compiler-core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-10 10:04:06 -0400
committerGitHub <noreply@github.com>2022-08-10 10:04:06 -0400
commit1378fffd9da094beb41b2db89b96f556c23ab6cb (patch)
treee0558c031bd4b1a013dc56b75c4caa3ff5442021 /source/compiler-core
parent89083c4b50af8e48e70b25b63cc62aca21ab706c (diff)
Artifact and ICastable (#2351)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP with hierarchical enums. * Some small fixes and improvements around artifact desc related types. * Improvements around hierarchical enum. * Fixes to get Artifact types refactor to be able to execute tests. * Attempt to better categorize PTX. * Work around for potentially unused function warning. * Typo fix. * Simplify Artifact header. * Small improvements around Artifact kind/payload/style. * Added IDestroyable/ICastable * Add IArtifactList. * First impl of IArtifactUtil. * Use the ICastable interface for IArtifactRepresentation. * Added IArtifactRepresentation & IArtifactAssociated. * Add SLANG_OVERRIDE to avoid gcc/clang warning. * Fix calling convention issue on win32. * Fix missing SLANG_OVERRIDE. * First attempt at file abstraction around Artifact. * Added creation of lock file. * Move functionality for determining file paths to the IArtifactUtil. Add casting to ICastable. * Added some casting/finding mechanisms. * Simplify IArtifact interface, and use Items for file reps. * Fix problem with libraries on DXIL. * Split out ArtifactRepresentation. * Move ArtifactDesc functionality to ArtifactDescUtil. ArtifactInfoUtil becomes ArtifactDescUtil. * Split implementations from the interfaces for Artifact. * Use TypeTextUtil for target name outputting. * Add artifact impls. * Add ICastableList * Added UnknownCastableAdapter * Make ISlangSharedLibrary derive from ICastable, and remain backwards compatible with slang-llvm. * Refactor Representation on Artifact. * Make our ISlangBlobs also derive from ICastable. Make ISlangBlob atomic ref counted. * Fix typo.
Diffstat (limited to 'source/compiler-core')
-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
8 files changed, 597 insertions, 141 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);