tbv2: replace DB template param with Ctx (#409)

Summary:
tbv2: replace DB template param with Ctx

TreeBuilder v2 adds a DB template parameter to every function. This is used as
part of the static type to decide what type of DataBuffer is being used:
currently `BackInserterDataBuffer<std::vector<uint8_t>>` for OIL and it would
be `DataSegmentDataBuffer` for OID.

This change replaces the `DB` template parameter with a more general `Ctx`. Due
to issues with dependent naming it also adds a `using DB` to each `TypeHandler`
which has the same function as before. This allows us to add more "static
context" (typedefs and constants) to functions without changing this signature
again, because changing the signature of everything is a massive pain.

Currently this change achieves nothing because Ctx contains only DB in a static
wrapper. In the next change I'm going to pass a reference of type Ctx around to
add a "dynamic context" to invocations which will contain the pointer array. In
future we'll then be able to add either static or dynamic context without any
signature adjustments.


Test Plan:
- CI

---
Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebookexperimental/object-introspection/pull/409).
* https://github.com/facebookexperimental/object-introspection/issues/410
* __->__ https://github.com/facebookexperimental/object-introspection/issues/409

Reviewed By: ajor

Differential Revision: D51352092

Pulled By: JakeHillion
This commit is contained in:
Jake Hillion 2023-11-15 11:28:21 -08:00 committed by Facebook Community Bot
parent 02306bf80e
commit 592e182e0f
30 changed files with 200 additions and 187 deletions

View File

