summaryrefslogtreecommitdiff
path: root/source/slang/slang-serialize-factory.cpp
blob: 2bb7b047eadba8263152eed4cf6769b0a7532300 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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