| 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 |