summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-16 03:39:41 -0400
committerGitHub <noreply@github.com>2022-08-16 00:39:41 -0700
commitac71724c03392b429e44641a3641b2bcf7cc55fc (patch)
tree8f7ffa61329dd24bc9be551e293840b6b94aab36
parent786f48d32340c36a06865a333ff9066033b5b2bc (diff)
Remove CompileResult to use IArtifact (#2357)
* #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. * Split out CastableList and related types, and placed in core. * Small fixes around IArtifact. Improve IArtifact docs. First impl of getChildren for IArtifact. * Documentation improvements for Artifact related types. * Fix typo. * Special case adding a ICastableList to a LazyCastableList. * Small simplification of LazyCastableList, by adding State member. * Removed the ILockFile interface because IFileArtifactRepresentation can be used. * Implement DiagnosticsArtifactRepresentation. * Added PostEmitMetadataArtifactRepresentation * Add searching by predicate. Added handling of accessing Artifact as ISharedLibrary * Fix typo. * Add find to IArtifacgtList. Fix some missing SLANG_NO_THROW. * Small improvements around ArtifactDesc types. * Another small change around ArtifactKind. * Some more shuffling of ArtifactDesc. * Make IArtifact castable Remove IArtifactList Made IArtifactContainer derive from IArtifact Made ModuleLibrary atomic ref counted/given IModuleLibrary interface. * Must call _requireChildren before any children access. * Fix missing SLANG_MCALL on castAs. * Fix missing SLANG_OVERRIDE. * Added IArtifactHandler * Use ICastable for basis of scope/lookup. * WIP first attempt to remove CompileResult. * Fix support for for downstream compiler shared library adapter. * Fix issues found when replacing CompileResult. * Fix typo. * Fix getting items form 'significant' member of an Artifact. * Split out ArtifactUtil & ArtifactHandler. * Work around for problem on Visual studio. * Improve searching. * Add missing files.
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj4
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj.filters12
-rw-r--r--source/compiler-core/slang-artifact-desc-util.cpp33
-rw-r--r--source/compiler-core/slang-artifact-desc-util.h22
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.cpp380
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.h45
-rw-r--r--source/compiler-core/slang-artifact-helper.cpp124
-rw-r--r--source/compiler-core/slang-artifact-helper.h84
-rw-r--r--source/compiler-core/slang-artifact-impl.cpp125
-rw-r--r--source/compiler-core/slang-artifact-impl.h26
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.cpp52
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.h43
-rw-r--r--source/compiler-core/slang-artifact-util.cpp396
-rw-r--r--source/compiler-core/slang-artifact-util.h107
-rw-r--r--source/compiler-core/slang-artifact.h35
-rw-r--r--source/compiler-core/slang-downstream-compiler.h3
-rw-r--r--source/compiler-core/slang-dxc-compiler.cpp4
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.cpp3
-rw-r--r--source/compiler-core/slang-visual-studio-compiler-util.cpp4
-rw-r--r--source/slang/slang-compiler.cpp513
-rwxr-xr-xsource/slang/slang-compiler.h46
-rw-r--r--source/slang/slang-emit.cpp57
-rw-r--r--source/slang/slang-ir-link.h2
-rw-r--r--source/slang/slang-ir-metadata.cpp2
-rw-r--r--source/slang/slang.cpp135
25 files changed, 1364 insertions, 893 deletions
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj b/build/visual-studio/compiler-core/compiler-core.vcxproj
index 7e6d7540a..bf51fc974 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj
@@ -275,6 +275,8 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\source\compiler-core\slang-artifact-desc-util.h" />
+ <ClInclude Include="..\..\..\source\compiler-core\slang-artifact-handler-impl.h" />
+ <ClInclude Include="..\..\..\source\compiler-core\slang-artifact-helper.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-artifact-impl.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-artifact-representation-impl.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-artifact-representation.h" />
@@ -315,6 +317,8 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\source\compiler-core\slang-artifact-desc-util.cpp" />
+ <ClCompile Include="..\..\..\source\compiler-core\slang-artifact-handler-impl.cpp" />
+ <ClCompile Include="..\..\..\source\compiler-core\slang-artifact-helper.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-artifact-impl.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-artifact-representation-impl.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-artifact-util.cpp" />
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
index bbaa0a423..425c1af21 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
@@ -12,6 +12,12 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-artifact-desc-util.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\compiler-core\slang-artifact-handler-impl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\source\compiler-core\slang-artifact-helper.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\compiler-core\slang-artifact-impl.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -128,6 +134,12 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-artifact-desc-util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\compiler-core\slang-artifact-handler-impl.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\source\compiler-core\slang-artifact-helper.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\compiler-core\slang-artifact-impl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp
index 314703c0b..2c2b177c2 100644
--- a/source/compiler-core/slang-artifact-desc-util.cpp
+++ b/source/compiler-core/slang-artifact-desc-util.cpp
@@ -122,7 +122,7 @@ struct HierarchicalEnumTable
return true;
}
type = m_parents[Index(type)];
- } while (Index(type) > Index(T::Base));
+ } while (Index(type) >= Index(T::Base));
return false;
}
@@ -620,31 +620,6 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des
return getBaseNameFromPath(desc, path);
}
-/* static */String ArtifactDescUtil::getBaseName(IArtifact* artifact)
-{
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
- {
- return getBaseName(artifact->getDesc(), fileRep);
- }
- // Else use the name
- return artifact->getName();
-}
-
-/* static */String ArtifactDescUtil::getParentPath(IFileArtifactRepresentation* fileRep)
-{
- UnownedStringSlice path(fileRep->getPath());
- return Path::getParentDirectory(path);
-}
-
-/* static */String ArtifactDescUtil::getParentPath(IArtifact* artifact)
-{
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
- {
- return getParentPath(fileRep);
- }
- return String();
-}
-
/* static */SlangResult ArtifactDescUtil::calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath)
{
outPath.Clear();
@@ -690,10 +665,4 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des
return SLANG_OK;
}
-/* static */ComPtr<IArtifactContainer> ArtifactDescUtil::createContainer(const ArtifactDesc& desc)
-{
- const auto containerDesc = ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults, desc.style);
- return ArtifactContainer::create(containerDesc);
-}
-
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-desc-util.h b/source/compiler-core/slang-artifact-desc-util.h
index 604d5a4ce..e3d1e6478 100644
--- a/source/compiler-core/slang-artifact-desc-util.h
+++ b/source/compiler-core/slang-artifact-desc-util.h
@@ -75,23 +75,29 @@ struct ArtifactDescUtil
/// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
/// Else if there is an explicit name set, this is returned.
/// Else returns the empty string
- static String getBaseName(IArtifact* artifact);
+
static String getBaseName(const ArtifactDesc& desc, IFileArtifactRepresentation* fileRep);
- /// Get the parent path (empty if there isn't one)
- static String getParentPath(IArtifact* artifact);
- static String getParentPath(IFileArtifactRepresentation* fileRep);
-
/// Given a desc, and a basePath returns a suitable path for a entity of specified desc
static SlangResult calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath);
- /// Make ArtifactDesc from target
+ /// Given a target returns the ArtifactDesc
static ArtifactDesc makeDescFromCompileTarget(SlangCompileTarget target);
- /// Create an empty container which is compatible with the desc
- static ComPtr<IArtifactContainer> createContainer(const ArtifactDesc& desc);
+ /// Make ArtifactDesc from target
+ static bool isDescDerivedFrom(const ArtifactDesc& desc, const ArtifactDesc& from);
};
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+inline /* static */bool ArtifactDescUtil::isDescDerivedFrom(const ArtifactDesc& desc, const ArtifactDesc& from)
+{
+ // TODO(JS): Currently this ignores flags in desc. That may or may not be right
+ // long term.
+ return isDerivedFrom(desc.kind, from.kind) &&
+ isDerivedFrom(desc.payload, from.payload) &&
+ isDerivedFrom(desc.style, from.style);
+}
+
} // namespace Slang
#endif
diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp
new file mode 100644
index 000000000..c93a4907b
--- /dev/null
+++ b/source/compiler-core/slang-artifact-handler-impl.cpp
@@ -0,0 +1,380 @@
+// slang-artifact-handler-impl.cpp
+#include "slang-artifact-handler-impl.h"
+
+#include "slang-artifact-impl.h"
+#include "slang-artifact-representation-impl.h"
+
+#include "slang-artifact-desc-util.h"
+
+#include "slang-artifact-helper.h"
+
+#include "../core/slang-castable-list-impl.h"
+
+#include "../core/slang-file-system.h"
+#include "../core/slang-io.h"
+#include "../core/slang-shared-library.h"
+
+// For workaround for DownstreamResult
+#include "slang-downstream-compiler.h"
+
+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);
+}
+
+/* Hack to take into account downstream compilers shared library interface might need an adapter */
+static SlangResult _getDownstreamSharedLibrary(DownstreamCompileResult* downstreamResult, ComPtr<ISlangSharedLibrary>& outSharedLibrary)
+{
+ 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_E_NOT_FOUND;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */DefaultArtifactHandler DefaultArtifactHandler::g_singleton;
+
+SlangResult DefaultArtifactHandler::queryInterface(SlangUUID const& uuid, void** outObject)
+{
+ if (auto ptr = getInterface(uuid))
+ {
+ addRef();
+ *outObject = static_cast<IArtifactHandler*>(this);
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+}
+
+void* DefaultArtifactHandler::castAs(const Guid& guid)
+{
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+void* DefaultArtifactHandler::getInterface(const Guid& uuid)
+{
+ if (uuid == ISlangUnknown::getTypeGuid() ||
+ uuid == ICastable::getTypeGuid() ||
+ uuid == IArtifactHandler::getTypeGuid())
+ {
+ return static_cast<IArtifactHandler*>(this);
+ }
+
+ return nullptr;
+}
+
+void* DefaultArtifactHandler::getObject(const Guid& uuid)
+{
+ SLANG_UNUSED(uuid);
+ return nullptr;
+}
+
+SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable)
+{
+ SLANG_ASSERT(rep);
+
+ // See if it implements ICastable
+ {
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(rep->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ {
+ return _addRepresentation(artifact, keep, castable, outCastable);
+ }
+ }
+
+ // We have to wrap
+ ComPtr<IUnknownCastableAdapter> adapter(new UnknownCastableAdapter(rep));
+ return _addRepresentation(artifact, keep, adapter, outCastable);
+}
+
+SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable)
+{
+ SLANG_ASSERT(castable);
+
+ if (canKeep(keep))
+ {
+ artifact->addRepresentation(castable);
+ }
+
+ castable->addRef();
+ *outCastable = castable;
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHandler::expandChildren(IArtifactContainer* container)
+{
+ SlangResult res = container->getExpandChildrenResult();
+ if (res != SLANG_E_UNINITIALIZED)
+ {
+ // It's already expanded
+ return res;
+ }
+
+ // For the generic container type, we just expand as empty
+ const auto desc = container->getDesc();
+ if (desc.kind == ArtifactKind::Container)
+ {
+ container->setChildren(nullptr, 0);
+ return SLANG_OK;
+ }
+ // TODO(JS):
+ // Proper implementation should (for example) be able to expand a Zip file etc.
+ return SLANG_E_NOT_IMPLEMENTED;
+}
+
+
+
+SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable)
+{
+ // See if we already have a rep of this type
+ {
+ for (ICastable* rep : artifact->getRepresentations())
+ {
+ if (rep->castAs(guid))
+ {
+ rep->addRef();
+ *outCastable = rep;
+ return SLANG_OK;
+ }
+ }
+ }
+
+ // TODO(JS): Temporary whilst DownstreamCompileResult is
+ // Special handling for DownstreamCompileResult
+ if (auto downstreamResult = findRepresentation<DownstreamCompileResult>(artifact))
+ {
+ if (guid == ISlangBlob::getTypeGuid())
+ {
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(downstreamResult->getBinary(blob));
+ return _addRepresentation(artifact, keep, blob, outCastable);
+ }
+ else if (guid == ISlangSharedLibrary::getTypeGuid())
+ {
+ ComPtr<ISlangSharedLibrary> lib;
+ SLANG_RETURN_ON_FAIL(_getDownstreamSharedLibrary(downstreamResult, lib));
+ return _addRepresentation(artifact, keep, lib, outCastable);
+ }
+ }
+
+ // Normal construction
+ if (guid == ISlangBlob::getTypeGuid())
+ {
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(_loadBlob(artifact, keep, blob.writeRef()));
+ return _addRepresentation(artifact, keep, blob, outCastable);
+ }
+ else if (guid == ISlangSharedLibrary::getTypeGuid())
+ {
+ ComPtr<ISlangSharedLibrary> sharedLib;
+ SLANG_RETURN_ON_FAIL(_loadSharedLibrary(artifact, keep, sharedLib.writeRef()));
+ return _addRepresentation(artifact, keep, sharedLib, outCastable);
+ }
+
+ return SLANG_E_NOT_AVAILABLE;
+}
+
+static bool _isFileSystemFile(ICastable* castable, void* data)
+{
+ if (auto fileRep = as<IFileArtifactRepresentation>(castable))
+ {
+ ISlangMutableFileSystem* fileSystem = (ISlangMutableFileSystem*)data;
+ if (fileRep->getFileSystem() == fileSystem)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep)
+{
+ // See if we already have it
+ if (auto fileRep = as<IFileArtifactRepresentation>(artifact->findRepresentationWithPredicate(&_isFileSystemFile, fileSystem)))
+ {
+ fileRep->addRef();
+ *outFileRep = fileRep;
+ return SLANG_OK;
+ }
+
+ auto helper = DefaultArtifactHelper::getSingleton();
+
+ // If we are going to access as a file we need to be able to write it, and to do that we need a blob
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(getIntermediateKeep(keep), blob.writeRef()));
+
+ // Okay we need to store as a temporary. Get a lock file.
+ ComPtr<IFileArtifactRepresentation> lockFile;
+ SLANG_RETURN_ON_FAIL(helper->createLockFile(artifact->getName(), fileSystem, lockFile.writeRef()));
+
+ // Now we need the appropriate name for this item
+ ComPtr<ISlangBlob> pathBlob;
+ SLANG_RETURN_ON_FAIL(helper->calcArtifactPath(artifact->getDesc(), lockFile->getPath(), pathBlob.writeRef()));
+
+ const auto path = StringUtil::getString(pathBlob);
+
+ // Write the contents
+ SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize()));
+
+ ComPtr<IFileArtifactRepresentation> fileRep;
+
+ // TODO(JS): This path comparison is perhaps not perfect, in that it assumes the path is not changed
+ // in any way. For example an impl of calcArtifactPath that changed slashes or used a canonical path
+ // might mean the lock file and the rep have the same path.
+ // As it stands calcArtifactPath impl doesn't do that, but that is perhaps somewhatfragile
+
+ // If the paths are identical, we can just use the lock file for the rep
+ if (UnownedStringSlice(lockFile->getPath()) == path.getUnownedSlice())
+ {
+ fileRep.swap(lockFile);
+ }
+ else
+ {
+ // Create a new rep that references the lock file
+ fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, lockFile->getFileSystem());
+ }
+
+ // Create the rep
+ if (canKeep(keep))
+ {
+ artifact->addRepresentation(fileRep);
+ }
+
+ // Return the file
+ *outFileRep = fileRep.detach();
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHandler::_loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary)
+{
+ // If it is 'shared library' for a CPU like thing, we can try and load it
+ const auto desc = artifact->getDesc();
+ if ((isDerivedFrom(desc.kind, ArtifactKind::HostCallable) ||
+ isDerivedFrom(desc.kind, ArtifactKind::SharedLibrary)) &&
+ isDerivedFrom(desc.payload, ArtifactPayload::CPULike))
+ {
+ // Get as a file represenation on the OS file system
+ ComPtr<IFileArtifactRepresentation> fileRep;
+ SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::No, nullptr, fileRep.writeRef()));
+
+ // We requested on the OS file system, just check that's what we got...
+ SLANG_ASSERT(fileRep->getFileSystem() == nullptr);
+
+ // Try loading the shared library
+ SharedLibrary::Handle handle;
+ if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(fileRep->getPath(), handle)))
+ {
+ return SLANG_FAIL;
+ }
+
+ // The ScopeSharedLibrary will keep the fileRep in scope as long as is needed
+ auto sharedLibrary = new ScopeSharedLibrary(handle, fileRep);
+
+ if (canKeep(keep))
+ {
+ // We want to keep the fileRep, as that is necessary for the sharedLibrary to even work
+ artifact->addRepresentation(fileRep);
+ // Keep the shared library
+ artifact->addRepresentation(sharedLibrary);
+ }
+
+ // Output
+ sharedLibrary->addRef();
+ *outSharedLibrary = sharedLibrary;
+
+ return SLANG_OK;
+ }
+
+ return SLANG_FAIL;
+}
+
+SlangResult DefaultArtifactHandler::_loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob)
+{
+ SLANG_UNUSED(keep);
+
+ ComPtr<ISlangBlob> blob;
+
+ // Look for a representation that we can serialize into a blob
+ for (auto rep : artifact->getRepresentations())
+ {
+ if (auto artifactRep = as<IArtifactRepresentation>(rep))
+ {
+ SlangResult res = artifactRep->writeToBlob(blob.writeRef());
+ if (SLANG_SUCCEEDED(res) && blob)
+ {
+ break;
+ }
+ }
+ }
+
+ // Wasn't able to construct
+ if (!blob)
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+
+ *outBlob = blob.detach();
+ return SLANG_OK;
+}
+
+} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-handler-impl.h b/source/compiler-core/slang-artifact-handler-impl.h
new file mode 100644
index 000000000..c7861b598
--- /dev/null
+++ b/source/compiler-core/slang-artifact-handler-impl.h
@@ -0,0 +1,45 @@
+// slang-artifact-handler-impl.h
+#ifndef SLANG_ARTIFACT_HANDLER_IMPL_H
+#define SLANG_ARTIFACT_HANDLER_IMPL_H
+
+#include "slang-artifact.h"
+#include "slang-artifact-representation.h"
+
+#include "../core/slang-com-object.h"
+
+namespace Slang
+{
+
+class DefaultArtifactHandler : public ComBaseObject, public IArtifactHandler
+{
+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; }
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IArtifactHandler
+ SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren(IArtifactContainer* container) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
+
+ static IArtifactHandler* getSingleton() { return &g_singleton; }
+protected:
+
+ SlangResult _loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary);
+ SlangResult _loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob);
+
+ void* getInterface(const Guid& uuid);
+ void* getObject(const Guid& uuid);
+
+ SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable);
+ SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable);
+
+ static DefaultArtifactHandler g_singleton;
+};
+
+} // namespace Slang
+
+#endif
diff --git a/source/compiler-core/slang-artifact-helper.cpp b/source/compiler-core/slang-artifact-helper.cpp
new file mode 100644
index 000000000..ce6fab7d9
--- /dev/null
+++ b/source/compiler-core/slang-artifact-helper.cpp
@@ -0,0 +1,124 @@
+// slang-artifact-helper.cpp
+#include "slang-artifact-helper.h"
+
+#include "slang-artifact-impl.h"
+#include "slang-artifact-representation-impl.h"
+
+#include "slang-artifact-desc-util.h"
+
+#include "../core/slang-castable-list-impl.h"
+
+#include "../core/slang-file-system.h"
+#include "../core/slang-io.h"
+#include "../core/slang-shared-library.h"
+
+namespace Slang {
+
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHelper !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */DefaultArtifactHelper DefaultArtifactHelper::g_singleton;
+
+SlangResult DefaultArtifactHelper::queryInterface(SlangUUID const& uuid, void** outObject)
+{
+ if (auto intf = getInterface(uuid))
+ {
+ *outObject = intf;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+}
+
+void* DefaultArtifactHelper::castAs(const Guid& guid)
+{
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+void* DefaultArtifactHelper::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == IArtifactHelper::getTypeGuid())
+ {
+ return static_cast<IArtifactHelper*>(this);
+ }
+ return nullptr;
+}
+
+void* DefaultArtifactHelper::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+SlangResult DefaultArtifactHelper::createArtifact(const ArtifactDesc& desc, const char* inName, IArtifact** outArtifact)
+{
+ *outArtifact = inName ?
+ Artifact::create(desc, inName).detach() :
+ Artifact::create(desc).detach();
+
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHelper::createArtifactContainer(const ArtifactDesc& desc, const char* inName, IArtifactContainer** outArtifactContainer)
+{
+ *outArtifactContainer = inName ?
+ ArtifactContainer::create(desc, inName).detach() :
+ ArtifactContainer::create(desc).detach();
+
+ return SLANG_OK;
+}
+
+ArtifactKind DefaultArtifactHelper::getKindParent(ArtifactKind kind) { return getParent(kind); }
+UnownedStringSlice DefaultArtifactHelper::getKindName(ArtifactKind kind) { return getName(kind); }
+bool DefaultArtifactHelper::isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) { return isDerivedFrom(kind, base); }
+
+ArtifactPayload DefaultArtifactHelper::getPayloadParent(ArtifactPayload payload) { return getParent(payload); }
+UnownedStringSlice DefaultArtifactHelper::getPayloadName(ArtifactPayload payload) { return getName(payload); }
+bool DefaultArtifactHelper::isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) { return isDerivedFrom(payload, base); }
+
+ArtifactStyle DefaultArtifactHelper::getStyleParent(ArtifactStyle style) { return getParent(style); }
+UnownedStringSlice DefaultArtifactHelper::getStyleName(ArtifactStyle style) { return getName(style); }
+bool DefaultArtifactHelper::isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) { return isDerivedFrom(style, base); }
+
+SlangResult DefaultArtifactHelper::createLockFile(const char* inNameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile)
+{
+ if (fileSystem)
+ {
+ if (fileSystem != OSFileSystem::getMutableSingleton())
+ {
+ // We can only create lock files, on the global OS file system
+ return SLANG_E_NOT_AVAILABLE;
+ }
+ fileSystem = nullptr;
+ }
+
+ const UnownedStringSlice nameBase = (inNameBase && inNameBase[0] != 0) ? UnownedStringSlice(inNameBase) : UnownedStringSlice("unknown");
+
+ String lockPath;
+ SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, lockPath));
+
+ ComPtr<IFileArtifactRepresentation> lockFile(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Lock, lockPath, nullptr, fileSystem));
+
+ *outLockFile = lockFile.detach();
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHelper::calcArtifactPath(const ArtifactDesc& desc, const char* inBasePath, ISlangBlob** outPath)
+{
+ UnownedStringSlice basePath(inBasePath);
+ StringBuilder path;
+ SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, basePath, path));
+ *outPath = StringBlob::create(path).detach();
+ return SLANG_OK;
+}
+
+ArtifactDesc DefaultArtifactHelper::makeDescFromCompileTarget(SlangCompileTarget target)
+{
+ return ArtifactDescUtil::makeDescFromCompileTarget(target);
+}
+
+} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-helper.h b/source/compiler-core/slang-artifact-helper.h
new file mode 100644
index 000000000..41bf0f2c9
--- /dev/null
+++ b/source/compiler-core/slang-artifact-helper.h
@@ -0,0 +1,84 @@
+// slang-artifact-helper.h
+#ifndef SLANG_ARTIFACT_HELPER_H
+#define SLANG_ARTIFACT_HELPER_H
+
+#include "slang-artifact.h"
+#include "slang-artifact-representation.h"
+
+#include "../core/slang-com-object.h"
+
+namespace Slang
+{
+
+class IArtifactHelper : public ICastable
+{
+ SLANG_COM_INTERFACE(0x882b25d7, 0xe300, 0x4b20, { 0xbe, 0xb, 0x26, 0xd2, 0x52, 0x3e, 0x70, 0x20 })
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) = 0;
+
+ virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) = 0;
+
+ virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) = 0;
+
+ virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) = 0;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) = 0;
+
+ /// Given a desc and a basePath returns a suitable name
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) = 0;
+
+ virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) = 0;
+};
+
+class DefaultArtifactHelper : public IArtifactHelper
+{
+public:
+ // ISlangUnknown
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IArtifactInterface
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) SLANG_OVERRIDE;
+
+ static IArtifactHelper* getSingleton() { return &g_singleton; }
+
+protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
+ static DefaultArtifactHelper g_singleton;
+};
+
+} // namespace Slang
+
+#endif
diff --git a/source/compiler-core/slang-artifact-impl.cpp b/source/compiler-core/slang-artifact-impl.cpp
index 061aa9ee7..ed952e72c 100644
--- a/source/compiler-core/slang-artifact-impl.cpp
+++ b/source/compiler-core/slang-artifact-impl.cpp
@@ -6,10 +6,21 @@
#include "slang-artifact-util.h"
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-handler-impl.h"
+
#include "../core/slang-castable-list-impl.h"
namespace Slang {
+static bool _checkSelf(IArtifact::FindStyle findStyle)
+{
+ return Index(findStyle) <= Index(IArtifact::FindStyle::SelfOrChildren);
+}
+
+static bool _checkChildren(IArtifact::FindStyle findStyle)
+{
+ return Index(findStyle) >= Index(IArtifact::FindStyle::SelfOrChildren);
+}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Artifact !!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -187,6 +198,26 @@ ICastableList* Artifact::getRepresentationList()
return m_representations.requireList();
}
+IArtifact* Artifact::findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& from)
+{
+ return (_checkSelf(findStyle) && ArtifactDescUtil::isDescDerivedFrom(m_desc, from)) ? this : nullptr;
+}
+
+IArtifact* Artifact::findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data)
+{
+ return (_checkSelf(findStyle) && func(this, data)) ? this : nullptr;
+}
+
+IArtifact* Artifact::findArtifactByName(FindStyle findStyle, const char* name)
+{
+ return (_checkSelf(findStyle) && m_name == name) ? this : nullptr;
+}
+
+IArtifact* Artifact::findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc)
+{
+ return (_checkSelf(findStyle) && m_desc == desc) ? this : nullptr;
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactContainer !!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* ArtifactContainer::getInterface(const Guid& guid)
@@ -267,67 +298,79 @@ void ArtifactContainer::clearChildren()
m_children.clearAndDeallocate();
}
-IArtifact* ArtifactContainer::findChildByDesc(const ArtifactDesc& desc)
+static bool _isDerivedDesc(IArtifact* artifact, void* data)
{
- _requireChildren();
-
- for (IArtifact* artifact : m_children)
- {
- if (artifact->getDesc() == desc)
- {
- return artifact;
- }
- }
- return nullptr;
+ const ArtifactDesc& from = *(const ArtifactDesc*)data;
+ return ArtifactDescUtil::isDescDerivedFrom(artifact->getDesc(), from);
}
-IArtifact* ArtifactContainer::findChildByDerivedDesc(const ArtifactDesc& desc)
+static bool _isDesc(IArtifact* artifact, void* data)
{
- _requireChildren();
+ const ArtifactDesc& desc = *(const ArtifactDesc*)data;
+ return desc == artifact->getDesc();
+}
- for (IArtifact* artifact : m_children)
+static bool _isName(IArtifact* artifact, void* data)
+{
+ const char* name = (const char*)data;
+ const char* artifactName = artifact->getName();
+ if (artifactName == nullptr)
{
- const ArtifactDesc artifactDesc = artifact->getDesc();
- // TODO(JS): Currently this ignores flags in desc. That may or may not be right
- // long term.
- if (isDerivedFrom(artifactDesc.kind, desc.kind) &&
- isDerivedFrom(artifactDesc.payload, desc.payload) &&
- isDerivedFrom(artifactDesc.style, desc.style))
- {
- return artifact;
- }
+ return false;
}
- return nullptr;
+ return ::strcmp(name, artifactName) == 0;
}
-IArtifact* ArtifactContainer::findChildByName(const char* name)
+
+IArtifact* ArtifactContainer::findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& from)
{
- _requireChildren();
+ return findArtifactByPredicate(findStyle, _isDerivedDesc, const_cast<ArtifactDesc*>(&from));
+}
- for (IArtifact* artifact : m_children)
- {
- const char* artifactName = artifact->getName();
+IArtifact* ArtifactContainer::findArtifactByName(FindStyle findStyle, const char* name)
+{
+ return findArtifactByPredicate(findStyle, _isName, const_cast<char*>(name));
+}
- if (artifactName == name ||
- ::strcmp(artifactName, name) == 0)
- {
- return artifact;
- }
- }
- return nullptr;
+IArtifact* ArtifactContainer::findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc)
+{
+ return findArtifactByPredicate(findStyle, _isDesc, const_cast<ArtifactDesc*>(&desc));
}
-IArtifact* ArtifactContainer::findChildByPredicate(FindFunc func, void* data)
+IArtifact* ArtifactContainer::findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data)
{
- _requireChildren();
+ if (_checkSelf(findStyle) && func(this, data))
+ {
+ return this;
+ }
- for (IArtifact* artifact : m_children)
+ if (_checkChildren(findStyle))
{
- if (func(artifact, data))
+ auto children = getChildren();
+
+ // First search the children
+ for (auto child : children)
{
- return artifact;
+ if (func(child, data))
+ {
+ return child;
+ }
+ }
+
+ // Then the childrens recursively
+ if (findStyle == FindStyle::Recursive ||
+ findStyle == FindStyle::ChildrenRecursive)
+ {
+ for (auto child : children)
+ {
+ if (auto found = child->findArtifactByPredicate(FindStyle::ChildrenRecursive, func, data))
+ {
+ return found;
+ }
+ }
}
}
+
return nullptr;
}
diff --git a/source/compiler-core/slang-artifact-impl.h b/source/compiler-core/slang-artifact-impl.h
index 8b15d0664..e0a976929 100644
--- a/source/compiler-core/slang-artifact-impl.h
+++ b/source/compiler-core/slang-artifact-impl.h
@@ -61,18 +61,20 @@ public:
virtual SLANG_NO_THROW ICastable* SLANG_MCALL findRepresentationWithPredicate(ICastableList::FindFunc findFunc, void* data) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(const Guid& typeGuid, ArtifactKeep keep, ICastable** outCastable) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE { return Slice<IArtifact*>(nullptr, 0); }
+
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByName(FindStyle findStyle, const char* name) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+
// IArtifactCollection (Not implemented)
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getExpandChildrenResult() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL setChildren(IArtifact** children, Count count) SLANG_OVERRIDE { SLANG_UNUSED(children); SLANG_UNUSED(count); SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL addChild(IArtifact* artifact) SLANG_OVERRIDE { SLANG_UNUSED(artifact); SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL removeChildAt(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDesc(const ArtifactDesc& desc) SLANG_OVERRIDE { SLANG_UNUSED(desc); SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDerivedDesc(const ArtifactDesc& desc) SLANG_OVERRIDE { SLANG_UNUSED(desc); SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByName(const char* name) SLANG_OVERRIDE { SLANG_UNUSED(name); SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByPredicate(FindFunc func, void* data) SLANG_OVERRIDE { SLANG_UNUSED(func); SLANG_UNUSED(data); SLANG_UNREACHABLE("Not implemented"); }
static ComPtr<IArtifact> create(const Desc& desc) { return ComPtr<IArtifact>(new Artifact(desc)); }
static ComPtr<IArtifact> create(const Desc& desc, const String& name) { return ComPtr<IArtifact>(new Artifact(desc, name)); }
@@ -115,19 +117,21 @@ public:
/// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+ /// IArtifact
+ virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByName(FindStyle findStyle, const char* name) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+
// IArtifactCollection
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getExpandChildrenResult() SLANG_OVERRIDE { return m_expandResult; }
virtual SLANG_NO_THROW void SLANG_MCALL setChildren(IArtifact** children, Count count) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren() SLANG_OVERRIDE;
- virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL addChild(IArtifact* artifact) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL removeChildAt(Index index) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDesc(const ArtifactDesc& desc) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDerivedDesc(const ArtifactDesc& desc) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByName(const char* name) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByPredicate(FindFunc func, void* data) SLANG_OVERRIDE;
-
+
static ComPtr<IArtifactContainer> create(const Desc& desc) { return ComPtr<IArtifactContainer>(new ArtifactContainer(desc)); }
static ComPtr<IArtifactContainer> create(const Desc& desc, const String& name) { return ComPtr<IArtifactContainer>(new ArtifactContainer(desc, name)); }
diff --git a/source/compiler-core/slang-artifact-representation-impl.cpp b/source/compiler-core/slang-artifact-representation-impl.cpp
index 6ae2d646f..32ec055d8 100644
--- a/source/compiler-core/slang-artifact-representation-impl.cpp
+++ b/source/compiler-core/slang-artifact-representation-impl.cpp
@@ -178,10 +178,58 @@ void* PostEmitMetadataArtifactRepresentation::getObject(const Guid& uuid)
return nullptr;
}
+void* PostEmitMetadataArtifactRepresentation::castAs(const Guid& guid)
+{
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+
Slice<ShaderBindingRange> PostEmitMetadataArtifactRepresentation::getBindingRanges()
{
- return Slice<ShaderBindingRange>(m_usedBindings.getBuffer(), m_usedBindings.getCount());
+ return Slice<ShaderBindingRange>(m_metadata.usedBindings.getBuffer(), m_metadata.usedBindings.getCount());
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadataArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* ObjectArtifactRepresentation::castAs(const Guid& guid)
+{
+
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+void* ObjectArtifactRepresentation::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == IArtifactRepresentation::getTypeGuid())
+ {
+ return static_cast<IArtifactRepresentation*>(this);
+ }
+ return nullptr;
+}
+
+void* ObjectArtifactRepresentation::getObject(const Guid& guid)
+{
+ if (guid == getTypeGuid())
+ {
+ return this;
+ }
+
+ // If matches the guid saved in the object, we return that
+ if (m_object && m_typeGuid == guid)
+ {
+ return m_object;
+ }
+
+ return nullptr;
}
-
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-representation-impl.h b/source/compiler-core/slang-artifact-representation-impl.h
index 00d36ab49..fb2e37c76 100644
--- a/source/compiler-core/slang-artifact-representation-impl.h
+++ b/source/compiler-core/slang-artifact-representation-impl.h
@@ -10,8 +10,6 @@
#include "../core/slang-com-object.h"
#include "../core/slang-memory-arena.h"
-//#include "../core/slang-string-slice-pool.h"
-
namespace Slang
{
@@ -172,7 +170,10 @@ struct ShaderBindingRange
}
};
-typedef List<ShaderBindingRange> ShaderBindingRanges;
+struct PostEmitMetadata
+{
+ List<ShaderBindingRange> usedBindings;
+};
class PostEmitMetadataArtifactRepresentation : public ComBaseObject, public IPostEmitMetadataArtifactRepresentation
{
@@ -184,15 +185,45 @@ public:
// ICastable
SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// IArtifactRepresentation
- SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) SLANG_OVERRIDE;
- SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** outBlob) SLANG_OVERRIDE { SLANG_UNUSED(outBlob); return SLANG_E_NOT_AVAILABLE; }
+ SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return true; }
// IPostEmitMetadataArtifactRepresentation
SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getBindingRanges() SLANG_OVERRIDE;
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
- ShaderBindingRanges m_usedBindings;
+ PostEmitMetadata m_metadata;
+};
+
+/* This allows wrapping any object to be an artifact representation.
+
+NOTE! Only allows casting from a single guid. Passing a RefObject across an ABI bounday remains risky!
+*/
+class ObjectArtifactRepresentation : public ComBaseObject, public IArtifactRepresentation
+{
+public:
+ SLANG_CLASS_GUID(0xb9d5af57, 0x725b, 0x45f8, { 0xac, 0xed, 0x18, 0xf4, 0xa8, 0x4b, 0xf4, 0x73 })
+
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+ // IArtifactRepresentation
+ SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** outBlob) SLANG_OVERRIDE { SLANG_UNUSED(outBlob); return SLANG_E_NOT_AVAILABLE; }
+ SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return m_object; }
+
+ ObjectArtifactRepresentation(const Guid& typeGuid, RefObject* obj):
+ m_typeGuid(typeGuid),
+ m_object(obj)
+ {
+ }
+
+ void* getInterface(const Guid& uuid);
+ void* getObject(const Guid& uuid);
+
+ Guid m_typeGuid; ///< Will return m_object if a cast to m_typeGuid is given
+ RefPtr<RefObject> m_object; ///< The object
};
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp
index 366ab4111..f93924afb 100644
--- a/source/compiler-core/slang-artifact-util.cpp
+++ b/source/compiler-core/slang-artifact-util.cpp
@@ -8,370 +8,100 @@
#include "../core/slang-castable-list-impl.h"
-#include "../core/slang-file-system.h"
#include "../core/slang-io.h"
-#include "../core/slang-shared-library.h"
namespace Slang {
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-/* static */DefaultArtifactHandler DefaultArtifactHandler::g_singleton;
-
-SlangResult DefaultArtifactHandler::queryInterface(SlangUUID const& uuid, void** outObject)
-{
- if (auto ptr = getInterface(uuid))
- {
- addRef();
- *outObject = static_cast<IArtifactHandler*>(this);
- return SLANG_OK;
- }
- return SLANG_E_NO_INTERFACE;
-}
-
-void* DefaultArtifactHandler::castAs(const Guid& guid)
-{
- if (auto ptr = getInterface(guid))
- {
- return ptr;
- }
- return getObject(guid);
-}
-
-void* DefaultArtifactHandler::getInterface(const Guid& uuid)
-{
- if (uuid == ISlangUnknown::getTypeGuid() ||
- uuid == ICastable::getTypeGuid() ||
- uuid == IArtifactHandler::getTypeGuid())
- {
- return static_cast<IArtifactHandler*>(this);
- }
-
- return nullptr;
-}
-
-void* DefaultArtifactHandler::getObject(const Guid& uuid)
-{
- SLANG_UNUSED(uuid);
- return nullptr;
-}
-
-SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable)
-{
- SLANG_ASSERT(rep);
-
- // See if it implements ICastable
- {
- ComPtr<ICastable> castable;
- if (SLANG_SUCCEEDED(rep->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
- {
- return _addRepresentation(artifact, keep, castable, outCastable);
- }
- }
-
- // We have to wrap
- ComPtr<IUnknownCastableAdapter> adapter(new UnknownCastableAdapter(rep));
- return _addRepresentation(artifact, keep, adapter, outCastable);
-}
-
-SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable)
+/* static */ComPtr<IArtifactContainer> ArtifactUtil::createContainer(const ArtifactDesc& desc)
{
- SLANG_ASSERT(castable);
-
- if (canKeep(keep))
- {
- artifact->addRepresentation(castable);
- }
-
- castable->addRef();
- *outCastable = castable;
- return SLANG_OK;
+ const auto containerDesc = ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults, desc.style);
+ return ArtifactContainer::create(containerDesc);
}
-SlangResult DefaultArtifactHandler::expandChildren(IArtifactContainer* container)
+/* static */ComPtr<IArtifactContainer> ArtifactUtil::createResultsContainer()
{
- SlangResult res = container->getExpandChildrenResult();
- if (res != SLANG_E_UNINITIALIZED)
- {
- // It's already expanded
- return res;
- }
-
- // For the generic container type, we just expand as empty
- const auto desc = container->getDesc();
- if (desc.kind == ArtifactKind::Container)
- {
- container->setChildren(nullptr, 0);
- return SLANG_OK;
- }
- // TODO(JS):
- // Proper implementation should (for example) be able to expand a Zip file etc.
- return SLANG_E_NOT_IMPLEMENTED;
+ return ArtifactContainer::create(ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults));
}
-SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable)
+/* static */ComPtr<IArtifact> ArtifactUtil::createArtifactForCompileTarget(SlangCompileTarget target)
{
-
- // See if we already have a rep of this type
- {
- for (ICastable* rep : artifact->getRepresentations())
- {
- if (rep->castAs(guid))
- {
- rep->addRef();
- *outCastable = rep;
- return SLANG_OK;
- }
- }
- }
+ auto desc = ArtifactDescUtil::makeDescFromCompileTarget(target);
- if (guid == ISlangBlob::getTypeGuid())
- {
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(_loadBlob(artifact, keep, blob.writeRef()));
- return _addRepresentation(artifact, keep, blob, outCastable);
- }
- else if (guid == ISlangSharedLibrary::getTypeGuid())
- {
- ComPtr<ISlangSharedLibrary> sharedLib;
- SLANG_RETURN_ON_FAIL(_loadSharedLibrary(artifact, keep, sharedLib.writeRef()));
- return _addRepresentation(artifact, keep, sharedLib, outCastable);
- }
+ if (isDerivedFrom(desc.kind, ArtifactKind::Container))
+ {
+ auto container = ArtifactContainer::create(desc);
- return SLANG_E_NOT_AVAILABLE;
+ ComPtr<IArtifact> artifact;
+ artifact.attach(container.detach());
+ return artifact;
+ }
+ else
+ {
+ return Artifact::create(desc);
+ }
}
-static bool _isFileSystemFile(ICastable* castable, void* data)
+/* static */bool ArtifactUtil::isSignificant(IArtifact* artifact, void* data)
{
- if (auto fileRep = as<IFileArtifactRepresentation>(castable))
- {
- ISlangMutableFileSystem* fileSystem = (ISlangMutableFileSystem*)data;
- if (fileRep->getFileSystem() == fileSystem)
- {
- return true;
- }
- }
- return false;
-}
-
-SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep)
-{
- // See if we already have it
- if (auto fileRep = as<IFileArtifactRepresentation>(artifact->findRepresentationWithPredicate(&_isFileSystemFile, fileSystem)))
- {
- fileRep->addRef();
- *outFileRep = fileRep;
- return SLANG_OK;
- }
-
- auto util = ArtifactUtilImpl::getSingleton();
+ SLANG_UNUSED(data);
- // If we are going to access as a file we need to be able to write it, and to do that we need a blob
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(artifact->loadBlob(getIntermediateKeep(keep), blob.writeRef()));
+ const auto desc = artifact->getDesc();
- // Okay we need to store as a temporary. Get a lock file.
- ComPtr<IFileArtifactRepresentation> lockFile;
- SLANG_RETURN_ON_FAIL(util->createLockFile(artifact->getName(), fileSystem, lockFile.writeRef()));
+ // Containers are not significant as of themselves, they may contain something tho
+ if (isDerivedFrom(desc.kind, ArtifactKind::Container))
+ {
+ return false;
+ }
- // Now we need the appropriate name for this item
- ComPtr<ISlangBlob> pathBlob;
- SLANG_RETURN_ON_FAIL(util->calcArtifactPath(artifact->getDesc(), lockFile->getPath(), pathBlob.writeRef()));
+ // If it has no payload.. we are done
+ if (desc.payload == ArtifactPayload::None ||
+ desc.payload == ArtifactPayload::Invalid)
+ {
+ return false;
+ }
- const auto path = StringUtil::getString(pathBlob);
+ // If it's binary like or assembly/source we it's significant
+ if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike) ||
+ desc.kind == ArtifactKind::Assembly ||
+ desc.kind == ArtifactKind::Source)
+ {
+ return true;
+ }
- // Write the contents
- SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize()));
+ /* Hmm, we might want to have a base class for 'signifiant' payloads,
+ where signifiance here means somewhat approximately 'the meat' of a compilation result,
+ as contrasted with 'meta data', 'diagnostics etc'*/
+ if (isDerivedFrom(desc.payload, ArtifactPayload::MetaData))
+ {
+ return false;
+ }
- ComPtr<IFileArtifactRepresentation> fileRep;
-
- // TODO(JS): This path comparison is perhaps not perfect, in that it assumes the path is not changed
- // in any way. For example an impl of calcArtifactPath that changed slashes or used a canonical path
- // might mean the lock file and the rep have the same path.
- // As it stands calcArtifactPath impl doesn't do that, but that is perhaps somewhatfragile
-
- // If the paths are identical, we can just use the lock file for the rep
- if (UnownedStringSlice(lockFile->getPath()) == path.getUnownedSlice())
- {
- fileRep.swap(lockFile);
- }
- else
- {
- // Create a new rep that references the lock file
- fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, lockFile->getFileSystem());
- }
-
- // Create the rep
- if (canKeep(keep))
- {
- artifact->addRepresentation(fileRep);
- }
-
- // Return the file
- *outFileRep = fileRep.detach();
- return SLANG_OK;
+ return true;
}
-SlangResult DefaultArtifactHandler::_loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary)
+/* static */String ArtifactUtil::getBaseName(IArtifact* artifact)
{
- // If it is 'shared library' for a CPU like thing, we can try and load it
- const auto desc = artifact->getDesc();
- if ((isDerivedFrom(desc.kind, ArtifactKind::HostCallable) ||
- isDerivedFrom(desc.kind, ArtifactKind::SharedLibrary)) &&
- isDerivedFrom(desc.payload, ArtifactPayload::CPULike))
- {
- // Get as a file represenation on the OS file system
- ComPtr<IFileArtifactRepresentation> fileRep;
- SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::No, nullptr, fileRep.writeRef()));
-
- // We requested on the OS file system, just check that's what we got...
- SLANG_ASSERT(fileRep->getFileSystem() == nullptr);
-
- // Try loading the shared library
- SharedLibrary::Handle handle;
- if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(fileRep->getPath(), handle)))
- {
- return SLANG_FAIL;
- }
-
- // The ScopeSharedLibrary will keep the fileRep in scope as long as is needed
- auto sharedLibrary = new ScopeSharedLibrary(handle, fileRep);
-
- if (canKeep(keep))
- {
- // We want to keep the fileRep, as that is necessary for the sharedLibrary to even work
- artifact->addRepresentation(fileRep);
- // Keep the shared library
- artifact->addRepresentation(sharedLibrary);
- }
-
- // Output
- sharedLibrary->addRef();
- *outSharedLibrary = sharedLibrary;
-
- return SLANG_OK;
- }
-
- return SLANG_FAIL;
-}
-
-SlangResult DefaultArtifactHandler::_loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob)
-{
- SLANG_UNUSED(keep);
-
- ComPtr<ISlangBlob> blob;
-
- // Look for a representation that we can serialize into a blob
- for (auto rep : artifact->getRepresentations())
- {
- if (auto artifactRep = as<IArtifactRepresentation>(rep))
- {
- SlangResult res = artifactRep->writeToBlob(blob.writeRef());
- if (SLANG_SUCCEEDED(res) && blob)
- {
- break;
- }
- }
- }
-
- // Wasn't able to construct
- if (!blob)
- {
- return SLANG_E_NOT_FOUND;
- }
-
- *outBlob = blob.detach();
- return SLANG_OK;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactUtilImpl !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-/* static */ArtifactUtilImpl ArtifactUtilImpl::g_singleton;
-
-SlangResult ArtifactUtilImpl::queryInterface(SlangUUID const& uuid, void** outObject)
-{
- if (auto intf = getInterface(uuid))
- {
- *outObject = intf;
- return SLANG_OK;
- }
- return SLANG_E_NO_INTERFACE;
-}
-
-void* ArtifactUtilImpl::getInterface(const Guid& guid)
-{
- if (guid == ISlangUnknown::getTypeGuid() || guid == IArtifactUtil::getTypeGuid())
- {
- return static_cast<IArtifactUtil*>(this);
- }
- return nullptr;
-}
-
-SlangResult ArtifactUtilImpl::createArtifact(const ArtifactDesc& desc, const char* inName, IArtifact** outArtifact)
-{
- *outArtifact = inName ?
- Artifact::create(desc, inName).detach() :
- Artifact::create(desc).detach();
-
- return SLANG_OK;
-}
-
-SlangResult ArtifactUtilImpl::createArtifactContainer(const ArtifactDesc& desc, const char* inName, IArtifactContainer** outArtifactContainer)
-{
- *outArtifactContainer = inName ?
- ArtifactContainer::create(desc, inName).detach() :
- ArtifactContainer::create(desc).detach();
-
- return SLANG_OK;
-}
-
-ArtifactKind ArtifactUtilImpl::getKindParent(ArtifactKind kind) { return getParent(kind); }
-UnownedStringSlice ArtifactUtilImpl::getKindName(ArtifactKind kind) { return getName(kind); }
-bool ArtifactUtilImpl::isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) { return isDerivedFrom(kind, base); }
-
-ArtifactPayload ArtifactUtilImpl::getPayloadParent(ArtifactPayload payload) { return getParent(payload); }
-UnownedStringSlice ArtifactUtilImpl::getPayloadName(ArtifactPayload payload) { return getName(payload); }
-bool ArtifactUtilImpl::isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) { return isDerivedFrom(payload, base); }
-
-ArtifactStyle ArtifactUtilImpl::getStyleParent(ArtifactStyle style) { return getParent(style); }
-UnownedStringSlice ArtifactUtilImpl::getStyleName(ArtifactStyle style) { return getName(style); }
-bool ArtifactUtilImpl::isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) { return isDerivedFrom(style, base); }
-
-SlangResult ArtifactUtilImpl::createLockFile(const char* inNameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile)
-{
- if (fileSystem)
- {
- if (fileSystem != OSFileSystem::getMutableSingleton())
- {
- // We can only create lock files, on the global OS file system
- return SLANG_E_NOT_AVAILABLE;
- }
- fileSystem = nullptr;
- }
-
- const UnownedStringSlice nameBase = (inNameBase && inNameBase[0] != 0) ? UnownedStringSlice(inNameBase) : UnownedStringSlice("unknown");
-
- String lockPath;
- SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, lockPath));
-
- ComPtr<IFileArtifactRepresentation> lockFile(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Lock, lockPath, nullptr, fileSystem));
-
- *outLockFile = lockFile.detach();
- return SLANG_OK;
+ if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
+ {
+ return ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep);
+ }
+ // Else use the name
+ return artifact->getName();
}
-SlangResult ArtifactUtilImpl::calcArtifactPath(const ArtifactDesc& desc, const char* inBasePath, ISlangBlob** outPath)
+/* static */String ArtifactUtil::getParentPath(IFileArtifactRepresentation* fileRep)
{
- UnownedStringSlice basePath(inBasePath);
- StringBuilder path;
- SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, basePath, path));
- *outPath = StringBlob::create(path).detach();
- return SLANG_OK;
+ UnownedStringSlice path(fileRep->getPath());
+ return Path::getParentDirectory(path);
}
-ArtifactDesc ArtifactUtilImpl::makeDescFromCompileTarget(SlangCompileTarget target)
+/* static */String ArtifactUtil::getParentPath(IArtifact* artifact)
{
- return ArtifactDescUtil::makeDescFromCompileTarget(target);
+ if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
+ {
+ return getParentPath(fileRep);
+ }
+ return String();
}
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-util.h b/source/compiler-core/slang-artifact-util.h
index 5e44b7565..541a1f058 100644
--- a/source/compiler-core/slang-artifact-util.h
+++ b/source/compiler-core/slang-artifact-util.h
@@ -5,104 +5,35 @@
#include "slang-artifact.h"
#include "slang-artifact-representation.h"
-#include "../core/slang-com-object.h"
-
namespace Slang
{
-class DefaultArtifactHandler : public ComBaseObject, public IArtifactHandler
-{
-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; }
- SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
-
- // ICastable
- SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
-
- // IArtifactHandler
- SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren(IArtifactContainer* container) SLANG_OVERRIDE;
- SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable) SLANG_OVERRIDE;
- SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
-
- static IArtifactHandler* getSingleton() { return &g_singleton; }
-protected:
-
- SlangResult _loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary);
- SlangResult _loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob);
-
- void* getInterface(const Guid& uuid);
- void* getObject(const Guid& uuid);
-
- SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable);
- SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable);
-
- static DefaultArtifactHandler g_singleton;
-};
-
-class IArtifactUtil : public ISlangUnknown
-{
- SLANG_COM_INTERFACE(0x882b25d7, 0xe300, 0x4b20, { 0xbe, 0xb, 0x26, 0xd2, 0x52, 0x3e, 0x70, 0x20 })
-
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) = 0;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) = 0;
-
- virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) = 0;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) = 0;
- virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) = 0;
-
- virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) = 0;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) = 0;
- virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) = 0;
-
- virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) = 0;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) = 0;
- virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) = 0;
-
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) = 0;
-
- /// Given a desc and a basePath returns a suitable name
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) = 0;
-
- virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) = 0;
-};
-
-class ArtifactUtilImpl : public IArtifactUtil
+struct ArtifactUtil
{
-public:
- // ISlangUnknown
- SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
-
- // IArtifactInterface
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) SLANG_OVERRIDE;
-
- virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) SLANG_OVERRIDE;
-
- virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) SLANG_OVERRIDE;
-
- virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) SLANG_OVERRIDE;
+ /// Get the base name of this artifact.
+ /// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
+ /// Else if there is an explicit name set, this is returned.
+ /// Else returns the empty string
+ static String getBaseName(IArtifact* artifact);
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) SLANG_OVERRIDE;
+ /// Get the parent path (empty if there isn't one)
+ static String getParentPath(IArtifact* artifact);
+ static String getParentPath(IFileArtifactRepresentation* fileRep);
- virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) SLANG_OVERRIDE;
+ /// Create an empty container which is compatible with the desc
+ static ComPtr<IArtifactContainer> createContainer(const ArtifactDesc& desc);
- static IArtifactUtil* getSingleton() { return &g_singleton; }
+ /// Create a generic container
+ static ComPtr<IArtifactContainer> createResultsContainer();
-protected:
- void* getInterface(const Guid& guid);
+ /// Creates an empty artifact for a type
+ static ComPtr<IArtifact> createArtifactForCompileTarget(SlangCompileTarget target);
- static ArtifactUtilImpl g_singleton;
+ /// Returns true if an artifact is 'significant'
+ static bool isSignificant(IArtifact* artifact, void* data = nullptr);
+ /// Find a significant artifact
+ static IArtifact* findSignificant(IArtifact* artifact) { return artifact->findArtifactByPredicate(IArtifact::FindStyle::SelfOrChildren, &isSignificant, nullptr); }
};
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h
index e399578a9..bde7f9a08 100644
--- a/source/compiler-core/slang-artifact.h
+++ b/source/compiler-core/slang-artifact.h
@@ -307,6 +307,16 @@ class IArtifact : public ICastable
public:
SLANG_COM_INTERFACE(0x57375e20, 0xbed, 0x42b6, { 0x9f, 0x5e, 0x59, 0x4f, 0x6, 0x2b, 0xe6, 0x90 })
+ typedef bool (*FindFunc)(IArtifact* artifact, void* data);
+ enum class FindStyle : uint8_t
+ {
+ Self, ///< Just on self
+ SelfOrChildren, ///< Self, or if container just the children
+ Recursive, ///< On self plus any children recursively
+ Children, ///< Only on children
+ ChildrenRecursive, ///< Only on children recursively
+ };
+
typedef ArtifactDesc Desc;
typedef ArtifactKind Kind;
@@ -361,6 +371,18 @@ public:
/// Given a typeGuid representing the desired type get or create the representation.
/// If found outCastable holds an entity that *must* be castable to typeGuid
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(const Guid& typeGuid, ArtifactKeep keep, ICastable** outCastable) = 0;
+
+ /// Get the children, will only remain valid if no mutation of children list
+ virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() = 0;
+
+ /// Find an artifact that matches desc allowing derivations. Flags is ignored
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& desc) = 0;
+ /// Find an artifact that predicate matches
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data) = 0;
+ /// Find by name
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByName(FindStyle findStyle, const char* name) = 0;
+ /// Find by desc exactly
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc) = 0;
};
class IArtifactContainer : public IArtifact
@@ -368,30 +390,19 @@ class IArtifactContainer : public IArtifact
public:
SLANG_COM_INTERFACE(0xa96e29bd, 0xb546, 0x4e79, { 0xa0, 0xdc, 0x67, 0x49, 0x22, 0x2c, 0x39, 0xad })
- typedef bool (*FindFunc)(IArtifact* artifact, void* data);
-
/// Returns the result of expansion. Will return SLANG_E_UNINITIALIZED if expansion hasn't happened
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getExpandChildrenResult() = 0;
/// Sets all of the children, will set the expansion state to SLANG_OK
virtual SLANG_NO_THROW void SLANG_MCALL setChildren(IArtifact**children, Count count) = 0;
/// Will be called implicitly on access to children
virtual SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren() = 0;
- /// Get the children, will only remain valid if no mutation of children list
- virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() = 0;
+
/// Add the artifact to the list
virtual SLANG_NO_THROW void SLANG_MCALL addChild(IArtifact* artifact) = 0;
/// Removes the child at index, keeps other artifacts in the same order
virtual SLANG_NO_THROW void SLANG_MCALL removeChildAt(Index index) = 0;
/// Clear the list
virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() = 0;
- /// Find an artifact which is an exact match for the desc
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDesc(const ArtifactDesc& desc) = 0;
- /// Find an artifact that matches desc allowing derivations. Flags is ignored
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDerivedDesc(const ArtifactDesc& desc) = 0;
- /// Find by name
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByName(const char* name) = 0;
- /// Find via predicate function
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByPredicate(FindFunc func, void* data) = 0;
};
template <typename T>
diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h
index 9d58f6678..666ca5568 100644
--- a/source/compiler-core/slang-downstream-compiler.h
+++ b/source/compiler-core/slang-downstream-compiler.h
@@ -120,7 +120,8 @@ struct DownstreamDiagnostics
class DownstreamCompileResult : public RefObject
{
public:
-
+ SLANG_CLASS_GUID(0xdfc5d318, 0x8675, 0x40ef, { 0xbd, 0x7b, 0x4, 0xa4, 0xff, 0x66, 0x11, 0x30 })
+
virtual SlangResult getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) = 0;
virtual SlangResult getBinary(ComPtr<ISlangBlob>& outBlob) = 0;
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp
index 8467cbbdc..771aa870a 100644
--- a/source/compiler-core/slang-dxc-compiler.cpp
+++ b/source/compiler-core/slang-dxc-compiler.cpp
@@ -19,7 +19,7 @@
#include "../core/slang-shared-library.h"
-#include "../compiler-core/slang-artifact-desc-util.h"
+#include "../compiler-core/slang-artifact-util.h"
// Enable calling through to `dxc` to
// generate code on Windows.
@@ -83,7 +83,7 @@ static UnownedStringSlice _addName(const UnownedStringSlice& inSlice, StringSlic
static UnownedStringSlice _addName(IArtifact* artifact, StringSlicePool& pool)
{
- return _addName(ArtifactDescUtil::getBaseName(artifact).getUnownedSlice(), pool);
+ return _addName(ArtifactUtil::getBaseName(artifact).getUnownedSlice(), pool);
}
class DxcIncludeHandler : public IDxcIncludeHandler
diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp
index 3a0217d86..c1e6e8fbc 100644
--- a/source/compiler-core/slang-gcc-compiler-util.cpp
+++ b/source/compiler-core/slang-gcc-compiler-util.cpp
@@ -11,6 +11,7 @@
#include "../core/slang-string-slice-pool.h"
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-util.h"
namespace Slang
{
@@ -649,7 +650,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
// Get the name and path (can be empty) to the library
SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
- libPathPool.add(ArtifactDescUtil::getParentPath(fileRep));
+ libPathPool.add(ArtifactUtil::getParentPath(fileRep));
cmdLine.addPrefixPathArg("-l", ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep));
}
}
diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp
index 43c991337..21db9570a 100644
--- a/source/compiler-core/slang-visual-studio-compiler-util.cpp
+++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp
@@ -12,7 +12,9 @@
#endif
#include "../core/slang-io.h"
+
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-util.h"
namespace Slang
{
@@ -270,7 +272,7 @@ namespace Slang
ComPtr<IFileArtifactRepresentation> fileRep;
SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
- libPathPool.add(ArtifactDescUtil::getParentPath(fileRep));
+ libPathPool.add(ArtifactUtil::getParentPath(fileRep));
// We need the extension for windows
cmdLine.addArg(ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep) + ".lib");
}
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 80015440a..e49b67af2 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -18,6 +18,7 @@
#include "../compiler-core/slang-artifact-desc-util.h"
#include "../compiler-core/slang-artifact-representation-impl.h"
#include "../compiler-core/slang-artifact-impl.h"
+#include "../compiler-core/slang-artifact-util.h"
#include "slang-lower-to-ir.h"
#include "slang-mangle.h"
@@ -55,52 +56,7 @@
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 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -123,6 +79,7 @@ namespace Slang
// !!!!!!!!!!!!!!!!!!!!!!!!!!!! CompileResult !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#if 0
SlangResult CompileResult::getSharedLibrary(ComPtr<ISlangSharedLibrary>& outSharedLibrary)
{
if (downstreamResult)
@@ -188,27 +145,8 @@ namespace Slang
return SLANG_OK;
}
- SlangResult CompileResult::isParameterLocationUsed(SlangParameterCategory category, UInt spaceIndex, UInt registerIndex, bool& outUsed)
- {
- if (!postEmitMetadata)
- return SLANG_E_NOT_AVAILABLE;
-
- if (!ShaderBindingRange::isUsageTracked((slang::ParameterCategory)category))
- return SLANG_E_NOT_AVAILABLE;
- // TODO: optimize this with a binary search through a sorted list
- for (const auto& range : postEmitMetadata->usedBindings)
- {
- if (range.containsBinding((slang::ParameterCategory)category, spaceIndex, registerIndex))
- {
- outUsed = true;
- return SLANG_OK;
- }
- }
-
- outUsed = false;
- return SLANG_OK;
- }
+#endif
//
// FrontEndEntryPointRequest
@@ -729,13 +667,20 @@ namespace Slang
}
}
- SlangResult CodeGenContext::emitEntryPointsSource(
- String& outSource,
- RefPtr<PostEmitMetadata>& outMetadata)
+#if SLANG_VC
+// TODO(JS): This is a workaround
+// In debug VS builds there is a warning on line about it being unreachable.
+// for (auto entryPointIndex : getEntryPointIndices())
+// It's not clear how that could possibly be unreachable
+# pragma warning(push)
+# pragma warning(disable:4702)
+#endif
+ SlangResult CodeGenContext::emitEntryPointsSource(ComPtr<IArtifact>& outArtifact)
{
- outSource = String();
+ outArtifact.setNull();
- if(auto endToEndReq = isPassThroughEnabled())
+ auto endToEndReq = isPassThroughEnabled();
+ if(endToEndReq)
{
for (auto entryPointIndex : getEntryPointIndices())
{
@@ -776,16 +721,22 @@ namespace Slang
}
}
- outSource = codeBuilder.ProduceString();
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(getTargetFormat()));
+ artifact->addRepresentationUnknown(StringBlob::moveCreate(codeBuilder));
+
+ outArtifact.swap(artifact);
+ return SLANG_OK;
}
return SLANG_OK;
}
else
{
- return emitEntryPointsSourceFromIR(
- outSource, outMetadata);
+ return emitEntryPointsSourceFromIR(outArtifact);
}
}
+#if SLANG_VC
+# pragma warning(pop)
+#endif
String GetHLSLProfileName(Profile profile)
{
@@ -1052,11 +1003,9 @@ namespace Slang
return desc.style == ArtifactStyle::Host;
}
- SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(
- RefPtr<DownstreamCompileResult>& outResult,
- RefPtr<PostEmitMetadata>& outMetadata)
+ SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(ComPtr<IArtifact>& outArtifact)
{
- outResult.setNull();
+ outArtifact.setNull();
auto sink = getSink();
auto session = getSession();
@@ -1123,6 +1072,8 @@ namespace Slang
}
}
+ ComPtr<IArtifact> sourceContainerArtifact;
+
/* This is more convoluted than the other scenarios, because when we invoke C/C++ compiler we would ideally like
to use the original file. We want to do this because we want includes relative to the source file to work, and
for that to work most easily we want to use the original file, if there is one */
@@ -1189,7 +1140,10 @@ namespace Slang
options.sourceContentsPath = calcSourcePathForEntryPoints();
CodeGenContext sourceCodeGenContext(this, sourceTarget, extensionTracker);
- SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(options.sourceContents, outMetadata));
+
+ SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceContainerArtifact));
+
+ sourceCodeGenContext.maybeDumpIntermediate(sourceContainerArtifact);
}
else
{
@@ -1206,12 +1160,32 @@ namespace Slang
else
{
CodeGenContext sourceCodeGenContext(this, sourceTarget, extensionTracker);
- SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(options.sourceContents, outMetadata));
- sourceCodeGenContext.maybeDumpIntermediate(options.sourceContents.getBuffer());
+
+ SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceContainerArtifact));
+ sourceCodeGenContext.maybeDumpIntermediate(sourceContainerArtifact);
sourceLanguage = (SourceLanguage)TypeConvertUtil::getSourceLanguageFromTarget((SlangCompileTarget)sourceTarget);
}
+ ComPtr<IArtifact> metadata;
+ if (sourceContainerArtifact)
+ {
+ auto sourceArtifact = sourceContainerArtifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren,
+ ArtifactDesc::make(ArtifactKind::Source, ArtifactPayload::Base, ArtifactStyle::Base));
+ if (!sourceArtifact)
+ {
+ return SLANG_FAIL;
+ }
+
+ metadata = sourceContainerArtifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren,
+ ArtifactDesc::make(ArtifactKind::Base, ArtifactPayload::PostEmitMetadata, ArtifactStyle::Base));
+
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(sourceArtifact->loadBlob(ArtifactKeep::No, blob.writeRef()));
+
+ options.sourceContents = StringUtil::getString(blob);
+ }
+
// Add any preprocessor definitions associated with the linkage
{
// TODO(JS): This is somewhat arguable - should defines passed to Slang really be
@@ -1539,7 +1513,22 @@ namespace Slang
return SLANG_FAIL;
}
- outResult = downstreamCompileResult;
+ auto artifactContainer = ArtifactUtil::createResultsContainer();
+
+ if (metadata)
+ {
+ artifactContainer->addChild(metadata);
+ }
+
+ // Create the artifact that encapsulates the result
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target));
+
+ // Wrap the downstream compile result
+ auto objRep = new ObjectArtifactRepresentation(DownstreamCompileResult::getTypeGuid(), downstreamCompileResult);
+ artifact->addRepresentation(objRep);
+
+ // Set the artifact
+ outArtifact.swap(artifact);
return SLANG_OK;
}
@@ -1588,8 +1577,7 @@ namespace Slang
SlangResult emitSPIRVForEntryPointsDirectly(
CodeGenContext* codeGenContext,
- List<uint8_t>& spirvOut,
- RefPtr<PostEmitMetadata>& outMetadata);
+ ComPtr<IArtifact>& outArtifact);
static CodeGenTarget _getIntermediateTarget(CodeGenTarget target)
{
@@ -1603,9 +1591,7 @@ namespace Slang
}
/// Function to simplify the logic around emitting, and dissassembling
- SlangResult CodeGenContext::_emitEntryPoints(
- RefPtr<DownstreamCompileResult>& outDownstreamResult,
- RefPtr<PostEmitMetadata>& outMetadata)
+ SlangResult CodeGenContext::_emitEntryPoints(ComPtr<IArtifact>& outArtifact)
{
auto target = getTargetFormat();
switch (target)
@@ -1618,25 +1604,37 @@ namespace Slang
const CodeGenTarget intermediateTarget = _getIntermediateTarget(target);
CodeGenContext intermediateContext(this, intermediateTarget);
- RefPtr<DownstreamCompileResult> code;
- SLANG_RETURN_ON_FAIL(intermediateContext._emitEntryPoints(code, outMetadata));
- intermediateContext.maybeDumpIntermediate(code);
+ ComPtr<IArtifact> intermediateArtifact;
+
+ SLANG_RETURN_ON_FAIL(intermediateContext._emitEntryPoints(intermediateArtifact));
+ intermediateContext.maybeDumpIntermediate(intermediateArtifact);
+
+ IArtifact* binaryArtifact = intermediateArtifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren,
+ ArtifactDesc::make(ArtifactKind::BinaryLike, ArtifactPayload::Base, ArtifactStyle::Base));
+ if (!binaryArtifact)
+ {
+ return SLANG_FAIL;
+ }
+
+ ComPtr<ISlangBlob> binaryBlob;
+ SLANG_RETURN_ON_FAIL(binaryArtifact->loadBlob(ArtifactKeep::No, binaryBlob.writeRef()));
// Then disassemble the intermediate binary result to get the desired output
// Output the disassembly
ComPtr<ISlangBlob> disassemblyBlob;
- SLANG_RETURN_ON_FAIL(intermediateContext.dissassembleWithDownstream(code, disassemblyBlob.writeRef()));
+ SLANG_RETURN_ON_FAIL(intermediateContext.dissassembleWithDownstream(binaryBlob->getBufferPointer(), binaryBlob->getBufferSize(), disassemblyBlob.writeRef()));
+
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target));
+ artifact->addRepresentationUnknown(disassemblyBlob);
+
+ outArtifact.swap(artifact);
- outDownstreamResult = new BlobDownstreamCompileResult(DownstreamDiagnostics(), disassemblyBlob);
return SLANG_OK;
}
case CodeGenTarget::SPIRV:
if (getTargetReq()->shouldEmitSPIRVDirectly())
{
- List<uint8_t> spirv;
- SLANG_RETURN_ON_FAIL(emitSPIRVForEntryPointsDirectly(this, spirv, outMetadata));
- auto spirvBlob = ListBlob::moveCreate(spirv);
- outDownstreamResult = new BlobDownstreamCompileResult(DownstreamDiagnostics(), spirvBlob);
+ SLANG_RETURN_ON_FAIL(emitSPIRVForEntryPointsDirectly(this, outArtifact));
return SLANG_OK;
}
/* fall through to: */
@@ -1647,7 +1645,7 @@ namespace Slang
case CodeGenTarget::ShaderSharedLibrary:
case CodeGenTarget::HostExecutable:
case CodeGenTarget::HostHostCallable:
- SLANG_RETURN_ON_FAIL(emitWithDownstreamForEntryPoints(outDownstreamResult, outMetadata));
+ SLANG_RETURN_ON_FAIL(emitWithDownstreamForEntryPoints(outArtifact));
return SLANG_OK;
default: break;
@@ -1657,10 +1655,8 @@ namespace Slang
}
// Do emit logic for a zero or more entry points
- CompileResult CodeGenContext::emitEntryPoints()
+ SlangResult CodeGenContext::emitEntryPoints(ComPtr<IArtifact>& outArtifact)
{
- CompileResult result;
-
auto target = getTargetFormat();
switch (target)
@@ -1677,14 +1673,10 @@ namespace Slang
case CodeGenTarget::ShaderSharedLibrary:
case CodeGenTarget::HostExecutable:
{
- RefPtr<DownstreamCompileResult> downstreamResult;
- RefPtr<PostEmitMetadata> metadata;
+ SLANG_RETURN_ON_FAIL(_emitEntryPoints(outArtifact));
- if (SLANG_SUCCEEDED(_emitEntryPoints(downstreamResult, metadata)))
- {
- maybeDumpIntermediate(downstreamResult);
- result = CompileResult(downstreamResult, metadata);
- }
+ maybeDumpIntermediate(outArtifact);
+ return SLANG_OK;
}
break;
case CodeGenTarget::GLSL:
@@ -1695,35 +1687,31 @@ namespace Slang
case CodeGenTarget::CSource:
{
RefPtr<ExtensionTracker> extensionTracker = _newExtensionTracker(target);
- RefPtr<PostEmitMetadata> metadata;
-
+
CodeGenContext subContext(this, target, extensionTracker);
- String code;
- if (SLANG_FAILED(subContext.emitEntryPointsSource(code, metadata)))
- {
- return result;
- }
+ ComPtr<IArtifact> sourceArtifact;
+
+ SLANG_RETURN_ON_FAIL(subContext.emitEntryPointsSource(sourceArtifact));
- subContext.maybeDumpIntermediate(code.getBuffer());
- result = CompileResult(code, metadata);
+ subContext.maybeDumpIntermediate(sourceArtifact);
+ outArtifact = sourceArtifact;
+ return SLANG_OK;
}
break;
case CodeGenTarget::None:
// The user requested no output
- break;
+ return SLANG_OK;
// Note(tfoley): We currently hit this case when compiling the stdlib
case CodeGenTarget::Unknown:
- break;
+ return SLANG_OK;
default:
SLANG_UNEXPECTED("unhandled code generation target");
break;
}
-
- return result;
}
enum class OutputFileKind
@@ -1792,42 +1780,31 @@ namespace Slang
static void writeCompileResultToFile(
CodeGenContext* context,
String const& outputPath,
- CompileResult const& result)
+ IArtifact* inArtifact)
{
- switch (result.format)
+ // The artifact can contain multiple things, we want to find something like 'source' or binary like
+ IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact);
+ if (!artifact)
{
- case ResultFormat::Text:
- {
- auto text = result.outputString;
- writeOutputFile(context,
- outputPath,
- text.begin(),
- text.end() - text.begin(),
- OutputFileKind::Text);
- }
- break;
-
- case ResultFormat::Binary:
- {
- ComPtr<ISlangBlob> blob;
- if (SLANG_FAILED(result.getBlob(blob)))
- {
- SLANG_UNEXPECTED("No blob to emit");
- return;
- }
- writeOutputFile(context,
- outputPath,
- blob->getBufferPointer(),
- blob->getBufferSize(),
- OutputFileKind::Binary);
- }
- break;
+ return;
+ }
- default:
- SLANG_UNEXPECTED("unhandled output format");
- break;
+ ComPtr<ISlangBlob> blob;
+ if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef())))
+ {
+ // Unable to get blob
+ return;
}
+ const auto outputKind = ArtifactDescUtil::isText(artifact->getDesc()) ?
+ OutputFileKind::Text :
+ OutputFileKind::Binary;
+
+ writeOutputFile(context,
+ outputPath,
+ (const char*)blob->getBufferPointer(),
+ blob->getBufferSize(),
+ outputKind);
}
static void writeOutputToConsole(
@@ -1840,99 +1817,65 @@ namespace Slang
static void writeCompileResultToStandardOutput(
CodeGenContext* codeGenContext,
EndToEndCompileRequest* endToEndReq,
- CompileResult const& result)
+ IArtifact* inArtifact)
{
- auto targetReq = codeGenContext->getTargetReq();
ISlangWriter* writer = endToEndReq->getWriter(WriterChannel::StdOutput);
- switch (result.format)
+ // The artifact can contain multiple things, we want to find something like 'source' or binary like
+ IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact);
+ if (!artifact)
{
- case ResultFormat::Text:
- writeOutputToConsole(writer, result.outputString);
- break;
-
- case ResultFormat::Binary:
- {
- ComPtr<ISlangBlob> blob;
- if (SLANG_FAILED(result.getBlob(blob)))
- {
- if (ArtifactDescUtil::makeDescFromCompileTarget(asExternal(targetReq->getTarget())).kind == ArtifactKind::HostCallable)
- {
- // Some HostCallable are not directly representable as a 'binary'.
- // So here, we just ignore if that appears the case, and don't output an unexpected error.
- return;
- }
+ return;
+ }
- SLANG_UNEXPECTED("No blob to emit");
- return;
- }
+ ComPtr<ISlangBlob> blob;
+ if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef())))
+ {
+ // Unable to get blob
+ return;
+ }
- const void* blobData = blob->getBufferPointer();
- size_t blobSize = blob->getBufferSize();
+ // If is text, we can just output
+ if (ArtifactDescUtil::isText(artifact->getDesc()))
+ {
+ writer->write((const char*)blob->getBufferPointer(), blob->getBufferSize());
+ return;
+ }
- if (writer->isConsole())
+ if (writer->isConsole())
+ {
+ switch (artifact->getDesc().payload)
+ {
+ case ArtifactPayload::SPIRV:
+ case ArtifactPayload::DXIL:
+ case ArtifactPayload::DXBC:
{
- // Writing to console, so we need to generate text output.
+ ComPtr<ISlangBlob> disassemblyBlob;
- switch (targetReq->getTarget())
+ if (SLANG_SUCCEEDED(codeGenContext->dissassembleWithDownstream(blob->getBufferPointer(), blob->getBufferSize(), disassemblyBlob.writeRef())))
{
- case CodeGenTarget::SPIRVAssembly:
- case CodeGenTarget::DXBytecodeAssembly:
- case CodeGenTarget::DXILAssembly:
- {
- const UnownedStringSlice disassembly = StringUtil::getSlice(blob);
- writeOutputToConsole(writer, disassembly);
- }
- break;
- case CodeGenTarget::SPIRV:
- case CodeGenTarget::DXIL:
- case CodeGenTarget::DXBytecode:
- {
- ComPtr<ISlangBlob> disassemblyBlob;
-
- if (SLANG_SUCCEEDED(codeGenContext->dissassembleWithDownstream(blobData, blobSize, disassemblyBlob.writeRef())))
- {
- const UnownedStringSlice disassembly = StringUtil::getSlice(disassemblyBlob);
- writeOutputToConsole(writer, disassembly);
- }
- }
- break;
- case CodeGenTarget::PTX:
- // For now we just dump PTX out as hex
-
- case CodeGenTarget::HostHostCallable:
- case CodeGenTarget::ShaderHostCallable:
- case CodeGenTarget::ShaderSharedLibrary:
- case CodeGenTarget::HostExecutable:
- HexDumpUtil::dumpWithMarkers((const uint8_t*)blobData, blobSize, 24, writer);
- break;
-
-
- default:
- SLANG_UNEXPECTED("unhandled output format");
- return;
- }
+ const UnownedStringSlice disassembly = StringUtil::getSlice(disassemblyBlob);
+ writeOutputToConsole(writer, disassembly);
+ }
+ return;
}
- else
- {
- // Redirecting stdout to a file, so do the usual thing
- writer->setMode(SLANG_WRITER_MODE_BINARY);
-
- writeOutputFile(
- codeGenContext,
- writer,
- "stdout",
- blobData,
- blobSize);
}
- }
- break;
- default:
- SLANG_UNEXPECTED("unhandled output format");
- break;
+ // Else just dump as text
+ HexDumpUtil::dumpWithMarkers((const uint8_t*)blob->getBufferPointer(), blob->getBufferSize(), 24, writer);
}
+ else
+ {
+ // Redirecting stdout to a file, so do the usual thing
+ writer->setMode(SLANG_WRITER_MODE_BINARY);
+ writeOutputFile(
+ codeGenContext,
+ writer,
+ "stdout",
+ blob->getBufferPointer(),
+ blob->getBufferSize());
+ }
}
void EndToEndCompileRequest::writeWholeProgramResult(
@@ -1941,10 +1884,10 @@ namespace Slang
auto program = getSpecializedGlobalAndEntryPointsComponentType();
auto targetProgram = program->getTargetProgram(targetReq);
- auto& result = targetProgram->getExistingWholeProgramResult();
+ IArtifact* artifact = targetProgram->getExistingWholeProgramResult();
// Skip the case with no output
- if (result.format == ResultFormat::None)
+ if (artifact == nullptr)
return;
CodeGenContext::EntryPointIndices entryPointIndices;
@@ -1964,12 +1907,12 @@ namespace Slang
String outputPath = targetInfo->wholeTargetOutputPath;
if (outputPath != "")
{
- writeCompileResultToFile(&codeGenContext, outputPath, result);
+ writeCompileResultToFile(&codeGenContext, outputPath, artifact);
return;
}
}
- writeCompileResultToStandardOutput(&codeGenContext, this, result);
+ writeCompileResultToStandardOutput(&codeGenContext, this, artifact);
}
void EndToEndCompileRequest::writeEntryPointResult(
@@ -1979,10 +1922,10 @@ namespace Slang
auto program = getSpecializedGlobalAndEntryPointsComponentType();
auto targetProgram = program->getTargetProgram(targetReq);
- auto& result = targetProgram->getExistingEntryPointResult(entryPointIndex);
+ IArtifact* artifact = targetProgram->getExistingEntryPointResult(entryPointIndex);
// Skip the case with no output
- if (result.format == ResultFormat::None)
+ if (artifact == nullptr)
return;
CodeGenContext::EntryPointIndices entryPointIndices;
@@ -2003,15 +1946,15 @@ namespace Slang
String outputPath;
if(targetInfo->entryPointOutputPaths.TryGetValue(entryPointIndex, outputPath))
{
- writeCompileResultToFile(&codeGenContext, outputPath, result);
+ writeCompileResultToFile(&codeGenContext, outputPath, artifact);
return;
}
}
- writeCompileResultToStandardOutput(&codeGenContext, this, result);
+ writeCompileResultToStandardOutput(&codeGenContext, this, artifact);
}
- CompileResult& TargetProgram::_createWholeProgramResult(
+ IArtifact* TargetProgram::_createWholeProgramResult(
DiagnosticSink* sink,
EndToEndCompileRequest* endToEndReq)
{
@@ -2026,17 +1969,18 @@ namespace Slang
for (Index i = 0; i < entryPointIndices.getCount(); i++)
entryPointIndices[i] = i;
- auto& result = m_wholeProgramResult;
-
CodeGenContext::Shared sharedCodeGenContext(this, entryPointIndices, sink, endToEndReq);
CodeGenContext codeGenContext(&sharedCodeGenContext);
- result = codeGenContext.emitEntryPoints();
-
- return result;
+ if (SLANG_FAILED(codeGenContext.emitEntryPoints(m_wholeProgramResult)))
+ {
+ return nullptr;
+ }
+
+ return m_wholeProgramResult;
}
- CompileResult& TargetProgram::_createEntryPointResult(
+ IArtifact* TargetProgram::_createEntryPointResult(
Int entryPointIndex,
DiagnosticSink* sink,
EndToEndCompileRequest* endToEndReq)
@@ -2050,26 +1994,25 @@ namespace Slang
// this problem.
//
if(entryPointIndex >= m_entryPointResults.getCount())
- m_entryPointResults.setCount(entryPointIndex+1);
-
- auto& result = m_entryPointResults[entryPointIndex];
+ m_entryPointResults.setCount(entryPointIndex + 1);
+
CodeGenContext::EntryPointIndices entryPointIndices;
entryPointIndices.add(entryPointIndex);
CodeGenContext::Shared sharedCodeGenContext(this, entryPointIndices, sink, endToEndReq);
CodeGenContext codeGenContext(&sharedCodeGenContext);
- result = codeGenContext.emitEntryPoints();
- return result;
+ codeGenContext.emitEntryPoints(m_entryPointResults[entryPointIndex]);
+
+ return m_entryPointResults[entryPointIndex];
}
- CompileResult& TargetProgram::getOrCreateWholeProgramResult(
+ IArtifact* TargetProgram::getOrCreateWholeProgramResult(
DiagnosticSink* sink)
{
- auto& result = m_wholeProgramResult;
- if (result.format != ResultFormat::None)
- return result;
+ if (m_wholeProgramResult)
+ return m_wholeProgramResult;
// If we haven't yet computed a layout for this target
// program, we need to make sure that is done before
@@ -2077,22 +2020,21 @@ namespace Slang
//
if (!getOrCreateIRModuleForLayout(sink))
{
- return result;
+ return nullptr;
}
return _createWholeProgramResult(sink);
}
- CompileResult& TargetProgram::getOrCreateEntryPointResult(
+ IArtifact* TargetProgram::getOrCreateEntryPointResult(
Int entryPointIndex,
DiagnosticSink* sink)
{
if(entryPointIndex >= m_entryPointResults.getCount())
- m_entryPointResults.setCount(entryPointIndex+1);
+ m_entryPointResults.setCount(entryPointIndex + 1);
- auto& result = m_entryPointResults[entryPointIndex];
- if( result.format != ResultFormat::None )
- return result;
+ if(IArtifact* artifact = m_entryPointResults[entryPointIndex])
+ return artifact;
// If we haven't yet computed a layout for this target
// program, we need to make sure that is done before
@@ -2100,7 +2042,7 @@ namespace Slang
//
if( !getOrCreateIRModuleForLayout(sink) )
{
- return result;
+ return nullptr;
}
return _createEntryPointResult(
@@ -2492,6 +2434,59 @@ namespace Slang
return nullptr;
}
+ void CodeGenContext::maybeDumpIntermediate(IArtifact* inArtifact)
+ {
+ if (!shouldDumpIntermediates())
+ return;
+
+ IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact);
+ if (!artifact)
+ {
+ return;
+ }
+
+ ComPtr<ISlangBlob> blob;
+ if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef())))
+ {
+ return;
+ }
+
+ const auto desc = artifact->getDesc();
+ String ext = ArtifactDescUtil::getDefaultExtension(desc);
+
+
+ if (ArtifactDescUtil::isText(artifact->getDesc()))
+ {
+ dumpIntermediateText(blob->getBufferPointer(), blob->getBufferSize(), ext.getBuffer());
+ }
+ else
+ {
+ switch (artifact->getDesc().payload)
+ {
+ case ArtifactPayload::SPIRV:
+ case ArtifactPayload::DXIL:
+ case ArtifactPayload::DXBC:
+ {
+ ComPtr<ISlangBlob> disassemblyBlob;
+
+ if (SLANG_SUCCEEDED(dissassembleWithDownstream(blob->getBufferPointer(), blob->getBufferSize(), disassemblyBlob.writeRef())))
+ {
+ ArtifactDesc assemblyDesc(desc);
+ assemblyDesc.kind = ArtifactKind::Assembly;
+
+ ext = ArtifactDescUtil::getDefaultExtension(assemblyDesc);
+
+ dumpIntermediateText(disassemblyBlob->getBufferPointer(), disassemblyBlob->getBufferSize(), ext.getBuffer());
+ return;
+ }
+ }
+ default: break;
+ }
+
+ dumpIntermediateBinary(blob->getBufferPointer(), blob->getBufferSize(), ext.getBuffer());
+ }
+ }
+
void CodeGenContext::maybeDumpIntermediate(
void const* data,
size_t size)
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 56e161483..9f75d94d3 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -144,11 +144,7 @@ namespace Slang
class Module;
class TranslationUnitRequest;
- struct PostEmitMetadata : public RefObject
- {
- List<ShaderBindingRange> usedBindings;
- };
-
+#if 0
// Result of compiling an entry point.
// Should only ever be string, binary or shared library
class CompileResult
@@ -187,6 +183,7 @@ namespace Slang
RefPtr<PostEmitMetadata> postEmitMetadata;
};
+#endif
/// Information collected about global or entry-point shader parameters
struct ShaderParamInfo
@@ -2171,11 +2168,10 @@ namespace Slang
/// been requested, report any errors that arise during
/// code generation to the given `sink`.
///
- CompileResult& getOrCreateEntryPointResult(Int entryPointIndex, DiagnosticSink* sink);
- CompileResult& getOrCreateWholeProgramResult(DiagnosticSink* sink);
+ IArtifact* getOrCreateEntryPointResult(Int entryPointIndex, DiagnosticSink* sink);
+ IArtifact* getOrCreateWholeProgramResult(DiagnosticSink* sink);
-
- CompileResult& getExistingWholeProgramResult()
+ IArtifact* getExistingWholeProgramResult()
{
return m_wholeProgramResult;
}
@@ -2184,12 +2180,12 @@ namespace Slang
/// This routine assumes that `getOrCreateEntryPointResult`
/// has already been called previously.
///
- CompileResult& getExistingEntryPointResult(Int entryPointIndex)
+ IArtifact* getExistingEntryPointResult(Int entryPointIndex)
{
return m_entryPointResults[entryPointIndex];
}
- CompileResult& _createWholeProgramResult(
+ IArtifact* _createWholeProgramResult(
DiagnosticSink* sink,
EndToEndCompileRequest* endToEndReq = nullptr);
@@ -2200,7 +2196,7 @@ namespace Slang
///
/// Shouldn't be called directly by most code.
///
- CompileResult& _createEntryPointResult(
+ IArtifact* _createEntryPointResult(
Int entryPointIndex,
DiagnosticSink* sink,
EndToEndCompileRequest* endToEndReq = nullptr);
@@ -2227,8 +2223,8 @@ namespace Slang
// Generated compile results for each entry point
// in the parent `Program` (indexing matches
// the order they are given in the `Program`)
- CompileResult m_wholeProgramResult;
- List<CompileResult> m_entryPointResults;
+ ComPtr<IArtifact> m_wholeProgramResult;
+ List<ComPtr<IArtifact>> m_entryPointResults;
RefPtr<IRModule> m_irModuleForLayout;
};
@@ -2416,7 +2412,7 @@ namespace Slang
//
- CompileResult emitEntryPoints();
+ SlangResult emitEntryPoints(ComPtr<IArtifact>& outArtifact);
SlangResult dissassembleWithDownstream(
const void* data,
@@ -2431,6 +2427,8 @@ namespace Slang
CodeGenTarget m_targetFormat = CodeGenTarget::Unknown;
ExtensionTracker* m_extensionTracker = nullptr;
+ void maybeDumpIntermediate(IArtifact* artifact);
+
// Helper to dump intermediate output when debugging
void maybeDumpIntermediate(
void const* data,
@@ -2459,17 +2457,11 @@ namespace Slang
/* Emits entry point source taking into account if a pass-through or not. Uses 'targetFormat' to determine
the target (not targetReq) */
- SlangResult emitEntryPointsSource(
- String& outSource,
- RefPtr<PostEmitMetadata>& outMetadata);
-
- SlangResult emitEntryPointsSourceFromIR(
- String& outSource,
- RefPtr<PostEmitMetadata>& outMetadata);
+ SlangResult emitEntryPointsSource(ComPtr<IArtifact>& outArtifact);
- SlangResult emitWithDownstreamForEntryPoints(
- RefPtr<DownstreamCompileResult>& outResult,
- RefPtr<PostEmitMetadata>& outMetadata);
+ SlangResult emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outArtifact);
+
+ SlangResult emitWithDownstreamForEntryPoints(ComPtr<IArtifact>& outArtifact);
/* Determines a suitable filename to identify the input for a given entry point being compiled.
If the end-to-end compile is a pass-through case, will attempt to find the (unique) source file
@@ -2484,9 +2476,7 @@ namespace Slang
Int entryPointIndex);
- SlangResult _emitEntryPoints(
- RefPtr<DownstreamCompileResult>& outDownstreamResult,
- RefPtr<PostEmitMetadata>& outMetadata);
+ SlangResult _emitEntryPoints(ComPtr<IArtifact>& outArtifact);
private:
Shared* m_shared = nullptr;
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index f3e78e48f..43f9da3df 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -69,6 +69,8 @@
#include "slang-emit-cuda.h"
#include "../compiler-core/slang-artifact-desc-util.h"
+#include "../compiler-core/slang-artifact-util.h"
+#include "../compiler-core/slang-artifact-impl.h"
#include <assert.h>
@@ -834,17 +836,20 @@ Result linkAndOptimizeIR(
#endif
validateIRModuleIfEnabled(codeGenContext, irModule);
- outLinkedIR.metadata = new PostEmitMetadata();
- collectMetadata(irModule, *outLinkedIR.metadata);
+ auto metadata = Artifact::create(ArtifactDesc::make(ArtifactKind::Instance, ArtifactPayload::PostEmitMetadata, artifactDesc.style));
+ auto postEmitMetaRep = new PostEmitMetadataArtifactRepresentation;
+ metadata->addRepresentation(postEmitMetaRep);
+
+ collectMetadata(irModule, postEmitMetaRep->m_metadata);
+
+ outLinkedIR.metadata = metadata;
return SLANG_OK;
}
-SlangResult CodeGenContext::emitEntryPointsSourceFromIR(
- String& outSource,
- RefPtr<PostEmitMetadata>& outMetadata)
+SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outArtifact)
{
- outSource = String();
+ outArtifact.setNull();
auto session = getSession();
auto sink = getSink();
@@ -852,6 +857,8 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(
auto target = getTargetFormat();
auto targetRequest = getTargetReq();
+ auto artifactContainer = ArtifactUtil::createResultsContainer();
+
auto lineDirectiveMode = targetRequest->getLineDirectiveMode();
// To try to make the default behavior reasonable, we will
// always use C-style line directives (to give the user
@@ -923,6 +930,7 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(
SLANG_RETURN_ON_FAIL(sourceEmitter->init());
+
{
LinkingAndOptimizationOptions linkingAndOptimizationOptions;
@@ -947,8 +955,11 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(
auto irModule = linkedIR.module;
- outMetadata = linkedIR.metadata;
-
+ if (linkedIR.metadata)
+ {
+ artifactContainer->addChild(linkedIR.metadata);
+ }
+
// After all of the required optimization and legalization
// passes have been performed, we can emit target code from
// the IR module.
@@ -1017,7 +1028,13 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(
finalResult.append(code);
// Write out the result
- outSource = finalResult;
+
+ auto targetArtifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target));
+ targetArtifact->addRepresentationUnknown(StringBlob::moveCreate(finalResult));
+
+ artifactContainer->addChild(targetArtifact);
+
+ outArtifact = artifactContainer;
return SLANG_OK;
}
@@ -1029,9 +1046,10 @@ SlangResult emitSPIRVFromIR(
SlangResult emitSPIRVForEntryPointsDirectly(
CodeGenContext* codeGenContext,
- List<uint8_t>& spirvOut,
- RefPtr<PostEmitMetadata>& outMetadata)
+ ComPtr<IArtifact>& outArtifact)
{
+ auto artifactContainer = ArtifactUtil::createResultsContainer();
+
// Outside because we want to keep IR in scope whilst we are processing emits
LinkedIR linkedIR;
LinkingAndOptimizationOptions linkingAndOptimizationOptions;
@@ -1043,13 +1061,22 @@ SlangResult emitSPIRVForEntryPointsDirectly(
auto irModule = linkedIR.module;
auto irEntryPoints = linkedIR.entryPoints;
- emitSPIRVFromIR(codeGenContext, irModule, irEntryPoints, spirvOut);
+ List<uint8_t> spirv;
+ emitSPIRVFromIR(codeGenContext, irModule, irEntryPoints, spirv);
- outMetadata = linkedIR.metadata;
+ auto targetArtifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(codeGenContext->getTargetFormat()));
+ targetArtifact->addRepresentationUnknown(ListBlob::moveCreate(spirv));
- return SLANG_OK;
-}
+ artifactContainer->addChild(targetArtifact);
+ if (linkedIR.metadata)
+ {
+ artifactContainer->addChild(linkedIR.metadata);
+ }
+
+ outArtifact = artifactContainer;
+ return SLANG_OK;
+}
} // namespace Slang
diff --git a/source/slang/slang-ir-link.h b/source/slang/slang-ir-link.h
index 798013a8d..dcfb642da 100644
--- a/source/slang/slang-ir-link.h
+++ b/source/slang/slang-ir-link.h
@@ -12,7 +12,7 @@ namespace Slang
RefPtr<IRModule> module;
IRVarLayout* globalScopeVarLayout;
List<IRFunc*> entryPoints;
- RefPtr<PostEmitMetadata> metadata;
+ ComPtr<IArtifact> metadata;
};
diff --git a/source/slang/slang-ir-metadata.cpp b/source/slang/slang-ir-metadata.cpp
index cc5922e93..396c40837 100644
--- a/source/slang/slang-ir-metadata.cpp
+++ b/source/slang/slang-ir-metadata.cpp
@@ -4,6 +4,8 @@
#include "slang-ir.h"
#include "slang-ir-insts.h"
+#include "../compiler-core/slang-artifact-representation-impl.h"
+
namespace Slang
{
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index c0c7c4f5a..6515dc35d 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -10,6 +10,7 @@
// Artifact
#include "../compiler-core/slang-artifact-impl.h"
#include "../compiler-core/slang-artifact-desc-util.h"
+#include "../compiler-core/slang-artifact-util.h"
#include "slang-module-library.h"
@@ -3151,16 +3152,20 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointCode(
auto targetProgram = getTargetProgram(target);
DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer);
- auto& entryPointResult = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink);
+
+ IArtifact* entryPointResult = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink);
sink.getBlobIfNeeded(outDiagnostics);
- if(entryPointResult.format == ResultFormat::None )
+ if(entryPointResult == nullptr)
return SLANG_FAIL;
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(entryPointResult.getBlob(blob));
- *outCode = blob.detach();
- return SLANG_OK;
+ IArtifact* significantBlob = ArtifactUtil::findSignificant(entryPointResult);
+ if (!significantBlob)
+ {
+ return SLANG_FAIL;
+ }
+
+ return significantBlob->loadBlob(ArtifactKeep::Yes, outCode);
}
SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable(
@@ -3177,17 +3182,13 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable(
auto targetProgram = getTargetProgram(target);
DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer);
- auto& entryPointResult = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink);
+ IArtifact* artifact = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink);
sink.getBlobIfNeeded(outDiagnostics);
- if(entryPointResult.format == ResultFormat::None )
+ if(artifact == nullptr)
return SLANG_FAIL;
- ComPtr<ISlangSharedLibrary> sharedLibrary;
- SLANG_RETURN_ON_FAIL(entryPointResult.getSharedLibrary(sharedLibrary));
-
- *outSharedLibrary = sharedLibrary.detach();
- return SLANG_OK;
+ return artifact->loadSharedLibrary(ArtifactKeep::Yes, outSharedLibrary);
}
RefPtr<ComponentType> ComponentType::specialize(
@@ -4757,10 +4758,14 @@ void const* EndToEndCompileRequest::getEntryPointCode(int entryPointIndex, size_
auto targetProgram = program->getTargetProgram(targetReq);
if (!targetProgram)
return nullptr;
- CompileResult& result = targetProgram->getExistingEntryPointResult(entryPointIndex);
+ IArtifact* artifact = targetProgram->getExistingEntryPointResult(entryPointIndex);
+ if (!artifact)
+ {
+ return nullptr;
+ }
ComPtr<ISlangBlob> blob;
- SLANG_RETURN_NULL_ON_FAIL(result.getBlob(blob));
+ SLANG_RETURN_NULL_ON_FAIL(artifact->loadBlob(ArtifactKeep::Yes, blob.writeRef()));
if (outSize)
{
@@ -4774,7 +4779,7 @@ static SlangResult _getEntryPointResult(
EndToEndCompileRequest* req,
int entryPointIndex,
int targetIndex,
- Slang::CompileResult** outCompileResult)
+ ComPtr<IArtifact>& outArtifact)
{
auto linkage = req->getLinkage();
auto program = req->getSpecializedGlobalAndEntryPointsComponentType();
@@ -4793,18 +4798,18 @@ static SlangResult _getEntryPointResult(
}
auto entryPointReq = program->getEntryPoint(entryPointIndex);
-
auto targetProgram = program->getTargetProgram(targetReq);
if (!targetProgram)
return SLANG_FAIL;
- *outCompileResult = &targetProgram->getExistingEntryPointResult(entryPointIndex);
+
+ outArtifact = targetProgram->getExistingEntryPointResult(entryPointIndex);
return SLANG_OK;
}
static SlangResult _getWholeProgramResult(
EndToEndCompileRequest* req,
int targetIndex,
- Slang::CompileResult** outCompileResult)
+ ComPtr<IArtifact>& outArtifact)
{
auto linkage = req->getLinkage();
auto program = req->getSpecializedGlobalAndEntryPointsComponentType();
@@ -4824,34 +4829,34 @@ static SlangResult _getWholeProgramResult(
auto targetProgram = program->getTargetProgram(targetReq);
if (!targetProgram)
return SLANG_FAIL;
- *outCompileResult = &targetProgram->getExistingWholeProgramResult();
+ outArtifact = targetProgram->getExistingWholeProgramResult();
return SLANG_OK;
}
SlangResult EndToEndCompileRequest::getEntryPointCodeBlob(int entryPointIndex, int targetIndex, ISlangBlob** outBlob)
{
if (!outBlob) return SLANG_E_INVALID_ARG;
-
- CompileResult* compileResult = nullptr;
- SLANG_RETURN_ON_FAIL(_getEntryPointResult(this, entryPointIndex, targetIndex, &compileResult));
-
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(compileResult->getBlob(blob));
- *outBlob = blob.detach();
- return SLANG_OK;
+ ComPtr<IArtifact> artifact;
+ SLANG_RETURN_ON_FAIL(_getEntryPointResult(this, entryPointIndex, targetIndex, artifact));
+ if (auto significant = ArtifactUtil::findSignificant(artifact))
+ {
+ SLANG_RETURN_ON_FAIL(significant->loadBlob(ArtifactKeep::Yes, outBlob));
+ return SLANG_OK;
+ }
+ return SLANG_E_NOT_AVAILABLE;
}
SlangResult EndToEndCompileRequest::getEntryPointHostCallable(int entryPointIndex, int targetIndex, ISlangSharedLibrary** outSharedLibrary)
{
if (!outSharedLibrary) return SLANG_E_INVALID_ARG;
-
- CompileResult* compileResult = nullptr;
- SLANG_RETURN_ON_FAIL(_getEntryPointResult(this, entryPointIndex, targetIndex, &compileResult));
-
- ComPtr<ISlangSharedLibrary> sharedLibrary;
- SLANG_RETURN_ON_FAIL(compileResult->getSharedLibrary(sharedLibrary));
- *outSharedLibrary = sharedLibrary.detach();
- return SLANG_OK;
+ ComPtr<IArtifact> artifact;
+ SLANG_RETURN_ON_FAIL(_getEntryPointResult(this, entryPointIndex, targetIndex, artifact));
+ if (auto significant = ArtifactUtil::findSignificant(artifact))
+ {
+ SLANG_RETURN_ON_FAIL(significant->loadSharedLibrary(ArtifactKeep::Yes, outSharedLibrary));
+ return SLANG_OK;
+ }
+ return SLANG_E_NOT_AVAILABLE;
}
SlangResult EndToEndCompileRequest::getTargetCodeBlob(int targetIndex, ISlangBlob** outBlob)
@@ -4859,13 +4864,15 @@ SlangResult EndToEndCompileRequest::getTargetCodeBlob(int targetIndex, ISlangBlo
if (!outBlob)
return SLANG_E_INVALID_ARG;
- CompileResult* compileResult = nullptr;
- SLANG_RETURN_ON_FAIL(_getWholeProgramResult(this, targetIndex, &compileResult));
+ ComPtr<IArtifact> artifact;
+ SLANG_RETURN_ON_FAIL(_getWholeProgramResult(this, targetIndex, artifact));
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(compileResult->getBlob(blob));
- *outBlob = blob.detach();
- return SLANG_OK;
+ if (auto significant = ArtifactUtil::findSignificant(artifact))
+ {
+ SLANG_RETURN_ON_FAIL(significant->loadBlob(ArtifactKeep::Yes, outBlob));
+ return SLANG_OK;
+ }
+ return SLANG_E_NOT_AVAILABLE;
}
SlangResult EndToEndCompileRequest::getTargetHostCallable(int targetIndex,ISlangSharedLibrary** outSharedLibrary)
@@ -4873,12 +4880,9 @@ SlangResult EndToEndCompileRequest::getTargetHostCallable(int targetIndex,ISlang
if (!outSharedLibrary)
return SLANG_E_INVALID_ARG;
- CompileResult* compileResult = nullptr;
- SLANG_RETURN_ON_FAIL(_getWholeProgramResult(this, targetIndex, &compileResult));
-
- ComPtr<ISlangSharedLibrary> sharedLibrary;
- SLANG_RETURN_ON_FAIL(compileResult->getSharedLibrary(sharedLibrary));
- *outSharedLibrary = sharedLibrary.detach();
+ ComPtr<IArtifact> artifact;
+ SLANG_RETURN_ON_FAIL(_getWholeProgramResult(this, targetIndex, artifact));
+ SLANG_RETURN_ON_FAIL(artifact->loadSharedLibrary(ArtifactKeep::Yes, outSharedLibrary));
return SLANG_OK;
}
@@ -5019,12 +5023,39 @@ SlangResult EndToEndCompileRequest::getEntryPoint(SlangInt entryPointIndex, slan
SlangResult EndToEndCompileRequest::isParameterLocationUsed(Int entryPointIndex, Int targetIndex, SlangParameterCategory category, UInt spaceIndex, UInt registerIndex, bool& outUsed)
{
- CompileResult* compileResult = nullptr;
- if (_getEntryPointResult(this, static_cast<int>(entryPointIndex), static_cast<int>(targetIndex), &compileResult) != SLANG_OK)
+ if (!ShaderBindingRange::isUsageTracked((slang::ParameterCategory)category))
+ return SLANG_E_NOT_AVAILABLE;
+
+ ComPtr<IArtifact> artifact;
+ if (SLANG_FAILED(_getEntryPointResult(this, static_cast<int>(entryPointIndex), static_cast<int>(targetIndex), artifact)))
return SLANG_E_INVALID_ARG;
- return compileResult->isParameterLocationUsed(category, spaceIndex, registerIndex, outUsed);
-}
+ // We need to find the meta data
+ IArtifact* metadataArtifact = artifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren,
+ ArtifactDesc::make(ArtifactKind::Base, ArtifactPayload::PostEmitMetadata, ArtifactStyle::Base));
+ if (!metadataArtifact)
+ {
+ return SLANG_E_NOT_AVAILABLE;
+ }
+
+ // Find a rep
+ auto metadataRep = findRepresentation<IPostEmitMetadataArtifactRepresentation>(metadataArtifact);
+ if (!metadataRep)
+ return SLANG_E_NOT_AVAILABLE;
+
+ // TODO: optimize this with a binary search through a sorted list
+ for (const auto& range : metadataRep->getBindingRanges())
+ {
+ if (range.containsBinding((slang::ParameterCategory)category, spaceIndex, registerIndex))
+ {
+ outUsed = true;
+ return SLANG_OK;
+ }
+ }
+
+ outUsed = false;
+ return SLANG_OK;
+}
} // namespace Slang