oil: change std::stack reference to a std::function (#345)

Summary:

Previously on large types OIL would have problems with corrupting the `std::stack<exporter::inst::Inst>` that is passed to the processors. This change hides the implementation of the stack from the processors by wrapping the call to emplace in a `std::function` written by the non-generated code, which solves the test case I've seen for this crashing. It also allows us to easily change the stack implementation in future - I plan to change it to a `std::stack<T, std::vector<T>>` in a follow up.

Reviewed By: tyroguru

Differential Revision: D49273116
This commit is contained in:
Jake Hillion 2023-09-14 08:09:23 -07:00 committed by Jake Hillion
parent a6d74a20a6
commit d71307cb43
28 changed files with 37 additions and 33 deletions

View File

@ -23,8 +23,8 @@
#include <array>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <stack>
#include <utility>
#include <variant>
@ -34,7 +34,9 @@ struct PopTypePath;
struct Field;
using Inst = std::variant<PopTypePath, std::reference_wrapper<const Field>>;
using Processor = void (*)(result::Element&, std::stack<Inst>&, ParsedData);
using Processor = void (*)(result::Element&,
std::function<void(Inst)>,
ParsedData);
using ProcessorInst = std::pair<types::dy::Dynamic, Processor>;
struct PopTypePath {};

View File

@ -948,7 +948,8 @@ void genContainerTypeHandler(FeatureSet features,
code += " static void processor_";
code += std::to_string(count++);
code +=
"(result::Element& el, std::stack<inst::Inst>& ins, ParsedData d) {\n";
"(result::Element& el, std::function<void(inst::Inst)> stack_ins, "
"ParsedData d) {\n";
code += pr.func; // bad indentation
code += " }\n";
}

View File

@ -726,10 +726,10 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
)";
if (features[Feature::TreeBuilderV2]) {
code += R"(private:
static void process_pointer(result::Element& el, std::stack<inst::Inst>& ins, ParsedData d) {
static void process_pointer(result::Element& el, std::function<void(inst::Inst)> stack_ins, ParsedData d) {
el.pointer = std::get<ParsedData::VarInt>(d.val).value;
}
static void process_pointer_content(result::Element& el, std::stack<inst::Inst>& ins, ParsedData d) {
static void process_pointer_content(result::Element& el, std::function<void(inst::Inst)> stack_ins, ParsedData d) {
static constexpr std::array<std::string_view, 1> names{"TODO"};
static constexpr auto childField = inst::Field{
sizeof(T),
@ -747,7 +747,7 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
return;
el.container_stats->length = 1;
ins.emplace(childField);
stack_ins(childField);
}
static constexpr auto choose_fields() {
@ -862,7 +862,7 @@ el.container_stats.emplace(result::Element::ContainerStats{ .capacity = N0, .len
auto list = std::get<ParsedData::List>(d.val);
// assert(list.length == N0);
for (size_t i = 0; i < N0; i++)
ins.emplace(childField);
stack_ins(childField);
)",
});

View File

@ -62,7 +62,8 @@ IntrospectionResult::const_iterator::operator++() {
for (const auto& [dy, handler] : ty.processors) {
auto parsed = exporters::ParsedData::parse(data_, dy);
handler(*next_, stack_, parsed);
handler(
*next_, [this](auto i) { stack_.emplace(i); }, parsed);
}
for (auto it = ty.fields.rbegin(); it != ty.fields.rend(); ++it) {
stack_.emplace(*it);

View File

@ -71,5 +71,5 @@ size_t size = std::get<ParsedData::List>(d.val).length;
el.exclusive_size = N0 == 0 ? 1 : 0;
el.container_stats.emplace(result::Element::ContainerStats{ .capacity = size, .length = size });
for (size_t i = 0; i < size; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -120,5 +120,5 @@ static constexpr inst::Field element{
};
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -99,5 +99,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
static constexpr auto childField = make_field<DB, T0>("[]");
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -120,5 +120,5 @@ static constexpr inst::Field element{
};
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -99,5 +99,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
static constexpr auto childField = make_field<DB, T0>("[]");
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -120,5 +120,5 @@ static constexpr inst::Field element{
};
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -99,5 +99,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
static constexpr auto childField = make_field<DB, T0>("[]");
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -120,5 +120,5 @@ static constexpr inst::Field element{
};
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -99,5 +99,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
static constexpr auto childField = make_field<DB, T0>("[]");
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -120,5 +120,5 @@ el.container_stats->length = list.length;
el.exclusive_size += (el.container_stats->capacity - el.container_stats->length) * sizeof(element_type);
for (size_t i = 0; i < list.length; i++)
ins.emplace(entry);
stack_ins(entry);
'''

View File

@ -155,5 +155,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
});
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -138,5 +138,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
el.exclusive_size += el.container_stats->length * (element_size - sizeof(T0));
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -81,6 +81,6 @@ el.container_stats = result::Element::ContainerStats {
if (sum.index == 1) {
el.exclusive_size -= sizeof(T0);
ins.emplace(elementField);
stack_ins(elementField);
}
"""

View File

@ -62,6 +62,6 @@ static constexpr auto firstField = make_field<DB, T0>("first");
static constexpr auto secondField = make_field<DB, T1>("second");
el.exclusive_size = sizeof(std::pair<T0, T1>) - sizeof(T0) - sizeof(T1);
ins.emplace(secondField);
ins.emplace(firstField);
stack_ins(secondField);
stack_ins(firstField);
"""

View File

@ -102,5 +102,5 @@ el.container_stats->length = list.length;
el.exclusive_size += (el.container_stats->capacity - el.container_stats->length) * sizeof(T0);
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -142,5 +142,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
el.exclusive_size += el.container_stats->length * (element_size - sizeof(T0));
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -120,7 +120,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
if constexpr (!std::is_void<T0>::value) {
if (sum.index == 1) {
static constexpr auto element = make_field<DB, T0>("ptr_val");
ins.emplace(element);
stack_ins(element);
}
}
"""

View File

@ -126,5 +126,5 @@ if (uses_intern_storage) {
static constexpr auto childField = make_field<DB, T0>("[]");
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -163,5 +163,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
});
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -160,5 +160,5 @@ static constexpr auto element = inst::Field{
};
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -160,5 +160,5 @@ static constexpr auto element = inst::Field{
};
for (size_t i = 0; i < list.length; i++)
ins.emplace(element);
stack_ins(element);
"""

View File

@ -106,7 +106,7 @@ el.container_stats.emplace(result::Element::ContainerStats {
if constexpr (!std::is_void<T0>::value) {
if (sum.index == 1) {
static constexpr auto element = make_field<DB, T0>("ptr_val");
ins.emplace(element);
stack_ins(element);
}
}
"""

View File

@ -133,5 +133,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
static constexpr auto childField = make_field<DB, T0>("[]");
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""

View File

@ -133,5 +133,5 @@ el.container_stats.emplace(result::Element::ContainerStats {
static constexpr auto childField = make_field<DB, T0>("[]");
for (size_t i = 0; i < list.length; i++)
ins.emplace(childField);
stack_ins(childField);
"""