diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-09-30 13:28:56 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-30 13:28:56 -0400 |
| commit | 274c20a5eb133779a9d890ca79120815fb92b04e (patch) | |
| tree | 50f8074917a102b25a7f34adeacffaf185d59242 /source/slang/slang-serialize-ast.cpp | |
| parent | 94d3f2bd9c5557658751f73bc5fc443b41230d2c (diff) | |
Generalizing Serialization (#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.
Diffstat (limited to 'source/slang/slang-serialize-ast.cpp')
| -rw-r--r-- | source/slang/slang-serialize-ast.cpp | 1635 |
1 files changed, 160 insertions, 1475 deletions
diff --git a/source/slang/slang-serialize-ast.cpp b/source/slang/slang-serialize-ast.cpp index 82cd7d6b4..65a5488a3 100644 --- a/source/slang/slang-serialize-ast.cpp +++ b/source/slang/slang-serialize-ast.cpp @@ -4,55 +4,23 @@ #include "slang-ast-generated.h" #include "slang-ast-generated-macro.h" -#include "slang-compiler.h" -#include "slang-type-layout.h" - #include "slang-ast-dump.h" -#include "slang-mangle.h" #include "slang-ast-support-types.h" +// Needed for ModuleSerialFilter +// Needed for 'findModuleForDecl' #include "slang-legalize-types.h" +#include "slang-mangle.h" -#include "../core/slang-byte-encode-util.h" +#include "slang-serialize-type-info.h" +#include "slang-serialize-misc-type-info.h" namespace Slang { +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ModuleSerialFilter !!!!!!!!!!!!!!!!!!!!!!!! -// Things stored as references: -// -// NodeBase derived types -// Array -// -// RefObject derived types: -// -// Breadcrumb -// StringRepresentation -// Scope - - - -// Helpers to convert fields treated as values - -class ASTSerialReader; -class ASTSerialWriter; - -template <typename NATIVE_TYPE, typename SERIAL_TYPE> -static void _toSerialValue(ASTSerialWriter* writer, const NATIVE_TYPE& src, SERIAL_TYPE& dst) -{ - ASTSerialTypeInfo<NATIVE_TYPE>::toSerial(writer, &src, &dst); -} - -template <typename SERIAL_TYPE, typename NATIVE_TYPE> -static void _toNativeValue(ASTSerialReader* reader, const SERIAL_TYPE& src, NATIVE_TYPE& dst) -{ - ASTSerialTypeInfo<NATIVE_TYPE>::toNative(reader, &src, &dst); -} - -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ModuleASTSerialFilter !!!!!!!!!!!!!!!!!!!!!!!! - - -ASTSerialIndex ModuleASTSerialFilter::writePointer(ASTSerialWriter* writer, const NodeBase* inPtr) +SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const NodeBase* inPtr) { NodeBase* ptr = const_cast<NodeBase*>(inPtr); SLANG_ASSERT(ptr); @@ -71,7 +39,7 @@ ASTSerialIndex ModuleASTSerialFilter::writePointer(ASTSerialWriter* writer, cons ImportExternalDecl* importDecl = astBuilder->create<ImportExternalDecl>(); importDecl->mangledName = mangledName; - const ASTSerialIndex index = writer->writePointer(importDecl); + const SerialIndex index = writer->addPointer(importDecl); // Set as the index of this writer->setPointerIndex(ptr, index); @@ -81,7 +49,7 @@ ASTSerialIndex ModuleASTSerialFilter::writePointer(ASTSerialWriter* writer, cons else { // Okay... we can just write it out then - return writer->writePointer(ptr); + return writer->writeObject(ptr); } } @@ -95,224 +63,52 @@ ASTSerialIndex ModuleASTSerialFilter::writePointer(ASTSerialWriter* writer, cons if (Stmt* stmt = as<Stmt>(ptr)) { // - writer->setPointerIndex(stmt, ASTSerialIndex(0)); - return ASTSerialIndex(0); + writer->setPointerIndex(stmt, SerialIndex(0)); + return SerialIndex(0); } // For now for everything else just write it - return writer->writePointer(ptr); + return writer->writeObject(ptr); } -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Serial <-> Native conversion !!!!!!!!!!!!!!!!!!!!!!!! - - -// We need to have a way to map between the two. -// If no mapping is needed, (just a copy), then we don't bother with the functions -template <typename T> -struct ASTSerialBasicTypeInfo -{ - typedef T NativeType; - typedef T SerialType; - - // We want the alignment to be the same as the size of the type for basic types - // NOTE! Might be different from SLANG_ALIGN_OF(SerialType) - enum { SerialAlignment = sizeof(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) { SLANG_UNUSED(writer); *(T*)serial = *(const T*)native; } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) { SLANG_UNUSED(reader); *(T*)native = *(const T*)serial; } - - static const ASTSerialType* getType() - { - static const ASTSerialType type = { sizeof(SerialType), uint8_t(SerialAlignment), &toSerial, &toNative }; - return &type; - } -}; - -template <typename NATIVE_T, typename SERIAL_T> -struct ASTSerialConvertTypeInfo -{ - typedef NATIVE_T NativeType; - typedef SERIAL_T SerialType; - - enum { SerialAlignment = ASTSerialBasicTypeInfo<SERIAL_T>::SerialAlignment }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) { SLANG_UNUSED(writer); *(SERIAL_T*)serial = SERIAL_T(*(const NATIVE_T*)native); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) { SLANG_UNUSED(reader); *(NATIVE_T*)native = NATIVE_T(*(const SERIAL_T*)serial); } -}; +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! AST types !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +// SyntaxClass<T> template <typename T> -struct ASTSerialIdentityTypeInfo -{ - typedef T NativeType; - typedef T SerialType; - - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) { SLANG_UNUSED(writer); *(T*)serial = *(const T*)native; } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) { SLANG_UNUSED(reader); *(T*)native = *(const T*)serial; } -}; - -// Don't need to convert the index type - -template <> -struct ASTSerialTypeInfo<ASTSerialIndex> : public ASTSerialIdentityTypeInfo<ASTSerialIndex> {}; - - -// Because is sized, we don't need to convert -template <> -struct ASTSerialTypeInfo<FeedbackType::Kind> : public ASTSerialIdentityTypeInfo<FeedbackType::Kind> {}; - -// Implement for Basic Types - -template <> -struct ASTSerialTypeInfo<uint8_t> : public ASTSerialBasicTypeInfo<uint8_t> {}; -template <> -struct ASTSerialTypeInfo<uint16_t> : public ASTSerialBasicTypeInfo<uint16_t> {}; -template <> -struct ASTSerialTypeInfo<uint32_t> : public ASTSerialBasicTypeInfo<uint32_t> {}; -template <> -struct ASTSerialTypeInfo<uint64_t> : public ASTSerialBasicTypeInfo<uint64_t> {}; - -template <> -struct ASTSerialTypeInfo<int8_t> : public ASTSerialBasicTypeInfo<int8_t> {}; -template <> -struct ASTSerialTypeInfo<int16_t> : public ASTSerialBasicTypeInfo<int16_t> {}; -template <> -struct ASTSerialTypeInfo<int32_t> : public ASTSerialBasicTypeInfo<int32_t> {}; -template <> -struct ASTSerialTypeInfo<int64_t> : public ASTSerialBasicTypeInfo<int64_t> {}; - -template <> -struct ASTSerialTypeInfo<float> : public ASTSerialBasicTypeInfo<float> {}; -template <> -struct ASTSerialTypeInfo<double> : public ASTSerialBasicTypeInfo<double> {}; - -// SamplerStateFlavor - -template <> -struct ASTSerialTypeInfo<SamplerStateFlavor> : public ASTSerialConvertTypeInfo<SamplerStateFlavor, uint8_t> {}; - -// TextureFlavor - -template <> -struct ASTSerialTypeInfo<TextureFlavor> +struct SerialTypeInfo<SyntaxClass<T>> { - typedef TextureFlavor NativeType; + typedef SyntaxClass<T> NativeType; typedef uint16_t SerialType; - enum { SerialAlignment = sizeof(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) { SLANG_UNUSED(writer); *(SerialType*)serial = ((const NativeType*)native)->flavor; } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) { SLANG_UNUSED(reader); ((NativeType*)native)->flavor = *(const SerialType*)serial; } -}; - -// Fixed arrays - -template <typename T, size_t N> -struct ASTSerialTypeInfo<T[N]> -{ - typedef ASTSerialTypeInfo<T> ElementASTSerialType; - typedef typename ElementASTSerialType::SerialType SerialElementType; - - typedef T NativeType[N]; - typedef SerialElementType SerialType[N]; - - enum { SerialAlignment = ASTSerialTypeInfo<T>::SerialAlignment }; - - static void toSerial(ASTSerialWriter* writer, const void* inNative, void* outSerial) - { - SerialElementType* serial = (SerialElementType*)outSerial; - const T* native = (const T*)inNative; - for (Index i = 0; i < Index(N); ++i) - { - ElementASTSerialType::toSerial(writer, native + i, serial + i); - } - } - static void toNative(ASTSerialReader* reader, const void* inSerial, void* outNative) - { - const SerialElementType* serial = (const SerialElementType*)inSerial; - T* native = (T*)outNative; - for (Index i = 0; i < Index(N); ++i) - { - ElementASTSerialType::toNative(reader, serial + i, native + i); - } - } -}; - -// Special case bool - as we can't rely on size alignment -template <> -struct ASTSerialTypeInfo<bool> -{ - typedef bool NativeType; - typedef uint8_t SerialType; - enum { SerialAlignment = sizeof(SerialType) }; + enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - static void toSerial(ASTSerialWriter* writer, const void* inNative, void* outSerial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { SLANG_UNUSED(writer); - *(SerialType*)outSerial = *(const NativeType*)inNative ? 1 : 0; + auto& src = *(const NativeType*)native; + auto& dst = *(SerialType*)serial; + dst = SerialType(src.classInfo->m_classId); } - static void toNative(ASTSerialReader* reader, const void* inSerial, void* outNative) + static void toNative(SerialReader* reader, const void* serial, void* native) { SLANG_UNUSED(reader); - *(NativeType*)outNative = (*(const SerialType*)inSerial) != 0; - } -}; - - -// Pointer -// Could handle different pointer base types with some more template magic here, but instead went with Pointer type to keep -// things simpler. -template <typename T> -struct ASTSerialTypeInfo<T*> -{ - typedef T* NativeType; - typedef ASTSerialIndex SerialType; - - enum - { - SerialAlignment = SLANG_ALIGN_OF(SerialType) - }; - - static void toSerial(ASTSerialWriter* writer, const void* inNative, void* outSerial) - { - *(SerialType*)outSerial = writer->addPointer(*(T**)inNative); - } - static void toNative(ASTSerialReader* reader, const void* inSerial, void* outNative) - { - *(T**)outNative = reader->getPointer(*(const SerialType*)inSerial).dynamicCast<T>(); - } -}; - -// Special case Name -template <> -struct ASTSerialTypeInfo<Name*> : public ASTSerialTypeInfo<RefObject*> -{ - // Special case - typedef Name* NativeType; - static void toNative(ASTSerialReader* reader, const void* inSerial, void* outNative) - { - *(Name**)outNative = reader->getName(*(const SerialType*)inSerial); + auto& src = *(const SerialType*)serial; + auto& dst = *(NativeType*)native; + dst.classInfo = ASTClassInfo::getInfo(ASTNodeType(src)); } }; -template <> -struct ASTSerialTypeInfo<const Name*> : public ASTSerialTypeInfo<Name*> -{ -}; - - -struct ASTSerialDeclRefBaseTypeInfo +struct SerialDeclRefBaseTypeInfo { typedef DeclRefBase NativeType; struct SerialType { - ASTSerialIndex substitutions; - ASTSerialIndex decl; + SerialIndex substitutions; + SerialIndex decl; }; enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - static void toSerial(ASTSerialWriter* writer, const void* inNative, void* outSerial) + static void toSerial(SerialWriter* writer, const void* inNative, void* outSerial) { SerialType& serial = *(SerialType*)outSerial; const NativeType& native = *(const NativeType*)inNative; @@ -320,7 +116,7 @@ struct ASTSerialDeclRefBaseTypeInfo serial.decl = writer->addPointer(native.decl); serial.substitutions = writer->addPointer(native.substitutions.substitutions); } - static void toNative(ASTSerialReader* reader, const void* inSerial, void* outNative) + static void toNative(SerialReader* reader, const void* inSerial, void* outNative) { DeclRefBase& native = *(DeclRefBase*)(outNative); const SerialType& serial = *(const SerialType*)inSerial; @@ -328,196 +124,49 @@ struct ASTSerialDeclRefBaseTypeInfo native.decl = reader->getPointer(serial.decl).dynamicCast<Decl>(); native.substitutions.substitutions = reader->getPointer(serial.substitutions).dynamicCast<Substitutions>(); } - static const ASTSerialType* getType() + static const SerialFieldType* getFieldType() { - static const ASTSerialType type = { sizeof(SerialType), uint8_t(SerialAlignment), &toSerial, &toNative }; + static const SerialFieldType type = { sizeof(SerialType), uint8_t(SerialAlignment), &toSerial, &toNative }; return &type; } }; - +// Special case DeclRef, because it always uses the same type template <typename T> -struct ASTSerialTypeInfo<DeclRef<T>> : public ASTSerialDeclRefBaseTypeInfo {}; - -// MatrixCoord can just go as is -template <> -struct ASTSerialTypeInfo<MatrixCoord> : ASTSerialIdentityTypeInfo<MatrixCoord> {}; - -// SourceLoc - -// Make the type exposed, so we can look for it if we want to remap. -template <> -struct ASTSerialTypeInfo<SourceLoc> -{ - typedef SourceLoc NativeType; - typedef ASTSerialSourceLoc SerialType; - enum { SerialAlignment = SLANG_ALIGN_OF(ASTSerialSourceLoc) }; - - static void toSerial(ASTSerialWriter* writer, const void* inNative, void* outSerial) - { - *(SerialType*)outSerial = writer->addSourceLoc(*(const NativeType*)inNative); - } - static void toNative(ASTSerialReader* reader, const void* inSerial, void* outNative) - { - *(NativeType*)outNative = reader->getSourceLoc(*(const SerialType*)inSerial); - } -}; - -// List -template <typename T, typename ALLOCATOR> -struct ASTSerialTypeInfo<List<T, ALLOCATOR>> +struct SerialGetFieldType<DeclRef<T>> { - typedef List<T, ALLOCATOR> NativeType; - typedef ASTSerialIndex SerialType; - - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - auto& src = *(const NativeType*)native; - auto& dst = *(SerialType*)serial; - - dst = writer->addArray(src.getBuffer(), src.getCount()); - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - auto& dst = *(NativeType*)native; - auto& src = *(const SerialType*)serial; - - reader->getArray(src, dst); - } + static const SerialFieldType* getFieldType() { return SerialDeclRefBaseTypeInfo::getFieldType(); } }; -// Dictionary -template <typename KEY, typename VALUE> -struct ASTSerialTypeInfo<Dictionary<KEY, VALUE>> -{ - typedef Dictionary<KEY, VALUE> NativeType; - struct SerialType - { - ASTSerialIndex keys; ///< Index an array - ASTSerialIndex values; ///< Index an array - }; - - typedef typename ASTSerialTypeInfo<KEY>::SerialType KeySerialType; - typedef typename ASTSerialTypeInfo<VALUE>::SerialType ValueSerialType; - - enum { SerialAlignment = SLANG_ALIGN_OF(ASTSerialIndex) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - auto& src = *(const NativeType*)native; - auto& dst = *(SerialType*)serial; - - List<KeySerialType> keys; - List<ValueSerialType> values; - - Index count = Index(src.Count()); - keys.setCount(count); - values.setCount(count); - - Index i = 0; - for (const auto& pair : src) - { - ASTSerialTypeInfo<KEY>::toSerial(writer, &pair.Key, &keys[i]); - ASTSerialTypeInfo<VALUE>::toSerial(writer, &pair.Value, &values[i]); - i++; - } - - dst.keys = writer->addArray(keys.getBuffer(), count); - dst.values = writer->addArray(values.getBuffer(), count); - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - auto& src = *(const SerialType*)serial; - auto& dst = *(NativeType*)native; - - // Clear it - dst = NativeType(); - - List<KEY> keys; - List<VALUE> values; - - reader->getArray(src.keys, keys); - reader->getArray(src.values, values); - - SLANG_ASSERT(keys.getCount() == values.getCount()); - - const Index count = keys.getCount(); - for (Index i = 0; i < count; ++i) - { - dst.Add(keys[i], values[i]); - } - } -}; -// SyntaxClass<T> template <typename T> -struct ASTSerialTypeInfo<SyntaxClass<T>> -{ - typedef SyntaxClass<T> NativeType; - typedef uint16_t SerialType; - - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; +struct SerialTypeInfo<DeclRef<T>> : public SerialDeclRefBaseTypeInfo {}; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - SLANG_UNUSED(writer); - auto& src = *(const NativeType*)native; - auto& dst = *(SerialType*)serial; - dst = SerialType(src.classInfo->m_classId); - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - SLANG_UNUSED(reader); - auto& src = *(const SerialType*)serial; - auto& dst = *(NativeType*)native; - dst.classInfo = ReflectClassInfo::getInfo(ASTNodeType(src)); - } -}; - -// Handle RefPtr - just convert into * to do the conversion -template <typename T> -struct ASTSerialTypeInfo<RefPtr<T>> -{ - typedef RefPtr<T> NativeType; - typedef typename ASTSerialTypeInfo<T*>::SerialType SerialType; - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; +// MatrixCoord can just go as is +template <> +struct SerialTypeInfo<MatrixCoord> : SerialIdentityTypeInfo<MatrixCoord> {}; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - auto& src = *(const NativeType*)native; - T* obj = src; - ASTSerialTypeInfo<T*>::toSerial(writer, &obj, serial); - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - T* obj = nullptr; - ASTSerialTypeInfo<T*>::toNative(reader, serial, &obj); - *(NativeType*)native = obj; - } -}; // QualType template <> -struct ASTSerialTypeInfo<QualType> +struct SerialTypeInfo<QualType> { typedef QualType NativeType; struct SerialType { - ASTSerialIndex type; + SerialIndex type; uint8_t isLeftValue; }; - enum { SerialAlignment = SLANG_ALIGN_OF(ASTSerialIndex) }; + enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { auto dst = (SerialType*)serial; auto src = (const NativeType*)native; dst->isLeftValue = src->isLeftValue ? 1 : 0; dst->type = writer->addPointer(src->type); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { auto src = (const SerialType*)serial; auto dst = (NativeType*)native; @@ -529,81 +178,81 @@ struct ASTSerialTypeInfo<QualType> // LookupResult::Breadcrumb template <> -struct ASTSerialTypeInfo<LookupResultItem::Breadcrumb> +struct SerialTypeInfo<LookupResultItem::Breadcrumb> { typedef LookupResultItem::Breadcrumb NativeType; struct SerialType { NativeType::Kind kind; NativeType::ThisParameterMode thisParameterMode; - ASTSerialTypeInfo<DeclRef<Decl>>::SerialType declRef; - ASTSerialTypeInfo<RefPtr<NativeType>> next; + SerialTypeInfo<DeclRef<Decl>>::SerialType declRef; + SerialTypeInfo<RefPtr<NativeType>> next; }; enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { auto& src = *(const NativeType*)native; auto& dst = *(SerialType*)serial; dst.kind = src.kind; dst.thisParameterMode = src.thisParameterMode; - _toSerialValue(writer, src.declRef, dst.declRef); - _toSerialValue(writer, src.next, dst.next); + toSerialValue(writer, src.declRef, dst.declRef); + toSerialValue(writer, src.next, dst.next); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { auto& dst = *(NativeType*)native; auto& src = *(const SerialType*)serial; dst.kind = src.kind; dst.thisParameterMode = src.thisParameterMode; - _toNativeValue(reader, src.declRef, dst.declRef); - _toNativeValue(reader, src.next, dst.next); + toNativeValue(reader, src.declRef, dst.declRef); + toNativeValue(reader, src.next, dst.next); } }; // LookupResultItem template <> -struct ASTSerialTypeInfo<LookupResultItem> +struct SerialTypeInfo<LookupResultItem> { typedef LookupResultItem NativeType; struct SerialType { - ASTSerialTypeInfo<DeclRef<Decl>>::SerialType declRef; - ASTSerialTypeInfo<RefPtr<NativeType::Breadcrumb>> breadcrumbs; + SerialTypeInfo<DeclRef<Decl>>::SerialType declRef; + SerialTypeInfo<RefPtr<NativeType::Breadcrumb>> breadcrumbs; }; enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { auto& src = *(const NativeType*)native; auto& dst = *(SerialType*)serial; - _toSerialValue(writer, src.declRef, dst.declRef); - _toSerialValue(writer, src.breadcrumbs, dst.breadcrumbs); + toSerialValue(writer, src.declRef, dst.declRef); + toSerialValue(writer, src.breadcrumbs, dst.breadcrumbs); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { auto& dst = *(NativeType*)native; auto& src = *(const SerialType*)serial; - _toNativeValue(reader, src.declRef, dst.declRef); - _toNativeValue(reader, src.breadcrumbs, dst.breadcrumbs); + toNativeValue(reader, src.declRef, dst.declRef); + toNativeValue(reader, src.breadcrumbs, dst.breadcrumbs); } }; // LookupResult template <> -struct ASTSerialTypeInfo<LookupResult> +struct SerialTypeInfo<LookupResult> { typedef LookupResult NativeType; - typedef ASTSerialIndex SerialType; + typedef SerialIndex SerialType; enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { auto& src = *(const NativeType*)native; auto& dst = *(SerialType*)serial; @@ -619,10 +268,10 @@ struct ASTSerialTypeInfo<LookupResult> } else { - dst = ASTSerialIndex(0); + dst = SerialIndex(0); } } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { auto& dst = *(NativeType*)native; auto& src = *(const SerialType*)serial; @@ -646,20 +295,19 @@ struct ASTSerialTypeInfo<LookupResult> } }; - // GlobalGenericParamSubstitution::ConstraintArg template <> -struct ASTSerialTypeInfo<GlobalGenericParamSubstitution::ConstraintArg> +struct SerialTypeInfo<GlobalGenericParamSubstitution::ConstraintArg> { typedef GlobalGenericParamSubstitution::ConstraintArg NativeType; struct SerialType { - ASTSerialIndex decl; - ASTSerialIndex val; + SerialIndex decl; + SerialIndex val; }; - enum { SerialAlignment = SLANG_ALIGN_OF(ASTSerialIndex) }; + enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { auto& dst = *(SerialType*)serial; auto& src = *(const NativeType*)native; @@ -667,7 +315,7 @@ struct ASTSerialTypeInfo<GlobalGenericParamSubstitution::ConstraintArg> dst.decl = writer->addPointer(src.decl); dst.val = writer->addPointer(src.val); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { auto& src = *(const SerialType*)serial; auto& dst = *(NativeType*)native; @@ -679,17 +327,17 @@ struct ASTSerialTypeInfo<GlobalGenericParamSubstitution::ConstraintArg> // ExpandedSpecializationArg template <> -struct ASTSerialTypeInfo<ExpandedSpecializationArg> +struct SerialTypeInfo<ExpandedSpecializationArg> { typedef ExpandedSpecializationArg NativeType; struct SerialType { - ASTSerialIndex val; - ASTSerialIndex witness; + SerialIndex val; + SerialIndex witness; }; - enum { SerialAlignment = SLANG_ALIGN_OF(ASTSerialIndex) }; + enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { auto& dst = *(SerialType*)serial; auto& src = *(const NativeType*)native; @@ -697,7 +345,7 @@ struct ASTSerialTypeInfo<ExpandedSpecializationArg> dst.witness = writer->addPointer(src.witness); dst.val = writer->addPointer(src.val); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { auto& src = *(const SerialType*)serial; auto& dst = *(NativeType*)native; @@ -709,17 +357,17 @@ struct ASTSerialTypeInfo<ExpandedSpecializationArg> // TypeExp template <> -struct ASTSerialTypeInfo<TypeExp> +struct SerialTypeInfo<TypeExp> { typedef TypeExp NativeType; struct SerialType { - ASTSerialIndex type; - ASTSerialIndex expr; + SerialIndex type; + SerialIndex expr; }; - enum { SerialAlignment = SLANG_ALIGN_OF(ASTSerialIndex) }; + enum { SerialAlignment = SLANG_ALIGN_OF(SerialIndex) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { auto& dst = *(SerialType*)serial; auto& src = *(const NativeType*)native; @@ -727,7 +375,7 @@ struct ASTSerialTypeInfo<TypeExp> dst.type = writer->addPointer(src.type); dst.expr = writer->addPointer(src.exp); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { auto& src = *(const SerialType*)serial; auto& dst = *(NativeType*)native; @@ -739,19 +387,19 @@ struct ASTSerialTypeInfo<TypeExp> // DeclCheckStateExt template <> -struct ASTSerialTypeInfo<DeclCheckStateExt> +struct SerialTypeInfo<DeclCheckStateExt> { typedef DeclCheckStateExt NativeType; typedef DeclCheckStateExt::RawType SerialType; enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { SLANG_UNUSED(writer); *(SerialType*)serial = (*(const NativeType*)native).getRaw(); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { SLANG_UNUSED(reader); (*(NativeType*)serial).setRaw(*(const SerialType*)native); @@ -760,24 +408,24 @@ struct ASTSerialTypeInfo<DeclCheckStateExt> // Modifiers template <> -struct ASTSerialTypeInfo<Modifiers> +struct SerialTypeInfo<Modifiers> { typedef Modifiers NativeType; - typedef ASTSerialIndex SerialType; + typedef SerialIndex SerialType; enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) + static void toSerial(SerialWriter* writer, const void* native, void* serial) { // We need to make into an array - List<ASTSerialIndex> modifierIndices; + List<SerialIndex> modifierIndices; for (Modifier* modifier : *(NativeType*)native) { modifierIndices.add(writer->addPointer(modifier)); } *(SerialType*)serial = writer->addArray(modifierIndices.getBuffer(), modifierIndices.getCount()); } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) + static void toNative(SerialReader* reader, const void* serial, void* native) { List<Modifier*> modifiers; reader->getArray(*(const SerialType*)serial, modifiers); @@ -796,1115 +444,150 @@ struct ASTSerialTypeInfo<Modifiers> } }; -// ImageFormat -template <> -struct ASTSerialTypeInfo<ImageFormat> : public ASTSerialConvertTypeInfo<ImageFormat, uint8_t> {}; - -// Stage -template <> -struct ASTSerialTypeInfo<Stage> : public ASTSerialConvertTypeInfo<Stage, uint8_t> {}; - -// TokenType -template <> -struct ASTSerialTypeInfo<TokenType> : public ASTSerialConvertTypeInfo<TokenType, uint8_t> {}; - -// BaseType -template <> -struct ASTSerialTypeInfo<BaseType> : public ASTSerialConvertTypeInfo<BaseType, uint8_t> {}; - -// SemanticVersion -template <> -struct ASTSerialTypeInfo<SemanticVersion> : public ASTSerialIdentityTypeInfo<SemanticVersion> {}; - // ASTNodeType template <> -struct ASTSerialTypeInfo<ASTNodeType> : public ASTSerialConvertTypeInfo<ASTNodeType, uint16_t> {}; - -// String -template <> -struct ASTSerialTypeInfo<String> -{ - typedef String NativeType; - typedef ASTSerialIndex SerialType; - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - auto& src = *(const NativeType*)native; - *(SerialType*)serial = writer->addString(src); - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - auto& src = *(const SerialType*)serial; - auto& dst = *(NativeType*)native; - dst = reader->getString(src); - } -}; - -// Token -template <> -struct ASTSerialTypeInfo<Token> -{ - typedef Token NativeType; - struct SerialType - { - ASTSerialTypeInfo<BaseType>::SerialType type; - ASTSerialTypeInfo<SourceLoc>::SerialType loc; - ASTSerialIndex name; - }; - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - auto& src = *(const NativeType*)native; - auto& dst = *(SerialType*)serial; - - ASTSerialTypeInfo<TokenType>::toSerial(writer, &src.type, &dst.type); - ASTSerialTypeInfo<SourceLoc>::toSerial(writer, &src.loc, &dst.loc); - - if (src.flags & TokenFlag::Name) - { - dst.name = writer->addName(src.getName()); - } - else - { - dst.name = writer->addString(src.getContent()); - } - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - auto& src = *(const SerialType*)serial; - auto& dst = *(NativeType*)native; - - dst.flags = 0; - dst.charsNameUnion.chars = nullptr; - - ASTSerialTypeInfo<TokenType>::toNative(reader, &src.type, &dst.type); - ASTSerialTypeInfo<SourceLoc>::toNative(reader, &src.loc, &dst.loc); - - // At the other end all token content will appear as Names. - if (src.name != ASTSerialIndex(0)) - { - dst.charsNameUnion.name = reader->getName(src.name); - dst.flags |= TokenFlag::Name; - } - } -}; - -// NameLoc -template <> -struct ASTSerialTypeInfo<NameLoc> -{ - typedef NameLoc NativeType; - struct SerialType - { - ASTSerialTypeInfo<SourceLoc>::SerialType loc; - ASTSerialIndex name; - }; - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - auto& src = *(const NativeType*)native; - auto& dst = *(SerialType*)serial; - - dst.name = writer->addName(src.name); - ASTSerialTypeInfo<SourceLoc>::toSerial(writer, &src.loc, &dst.loc); - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - auto& src = *(const SerialType*)serial; - auto& dst = *(NativeType*)native; - - dst.name = reader->getName(src.name); - ASTSerialTypeInfo<SourceLoc>::toNative(reader, &src.loc, &dst.loc); - } -}; - -// DiagnosticInfo -template <> -struct ASTSerialTypeInfo<const DiagnosticInfo*> -{ - typedef const DiagnosticInfo* NativeType; - typedef ASTSerialIndex SerialType; - - enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) }; - - static void toSerial(ASTSerialWriter* writer, const void* native, void* serial) - { - auto& src = *(const NativeType*)native; - auto& dst = *(SerialType*)serial; - dst = src ? writer->addString(UnownedStringSlice(src->name)) : ASTSerialIndex(0); - } - static void toNative(ASTSerialReader* reader, const void* serial, void* native) - { - auto& src = *(const SerialType*)serial; - auto& dst = *(NativeType*)native; - - if (src == ASTSerialIndex(0)) - { - dst = nullptr; - } - else - { - dst = findDiagnosticByName(reader->getStringSlice(src)); - } - } -}; - -// !!!!!!!!!!!!!!!!!!!!! ASTSerialGetType<T> !!!!!!!!!!!!!!!!!!!!!!!!!!! -// Getting the type info, let's use a static variable to hold the state to keep simple - -template <typename T> -struct ASTSerialGetType -{ - static const ASTSerialType* getType() - { - typedef ASTSerialTypeInfo<T> Info; - static const ASTSerialType type = { sizeof(typename Info::SerialType), uint8_t(Info::SerialAlignment), &Info::toSerial, &Info::toNative }; - return &type; - } -}; - -// Special case DeclRef, because it always uses the same type -template <typename T> -struct ASTSerialGetType<DeclRef<T>> -{ - static const ASTSerialType* getType() { return ASTSerialDeclRefBaseTypeInfo::getType(); } -}; +struct SerialTypeInfo<ASTNodeType> : public SerialConvertTypeInfo<ASTNodeType, uint16_t> {}; // !!!!!!!!!!!!!!!!!!!!!! Generate fields for a type !!!!!!!!!!!!!!!!!!!!!!!!!!! - template <typename T> -ASTSerialField _calcField(const char* name, T& in) +SerialField _makeField(const char* name, T& in) { uint8_t* ptr = &reinterpret_cast<uint8_t&>(in); - ASTSerialField field; + SerialField field; field.name = name; - field.type = ASTSerialGetType<T>::getType(); + field.type = SerialGetFieldType<T>::getFieldType(); // This only works because we in is an offset from 1 field.nativeOffset = uint32_t(size_t(ptr) - 1); field.serialOffset = 0; return field; } -static ASTSerialClass _makeClass(MemoryArena* arena, ASTNodeType type, const List<ASTSerialField>& fields) +static const SerialClass* _addClass(SerialClasses* serialClasses, ASTNodeType type, ASTNodeType super, const List<SerialField>& fields) { - ASTSerialClass cls = { type, 0, 0, 0, 0 }; - cls.fieldsCount = fields.getCount(); - cls.fields = arena->allocateAndCopyArray(fields.getBuffer(), fields.getCount()); - return cls; + const SerialClass* superClass = serialClasses->getSerialClass(SerialTypeKind::NodeBase, SerialSubType(super)); + return serialClasses->add(SerialTypeKind::NodeBase, SerialSubType(type), fields.getBuffer(), fields.getCount(), superClass); } -#define SLANG_AST_SERIAL_FIELD(FIELD_NAME, TYPE, param) fields.add(_calcField(#FIELD_NAME, obj->FIELD_NAME)); +#define SLANG_AST_ADD_SERIAL_FIELD(FIELD_NAME, TYPE, param) fields.add(_makeField(#FIELD_NAME, obj->FIELD_NAME)); // Note that the obj point is not nullptr, because some compilers notice this is 'indexing from null' // and warn/error. So we offset from 1. -#define SLANG_AST_SERIAL_MAKE_CLASS(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \ +#define SLANG_AST_ADD_SERIAL_CLASS(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \ { \ NAME* obj = (NAME*)1; \ SLANG_UNUSED(obj); \ fields.clear(); \ - SLANG_FIELDS_ASTNode_##NAME(SLANG_AST_SERIAL_FIELD, param) \ - outClasses[Index(ASTNodeType::NAME)] = _makeClass(arena, ASTNodeType::NAME, fields); \ + SLANG_FIELDS_ASTNode_##NAME(SLANG_AST_ADD_SERIAL_FIELD, param) \ + _addClass(serialClasses, ASTNodeType::NAME, ASTNodeType::SUPER, fields); \ } struct ASTFieldAccess { - static void calcClasses(MemoryArena* arena, ASTSerialClass outClasses[Index(ASTNodeType::CountOf)]) + static void calcClasses(SerialClasses* serialClasses) { - List<ASTSerialField> fields; - SLANG_ALL_ASTNode_NodeBase(SLANG_AST_SERIAL_MAKE_CLASS, _) + // Add NodeBase first, and specially handle so that we add a null super class + serialClasses->add(SerialTypeKind::NodeBase, SerialSubType(ASTNodeType::NodeBase), nullptr, 0, nullptr); + + // Add the rest in order such that Super class is always added before its children + List<SerialField> fields; + SLANG_CHILDREN_ASTNode_NodeBase(SLANG_AST_ADD_SERIAL_CLASS, _) } }; -ASTSerialClasses::ASTSerialClasses(): - m_arena(2048) +void addASTTypes(SerialClasses* serialClasses) { - memset(m_classes, 0, sizeof(m_classes)); - ASTFieldAccess::calcClasses(&m_arena, m_classes); - - // Now work out the layout - for (Index i = 0; i < SLANG_COUNT_OF(m_classes); ++i) { - // Set up each class in order, from lowest to highest index - // Doing so means super class is always setup - ASTSerialClass& serialClass = m_classes[i]; - - const ReflectClassInfo* info = ReflectClassInfo::getInfo(serialClass.type); - - size_t maxAlignment = 1; - size_t offset = 0; - - const ReflectClassInfo* superInfo = info->m_superClass; - if (superInfo) - { - ASTSerialClass& superSerialInfo = m_classes[superInfo->m_classId]; - - // If it's been setup, then alignment must be non zero. - // The ordering of ASTNodeType, should mean type have larger ASTNodeType greater than supers ASTNodeType. - SLANG_ASSERT(superSerialInfo.alignment != 0); - - // Must be a power of 2 - SLANG_ASSERT((superSerialInfo.alignment & (superSerialInfo.alignment - 1)) == 0); - - maxAlignment = superSerialInfo.alignment; - offset = superSerialInfo.size; - - // Check it is correctly aligned - SLANG_ASSERT((offset & (maxAlignment - 1)) == 0); - } - - // Okay, go through fields setting their offset - ASTSerialField* fields = serialClass.fields; - for (Index j = 0; j < serialClass.fieldsCount; j++) - { - ASTSerialField& field = fields[j]; - - size_t alignment = field.type->serialAlignment; - // Make sure the offset is aligned for the field requirement - offset = (offset + alignment - 1) & ~(alignment - 1); - - // Save the field offset - field.serialOffset = uint32_t(offset); - - // Move past the field - offset += field.type->serialSizeInBytes; - - // Calc the maximum alignment - maxAlignment = (alignment > maxAlignment) ? alignment : maxAlignment; - } - - // Align with maximum alignment - offset = (offset + maxAlignment - 1) & ~(maxAlignment - 1); - - serialClass.alignment = uint8_t(maxAlignment); - serialClass.size = uint32_t(offset); + ASTFieldAccess::calcClasses(serialClasses); } -} - -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ASTSerialWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!! - -ASTSerialWriter::ASTSerialWriter(ASTSerialClasses* classes, ASTSerialFilter* filter, DebugSerialWriter* debugWriter) : - m_arena(2048), - m_classes(classes), - m_filter(filter), - m_debugWriter(debugWriter) -{ - // 0 is always the null pointer - m_entries.add(nullptr); - m_ptrMap.Add(nullptr, 0); -} - -ASTSerialIndex ASTSerialWriter::writePointer(const NodeBase* node) -{ - // This pointer cannot be in the map - SLANG_ASSERT(m_ptrMap.TryGetValue(node) == nullptr); - - const ASTSerialClass* serialClass = m_classes->getSerialClass(node->astNodeType); - - typedef ASTSerialInfo::NodeEntry NodeEntry; - NodeEntry* nodeEntry = (NodeEntry*)m_arena.allocateAligned(sizeof(NodeEntry) + serialClass->size, ASTSerialInfo::MAX_ALIGNMENT); - - nodeEntry->type = ASTSerialInfo::Type::Node; - nodeEntry->astNodeType = uint16_t(node->astNodeType); - nodeEntry->info = ASTSerialInfo::makeEntryInfo(serialClass->alignment); - - auto index = _add(node, nodeEntry); - - uint8_t* serialPayload = (uint8_t*)(nodeEntry + 1); - - while (serialClass) { - for (Index i = 0; i < serialClass->fieldsCount; ++i) { - auto field = serialClass->fields[i]; - - // Work out the offsets - auto srcField = ((const uint8_t*)node) + field.nativeOffset; - auto dstField = serialPayload + field.serialOffset; + // Let's hack Breadcrumbs... - field.type->toSerialFunc(this, srcField, dstField); + typedef LookupResultItem::Breadcrumb Type; + Type* obj = (Type*)1; + SerialField field = _makeField("_", *obj); + serialClasses->add(SerialTypeKind::RefObject, SerialSubType(RefObjectSerialSubType::LookupResultItem_Breadcrumb), &field, 1, nullptr); } - // Get the super class - const ReflectClassInfo* reflectInfo = ReflectClassInfo::getInfo(serialClass->type); - const ReflectClassInfo* superReflectInfo = reflectInfo->m_superClass; - - serialClass = superReflectInfo ? m_classes->getSerialClass(ASTNodeType(superReflectInfo->m_classId)) : nullptr; - } - - return index; -} - -void ASTSerialWriter::setPointerIndex(const NodeBase* ptr, ASTSerialIndex index) -{ - m_ptrMap.Add(ptr, Index(index)); -} - -ASTSerialIndex ASTSerialWriter::addPointer(const NodeBase* node) -{ - // Null is always 0 - if (node == nullptr) - { - return ASTSerialIndex(0); - } - // Look up in the map - Index* indexPtr = m_ptrMap.TryGetValue(node); - if (indexPtr) - { - return ASTSerialIndex(*indexPtr); - } - - if (m_filter) - { - return m_filter->writePointer(this, node); - } - else - { - return writePointer(node); - } -} - -ASTSerialIndex ASTSerialWriter::addPointer(const RefObject* obj) -{ - // Null is always 0 - if (obj == nullptr) - { - return ASTSerialIndex(0); - } - // Look up in the map - Index* indexPtr = m_ptrMap.TryGetValue(obj); - if (indexPtr) - { - return ASTSerialIndex(*indexPtr); - } - - if (auto stringRep = dynamicCast<StringRepresentation>(obj)) - { - ASTSerialIndex index = addString(StringRepresentation::asSlice(stringRep)); - m_ptrMap.Add(obj, Index(index)); - return index; - } - else if (auto breadcrumb = dynamicCast<LookupResultItem::Breadcrumb>(obj)) - { - typedef ASTSerialTypeInfo<LookupResultItem::Breadcrumb> TypeInfo; - typedef ASTSerialInfo::RefObjectEntry RefObjectEntry; - - size_t alignment = TypeInfo::SerialAlignment; - alignment = (alignment < SLANG_ALIGN_OF(ASTSerialInfo::RefObjectEntry)) ? SLANG_ALIGN_OF(ASTSerialInfo::RefObjectEntry) : alignment; - - RefObjectEntry* entry = (RefObjectEntry*)m_arena.allocateAligned(sizeof(RefObjectEntry) + sizeof(TypeInfo::SerialType), alignment); - - entry->type = ASTSerialInfo::Type::RefObject; - entry->info = ASTSerialInfo::makeEntryInfo(int(alignment)); - entry->subType = RefObjectEntry::SubType::Breadcrumb; - - auto index = _add(breadcrumb, entry); - - // Do any conversion - TypeInfo::toSerial(this, breadcrumb, entry + 1); - return index; - } - else if (auto name = dynamicCast<const Name>(obj)) - { - return addName(name); - } - else if (auto scope = dynamicCast<Scope>(obj)) - { - // We don't serialize scope - return ASTSerialIndex(0); - } - else if (auto module = dynamicCast<Module>(obj)) - { - // We don't serialize Module - return ASTSerialIndex(0); - } - - SLANG_ASSERT(!"Unhandled type"); - return ASTSerialIndex(0); -} - -ASTSerialIndex ASTSerialWriter::addString(const UnownedStringSlice& slice) -{ - typedef ByteEncodeUtil Util; - typedef ASTSerialInfo::StringEntry StringEntry; - - if (slice.getLength() == 0) - { - return ASTSerialIndex(0); - } - - Index newIndex = m_entries.getCount(); - - Index* indexPtr = m_sliceMap.TryGetValueOrAdd(slice, newIndex); - if (indexPtr) - { - return ASTSerialIndex(*indexPtr); - } - - // Okay we need to add the string - - uint8_t encodeBuf[Util::kMaxLiteEncodeUInt32]; - const int encodeCount = Util::encodeLiteUInt32(uint32_t(slice.getLength()), encodeBuf); - - StringEntry* entry = (StringEntry*)m_arena.allocateUnaligned(SLANG_OFFSET_OF(StringEntry, sizeAndChars) + encodeCount + slice.getLength()); - entry->info = ASTSerialInfo::EntryInfo::Alignment1; - entry->type = ASTSerialInfo::Type::String; - uint8_t* dst = (uint8_t*)(entry->sizeAndChars); - for (int i = 0; i < encodeCount; ++i) - { - dst[i] = encodeBuf[i]; - } - - memcpy(dst + encodeCount, slice.begin(), slice.getLength()); - - m_entries.add(entry); - return ASTSerialIndex(newIndex); -} - - -ASTSerialIndex ASTSerialWriter::addString(const String& in) -{ - return addPointer(in.getStringRepresentation()); -} - -ASTSerialIndex ASTSerialWriter::addName(const Name* name) -{ - if (name == nullptr) - { - return ASTSerialIndex(0); - } - - // Look it up - Index* indexPtr = m_ptrMap.TryGetValue(name); - if (indexPtr) - { - return ASTSerialIndex(*indexPtr); + // Set these types to not serialize + serialClasses->addUnserialized(SerialTypeKind::RefObject, SerialSubType(RefObjectSerialSubType::Module)); + serialClasses->addUnserialized(SerialTypeKind::RefObject, SerialSubType(RefObjectSerialSubType::Scope)); } - - ASTSerialIndex index = addString(name->text); - m_ptrMap.Add(name, Index(index)); - return index; } -ASTSerialSourceLoc ASTSerialWriter::addSourceLoc(SourceLoc sourceLoc) +// A Hack for now to turn an RefObject* into a SubType for serialization +extern RefObjectSerialSubType getRefObjectSubType(const RefObject* obj) { - if (sourceLoc.isValid() && m_debugWriter) + if (as<LookupResultItem::Breadcrumb>(obj)) { - return m_debugWriter->addSourceLoc(sourceLoc); + return RefObjectSerialSubType::LookupResultItem_Breadcrumb; } - else + else if (as<Module>(obj)) { - return 0; + return RefObjectSerialSubType::Module; } -} - -ASTSerialIndex ASTSerialWriter::_addArray(size_t elementSize, size_t alignment, const void* elements, Index elementCount) -{ - typedef ASTSerialInfo::ArrayEntry Entry; - - if (elementCount == 0) + else if (as<Scope>(obj)) { - return ASTSerialIndex(0); + return RefObjectSerialSubType::Scope; } - - SLANG_ASSERT(alignment >= 1 && alignment <= ASTSerialInfo::MAX_ALIGNMENT); - - // We must at a minimum have the alignment for the array prefix info - alignment = (alignment < SLANG_ALIGN_OF(Entry)) ? SLANG_ALIGN_OF(Entry) : alignment; - - size_t payloadSize = elementCount * elementSize; - - Entry* entry = (Entry*)m_arena.allocateAligned(sizeof(Entry) + payloadSize, alignment); - - entry->type = ASTSerialInfo::Type::Array; - entry->info = ASTSerialInfo::makeEntryInfo(int(alignment)); - entry->elementSize = uint16_t(elementSize); - entry->elementCount = uint32_t(elementCount); - - memcpy(entry + 1, elements, payloadSize); - - m_entries.add(entry); - return ASTSerialIndex(m_entries.getCount() - 1); + return RefObjectSerialSubType::Invalid; } -static const uint8_t s_fixBuffer[ASTSerialInfo::MAX_ALIGNMENT]{ 0, }; +/* !!!!!!!!!!!!!!!!!!!!!! DefaultSerialObjectFactory !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -SlangResult ASTSerialWriter::write(Stream* stream) +void* DefaultSerialObjectFactory::create(SerialTypeKind typeKind, SerialSubType subType) { - const Int entriesCount = m_entries.getCount(); - - // Add a sentinal so we don't need special handling for - ASTSerialInfo::Entry sentinal; - sentinal.type = ASTSerialInfo::Type::String; - sentinal.info = ASTSerialInfo::EntryInfo::Alignment1; - - m_entries.add(&sentinal); - m_entries.removeLast(); - - ASTSerialInfo::Entry** entries = m_entries.getBuffer(); - // Note strictly required in our impl of List. But by writing this and - // knowing that removeLast cannot release memory, means the sentinal must be at the last position. - entries[entriesCount] = &sentinal; - - + switch (typeKind) { - size_t offset = 0; - - ASTSerialInfo::Entry* entry = entries[1]; - // We start on 1, because 0 is nullptr and not used for anything - for (Index i = 1; i < entriesCount; ++i) + case SerialTypeKind::NodeBase: { - ASTSerialInfo::Entry* next = entries[i + 1]; - // Before writing we need to store the next alignment - - const size_t nextAlignment = ASTSerialInfo::getAlignment(next->info); - const size_t alignment = ASTSerialInfo::getAlignment(entry->info); - - entry->info = ASTSerialInfo::combineWithNext(entry->info, next->info); - - // Check we are aligned correctly - SLANG_ASSERT((offset & (alignment - 1)) == 0); - - // When we write, we need to make sure it take into account the next alignment - const size_t entrySize = entry->calcSize(m_classes); - - // Work out the fix for next alignment - size_t nextOffset = offset + entrySize; - nextOffset = (nextOffset + nextAlignment - 1) & ~(nextAlignment - 1); - - size_t alignmentFixSize = nextOffset - (offset + entrySize); - - // The fix must be less than max alignment. We require it to be less because we aligned each Entry to - // MAX_ALIGNMENT, and so < MAX_ALIGNMENT is the most extra bytes we can write - SLANG_ASSERT( alignmentFixSize < ASTSerialInfo::MAX_ALIGNMENT); - - try - { - stream->write(entry, entrySize); - // If we needed to fix so that subsequent alignment is right, write out extra bytes here - if (alignmentFixSize) - { - stream->write(s_fixBuffer, alignmentFixSize); - } - } - catch (const IOException&) - { - return SLANG_FAIL; - } - - // Onto next - offset = nextOffset; - entry = next; + return m_astBuilder->createByNodeType(ASTNodeType(subType)); } - } - - return SLANG_OK; -} - -SlangResult ASTSerialWriter::writeIntoContainer(RiffContainer* container) -{ - typedef RiffContainer::Chunk Chunk; - typedef RiffContainer::ScopeChunk ScopeChunk; - - // This is the container for the AST Data - ScopeChunk scopeModule(container, Chunk::Kind::List, ASTSerialBinary::kSlangASTModuleFourCC); - { - ScopeChunk scopeData(container, Chunk::Kind::Data, ASTSerialBinary::kSlangASTModuleDataFourCC); - + case SerialTypeKind::RefObject: { - // Sentinal so we don't need special handling for end of list - ASTSerialInfo::Entry sentinal; - sentinal.type = ASTSerialInfo::Type::String; - sentinal.info = ASTSerialInfo::EntryInfo::Alignment1; - - size_t offset = 0; - const Int entriesCount = m_entries.getCount(); - - { - m_entries.add(&sentinal); - m_entries.removeLast(); - // Note strictly required in our impl of List. But by writing this and - // knowing that removeLast cannot release memory, means the sentinal must be at the last position. - m_entries.getBuffer()[entriesCount] = &sentinal; - } - - ASTSerialInfo::Entry*const* entries = m_entries.getBuffer(); - - ASTSerialInfo::Entry* entry = entries[1]; - // We start on 1, because 0 is nullptr and not used for anything - for (Index i = 1; i < entriesCount; ++i) + switch (RefObjectSerialSubType(subType)) { - ASTSerialInfo::Entry* next = entries[i + 1]; - - // Before writing we need to store the next alignment - - const size_t nextAlignment = ASTSerialInfo::getAlignment(next->info); - const size_t alignment = ASTSerialInfo::getAlignment(entry->info); - - entry->info = ASTSerialInfo::combineWithNext(entry->info, next->info); - - // Check we are aligned correctly - SLANG_ASSERT((offset & (alignment - 1)) == 0); - - // When we write, we need to make sure it take into account the next alignment - const size_t entrySize = entry->calcSize(m_classes); - - // Work out the fix for next alignment - size_t nextOffset = offset + entrySize; - nextOffset = (nextOffset + nextAlignment - 1) & ~(nextAlignment - 1); - - size_t alignmentFixSize = nextOffset - (offset + entrySize); - - // The fix must be less than max alignment. We require it to be less because we aligned each Entry to - // MAX_ALIGNMENT, and so < MAX_ALIGNMENT is the most extra bytes we can write - SLANG_ASSERT(alignmentFixSize < ASTSerialInfo::MAX_ALIGNMENT); - - container->write(entry, entrySize); - if (alignmentFixSize) + case RefObjectSerialSubType::LookupResultItem_Breadcrumb: { - container->write(s_fixBuffer, alignmentFixSize); + typedef LookupResultItem::Breadcrumb Breadcrumb; + return _add(new LookupResultItem::Breadcrumb(Breadcrumb::Kind::Member, DeclRef<Decl>(), nullptr, nullptr)); } - - // Onto next - offset = nextOffset; - entry = next; + default: break; } } - } - - return SLANG_OK; -} - -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ASTSerialInfo::Entry !!!!!!!!!!!!!!!!!!!!!!!! - -size_t ASTSerialInfo::Entry::calcSize(ASTSerialClasses* serialClasses) const -{ - switch (type) - { - case Type::String: - { - auto entry = static_cast<const StringEntry*>(this); - const uint8_t* cur = (const uint8_t*)entry->sizeAndChars; - uint32_t charsSize; - int sizeSize = ByteEncodeUtil::decodeLiteUInt32(cur, &charsSize); - return SLANG_OFFSET_OF(StringEntry, sizeAndChars) + sizeSize + charsSize; - } - case Type::Node: - { - auto entry = static_cast<const NodeEntry*>(this); - auto serialClass = serialClasses->getSerialClass(ASTNodeType(entry->astNodeType)); - - // Align by the alignment of the entry - size_t alignment = getAlignment(entry->info); - size_t size = sizeof(NodeEntry) + serialClass->size; - - size = size + (alignment - 1) & ~(alignment - 1); - return size; - } - case Type::RefObject: - { - auto entry = static_cast<const RefObjectEntry*>(this); - - size_t payloadSize; - switch (entry->subType) - { - case RefObjectEntry::SubType::Breadcrumb: - { - payloadSize = sizeof(ASTSerialTypeInfo<LookupResultItem::Breadcrumb>::SerialType); - break; - } - default: - { - SLANG_ASSERT(!"Unknown type"); - return 0; - } - } - - return sizeof(RefObjectEntry) + payloadSize; - } - case Type::Array: - { - auto entry = static_cast<const ArrayEntry*>(this); - return sizeof(ArrayEntry) + entry->elementSize * entry->elementCount; - } - default: break; - } - - SLANG_ASSERT(!"Unknown type"); - return 0; -} - -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ASTSerialReader !!!!!!!!!!!!!!!!!!!!!!!!!!!! - -const void* ASTSerialReader::getArray(ASTSerialIndex index, Index& outCount) -{ - if (index == ASTSerialIndex(0)) - { - outCount = 0; - return nullptr; - } - - SLANG_ASSERT(ASTSerialIndexRaw(index) < ASTSerialIndexRaw(m_entries.getCount())); - const Entry* entry = m_entries[Index(index)]; - - switch (entry->type) - { - case Type::Array: - { - auto arrayEntry = static_cast<const ASTSerialInfo::ArrayEntry*>(entry); - outCount = Index(arrayEntry->elementCount); - return (arrayEntry + 1); - } default: break; } - SLANG_ASSERT(!"Not an array"); - outCount = 0; return nullptr; } -ASTSerialPointer ASTSerialReader::getPointer(ASTSerialIndex index) -{ - if (index == ASTSerialIndex(0)) - { - return ASTSerialPointer(); - } - - SLANG_ASSERT(ASTSerialIndexRaw(index) < ASTSerialIndexRaw(m_entries.getCount())); - const Entry* entry = m_entries[Index(index)]; - - switch (entry->type) - { - case Type::String: - { - // Hmm. Tricky -> we don't know if will be cast as Name or String. Lets assume string. - String string = getString(index); - return ASTSerialPointer(string.getStringRepresentation()); - } - case Type::Node: - { - return ASTSerialPointer((NodeBase*)m_objects[Index(index)]); - } - case Type::RefObject: - { - return ASTSerialPointer((RefObject*)m_objects[Index(index)]); - } - default: break; - } - - SLANG_ASSERT(!"Cannot access as a pointer"); - return ASTSerialPointer(); -} - -String ASTSerialReader::getString(ASTSerialIndex index) -{ - if (index == ASTSerialIndex(0)) - { - return String(); - } - - SLANG_ASSERT(ASTSerialIndexRaw(index) < ASTSerialIndexRaw(m_entries.getCount())); - const Entry* entry = m_entries[Index(index)]; - - // It has to be a string type - if (entry->type != Type::String) - { - SLANG_ASSERT(!"Not a string"); - return String(); - } - - RefObject* obj = (RefObject*)m_objects[Index(index)]; - - if (obj) - { - StringRepresentation* stringRep = dynamicCast<StringRepresentation>(obj); - if (stringRep) - { - return String(stringRep); - } - // Must be a name then - Name* name = dynamicCast<Name>(obj); - SLANG_ASSERT(name); - return name->text; - } - - // Okay we need to construct as a string - UnownedStringSlice slice = getStringSlice(index); - String string(slice); - StringRepresentation* stringRep = string.getStringRepresentation(); - - m_scope.add(stringRep); - m_objects[Index(index)] = stringRep; - return string; -} - -Name* ASTSerialReader::getName(ASTSerialIndex index) -{ - if (index == ASTSerialIndex(0)) - { - return nullptr; - } - - SLANG_ASSERT(ASTSerialIndexRaw(index) < ASTSerialIndexRaw(m_entries.getCount())); - const Entry* entry = m_entries[Index(index)]; - - // It has to be a string type - if (entry->type != Type::String) - { - SLANG_ASSERT(!"Not a string"); - return nullptr; - } - - RefObject* obj = (RefObject*)m_objects[Index(index)]; - - if (obj) - { - Name* name = dynamicCast<Name>(obj); - if (name) - { - return name; - } - // Can only be a string then - StringRepresentation* stringRep = dynamicCast<StringRepresentation>(obj); - SLANG_ASSERT(stringRep); - - // I don't need to scope, as scoped in NamePool - name = m_namePool->getName(String(stringRep)); - - // Store as name, as can always access the inner string if needed - m_objects[Index(index)] = name; - return name; - } - - UnownedStringSlice slice = getStringSlice(index); - String string(slice); - Name* name = m_namePool->getName(string); - // Don't need to add to scope, because scoped on the pool - m_objects[Index(index)] = name; - return name; -} - -UnownedStringSlice ASTSerialReader::getStringSlice(ASTSerialIndex index) -{ - SLANG_ASSERT(ASTSerialIndexRaw(index) < ASTSerialIndexRaw(m_entries.getCount())); - const Entry* entry = m_entries[Index(index)]; - - // It has to be a string type - if (entry->type != Type::String) - { - SLANG_ASSERT(!"Not a string"); - return UnownedStringSlice(); - } - - auto stringEntry = static_cast<const ASTSerialInfo::StringEntry*>(entry); - - const uint8_t* src = (const uint8_t*)stringEntry->sizeAndChars; - - // Decode the string - uint32_t size; - int sizeSize = ByteEncodeUtil::decodeLiteUInt32(src, &size); - return UnownedStringSlice((const char*)src + sizeSize, size); -} - -SourceLoc ASTSerialReader::getSourceLoc(ASTSerialSourceLoc loc) -{ - return (loc && m_debugReader) ? m_debugReader->getSourceLoc(loc) : SourceLoc(); -} - -SlangResult ASTSerialReader::loadEntries(const uint8_t* data, size_t dataCount, List<const ASTSerialInfo::Entry*>& outEntries) -{ - // Check the input data is at least aligned to the max alignment (otherwise everything cannot be aligned correctly) - SLANG_ASSERT((size_t(data) & (ASTSerialInfo::MAX_ALIGNMENT - 1)) == 0); - - outEntries.setCount(1); - outEntries[0] = nullptr; - - const uint8_t*const end = data + dataCount; - - const uint8_t* cur = data; - while (cur < end) - { - const Entry* entry = (const Entry*)cur; - outEntries.add(entry); - - const size_t entrySize = entry->calcSize(m_classes); - cur += entrySize; - - // Need to get the next alignment - const size_t nextAlignment = ASTSerialInfo::getNextAlignment(entry->info); - - // Need to fix cur with the alignment - cur = (const uint8_t*)((size_t(cur) + nextAlignment - 1) & ~(nextAlignment - 1)); - } - - return SLANG_OK; -} - -SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuilder* builder, NamePool* namePool) -{ - SLANG_RETURN_ON_FAIL(loadEntries(data, dataCount, m_entries)); - - m_namePool = namePool; - - m_objects.clearAndDeallocate(); - m_objects.setCount(m_entries.getCount()); - memset(m_objects.getBuffer(), 0, m_objects.getCount() * sizeof(void*)); - - // Go through entries, constructing objects. - for (Index i = 1; i < m_entries.getCount(); ++i) - { - const Entry* entry = m_entries[i]; - - switch (entry->type) - { - case Type::String: - { - // Don't need to construct an object. This is probably a StringRepresentation, or a Name - // Will evaluate lazily. - break; - } - case Type::Node: - { - auto nodeEntry = static_cast<const ASTSerialInfo::NodeEntry*>(entry); - m_objects[i] = builder->createByNodeType(ASTNodeType(nodeEntry->astNodeType)); - break; - } - case Type::RefObject: - { - auto objEntry = static_cast<const ASTSerialInfo::RefObjectEntry*>(entry); - switch (objEntry->subType) - { - case ASTSerialInfo::RefObjectEntry::SubType::Breadcrumb: - { - typedef LookupResultItem::Breadcrumb Breadcrumb; - - auto breadcrumb = new LookupResultItem::Breadcrumb(Breadcrumb::Kind::Member, DeclRef<Decl>(), nullptr, nullptr); - m_scope.add(breadcrumb); - m_objects[i] = breadcrumb; - break; - } - default: - { - SLANG_ASSERT(!"Unknown type"); - return SLANG_FAIL; - } - } - break; - } - case Type::Array: - { - // Don't need to construct an object, as will be accessed an interpreted by the object that holds it - break; - } - } - } - - // Deserialize - for (Index i = 1; i < m_entries.getCount(); ++i) - { - const Entry* entry = m_entries[i]; - void* native = m_objects[i]; - if (!native) - { - continue; - } - switch (entry->type) - { - case Type::Node: - { - auto nodeEntry = static_cast<const ASTSerialInfo::NodeEntry*>(entry); - auto serialClass = m_classes->getSerialClass(ASTNodeType(nodeEntry->astNodeType)); - - const uint8_t* src = (const uint8_t*)(nodeEntry + 1); - uint8_t* dst = (uint8_t*)m_objects[i]; - - // It must be constructed - SLANG_ASSERT(dst); - - while (serialClass) - { - for (Index j = 0; j < serialClass->fieldsCount; ++j) - { - auto field = serialClass->fields[j]; - auto fieldType = field.type; - fieldType->toNativeFunc(this, src + field.serialOffset, dst + field.nativeOffset); - } - - auto cls = ReflectClassInfo::getInfo(serialClass->type); - auto superCls = cls->m_superClass; - - // Get the super class - serialClass = superCls ? m_classes->getSerialClass(ASTNodeType(superCls->m_classId)) : nullptr; - } - - break; - } - case Type::RefObject: - { - auto objEntry = static_cast<const ASTSerialInfo::RefObjectEntry*>(entry); - switch (objEntry->subType) - { - case ASTSerialInfo::RefObjectEntry::SubType::Breadcrumb: - { - typedef LookupResultItem::Breadcrumb Breadcrumb; - auto serialType = ASTSerialGetType<Breadcrumb>::getType(); - serialType->toNativeFunc(this, (entry + 1), m_objects[i]); - break; - } - default: - { - SLANG_ASSERT(!"Unknown type"); - return SLANG_FAIL; - } - } - break; - } - default: break; - } - } - - return SLANG_OK; -} - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ASTSerializeUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!! /* static */SlangResult ASTSerialTestUtil::selfTest() { - RefPtr<ASTSerialClasses> classes = new ASTSerialClasses; + RefPtr<SerialClasses> classes; + SerialClasses::create(classes); { - struct Thing - { - Module* node; - }; - Thing thing; - - //Pointer pointer(thing.node); - - auto field = _calcField("node", thing.node); - - - const ASTSerialType* type = ASTSerialGetType<Type*>::getType(); + const SerialFieldType* type = SerialGetFieldType<Type*>::getFieldType(); SLANG_UNUSED(type); } { - const ASTSerialType* type = ASTSerialGetType<int[10]>::getType(); + const SerialFieldType* type = SerialGetFieldType<int[10]>::getFieldType(); SLANG_UNUSED(type); } { - const ASTSerialType* type = ASTSerialGetType<bool[3]>::getType(); + const SerialFieldType* type = SerialGetFieldType<bool[3]>::getFieldType(); SLANG_UNUSED(type); } { - const ASTSerialType* type = ASTSerialGetType<Type*[3]>::getType(); + const SerialFieldType* type = SerialGetFieldType<Type*[3]>::getFieldType(); SLANG_UNUSED(type); } @@ -1913,7 +596,8 @@ SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuil /* static */SlangResult ASTSerialTestUtil::testSerialize(NodeBase* node, RootNamePool* rootNamePool, SharedASTBuilder* sharedASTBuilder, SourceManager* sourceManager) { - RefPtr<ASTSerialClasses> classes = new ASTSerialClasses; + RefPtr<SerialClasses> classes; + SerialClasses::create(classes); List<uint8_t> contents; @@ -1921,11 +605,12 @@ SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuil OwnedMemoryStream stream(FileAccess::ReadWrite); ModuleDecl* moduleDecl = as<ModuleDecl>(node); - ModuleASTSerialFilter filterStorage(moduleDecl); + // Only serialize out things *in* this module + ModuleSerialFilter filterStorage(moduleDecl); - ASTSerialFilter* filter = moduleDecl ? &filterStorage : nullptr; + SerialFilter* filter = moduleDecl ? &filterStorage : nullptr; - ASTSerialWriter writer(classes, filter, nullptr); + SerialWriter writer(classes, filter); // Lets serialize it all writer.addPointer(node); @@ -1937,15 +622,17 @@ SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuil NamePool namePool; namePool.setRootNamePool(rootNamePool); - ASTSerialReader reader(classes, nullptr); + SerialReader reader(classes, nullptr); ASTBuilder builder(sharedASTBuilder, "Serialize Check"); + DefaultSerialObjectFactory objectFactory(&builder); + // We could now check that the loaded data matches { - const List<ASTSerialInfo::Entry*>& writtenEntries = writer.getEntries(); - List<const ASTSerialInfo::Entry*> readEntries; + const List<SerialInfo::Entry*>& writtenEntries = writer.getEntries(); + List<const SerialInfo::Entry*> readEntries; SlangResult res = reader.loadEntries(contents.getBuffer(), contents.getCount(), readEntries); SLANG_UNUSED(res); @@ -1969,7 +656,7 @@ SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuil } { - SlangResult res = reader.load(contents.getBuffer(), contents.getCount(), &builder, &namePool); + SlangResult res = reader.load(contents.getBuffer(), contents.getCount(), &namePool); SLANG_UNUSED(res); } @@ -1979,7 +666,7 @@ SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuil String readDump; { SourceWriter sourceWriter(sourceManager, LineDirectiveMode::None); - ASTDumpUtil::dump(reader.getPointer(ASTSerialIndex(1)).dynamicCast<NodeBase>(), ASTDumpUtil::Style::Hierachical, dumpFlags, &sourceWriter); + ASTDumpUtil::dump(reader.getPointer(SerialIndex(1)).dynamicCast<NodeBase>(), ASTDumpUtil::Style::Hierachical, dumpFlags, &sourceWriter); readDump = sourceWriter.getContentAndClear(); } @@ -1994,7 +681,6 @@ SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuil File::writeAllText("ast-read.ast-dump", readDump); File::writeAllText("ast-orig.ast-dump", origDump); - if (readDump != origDump) { return SLANG_FAIL; @@ -2004,5 +690,4 @@ SlangResult ASTSerialReader::load(const uint8_t* data, size_t dataCount, ASTBuil return SLANG_OK; } - } // namespace Slang |
