summaryrefslogtreecommitdiff
path: root/source/slang/slang-serialize-factory.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-10-06 17:07:22 -0400
committerGitHub <noreply@github.com>2020-10-06 14:07:22 -0700
commit4ad2e52662a00f7d8b25be6d451bba33ba62947f (patch)
treeabd70777a73037c44e40d182e332c7a19c60e779 /source/slang/slang-serialize-factory.cpp
parent8a70e20df6f47678c146eb29f89655aa734f97c7 (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.cpp133
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