thrift isset: add type handler

This commit is contained in:
Jake Hillion 2023-07-03 10:51:25 -07:00 committed by Jake Hillion
parent 8805480653
commit 099be82459
4 changed files with 79 additions and 20 deletions

View File

@ -27,7 +27,7 @@ workflows:
- build-gcc - build-gcc
oid_test_args: "-ftyped-data-segment" oid_test_args: "-ftyped-data-segment"
tests_regex: "OidIntegration\\..*" tests_regex: "OidIntegration\\..*"
exclude_regex: ".*inheritance_polymorphic.*|.*thrift_.*|.*std_vector_del_allocator_a|.*cycles_.*" exclude_regex: ".*inheritance_polymorphic.*|.*std_vector_del_allocator_a|.*cycles_.*"
- coverage: - coverage:
name: coverage name: coverage
requires: requires:

View File

@ -566,28 +566,74 @@ void addStandardTypeHandlers(std::string& code) {
)"; )";
} }
// TODO support thrift isset } // namespace
void getClassTypeHandler(const Class& c, std::string& code) {
void CodeGen::getClassTypeHandler(const Class& c, std::string& code) {
std::string funcName = "getSizeType"; std::string funcName = "getSizeType";
std::string extras;
const Member* thriftIssetMember = nullptr;
if (const auto it = thriftIssetMembers_.find(&c);
it != thriftIssetMembers_.end()) {
thriftIssetMember = it->second;
extras += "\n using thrift_data = apache::thrift::TStructDataStorage<" +
c.fqName() + ">;";
extras += (boost::format(R"(
static int getThriftIsset(const %1%& t, size_t i) {
if (&thrift_data::isset_indexes == nullptr) return -1;
auto idx = thrift_data::isset_indexes[i];
if (idx == -1) return -1;
return t.%2%.get(idx);
}
)") % c.name() %
thriftIssetMember->name)
.str();
}
size_t lastNonPaddingElement = -1;
for (size_t i = 0; i < c.members.size(); i++) {
const auto& el = c.members[i];
if (!el.name.starts_with(type_graph::AddPadding::MemberPrefix)) {
lastNonPaddingElement = i;
}
}
std::string typeStaticType; std::string typeStaticType;
{ {
size_t pairs = 0; size_t pairs = 0;
for (size_t i = 0; i < c.members.size(); i++) { for (size_t i = 0; i < lastNonPaddingElement + 1; i++) {
const auto& member = c.members[i]; const auto& member = c.members[i];
if (member.name.starts_with(type_graph::AddPadding::MemberPrefix)) {
continue;
}
if (i != c.members.size() - 1) { if (i != lastNonPaddingElement) {
typeStaticType += "types::st::Pair<DB, "; typeStaticType += "types::st::Pair<DB, ";
pairs++; pairs++;
} }
if (thriftIssetMember != nullptr && thriftIssetMember != &member) {
// Return an additional VarInt before every field except for __isset
// itself.
pairs++;
if (i == lastNonPaddingElement) {
typeStaticType += "types::st::Pair<DB, types::st::VarInt<DB>, ";
} else {
typeStaticType += "types::st::VarInt<DB>, types::st::Pair<DB, ";
}
}
typeStaticType += typeStaticType +=
(boost::format("typename TypeHandler<DB, decltype(%1%::%2%)>::type") % (boost::format("typename TypeHandler<DB, decltype(%1%::%2%)>::type") %
c.name() % member.name) c.name() % member.name)
.str(); .str();
if (i != c.members.size() - 1) { if (i != lastNonPaddingElement) {
typeStaticType += ", "; typeStaticType += ", ";
} }
} }
@ -603,10 +649,17 @@ void getClassTypeHandler(const Class& c, std::string& code) {
if (!c.members.empty()) { if (!c.members.empty()) {
traverser = "auto ret = returnArg"; traverser = "auto ret = returnArg";
} }
for (size_t i = 0; i < c.members.size(); i++) { for (size_t i = 0; i < lastNonPaddingElement + 1; i++) {
const auto& member = c.members[i]; const auto& member = c.members[i];
if (member.name.starts_with(type_graph::AddPadding::MemberPrefix)) {
continue;
}
if (i != c.members.size() - 1) { if (thriftIssetMember != nullptr && thriftIssetMember != &member) {
traverser += "\n .write(getThriftIsset(t, " + std::to_string(i) + "))";
}
if (i != lastNonPaddingElement) {
traverser += "\n .delegate([&t](auto ret) {"; traverser += "\n .delegate([&t](auto ret) {";
traverser += "\n return OIInternal::getSizeType<DB>(t." + traverser += "\n return OIInternal::getSizeType<DB>(t." +
member.name + ", ret);"; member.name + ", ret);";
@ -625,20 +678,22 @@ void getClassTypeHandler(const Class& c, std::string& code) {
code += (boost::format(R"( code += (boost::format(R"(
template <typename DB> template <typename DB>
class TypeHandler<DB, %1%> { class TypeHandler<DB, %1%> {%2%
public: public:
using type = %2%; using type = %3%;
static types::st::Unit<DB> %3%( static types::st::Unit<DB> %4%(
const %1%& t, const %1%& t,
typename TypeHandler<DB, %1%>::type returnArg) { typename TypeHandler<DB, %1%>::type returnArg) {
%4% %5%
} }
}; };
)") % c.name() % )") % c.name() %
typeStaticType % funcName % traverser) extras % typeStaticType % funcName % traverser)
.str(); .str();
} }
namespace {
void getContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used, void getContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
const Container& c, const Container& c,
std::string& code) { std::string& code) {
@ -658,19 +713,17 @@ void getContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
code += fmt.str(); code += fmt.str();
} }
void addTypeHandlers( } // namespace
std::unordered_set<const ContainerInfo*>& definedContainers,
const TypeGraph& typeGraph, void CodeGen::addTypeHandlers(const TypeGraph& typeGraph, std::string& code) {
std::string& code) {
for (const Type& t : typeGraph.finalTypes) { for (const Type& t : typeGraph.finalTypes) {
if (const auto* c = dynamic_cast<const Class*>(&t)) { if (const auto* c = dynamic_cast<const Class*>(&t)) {
getClassTypeHandler(*c, code); getClassTypeHandler(*c, code);
} else if (const auto* con = dynamic_cast<const Container*>(&t)) { } else if (const auto* con = dynamic_cast<const Container*>(&t)) {
getContainerTypeHandler(definedContainers, *con, code); getContainerTypeHandler(definedContainers_, *con, code);
} }
} }
} }
} // namespace
bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, std::string& code) { bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, std::string& code) {
try { try {
@ -787,7 +840,7 @@ void CodeGen::generate(
if (config_.features[Feature::TypedDataSegment]) { if (config_.features[Feature::TypedDataSegment]) {
addStandardTypeHandlers(code); addStandardTypeHandlers(code);
addTypeHandlers(definedContainers_, typeGraph, code); addTypeHandlers(typeGraph, code);
} else { } else {
addStandardGetSizeFuncDecls(code); addStandardGetSizeFuncDecls(code);
addGetSizeFuncDecls(typeGraph, code); addGetSizeFuncDecls(typeGraph, code);

View File

@ -72,4 +72,7 @@ class CodeGen {
void getClassSizeFuncConcrete(std::string_view funcName, void getClassSizeFuncConcrete(std::string_view funcName,
const type_graph::Class& c, const type_graph::Class& c,
std::string& code) const; std::string& code) const;
void addTypeHandlers(const type_graph::TypeGraph& typeGraph,
std::string& code);
void getClassTypeHandler(const type_graph::Class& c, std::string& code);
}; };

View File

@ -16,3 +16,6 @@ decl = """
func = """ func = """
// DummyFunc %1% // DummyFunc %1%
""" """
handler = """
// DummyHandler %1%
"""