@ -651,7 +651,7 @@ void CodeGen::genClassTraversalFunction(const Class& c, std::string& code) {
code += funcName;
code += "(\n const ";
code += c.name();
code += "& t,\n typename TypeHandler<DB, ";
code += "& t,\n typename TypeHandler<Ctx, ";
code += c.name();
code += ">::type returnArg) {\n";
@ -683,7 +683,7 @@ void CodeGen::genClassTraversalFunction(const Class& c, std::string& code) {
} else {
code += "delegate";
}
code += "([&t](auto ret) { return OIInternal::getSizeType<DB>(t.";
code += "([&t](auto ret) { return OIInternal::getSizeType<Ctx>(t.";
code += member.name;
code += ", ret); })";
}
@ -695,7 +695,7 @@ void CodeGen::genClassTraversalFunction(const Class& c, std::string& code) {
}
// Generate the static type for the class's representation in the data buffer.
// For `class { int a,b,c; }` we generate (DB omitted for clarity):
// For `class { int a,b,c; }` we generate (Ctx/DB omitted for clarity):
// Pair<TypeHandler<int>::type,
// Pair<TypeHandler<int>::type,
// TypeHandler<int>::type
@ -734,7 +734,7 @@ void CodeGen::genClassStaticType(const Class& c, std::string& code) {
}
code +=
(boost::format("typename TypeHandler<DB, decltype(%1%::%2%)>::type") %
(boost::format("typename TypeHandler<Ctx, decltype(%1%::%2%)>::type") %
c.name() % member.name)
.str();
@ -787,8 +787,8 @@ void CodeGen::genClassTreeBuilderInstructions(const Class& c,
code += " inst::Field{sizeof(" + fullName + "), " +
std::to_string(calculateExclusiveSize(m.type())) + ",\"" +
m.inputName + "\", member_" + std::to_string(index) +
"_type_names, TypeHandler<DB, decltype(" + fullName +
")>::fields, TypeHandler<DB, decltype(" + fullName +
"_type_names, TypeHandler<Ctx, decltype(" + fullName +
")>::fields, TypeHandler<Ctx, decltype(" + fullName +
")>::processors},\n";
}
code += " };\n";
@ -820,10 +820,11 @@ void CodeGen::genClassTypeHandler(const Class& c, std::string& code) {
.str();
}
code += "template <typename DB>\n";
code += "class TypeHandler<DB, ";
code += "template <typename Ctx>\n";
code += "class TypeHandler<Ctx, ";
code += c.name();
code += "> {\n";
code += " using DB = typename Ctx::DataBuffer;\n";
code += helpers;
code += " public:\n";
code += " using type = ";
@ -877,7 +878,7 @@ void genContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
containerWithTypes = "OICaptureKeys<" + containerWithTypes + ">";
}
code += "template <typename DB";
code += "template <typename Ctx";
types = 0, values = 0;
for (const auto& p : templateParams) {
if (p.value) {
@ -889,9 +890,10 @@ void genContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
}
}
code += ">\n";
code += "struct TypeHandler<DB, ";
code += "struct TypeHandler<Ctx, ";
code += containerWithTypes;
code += "> {\n";
code += " using DB = typename Ctx::DataBuffer;\n";
if (c.captureKeys) {
code += " static constexpr bool captureKeys = true;\n";
@ -922,7 +924,7 @@ void genContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
code += " const ";
code += containerWithTypes;
code += "& container,\n";
code += " typename TypeHandler<DB, ";
code += " typename TypeHandler<Ctx, ";
code += containerWithTypes;
code += ">::type returnArg) {\n";
code += func; // has rubbish indentation
@ -961,8 +963,9 @@ void genContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
void addCaptureKeySupport(std::string& code) {
code += R"(
template <typename DB, typename T>
template <typename Ctx, typename T>
class CaptureKeyHandler {
using DB = typename Ctx::DataBuffer;
public:
using type = types::st::Sum<DB, types::st::VarInt<DB>, types::st::VarInt<DB>>;
@ -975,24 +978,24 @@ void addCaptureKeySupport(std::string& code) {
}
};
template <bool CaptureKeys, typename DB, typename T>
template <bool CaptureKeys, typename Ctx, typename T>
auto maybeCaptureKey(const T& key, auto returnArg) {
if constexpr (CaptureKeys) {
return returnArg.delegate([&key](auto ret) {
return CaptureKeyHandler<DB, T>::captureKey(key, ret);
return CaptureKeyHandler<Ctx, T>::captureKey(key, ret);
});
} else {
return returnArg;
}
}
template <typename DB, typename T>
template <typename Ctx, typename T>
static constexpr inst::ProcessorInst CaptureKeysProcessor{
CaptureKeyHandler<DB, T>::type::describe,
CaptureKeyHandler<Ctx, T>::type::describe,
[](result::Element& el, std::function<void(inst::Inst)> stack_ins, ParsedData d) {
if constexpr (std::is_same_v<
typename CaptureKeyHandler<DB, T>::type,
types::st::List<DB, types::st::VarInt<DB>>>) {
typename CaptureKeyHandler<Ctx, T>::type,
types::st::List<typename Ctx::DataBuffer, types::st::VarInt<typename Ctx::DataBuffer>>>) {
// String
auto& str = el.data.emplace<std::string>();
auto list = std::get<ParsedData::List>(d.val);
@ -1013,11 +1016,11 @@ void addCaptureKeySupport(std::string& code) {
}
};
template <bool CaptureKeys, typename DB, typename T>
template <bool CaptureKeys, typename Ctx, typename T>
static constexpr auto maybeCaptureKeysProcessor() {
if constexpr (CaptureKeys) {
return std::array<inst::ProcessorInst, 1>{
CaptureKeysProcessor<DB, T>,
CaptureKeysProcessor<Ctx, T>,
};
}
else {
@ -1034,28 +1037,28 @@ void addStandardTypeHandlers(TypeGraph& typeGraph,
addCaptureKeySupport(code);
// Provide a wrapper function, getSizeType, to infer T instead of having to
// explicitly specify it with TypeHandler<DB, T>::getSizeType every time.
// explicitly specify it with TypeHandler<Ctx, T>::getSizeType every time.
code += R"(
template <typename DB, typename T>
types::st::Unit<DB>
getSizeType(const T &t, typename TypeHandler<DB, T>::type returnArg) {
template <typename Ctx, typename T>
types::st::Unit<typename Ctx::DataBuffer>
getSizeType(const T &t, typename TypeHandler<Ctx, T>::type returnArg) {
JLOG("obj @");
JLOGPTR(&t);
return TypeHandler<DB, T>::getSizeType(t, returnArg);
return TypeHandler<Ctx, T>::getSizeType(t, returnArg);
}
)";
if (features[Feature::TreeBuilderV2]) {
code += R"(
template <typename DB, typename T>
template <typename Ctx, typename T>
constexpr inst::Field make_field(std::string_view name) {
return inst::Field{
sizeof(T),
ExclusiveSizeProvider<T>::size,
name,
NameProvider<T>::names,
TypeHandler<DB, T>::fields,
TypeHandler<DB, T>::processors,
TypeHandler<Ctx, T>::fields,
TypeHandler<Ctx, T>::processors,
};
}
)";

View File

@ -268,11 +268,13 @@ void __attribute__((used, retain)) introspect_%2$016x(
v.clear();
v.reserve(4096);
using DataBufferType = DataBuffer::BackInserter<std::vector<uint8_t>>;
using ContentType = OIInternal::TypeHandler<DataBufferType, OIInternal::__ROOT_TYPE__>::type;
struct Context {
using DataBuffer = DataBuffer::BackInserter<std::vector<uint8_t>>;
};
using ContentType = OIInternal::TypeHandler<Context, OIInternal::__ROOT_TYPE__>::type;
ContentType ret{DataBufferType{v}};
OIInternal::getSizeType<DataBufferType>(t, ret);
ContentType ret{Context::DataBuffer{v}};
OIInternal::getSizeType<Context>(t, ret);
}
)";
@ -368,6 +370,9 @@ void FuncGen::DefineTreeBuilderInstructions(
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-attributes"
namespace {
struct FakeContext {
using DataBuffer = int;
};
const std::array<std::string_view, )";
code += std::to_string(typeNames.size());
code += "> typeNames";
@ -386,8 +391,10 @@ const std::array<std::string_view, )";
code += ", \"a0\", typeNames";
code += typeHash;
code +=
", OIInternal::TypeHandler<int, OIInternal::__ROOT_TYPE__>::fields, "
"OIInternal::TypeHandler<int, OIInternal::__ROOT_TYPE__>::processors};\n";
", OIInternal::TypeHandler<FakeContext, "
"OIInternal::__ROOT_TYPE__>::fields, "
"OIInternal::TypeHandler<FakeContext, "
"OIInternal::__ROOT_TYPE__>::processors};\n";
code += "} // namespace\n";
code +=
"extern const exporters::inst::Inst __attribute__((used, retain)) "
@ -603,14 +610,15 @@ class BackInserter {
*/
void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
code += R"(
template <typename DB, typename T>
template <typename Ctx, typename T>
struct TypeHandler {
using DB = typename Ctx::DataBuffer;
private:
static auto choose_type() {
if constexpr(std::is_pointer_v<T>) {
return std::type_identity<types::st::Pair<DB,
types::st::VarInt<DB>,
types::st::Sum<DB, types::st::Unit<DB>, typename TypeHandler<DB, std::remove_pointer_t<T>>::type>
types::st::Sum<DB, types::st::Unit<DB>, typename TypeHandler<Ctx, std::remove_pointer_t<T>>::type>
>>();
} else {
return std::type_identity<types::st::Unit<DB>>();
@ -631,8 +639,8 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
sizeof(T),
"*",
names,
TypeHandler<DB, T>::fields,
TypeHandler<DB, T>::processors,
TypeHandler<Ctx, T>::fields,
TypeHandler<Ctx, T>::processors,
};
const ParsedData::Sum& sum = std::get<ParsedData::Sum>(d.val);
@ -657,7 +665,7 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
if constexpr(std::is_pointer_v<T>) {
return std::array<inst::ProcessorInst, 2>{
{types::st::VarInt<DB>::describe, &process_pointer},
{types::st::Sum<DB, types::st::Unit<DB>, typename TypeHandler<DB, std::remove_pointer_t<T>>::type>::describe, &process_pointer_content},
{types::st::Sum<DB, types::st::Unit<DB>, typename TypeHandler<Ctx, std::remove_pointer_t<T>>::type>::describe, &process_pointer_content},
};
} else {
return std::array<inst::ProcessorInst, 0>{};
@ -671,7 +679,7 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
code += R"(
static types::st::Unit<DB> getSizeType(
const T& t,
typename TypeHandler<DB, T>::type returnArg) {
typename TypeHandler<Ctx, T>::type returnArg) {
if constexpr(std::is_pointer_v<T>) {
JLOG("ptr val @");
JLOGPTR(t);
@ -679,7 +687,7 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
if (t && 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<DB, std::remove_pointer_t<T>>::getSizeType(*t, ret);
return TypeHandler<Ctx, std::remove_pointer_t<T>>::getSizeType(*t, ret);
} else {
return ret;
}
@ -695,8 +703,9 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
)";
code += R"(
template <typename DB>
class TypeHandler<DB, void> {
template <typename Ctx>
class TypeHandler<Ctx, void> {
using DB = typename Ctx::DataBuffer;
public:
using type = types::st::Unit<DB>;
)";
@ -719,21 +728,21 @@ ContainerInfo FuncGen::GetOiArrayContainerInfo() {
auto tail = returnArg.write(N0);
for (size_t i=0; i<N0; i++) {
tail = tail.delegate([&container, i](auto ret) {
return TypeHandler<DB, T0>::getSizeType(container.vals[i], ret);
return TypeHandler<Ctx, T0>::getSizeType(container.vals[i], ret);
});
}
return tail.finish();
)";
oiArray.codegen.processors.emplace_back(ContainerInfo::Processor{
.type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>",
.type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>",
.func = R"(
static constexpr std::array<std::string_view, 1> names{"TODO"};
static constexpr auto childField = inst::Field{
sizeof(T0),
"[]",
names,
TypeHandler<DB, T0>::fields,
TypeHandler<DB, T0>::processors,
TypeHandler<Ctx, T0>::fields,
TypeHandler<Ctx, T0>::processors,
};
el.exclusive_size = 0;

View File

@ -34,7 +34,7 @@ traversal_func = """
for (auto & it: container) {
tail = tail.delegate([&it](auto ret) {
return TypeHandler<DB, T0>::getSizeType(it, ret);
return TypeHandler<Ctx, T0>::getSizeType(it, ret);
});
}
@ -42,9 +42,9 @@ traversal_func = """
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
size_t size = std::get<ParsedData::List>(d.val).length;
el.exclusive_size = N0 == 0 ? 1 : 0;

View File

@ -39,7 +39,7 @@ auto tail = returnArg.write((uintptr_t)&container)
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -53,7 +53,7 @@ el.pointer = std::get<ParsedData::VarInt>(d.val).value;
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
#ifdef __GLIBCXX__
static constexpr size_t element_size = sizeof(std::_List_node<T0>);
@ -62,7 +62,7 @@ static_assert(false && "No known element_size for list. See types/cxx11_list_typ
#endif
static constexpr std::array<inst::Field, 1> child_field{
make_field<DB, T0>("*"),
make_field<Ctx, T0>("*"),
};
static constexpr inst::Field element{
element_size,
@ -72,7 +72,7 @@ static constexpr inst::Field element{
child_field,
std::array<inst::ProcessorInst, 0>{},
};
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
auto list = std::get<ParsedData::List>(d.val);
el.container_stats.emplace(result::Element::ContainerStats{

View File

@ -37,8 +37,9 @@ void getSizeType(const %1%<T, Traits, Allocator> &container, size_t& returnArg)
"""
extra = """
template <typename DB, typename CharT, typename Traits, typename Allocator>
class CaptureKeyHandler<DB, std::__cxx11::basic_string<CharT, Traits, Allocator>> {
template <typename Ctx, typename CharT, typename Traits, typename Allocator>
class CaptureKeyHandler<Ctx, std::__cxx11::basic_string<CharT, Traits, Allocator>> {
using DB = typename Ctx::DataBuffer;
public:
// List of characters
using type = types::st::List<DB, types::st::VarInt<DB>>;

View File

@ -44,10 +44,10 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(key, ret);
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
});
return OIInternal::getSizeType<DB>(value, next);
return OIInternal::getSizeType<Ctx>(value, next);
});
}
@ -69,8 +69,8 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
"""
func = """
static constexpr size_t element_size = sizeof(typename container_type::value_type);
@ -84,8 +84,8 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * element_size;
static constexpr std::array<inst::Field, 2> element_fields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr inst::Field element{

View File

@ -43,7 +43,7 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<DB>(entry, ret);
return OIInternal::getSizeType<Ctx>(entry, ret);
});
}
@ -64,7 +64,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, typename TypeHandler<DB, T0>::type>
types::st::List<DB, typename TypeHandler<Ctx, T0>::type>
"""
func = """
auto allocationSize = el.pointer.value();
@ -75,7 +75,7 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * sizeof(T0);
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""

View File

@ -44,10 +44,10 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(key, ret);
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
});
return OIInternal::getSizeType<DB>(value, next);
return OIInternal::getSizeType<Ctx>(value, next);
});
}
@ -69,8 +69,8 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
"""
func = """
static constexpr size_t element_size = sizeof(typename container_type::value_type);
@ -84,8 +84,8 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * element_size;
static constexpr std::array<inst::Field, 2> element_fields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr inst::Field element{

View File

@ -43,7 +43,7 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<DB>(entry, ret);
return OIInternal::getSizeType<Ctx>(entry, ret);
});
}
@ -64,7 +64,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, typename TypeHandler<DB, T0>::type>
types::st::List<DB, typename TypeHandler<Ctx, T0>::type>
"""
func = """
auto allocationSize = el.pointer.value();
@ -75,7 +75,7 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * sizeof(T0);
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""

View File

@ -44,10 +44,10 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(key, ret);
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
});
return OIInternal::getSizeType<DB>(value, next);
return OIInternal::getSizeType<Ctx>(value, next);
});
}
@ -69,8 +69,8 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
"""
func = """
static constexpr size_t element_size = sizeof(typename container_type::value_type);
@ -84,8 +84,8 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * element_size;
static constexpr std::array<inst::Field, 2> element_fields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr inst::Field element{

View File

@ -43,7 +43,7 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<DB>(entry, ret);
return OIInternal::getSizeType<Ctx>(entry, ret);
});
}
@ -64,7 +64,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, typename TypeHandler<DB, T0>::type>
types::st::List<DB, typename TypeHandler<Ctx, T0>::type>
"""
func = """
auto allocationSize = el.pointer.value();
@ -75,7 +75,7 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * sizeof(T0);
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""

