summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-26 20:32:53 -0400
committerGitHub <noreply@github.com>2022-08-26 20:32:53 -0400
commit5c2c2cfc9918bb43225159e67a851e196e17759a (patch)
tree216009d02afe9dc17b074fdd394141ef71472268 /source/core
parentef067bef2f2188a4b3c420cbcd8d223874888ed2 (diff)
DownstreamCompileOptions using POD types (#2381)
* #include an absolute path didn't work - because paths were taken to always be relative. * Make DownstreamCompileOptions use POD types. * CharSliceAllocator -> SliceAllocator Added SliceConverter CharSliceCaster -> SliceCaster * First attempt at zero terminating around blobs. * Fix clang warning. * Add SlangTerminatedChars Make Blob implementations support it. Make most blobs 'terminated'. * Fix bug setting up sourceFiles for CommandLineDownstreamCompiler. * Traffic in TerminatedCharSlice for sourceFiles. Use ArtifactDesc to generate temporary file names for source. * Fix typo in testing for shared library/C++.
Diffstat (limited to 'source/core')
-rw-r--r--source/core/slang-blob.cpp98
-rw-r--r--source/core/slang-blob.h92
-rw-r--r--source/core/slang-io.cpp2
-rw-r--r--source/core/slang-riff-file-system.cpp2
-rw-r--r--source/core/slang-zip-file-system.cpp2
5 files changed, 165 insertions, 31 deletions
diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp
index 0da8f6292..6cf5214cc 100644
--- a/source/core/slang-blob.cpp
+++ b/source/core/slang-blob.cpp
@@ -33,6 +33,104 @@ void* BlobBase::castAs(const SlangUUID& guid)
return getObject(guid);
}
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* StringBlob::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+void* StringBlob::getObject(const Guid& guid)
+{
+ // Can allow accessing the contained String
+ if (guid == getTypeGuid())
+ {
+ return this;
+ }
+ // Can always be accessed as terminated char*
+ if (guid == SlangTerminatedChars::getTypeGuid())
+ {
+ return const_cast<char*>(m_string.getBuffer());
+ }
+ return nullptr;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RawBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* RawBlob::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+void* RawBlob::getObject(const Guid& guid)
+{
+ // If the data has 0 termination, we can return the pointer
+ if (guid == SlangTerminatedChars::getTypeGuid() && m_data.isTerminated())
+ {
+ return (char*)m_data.getData();
+ }
+ return nullptr;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ScopeBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* ScopeBlob::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ if (auto obj = getObject(guid))
+ {
+ return obj;
+ }
+
+ // If the contained thing is castable, ask it
+ if (m_castable)
+ {
+ return m_castable->castAs(guid);
+ }
+
+ return nullptr;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ListBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* ListBlob::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+void* ListBlob::getObject(const Guid& guid)
+{
+ // If the data is terminated return the pointer
+ if (guid == SlangTerminatedChars::getTypeGuid())
+ {
+ const auto count = m_data.getCount();
+ if (m_data.getCapacity() > count)
+ {
+ auto buf = m_data.getBuffer();
+ if (buf[count] == 0)
+ {
+ return (char*)buf;
+ }
+ }
+ }
+ return nullptr;
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StaticBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject)
diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h
index 49bfd4a17..1acf279ef 100644
--- a/source/core/slang-blob.h
+++ b/source/core/slang-blob.h
@@ -40,7 +40,12 @@ There is a reasonable argument that StringBlob should contain it's own copy of t
class StringBlob : public BlobBase
{
public:
- // ISlangBlob
+ SLANG_CLASS_GUID(0xf7e0e93c, 0xde70, 0x4531, { 0x9c, 0x9f, 0xdd, 0xa3, 0xf6, 0xc6, 0xc0, 0xdd });
+
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
+
+ // ISlangBlob
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_string.getBuffer(); }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_string.getLength(); }
@@ -61,6 +66,8 @@ protected:
/// Get the contained string
SLANG_FORCE_INLINE const String& getString() const { return m_string; }
+ void* getObject(const Guid& guid);
+
String m_string;
};
@@ -70,6 +77,8 @@ public:
typedef BlobBase Super;
typedef ListBlob ThisType;
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangBlob
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getBuffer(); }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getCount(); }
@@ -83,6 +92,8 @@ protected:
// Move ctor
explicit ListBlob(List<uint8_t>&& data) : m_data(data) {}
+ void* getObject(const Guid& guid);
+
void operator=(const ThisType& rhs) = delete;
List<uint8_t> m_data;
@@ -96,10 +107,22 @@ public:
void* allocate(size_t size)
{
deallocate();
- m_data = ::malloc(size);
+ if (size > 0)
+ {
+ m_data = ::malloc(size);
+ }
m_sizeInBytes = size;
+ m_capacityInBytes = size;
return m_data;
}
+ /// Allocate size including a 0 byte at `size`.
+ void* allocateTerminated(size_t size)
+ {
+ uint8_t* data = (uint8_t*)allocate(size + 1);
+ data[size] = 0;
+ m_sizeInBytes = size;
+ return data;
+ }
/// Deallocates if holds an allocation
void deallocate()
{
@@ -109,14 +132,16 @@ public:
m_data = nullptr;
}
m_sizeInBytes = 0;
+ m_capacityInBytes = 0;
}
- // Reallocate so the buffer is the specified size. Contents of buffer up to size remain intact.
- void reallocate(size_t size)
+ // Reallocate so the buffer is the specified capacity/size. Contents of buffer up to size remain intact.
+ void reallocate(size_t capacity)
{
- if (size != m_sizeInBytes)
+ if (capacity != m_capacityInBytes)
{
- m_data = ::realloc(m_data, size);
- m_sizeInBytes = size;
+ m_data = ::realloc(m_data, capacity);
+ m_sizeInBytes = capacity;
+ m_capacityInBytes = capacity;
}
}
/// Makes this no longer own the allocation. Returns the allocated data (or nullptr if no allocation)
@@ -125,6 +150,7 @@ public:
void* data = m_data;
m_data = nullptr;
m_sizeInBytes = 0;
+ m_capacityInBytes = 0;
return data;
}
/// Attach some data.
@@ -134,6 +160,7 @@ public:
deallocate();
m_data = data;
m_sizeInBytes = size;
+ m_capacityInBytes = size;
}
void* set(const void* data, size_t size)
@@ -146,26 +173,33 @@ public:
return dst;
}
- /// Get the allocated data. Returns nullptr if there is no allocated data
+ /// Get the allocated data. Returns nullptr if there is no allocated data
void* getData() const { return m_data; }
- /// Get the size of the allocated data.
+ /// Get the size of the allocated data.
size_t getSizeInBytes() const { return m_sizeInBytes; }
+ /// Get the capacity in bytes
+ size_t getCapacityInBytes() const { return m_capacityInBytes; }
- void swap(ThisType& rhs)
+ void setSizeInBytes(size_t size)
{
- void*const data = m_data;
- const size_t sizeInBytes = m_sizeInBytes;
-
- m_data = rhs.m_data;
- m_sizeInBytes = rhs.m_sizeInBytes;
+ SLANG_ASSERT(size <= m_capacityInBytes);
+ m_sizeInBytes = size;
+ }
- rhs.m_data = data;
- rhs.m_sizeInBytes = sizeInBytes;
+ void swap(ThisType& rhs)
+ {
+ Swap(m_data, rhs.m_data);
+ Swap(m_sizeInBytes, rhs.m_sizeInBytes);
+ Swap(m_capacityInBytes, rhs.m_capacityInBytes);
}
+ /// True if has zero termination, at the byte at m_sizeInBytes
+ bool isTerminated() const { return m_capacityInBytes > m_sizeInBytes && ((const char*)m_data)[m_sizeInBytes] == 0; }
+
ScopedAllocation() :
m_data(nullptr),
- m_sizeInBytes(0)
+ m_sizeInBytes(0),
+ m_capacityInBytes(0)
{
}
@@ -178,6 +212,7 @@ private:
void* m_data;
size_t m_sizeInBytes;
+ size_t m_capacityInBytes;
};
/** A blob that manages some raw data that it owns.
@@ -185,18 +220,12 @@ private:
class RawBlob : public BlobBase
{
public:
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangBlob
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getData(); }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getSizeInBytes(); }
- /// Moves ownership of data and dataCount to the blob
- /// data must be a pointer returned by ::malloc.
- static ComPtr<ISlangBlob> moveCreate(uint8_t* data, size_t dataCount)
- {
- RawBlob* blob = new RawBlob;
- blob->m_data.attach(data, dataCount);
- return ComPtr<ISlangBlob>(blob);
- }
static ComPtr<ISlangBlob> moveCreate(ScopedAllocation& alloc)
{
RawBlob* blob = new RawBlob;
@@ -215,9 +244,11 @@ protected:
// NOTE! Takes a copy of the input data
RawBlob(const void* data, size_t size)
{
- memcpy(m_data.allocate(size), data, size);
+ memcpy(m_data.allocateTerminated(size), data, size);
}
+ void* getObject(const Guid& guid);
+
RawBlob() = default;
ScopedAllocation m_data;
@@ -287,6 +318,9 @@ protected:
class ScopeBlob : public BlobBase
{
public:
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
+
// 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(); }
@@ -299,15 +333,17 @@ public:
protected:
// Ctor
-
ScopeBlob(ISlangBlob* blob, ISlangUnknown* scope) :
m_blob(blob),
m_scope(scope)
{
+ // Cache the ICastable interface if there is one.
+ blob->queryInterface(ICastable::getTypeGuid(), (void**)m_castable.writeRef());
}
ComPtr<ISlangUnknown> m_scope;
ComPtr<ISlangBlob> m_blob;
+ ComPtr<ICastable> m_castable; ///< Set if the blob has this interface. Set to nullptr if does not.
};
} // namespace Slang
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index a6e97057b..ef260f088 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -894,7 +894,7 @@ namespace Slang
const size_t sizeInBytes = size_t(positionSizeInBytes);
- void* data = out.allocate(sizeInBytes);
+ void* data = out.allocateTerminated(sizeInBytes);
if (!data)
{
return SLANG_E_OUT_OF_MEMORY;
diff --git a/source/core/slang-riff-file-system.cpp b/source/core/slang-riff-file-system.cpp
index 186650ed3..e916cf689 100644
--- a/source/core/slang-riff-file-system.cpp
+++ b/source/core/slang-riff-file-system.cpp
@@ -87,7 +87,7 @@ SlangResult RiffFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
{
// Okay lets decompress into a blob
ScopedAllocation alloc;
- void* dst = alloc.allocate(entry->m_uncompressedSizeInBytes);
+ void* dst = alloc.allocateTerminated(entry->m_uncompressedSizeInBytes);
ISlangBlob* compressedData = entry->m_contents;
SLANG_RETURN_ON_FAIL(m_compressionSystem->decompress(compressedData->getBufferPointer(), compressedData->getBufferSize(), entry->m_uncompressedSizeInBytes, dst));
diff --git a/source/core/slang-zip-file-system.cpp b/source/core/slang-zip-file-system.cpp
index ce25066df..64ed64e13 100644
--- a/source/core/slang-zip-file-system.cpp
+++ b/source/core/slang-zip-file-system.cpp
@@ -430,7 +430,7 @@ SlangResult ZipFileSystemImpl::loadFile(char const* path, ISlangBlob** outBlob)
}
ScopedAllocation alloc;
- if (!alloc.allocate(size_t(fileStat.m_uncomp_size)))
+ if (!alloc.allocateTerminated(size_t(fileStat.m_uncomp_size)))
{
return SLANG_E_OUT_OF_MEMORY;
}