Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | |||
4 | /// @file codegen/FunctionRegistry.cc | ||
5 | |||
6 | #include "FunctionRegistry.h" | ||
7 | #include "Functions.h" | ||
8 | #include "FunctionTypes.h" | ||
9 | |||
10 | #include "../Exceptions.h" | ||
11 | |||
12 | namespace openvdb { | ||
13 | OPENVDB_USE_VERSION_NAMESPACE | ||
14 | namespace OPENVDB_VERSION_NAME { | ||
15 | |||
16 | namespace ax { | ||
17 | namespace codegen { | ||
18 | |||
19 | 157516 | void FunctionRegistry::insert(const std::string& identifier, | |
20 | const FunctionRegistry::ConstructorT creator, const bool internal) | ||
21 | { | ||
22 | 157516 | if (!mMap.emplace(std::piecewise_construct, | |
23 | 157516 | std::forward_as_tuple(identifier), | |
24 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 157516 times.
|
157516 | std::forward_as_tuple(creator, internal)).second) { |
25 | ✗ | OPENVDB_THROW(AXCompilerError, "A function already exists" | |
26 | " with the provided identifier: \"" + identifier + "\""); | ||
27 | } | ||
28 | 157516 | } | |
29 | |||
30 | 21 | void FunctionRegistry::insertAndCreate(const std::string& identifier, | |
31 | const FunctionRegistry::ConstructorT creator, | ||
32 | const FunctionOptions& op, | ||
33 | const bool internal) | ||
34 | { | ||
35 | auto inserted = mMap.emplace(std::piecewise_construct, | ||
36 | 21 | std::forward_as_tuple(identifier), | |
37 | 21 | std::forward_as_tuple(creator, internal)); | |
38 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (!inserted.second) { |
39 | ✗ | OPENVDB_THROW(AXCompilerError, "A function already exists" | |
40 | " with the provided token: \"" + identifier + "\""); | ||
41 | } | ||
42 | 21 | inserted.first->second.create(op); | |
43 | 21 | } | |
44 | |||
45 | 32095 | const FunctionGroup* FunctionRegistry::getOrInsert(const std::string& identifier, | |
46 | const FunctionOptions& op, | ||
47 | const bool allowInternalAccess) | ||
48 | { | ||
49 |
2/2✓ Branch 0 taken 32094 times.
✓ Branch 1 taken 1 times.
|
32095 | auto iter = mMap.find(identifier); |
50 |
2/2✓ Branch 0 taken 32094 times.
✓ Branch 1 taken 1 times.
|
32095 | if (iter == mMap.end()) return nullptr; |
51 | 32094 | FunctionRegistry::RegisteredFunction& reg = iter->second; | |
52 |
3/4✓ Branch 0 taken 5258 times.
✓ Branch 1 taken 26836 times.
✓ Branch 2 taken 5258 times.
✗ Branch 3 not taken.
|
32094 | if (!allowInternalAccess && reg.isInternal()) return nullptr; |
53 | |||
54 |
2/2✓ Branch 0 taken 5582 times.
✓ Branch 1 taken 26512 times.
|
32094 | if (!reg.function()) reg.create(op); |
55 | |||
56 | const FunctionGroup* const function = reg.function(); | ||
57 | |||
58 | // initialize function dependencies if necessary | ||
59 | |||
60 |
2/4✓ Branch 0 taken 32094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32094 times.
✗ Branch 3 not taken.
|
32094 | if (op.mLazyFunctions && function) { |
61 |
2/2✓ Branch 0 taken 628818 times.
✓ Branch 1 taken 32094 times.
|
660912 | for (const auto& decl : function->list()) { |
62 | const std::vector<const char*>& deps = decl->dependencies(); | ||
63 |
2/2✓ Branch 0 taken 10251 times.
✓ Branch 1 taken 628818 times.
|
639069 | for (const auto& dep : deps) { |
64 | // if the function ptr doesn't exist, create it with getOrInsert. | ||
65 | // This provides internal access and ensures handling of cyclical | ||
66 | // dependencies do not cause a problem | ||
67 |
2/4✓ Branch 1 taken 10251 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10251 times.
✗ Branch 5 not taken.
|
10251 | const FunctionGroup* const internal = this->get(dep, true); |
68 |
4/6✓ Branch 0 taken 545 times.
✓ Branch 1 taken 9706 times.
✓ Branch 3 taken 545 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 545 times.
✗ Branch 7 not taken.
|
10796 | if (!internal) this->getOrInsert(dep, op, true); |
69 | } | ||
70 | } | ||
71 | } | ||
72 | |||
73 | return function; | ||
74 | } | ||
75 | |||
76 | 10251 | const FunctionGroup* FunctionRegistry::get(const std::string& identifier, const bool allowInternalAccess) const | |
77 | { | ||
78 |
1/2✓ Branch 0 taken 10251 times.
✗ Branch 1 not taken.
|
10251 | auto iter = mMap.find(identifier); |
79 |
1/2✓ Branch 0 taken 10251 times.
✗ Branch 1 not taken.
|
10251 | if (iter == mMap.end()) return nullptr; |
80 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 10251 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
10251 | if (!allowInternalAccess && iter->second.isInternal()) return nullptr; |
81 | 10251 | return iter->second.function(); | |
82 | } | ||
83 | |||
84 | 1 | void FunctionRegistry::createAll(const FunctionOptions& op, const bool verify) | |
85 | { | ||
86 |
2/2✓ Branch 0 taken 106 times.
✓ Branch 1 taken 1 times.
|
107 | for (auto& it : mMap) it.second.create(op); |
87 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!verify) return; |
88 | |||
89 | std::set<std::string> symbols; | ||
90 | |||
91 |
2/2✓ Branch 0 taken 106 times.
✓ Branch 1 taken 1 times.
|
107 | for (auto& it : mMap) { |
92 | const auto& func = it.second.function(); | ||
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
|
106 | if (!func) { |
94 | OPENVDB_LOG_WARN("Unable to create function '" << it.first << "'."); | ||
95 | } | ||
96 |
2/4✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 106 times.
|
106 | if (it.first != std::string(func->name())) { |
97 | ✗ | OPENVDB_LOG_WARN("Registered function identifier does not match function name '" << | |
98 | it.first << "' -> '" << func->name() << "'."); | ||
99 | } | ||
100 |
2/4✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 106 times.
|
106 | if (it.first.empty() || !func->name()) { |
101 | OPENVDB_LOG_WARN("Registered function has no identifier or name."); | ||
102 | } | ||
103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
|
106 | if (func->list().empty()) { |
104 | OPENVDB_LOG_WARN("Function '" << it.first << "' has no declarations."); | ||
105 | } | ||
106 |
2/2✓ Branch 0 taken 412 times.
✓ Branch 1 taken 106 times.
|
518 | for (const auto& decl : func->list()) { |
107 |
2/4✓ Branch 1 taken 412 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 412 times.
|
824 | if (symbols.count(std::string(decl->symbol()))) { |
108 | ✗ | OPENVDB_LOG_WARN("Function '" << it.first << "' has a symbol clash. Symbol '" << | |
109 | decl->symbol() << "' already exists."); | ||
110 | } | ||
111 |
1/2✓ Branch 1 taken 412 times.
✗ Branch 2 not taken.
|
824 | symbols.insert(std::string(decl->symbol())); |
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | } // namespace codegen | ||
117 | } // namespace ax | ||
118 | } // namespace OPENVDB_VERSION_NAME | ||
119 | } // namespace openvdb | ||
120 | |||
121 |