Skip to content

Commit 274c20a

Browse files
authored
Generalizing Serialization (shader-slang#1563)
* First pass at generalizing serializer. * Split out ReflectClassInfo * Use the general ReflectClassInfo * Fix some typos in debug generalized serialization. * Add calculation of classIds. Make distinct addCopy/add on SerialClasses. * Write up of more generalized serialization * WIP to transition from ASTSerialReader/Writer etc to generalized SerialReader/Writer and associated types. * Improvements to SerialExtraObjects. Keep RefObjects in scope in factory * Compiles with Serial refactor - doesn't quite work yet. * First pass serialization appears to work with refector. * Split out type info for general slang types. * Split out slang-serialize-misc-type-info.h * DebugSerialData -> SerialSourecLocData DebugSerialReader -> SerialSourceLocReader DebugSerialWriter -> SerialSourceLocWriter * Remove unused template that only compiles on VS. * Fix warning around unused function on non-VS.
1 parent 94d3f2b commit 274c20a

22 files changed

+2769
-2287
lines changed

source/slang/slang-ast-base.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
#include "slang-ast-generated.h"
88
#include "slang-ast-reflect.h"
99

10+
#include "slang-serialize-reflection.h"
11+
1012
// This file defines the primary base classes for the hierarchy of
1113
// AST nodes and related objects. For example, this is where the
1214
// basic `Decl`, `Stmt`, `Expr`, `type`, etc. definitions come from.
1315

1416
namespace Slang
1517
{
1618

17-
struct ReflectClassInfo;
18-
1919
class NodeBase
2020
{
2121
SLANG_ABSTRACT_CLASS(NodeBase)
@@ -26,7 +26,7 @@ class NodeBase
2626
SLANG_FORCE_INLINE void init(ASTNodeType inAstNodeType, ASTBuilder* /* astBuilder*/ ) { astNodeType = inAstNodeType; }
2727

2828
/// Get the class info
29-
SLANG_FORCE_INLINE const ReflectClassInfo& getClassInfo() const { return *ReflectClassInfo::getInfo(astNodeType); }
29+
SLANG_FORCE_INLINE const ReflectClassInfo& getClassInfo() const { return *ASTClassInfo::getInfo(astNodeType); }
3030

3131
SyntaxClass<NodeBase> getClass() { return SyntaxClass<NodeBase>(&getClassInfo()); }
3232

@@ -41,25 +41,25 @@ class NodeBase
4141
template<typename T>
4242
SLANG_FORCE_INLINE T* dynamicCast(NodeBase* node)
4343
{
44-
return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
44+
return (node && ReflectClassInfo::isSubClassOf(uint32_t(node->astNodeType), T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
4545
}
4646

4747
template<typename T>
4848
SLANG_FORCE_INLINE const T* dynamicCast(const NodeBase* node)
4949
{
50-
return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
50+
return (node && ReflectClassInfo::isSubClassOf(uint32_t(node->astNodeType), T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
5151
}
5252

5353
template<typename T>
5454
SLANG_FORCE_INLINE T* as(NodeBase* node)
5555
{
56-
return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
56+
return (node && ReflectClassInfo::isSubClassOf(uint32_t(node->astNodeType), T::kReflectClassInfo)) ? static_cast<T*>(node) : nullptr;
5757
}
5858

5959
template<typename T>
6060
SLANG_FORCE_INLINE const T* as(const NodeBase* node)
6161
{
62-
return (node && ReflectClassInfo::isSubClassOf(node->astNodeType, T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
62+
return (node && ReflectClassInfo::isSubClassOf(uint32_t(node->astNodeType), T::kReflectClassInfo)) ? static_cast<const T*>(node) : nullptr;
6363
}
6464

6565

source/slang/slang-ast-builder.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void SharedASTBuilder::init(Session* session)
3838
// NOTE! That this adds the names of the abstract classes too(!)
3939
for (Index i = 0; i < Index(ASTNodeType::CountOf); ++i)
4040
{
41-
const ReflectClassInfo* info = ReflectClassInfo::getInfo(ASTNodeType(i));
41+
const ReflectClassInfo* info = ASTClassInfo::getInfo(ASTNodeType(i));
4242
if (info)
4343
{
4444
m_sliceToTypeMap.Add(UnownedStringSlice(info->m_name), info);
@@ -171,15 +171,15 @@ ASTBuilder::~ASTBuilder()
171171
{
172172
for (NodeBase* node : m_dtorNodes)
173173
{
174-
const ReflectClassInfo* info = ReflectClassInfo::getInfo(node->astNodeType);
174+
const ReflectClassInfo* info = ASTClassInfo::getInfo(node->astNodeType);
175175
SLANG_ASSERT(info->m_destructorFunc);
176176
info->m_destructorFunc(node);
177177
}
178178
}
179179

180180
NodeBase* ASTBuilder::createByNodeType(ASTNodeType nodeType)
181181
{
182-
const ReflectClassInfo* info = ReflectClassInfo::getInfo(nodeType);
182+
const ReflectClassInfo* info = ASTClassInfo::getInfo(nodeType);
183183

184184
auto createFunc = info->m_createFunc;
185185
SLANG_ASSERT(createFunc);

source/slang/slang-ast-dump.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ struct ASTDumpContext
582582
void dump(ASTNodeType nodeType)
583583
{
584584
// Get the class
585-
auto info = ReflectClassInfo::getInfo(nodeType);
585+
auto info = ASTClassInfo::getInfo(nodeType);
586586
// Write the name
587587
m_writer->emit(info->m_name);
588588
}

source/slang/slang-ast-reflect.cpp

+5-16
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,15 @@ namespace Slang
1818

1919
#define SLANG_REFLECT_GET_REFLECT_CLASS_INFO(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) infos.infos[int(ASTNodeType::NAME)] = &NAME::kReflectClassInfo;
2020

21-
static ReflectClassInfo::Infos _calcInfos()
21+
static ASTClassInfo::Infos _calcInfos()
2222
{
23-
ReflectClassInfo::Infos infos;
23+
ASTClassInfo::Infos infos;
2424
memset(&infos, 0, sizeof(infos));
2525
SLANG_ALL_ASTNode_NodeBase(SLANG_REFLECT_GET_REFLECT_CLASS_INFO, _)
2626
return infos;
2727
}
2828

29-
/* static */const ReflectClassInfo::Infos ReflectClassInfo::kInfos = _calcInfos();
30-
31-
bool ReflectClassInfo::isSubClassOfSlow(const ThisType& super) const
32-
{
33-
ReflectClassInfo const* info = this;
34-
while (info)
35-
{
36-
if (info == &super)
37-
return true;
38-
info = info->m_superClass;
39-
}
40-
return false;
41-
}
29+
/* static */const ASTClassInfo::Infos ASTClassInfo::kInfos = _calcInfos();
4230

4331
// Now try and implement all of the classes
4432
// Macro generated is of the format
@@ -48,8 +36,9 @@ struct ASTConstructAccess
4836
template <typename T>
4937
struct Impl
5038
{
51-
static void* create(ASTBuilder* astBuilder)
39+
static void* create(void* context)
5240
{
41+
ASTBuilder* astBuilder = (ASTBuilder*)context;
5342
return astBuilder->create<T>();
5443
}
5544
static void destroy(void* ptr)

source/slang/slang-ast-support-types.h

+3-41
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
#include "slang-ast-reflect.h"
1515

16+
#include "slang-serialize-reflection.h"
17+
1618
#include "slang-name.h"
1719

1820
#include <assert.h>
@@ -462,53 +464,13 @@ namespace Slang
462464

463465
class ASTBuilder;
464466

465-
struct ReflectClassInfo
467+
struct ASTClassInfo
466468
{
467-
typedef ReflectClassInfo ThisType;
468-
469-
typedef void* (*CreateFunc)(ASTBuilder* astBuilder);
470-
typedef void (*DestructorFunc)(void* ptr);
471-
472-
/// A constant time implementation of isSubClassOf
473-
SLANG_FORCE_INLINE bool isSubClassOf(const ThisType& super) const
474-
{
475-
// We include super.m_classId, because it's a subclass of itself.
476-
return m_classId >= super.m_classId && m_classId <= super.m_lastClassId;
477-
}
478-
// True if typeId derives from this type
479-
SLANG_FORCE_INLINE bool isDerivedFrom(uint32_t typeId) const
480-
{
481-
return typeId >= m_classId && typeId <= m_lastClassId;
482-
}
483-
SLANG_FORCE_INLINE static bool isSubClassOf(ASTNodeType type, const ThisType& super)
484-
{
485-
// Check the type appears valid
486-
SLANG_ASSERT(int(type) >= 0);
487-
// We include super.m_classId, because it's a subclass of itself.
488-
return uint32_t(type) >= super.m_classId && uint32_t(type) <= super.m_lastClassId;
489-
}
490-
491-
/// Will produce the same result as isSubClassOf, but more slowly by traversing the m_superClass
492-
/// Works without initRange being called.
493-
bool isSubClassOfSlow(const ThisType& super) const;
494-
495-
uint32_t m_classId;
496-
uint32_t m_lastClassId;
497-
498-
const ReflectClassInfo* m_superClass; ///< The super class of this class, or nullptr if has no super class.
499-
const char* m_name; ///< Textual class name, for debugging
500-
CreateFunc m_createFunc; ///< Callback to use when creating instances (using an ASTBuilder for backing memory)
501-
DestructorFunc m_destructorFunc; ///< The destructor for this type. Being just destructor, does not free backing memory for type.
502-
uint32_t m_sizeInBytes; ///< Total size of the type
503-
uint8_t m_alignment; ///< The required alignment of the type
504-
505469
struct Infos
506470
{
507471
const ReflectClassInfo* infos[int(ASTNodeType::CountOf)];
508472
};
509-
510473
SLANG_FORCE_INLINE static const ReflectClassInfo* getInfo(ASTNodeType type) { return kInfos.infos[int(type)]; }
511-
512474
static const Infos kInfos;
513475
};
514476

0 commit comments

Comments
 (0)