View File

@ -44,10 +44,10 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(key, ret);
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
});
return OIInternal::getSizeType<DB>(value, next);
return OIInternal::getSizeType<Ctx>(value, next);
});
}
@ -69,8 +69,8 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
"""
func = """
static constexpr size_t element_size = sizeof(typename container_type::value_type);
@ -84,8 +84,8 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * element_size;
static constexpr std::array<inst::Field, 2> element_fields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr inst::Field element{

View File

@ -43,7 +43,7 @@ auto tail = returnArg
for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) {
return OIInternal::getSizeType<DB>(entry, ret);
return OIInternal::getSizeType<Ctx>(entry, ret);
});
}
@ -64,7 +64,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, typename TypeHandler<DB, T0>::type>
types::st::List<DB, typename TypeHandler<Ctx, T0>::type>
"""
func = """
auto allocationSize = el.pointer.value();
@ -75,7 +75,7 @@ el.container_stats->length = list.length;
el.exclusive_size += allocationSize - list.length * sizeof(T0);
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""

View File

@ -39,7 +39,7 @@ auto tail = returnArg.write((uintptr_t)&container)
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -53,7 +53,7 @@ el.pointer = std::get<ParsedData::VarInt>(d.val).value;
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
#ifdef __GLIBCXX__
static constexpr size_t element_size = sizeof(std::_List_node<T0>);
@ -62,7 +62,7 @@ static_assert(false && "No known element_size for list. See types/cxx11_list_typ
#endif
static constexpr std::array<inst::Field, 1> child_field{
make_field<DB, T0>("*"),
make_field<Ctx, T0>("*"),
};
static constexpr inst::Field element{
element_size,
@ -72,7 +72,7 @@ static constexpr inst::Field element{
child_field,
std::array<inst::ProcessorInst, 0>{},
};
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
auto list = std::get<ParsedData::List>(d.val);
el.container_stats.emplace(result::Element::ContainerStats{

View File

@ -43,11 +43,11 @@ traversal_func = '''
for (const auto& kv : container) {
tail = tail.delegate([&kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, DB, T0>(kv.first, ret);
auto next = start.delegate([&kv](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(kv.first, 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);
});
return OIInternal::getSizeType<DB>(kv.second, next);
return OIInternal::getSizeType<Ctx>(kv.second, next);
});
}
@ -68,22 +68,22 @@ el.container_stats.emplace(result::Element::ContainerStats{ .capacity = std::get
type = '''
std::conditional_t<captureKeys,
types::st::List<DB, types::st::Pair<DB,
typename CaptureKeyHandler<DB, T0>::type,
typename CaptureKeyHandler<Ctx, T0>::type,
types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>>,
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>>,
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>>
'''
func = '''
using element_type = std::pair<T0, T1>;
static constexpr std::array<inst::Field, 2> entryFields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, DB, T0>();
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, Ctx, T0>();
static constexpr auto entry = inst::Field {
sizeof(element_type),
sizeof(element_type) - sizeof(T0) - sizeof(T1),

View File

@ -40,10 +40,10 @@ auto tail = returnArg
for (const auto &entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(key, ret);
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret);
});
return OIInternal::getSizeType<DB>(value, next);
return OIInternal::getSizeType<Ctx>(value, next);
});
}
@ -57,8 +57,8 @@ func = "el.pointer = std::get<ParsedData::VarInt>(d.val).value;"
[[codegen.processor]]
type = """
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
"""
func = """
#ifdef __GLIBCXX__
@ -108,8 +108,8 @@ static_assert(false && "No known element_size for sets. See types/multi_map_type
#endif
static constexpr std::array<inst::Field, 2> elementFields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr auto element = inst::Field {
element_size,

View File

@ -43,7 +43,7 @@ auto tail = returnArg.write((uintptr_t)&container)
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -57,7 +57,7 @@ el.pointer = std::get<ParsedData::VarInt>(d.val).value;
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
#ifdef __GLIBCXX__
/* We don't have access to the _Rb_tree_node struct, so we manually re-create it
@ -103,7 +103,7 @@ static constexpr size_t element_size = sizeof(OI__tree_node);
static_assert(false && "No known element_size for multisets. See types/multi_set_type.toml");
#endif
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
auto list = std::get<ParsedData::List>(d.val);
el.container_stats.emplace(result::Element::ContainerStats {

View File

@ -31,7 +31,7 @@ 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<DB>(*container, ret);
return OIInternal::getSizeType<Ctx>(*container, ret);
});
} else {
return returnArg.template delegate<0>(std::identity());
@ -39,15 +39,15 @@ if (container.has_value()) {
"""
[[codegen.processor]]
type = "types::st::Sum<DB, types::st::Unit<DB>, typename TypeHandler<DB, T0>::type>"
type = "types::st::Sum<DB, types::st::Unit<DB>, typename TypeHandler<Ctx, T0>::type>"
func = """
static constexpr std::array<std::string_view, 1> names{"TODO"};
static constexpr auto elementField = inst::Field{
sizeof(T0),
"el",
names,
TypeHandler<DB, T0>::fields,
TypeHandler<DB, T0>::processors,
TypeHandler<Ctx, T0>::fields,
TypeHandler<Ctx, T0>::processors,
};
auto sum = std::get<ParsedData::Sum>(d.val);

View File

@ -27,19 +27,19 @@ void getSizeType(const %1%<P,Q> &container, size_t& returnArg)
"""
traversal_func = """
return OIInternal::getSizeType<DB>(
return OIInternal::getSizeType<Ctx>(
container.second,
returnArg.delegate([&container](auto ret) {
return OIInternal::getSizeType<DB>(container.first, ret);
return OIInternal::getSizeType<Ctx>(container.first, ret);
})
);
"""
[[codegen.processor]]
type = "types::st::Pair<DB, typename TypeHandler<DB, T0>::type, typename TypeHandler<DB, T1>::type>"
type = "types::st::Pair<DB, typename TypeHandler<Ctx, T0>::type, typename TypeHandler<Ctx, T1>::type>"
func = """
static constexpr auto firstField = make_field<DB, T0>("first");
static constexpr auto secondField = make_field<DB, T1>("second");
static constexpr auto firstField = make_field<Ctx, T0>("first");
static constexpr auto secondField = make_field<Ctx, T1>("second");
el.exclusive_size = sizeof(std::pair<T0, T1>) - sizeof(T0) - sizeof(T1);
stack_ins(secondField);

View File

@ -44,7 +44,7 @@ auto tail = returnArg.write((uintptr_t)&container)
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -64,9 +64,9 @@ el.container_stats.emplace(result::Element::ContainerStats{ .capacity = std::get
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
auto list = std::get<ParsedData::List>(d.val);
el.container_stats->length = list.length;

View File

@ -44,7 +44,7 @@ auto tail = returnArg.write((uintptr_t)&container)
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -58,7 +58,7 @@ el.pointer = std::get<ParsedData::VarInt>(d.val).value;
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
#ifdef __GLIBCXX__
/* We don't have access to the _Rb_tree_node struct, so we manually re-create it
@ -104,7 +104,7 @@ static constexpr size_t element_size = sizeof(OI__tree_node);
static_assert(false && "No known element_size for sets. See types/set_type.toml");
#endif
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
auto list = std::get<ParsedData::List>(d.val);
el.container_stats.emplace(result::Element::ContainerStats {

View File

@ -45,7 +45,7 @@ if constexpr (std::is_void<T0>::value) {
return tail.template delegate<0>(std::identity());
return tail.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<DB>(*container, ret);
return OIInternal::getSizeType<Ctx>(*container, ret);
});
}
"""
@ -60,7 +60,7 @@ el.pointer = std::get<ParsedData::VarInt>(d.val).value;
type = """
types::st::Sum<DB,
types::st::Unit<DB>,
typename TypeHandler<DB, T0>::type>
typename TypeHandler<Ctx, T0>::type>
"""
func = """
#ifdef __GLIBCXX__
@ -84,10 +84,10 @@ el.container_stats.emplace(result::Element::ContainerStats {
.length = sum.index, // 0 for empty containers/void, 1 otherwise
});
// Must be in a `if constexpr` or the compiler will complain about make_field<DB, void>
// Must be in a `if constexpr` or the compiler will complain about make_field<Ctx, void>
if constexpr (!std::is_void<T0>::value) {
if (sum.index == 1) {
static constexpr auto element = make_field<DB, T0>("ptr_val");
static constexpr auto element = make_field<Ctx, T0>("ptr_val");
stack_ins(element);
}
}

View File

@ -56,8 +56,8 @@ auto tail = returnArg
.write(container.size());
for (auto &&it: container) {
tail = tail.delegate([&it](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(it, ret);
tail = tail.delegate([&it](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -81,7 +81,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
// Reading the `uses_intern_storage` boolean that was stored in `pointer` by the processor above.
bool uses_intern_storage = std::exchange(el.pointer.value(), (uintptr_t)0);
@ -97,7 +97,7 @@ if (uses_intern_storage) {
el.exclusive_size += (el.container_stats->capacity - el.container_stats->length) * sizeof(T0);
}
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""

View File

@ -38,7 +38,7 @@ auto tail = returnArg.write((uintptr_t)&container)
for (const auto& el : container) {
tail = tail.delegate([&el](auto ret) {
return OIInternal::getSizeType<DB>(el, ret);
return OIInternal::getSizeType<Ctx>(el, ret);
});
}
@ -56,9 +56,9 @@ el.container_stats.emplace(result::Element::ContainerStats{ .capacity = std::get
'''
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
auto list = std::get<ParsedData::List>(d.val);
el.container_stats->length = list.length;

View File

@ -44,11 +44,11 @@ auto tail = returnArg
for (const auto &entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
auto start = maybeCaptureKey<captureKeys, DB, T0>(key, ret);
auto next = start.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(key, 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);
});
return OIInternal::getSizeType<DB>(value, next);
return OIInternal::getSizeType<Ctx>(value, next);
});
}
@ -64,14 +64,14 @@ type = """
std::conditional_t<captureKeys,
types::st::List<DB,
types::st::Pair<DB,
typename CaptureKeyHandler<DB, T0>::type,
typename CaptureKeyHandler<Ctx, T0>::type,
types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>>,
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>>,
types::st::List<DB,
types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
>
"""
func = """
@ -122,11 +122,11 @@ static_assert(false && "No known element_size for sets. See types/std_map_type.t
#endif
static constexpr std::array<inst::Field, 2> element_fields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, DB, T0>();
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, Ctx, T0>();
static constexpr inst::Field element{
element_size,

View File

@ -47,11 +47,11 @@ auto tail = returnArg
for (const auto& kv : container) {
tail = tail.delegate([&kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, DB, T0>(kv.first, ret);
auto next = start.delegate([&kv](typename TypeHandler<DB, T0>::type ret) {
return OIInternal::getSizeType<DB>(kv.first, 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);
});
return OIInternal::getSizeType<DB>(kv.second, next);
return OIInternal::getSizeType<Ctx>(kv.second, next);
});
}
@ -79,13 +79,13 @@ type = """
std::conditional_t<captureKeys,
types::st::List<DB,
types::st::Pair<DB,
typename CaptureKeyHandler<DB, T0>::type,
typename CaptureKeyHandler<Ctx, T0>::type,
types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>>,
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>>,
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
>
"""
func = """
@ -122,11 +122,11 @@ el.container_stats.emplace(result::Element::ContainerStats {
});
static constexpr std::array<inst::Field, 2> element_fields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, DB, T0>();
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, Ctx, T0>();
static constexpr auto element = inst::Field{
element_size,

View File

@ -47,7 +47,7 @@ auto tail = returnArg
for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -73,8 +73,8 @@ el.container_stats.emplace(result::Element::ContainerStats {
[[codegen.processor]]
type = """
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>>
typename TypeHandler<Ctx, T0>::type,
typename TypeHandler<Ctx, T1>::type>>
"""
func = """
#ifdef __GLIBCXX__
@ -110,8 +110,8 @@ el.container_stats.emplace(result::Element::ContainerStats {
});
static constexpr std::array<inst::Field, 2> element_fields{
make_field<DB, T0>("key"),
make_field<DB, T1>("value"),
make_field<Ctx, T0>("key"),
make_field<Ctx, T1>("value"),
};
static constexpr auto element = inst::Field{

View File

@ -46,7 +46,7 @@ if constexpr (std::is_void<T0>::value) {
return tail.template delegate<0>(std::identity());
return tail.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<DB>(*container, ret);
return OIInternal::getSizeType<Ctx>(*container, ret);
});
}
"""
@ -61,7 +61,7 @@ el.pointer = std::get<ParsedData::VarInt>(d.val).value;
type = """
types::st::Sum<DB,
types::st::Unit<DB>,
typename TypeHandler<DB, T0>::type>
typename TypeHandler<Ctx, T0>::type>
"""
func = """
auto sum = std::get<ParsedData::Sum>(d.val);
@ -70,10 +70,10 @@ el.container_stats.emplace(result::Element::ContainerStats {
.length = sum.index, // 0 for empty containers/void, 1 otherwise
});
// Must be in a `if constexpr` or the compiler will complain about make_field<DB, void>
// Must be in a `if constexpr` or the compiler will complain about make_field<Ctx, void>
if constexpr (!std::is_void<T0>::value) {
if (sum.index == 1) {
static constexpr auto element = make_field<DB, T0>("ptr_val");
static constexpr auto element = make_field<Ctx, T0>("ptr_val");
stack_ins(element);
}
}

View File

@ -45,7 +45,7 @@ auto tail = returnArg
for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -69,7 +69,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
#ifdef __GLIBCXX__
/* Use libstdc++ implementation __details to compute the size of Nodes and Buckets.
@ -100,7 +100,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
.length = list.length,
});
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""

View File

@ -45,7 +45,7 @@ auto tail = returnArg
for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
return OIInternal::getSizeType<Ctx>(it, ret);
});
}
@ -69,7 +69,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
"""
[[codegen.processor]]
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
#ifdef __GLIBCXX__
/* Use libstdc++ implementation __details to compute the size of Nodes and Buckets.
@ -100,7 +100,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
.length = list.length,
});
static constexpr auto childField = make_field<DB, T0>("[]");
static constexpr auto childField = make_field<Ctx, T0>("[]");
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""