mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-09-19 11:09:05 +01:00
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:
parent
a6d74a20a6
commit
d71307cb43
@ -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 {};
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
)",
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -120,5 +120,5 @@ static constexpr inst::Field element{
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < list.length; i++)
|
||||
ins.emplace(element);
|
||||
stack_ins(element);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -120,5 +120,5 @@ static constexpr inst::Field element{
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < list.length; i++)
|
||||
ins.emplace(element);
|
||||
stack_ins(element);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -120,5 +120,5 @@ static constexpr inst::Field element{
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < list.length; i++)
|
||||
ins.emplace(element);
|
||||
stack_ins(element);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -120,5 +120,5 @@ static constexpr inst::Field element{
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < list.length; i++)
|
||||
ins.emplace(element);
|
||||
stack_ins(element);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
'''
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
}
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
@ -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);
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user