From f5755019246504ad4da4614d1e34a00d74970ea7 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 24 Aug 2022 09:25:51 -0400 Subject: Assorted Artifact improvements (#2374) * #include an absolute path didn't work - because paths were taken to always be relative. * WIP replacing DownstreamCompileResult. * First attempt at replacing DownstreamCompileResult with IArtifact and associated types. * Small renaming around CharSlice. * ICastable -> ISlangCastable Added IClonable Fix issue with cloning in ArtifactDiagnostics. * Only add the blob if one is defined in DXC. * Guard adding blob representation. * Make cloneInterface available across code base. Set enums backing type for ArtifactDiagnostic. * Added ::create for ArtifactDiagnostics. * Use SemanticVersion for DownstreamCompilerDesc. Set sizes for enum types. * Depreciate old incompatible CompileOptions. Change SemanticVersion use 32 bits for the patch. * Split out CastableUtil. * Change IDownstreamCompiler to use canConvert and convert to use artifact types. * Fix typos. * Fix typo bug. Allow trafficing in PTX assembly/binaries * struct DownstreamCompilerBaseUtil -> struct DownstreamCompilerUtilBase * Add other riff types. * Small fix around artifact kind. * Make using slices instead of strings explicit on atomic ref counted types. (not complete). Added IArtifactList. Use IArtifactList to hold the 'associated' files. Use IUnknown for scoping for atomic ref counting. Small naming improvements. * Make artifact not use String in construction (so it owns contents). * Calculate compile products as artifacts. * Small improvements around ArtifactDesc. * Use ICastableList for list of artifacts and remove IArtifactList. --- source/compiler-core/slang-artifact-desc-util.cpp | 104 +++++++++++++++------ source/compiler-core/slang-artifact-desc-util.h | 7 +- .../compiler-core/slang-artifact-handler-impl.cpp | 4 +- source/compiler-core/slang-artifact-helper.cpp | 10 +- source/compiler-core/slang-artifact-helper.h | 4 +- source/compiler-core/slang-artifact-impl.h | 10 +- .../slang-artifact-representation-impl.h | 11 ++- .../compiler-core/slang-artifact-representation.h | 20 ++-- source/compiler-core/slang-artifact-util.cpp | 6 +- source/compiler-core/slang-artifact.h | 35 +++++-- source/compiler-core/slang-downstream-compiler.cpp | 61 +++++++----- source/compiler-core/slang-downstream-compiler.h | 14 +-- source/compiler-core/slang-gcc-compiler-util.cpp | 61 ++++-------- source/compiler-core/slang-gcc-compiler-util.h | 8 +- .../slang-visual-studio-compiler-util.cpp | 53 ++++------- .../slang-visual-studio-compiler-util.h | 7 +- source/core/slang-blob.h | 11 +-- source/core/slang-castable-list-impl.h | 2 + source/core/slang-shared-library.cpp | 12 --- source/core/slang-shared-library.h | 24 ----- source/slang/slang-compiler.cpp | 10 +- source/slang/slang-emit-cpp.cpp | 2 +- source/slang/slang-emit.cpp | 2 +- source/slang/slang-options.cpp | 8 +- source/slang/slang-parameter-binding.cpp | 2 +- source/slang/slang-type-layout.cpp | 2 +- source/slang/slang.cpp | 2 +- 27 files changed, 251 insertions(+), 241 deletions(-) diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp index 4681b60f4..cb5d401a9 100644 --- a/source/compiler-core/slang-artifact-desc-util.cpp +++ b/source/compiler-core/slang-artifact-desc-util.cpp @@ -159,19 +159,22 @@ bool isDerivedFrom(ENUM_TYPE kind, ENUM_TYPE base) { return g_table##ENUM_TYPE.i x(Base, Invalid) \ x(None, Base) \ x(Unknown, Base) \ - x(Container, Base) \ - x(Zip, Container) \ - x(Riff, Container) \ + x(BinaryFormat, Base) \ + x(Container, BinaryFormat) \ + x(Zip, Container) \ + x(RiffContainer, Container) \ + x(RiffLz4Container, Container) \ + x(RiffDeflateContainer, Container) \ + x(CompileBinary, BinaryFormat) \ + x(ObjectCode, CompileBinary) \ + x(Library, CompileBinary) \ + x(Executable, CompileBinary) \ + x(SharedLibrary, CompileBinary) \ + x(HostCallable, CompileBinary) \ x(Text, Base) \ x(HumanText, Text) \ x(Source, Text) \ x(Assembly, Text) \ - x(BinaryLike, Base) \ - x(ObjectCode, BinaryLike) \ - x(Library, BinaryLike) \ - x(Executable, BinaryLike) \ - x(SharedLibrary, BinaryLike) \ - x(HostCallable, BinaryLike) \ x(Instance, Base) #define SLANG_ARTIFACT_KIND_ENTRY(TYPE, PARENT) { Index(ArtifactKind::TYPE), Index(ArtifactKind::PARENT), #TYPE }, @@ -214,9 +217,12 @@ SLANG_HIERARCHICAL_ENUM(ArtifactKind, SLANG_ARTIFACT_KIND, SLANG_ARTIFACT_KIND_E x(AST, Base) \ x(SlangAST, AST) \ x(CompileResults, Base) \ - x(MetaData, Base) \ - x(DebugInfo, MetaData) \ - x(Diagnostics, MetaData) + x(Metadata, Base) \ + x(DebugInfo, Metadata) \ + x(Diagnostics, Metadata) \ + x(Miscellaneous, Base) \ + x(Log, Miscellaneous) \ + x(Lock, Miscellaneous) #define SLANG_ARTIFACT_PAYLOAD_ENTRY(TYPE, PARENT) { Index(ArtifactPayload::TYPE), Index(ArtifactPayload::PARENT), #TYPE }, @@ -227,9 +233,11 @@ SLANG_HIERARCHICAL_ENUM(ArtifactPayload, SLANG_ARTIFACT_PAYLOAD, SLANG_ARTIFACT_ #define SLANG_ARTIFACT_STYLE(x) \ x(Invalid, Invalid) \ x(Base, Invalid) \ + x(None, Base) \ x(Unknown, Base) \ - x(Kernel, Base) \ - x(Host, Base) + x(CodeLike, Base) \ + x(Kernel, CodeLike) \ + x(Host, CodeLike) #define SLANG_ARTIFACT_STYLE_ENTRY(TYPE, PARENT) { Index(ArtifactStyle::TYPE), Index(ArtifactStyle::PARENT), #TYPE }, @@ -238,7 +246,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDescUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -/* static */ArtifactDesc ArtifactDescUtil::makeDescFromCompileTarget(SlangCompileTarget target) +/* static */ArtifactDesc ArtifactDescUtil::makeDescForCompileTarget(SlangCompileTarget target) { switch (target) { @@ -279,6 +287,27 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL SLANG_UNEXPECTED("Unhandled type"); } + +/* static */ArtifactPayload ArtifactDescUtil::getPayloadForSourceLanaguage(SlangSourceLanguage language) +{ + switch (language) + { + default: + case SLANG_SOURCE_LANGUAGE_UNKNOWN: return Payload::Unknown; + case SLANG_SOURCE_LANGUAGE_SLANG: return Payload::Slang; + case SLANG_SOURCE_LANGUAGE_HLSL: return Payload::HLSL; + case SLANG_SOURCE_LANGUAGE_GLSL: return Payload::GLSL; + case SLANG_SOURCE_LANGUAGE_C: return Payload::C; + case SLANG_SOURCE_LANGUAGE_CPP: return Payload::Cpp; + case SLANG_SOURCE_LANGUAGE_CUDA: return Payload::CUDA; + } +} + +/* static */ArtifactDesc ArtifactDescUtil::makeDescForSourceLanguage(SlangSourceLanguage language) +{ + return Desc::make(Kind::Source, getPayloadForSourceLanaguage(language), Style::Unknown, 0); +} + /* static */SlangCompileTarget ArtifactDescUtil::getCompileTargetFromDesc(const ArtifactDesc& desc) { switch (desc.kind) @@ -311,7 +340,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL default: break; } - if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike)) + if (isDerivedFrom(desc.kind, ArtifactKind::CompileBinary)) { if (isDerivedFrom(desc.payload, ArtifactPayload::CPULike)) { @@ -377,7 +406,7 @@ static const KindExtension g_cpuKindExts[] = /* static */ bool ArtifactDescUtil::isCpuBinary(const ArtifactDesc& desc) { - return isDerivedFrom(desc.kind, ArtifactKind::BinaryLike) && isDerivedFrom(desc.payload, ArtifactPayload::CPULike); + return isDerivedFrom(desc.kind, ArtifactKind::CompileBinary) && isDerivedFrom(desc.payload, ArtifactPayload::CPULike); } /* static */bool ArtifactDescUtil::isText(const ArtifactDesc& desc) @@ -389,7 +418,7 @@ static const KindExtension g_cpuKindExts[] = } // Special case PTX... - if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike)) + if (isDerivedFrom(desc.kind, ArtifactKind::CompileBinary)) { return desc.payload == ArtifactPayload::PTX; } @@ -400,7 +429,7 @@ static const KindExtension g_cpuKindExts[] = /* static */bool ArtifactDescUtil::isGpuUsable(const ArtifactDesc& desc) { - if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike)) + if (isDerivedFrom(desc.kind, ArtifactKind::CompileBinary)) { return isDerivedFrom(desc.payload, ArtifactPayload::KernelLike); } @@ -426,7 +455,7 @@ static const KindExtension g_cpuKindExts[] = /* static */bool ArtifactDescUtil::isLinkable(const ArtifactDesc& desc) { - if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike)) + if (isDerivedFrom(desc.kind, ArtifactKind::CompileBinary)) { if (isDerivedFrom(desc.payload, ArtifactPayload::KernelLike)) { @@ -460,7 +489,7 @@ static const KindExtension g_cpuKindExts[] = /* static */bool ArtifactDescUtil::isCpuLikeTarget(const ArtifactDesc& desc) { - if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike)) + if (isDerivedFrom(desc.kind, ArtifactKind::CompileBinary)) { return isDerivedFrom(desc.payload, ArtifactPayload::CPULike); } @@ -496,9 +525,22 @@ static const KindExtension g_cpuKindExts[] = { return ArtifactDesc::make(ArtifactKind::Zip, ArtifactPayload::Unknown); } - else if (slice == toSlice("riff")) + + if (slice.startsWith(toSlice("riff"))) { - return ArtifactDesc::make(ArtifactKind::Riff, ArtifactPayload::Unknown); + auto tail = slice.tail(4); + if (tail.getLength() == 0) + { + return ArtifactDesc::make(ArtifactKind::RiffContainer, ArtifactPayload::Unknown); + } + else if (tail == "-lz4") + { + return ArtifactDesc::make(ArtifactKind::RiffLz4Container, ArtifactPayload::Unknown); + } + else if (tail == "-deflate") + { + return ArtifactDesc::make(ArtifactKind::RiffDeflateContainer, ArtifactPayload::Unknown); + } } if (slice == toSlice("asm")) @@ -518,7 +560,7 @@ static const KindExtension g_cpuKindExts[] = const auto target = TypeTextUtil::findCompileTargetFromExtension(slice); - return makeDescFromCompileTarget(target); + return makeDescForCompileTarget(target); } /* static */ArtifactDesc ArtifactDescUtil::getDescFromPath(const UnownedStringSlice& slice) @@ -605,11 +647,21 @@ SlangResult ArtifactDescUtil::appendDefaultExtension(const ArtifactDesc& desc, S out << toSlice("zip"); return SLANG_OK; } - case ArtifactKind::Riff: + case ArtifactKind::RiffContainer: { out << toSlice("riff"); return SLANG_OK; } + case ArtifactKind::RiffLz4Container: + { + out << toSlice("riff-lz4"); + return SLANG_OK; + } + case ArtifactKind::RiffDeflateContainer: + { + out << toSlice("riff-deflate"); + return SLANG_OK; + } case ArtifactKind::Assembly: { // Special case PTX, because it is assembly @@ -764,7 +816,7 @@ SlangResult ArtifactDescUtil::appendDefaultExtension(const ArtifactDesc& desc, S /* static */bool ArtifactDescUtil::isDissassembly(const ArtifactDesc& from, const ArtifactDesc& to) { // From must be a binary like type - if (!isDerivedFrom(from.kind, ArtifactKind::BinaryLike)) + if (!isDerivedFrom(from.kind, ArtifactKind::CompileBinary)) { return false; } diff --git a/source/compiler-core/slang-artifact-desc-util.h b/source/compiler-core/slang-artifact-desc-util.h index ff54198b4..6c6c158f8 100644 --- a/source/compiler-core/slang-artifact-desc-util.h +++ b/source/compiler-core/slang-artifact-desc-util.h @@ -82,7 +82,12 @@ struct ArtifactDescUtil static SlangResult calcNameForDesc(const ArtifactDesc& desc, const UnownedStringSlice& baseName, StringBuilder& outName); /// Given a target returns the ArtifactDesc - static ArtifactDesc makeDescFromCompileTarget(SlangCompileTarget target); + static ArtifactDesc makeDescForCompileTarget(SlangCompileTarget target); + + /// Get the payload for the specified language + static ArtifactPayload getPayloadForSourceLanaguage(SlangSourceLanguage language); + /// Given a source language return a desc + static ArtifactDesc makeDescForSourceLanguage(SlangSourceLanguage language); /// Returns the closest compile target for desc. Will return /// SLANG_TARGET_UNKNOWN if not known diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp index 4f10b8cdd..b9dfb29b1 100644 --- a/source/compiler-core/slang-artifact-handler-impl.cpp +++ b/source/compiler-core/slang-artifact-handler-impl.cpp @@ -189,7 +189,7 @@ SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* art ComPtr pathBlob; SLANG_RETURN_ON_FAIL(helper->calcArtifactPath(artifact->getDesc(), lockFile->getPath(), pathBlob.writeRef())); - const auto path = StringUtil::getString(pathBlob); + const auto path = StringUtil::getSlice(pathBlob); // Write the contents SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize())); @@ -202,7 +202,7 @@ SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* art // 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()) + if (UnownedStringSlice(lockFile->getPath()) == path) { fileRep.swap(lockFile); } diff --git a/source/compiler-core/slang-artifact-helper.cpp b/source/compiler-core/slang-artifact-helper.cpp index 49b9e547e..d24d08909 100644 --- a/source/compiler-core/slang-artifact-helper.cpp +++ b/source/compiler-core/slang-artifact-helper.cpp @@ -58,7 +58,7 @@ void* DefaultArtifactHelper::getObject(const Guid& guid) SlangResult DefaultArtifactHelper::createArtifact(const ArtifactDesc& desc, const char* inName, IArtifact** outArtifact) { *outArtifact = inName ? - Artifact::create(desc, inName).detach() : + Artifact::create(desc, UnownedStringSlice(inName)).detach() : Artifact::create(desc).detach(); return SLANG_OK; @@ -67,7 +67,7 @@ SlangResult DefaultArtifactHelper::createArtifact(const ArtifactDesc& desc, cons SlangResult DefaultArtifactHelper::createArtifactContainer(const ArtifactDesc& desc, const char* inName, IArtifactContainer** outArtifactContainer) { *outArtifactContainer = inName ? - ArtifactContainer::create(desc, inName).detach() : + ArtifactContainer::create(desc, UnownedStringSlice(inName)).detach() : ArtifactContainer::create(desc).detach(); return SLANG_OK; @@ -102,7 +102,7 @@ SlangResult DefaultArtifactHelper::createLockFile(const char* inNameBase, ISlang String lockPath; SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, lockPath)); - ComPtr lockFile(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Lock, lockPath, nullptr, fileSystem)); + ComPtr lockFile(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Lock, lockPath.getUnownedSlice(), nullptr, fileSystem)); *outLockFile = lockFile.detach(); return SLANG_OK; @@ -117,9 +117,9 @@ SlangResult DefaultArtifactHelper::calcArtifactPath(const ArtifactDesc& desc, co return SLANG_OK; } -ArtifactDesc DefaultArtifactHelper::makeDescFromCompileTarget(SlangCompileTarget target) +ArtifactDesc DefaultArtifactHelper::makeDescForCompileTarget(SlangCompileTarget target) { - return ArtifactDescUtil::makeDescFromCompileTarget(target); + return ArtifactDescUtil::makeDescForCompileTarget(target); } void DefaultArtifactHelper::getCastable(ISlangUnknown* unk, ICastable** outCastable) diff --git a/source/compiler-core/slang-artifact-helper.h b/source/compiler-core/slang-artifact-helper.h index 58f29ef04..22c1b5c99 100644 --- a/source/compiler-core/slang-artifact-helper.h +++ b/source/compiler-core/slang-artifact-helper.h @@ -47,7 +47,7 @@ class IArtifactHelper : public ICastable virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) = 0; /// Given a compile target return the equivalent desc - virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) = 0; + virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescForCompileTarget(SlangCompileTarget target) = 0; /// Given an interface returns as a castable interface. This might just cast unk into ICastable, or wrap it such that it uses the castable interface virtual SLANG_NO_THROW void SLANG_MCALL getCastable(ISlangUnknown* unk, ICastable** outCastable) = 0; @@ -87,7 +87,7 @@ public: 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; + virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescForCompileTarget(SlangCompileTarget target) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL getCastable(ISlangUnknown* unk, ICastable** outCastable) SLANG_OVERRIDE; diff --git a/source/compiler-core/slang-artifact-impl.h b/source/compiler-core/slang-artifact-impl.h index a6e99a4f7..c5c7307a1 100644 --- a/source/compiler-core/slang-artifact-impl.h +++ b/source/compiler-core/slang-artifact-impl.h @@ -78,12 +78,12 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); } static ComPtr create(const Desc& desc) { return ComPtr(new Artifact(desc)); } - static ComPtr create(const Desc& desc, const String& name) { return ComPtr(new Artifact(desc, name)); } + static ComPtr create(const Desc& desc, const UnownedStringSlice& name) { return ComPtr(new Artifact(desc, name)); } protected: /// Ctor - Artifact(const Desc& desc, const String& name) : + Artifact(const Desc& desc, const UnownedStringSlice& name) : m_desc(desc), m_name(name), m_parent(nullptr) @@ -105,8 +105,6 @@ protected: LazyCastableList m_associated; ///< Associated items LazyCastableList m_representations; ///< Representations - - ComPtr m_children; ///< The children to this artifact }; class ArtifactContainer : public Artifact @@ -134,11 +132,11 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() SLANG_OVERRIDE; static ComPtr create(const Desc& desc) { return ComPtr(new ArtifactContainer(desc)); } - static ComPtr create(const Desc& desc, const String& name) { return ComPtr(new ArtifactContainer(desc, name)); } + static ComPtr create(const Desc& desc, const UnownedStringSlice& name) { return ComPtr(new ArtifactContainer(desc, name)); } protected: /// Ctor - ArtifactContainer(const Desc& desc, const String& name) :Super(desc, name) {} + ArtifactContainer(const Desc& desc, const UnownedStringSlice& name) :Super(desc, name) {} ArtifactContainer(const Desc& desc) : Super(desc) {} void* getInterface(const Guid& uuid); diff --git a/source/compiler-core/slang-artifact-representation-impl.h b/source/compiler-core/slang-artifact-representation-impl.h index 5e6716641..4ccd9062c 100644 --- a/source/compiler-core/slang-artifact-representation-impl.h +++ b/source/compiler-core/slang-artifact-representation-impl.h @@ -17,7 +17,7 @@ namespace Slang class FileArtifactRepresentation : public ComBaseObject, public IFileArtifactRepresentation { public: - typedef IFileArtifactRepresentation::Kind Kind; + typedef FileArtifactRepresentation ThisType; SLANG_COM_BASE_IUNKNOWN_ALL @@ -35,16 +35,21 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL disown() SLANG_OVERRIDE; virtual SLANG_NO_THROW IFileArtifactRepresentation* SLANG_MCALL getLockFile() SLANG_OVERRIDE { return m_lockFile; } - FileArtifactRepresentation(Kind kind, String path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem): + FileArtifactRepresentation(Kind kind, const UnownedStringSlice& path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem): m_kind(kind), - m_path(path), m_lockFile(lockFile), + m_path(path), m_fileSystem(fileSystem) { } ~FileArtifactRepresentation(); + static ComPtr create(Kind kind, const UnownedStringSlice& path, IFileArtifactRepresentation* lockFile, ISlangMutableFileSystem* fileSystem) + { + return ComPtr(new ThisType(kind, path, lockFile, fileSystem)); + } + protected: void* getInterface(const Guid& uuid); void* getObject(const Guid& uuid); diff --git a/source/compiler-core/slang-artifact-representation.h b/source/compiler-core/slang-artifact-representation.h index 466494052..32945b0be 100644 --- a/source/compiler-core/slang-artifact-representation.h +++ b/source/compiler-core/slang-artifact-representation.h @@ -8,9 +8,14 @@ namespace Slang { /* -A representation as a file. If it is a temporary file, it will likely disappear. -A file representation does not have to be a representation of a file on the file system. -That is indicated by getFileSystem returning nullptr. Then the path is the path on the *actual* OS file system. +A representation as a file. + +A file representation does not have to be a file on the OS file system, and might specify a file +contained in a virtual file system represented by ISlangMutableFileSystem. + +If `getFileSystem()` returns nullptr, then the path does specify a file on the regular OS file system otherwise +the path specifies the file contained in the virtual file system. + This distinction is important as it is sometimes necessary to have an artifact stored on the OS file system to be usable. */ class IFileArtifactRepresentation : public IArtifactRepresentation @@ -18,13 +23,13 @@ class IFileArtifactRepresentation : public IArtifactRepresentation public: SLANG_COM_INTERFACE(0xc7d7d3a4, 0x8683, 0x44b5, { 0x87, 0x96, 0xdf, 0xba, 0x9b, 0xc3, 0xf1, 0x7b }); - // NOTE! + /* Determines ownership and other characteristics of the 'file' */ enum class Kind { Reference, ///< References a file on the file system NameOnly, ///< Typically used for items that can be found by the 'system'. The path is just a name, and cannot typically be loaded as a blob. Owned, ///< File is *owned* by this instance and will be deleted when goes out of scope - Lock, ///< An owned type, indicates potentially in part may only exist to 'lock' a path for a temporary file + Lock, ///< An owned type, indicates potentially in part may only exist to 'lock' a path for a temporary file. Other files might exists based on the 'lock' path. CountOf, }; @@ -32,11 +37,12 @@ public: virtual SLANG_NO_THROW Kind SLANG_MCALL getKind() = 0; /// The path (on the file system) virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() = 0; - /// Optional, the file system it's on. If nullptr its on 'regular' OS file system. + /// Optional, the file system it's on. If nullptr its on the 'regular' OS file system. virtual SLANG_NO_THROW ISlangMutableFileSystem* SLANG_MCALL getFileSystem() = 0; /// Makes the file no longer owned. Only applicable for Owned/Lock and they will become 'Reference' virtual SLANG_NO_THROW void SLANG_MCALL disown() = 0; - /// Gets the 'lock file' if any associated with this file. Returns nullptr if there isn't one. + /// Gets the 'lock file' if any associated with this file. Returns nullptr if there isn't one. + /// If this file is based on a 'lock file', the lock file must stay in scope at least as long as this does. virtual SLANG_NO_THROW IFileArtifactRepresentation* SLANG_MCALL getLockFile() = 0; }; diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp index 084d96062..20a729cfa 100644 --- a/source/compiler-core/slang-artifact-util.cpp +++ b/source/compiler-core/slang-artifact-util.cpp @@ -48,7 +48,7 @@ namespace Slang { /* static */ComPtr ArtifactUtil::createArtifactForCompileTarget(SlangCompileTarget target) { - auto desc = ArtifactDescUtil::makeDescFromCompileTarget(target); + auto desc = ArtifactDescUtil::makeDescForCompileTarget(target); return createArtifact(desc); } @@ -72,7 +72,7 @@ namespace Slang { } // If it's binary like or assembly/source we it's significant - if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike) || + if (isDerivedFrom(desc.kind, ArtifactKind::CompileBinary) || desc.kind == ArtifactKind::Assembly || desc.kind == ArtifactKind::Source) { @@ -82,7 +82,7 @@ namespace Slang { /* 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)) + if (isDerivedFrom(desc.payload, ArtifactPayload::Metadata)) { return false; } diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h index ee5f6b61d..1fae7ab8a 100644 --- a/source/compiler-core/slang-artifact.h +++ b/source/compiler-core/slang-artifact.h @@ -19,6 +19,8 @@ struct Slice const T* begin() const { return data; } const T* end() const { return data + count; } + const T& operator[](Index index) { SLANG_ASSERT(index >= 0 && index < count); return data[index]; } + Slice() :count(0), data(nullptr) {} Slice(const T* inData, Count inCount) : data(inData), @@ -72,9 +74,13 @@ enum class ArtifactKind : uint8_t None, ///< Doesn't contain anything Unknown, ///< Unknown + BinaryFormat, ///< A generic binary format. + Container, ///< Container like types Zip, ///< Zip container - Riff, ///< Riff format + RiffContainer, ///< Riff container + RiffLz4Container, ///< Riff container using Lz4 compression + RiffDeflateContainer, ///< Riff container using deflate compression Text, ///< Representation is text. Encoding is utf8, unless prefixed with 'encoding'. @@ -82,7 +88,7 @@ enum class ArtifactKind : uint8_t Assembly, ///< Assembly (Type is in payload) HumanText, ///< Text for human consumption - BinaryLike, ///< Kinds which are 'binary like' - can be executed, linked with and so forth. + CompileBinary, ///< Kinds which are 'binary like' - can be executed, linked with and so forth. ObjectCode, ///< Object file Library, ///< Library (collection of object code) @@ -153,11 +159,16 @@ enum class ArtifactPayload : uint8_t CompileResults, ///< Payload is a collection of compilation results - MetaData, ///< Meta data + Metadata, ///< Metadata DebugInfo, ///< Debugging information Diagnostics, ///< Diagnostics information + Miscellaneous, ///< Category for miscellaneous payloads (like Log/Lock) + + Log, ///< Log file + Lock, ///< Typically some kind of 'lock' file. Contents is typically not important. + CountOf, }; @@ -174,8 +185,12 @@ enum class ArtifactStyle : uint8_t Invalid, ///< Invalid style (indicating an error) Base, + None, ///< A style is not applicable + Unknown, ///< Unknown + CodeLike, ///< For styles that are 'code like' such as 'kernel' or 'host'. + Kernel, ///< Compiled as `GPU kernel` style. Host, ///< Compiled in `host` style @@ -197,7 +212,7 @@ A value type to describe aspects of the contents of an Artifact. struct ArtifactDesc { public: - typedef ArtifactDesc This; + typedef ArtifactDesc ThisType; typedef ArtifactKind Kind; typedef ArtifactPayload Payload; @@ -210,14 +225,15 @@ public: /// Get in packed format inline Packed getPacked() const; - bool operator==(const This& rhs) const { return kind == rhs.kind && payload == rhs.payload && style == rhs.style && flags == rhs.flags; } - bool operator!=(const This& rhs) const { return !(*this == rhs); } + bool operator==(const ThisType& rhs) const { return kind == rhs.kind && payload == rhs.payload && style == rhs.style && flags == rhs.flags; } + bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } /// Construct from the elements - static This make(Kind inKind, Payload inPayload, Style inStyle = Style::Unknown, Flags flags = 0) { return This{ inKind, inPayload, inStyle, flags }; } + static ThisType make(Kind inKind, Payload inPayload, Style inStyle = Style::Unknown, Flags flags = 0) { return ThisType{ inKind, inPayload, inStyle, flags }; } + static ThisType make(Kind inKind, Payload inPayload, const ThisType& base) { return ThisType{ inKind, inPayload, base.style, base.flags }; } /// Construct from the packed format - inline static This make(Packed inPacked); + inline static ThisType make(Packed inPacked); Kind kind; Payload payload; @@ -240,7 +256,7 @@ inline /* static */ArtifactDesc ArtifactDesc::make(Packed inPacked) { const PackedBacking packed = PackedBacking(inPacked); - This r; + ThisType r; r.kind = Kind(packed >> 24); r.payload = Payload(uint8_t(packed >> 16)); r.style = Style(uint8_t(packed >> 8)); @@ -252,7 +268,6 @@ inline /* static */ArtifactDesc ArtifactDesc::make(Packed inPacked) // Forward declare class IFileArtifactRepresentation; class IArtifactRepresentation; -class IArtifactList; // Controls what items can be kept. enum class ArtifactKeep diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp index 498903727..13d605b3d 100644 --- a/source/compiler-core/slang-downstream-compiler.cpp +++ b/source/compiler-core/slang-downstream-compiler.cpp @@ -14,8 +14,14 @@ #include "../core/slang-castable-util.h" +#include "slang-artifact-impl.h" +#include "slang-artifact-representation-impl.h" #include "slang-artifact-associated-impl.h" #include "slang-artifact-util.h" +#include "slang-artifact-helper.h" +#include "slang-artifact-desc-util.h" + +#include "../core/slang-castable-list-impl.h" namespace Slang { @@ -101,12 +107,7 @@ SlangResult CommandLineDownstreamArtifactRepresentation::createRepresentation(co } // The shared library needs to keep temp files in scope - auto temporarySharedLibrary = new TemporarySharedLibrary(handle, m_moduleFilePath); - ComPtr lib(temporarySharedLibrary); - - // Set any additional info on the non COM pointer - temporarySharedLibrary->m_temporaryFileSet = m_temporaryFiles; - + ComPtr lib(new ScopeSharedLibrary(handle, m_artifactList)); *outCastable = lib.detach(); return SLANG_OK; } @@ -117,7 +118,7 @@ SlangResult CommandLineDownstreamArtifactRepresentation::createRepresentation(co // Read the contents of the binary SLANG_RETURN_ON_FAIL(File::readAllBytes(m_moduleFilePath, contents)); - auto blob = ScopeRefObjectBlob::create(ListBlob::moveCreate(contents), m_temporaryFiles); + auto blob = ScopeBlob::create(ListBlob::moveCreate(contents), m_artifactList); *outCastable = CastableUtil::getCastable(blob).detach(); return SLANG_OK; @@ -169,9 +170,14 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio CompileOptions options(inOptions); + auto helper = DefaultArtifactHelper::getSingleton(); + // Find all the files that will be produced - RefPtr productFileSet(new TemporaryFileSet); - + + auto artifactList = CastableList::create(); + + ComPtr lockFile; + if (options.modulePath.getLength() == 0 || options.sourceContents.getLength() != 0) { String modulePath = options.modulePath; @@ -179,15 +185,14 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio // If there is no module path, generate one. if (modulePath.getLength() == 0) { - // Holds the temporary lock path, if a temporary path is used - String temporaryLockPath; + SLANG_RETURN_ON_FAIL(helper->createLockFile("slang-generated", nullptr, lockFile.writeRef())); - // Generate a unique module path name - SLANG_RETURN_ON_FAIL(File::generateTemporary(UnownedStringSlice::fromLiteral("slang-generated"), temporaryLockPath)); - productFileSet->add(temporaryLockPath); + auto lockArtifact = Artifact::create(ArtifactDesc::make(ArtifactKind::Base, ArtifactPayload::Lock, ArtifactStyle::None)); + lockArtifact->addRepresentation(lockFile); - modulePath = temporaryLockPath; + artifactList->add(lockArtifact); + modulePath = lockFile->getPath(); options.modulePath = modulePath; } @@ -199,7 +204,6 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio { String compileSourcePath = modulePath; - // NOTE: Strictly speaking producing filenames by modifying the generateTemporary path that may introduce a temp filename clash, but in practice is extraordinary unlikely compileSourcePath.append("-src"); // Make the temporary filename have the appropriate extension. @@ -213,9 +217,15 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio } // Write it out - productFileSet->add(compileSourcePath); SLANG_RETURN_ON_FAIL(File::writeAllText(compileSourcePath, options.sourceContents)); + // Create the reference to the file + auto fileRep = FileArtifactRepresentation::create(IFileArtifactRepresentation::Kind::Owned, compileSourcePath.getUnownedSlice(), lockFile, nullptr); + auto fileArtifact = ArtifactUtil::createArtifact(ArtifactDescUtil::makeDescForSourceLanguage(options.sourceLanguage)); + fileArtifact->addRepresentation(fileRep); + + artifactList->add(fileArtifact); + // Add it as a source file options.sourceFiles.add(compileSourcePath); } @@ -232,14 +242,20 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio { StringBuilder builder; - SLANG_RETURN_ON_FAIL(calcModuleFilePath(options, builder)); + const auto desc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType); + SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, options.modulePath.getUnownedSlice(), builder)); + moduleFilePath = builder.ProduceString(); } { - List paths; - SLANG_RETURN_ON_FAIL(calcCompileProducts(options, DownstreamProductFlag::All, paths)); - productFileSet->add(paths); + List> artifacts; + SLANG_RETURN_ON_FAIL(calcCompileProducts(options, DownstreamProductFlag::All, lockFile, artifacts)); + + for (IArtifact* artifact : artifacts) + { + artifactList->add(artifact); + } } ExecuteResult exeRes; @@ -269,8 +285,9 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio // Add the artifact artifact->addAssociated(diagnostics); - ComPtr rep(new CommandLineDownstreamArtifactRepresentation(moduleFilePath, productFileSet)); + ComPtr rep(new CommandLineDownstreamArtifactRepresentation(moduleFilePath.getUnownedSlice(), artifactList)); artifact->addRepresentation(rep); + artifact->addAssociated(artifactList); *outArtifact = artifact.detach(); diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h index 7ebbd5f95..e5e69fdfe 100644 --- a/source/compiler-core/slang-downstream-compiler.h +++ b/source/compiler-core/slang-downstream-compiler.h @@ -238,13 +238,13 @@ public: virtual SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) SLANG_OVERRIDE; virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE; - CommandLineDownstreamArtifactRepresentation(const String& moduleFilePath, TemporaryFileSet* temporaryFileSet) : + CommandLineDownstreamArtifactRepresentation(const UnownedStringSlice& moduleFilePath, ICastableList* artifactList) : m_moduleFilePath(moduleFilePath), - m_temporaryFiles(temporaryFileSet) + m_artifactList(artifactList) { } - RefPtr m_temporaryFiles; + ComPtr m_artifactList; protected: @@ -252,10 +252,6 @@ protected: void* getObject(const Guid& guid); String m_moduleFilePath; - DownstreamCompileOptions m_options; - ComPtr m_binaryBlob; - /// Cache of the shared library if appropriate - ComPtr m_hostCallableSharedLibrary; }; class CommandLineDownstreamCompiler : public DownstreamCompilerBase @@ -269,12 +265,10 @@ public: // Functions to be implemented for a specific CommandLine - /// Given the compilation options and the module name, determines the actual file name used for output - virtual SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) = 0; /// Given options determines the paths to products produced (including the 'moduleFilePath'). /// Note that does *not* guarentee all products were or should be produced. Just aims to include all that could /// be produced, such that can be removed on completion. - virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, List& outPaths) = 0; + virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, IFileArtifactRepresentation* lockFile, List>& outArtifacts) = 0; virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) = 0; virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) = 0; diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp index a4ae7fbd5..428da1632 100644 --- a/source/compiler-core/slang-gcc-compiler-util.cpp +++ b/source/compiler-core/slang-gcc-compiler-util.cpp @@ -13,6 +13,7 @@ #include "slang-artifact-desc-util.h" #include "slang-artifact-diagnostic-util.h" #include "slang-artifact-util.h" +#include "slang-artifact-representation-impl.h" namespace Slang { @@ -431,51 +432,23 @@ static SlangResult _parseGCCFamilyLine(CharSliceAllocator& allocator, const Unow return SLANG_OK; } -/* static */ SlangResult GCCDownstreamCompilerUtil::calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) +/* static */SlangResult GCCDownstreamCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List>& outArtifacts) { SLANG_ASSERT(options.modulePath.getLength()); - outPath.Clear(); - - switch (options.targetType) - { - case SLANG_SHADER_SHARED_LIBRARY: - { - outPath << SharedLibrary::calcPlatformPath(options.modulePath.getUnownedSlice()); - return SLANG_OK; - } - case SLANG_HOST_EXECUTABLE: - { - outPath << options.modulePath; - outPath << Process::getExecutableSuffix(); - return SLANG_OK; - } - case SLANG_OBJECT_CODE: - { -#if __CYGWIN__ - outPath << options.modulePath << ".obj"; -#else - // Will be .o for typical gcc targets - outPath << options.modulePath << ".o"; -#endif - return SLANG_OK; - } - } - - return SLANG_FAIL; -} - -/* static */SlangResult GCCDownstreamCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, List& outPaths) -{ - SLANG_ASSERT(options.modulePath.getLength()); - - outPaths.clear(); + outArtifacts.clear(); if (flags & ProductFlag::Execution) { StringBuilder builder; - SLANG_RETURN_ON_FAIL(calcModuleFilePath(options, builder)); - outPaths.add(builder); + const auto desc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType); + SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, options.modulePath.getUnownedSlice(), builder)); + + auto fileRep = FileArtifactRepresentation::create(IFileArtifactRepresentation::Kind::Owned, builder.getUnownedSlice(), lockFile, nullptr); + auto artifact = ArtifactUtil::createArtifact(desc); + artifact->addRepresentation(fileRep); + + outArtifacts.add(artifact); } return SLANG_OK; @@ -488,6 +461,8 @@ static SlangResult _parseGCCFamilyLine(CharSliceAllocator& allocator, const Unow PlatformKind platformKind = (options.platform == PlatformKind::Unknown) ? PlatformUtil::getPlatformKind() : options.platform; + const auto targetDesc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType); + if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP) { cmdLine.addArg("-fvisibility=hidden"); @@ -563,9 +538,9 @@ static SlangResult _parseGCCFamilyLine(CharSliceAllocator& allocator, const Unow } } - StringBuilder moduleFilePath; - calcModuleFilePath(options, moduleFilePath); - + StringBuilder moduleFilePath; + SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(targetDesc, options.modulePath.getUnownedSlice(), moduleFilePath)); + cmdLine.addArg("-o"); cmdLine.addArg(moduleFilePath); @@ -661,9 +636,9 @@ static SlangResult _parseGCCFamilyLine(CharSliceAllocator& allocator, const Unow // Artifacts might add library paths for (IArtifact* artifact : options.libraries) { - const auto desc = artifact->getDesc(); + const auto artifactDesc = artifact->getDesc(); // If it's a library for CPU types, try and use it - if (ArtifactDescUtil::isCpuBinary(desc) && desc.kind == ArtifactKind::Library) + if (ArtifactDescUtil::isCpuBinary(artifactDesc) && artifactDesc.kind == ArtifactKind::Library) { ComPtr fileRep; diff --git a/source/compiler-core/slang-gcc-compiler-util.h b/source/compiler-core/slang-gcc-compiler-util.h index 84e68db9c..8791930bb 100644 --- a/source/compiler-core/slang-gcc-compiler-util.h +++ b/source/compiler-core/slang-gcc-compiler-util.h @@ -21,11 +21,8 @@ struct GCCDownstreamCompilerUtil : public DownstreamCompilerUtilBase /// Parse ExecuteResult into diagnostics static SlangResult parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* diagnostics); - /// Calculate the output module filename - static SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath); - /// Given options, calculate paths to products/files produced for a compilation - static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, List& outPaths); + static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List>& outArtifacts); /// Given the exe location, creates a DownstreamCompiler. /// Note! Invoke/s the compiler to determine the compiler version number. @@ -47,8 +44,7 @@ public: // CommandLineCPPCompiler impl - just forwards to the Util virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) SLANG_OVERRIDE { return Util::calcArgs(options, cmdLine); } virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) SLANG_OVERRIDE { return Util::parseOutput(exeResult, diagnostics); } - virtual SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) SLANG_OVERRIDE { return Util::calcModuleFilePath(options, outPath); } - virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, List& outPaths) SLANG_OVERRIDE { return Util::calcCompileProducts(options, flags, outPaths); } + virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, IFileArtifactRepresentation* lockFile, List>& outArtifacts) SLANG_OVERRIDE { return Util::calcCompileProducts(options, flags, lockFile, outArtifacts); } GCCDownstreamCompiler(const Desc& desc):Super(desc) {} }; diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp index 4e703f58f..ff3f378d6 100644 --- a/source/compiler-core/slang-visual-studio-compiler-util.cpp +++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp @@ -16,69 +16,54 @@ #include "slang-artifact-desc-util.h" #include "slang-artifact-diagnostic-util.h" #include "slang-artifact-util.h" +#include "slang-artifact-representation-impl.h" namespace Slang { -/* static */ SlangResult VisualStudioCompilerUtil::calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) +static void _addFile(const String& path, const ArtifactDesc& desc, IFileArtifactRepresentation* lockFile, List>& outArtifacts) { - SLANG_ASSERT(options.modulePath.getLength()); - - outPath.Clear(); + auto fileRep = FileArtifactRepresentation::create(IFileArtifactRepresentation::Kind::Owned, path.getUnownedSlice(), lockFile, nullptr); + auto artifact = ArtifactUtil::createArtifact(desc); + artifact->addRepresentation(fileRep); - switch (options.targetType) - { - case SLANG_SHADER_SHARED_LIBRARY: - { - outPath << options.modulePath << ".dll"; - return SLANG_OK; - } - case SLANG_HOST_EXECUTABLE: - { - outPath << options.modulePath << ".exe"; - return SLANG_OK; - } - case SLANG_OBJECT_CODE: - { - outPath << options.modulePath << ".obj"; - return SLANG_OK; - } - default: break; - } - - return SLANG_FAIL; + outArtifacts.add(artifact); } -/* static */SlangResult VisualStudioCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, List& outPaths) +/* static */SlangResult VisualStudioCompilerUtil::calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List>& outArtifacts) { SLANG_ASSERT(options.modulePath.getLength()); - outPaths.clear(); + const auto targetDesc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType); + + outArtifacts.clear(); if (flags & ProductFlag::Execution) { StringBuilder builder; - SLANG_RETURN_ON_FAIL(calcModuleFilePath(options, builder)); - outPaths.add(builder); + const auto desc = ArtifactDescUtil::makeDescForCompileTarget(options.targetType); + SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, options.modulePath.getUnownedSlice(), builder)); + + _addFile(builder, desc, lockFile, outArtifacts); } if (flags & ProductFlag::Miscellaneous) { - outPaths.add(options.modulePath + ".ilk"); + _addFile(options.modulePath + ".ilk", ArtifactDesc::make(ArtifactKind::BinaryFormat, ArtifactPayload::Unknown, ArtifactStyle::None), lockFile, outArtifacts); if (options.targetType == SLANG_SHADER_SHARED_LIBRARY) { - outPaths.add(options.modulePath + ".exp"); - outPaths.add(options.modulePath + ".lib"); + _addFile(options.modulePath + ".exp", ArtifactDesc::make(ArtifactKind::BinaryFormat, ArtifactPayload::Unknown, ArtifactStyle::None), lockFile, outArtifacts); + _addFile(options.modulePath + ".lib", ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::HostCPU, targetDesc), lockFile, outArtifacts); } } if (flags & ProductFlag::Compile) { - outPaths.add(options.modulePath + ".obj"); + _addFile(options.modulePath + ".obj", ArtifactDesc::make(ArtifactKind::ObjectCode, ArtifactPayload::HostCPU, targetDesc), lockFile, outArtifacts); } if (flags & ProductFlag::Debug) { // TODO(JS): Could try and determine based on debug information - outPaths.add(options.modulePath + ".pdb"); + _addFile(options.modulePath + ".pdb", ArtifactDesc::make(ArtifactKind::BinaryFormat, ArtifactPayload::DebugInfo, targetDesc), lockFile, outArtifacts); } return SLANG_OK; diff --git a/source/compiler-core/slang-visual-studio-compiler-util.h b/source/compiler-core/slang-visual-studio-compiler-util.h index 4eed9badb..db9f9b7ac 100644 --- a/source/compiler-core/slang-visual-studio-compiler-util.h +++ b/source/compiler-core/slang-visual-studio-compiler-util.h @@ -14,9 +14,7 @@ struct VisualStudioCompilerUtil : public DownstreamCompilerUtilBase /// Parse Visual Studio exeRes into CPPCompiler::Output static SlangResult parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* outOutput); - static SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath); - - static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, List& outPaths); + static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, IFileArtifactRepresentation* lockFile, List>& outArtifacts); static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set); }; @@ -30,8 +28,7 @@ public: // CommandLineDownstreamCompiler impl - just forwards to the Util virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) SLANG_OVERRIDE { return Util::calcArgs(options, cmdLine); } virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) SLANG_OVERRIDE { return Util::parseOutput(exeResult, diagnostics); } - virtual SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) SLANG_OVERRIDE { return Util::calcModuleFilePath(options, outPath); } - virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags productFlags, List& outPaths) SLANG_OVERRIDE { return Util::calcCompileProducts(options, productFlags, outPaths); } + virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags productFlags, IFileArtifactRepresentation* lockFile, List>& outArtifacts) SLANG_OVERRIDE { return Util::calcCompileProducts(options, productFlags, lockFile, outArtifacts); } VisualStudioDownstreamCompiler(const Desc& desc):Super(desc) {} }; diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h index 8a9ab5dea..49bfd4a17 100644 --- a/source/core/slang-blob.h +++ b/source/core/slang-blob.h @@ -284,30 +284,29 @@ protected: size_t m_dataCount; }; -class ScopeRefObjectBlob : public BlobBase +class ScopeBlob : public BlobBase { public: // ISlangBlob SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_blob->getBufferPointer(); } SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_blob->getBufferSize(); } - static inline ComPtr create(ISlangBlob* blob, RefObject* scope) + static inline ComPtr create(ISlangBlob* blob, ISlangUnknown* scope) { - return ComPtr(new ScopeRefObjectBlob(blob, scope)); + return ComPtr(new ScopeBlob(blob, scope)); } protected: // Ctor - ScopeRefObjectBlob(ISlangBlob* blob, RefObject* scope) : + ScopeBlob(ISlangBlob* blob, ISlangUnknown* scope) : m_blob(blob), m_scope(scope) { } - - RefPtr m_scope; + ComPtr m_scope; ComPtr m_blob; }; diff --git a/source/core/slang-castable-list-impl.h b/source/core/slang-castable-list-impl.h index 7a7f98a6a..adbd121fb 100644 --- a/source/core/slang-castable-list-impl.h +++ b/source/core/slang-castable-list-impl.h @@ -35,6 +35,8 @@ public: virtual ICastable* SLANG_MCALL findWithPredicate(FindFunc func, void* data) SLANG_OVERRIDE; virtual ICastable*const* SLANG_MCALL getBuffer() SLANG_OVERRIDE { return m_list.getBuffer(); } + static ComPtr create() { return ComPtr(new CastableList); } + /// Dtor virtual ~CastableList(); diff --git a/source/core/slang-shared-library.cpp b/source/core/slang-shared-library.cpp index 35440ac9e..e0fe82012 100644 --- a/source/core/slang-shared-library.cpp +++ b/source/core/slang-shared-library.cpp @@ -62,18 +62,6 @@ SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(const char* pa } } -/* !!!!!!!!!!!!!!!!!!!!!!!!!! TemporarySharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ - -TemporarySharedLibrary::~TemporarySharedLibrary() -{ - if (m_sharedLibraryHandle) - { - // We have to unload if we want to be able to remove - SharedLibrary::unload(m_sharedLibraryHandle); - m_sharedLibraryHandle = nullptr; - } -} - /* !!!!!!!!!!!!!!!!!!!!!!!!!! ScopeSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ ScopeSharedLibrary::~ScopeSharedLibrary() diff --git a/source/core/slang-shared-library.h b/source/core/slang-shared-library.h index 0a63e570e..9015219b1 100644 --- a/source/core/slang-shared-library.h +++ b/source/core/slang-shared-library.h @@ -76,30 +76,6 @@ class DefaultSharedLibrary : public ISlangSharedLibrary, public ComBaseObject SharedLibrary::Handle m_sharedLibraryHandle = nullptr; }; -class TemporarySharedLibrary : public DefaultSharedLibrary -{ -public: - typedef DefaultSharedLibrary Super; - - /// Get the path to the shared library - const String& getPath() const { return m_path; } - - /// Ctor - TemporarySharedLibrary(const SharedLibrary::Handle sharedLibraryHandle, const String& path): - Super(sharedLibraryHandle), - m_path(path) - { - } - - virtual ~TemporarySharedLibrary(); - - /// Any files specified in this set will be deleted on exit - RefPtr m_temporaryFileSet; - -protected: - String m_path; -}; - class ScopeSharedLibrary : public DefaultSharedLibrary { public: diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index a41463ad5..d50350b29 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -44,7 +44,7 @@ namespace Slang bool isHeterogeneousTarget(CodeGenTarget target) { - return ArtifactDescUtil::makeDescFromCompileTarget(asExternal(target)).style == ArtifactStyle::Host; + return ArtifactDescUtil::makeDescForCompileTarget(asExternal(target)).style == ArtifactStyle::Host; } void printDiagnosticArg(StringBuilder& sb, CodeGenTarget val) @@ -909,7 +909,7 @@ namespace Slang static bool _isCPUHostTarget(CodeGenTarget target) { - auto desc = ArtifactDescUtil::makeDescFromCompileTarget(asExternal(target)); + auto desc = ArtifactDescUtil::makeDescForCompileTarget(asExternal(target)); return desc.style == ArtifactStyle::Host; } @@ -1230,7 +1230,7 @@ namespace Slang // If we aren't using LLVM 'host callable', we want downstream compile to produce a shared library if (compilerType != PassThroughMode::LLVM && - ArtifactDescUtil::makeDescFromCompileTarget(asExternal(target)).kind == ArtifactKind::HostCallable) + ArtifactDescUtil::makeDescForCompileTarget(asExternal(target)).kind == ArtifactKind::HostCallable) { target = CodeGenTarget::ShaderSharedLibrary; } @@ -1242,9 +1242,9 @@ namespace Slang options.libraryPaths.add(Path::getParentDirectory(Path::getExecutablePath())); // Set up the library artifact - auto artifact = Artifact::create(ArtifactDesc::make(ArtifactKind::Library, Artifact::Payload::HostCPU), "slang-rt"); + auto artifact = Artifact::create(ArtifactDesc::make(ArtifactKind::Library, Artifact::Payload::HostCPU), toSlice("slang-rt")); - ComPtr fileRep(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, "slang-rt", nullptr, nullptr)); + ComPtr fileRep(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, toSlice("slang-rt"), nullptr, nullptr)); artifact->addRepresentation(fileRep); options.libraries.add(artifact); diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 345b6548a..9c1573bf8 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -1655,7 +1655,7 @@ CPPSourceEmitter::CPPSourceEmitter(const Desc& desc): //m_semanticUsedFlags = SemanticUsedFlag::GroupID | SemanticUsedFlag::GroupThreadID | SemanticUsedFlag::DispatchThreadID; - const auto artifactDesc = ArtifactDescUtil::makeDescFromCompileTarget(asExternal(getTarget())); + const auto artifactDesc = ArtifactDescUtil::makeDescForCompileTarget(asExternal(getTarget())); // If we have runtime library we can convert to a terminated string slice m_hasString = (artifactDesc.style == ArtifactStyle::Host); diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 11e0812d9..a8d3390f0 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -187,7 +187,7 @@ Result linkAndOptimizeIR( auto targetRequest = codeGenContext->getTargetReq(); // Get the artifact desc for the target - const auto artifactDesc = ArtifactDescUtil::makeDescFromCompileTarget(asExternal(target)); + const auto artifactDesc = ArtifactDescUtil::makeDescForCompileTarget(asExternal(target)); // We start out by performing "linking" at the level of the IR. // This step will create a fresh IR module to be used for diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index c40e5d16c..a28217fd8 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -1484,7 +1484,7 @@ struct OptionsParser const String name = ArtifactDescUtil::getBaseNameFromPath(desc, path.getUnownedSlice()); // Create the artifact - auto artifact = Artifact::create(desc, name); + auto artifact = Artifact::create(desc, name.getUnownedSlice()); // There is a problem here if I want to reference a library that is a 'system' library or is not directly a file // In that case the path shouldn't be set and the name should completely define the library. @@ -1495,11 +1495,11 @@ struct OptionsParser if (Path::getPathExt(path).getLength() <= 0) { // If there is no extension *assume* it is the name of a system level library - fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, path, nullptr, nullptr); + fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, path.getUnownedSlice(), nullptr, nullptr); } else { - fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Reference, path, nullptr, nullptr); + fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Reference, path.getUnownedSlice(), nullptr, nullptr); if (!fileRep->exists()) { sink->diagnose(referenceModuleName.loc, Diagnostics::libraryDoesNotExist, path); @@ -2045,7 +2045,7 @@ struct OptionsParser // and output type is callable, add an empty' rawOutput. if (rawOutputs.getCount() == 0 && rawTargets.getCount() == 1 && - ArtifactDescUtil::makeDescFromCompileTarget(asExternal(rawTargets[0].format)).kind == ArtifactKind::HostCallable) + ArtifactDescUtil::makeDescForCompileTarget(asExternal(rawTargets[0].format)).kind == ArtifactKind::HostCallable) { RawOutput rawOutput; rawOutput.impliedFormat = rawTargets[0].format; diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp index 0a5df003a..07875c183 100644 --- a/source/slang/slang-parameter-binding.cpp +++ b/source/slang/slang-parameter-binding.cpp @@ -3031,7 +3031,7 @@ static int _calcTotalNumUsedRegistersForLayoutResourceKind(ParameterBindingConte static bool _isCPUTarget(CodeGenTarget target) { - const auto desc = ArtifactDescUtil::makeDescFromCompileTarget(asExternal(target)); + const auto desc = ArtifactDescUtil::makeDescForCompileTarget(asExternal(target)); return ArtifactDescUtil::isCpuLikeTarget(desc); } diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index 73ccd4726..5a32f6566 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -1618,7 +1618,7 @@ bool isKhronosTarget(TargetRequest* targetReq) bool isCPUTarget(TargetRequest* targetReq) { - return ArtifactDescUtil::isCpuLikeTarget(ArtifactDescUtil::makeDescFromCompileTarget(asExternal(targetReq->getTarget()))); + return ArtifactDescUtil::isCpuLikeTarget(ArtifactDescUtil::makeDescForCompileTarget(asExternal(targetReq->getTarget()))); } bool isCUDATarget(TargetRequest* targetReq) diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 3fce0e6d9..2224c10bf 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -733,7 +733,7 @@ SlangPassThrough Session::getDownstreamCompilerForTransition(SlangCompileTarget return (SlangPassThrough)m_codeGenTransitionMap.getTransition(source, target); } - const auto desc = ArtifactDescUtil::makeDescFromCompileTarget(inTarget); + const auto desc = ArtifactDescUtil::makeDescForCompileTarget(inTarget); // Special case host-callable if ((desc.kind == ArtifactKind::HostCallable) && -- cgit v1.2.3