tbv2: add dynamic context passed through all functions (#410)

Summary:
tbv2: add dynamic context passed through all functions

Previously for we had some shared state between all requests, noticeably the
pointers set. This change adds a by reference value to all requests which can
hold additional mutable state. The pointers set is moved into this mutable
state for OIL, which means each concurrent request will have its own pointer
set. Doing things this way allows more features to be added in the future
without such a big code modification.

Closes https://github.com/facebookexperimental/object-introspection/issues/404

Pull Request resolved: https://github.com/facebookexperimental/object-introspection/pull/410

Test Plan: - CI

Differential Revision: D51394035

Pulled By: JakeHillion

fbshipit-source-id: 55d2ba9b5e056148a29dc821020cfc3d94e5175a
This commit is contained in:
Jake Hillion 2023-11-16 07:34:03 -08:00 committed by Facebook Community Bot
parent 352b71b02b
commit b117150f83
34 changed files with 131 additions and 107 deletions

View File

@ -128,8 +128,9 @@ void addIncludes(const TypeGraph& typeGraph,
includes.emplace("oi/types/st.h");
}
if (features[Feature::Library]) {
includes.emplace("vector");
includes.emplace("memory");
includes.emplace("oi/IntrospectionResult.h");
includes.emplace("vector");
}
if (features[Feature::JitTiming]) {
includes.emplace("chrono");
@ -428,7 +429,7 @@ void addStandardGetSizeFuncDefs(std::string& code) {
JLOG("ptr val @");
JLOGPTR(s_ptr);
StoreData((uintptr_t)(s_ptr), returnArg);
if (s_ptr && pointers.add((uintptr_t)s_ptr)) {
if (s_ptr && ctx.pointers.add((uintptr_t)s_ptr)) {
StoreData(1, returnArg);
getSizeType(*(s_ptr), returnArg);
} else {
@ -649,7 +650,8 @@ void CodeGen::genClassTraversalFunction(const Class& c, std::string& code) {
code += " static types::st::Unit<DB> ";
code += funcName;
code += "(\n const ";
code += "(\n Ctx& ctx,\n";
code += " const ";
code += c.name();
code += "& t,\n typename TypeHandler<Ctx, ";
code += c.name();
@ -683,7 +685,8 @@ void CodeGen::genClassTraversalFunction(const Class& c, std::string& code) {
} else {
code += "delegate";
}
code += "([&t](auto ret) { return OIInternal::getSizeType<Ctx>(t.";
code +=
"([&ctx, &t](auto ret) { return OIInternal::getSizeType<Ctx>(ctx, t.";
code += member.name;
code += ", ret); })";
}
@ -921,6 +924,7 @@ void genContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
code += ";\n";
code += " static types::st::Unit<DB> getSizeType(\n";
code += " Ctx& ctx,\n";
code += " const ";
code += containerWithTypes;
code += "& container,\n";
@ -979,7 +983,7 @@ void addCaptureKeySupport(std::string& code) {
};
template <bool CaptureKeys, typename Ctx, typename T>
auto maybeCaptureKey(const T& key, auto returnArg) {
auto maybeCaptureKey(Ctx& ctx, const T& key, auto returnArg) {
if constexpr (CaptureKeys) {
return returnArg.delegate([&key](auto ret) {
return CaptureKeyHandler<Ctx, T>::captureKey(key, ret);
@ -1041,10 +1045,10 @@ void addStandardTypeHandlers(TypeGraph& typeGraph,
code += R"(
template <typename Ctx, typename T>
types::st::Unit<typename Ctx::DataBuffer>
getSizeType(const T &t, typename TypeHandler<Ctx, T>::type returnArg) {
getSizeType(Ctx& ctx, const T &t, typename TypeHandler<Ctx, T>::type returnArg) {
JLOG("obj @");
JLOGPTR(&t);
return TypeHandler<Ctx, T>::getSizeType(t, returnArg);
return TypeHandler<Ctx, T>::getSizeType(ctx, t, returnArg);
}
)";
@ -1233,6 +1237,13 @@ void CodeGen::generate(
if (config_.features[Feature::CaptureThriftIsset]) {
genDefsThrift(typeGraph, code);
}
if (!config_.features[Feature::TreeBuilderV2]) {
code += "namespace {\n";
code += "static struct Context {\n";
code += " PointerHashSet<> pointers;\n";
code += "} ctx;\n";
code += "} // namespace\n";
}
/*
* The purpose of the anonymous namespace within `OIInternal` is that

View File

@ -262,19 +262,24 @@ void __attribute__((used, retain)) introspect_%2$016x(
std::vector<uint8_t>& v)
#pragma GCC diagnostic pop
{
pointers.initialize();
pointers.add((uintptr_t)&t);
v.clear();
v.reserve(4096);
auto pointers = std::make_unique<PointerHashSet<>>();
pointers->initialize();
struct Context {
using DataBuffer = DataBuffer::BackInserter<std::vector<uint8_t>>;
PointerHashSet<>& pointers;
};
Context ctx{ .pointers = *pointers };
ctx.pointers.add((uintptr_t)&t);
using ContentType = OIInternal::TypeHandler<Context, OIInternal::__ROOT_TYPE__>::type;
ContentType ret{Context::DataBuffer{v}};
OIInternal::getSizeType<Context>(t, ret);
OIInternal::getSizeType<Context>(ctx, t, ret);
}
)";
@ -319,8 +324,8 @@ void FuncGen::DefineTopLevelGetSizeRef(std::string& testCode,
func += " const auto startTime = std::chrono::steady_clock::now();\n";
}
func += R"(
pointers.initialize();
pointers.add((uintptr_t)&t);
ctx.pointers.initialize();
ctx.pointers.add((uintptr_t)&t);
auto data = reinterpret_cast<uintptr_t*>(dataBase);
size_t dataSegOffset = 0;
@ -340,8 +345,8 @@ void FuncGen::DefineTopLevelGetSizeRef(std::string& testCode,
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
writtenSize = dataSegOffset;
dataBase += dataSegOffset;
pointersSize = pointers.size();
pointersCapacity = pointers.capacity();
pointersSize = ctx.pointers.size();
pointersCapacity = ctx.pointers.capacity();
)";
if (features[Feature::JitTiming]) {
func += R"(
@ -421,7 +426,7 @@ void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
func += " const auto startTime = std::chrono::steady_clock::now();\n";
}
func += R"(
pointers.initialize();
ctx.pointers.initialize();
auto data = reinterpret_cast<uintptr_t*>(dataBase);
size_t dataSegOffset = 0;
@ -440,8 +445,8 @@ void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
writtenSize = dataSegOffset;
dataBase += dataSegOffset;
pointersSize = pointers.size();
pointersCapacity = pointers.capacity();
pointersSize = ctx.pointers.size();
pointersCapacity = ctx.pointers.capacity();
)";
if (features[Feature::JitTiming]) {
func += R"(
@ -678,13 +683,14 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
}
code += R"(
static types::st::Unit<DB> getSizeType(
Ctx& ctx,
const T& t,
typename TypeHandler<Ctx, T>::type returnArg) {
if constexpr(std::is_pointer_v<T>) {
JLOG("ptr val @");
JLOGPTR(t);
auto r0 = returnArg.write((uintptr_t)t);
if (t && pointers.add((uintptr_t)t)) {
if (t && ctx.pointers.add((uintptr_t)t)) {
return r0.template delegate<1>([&t](auto ret) {
if constexpr (!std::is_void<std::remove_pointer_t<T>>::value) {
return TypeHandler<Ctx, std::remove_pointer_t<T>>::getSizeType(*t, ret);
@ -727,8 +733,8 @@ ContainerInfo FuncGen::GetOiArrayContainerInfo() {
oiArray.codegen.traversalFunc = R"(
auto tail = returnArg.write(N0);
for (size_t i=0; i<N0; i++) {
tail = tail.delegate([&container, i](auto ret) {
return TypeHandler<Ctx, T0>::getSizeType(container.vals[i], ret);
tail = tail.delegate([&ctx, &container, i](auto ret) {
return TypeHandler<Ctx, T0>::getSizeType(ctx, container.vals[i], ret);
});
}
return tail.finish();

View File

@ -3049,6 +3049,12 @@ bool OICodeGen::generateJitCode(std::string& code) {
#define SAVE_DATA(val) StoreData(val, returnArg)
)");
code.append("namespace {\n");
code.append("static struct Context {\n");
code.append(" PointerHashSet<> pointers;\n");
code.append("} ctx;\n");
code.append("} // namespace\n");
FuncGen::DefineJitLog(code, config.features);
// The purpose of the anonymous namespace within `OIInternal` is that
@ -3267,7 +3273,7 @@ bool OICodeGen::generateJitCode(std::string& code) {
JLOG("ptr val @");
JLOGPTR(s_ptr);
StoreData((uintptr_t)(s_ptr), returnArg);
if (s_ptr && pointers.add((uintptr_t)s_ptr)) {
if (s_ptr && ctx.pointers.add((uintptr_t)s_ptr)) {
StoreData(1, returnArg);
getSizeType(*(s_ptr), returnArg);
} else {

View File

@ -40,10 +40,11 @@ constexpr int oidMagicId = 0x01DE8;
namespace {
class {
template <size_t Size = (1 << 20) / sizeof(uintptr_t)>
class PointerHashSet {
private:
// 1 MiB of pointers
std::array<uintptr_t, (1 << 20) / sizeof(uintptr_t)> data;
std::array<uintptr_t, Size> data;
size_t numEntries;
/*
@ -107,7 +108,7 @@ class {
bool add(const auto* p) {
return add((uintptr_t)p);
}
} static pointers;
};
} // namespace

View File

@ -33,8 +33,8 @@ traversal_func = """
auto tail = returnArg.write(container.size());
for (auto & it: container) {
tail = tail.delegate([&it](auto ret) {
return TypeHandler<Ctx, T0>::getSizeType(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return TypeHandler<Ctx, T0>::getSizeType(ctx, it, ret);
});
}

View File

@ -38,8 +38,8 @@ auto tail = returnArg.write((uintptr_t)&container)
.write(container.size());
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, key, ret);
});
return OIInternal::getSizeType<Ctx>(value, next);
return OIInternal::getSizeType<Ctx>(ctx, value, next);
});
}

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret);
tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
});
}

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, key, ret);
});
return OIInternal::getSizeType<Ctx>(value, next);
return OIInternal::getSizeType<Ctx>(ctx, value, next);
});
}

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret);
tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
});
}

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, key, ret);
});
return OIInternal::getSizeType<Ctx>(value, next);
return OIInternal::getSizeType<Ctx>(ctx, value, next);
});
}

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret);
tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
});
}

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, key, ret);
});
return OIInternal::getSizeType<Ctx>(value, next);
return OIInternal::getSizeType<Ctx>(ctx, value, next);
});
}

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size());
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret);
tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
});
}

View File

@ -29,7 +29,7 @@ void getSizeType(const %1%<E, T, A, Storage> &container, size_t& returnArg)
&&
((uintptr_t)container.data() >= (uintptr_t)&container);
if (!inlined && pointers.add((uintptr_t)container.data())) {
if (!inlined && ctx.pointers.add((uintptr_t)container.data())) {
SAVE_SIZE(container.capacity() * sizeof(T));
SAVE_DATA(1);
} else {
@ -60,7 +60,7 @@ if (isStorageInline(container)) {
category = Category::InlinedStorage;
} else if (capacity < minLargeSize) {
category = Category::OwnedHeapStorage;
} else if (pointers.add(container.data())) {
} else if (ctx.pointers.add(container.data())) {
category = Category::ReferenceCountedStorage;
} else {
category = Category::AlreadyAttributed;

View File

@ -22,7 +22,7 @@ void getSizeType(const %1% &container, size_t& returnArg)
const folly::IOBuf *head = container.front();
SAVE_DATA((uintptr_t)head);
if (head && pointers.add((uintptr_t)head)) {
if (head && ctx.pointers.add((uintptr_t)head)) {
SAVE_DATA(1);
getSizeType(*head, returnArg);
} else {

View File

@ -38,8 +38,8 @@ auto tail = returnArg.write((uintptr_t)&container)
.write(container.size());
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -42,12 +42,12 @@ traversal_func = '''
.write(container.size());
for (const auto& kv : container) {
tail = tail.delegate([&kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(kv.first, ret);
auto next = start.delegate([&kv](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(kv.first, ret);
tail = tail.delegate([&ctx, &kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(ctx, kv.first, ret);
auto next = start.delegate([&ctx, &kv](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, kv.first, ret);
});
return OIInternal::getSizeType<Ctx>(kv.second, next);
return OIInternal::getSizeType<Ctx>(ctx, kv.second, next);
});
}

View File

@ -39,11 +39,11 @@ auto tail = returnArg
.write(container.size());
for (const auto &entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, key, ret);
});
return OIInternal::getSizeType<Ctx>(value, next);
return OIInternal::getSizeType<Ctx>(ctx, value, next);
});
}

View File

@ -42,8 +42,8 @@ auto tail = returnArg.write((uintptr_t)&container)
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -30,8 +30,8 @@ void getSizeType(const %1%<T>& container, size_t& returnArg) {
traversal_func = """
if (container.has_value()) {
return returnArg.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<Ctx>(*container, ret);
return returnArg.template delegate<1>([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, *container, ret);
});
} else {
return returnArg.template delegate<0>(std::identity());

View File

@ -27,10 +27,10 @@ void getSizeType(const %1%<P,Q> &container, size_t& returnArg)
"""
traversal_func = """
return OIInternal::getSizeType<Ctx>(
return OIInternal::getSizeType<Ctx>(ctx,
container.second,
returnArg.delegate([&container](auto ret) {
return OIInternal::getSizeType<Ctx>(container.first, ret);
returnArg.delegate([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, container.first, ret);
})
);
"""

View File

@ -21,7 +21,7 @@ void getSizeType(const %1%<T> &ref, size_t& returnArg)
{
SAVE_SIZE(sizeof(%1%<T>));
SAVE_DATA((uintptr_t)&(ref.get()));
if (pointers.add((uintptr_t)&ref.get())) {
if (ctx.pointers.add((uintptr_t)&ref.get())) {
SAVE_DATA(1);
getSizeType(ref.get(), returnArg);
} else {

View File

@ -43,8 +43,8 @@ auto tail = returnArg.write((uintptr_t)&container)
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -43,8 +43,8 @@ auto tail = returnArg.write((uintptr_t)&container)
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -24,7 +24,7 @@ void getSizeType(const %1%<T> &s_ptr, size_t& returnArg)
if constexpr (!std::is_void<T>::value) {
SAVE_DATA((uintptr_t)(s_ptr.get()));
if (s_ptr && pointers.add((uintptr_t)(s_ptr.get()))) {
if (s_ptr && ctx.pointers.add((uintptr_t)(s_ptr.get()))) {
SAVE_DATA(1);
getSizeType(*(s_ptr.get()), returnArg);
} else {
@ -40,12 +40,12 @@ auto tail = returnArg.write((uintptr_t)container.get());
if constexpr (std::is_void<T0>::value) {
return tail.template delegate<0>(std::identity());
} else {
bool do_visit = container && pointers.add((uintptr_t)container.get());
bool do_visit = container && ctx.pointers.add((uintptr_t)container.get());
if (!do_visit)
return tail.template delegate<0>(std::identity());
return tail.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<Ctx>(*container, ret);
return tail.template delegate<1>([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, *container, ret);
});
}
"""

View File

@ -56,8 +56,8 @@ auto tail = returnArg
.write(container.size());
for (auto &&it: container) {
tail = tail.delegate([&it](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -37,8 +37,8 @@ auto tail = returnArg.write((uintptr_t)&container)
.write(container.size());
for (const auto& el : container) {
tail = tail.delegate([&el](auto ret) {
return OIInternal::getSizeType<Ctx>(el, ret);
tail = tail.delegate([&ctx, &el](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, el, ret);
});
}

View File

@ -43,12 +43,12 @@ auto tail = returnArg
.write(container.size());
for (const auto &entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(key, ret);
auto next = start.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(ctx, key, ret);
auto next = start.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, key, ret);
});
return OIInternal::getSizeType<Ctx>(value, next);
return OIInternal::getSizeType<Ctx>(ctx, value, next);
});
}

View File

@ -46,12 +46,12 @@ auto tail = returnArg
.write(container.size());
for (const auto& kv : container) {
tail = tail.delegate([&kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(kv.first, ret);
auto next = start.delegate([&kv](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(kv.first, ret);
tail = tail.delegate([&ctx, &kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(ctx, kv.first, ret);
auto next = start.delegate([&ctx, &kv](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(ctx, kv.first, ret);
});
return OIInternal::getSizeType<Ctx>(kv.second, next);
return OIInternal::getSizeType<Ctx>(ctx, kv.second, next);
});
}

View File

@ -46,8 +46,8 @@ auto tail = returnArg
.write(container.size());
for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -25,7 +25,7 @@ void getSizeType(const %1%<T,Deleter> &u_ptr, size_t& returnArg)
if constexpr (!std::is_void<T>::value) {
SAVE_DATA((uintptr_t)(u_ptr.get()));
if (u_ptr && pointers.add((uintptr_t)(u_ptr.get()))) {
if (u_ptr && ctx.pointers.add((uintptr_t)(u_ptr.get()))) {
SAVE_DATA(1);
getSizeType(*(u_ptr.get()), returnArg);
} else {
@ -41,12 +41,12 @@ auto tail = returnArg.write((uintptr_t)container.get());
if constexpr (std::is_void<T0>::value) {
return tail.template delegate<0>(std::identity());
} else {
bool do_visit = container && pointers.add((uintptr_t)container.get());
bool do_visit = container && ctx.pointers.add((uintptr_t)container.get());
if (!do_visit)
return tail.template delegate<0>(std::identity());
return tail.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<Ctx>(*container, ret);
return tail.template delegate<1>([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, *container, ret);
});
}
"""

View File

@ -44,8 +44,8 @@ auto tail = returnArg
.write(container.size());
for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}

View File

@ -44,8 +44,8 @@ auto tail = returnArg
.write(container.size());
for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
});
}