Skip to content

Commit 099be82

Browse files
committed
thrift isset: add type handler
1 parent 8805480 commit 099be82

File tree

4 files changed

+79
-20
lines changed

4 files changed

+79
-20
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ workflows:
2727
- build-gcc
2828
oid_test_args: "-ftyped-data-segment"
2929
tests_regex: "OidIntegration\\..*"
30-
exclude_regex: ".*inheritance_polymorphic.*|.*thrift_.*|.*std_vector_del_allocator_a|.*cycles_.*"
30+
exclude_regex: ".*inheritance_polymorphic.*|.*std_vector_del_allocator_a|.*cycles_.*"
3131
- coverage:
3232
name: coverage
3333
requires:

oi/CodeGen.cpp

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -566,28 +566,74 @@ void addStandardTypeHandlers(std::string& code) {
566566
)";
567567
}
568568

569-
// TODO support thrift isset
570-
void getClassTypeHandler(const Class& c, std::string& code) {
569+
} // namespace
570+
571+
void CodeGen::getClassTypeHandler(const Class& c, std::string& code) {
571572
std::string funcName = "getSizeType";
573+
std::string extras;
574+
575+
const Member* thriftIssetMember = nullptr;
576+
if (const auto it = thriftIssetMembers_.find(&c);
577+
it != thriftIssetMembers_.end()) {
578+
thriftIssetMember = it->second;
579+
580+
extras += "\n using thrift_data = apache::thrift::TStructDataStorage<" +
581+
c.fqName() + ">;";
582+
583+
extras += (boost::format(R"(
584+
static int getThriftIsset(const %1%& t, size_t i) {
585+
if (&thrift_data::isset_indexes == nullptr) return -1;
586+
587+
auto idx = thrift_data::isset_indexes[i];
588+
if (idx == -1) return -1;
589+
590+
return t.%2%.get(idx);
591+
}
592+
)") % c.name() %
593+
thriftIssetMember->name)
594+
.str();
595+
}
596+
597+
size_t lastNonPaddingElement = -1;
598+
for (size_t i = 0; i < c.members.size(); i++) {
599+
const auto& el = c.members[i];
600+
if (!el.name.starts_with(type_graph::AddPadding::MemberPrefix)) {
601+
lastNonPaddingElement = i;
602+
}
603+
}
572604

573605
std::string typeStaticType;
574606
{
575607
size_t pairs = 0;
576608

577-
for (size_t i = 0; i < c.members.size(); i++) {
609+
for (size_t i = 0; i < lastNonPaddingElement + 1; i++) {
578610
const auto& member = c.members[i];
611+
if (member.name.starts_with(type_graph::AddPadding::MemberPrefix)) {
612+
continue;
613+
}
579614

580-
if (i != c.members.size() - 1) {
615+
if (i != lastNonPaddingElement) {
581616
typeStaticType += "types::st::Pair<DB, ";
582617
pairs++;
583618
}
584619

620+
if (thriftIssetMember != nullptr && thriftIssetMember != &member) {
621+
// Return an additional VarInt before every field except for __isset
622+
// itself.
623+
pairs++;
624+
if (i == lastNonPaddingElement) {
625+
typeStaticType += "types::st::Pair<DB, types::st::VarInt<DB>, ";
626+
} else {
627+
typeStaticType += "types::st::VarInt<DB>, types::st::Pair<DB, ";
628+
}
629+
}
630+
585631
typeStaticType +=
586632
(boost::format("typename TypeHandler<DB, decltype(%1%::%2%)>::type") %
587633
c.name() % member.name)
588634
.str();
589635

590-
if (i != c.members.size() - 1) {
636+
if (i != lastNonPaddingElement) {
591637
typeStaticType += ", ";
592638
}
593639
}
@@ -603,10 +649,17 @@ void getClassTypeHandler(const Class& c, std::string& code) {
603649
if (!c.members.empty()) {
604650
traverser = "auto ret = returnArg";
605651
}
606-
for (size_t i = 0; i < c.members.size(); i++) {
652+
for (size_t i = 0; i < lastNonPaddingElement + 1; i++) {
607653
const auto& member = c.members[i];
654+
if (member.name.starts_with(type_graph::AddPadding::MemberPrefix)) {
655+
continue;
656+
}
608657

609-
if (i != c.members.size() - 1) {
658+
if (thriftIssetMember != nullptr && thriftIssetMember != &member) {
659+
traverser += "\n .write(getThriftIsset(t, " + std::to_string(i) + "))";
660+
}
661+
662+
if (i != lastNonPaddingElement) {
610663
traverser += "\n .delegate([&t](auto ret) {";
611664
traverser += "\n return OIInternal::getSizeType<DB>(t." +
612665
member.name + ", ret);";
@@ -625,20 +678,22 @@ void getClassTypeHandler(const Class& c, std::string& code) {
625678

626679
code += (boost::format(R"(
627680
template <typename DB>
628-
class TypeHandler<DB, %1%> {
681+
class TypeHandler<DB, %1%> {%2%
629682
public:
630-
using type = %2%;
631-
static types::st::Unit<DB> %3%(
683+
using type = %3%;
684+
static types::st::Unit<DB> %4%(
632685
const %1%& t,
633686
typename TypeHandler<DB, %1%>::type returnArg) {
634-
%4%
687+
%5%
635688
}
636689
};
637690
)") % c.name() %
638-
typeStaticType % funcName % traverser)
691+
extras % typeStaticType % funcName % traverser)
639692
.str();
640693
}
641694

695+
namespace {
696+
642697
void getContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
643698
const Container& c,
644699
std::string& code) {
@@ -658,19 +713,17 @@ void getContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
658713
code += fmt.str();
659714
}
660715

661-
void addTypeHandlers(
662-
std::unordered_set<const ContainerInfo*>& definedContainers,
663-
const TypeGraph& typeGraph,
664-
std::string& code) {
716+
} // namespace
717+
718+
void CodeGen::addTypeHandlers(const TypeGraph& typeGraph, std::string& code) {
665719
for (const Type& t : typeGraph.finalTypes) {
666720
if (const auto* c = dynamic_cast<const Class*>(&t)) {
667721
getClassTypeHandler(*c, code);
668722
} else if (const auto* con = dynamic_cast<const Container*>(&t)) {
669-
getContainerTypeHandler(definedContainers, *con, code);
723+
getContainerTypeHandler(definedContainers_, *con, code);
670724
}
671725
}
672726
}
673-
} // namespace
674727

675728
bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, std::string& code) {
676729
try {
@@ -787,7 +840,7 @@ void CodeGen::generate(
787840

788841
if (config_.features[Feature::TypedDataSegment]) {
789842
addStandardTypeHandlers(code);
790-
addTypeHandlers(definedContainers_, typeGraph, code);
843+
addTypeHandlers(typeGraph, code);
791844
} else {
792845
addStandardGetSizeFuncDecls(code);
793846
addGetSizeFuncDecls(typeGraph, code);

oi/CodeGen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,7 @@ class CodeGen {
7272
void getClassSizeFuncConcrete(std::string_view funcName,
7373
const type_graph::Class& c,
7474
std::string& code) const;
75+
void addTypeHandlers(const type_graph::TypeGraph& typeGraph,
76+
std::string& code);
77+
void getClassTypeHandler(const type_graph::Class& c, std::string& code);
7578
};

types/thrift_isset_type.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ decl = """
1616
func = """
1717
// DummyFunc %1%
1818
"""
19+
handler = """
20+
// DummyHandler %1%
21+
"""

0 commit comments

Comments
 (0)