diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-08-09 10:31:22 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-09 10:31:22 -0400 |
| commit | c0733be56dc24ef0eb67b26fe0c49d3419e75773 (patch) | |
| tree | e094e31981c69e887ff9df84df07defe9eb77bf5 /source/compiler-core/slang-artifact.cpp | |
| parent | 2db8c15c04f2aade49636e42f0adee636afb3b73 (diff) | |
Support for Items on IArtifact (#2347)
* #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.
Diffstat (limited to 'source/compiler-core/slang-artifact.cpp')
| -rw-r--r-- | source/compiler-core/slang-artifact.cpp | 325 |
1 files changed, 162 insertions, 163 deletions
diff --git a/source/compiler-core/slang-artifact.cpp b/source/compiler-core/slang-artifact.cpp index cb77f5140..cefb8d753 100644 --- a/source/compiler-core/slang-artifact.cpp +++ b/source/compiler-core/slang-artifact.cpp @@ -3,10 +3,14 @@ #include "slang-artifact-info.h" +#include "../core/slang-file-system.h" + #include "../core/slang-type-text-util.h" #include "../core/slang-io.h" #include "../core/slang-array-view.h" +#include "slang-artifact-util.h" + namespace Slang { namespace { // anonymous @@ -276,6 +280,139 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL SLANG_UNEXPECTED("Unhandled type"); } +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FileArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void* FileArtifactRepresentation::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == IArtifactRepresentation::getTypeGuid() || + guid == IFileArtifactRepresentation::getTypeGuid()) + { + return static_cast<IFileArtifactRepresentation*>(this); + } + return nullptr; +} + +void* FileArtifactRepresentation::getObject(const Guid& guid) +{ + SLANG_UNUSED(guid); + return nullptr; +} + +ISlangMutableFileSystem* FileArtifactRepresentation::_getFileSystem() +{ + return m_fileSystem ? m_fileSystem : OSFileSystem::getMutableSingleton(); +} + +void* FileArtifactRepresentation::castAs(const Guid& guid) +{ + if (auto intf = getInterface(guid)) + { + return intf; + } + return getObject(guid); +} + +SlangResult FileArtifactRepresentation::writeToBlob(ISlangBlob** blob) +{ + if (m_kind == Kind::NameOnly) + { + // If it's referenced by a name only, it's a file that *can't* be loaded as a blob in general. + return SLANG_E_NOT_AVAILABLE; + } + + auto fileSystem = _getFileSystem(); + return fileSystem->loadFile(m_path.getBuffer(), blob); +} + +bool FileArtifactRepresentation::exists() +{ + // TODO(JS): + // If it's a name only it's hard to know what exists should do. It can't *check* because it relies on the 'system' doing + // the actual location. We could ask the IArtifactUtil, and that could change the behavior. + // For now we just assume it does. + if (m_kind == Kind::NameOnly) + { + return true; + } + + auto fileSystem = _getFileSystem(); + + SlangPathType pathType; + const auto res = fileSystem->getPathType(m_path.getBuffer(), &pathType); + + // It exists if it is a file + return SLANG_SUCCEEDED(res) && pathType == SLANG_PATH_TYPE_FILE; +} + +FileArtifactRepresentation::~FileArtifactRepresentation() +{ + if (m_kind == Kind::Owned) + { + auto fileSystem = _getFileSystem(); + fileSystem->remove(m_path.getBuffer()); + } +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! LockFile !!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void* LockFile::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == ILockFile::getTypeGuid()) + { + return static_cast<ILockFile*>(this); + } + return nullptr; +} + +void* LockFile::getObject(const Guid& guid) +{ + SLANG_UNUSED(guid); + return nullptr; +} + +ISlangMutableFileSystem* LockFile::_getFileSystem() +{ + return m_fileSystem ? m_fileSystem : OSFileSystem::getMutableSingleton(); +} + +void* LockFile::castAs(const Guid& guid) +{ + if (auto intf = getInterface(guid)) + { + return intf; + } + return getObject(guid); +} + +const char* LockFile::getPath() +{ + return (m_path.getLength() > 0) ? m_path.getBuffer() : nullptr; +} + +ISlangMutableFileSystem* LockFile::getFileSystem() +{ + return m_fileSystem; +} + +LockFile::~LockFile() +{ + if (m_path.getLength() > 0) + { + auto fileSystem = _getFileSystem(); + fileSystem->remove(m_path.getBuffer()); + } +} + +void LockFile::disown() +{ + m_path = String(); + m_fileSystem.setNull(); +} + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactList !!!!!!!!!!!!!!!!!!!!!!!!!!! */ void* ArtifactList::getInterface(const Guid& guid) @@ -358,35 +495,15 @@ void* Artifact::getInterface(const Guid& uuid) return nullptr; } -Artifact::~Artifact() -{ - // Remove the temporary - if (m_pathType == PathType::Temporary) - { - File::remove(m_path); - } - // If there is a temporary lock path, remove that - if (m_temporaryLockPath.getLength()) - { - File::remove(m_temporaryLockPath); - } -} - bool Artifact::exists() { - // If we have a blob it exists - if (m_blob) - { - return true; - } - for (ISlangUnknown* item : m_items) { ComPtr<ICastable> castable; if (SLANG_SUCCEEDED(item->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable) { - auto rep = (IArtifactRepresentation*)castable->castAs(IArtifactRepresentation::getTypeGuid()); + auto rep = as<IArtifactRepresentation>(castable); if (rep) { // It is a rep and it exists @@ -397,7 +514,7 @@ bool Artifact::exists() continue; } // Associated types don't encapsulate an artifact representation, so don't signal existance - if (castable->castAs(IArtifactAssociated::getTypeGuid())) + if (as<IArtifactAssociated>(castable)) { continue; } @@ -407,17 +524,9 @@ bool Artifact::exists() return true; } - // If we don't have a path then it can't exist - if (m_pathType == PathType::None) - { - return false; - } - - // If the file exists we assume it exists - return File::exists(m_path); + return false; } - void Artifact::addItem(ISlangUnknown* intf) { SLANG_ASSERT(intf); @@ -432,7 +541,6 @@ void Artifact::removeItemAt(Index i) m_items.removeAt(i); } - void* Artifact::findItemInterface(const Guid& guid) { for (ISlangUnknown* intf : m_items) @@ -471,157 +579,48 @@ void* Artifact::findItemObject(const Guid& classGuid) return nullptr; } -SlangResult Artifact::requireFileLike(Keep keep) +SlangResult Artifact::requireFile(Keep keep, IFileArtifactRepresentation** outFileRep) { - // If there is no path set and no blob we still need a name. - // If the artifact is a library we can assume it's a system level library, - // or it can be found by appropriate search paths. - if (m_pathType == PathType::None && - m_blob == nullptr && - (m_desc.kind == ArtifactKind::Library || - m_desc.kind == ArtifactKind::SharedLibrary)) - { - if (m_name.getLength() > 0) - { - return SLANG_OK; - } - - // TODO(JS): If we could serialize, we could turn some other representation into a file, and therefore - // a name, but currently that's not supported - return SLANG_E_NOT_FOUND; - } - - // Will turn into a file if necessary - SLANG_RETURN_ON_FAIL(requireFile(keep)); - return SLANG_OK; + auto util = ArtifactUtilImpl::getSingleton(); + return util->requireFileDefaultImpl(this, keep, outFileRep); } -SlangResult Artifact::requireFile(Keep keep) +SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob) { - if (m_pathType != PathType::None) + // If we have a blob just return it + if (auto blob = findItem<ISlangBlob>(this)) { + blob->addRef(); + *outBlob = blob; return SLANG_OK; } ComPtr<ISlangBlob> 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.writeRef())); - - // If we have a name, make the generated name based on that name - // Else just use 'slang-generated' the basis - - UnownedStringSlice nameBase; - if (m_name.getLength() > 0) - { - nameBase = m_name.getUnownedSlice(); - } - else - { - nameBase = UnownedStringSlice::fromLiteral("slang-generated"); - } - - // TODO(JS): NOTE! This isn't strictly correct, as the generated filename is not guarenteed to be unique - // if we change it with an extension (or prefix). - // This doesn't change the previous behavior though. - String temporaryLockPath; - SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, temporaryLockPath)); - - String path = temporaryLockPath; - - if (ArtifactInfoUtil::isCpuBinary(m_desc) && - (m_desc.kind == ArtifactKind::SharedLibrary || - m_desc.kind == ArtifactKind::Library)) + // Look for a representation that we can serialize into a blob + for (ISlangUnknown* intf : m_items) { - const bool isSharedLibraryPrefixPlatform = SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY; - if (isSharedLibraryPrefixPlatform) + ComPtr<IArtifactRepresentation> rep; + if (SLANG_SUCCEEDED(intf->queryInterface(IArtifactRepresentation::getTypeGuid(), (void**)rep.writeRef())) && rep) { - StringBuilder buf; - buf << "lib"; - buf << Path::getFileName(path); - - auto parentDir = Path::getParentDirectory(path); - if (parentDir.getLength()) - { - // Combine the name with path if their is a parent - path = Path::combine(parentDir, buf); - } - else + SlangResult res = rep->writeToBlob(blob.writeRef()); + if (SLANG_SUCCEEDED(res) && blob) { - // Just use the name as is - path = buf; + break; } } } - - // If there is an extension append it - const UnownedStringSlice ext = ArtifactInfoUtil::getDefaultExtension(m_desc); - - if (ext.getLength()) + + // Wasn't able to construct + if (!blob) { - path.appendChar('.'); - path.append(ext); + return SLANG_E_NOT_FOUND; } - // If the final path is different from the lock path save that path - if (path != temporaryLockPath) + // Put in cache + if (canKeep(keep)) { - m_temporaryLockPath = temporaryLockPath; - } - - // Write the contents - 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); - - return SLANG_OK; -} - -SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob) -{ - ComPtr<ISlangBlob> blob(m_blob); - - if (!blob) - { - if (m_pathType != PathType::None) - { - // Read into a blob - ScopedAllocation alloc; - SLANG_RETURN_ON_FAIL(File::readAllBytes(m_path, alloc)); - - // Create as a blob - blob = RawBlob::moveCreate(alloc); - } - else - { - // Look for a representation that we can serialize into a blob - for (ISlangUnknown* intf : m_items) - { - - ComPtr<IArtifactRepresentation> rep; - if (SLANG_SUCCEEDED(intf->queryInterface(IArtifactRepresentation::getTypeGuid(), (void**)rep.writeRef())) && rep) - { - SlangResult res = rep->writeToBlob(blob.writeRef()); - if (SLANG_SUCCEEDED(res) && blob) - { - break; - } - } - } - } - - // Wasn't able to construct - if (!blob) - { - return SLANG_E_NOT_FOUND; - } - - // Put in cache - if (canKeep(keep)) - { - setBlob(blob); - } + addItem(blob); } *outBlob = blob.detach(); |
