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 | |
| 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.
| -rw-r--r-- | build/visual-studio/compiler-core/compiler-core.vcxproj | 4 | ||||
| -rw-r--r-- | build/visual-studio/compiler-core/compiler-core.vcxproj.filters | 12 | ||||
| -rw-r--r-- | build/visual-studio/slang-test/slang-test.vcxproj | 1 | ||||
| -rw-r--r-- | build/visual-studio/slang-test/slang-test.vcxproj.filters | 3 | ||||
| -rw-r--r-- | slang.h | 183 | ||||
| -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 | ||||
| -rw-r--r-- | tools/slang-test/unit-test-struct-tag.cpp | 255 |
13 files changed, 23 insertions, 1588 deletions
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj b/build/visual-studio/compiler-core/compiler-core.vcxproj index da485b602..d472270cb 100644 --- a/build/visual-studio/compiler-core/compiler-core.vcxproj +++ b/build/visual-studio/compiler-core/compiler-core.vcxproj @@ -191,8 +191,6 @@ <ClInclude Include="..\..\..\source\compiler-core\slang-name.h" /> <ClInclude Include="..\..\..\source\compiler-core\slang-nvrtc-compiler.h" /> <ClInclude Include="..\..\..\source\compiler-core\slang-source-loc.h" /> - <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-converter.h" /> - <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-system.h" /> <ClInclude Include="..\..\..\source\compiler-core\slang-token-defs.h" /> <ClInclude Include="..\..\..\source\compiler-core\slang-token.h" /> <ClInclude Include="..\..\..\source\compiler-core\slang-visual-studio-compiler-util.h" /> @@ -217,8 +215,6 @@ <ClCompile Include="..\..\..\source\compiler-core\slang-name.cpp" /> <ClCompile Include="..\..\..\source\compiler-core\slang-nvrtc-compiler.cpp" /> <ClCompile Include="..\..\..\source\compiler-core\slang-source-loc.cpp" /> - <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-converter.cpp" /> - <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-system.cpp" /> <ClCompile Include="..\..\..\source\compiler-core\slang-token.cpp" /> <ClCompile Include="..\..\..\source\compiler-core\slang-visual-studio-compiler-util.cpp" /> <ClCompile Include="..\..\..\source\compiler-core\windows\slang-win-visual-studio-util.cpp" /> diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters index 2d88ae29d..da0ca5d63 100644 --- a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters +++ b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters @@ -72,12 +72,6 @@ <ClInclude Include="..\..\..\source\compiler-core\slang-source-loc.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-converter.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-system.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\..\source\compiler-core\slang-token-defs.h"> <Filter>Header Files</Filter> </ClInclude> @@ -146,12 +140,6 @@ <ClCompile Include="..\..\..\source\compiler-core\slang-source-loc.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-converter.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-system.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\..\source\compiler-core\slang-token.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/build/visual-studio/slang-test/slang-test.vcxproj b/build/visual-studio/slang-test/slang-test.vcxproj index a8c9506a8..a0b7eb825 100644 --- a/build/visual-studio/slang-test/slang-test.vcxproj +++ b/build/visual-studio/slang-test/slang-test.vcxproj @@ -189,7 +189,6 @@ <ClCompile Include="..\..\..\tools\slang-test\unit-test-riff.cpp" /> <ClCompile Include="..\..\..\tools\slang-test\unit-test-short-list.cpp" /> <ClCompile Include="..\..\..\tools\slang-test\unit-test-string.cpp" /> - <ClCompile Include="..\..\..\tools\slang-test\unit-test-struct-tag.cpp" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\core\core.vcxproj"> diff --git a/build/visual-studio/slang-test/slang-test.vcxproj.filters b/build/visual-studio/slang-test/slang-test.vcxproj.filters index 99735f156..1e5b6e4af 100644 --- a/build/visual-studio/slang-test/slang-test.vcxproj.filters +++ b/build/visual-studio/slang-test/slang-test.vcxproj.filters @@ -86,8 +86,5 @@ <ClCompile Include="..\..\..\tools\slang-test\unit-test-string.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\tools\slang-test\unit-test-struct-tag.cpp"> - <Filter>Source Files</Filter> - </ClCompile> </ItemGroup> </Project>
\ No newline at end of file @@ -450,178 +450,6 @@ convention for interface methods. #include <stddef.h> #endif // ! SLANG_NO_STDDEF -namespace slang -{ - -/* Slang provides a mechanism for value types (such as structures) to be able to provide forward and backward -ABI compatibility through. - -The type is made up of several parts. -0) The kind primary or extension -1) The category the type is in -2) An id for the type in the category -3) The major semantic version -4) The minor semantic version - -Within the 'semantic versioning' a structure that has only a larger minor semantic version can be used (with some -caveats) as is when being passed to a previous version of Slang. It may contain more fields. -*/ - -enum class StructTagKind : uint8_t -{ - Primary, ///< A primary struct (contains optional extensions) - Extension, ///< An extension struct -}; - -#define SLANG_STRUCT_TAG_ENUM(x) x, - -#define SLANG_STRUCT_TAG_CATEGORIES(x) \ - x(Core) \ - x(Slang) \ - x(Gfx) - - -enum class StructTagCategory : uint8_t -{ - SLANG_STRUCT_TAG_CATEGORIES(SLANG_STRUCT_TAG_ENUM) - CountOf, -}; - -/* AbiStructType is laid out as follows - - |Primary | Category | Type | Major version | Minor Version ------|--------|--------------|-----------|---------------|---------------- -Bits | 31 | 30-24 | 23-16 | 15-8 | 0-7 -Type | | AbiCategory | Cat Spec | | - -Type will be specified as something specific for the category. A typical implementation will have an enum that lists -types for that category. - -TODO(JS): This layout may need to be altered - too may bits are perhaps used by major/minor version for example. This should -be fine for the immediate future though. -*/ - -typedef uint32_t StructTagInt; -typedef uint32_t StructSize; - -enum class StructTag : StructTagInt; - -enum : uint32_t -{ - kStructTagPrimaryMask = 0x80000000, - - kStructTagCategoryMask = 0x7f000000, - kStructTagCategoryShift = 24, - - // Combination of category and TypeIndex - kStructTagCategoryTypeIndexMask = 0x7fff0000, - kStructTagCategoryTypeIndexShift = 16, - - kStructTagCategoryTypeMajorMask = 0xffffff00, - - kStructTagTypeIndexMask = 0x00ff0000, - kStructTagTypeIndexShift = 16, - - kStructTagVersionMask = 0x0000ffff, - kStructTagVersionShift = 0, - - kStructTagMajorMask = 0x0000ff00, - kStructTagMajorShift = 8, - - kStructTagMinorMask = 0x000000ff, - kStructTagMinorShift = 0, -}; - -// Types purely for use in template type identification -// Any Primary or Extension TaggedStruct must have a typedef of one of these as Tag. -enum class PrimaryTag; -enum class ExtensionTag; - -#define SLANG_MAKE_PRIMARY_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR) slang::StructTag(slang::StructTagInt(slang::kStructTagPrimaryMask) | (slang::StructTagInt(CATEGORY) << 24) | (slang::StructTagInt(TYPE_ID) << 16) | (slang::StructTagInt(MAJOR) << 8) | slang::StructTagInt(MINOR)) -#define SLANG_MAKE_EXTENSION_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR) slang::StructTag((slang::StructTagInt(CATEGORY) << 24) | (slang::StructTagInt(TYPE_ID) << 16) | (slang::StructTagInt(MAJOR) << 8) | slang::StructTagInt(MINOR)) - -/* -`PrimaryStruct`s are structs that are passed directly into API calls. They always contain a 'structType' that identifies the exact version -and type of that is being passed in. `PrimaryStruct`s can also specify optional `ExtensionStruct` types that modify and/or add to the values -in the `PrimaryStruct`. - -`ExtensionStruct` cannot contain optional other extensions as PrimaryStructs do - all required extensions have to be specified via the list set on the -`PrimaryStruct`. - -`ExtensionStruct` is typically used when it is necessary to provide some special additional information that is not appropriate to place within -the `PrimaryStruct`. This also provides a mechanism such that a `PrimaryStruct` derived type does not need to include all the fields that will -every be needed. Cross cutting aspects can have their own uniquely identified structs. - -As a mechanism to provide extensibility without having to modify a struct or to allow optional and/or additional information through -ExtensionStruct set via the `exts` and `extsCount` members. - -A type that is ABI compatible with this mechanism must start with exactly the same fields as specified. -When using extensions, the exts and extsCount should be set. `exts` points to the extension ids (which must be at the start of the types) -to provide some kind of type safely without requiring inheritance. -*/ - -#define SLANG_EXTENSION_TAGGED_STRUCT_IMPL(TYPE_NAME, CATEGORY, TYPE_ID, MAJOR, MINOR) \ - typedef TYPE_NAME ThisType; \ - typedef slang::ExtensionTag Tag; \ - static const slang::StructTag kStructTag = SLANG_MAKE_EXTENSION_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR); \ - slang::StructTag structTag = kStructTag; \ - slang::StructSize structSize = slang::StructSize(sizeof(ThisType)); - -#define SLANG_PRIMARY_TAGGED_STRUCT_IMPL(TYPE_NAME, CATEGORY, TYPE_ID, MAJOR, MINOR) \ - typedef TYPE_NAME ThisType; \ - typedef ::slang::PrimaryTag Tag; \ - static const ::slang::StructTag kStructTag = SLANG_MAKE_PRIMARY_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR); \ - slang::StructTag structTag = kStructTag; \ - slang::StructSize structSize = slang::StructSize(sizeof(ThisType)); \ - const slang::StructTag** exts = nullptr; \ - int32_t extsCount = 0; - -#define SLANG_API_TYPE_ENUM(x) x, - -struct TaggedStructBase -{ - StructTag structTag; ///< Identity for the type - StructSize structSize; ///< Size of the type in bytes -}; - -/* Layout for a PrimaryTaggedStruct */ -struct PrimaryTaggedStruct -{ - StructTag structTag; ///< Identity for the type - StructSize structSize; ///< Size of the type in bytes - const StructTag** exts; ///< Extensions - StructTag type should be the first member of Extension structs - int32_t extsCount = 0; ///< The number of extensions -}; - -/* Layout for a Extension TaggedStruct */ -struct ExtensionTaggedStruct -{ - StructTag structTag; ///< Identity for the type - StructSize structSize; ///< Size of the type in bytes -}; - -// Enumerate all of the types that want ABI handling as part of Slang API. -// -// NOTE! That care is needed using the enumeration, because we want IDs to remain stable. -// New types should be added to the end. Removed types should become Depreciated_Name (say). -// -// NOTE! The names must match the type name for an active type exactly for the SLANG_PRIMARY_TAGGED_STRUCT and SLANG_EXTENSION_TAGGED_STRUCT -// macros to work. -#define SLANG_TAGGED_STRUCTS(x) \ - x(TargetDesc) \ - x(SessionDesc) - -// Define Slangs types in the enum -enum class SlangTaggedStruct -{ - SLANG_TAGGED_STRUCTS(SLANG_STRUCT_TAG_ENUM) -}; - -#define SLANG_PRIMARY_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_PRIMARY_TAGGED_STRUCT_IMPL(TYPE_NAME, StructTagCategory::Slang, SlangTaggedStruct::TYPE_NAME, MAJOR, MINOR) -#define SLANG_EXTENSION_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_EXTENSION_TAGGED_STRUCT_IMPL(TYPE_NAME, StructTagCategory::Slang, SlangTaggedStruct::TYPE_NAME, MAJOR, MINOR) - -} // namespace slang - #ifdef __cplusplus extern "C" { @@ -1003,9 +831,6 @@ extern "C" //! Could not complete because some underlying feature (hardware or software) was not available #define SLANG_E_NOT_AVAILABLE SLANG_MAKE_CORE_ERROR(7) - //! A type specified is StructTag incompatible with this version of slang -#define SLANG_E_STRUCT_TAG_INCOMPATIBLE SLANG_MAKE_CORE_ERROR(8) - /** A "Universally Unique Identifier" (UUID) The Slang API uses UUIDs to identify interfaces when @@ -3979,7 +3804,9 @@ namespace slang */ struct TargetDesc { - SLANG_PRIMARY_TAGGED_STRUCT(TargetDesc, 0, 0) + /** The size of this structure, in bytes. + */ + size_t structureSize = sizeof(TargetDesc); /** The target format to generate code for (e.g., SPIR-V, DXIL, etc.) */ @@ -4029,7 +3856,9 @@ namespace slang struct SessionDesc { - SLANG_PRIMARY_TAGGED_STRUCT(SessionDesc, 0, 0) + /** The size of this structure, in bytes. + */ + size_t structureSize = sizeof(SessionDesc); /** Code generation targets to include in the session. */ 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); } diff --git a/tools/slang-test/unit-test-struct-tag.cpp b/tools/slang-test/unit-test-struct-tag.cpp deleted file mode 100644 index cc22d9b1d..000000000 --- a/tools/slang-test/unit-test-struct-tag.cpp +++ /dev/null @@ -1,255 +0,0 @@ -// unit-test-struct-tag.cpp - -#include "../../source/core/slang-memory-arena.h" - -#include <stdio.h> -#include <stdlib.h> - -#include "test-context.h" - -#include "../../source/core/slang-random-generator.h" -#include "../../source/core/slang-list.h" - -#include "../../source/compiler-core/slang-struct-tag-system.h" -#include "../../source/compiler-core/slang-struct-tag-converter.h" - -using namespace Slang; - -namespace { // anonymous - -#define TAGGED_STRUCTS(x) \ - x(A) \ - x(B) \ - x(ExtensionA) \ - x(Desc) - -enum class TaggedStruct -{ - TAGGED_STRUCTS(SLANG_STRUCT_TAG_ENUM) -}; - -#define PRIMARY_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_PRIMARY_TAGGED_STRUCT_IMPL(TYPE_NAME##MAJOR##_##MINOR, slang::StructTagCategory::Core, TaggedStruct::TYPE_NAME, MAJOR, MINOR) -#define EXTENSION_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_EXTENSION_TAGGED_STRUCT_IMPL(TYPE_NAME##MAJOR##_##MINOR, slang::StructTagCategory::Core, TaggedStruct::TYPE_NAME, MAJOR, MINOR) - -struct A0_0 -{ - PRIMARY_TAGGED_STRUCT(A, 0, 0) - - int a = 10; -}; - -struct A0_1 -{ - PRIMARY_TAGGED_STRUCT(A, 0, 1) - - int a = 10; - int b = 20; -}; - -struct B0_0 -{ - PRIMARY_TAGGED_STRUCT(B, 0, 0) - - float v = -1.0f; -}; - -struct B0_1 -{ - PRIMARY_TAGGED_STRUCT(B, 0, 1) - - float v = -1.0f; - float u = 20.0f; -}; - -struct A1_0 -{ - PRIMARY_TAGGED_STRUCT(A, 1, 0) -}; - - -struct ExtensionA0_0 -{ - EXTENSION_TAGGED_STRUCT(ExtensionA, 0, 0) - - int b = 20; -}; - -// I guess a Desc could be implemented as 'Primary' or 'Extension' with what we have, but probably makes more sense -// for 'Desc' like things to be primary - -struct Desc0_0 -{ - EXTENSION_TAGGED_STRUCT(Desc, 0, 0) - int a = 1; -}; - -struct Desc0_1 -{ - EXTENSION_TAGGED_STRUCT(Desc, 0, 1) - int a = 1; - int b = 2; -}; - - -struct A0_2 -{ - PRIMARY_TAGGED_STRUCT(A, 0, 2) - - int a = 10; - int b = 20; - - Desc0_0* descs = nullptr; - Index descsCount = 0; -}; - -} // anonymous - -static RefPtr<StructTagSystem> _createSystem() -{ - 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) - } - - return system; -} - -static void structTagUnitTest() -{ - SourceManager sourceManager; - sourceManager.initialize(nullptr, nullptr); - - DiagnosticSink sink; - sink.init(&sourceManager, nullptr); - - { - StructTagUtil::TypeInfo info = StructTagUtil::getTypeInfo(A0_1::kStructTag); - - SLANG_CHECK(info.kind == slang::StructTagKind::Primary); - SLANG_CHECK(info.category == slang::StructTagCategory::Core); - SLANG_CHECK(info.majorVersion == 0); - SLANG_CHECK(info.minorVersion == 1); - } - - { - StructTagUtil::TypeInfo info = StructTagUtil::getTypeInfo(ExtensionA0_0::kStructTag); - - SLANG_CHECK(info.kind == slang::StructTagKind::Extension); - SLANG_CHECK(info.category == slang::StructTagCategory::Core); - SLANG_CHECK(info.majorVersion == 0); - SLANG_CHECK(info.minorVersion == 0); - } - - { - // Set up the system with the versions - auto system = _createSystem(); - - system->addType(B0_1::kStructTag, "B", sizeof(B0_1)); - system->addType(A0_1::kStructTag, "A", sizeof(A0_1)); - system->addType(ExtensionA0_0::kStructTag, "ExtensionA", sizeof(ExtensionA0_0)); - - { - //The null operation means we are converting everything that is current (as defined by the system) - - A0_1 a; - ExtensionA0_0 extA; - const slang::StructTag* exts[] = { &extA.structTag }; - a.exts = exts; - a.extsCount = SLANG_COUNT_OF(exts); - - - LazyStructTagConverter converter(system, nullptr, nullptr); - - auto dstA = converter.convertToCurrent<A0_1>(&a); - - // We shouldn't have to convert anything, so we should be done - SLANG_CHECK(dstA == &a); - } - - { - A0_0 a; - ExtensionA0_0 extA; - const slang::StructTag* exts[] = { &extA.structTag }; - a.exts = exts; - a.extsCount = SLANG_COUNT_OF(exts); - - - // Actually do a conversion from past - MemoryArena arena(1024); - LazyStructTagConverter converter(system, &arena, nullptr); - - auto dstA = converter.convertToCurrent<A0_1>(&a); - - SLANG_CHECK(dstA != nullptr); - SLANG_CHECK(dstA->a == 10 && dstA->b == 0); - - SLANG_CHECK(dstA->extsCount == 1); - SLANG_CHECK(((ExtensionA0_0*)dstA->exts[0])->b == 20); - } - } - - // Let's try going from the future backwards - { - // Set up the system with the versions - auto system = _createSystem(); - - system->addType(B0_1::kStructTag, "B", sizeof(B0_1)); - system->addType(A0_2::kStructTag, "A", sizeof(A0_2)); - system->addType(ExtensionA0_0::kStructTag, "ExtensionA", sizeof(ExtensionA0_0)); - system->addType(Desc0_0::kStructTag, "Desc", sizeof(Desc0_0)); - - // Add the fields - { - auto type = system->getType(A0_2::kStructTag); - A0_2 a; - auto field = StructTagTypeTraits::getFieldWithCount(&a, &a.descs, &a.descsCount); - type->m_fields.add(field); - } - - // - - A0_2 a; - Desc0_1 descs[2]; - descs[0].a = 27; - descs[1].a = -1; - - a.descs = (Desc0_0*)descs; - a.descsCount = SLANG_COUNT_OF(descs); - - // Actually do a conversion from future - MemoryArena arena(1024); - LazyStructTagConverter converter(system, &arena, nullptr); - - auto dstA = converter.convertToCurrent<A0_2>(&a); - - SLANG_CHECK(dstA->descsCount == a.descsCount); - - SLANG_CHECK(dstA->descs[0].a == 27 && dstA->descs[1].a == -1); - } - - // Lets try some invalid conversions - - { - // Set up the system with the versions - auto system = _createSystem(); - - system->addType(B0_1::kStructTag, "B", sizeof(B0_1)); - system->addType(A0_2::kStructTag, "A", sizeof(A0_2)); - system->addType(ExtensionA0_0::kStructTag, "ExtensionA", sizeof(ExtensionA0_0)); - system->addType(Desc0_0::kStructTag, "Desc", sizeof(Desc0_0)); - - A1_0 a; - - MemoryArena arena(1024); - LazyStructTagConverter converter(system, &arena, &sink); - - void* dst; - SLANG_CHECK(SLANG_FAILED(converter.convertCurrent(&a, dst))); - - } - -} - -SLANG_UNIT_TEST("StructTag", structTagUnitTest); |
