diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-10-06 17:07:22 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-06 14:07:22 -0700 |
| commit | 4ad2e52662a00f7d8b25be6d451bba33ba62947f (patch) | |
| tree | abd70777a73037c44e40d182e332c7a19c60e779 /source/slang/slang-serialize-factory.cpp | |
| parent | 8a70e20df6f47678c146eb29f89655aa734f97c7 (diff) | |
Use Reflection for (Serial)RefObject Serialization (#1567)
* 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.
* Improve output of type names that are in scopes in C++ extractor.
Update premake5.lua to run generation for RefObject derived types.
* C++ extractor working on RefObject type.
* Split out serialization functionality that spans different types into slang-serialization-factory.cpp/.h
Put AST type info into header.
Removed RefObjectSerialSubType - use RefObjectType
Add filtering for RefObject derived types
Remove construction and filteringhacks.
* Set up field serialization for SerialRefObject derived types.
* Fix template problem compiling on Clang/Gcc
* Work in progress to make Value types work.
* Added slang-value-reflect.cpp
Diffstat (limited to 'source/slang/slang-serialize-factory.cpp')
| -rw-r--r-- | source/slang/slang-serialize-factory.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/source/slang/slang-serialize-factory.cpp b/source/slang/slang-serialize-factory.cpp new file mode 100644 index 000000000..2bb7b047e --- /dev/null +++ b/source/slang/slang-serialize-factory.cpp @@ -0,0 +1,133 @@ +// slang-serialize-factory.cpp +#include "slang-serialize-factory.h" + +#include "../core/slang-math.h" + +#include "slang-ast-builder.h" + +#include "slang-ref-object-reflect.h" +#include "slang-ast-reflect.h" + +#include "slang-serialize-ast.h" +#include "slang-ref-object-reflect.h" + +// Needed for ModuleSerialFilter +// Needed for 'findModuleForDecl' +#include "slang-legalize-types.h" +#include "slang-mangle.h" + +namespace Slang { + +/* !!!!!!!!!!!!!!!!!!!!!! DefaultSerialObjectFactory !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void* DefaultSerialObjectFactory::create(SerialTypeKind typeKind, SerialSubType subType) +{ + switch (typeKind) + { + case SerialTypeKind::NodeBase: + { + return m_astBuilder->createByNodeType(ASTNodeType(subType)); + } + case SerialTypeKind::RefObject: + { + const ReflectClassInfo* info = SerialRefObjects::getClassInfo(RefObjectType(subType)); + + if (info && info->m_createFunc) + { + RefObject* obj = reinterpret_cast<RefObject*>(info->m_createFunc(nullptr)); + return _add(obj); + } + return nullptr; + } + default: break; + } + + return nullptr; +} + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ModuleSerialFilter !!!!!!!!!!!!!!!!!!!!!!!! + +SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const RefObject* inPtr) +{ + // We don't serialize Module or Scope + if (as<Module>(inPtr) || as<Scope>(inPtr)) + { + writer->setPointerIndex(inPtr, SerialIndex(0)); + return SerialIndex(0); + } + + // For now for everything else just write it + return writer->writeObject(inPtr); +} + +SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const NodeBase* inPtr) +{ + NodeBase* ptr = const_cast<NodeBase*>(inPtr); + SLANG_ASSERT(ptr); + + if (Decl* decl = as<Decl>(ptr)) + { + ModuleDecl* moduleDecl = findModuleForDecl(decl); + SLANG_ASSERT(moduleDecl); + if (moduleDecl && moduleDecl != m_moduleDecl) + { + ASTBuilder* astBuilder = m_moduleDecl->module->getASTBuilder(); + + // It's a reference to a declaration in another module, so create an ImportExternalDecl. + + String mangledName = getMangledName(astBuilder, decl); + + ImportExternalDecl* importDecl = astBuilder->create<ImportExternalDecl>(); + importDecl->mangledName = mangledName; + const SerialIndex index = writer->addPointer(importDecl); + + // Set as the index of this + writer->setPointerIndex(ptr, index); + + return index; + } + else + { + // Okay... we can just write it out then + return writer->writeObject(ptr); + } + } + + // TODO(JS): What we really want to do here is to ignore bodies functions. + // It's not 100% clear if this is even right though - for example does type inference + // imply the body is needed to say infer a return type? + // Also not clear if statements in other scenarios (if there are others) might need to be kept. + // + // For now we just ignore all stmts + + if (Stmt* stmt = as<Stmt>(ptr)) + { + // + writer->setPointerIndex(stmt, SerialIndex(0)); + return SerialIndex(0); + } + + // For now for everything else just write it + return writer->writeObject(ptr); +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SerialClassesUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +/* static */SlangResult SerialClassesUtil::addSerialClasses(SerialClasses* serialClasses) +{ + ASTSerialUtil::addSerialClasses(serialClasses); + SerialRefObjects::addSerialClasses(serialClasses); + + return SLANG_OK; +} + +/* static */SlangResult SerialClassesUtil::create(RefPtr<SerialClasses>& out) +{ + RefPtr<SerialClasses> classes(new SerialClasses); + SLANG_RETURN_ON_FAIL(addSerialClasses(classes)); + + out = classes; + return SLANG_OK; +} + +} // namespace Slang |
