From 634f5414f332f904c7db968810b3d6f0ca253959 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 27 Apr 2022 17:53:21 -0400 Subject: Make artifact an interface (#2195) * #include an absolute path didn't work - because paths were taken to always be relative. * Compile to a dxil library. * Added CompileProduct. * Support handling of ModuleLibrary. * CacheBehavior -> Cache * Use CompileProduct for -r references. * CompileProduct -> Artifact. * Determining an artifact type on binding. * Determine binary linkability. * Added Artifact::exists. * Added ArtifactKeep. * Small fixes. * Small improvements to Artifact. * Add zip extension. * Fix some comments. * Fix multiple adding of PublicDecoration. Make public output export for DXIL/lib. Add checking for simpleDecorations such that only added once. * Use 'whole program' to identify library build. * Move slang-artifact into compiler-core. * Split out Keep free functions. * Artifact::Keep -> ArtifactKeep. * Handle libraries as artifacts. * Add -target dxil so test infrastructure knows it needs DXC. * Linking working in DXC. * Improve handling around emit for 'export'. * Add comment around Artifact name. * Render test working with linking. * Improvements around Artifact handling. * Add ArtifactPayloadInfo. * Small tidy up around artifact. * Split out code to get info about Artifacts into artifact-info.cpp/.h * IArtifact interface and IArtifactInstance interface. * Fix small issues. * Fix compilation warning issue. * Fix missing SLANG_OVERRIDE. * Small fixes to make compilation work on Visual Studio 2022. * Small improvements to Artifact interface/naming. * Added Desc with each element in IArchive to allow more flexibility in usage. * Fix clang warning issue. * Add ArtifactPayload::Diagnostics * More discussion around IArtifact usage. * Re-add slang-artifact.h which was removed during merge. * Fix typo identified in review. --- source/compiler-core/slang-artifact.cpp | 226 +++++++++++++------------------- 1 file changed, 88 insertions(+), 138 deletions(-) (limited to 'source/compiler-core/slang-artifact.cpp') diff --git a/source/compiler-core/slang-artifact.cpp b/source/compiler-core/slang-artifact.cpp index 862e7bb37..dfa9e645b 100644 --- a/source/compiler-core/slang-artifact.cpp +++ b/source/compiler-core/slang-artifact.cpp @@ -46,68 +46,24 @@ namespace Slang { /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Artifact !!!!!!!!!!!!!!!!!!!!!!!!!!! */ -Artifact::~Artifact() +void* Artifact::getInterface(const Guid& uuid) { - if (m_pathType == PathType::Temporary) - { - File::remove(m_path); - } - - for (const auto& entry : m_entries) + if (uuid == ISlangUnknown::getTypeGuid() || uuid == IArtifact::getTypeGuid()) { - // Release the associated data - switch (entry.type) - { - case Entry::Type::ObjectInstance: - { - entry.object->releaseReference(); - break; - } - case Entry::Type::InterfaceInstance: - { - entry.intf->release(); - break; - } - default: break; - } + return static_cast(this); } + return nullptr; } -Index Artifact::indexOf(Entry::Type type) const -{ - return m_entries.findFirstIndex([&](const Entry& entry) -> bool { return entry.type == type; }); -} - -void Artifact::add(Entry::Style style, RefObject* obj) -{ - SLANG_ASSERT(obj); - - Entry entry; - entry.type = Entry::Type::ObjectInstance; - entry.style = style; - entry.object = obj; - - obj->addReference(); - - m_entries.add(entry); -} - -void Artifact::add(Entry::Style style, ISlangUnknown* intf) +Artifact::~Artifact() { - // Can't be nullptr - SLANG_ASSERT(intf); - - Entry entry; - entry.type = Entry::Type::InterfaceInstance; - entry.style = style; - - intf->addRef(); - - entry.intf = intf; - m_entries.add(entry); + if (m_pathType == PathType::Temporary) + { + File::remove(m_path); + } } -bool Artifact::exists() const +bool Artifact::exists() { // If we have a blob it exists if (m_blob) @@ -116,13 +72,9 @@ bool Artifact::exists() const } // If we have an associated entry that represents the artifact it exists - for (const auto& entry : m_entries) + if (findElement(IArtifactInstance::getTypeGuid())) { - if (entry.style == Entry::Style::Artifact) - { - // There is a representation that 'is' the artifact - return true; - } + return true; } // If we don't have a path then it can't exist @@ -135,78 +87,55 @@ bool Artifact::exists() const return File::exists(m_path); } -ISlangUnknown* Artifact::findInterfaceInstance(const Guid& guid) +ISlangUnknown* Artifact::findElement(const Guid& guid) { - for (const auto& entry : m_entries) + for (auto const& element : m_elements) { - if (entry.type == Entry::Type::InterfaceInstance) - { - ISlangUnknown* intf = nullptr; - if (SLANG_SUCCEEDED(entry.intf->queryInterface(guid, (void**)&intf)) && intf) - { - // NOTE! This assumes we *DONT* need to ref count to keep an interface in scope - // (as strict COM requires so as to allow on demand interfaces). - intf->release(); + ISlangUnknown* value = element.value; - return intf; - } + ISlangUnknown* intf = nullptr; + if (SLANG_SUCCEEDED(value->queryInterface(guid, (void**)&intf)) && intf) + { + // NOTE! This assumes we *DONT* need to ref count to keep an interface in scope + // (as strict COM requires so as to allow on demand interfaces). + intf->release(); + return intf; } } return nullptr; } -/* static */String Artifact::getBaseNameFromPath(Desc& desc, const UnownedStringSlice& path) +void Artifact::addElement(const Desc& desc, ISlangUnknown* intf) +{ + SLANG_ASSERT(intf); + Element element{ desc, ComPtr(intf) }; + m_elements.add(element); +} + +void Artifact::removeElementAt(Index i) { - String name = Path::getFileName(path); + m_elements.removeAt(i); +} - const bool isSharedLibraryPrefixPlatform = SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY; - if (isSharedLibraryPrefixPlatform) +void* Artifact::findElementObject(const Guid& classGuid) +{ + ComPtr instance; + for (const auto& element : m_elements) { - // Strip lib prefix - if (ArtifactInfoUtil::isCpuBinary(desc) && - (desc.kind == ArtifactKind::Library || - desc.kind == ArtifactKind::SharedLibrary)) + ISlangUnknown* value = element.value; + + if (SLANG_SUCCEEDED(value->queryInterface(IArtifactInstance::getTypeGuid(), (void**)instance.writeRef())) && instance) { - // If it starts with lib strip it - if (name.startsWith("lib")) + void* classInstance = instance->queryObject(classGuid); + if (classInstance) { - const String stripLib = name.getUnownedSlice().tail(3); - name = stripLib; + return classInstance; } } } - // Strip any extension - { - auto descExt = ArtifactInfoUtil::getDefaultExtension(desc); - // Strip the extension if it's a match - if (descExt.getLength() && - Path::getPathExt(name) == descExt) - { - name = Path::getFileNameWithoutExt(name); - } - } - - return name; -} - -String Artifact::getBaseName() -{ - if (m_pathType != PathType::None) - { - return getBaseNameFromPath(m_desc, m_path.getUnownedSlice()); - } - return m_name; -} - -String Artifact::getParentPath() -{ - if (m_pathType != PathType::None && m_path.getLength()) - { - return Path::getParentDirectory(m_path); - } - return String(); + return nullptr; } SlangResult Artifact::requireFileLike(Keep keep) @@ -244,7 +173,7 @@ SlangResult Artifact::requireFile(Keep keep) ComPtr blob; // Get the contents as a blob. If we can't do that, then we can't write anything... - SLANG_RETURN_ON_FAIL(loadBlob(getIntermediateKeep(keep), blob)); + SLANG_RETURN_ON_FAIL(loadBlob(getIntermediateKeep(keep), blob.writeRef())); // If we have a name, make the generated name based on that name // Else just use 'slang-generated' the basis @@ -303,41 +232,62 @@ SlangResult Artifact::requireFile(Keep keep) SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize())); // Okay we can now add this as temporary path too - setPath(PathType::Temporary, path); + _setPath(PathType::Temporary, path); return SLANG_OK; } -SlangResult Artifact::loadBlob(Keep keep, ComPtr& outBlob) +SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob) { - if (m_blob) - { - outBlob = m_blob; - return SLANG_OK; - } + ComPtr blob(m_blob); - // TODO(JS): - // Strictly speaking we could *potentially* convert some other representation into - // a blob by serializing it, but we don't worry about any of that here - if (m_pathType == PathType::None) + if (!blob) { - return SLANG_E_NOT_FOUND; - } + // TODO(JS): + // Strictly speaking we could *potentially* convert some other representation into + // a blob by serializing it, but we don't worry about any of that here + if (m_pathType != PathType::None) + { + // Read into a blob + ScopedAllocation alloc; + SLANG_RETURN_ON_FAIL(File::readAllBytes(m_path, alloc)); - // Read into a blob - ScopedAllocation alloc; - SLANG_RETURN_ON_FAIL(File::readAllBytes(m_path, alloc)); + // Create as a blob + blob = RawBlob::moveCreate(alloc); + } + else + { + for (const auto& element : m_elements) + { + ISlangUnknown* intf = element.value; + + ComPtr inst; + if (SLANG_SUCCEEDED(intf->queryInterface(IArtifactInstance::getTypeGuid(), (void**)inst.writeRef())) && inst) + { + SlangResult res = inst->writeToBlob(blob.writeRef()); + if (SLANG_SUCCEEDED(res) && blob) + { + break; + } + } + } + } - // Create as a blob - RefPtr blob = RawBlob::moveCreate(alloc); + // Wasn't able to construct - // Put in cache - if (canKeep(keep)) - { - setBlob(blob); + if (!blob) + { + return SLANG_E_NOT_FOUND; + } + + // Put in cache + if (canKeep(keep)) + { + setBlob(blob); + } } - outBlob = blob; + *outBlob = blob.detach(); return SLANG_OK; } -- cgit v1.2.3