// slang-downstream-dep1.cpp #include "slang-downstream-dep1.h" #include "slang-artifact-util.h" #include "slang-artifact-associated-impl.h" #include "../core/slang-castable-list-impl.h" namespace Slang { /* !!!!!!!!!!!!!!!!!!!!!!!!! DownstreamArtifactRepresentation_Dep1 !!!!!!!!!!!!!!!!!!!!!!!! */ class DownstreamResultArtifactRepresentationAdapater_Dep1 : public ComBaseObject, public IArtifactRepresentation { public: SLANG_COM_BASE_IUNKNOWN_ALL // ICastable virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE; // IArtifactRepresentation 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 { return true; } DownstreamResultArtifactRepresentationAdapater_Dep1(DownstreamCompileResult_Dep1* result): m_result(result) { } void* getInterface(const Guid& guid); void* getObject(const Guid& guid); RefPtr m_result; }; void* DownstreamResultArtifactRepresentationAdapater_Dep1::castAs(const SlangUUID& guid) { if (auto ptr = getInterface(guid)) { return ptr; } return getObject(guid); } void* DownstreamResultArtifactRepresentationAdapater_Dep1::getInterface(const Guid& guid) { if (guid == ISlangBlob::getTypeGuid() || guid == ICastable::getTypeGuid() || guid == IArtifactRepresentation::getTypeGuid()) { IArtifactRepresentation* rep = this; return rep; } return nullptr; } void* DownstreamResultArtifactRepresentationAdapater_Dep1::getObject(const Guid& guid) { SLANG_UNUSED(guid); return nullptr; } SlangResult DownstreamResultArtifactRepresentationAdapater_Dep1::createRepresentation(const Guid& typeGuid, ICastable** outCastable) { if (typeGuid == ISlangSharedLibrary::getTypeGuid()) { ComPtr lib; SLANG_RETURN_ON_FAIL(DownstreamUtil_Dep1::getDownstreamSharedLibrary(m_result, lib)); *outCastable = lib.detach(); return SLANG_OK; } else if (typeGuid == ISlangBlob::getTypeGuid()) { ComPtr blob; SLANG_RETURN_ON_FAIL(m_result->getBinary(blob)); *outCastable = CastableUtil::getCastable(blob).detach(); return SLANG_OK; } return SLANG_E_NOT_AVAILABLE; } /* !!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompilerAdapter_Dep1 !!!!!!!!!!!!!!!!!!!!!!!! */ SlangResult DownstreamCompilerAdapter_Dep1::compile(const CompileOptions& options, IArtifact** outArtifact) { RefPtr result; SLANG_RETURN_ON_FAIL(m_dep->compile(options, result)); typedef CharSliceCaster Caster; ComPtr artifact = ArtifactUtil::createArtifactForCompileTarget(options.targetType); // Convert the diagnostics auto dstDiagnostics = ArtifactDiagnostics::create(); const DownstreamDiagnostics_Dep1* srcDiagnostics = &result->getDiagnostics(); dstDiagnostics->setResult(srcDiagnostics->result); dstDiagnostics->setRaw(Caster::asCharSlice(srcDiagnostics->rawDiagnostics)); for (const auto& srcDiagnostic : srcDiagnostics->diagnostics) { IArtifactDiagnostics::Diagnostic dstDiagnostic; dstDiagnostic.severity = ArtifactDiagnostic::Severity(srcDiagnostic.severity); dstDiagnostic.stage = ArtifactDiagnostic::Stage(srcDiagnostic.stage); dstDiagnostic.code = Caster::asTerminatedCharSlice(srcDiagnostic.code); dstDiagnostic.text = Caster::asTerminatedCharSlice(srcDiagnostic.text); dstDiagnostic.filePath = Caster::asTerminatedCharSlice(srcDiagnostic.filePath); dstDiagnostic.location.line = srcDiagnostic.fileLine; } artifact->addAssociated(dstDiagnostics); // We need to add a representation that can produce shared libraries/blobs on demand auto rep = new DownstreamResultArtifactRepresentationAdapater_Dep1(result); artifact->addRepresentation(rep); *outArtifact = artifact.detach(); return SLANG_OK; } /* !!!!!!!!!!!!!!!!!!!!!!!!! SharedLibraryDep1Adapter !!!!!!!!!!!!!!!!!!!!!!!! */ // A temporary class that adapts `ISlangSharedLibrary_Dep1` to ISlangSharedLibrary class SharedLibraryAdapter_Dep1 : 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); } SharedLibraryAdapter_Dep1(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(this); } return nullptr; } void* getObject(const Guid& guid) { SLANG_UNUSED(guid); return nullptr; } ComPtr m_contained; }; void* SharedLibraryAdapter_Dep1::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 DownstreamUtil_Dep1::getDownstreamSharedLibrary(DownstreamCompileResult_Dep1* downstreamResult, ComPtr& outSharedLibrary) { ComPtr lib; SLANG_RETURN_ON_FAIL(downstreamResult->getHostCallableSharedLibrary(lib)); if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary::getTypeGuid(), (void**)outSharedLibrary.writeRef()))) { return SLANG_OK; } ComPtr libDep1; if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary_Dep1::getTypeGuid(), (void**)libDep1.writeRef()))) { // Okay, we need to adapt for now outSharedLibrary = new SharedLibraryAdapter_Dep1(libDep1); return SLANG_OK; } return SLANG_E_NOT_FOUND; } }