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

Test plan:
- CI
This commit is contained in:
Jake Hillion 2023-11-15 06:14:52 -08:00
parent ba79e50fb4
commit 143805dfe2
34 changed files with 127 additions and 103 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<(1 << 20) / sizeof(uintptr_t)> 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<(1 << 20) / sizeof(uintptr_t)>>();
pointers->initialize();
struct Context {
using DataBuffer = DataBuffer::BackInserter<std::vector<uint8_t>>;
PointerHashSet<(1 << 20) / sizeof(uintptr_t)>& 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;
@ -417,7 +422,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;
@ -670,13 +675,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);
@ -719,8 +725,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<(1 << 20) / sizeof(uintptr_t)> 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>
class PointerHashSet {
private:
// 1 MiB of pointers
std::array<uintptr_t, (1 << 20) / sizeof(uintptr_t)> data;
std::array<uintptr_t, Size> data;
// twang_mix64 hash function, taken from Folly where it is used
// as the default hash function for 64-bit integers
@ -84,7 +85,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);
});
}