diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-06-24 10:00:23 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-24 10:00:23 -0400 |
| commit | 542741143b69c248ab457d1f767b0895430e9f90 (patch) | |
| tree | 5a3592ae41ad240aa3ef3c0dcd7ca7bff39af346 /source | |
| parent | 353777ec33b5b097e0d0f4bc602811a9775ef237 (diff) | |
Remove StructTag and associated systems (#1895)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Remove StructTag and associated systems.
* Fix typo and remove unit test for StructTag.
Diffstat (limited to 'source')
| -rw-r--r-- | source/compiler-core/slang-misc-diagnostic-defs.h | 5 | ||||
| -rw-r--r-- | source/compiler-core/slang-struct-tag-converter.cpp | 538 | ||||
| -rw-r--r-- | source/compiler-core/slang-struct-tag-converter.h | 153 | ||||
| -rw-r--r-- | source/compiler-core/slang-struct-tag-system.cpp | 126 | ||||
| -rw-r--r-- | source/compiler-core/slang-struct-tag-system.h | 259 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 7 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 65 |
7 files changed, 17 insertions, 1136 deletions
diff --git a/source/compiler-core/slang-misc-diagnostic-defs.h b/source/compiler-core/slang-misc-diagnostic-defs.h index f3ac0bae5..aa87f02f9 100644 --- a/source/compiler-core/slang-misc-diagnostic-defs.h +++ b/source/compiler-core/slang-misc-diagnostic-defs.h @@ -30,11 +30,6 @@ DIAGNOSTIC(100002, Error, unbalancedDownstreamArguments, "unbalanced downstream DIAGNOSTIC(100003, Error, closeOfUnopenDownstreamArgs, "close of an unopen downstream argument scope") DIAGNOSTIC(100004, Error, downstreamToolNameNotDefined, "downstream tool name not defined") -DIAGNOSTIC(110001, Error, structTagConversionFailureNoArena, "StructTag conversion failed - no arena") -DIAGNOSTIC(110002, Error, unknownStructTag, "unknown StructTag $0") -DIAGNOSTIC(110003, Error, cannotConvertStructTag, "cannot convert StructTag $0 to $1") -DIAGNOSTIC(110004, Error, cannotConvertDifferentStructTag, "cannot convert different StructTag types $0 to $1") - DIAGNOSTIC(99999, Note, noteLocationOfInternalError, "an internal error threw an exception while working on code near this location") #undef DIAGNOSTIC diff --git a/source/compiler-core/slang-struct-tag-converter.cpp b/source/compiler-core/slang-struct-tag-converter.cpp deleted file mode 100644 index 9e891e642..000000000 --- a/source/compiler-core/slang-struct-tag-converter.cpp +++ /dev/null @@ -1,538 +0,0 @@ -#include "slang-struct-tag-converter.h" - -#include "slang-core-diagnostics.h" - -namespace Slang { - -static Index _getCount(const StructTagType::Field& field, const void* in) -{ - typedef StructTagField::Type FieldType; - - const uint8_t* ptr = (const uint8_t*)in; - - switch (field.m_countType) - { - case FieldType::I32: return Index(*(const int32_t*)(ptr + field.m_countOffset)); - case FieldType::I64: return Index(*(const int64_t*)(ptr + field.m_countOffset)); - default: break; - } - - SLANG_ASSERT(!"Cannot access as count"); - return -1; -} - -SlangResult StructTagConverterBase::_requireArena() -{ - if (!m_arena) - { - if (m_sink) - { - // Diagnose that we need an arena - m_sink->diagnose(SourceLoc(), MiscDiagnostics::structTagConversionFailureNoArena); - } - return SLANG_FAIL; - } - - return SLANG_OK; -} - -SlangResult StructTagConverterBase::_diagnoseCantConvert(slang::StructTag tag, StructTagType* structType) -{ - SLANG_UNUSED(tag); - SLANG_UNUSED(structType); - - if (m_sink) - { - // Diagnose why the tag couldn't be converted - StringBuilder from, to; - m_system->appendName(tag, from); - m_system->appendName(structType->m_tag, to); - - m_sink->diagnose(SourceLoc(), MiscDiagnostics::cannotConvertStructTag, from, to); - } - - return SLANG_E_STRUCT_TAG_INCOMPATIBLE; -} - -SlangResult StructTagConverterBase::_diagnoseUnknownType(slang::StructTag tag) -{ - SLANG_UNUSED(tag); - - if (m_sink) - { - StringBuilder buf; - m_system->appendName(tag, buf); - m_sink->diagnose(SourceLoc(), MiscDiagnostics::unknownStructTag, buf); - } - - // Perhaps this isn't quite right - but it's probably the most suitable error - return SLANG_E_STRUCT_TAG_INCOMPATIBLE; -} - -SlangResult StructTagConverterBase::_diagnoseDifferentTypes(slang::StructTag tagA, slang::StructTag tagB) -{ - if (m_sink) - { - StringBuilder a, b; - m_system->appendName(tagA, a); - m_system->appendName(tagB, b); - - m_sink->diagnose(SourceLoc(), MiscDiagnostics::cannotConvertDifferentStructTag, a, b); - } - - // Perhaps this isn't quite right - but it's probably the most suitable error - return SLANG_E_STRUCT_TAG_INCOMPATIBLE; -} - -bool StructTagConverterBase::canConvertToCurrent(slang::StructTag tag, StructTagType* type) const -{ - // Means can be used without any modification - if (StructTagUtil::isReadCompatible(tag, type->m_tag)) - { - return true; - } - - // We may want to allow zero extension, or initialization - // We can accept for conversion if it's the same type with only difference being the minor version. - return StructTagUtil::areSameMajorType(tag, type->m_tag); -} - -void StructTagConverterBase::copy(const StructTagType* structType, const void* src, void* dst) -{ - const slang::TaggedStructBase* srcBase = reinterpret_cast<const slang::TaggedStructBase*>(src); - - const slang::StructSize size = std::min(structType->m_sizeInBytes, srcBase->structSize); - - // Copy - ::memcpy(dst, src, size); - - // TODO(JS): Alternatively if we have the default set on the structType, we could initialize - // other fields with the default values. For the moment we zero - - // Zero any extra - if (size < structType->m_sizeInBytes) - { - ::memset((char*)dst + size, 0, structType->m_sizeInBytes - size); - } - - // Set the type and the size - slang::TaggedStructBase* dstBase = reinterpret_cast<slang::TaggedStructBase*>(dst); - dstBase->structTag = structType->m_tag; - dstBase->structSize = structType->m_sizeInBytes; -} - -void* StructTagConverterBase::allocateAndCopy(const StructTagType* structType, const void* src) -{ - uint8_t* dst = (uint8_t*)m_arena->allocate(structType->m_sizeInBytes); - copy(structType, src, dst); - return dst; -} - -SlangResult StructTagConverterBase::convertCurrent(slang::StructTag tag, const void* in, void*& out) -{ - auto base = reinterpret_cast<const slang::TaggedStructBase*>(in); - auto inTag = base->structTag; - - // Currently we can only convert if same major type. - // In future it might be possible to improve on this - if (!StructTagUtil::areSameMajorType(inTag, tag)) - { - return _diagnoseDifferentTypes(inTag, tag); - } - - return convertCurrent(in, out); -} - -SlangResult StructTagConverterBase::convertArrayField(const FieldType type, const void* in, Index count, void*& out) -{ - if (count <= 0) - { - out = const_cast<void*>(in); - return SLANG_OK; - } - - SLANG_ASSERT(in); - switch (type) - { - case FieldType::PtrTaggedStruct: return convertCurrentArray(in, count, out); - case FieldType::PtrPtrTaggedStruct: return convertCurrentPtrArray((const void*const*)in, count, (void**&)out); - default: break; - } - return SLANG_FAIL; -} - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - CopyStructTagConverter - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -SlangResult CopyStructTagConverter::convertCurrentPtrArray(const void*const* in, Index count, void**& out) -{ - if (count == 0) - { - out = nullptr; - return SLANG_OK; - } - void** dst = (void**)m_arena->allocate(count * sizeof(void*)); - for (Index i = 0; i < count; ++i) - { - SLANG_RETURN_ON_FAIL(convertCurrent(in[i], dst[i])); - } - out = dst; - return SLANG_OK; -} - -SlangResult CopyStructTagConverter::convertCurrentArray(const void* in, Index count, void*& out) -{ - if (count <= 0) - { - out = nullptr; - return SLANG_OK; - } - - if (count == 1) - { - return convertCurrent(in, out); - } - - const slang::TaggedStructBase* arr = reinterpret_cast<const slang::TaggedStructBase*>(in); - - // We assume all have the same size/type - auto tag = arr[0].structTag; - - auto structType = m_system->getType(tag); - - if (!structType) - { - return _diagnoseUnknownType(tag); - } - if (!canConvertToCurrent(tag, structType)) - { - return _diagnoseCantConvert(tag, structType); - } - - const size_t dstStride = structType->m_sizeInBytes; - uint8_t*const dstStart = (uint8_t*)m_arena->allocate(dstStride * count); - uint8_t* dst = dstStart; - - size_t srcStride = arr[0].structSize; - const uint8_t* src = reinterpret_cast<const uint8_t*>(in); - - for (Index i = 0; i < count; ++i) - { - copy(structType, src, dst); - SLANG_RETURN_ON_FAIL(convertCurrentContained(structType, dst)); - - src += srcStride; - dst += dstStride; - } - - out = dstStart; - return SLANG_OK; -} - -SlangResult CopyStructTagConverter::convertCurrentContained(const StructTagType* structType, void* inout) -{ - // Convert primary - if (StructTagUtil::isPrimary(structType->m_tag)) - { - // Copy extensions if needed - slang::PrimaryTaggedStruct* primary = reinterpret_cast<slang::PrimaryTaggedStruct*>(inout); - if (primary->extsCount > 0) - { - void** dstExts; - SLANG_RETURN_ON_FAIL(convertCurrentPtrArray((const void*const*)primary->exts, primary->extsCount, dstExts)); - primary->exts = (const slang::StructTag**)dstExts; - } - } - - // It may have fields that need to be converted - for (const auto& field : structType->m_fields) - { - const Index count = _getCount(field, inout); - if (count) - { - void*& ptrRef = *(void**)(reinterpret_cast<uint8_t*>(inout) + field.m_offset); - SLANG_RETURN_ON_FAIL(convertArrayField(field.m_type, ptrRef, count, ptrRef)); - } - } - - return SLANG_OK; -} - -SlangResult CopyStructTagConverter::convertCurrent(const void* in, void*& out) -{ - auto tag = reinterpret_cast<const slang::TaggedStructBase*>(in)->structTag; - - auto structType = m_system->getType(tag); - if (!structType) - { - return _diagnoseUnknownType(tag); - } - if (!canConvertToCurrent(tag, structType)) - { - return _diagnoseCantConvert(tag, structType); - } - - slang::TaggedStructBase* dst = (slang::TaggedStructBase*)allocateAndCopy(structType, in); - SLANG_RETURN_ON_FAIL(convertCurrentContained(structType, dst)); - out = dst; - return SLANG_OK; -} - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - LazyStructTagConverter - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -SlangResult LazyStructTagConverter::convertCurrentPtrArray(const void*const* in, Index count, void**& out) -{ - if (count == 0) - { - out = (void**)in; - return SLANG_OK; - } - - Index numConverted = 0; - ScopeStack stackScope(this); - - for (Index i = 0; i < count; ++i) - { - const void* src = in[i]; - void* dst; - SLANG_RETURN_ON_FAIL(convertCurrent(src, dst)); - - // Make space if not set up - numConverted += Index(dst != src); - m_convertStack.add(dst); - } - - // We need to make a copy of the exts - if (numConverted) - { - SLANG_RETURN_ON_FAIL(_requireArena()); - out = (void**)m_arena->allocateAndCopyArray(m_convertStack.getBuffer() + stackScope.getStartIndex(), count); - } - else - { - out = (void**)in; - } - - return SLANG_OK; -} - -void LazyStructTagConverter::setContainedConverted(const StructTagType* structType, Index stackIndex, BitField fieldsSet, void* out) -{ - if (fieldsSet == 0) - { - return; - } - - if (StructTagUtil::isPrimary(structType->m_tag)) - { - if (fieldsSet & 1) - { - // Copy extensions if needed - slang::PrimaryTaggedStruct* primary = reinterpret_cast<slang::PrimaryTaggedStruct*>(out); - primary->exts = (const slang::StructTag**)m_convertStack[stackIndex++]; - } - fieldsSet >>= 1; - } - - { - for (const auto& field : structType->m_fields) - { - if (fieldsSet == 0) - { - return; - } - - // If the field is set, copy - if (fieldsSet & 1) - { - switch (field.m_type) - { - case FieldType::PtrTaggedStruct: - case FieldType::PtrPtrTaggedStruct: - { - *(const void**)(reinterpret_cast<const uint8_t*>(out) + field.m_offset) = m_convertStack[stackIndex++]; - break; - } - default: break; - } - } - - // Remove the bit - fieldsSet >>= 1; - } - } -} - - -SlangResult LazyStructTagConverter::maybeConvertCurrentContained(const StructTagType* structType, const void* in, BitField* outFieldsSet) -{ - BitField fieldsSet = 0; - BitField bit = 1; - - if (StructTagUtil::isPrimary(structType->m_tag)) - { - // Copy extensions if needed - const slang::PrimaryTaggedStruct* primary = reinterpret_cast<const slang::PrimaryTaggedStruct*>(in); - if (primary->extsCount > 0) - { - auto srcExts = (const void*const*)primary->exts; - void** dstExts; - SLANG_RETURN_ON_FAIL(convertCurrentPtrArray(srcExts, primary->extsCount, dstExts)); - - if (dstExts != srcExts) - { - m_convertStack.add(dstExts); - fieldsSet |= bit; - } - } - - bit += bit; - } - - // It may have fields that need to be converted - - { - for (const auto& field : structType->m_fields) - { - const Index count = _getCount(field, in); - if (count > 0) - { - void* dst = nullptr; - const void* src = *(const void**)(reinterpret_cast<const uint8_t*>(in) + field.m_offset); - SLANG_RETURN_ON_FAIL(convertArrayField(field.m_type, src, count, dst)); - - if (dst != src) - { - // Set the and add to the stack - m_convertStack.add(dst); - fieldsSet |= bit; - } - } - - bit += bit; - } - } - - *outFieldsSet = fieldsSet; - return SLANG_OK; -} - -SlangResult LazyStructTagConverter::convertCurrentArray(const void* in, Index count, void*& out) -{ - if (count == 0) - { - out = (void*)in; - return SLANG_OK; - } - - if (count == 1) - { - return convertCurrent(in, out); - } - - const slang::TaggedStructBase* arr = reinterpret_cast<const slang::TaggedStructBase*>(in); - - // We assume all have the same size/type - auto tag = arr[0].structTag; - - auto structType = m_system->getType(tag); - - if (!structType) - { - return _diagnoseUnknownType(tag); - } - - if (StructTagUtil::areSameMajorType(tag, structType->m_tag) && structType->m_sizeInBytes == arr[0].structSize) - { - // Can just use what was passed in - out = (void*)in; - return SLANG_OK; - } - - if (!canConvertToCurrent(tag, structType)) - { - return _diagnoseCantConvert(tag, structType); - } - - SLANG_RETURN_ON_FAIL(_requireArena()); - - const size_t dstStride = structType->m_sizeInBytes; - uint8_t*const dstStart = (uint8_t*)m_arena->allocate(dstStride * count); - uint8_t* dst = dstStart; - - size_t srcStride = arr[0].structSize; - const uint8_t* src = reinterpret_cast<const uint8_t*>(in); - - for (Index i = 0; i < count; ++i) - { - // Do the straight copy - copy(structType, src, dst); - - // Work out what was converted - ScopeStack scopeStack(this); - BitField fieldsSet; - SLANG_RETURN_ON_FAIL(maybeConvertCurrentContained(structType, in, &fieldsSet)); - - // Copy anything converted - setContainedConverted(structType, scopeStack, fieldsSet, dst); - - src += srcStride; - dst += dstStride; - } - - out = dstStart; - return SLANG_OK; -} - -SlangResult LazyStructTagConverter::convertCurrent(const void* in, void*& out) -{ - auto base = reinterpret_cast<const slang::TaggedStructBase*>(in); - auto tag = base->structTag; - - // If can't find the type it's incompatible - auto structType = m_system->getType(tag); - if (!structType) - { - return _diagnoseUnknownType(tag); - } - - if (!canConvertToCurrent(tag, structType)) - { - return _diagnoseCantConvert(tag, structType); - } - - // Let's see if how everything contained converts - ScopeStack stackScope(this); - BitField fieldsSet; - SLANG_RETURN_ON_FAIL(maybeConvertCurrentContained(structType, in, &fieldsSet)); - - // If there were no fields set - if (fieldsSet == 0) - { - // And it's the same major type, and is at least as big a the current struct - // We can just use as is - if (StructTagUtil::areSameMajorType(tag, structType->m_tag) && base->structSize >= structType->m_sizeInBytes) - { - out = (void*)in; - return SLANG_OK; - } - } - - // Okay we will need to allocate and copy - void* dst = allocateAndCopy(structType, in); - - // Copy anything converted - setContainedConverted(structType, stackScope, fieldsSet, dst); - - out = dst; - return SLANG_OK; -} - -} // namespace Slang diff --git a/source/compiler-core/slang-struct-tag-converter.h b/source/compiler-core/slang-struct-tag-converter.h deleted file mode 100644 index 5f0ec7087..000000000 --- a/source/compiler-core/slang-struct-tag-converter.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef SLANG_COMPILER_CORE_STRUCT_TAG_CONVERTER_H -#define SLANG_COMPILER_CORE_STRUCT_TAG_CONVERTER_H - -#include "slang-struct-tag-system.h" -#include "slang-diagnostic-sink.h" - -namespace Slang { - -class StructTagConverterBase -{ -public: - typedef StructTagConverterBase ThisType; - typedef StructTagField Field; - typedef Field::Type FieldType; - - virtual SlangResult convertCurrent(const void* in, void*& out) = 0; - virtual SlangResult convertCurrentArray(const void* in, Index count, void*& out) = 0; - virtual SlangResult convertCurrentPtrArray(const void*const* in, Index count, void**& out) = 0; - - SlangResult convertCurrent(slang::StructTag tag, const void* in, void*& out); - - /// Allocates of type and copies src to dst - void* allocateAndCopy(const StructTagType* type, const void* src); - /// Copy from src to dst, zero extending or shrinking however structType requires - void copy(const StructTagType* structType, const void* src, void* dst); - - /// Returns true if it's possible to convert tag to current type - bool canConvertToCurrent(slang::StructTag tag, StructTagType* type) const; - - template <typename T> - const T* convertToCurrent(const void* in) - { - void* dst; - return SLANG_SUCCEEDED(convertCurrent(T::kStructTag, in, dst)) ? (const T*)dst : nullptr; - } - - template <typename T> - SlangResult convertToCurrent(const void* in, const T** out) - { - void* dst; - SLANG_RETURN_ON_FAIL(convertCurrent(T::kStructTag, in, dst)); - *out = (const T*)dst; - return SLANG_OK; - } - - /// Convert a single field which is an array type - SlangResult convertArrayField(const FieldType type, const void* in, Index count, void*& out); - - /// Ctor. Arena and sink can be optionally set (pass nullptr if not wanted) - StructTagConverterBase(StructTagSystem* system, MemoryArena* arena, DiagnosticSink* sink) : - m_system(system), - m_arena(arena), - m_sink(sink) - { - } - -protected: - StructTagConverterBase(const ThisType& rhs) = delete; - void operator=(const ThisType& rhs) = delete; - - SlangResult _requireArena(); - SlangResult _diagnoseCantConvert(slang::StructTag tag, StructTagType* type); - SlangResult _diagnoseUnknownType(slang::StructTag tag); - SlangResult _diagnoseDifferentTypes(slang::StructTag tagA, slang::StructTag tagB); - - StructTagSystem* m_system; - DiagnosticSink* m_sink; - MemoryArena* m_arena; -}; - -class CopyStructTagConverter : public StructTagConverterBase -{ -public: - typedef StructTagConverterBase Super; - - // StructTagConverterBase - virtual SlangResult convertCurrent(const void* in, void*& out) SLANG_OVERRIDE; - virtual SlangResult convertCurrentArray(const void* in, Index count, void*& out) SLANG_OVERRIDE; - virtual SlangResult convertCurrentPtrArray(const void*const* in, Index count, void**& out) SLANG_OVERRIDE; - - /// Convert the items contained in inout - SlangResult convertCurrentContained(const StructTagType* structType, void* inout); - - CopyStructTagConverter(StructTagSystem* system, MemoryArena* arena, DiagnosticSink* sink) : - Super(system, arena, sink) - { - // If we are going to copy -> we have to have an arena - SLANG_ASSERT(arena); - } -}; - -class LazyStructTagConverter : public StructTagConverterBase -{ -public: - typedef StructTagConverterBase Super; - - typedef uint32_t BitField; - - struct ScopeStack - { - ScopeStack(LazyStructTagConverter* converter): - m_stack(converter->m_convertStack), - m_startIndex(converter->m_convertStack.getCount()) - { - } - ~ScopeStack() - { - m_stack.setCount(m_startIndex); - } - - Index getStartIndex() const { return m_startIndex; } - operator Index() const { return m_startIndex; } - - protected: - List<void*>& m_stack; - Index m_startIndex; - }; - - // StructTagConverterBase - virtual SlangResult convertCurrent(const void* in, void*& out) SLANG_OVERRIDE; - virtual SlangResult convertCurrentArray(const void* in, Index count, void*& out) SLANG_OVERRIDE; - virtual SlangResult convertCurrentPtrArray(const void*const* in, Index count, void**& out) SLANG_OVERRIDE; - - /// Convert all the referenced items starting at in. - /// Items that are converted are stored on the m_convertStack. - /// The BitField records a bit for every 'field' (where exts is the 0 field) where there is something converted. - /// If the BitField has no bits set -> then nothing was converted and can be used as is. - /// To write the converted data, use setContainedConverted. - /// - /// NOTE! This method adds items to the end of the m_convertStack, it is the responsibility of the caller to clean up - /// This can be made simpler by just using ScopeStack. - SlangResult maybeConvertCurrentContained(const StructTagType* structType, const void* in, BitField* outFieldsSet); - - /// For every fieldSet bit set, copys over the data held in the m_convertStack (indexed from stackStartIndex). - void setContainedConverted(const StructTagType* structType, Index stackIndex, BitField fieldsSet, void* dst); - - /// Ctor. The sink and arena are optional. If the arena isn't set then it is not possible to copy convert anything - /// and so if a copy convert is required, it will fail. - /// The sink is optional - if it's set failures will occur silently. - LazyStructTagConverter(StructTagSystem* system, MemoryArena* arena, DiagnosticSink* sink): - Super(system, arena, sink) - { - } - -protected: - - /// Used to hold pointers to things that have been converted. - List<void*> m_convertStack; -}; - -} // namespace Slang - -#endif // SLANG_COMPILER_CORE_STRUCT_TAG_CONVERTER_H diff --git a/source/compiler-core/slang-struct-tag-system.cpp b/source/compiler-core/slang-struct-tag-system.cpp deleted file mode 100644 index 405d17360..000000000 --- a/source/compiler-core/slang-struct-tag-system.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "slang-struct-tag-system.h" - - -namespace Slang { - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructTagCategoryInfo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -StructTagCategoryInfo::~StructTagCategoryInfo() -{ - for (auto type : m_types) - { - if (type) - { - type->~StructTagType(); - } - } - -} - -void StructTagCategoryInfo::addType(StructTagType* type) -{ - auto typeIndex = StructTagUtil::getTypeIndex(type->m_tag); - - if (typeIndex >= m_types.getCount()) - { - Index prevCount = m_types.getCount(); - m_types.setCount(typeIndex + 1); - // Zero it - ::memset(m_types.getBuffer() + prevCount, 0, sizeof(StructTagType*) * (m_types.getCount() - prevCount)); - } - - SLANG_ASSERT(m_types[typeIndex] == nullptr); - m_types[typeIndex] = type; -} - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructTagSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -StructTagSystem::~StructTagSystem() -{ - for (auto category : m_categories) - { - if (category) - { - category->~StructTagCategoryInfo(); - } - } -} - -StructTagCategoryInfo* StructTagSystem::getCategoryInfo(slang::StructTagCategory category) -{ - const Index index = Index(category); - return (index < m_categories.getCount()) ? m_categories[index] : nullptr; -} - -StructTagCategoryInfo* StructTagSystem::addCategoryInfo(slang::StructTagCategory category, const String& name) -{ - StructTagCategoryInfo* categoryInfo = new (m_arena.allocateAligned(sizeof(StructTagCategoryInfo), SLANG_ALIGN_OF(StructTagCategoryInfo))) StructTagCategoryInfo(category, name); - - const Index index = Index(category); - - if (index >= m_categories.getCount()) - { - m_categories.setCount(index + 1); - } - m_categories[index] = categoryInfo; - return categoryInfo; -} - -StructTagType* StructTagSystem::addType(slang::StructTag tag, const String& name, size_t sizeInBytes) -{ - auto category = StructTagUtil::getCategory(tag); - auto categoryInfo = getCategoryInfo(category); - - auto structType = new (m_arena.allocate<StructTagType>()) StructTagType(tag, name, sizeInBytes); - categoryInfo->addType(structType); - - return structType; -} - -StructTagType* StructTagSystem::getType(slang::StructTag tag) -{ - const auto category = StructTagUtil::getCategory(tag); - auto categoryInfo = getCategoryInfo(category); - if (categoryInfo) - { - auto typeIndex = StructTagUtil::getTypeIndex(tag); - return categoryInfo->getType(typeIndex); - } - - return nullptr; -} - -void StructTagSystem::appendName(slang::StructTag tag, StringBuilder& out) -{ - auto info = StructTagUtil::getTypeInfo(tag); - - auto categoryInfo = getCategoryInfo(info.category); - if (categoryInfo) - { - out << categoryInfo->m_name; - } - else - { - out << Index(info.category); - } - - out << "::"; - - auto type = categoryInfo->getType(info.typeIndex); - - if (type) - { - out << type->m_name; - } - else - { - out << "~" << Index(info.typeIndex) << "~"; - } - - out << "_"; - out << Index(info.majorVersion); - out << "."; - out << Index(info.minorVersion); -} - -} // namespace Slang diff --git a/source/compiler-core/slang-struct-tag-system.h b/source/compiler-core/slang-struct-tag-system.h deleted file mode 100644 index 20581cec7..000000000 --- a/source/compiler-core/slang-struct-tag-system.h +++ /dev/null @@ -1,259 +0,0 @@ -#ifndef SLANG_COMPILER_CORE_STRUCT_TAG_SYSTEM_H -#define SLANG_COMPILER_CORE_STRUCT_TAG_SYSTEM_H - -#include "../../slang.h" - -#include "../../slang-com-helper.h" -#include "../../slang-com-ptr.h" - -#include "../core/slang-smart-pointer.h" - -#include "../core/slang-dictionary.h" -#include "../core/slang-semantic-version.h" -#include "../core/slang-memory-arena.h" - -namespace Slang { - -struct StructTagUtil -{ - struct TypeInfo - { - slang::StructTagKind kind; ///< The kind - slang::StructTagCategory category; ///< The category - uint8_t typeIndex; ///< Type index for the category type - uint8_t majorVersion; ///< The major semantic version - uint8_t minorVersion; ///< The minor semantic version - }; - - /// True if it's a primary struct - static bool isPrimary(slang::StructTag tag) { return (slang::StructTagInt(tag) & slang::kStructTagPrimaryMask) != 0; } - /// True if it's an extension - static bool isExtension(slang::StructTag tag) { return !isPrimary(tag); } - - inline static TypeInfo getTypeInfo(slang::StructTag tag); - - /// Get the category and type from the value - static slang::StructTagInt getCategoryTypeIndex(slang::StructTag tag) { return (slang::StructTagInt(tag) & slang::kStructTagCategoryTypeIndexMask) >> slang::kStructTagCategoryTypeIndexShift; } - - /// Get the type index - static Index getTypeIndex(slang::StructTag tag) { return Index((slang::StructTagInt(tag) & slang::kStructTagTypeIndexMask) >> slang::kStructTagTypeIndexShift); } - - /// Get the category - static slang::StructTagCategory getCategory(slang::StructTag tag) { return slang::StructTagCategory((slang::StructTagInt(tag) & slang::kStructTagCategoryMask) >> slang::kStructTagCategoryShift); } - - /// They are the same type and have same major version - static bool areSameMajorType(slang::StructTag a, slang::StructTag b) - { - const auto typeMask = slang::StructTagInt(slang::kStructTagCategoryTypeMajorMask); - return ((slang::StructTagInt(a) ^ slang::StructTagInt(b)) & typeMask) == 0; - } - - /// This will *only* determine if *just* this type is compatible for read and not if it contains other types (say in the form of extensions) - static bool isReadCompatible(slang::StructTag inTag, slang::StructTag inCurrentTag) - { - // Uniquely identifies the 'type'. - const auto typeMask = slang::StructTagInt(slang::kStructTagCategoryTypeMajorMask); - const auto minorMask = slang::StructTagInt(slang::kStructTagMinorMask); - - const auto tag = slang::StructTagInt(inTag); - const auto currentTag = slang::StructTagInt(inCurrentTag); - - // If they are the same type, and the input types minor is greater than equal to current minor we can accept for read (singly) - return ((tag ^ currentTag) & typeMask) == 0 && (tag & minorMask) >= (currentTag & minorMask); - } -}; - -/* static */ inline StructTagUtil::TypeInfo StructTagUtil::getTypeInfo(slang::StructTag tag) -{ - const auto intTag = slang::StructTagInt(tag); - - TypeInfo info; - info.kind = (intTag & slang::kStructTagPrimaryMask) ? slang::StructTagKind::Primary : slang::StructTagKind::Extension; - info.category = getCategory(tag); - info.typeIndex = uint8_t(getTypeIndex(tag)); - info.majorVersion = uint8_t((intTag & slang::kStructTagMajorMask) >> slang::kStructTagMajorShift); - info.minorVersion = uint8_t((intTag & slang::kStructTagMinorMask) >> slang::kStructTagMinorShift); - return info; -} - -/// We can have a 'field' that is made up of 2 elements, so we have two entries. -/// If m_countType is Unknown, then the entry can be ignored -struct StructTagField -{ - enum class Type : uint8_t - { - Unknown, - TaggedStruct, - PtrTaggedStruct, - PtrPtrTaggedStruct, - I32, - I64, - }; - - SLANG_FORCE_INLINE static bool isInRange(Type type, Type start, Type end) { return Index(type) >= Index(start) && Index(type) <= Index(end); } - - /// True if it's an integral - static bool isIntegral(Type type) { return isInRange(type, Type::I32, Type::I64); } - /// True if it's a pointer or pointer to a pointer - static bool isPtrLike(Type type) { return isInRange(type, Type::PtrTaggedStruct, Type::PtrPtrTaggedStruct); } - - Type m_type; - Type m_countType; - uint16_t m_offset; - uint16_t m_countOffset; -}; - -struct StructTagType -{ -public: - typedef StructTagField Field; - - StructTagType(slang::StructTag tag, const String& name, size_t sizeInBytes): - m_tag(tag), - m_name(name), - m_sizeInBytes(slang::StructSize(sizeInBytes)) - { - } - - slang::StructTag m_tag; ///< The type/current version - String m_name; ///< The name of the type - slang::StructSize m_sizeInBytes; ///< The size of this version in bytes - - List<Field> m_fields; ///< Fields that need to be followed -}; - -namespace StructTagTypeTraits -{ - typedef StructTagField Field; - typedef Field::Type Type; - - // Helper that works out what a pointer to the inner type is. - SLANG_FORCE_INLINE Type getPtrType(Type innerType) - { - switch (innerType) - { - case Type::TaggedStruct: return Type::PtrTaggedStruct; - case Type::PtrTaggedStruct: return Type::PtrPtrTaggedStruct; - default: return Type::Unknown; - } - } - - template <typename T, typename F> - SLANG_FORCE_INLINE uint16_t getOffset(T* obj, const F* f) - { - return uint16_t((const char*)f - (const char*)obj); - } - - // Use `substitution failure is not an error` (SFINAE) to detect tagged struct types - template <typename T> - struct IsTaggedStruct - { - typedef int32_t True; - typedef int8_t False; - - template <typename C> - static True check(typename C::Tag*); - template <typename> - static False check(...); - - // Is != 0 if it is a TaggedStruct type - enum { kValue = int(sizeof(check<T>(nullptr)) == sizeof(True)) }; - }; - - template <typename T> - struct Impl { static Type getType() { return IsTaggedStruct<T>::kValue ? Type::TaggedStruct : Type::Unknown; } }; - - // Doesn't currently handle fixed arrays, but could be added quite easily, with say a byte for the fixed size. - - // Integer types - // We won't bother with sign for now - template <> struct Impl<uint64_t> { static Type getType() { return Type::I64; } }; - template <> struct Impl<int64_t> { static Type getType() { return Type::I64; } }; - template <> struct Impl<uint32_t> { static Type getType() { return Type::I32; } }; - template <> struct Impl<int32_t> { static Type getType() { return Type::I32; } }; - - // StructTag is used to indicate it can be any 'tagged struct type' - template <> struct Impl<slang::StructTag> { static Type getType() { return Type::TaggedStruct; } }; - - // Pointer - template <typename T> struct Impl<T*> { static Type getType() { return getPtrType(Impl<T>::getType()); } }; - - /// f1 should hold the count - template <typename T, typename F0, typename F1> - Field getFieldWithCount(const T* obj, const F0* ptr, const F1* count) - { - Field field; - field.m_type = Impl<F0>::getType(); - field.m_countType = Impl<F1>::getType(); - field.m_offset = getOffset(obj, ptr); - field.m_countOffset = getOffset(obj, count); - - SLANG_ASSERT(StructTagField::isPtrLike(field.m_type)); - SLANG_ASSERT(StructTagField::isIntegral(field.m_countType)); - - return field; - } -} - -class StructTagCategoryInfo -{ -public: - - /// Add a type. Will replace a type if there is already one setup for the m_Type - void addType(StructTagType* type); - - /// Get a type - StructTagType* getType(Index typeIndex) const { return typeIndex < m_types.getCount() ? m_types[typeIndex] : nullptr; } - - StructTagCategoryInfo(slang::StructTagCategory category, const String& name) : - m_category(category), - m_name(name) - { - } - ~StructTagCategoryInfo(); - - slang::StructTagCategory m_category; ///< The category type - String m_name; ///< The name - - // All the types in this category - List<StructTagType*> m_types; -}; - -/* Holds the information about TaggedStruct types. Use the StructTagConverter to actually convert to conforming -types. */ -class StructTagSystem : public RefObject -{ -public: - - /// Add a category - StructTagCategoryInfo* addCategoryInfo(slang::StructTagCategory category, const String& name); - StructTagCategoryInfo* getCategoryInfo(slang::StructTagCategory category); - - /// Get struct type - StructTagType* getType(slang::StructTag tag); - - /// Add the struct type - StructTagType* addType(slang::StructTag tag, const String& name, size_t sizeInBytes); - - void appendName(slang::StructTag tag, StringBuilder& out); - String getName(slang::StructTag tag) { StringBuilder buf; appendName(tag, buf); return buf.ProduceString(); } - - StructTagSystem(): - m_arena(1024) - { - } - - ~StructTagSystem(); - -protected: - - /// Arena stores all of the types - MemoryArena m_arena; - - /// All of the categories - List<StructTagCategoryInfo*> m_categories; -}; - -} // namespace Slang - -#endif // SLANG_COMPILER_CORE_STRUCT_TAG_SYSTEM_H diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index e6684108b..a933716a8 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -11,8 +11,6 @@ #include "../compiler-core/slang-include-system.h" #include "../compiler-core/slang-command-line-args.h" -#include "../compiler-core/slang-struct-tag-system.h" - #include "../core/slang-std-writers.h" #include "../../slang-com-ptr.h" @@ -2320,9 +2318,6 @@ namespace Slang /// Get the built in linkage -> handy to get the stdlibs from Linkage* getBuiltinLinkage() const { return m_builtinLinkage; } - /// Get the Abi system used for managing binary compatibility of interface types (outside of COM mechanisms) - StructTagSystem* getStructTagSystem() const { return m_structTagSystem; } - void init(); void addBuiltinSource( @@ -2348,8 +2343,6 @@ namespace Slang /// Linkage used for all built-in (stdlib) code. RefPtr<Linkage> m_builtinLinkage; - RefPtr<StructTagSystem> m_structTagSystem; - String m_downstreamCompilerPaths[int(PassThroughMode::CountOf)]; ///< Paths for each pass through String m_languagePreludes[int(SourceLanguage::CountOf)]; ///< Prelude for each source language PassThroughMode m_defaultDownstreamCompilers[int(SourceLanguage::CountOf)]; diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 8d82ca1b7..acc4b6f77 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -23,7 +23,6 @@ #include "../core/slang-writer.h" #include "../compiler-core/slang-source-loc.h" -#include "../compiler-core/slang-struct-tag-converter.h" #include "slang-ast-dump.h" @@ -115,31 +114,6 @@ const char* getBuildTagString() return SLANG_TAG_VERSION; } -static RefPtr<StructTagSystem> _createStructTagSystem() -{ - RefPtr<StructTagSystem> system = new StructTagSystem; - - { -#define SLANG_STRUCT_TAG_ADD_CATEGORY(x) system->addCategoryInfo(slang::StructTagCategory::x, #x); - SLANG_STRUCT_TAG_CATEGORIES(SLANG_STRUCT_TAG_ADD_CATEGORY) - } - - { -#define SLANG_STRUCT_TAG_ADD_TYPE(X) system->addType(slang::X::kStructTag, "slang::" #X, sizeof(slang::X)); -SLANG_TAGGED_STRUCTS(SLANG_STRUCT_TAG_ADD_TYPE) - - // Add field that references more tagged structs - { - slang::SessionDesc desc; - auto field = StructTagTypeTraits::getFieldWithCount(&desc, &desc.targets, &desc.targetCount); - - auto type = system->getType(slang::SessionDesc::kStructTag); - type->m_fields.add(field); - } - } - - return system; -} void Session::init() { @@ -158,8 +132,6 @@ void Session::init() m_sharedASTBuilder = new SharedASTBuilder; m_sharedASTBuilder->init(this); - m_structTagSystem = _createStructTagSystem(); - // Use to create a ASTBuilder RefPtr<ASTBuilder> builtinAstBuilder(new ASTBuilder(m_sharedASTBuilder, "m_builtInLinkage::m_astBuilder")); @@ -467,45 +439,42 @@ ISlangUnknown* Session::getInterface(const Guid& guid) } SLANG_NO_THROW SlangResult SLANG_MCALL Session::createSession( - slang::SessionDesc const& inDesc, + slang::SessionDesc const& desc, slang::ISession** outSession) { - MemoryArena arena(1024); - - LazyStructTagConverter converter(getStructTagSystem(), &arena, nullptr); - - const slang::SessionDesc* desc = nullptr; - SLANG_RETURN_ON_FAIL(converter.convertToCurrent(&inDesc, &desc)); - RefPtr<ASTBuilder> astBuilder(new ASTBuilder(m_sharedASTBuilder, "Session::astBuilder")); RefPtr<Linkage> linkage = new Linkage(this, astBuilder, getBuiltinLinkage()); + Int targetCount = desc.targetCount; + const uint8_t* targetDescPtr = reinterpret_cast<const uint8_t*>(desc.targets); + for (Int ii = 0; ii < targetCount; ++ii) { - const Index targetCount = Index(desc->targetCount); - for(Index ii = 0; ii < targetCount; ++ii) - { - const auto& targetDesc = desc->targets[ii]; - linkage->addTarget(targetDesc); - } + slang::TargetDesc targetDesc; + // Copy the size field first. + memcpy(&targetDesc.structureSize, targetDescPtr, sizeof(size_t)); + // Copy the entire desc structure. + memcpy(&targetDesc, targetDescPtr, targetDesc.structureSize); + linkage->addTarget(targetDesc); + targetDescPtr += targetDesc.structureSize; } - if(desc->flags & slang::kSessionFlag_FalcorCustomSharedKeywordSemantics) + if(desc.flags & slang::kSessionFlag_FalcorCustomSharedKeywordSemantics) { linkage->m_useFalcorCustomSharedKeywordSemantics = true; } - linkage->setMatrixLayoutMode(desc->defaultMatrixLayoutMode); + linkage->setMatrixLayoutMode(desc.defaultMatrixLayoutMode); - Int searchPathCount = desc->searchPathCount; + Int searchPathCount = desc.searchPathCount; for(Int ii = 0; ii < searchPathCount; ++ii) { - linkage->addSearchPath(desc->searchPaths[ii]); + linkage->addSearchPath(desc.searchPaths[ii]); } - Int macroCount = desc->preprocessorMacroCount; + Int macroCount = desc.preprocessorMacroCount; for(Int ii = 0; ii < macroCount; ++ii) { - auto& macro = desc->preprocessorMacros[ii]; + auto& macro = desc.preprocessorMacros[ii]; linkage->addPreprocessorDefine(macro.name, macro.value); } |
