Skip to content

Commit

Permalink
JSONGenerator/Loader cleanups (#5146)
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Dodd <[email protected]>
  • Loading branch information
ChrisDodd authored Mar 2, 2025
1 parent 3ffac66 commit 79d1a85
Show file tree
Hide file tree
Showing 31 changed files with 525 additions and 487 deletions.
4 changes: 2 additions & 2 deletions backends/bmv2/pna_nic/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ int main(int argc, char *const argv[]) {
}
std::istream inJson(&fb);
JSONLoader jsonFileLoader(inJson);
if (jsonFileLoader.json == nullptr) {
if (!jsonFileLoader) {
::P4::error(ErrorType::ERR_IO, "%s: Not valid input file", options.file);
return 1;
}
Expand All @@ -102,7 +102,7 @@ int main(int argc, char *const argv[]) {
if (::P4::errorCount() > 1 || toplevel == nullptr || toplevel->getMain() == nullptr)
return 1;
if (options.dumpJsonFile.empty())
JSONGenerator(*openFile(options.dumpJsonFile, true), true) << program << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true), true).emit(program);
} catch (const std::exception &bug) {
std::cerr << bug.what() << std::endl;
return 1;
Expand Down
4 changes: 2 additions & 2 deletions backends/bmv2/psa_switch/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ int main(int argc, char *const argv[]) {
}
std::istream inJson(&fb);
JSONLoader jsonFileLoader(inJson);
if (jsonFileLoader.json == nullptr) {
if (!jsonFileLoader) {
::P4::error(ErrorType::ERR_IO, "%s: Not valid input file", options.file);
return 1;
}
Expand All @@ -102,7 +102,7 @@ int main(int argc, char *const argv[]) {
if (::P4::errorCount() > 1 || toplevel == nullptr || toplevel->getMain() == nullptr)
return 1;
if (!options.dumpJsonFile.empty())
JSONGenerator(*openFile(options.dumpJsonFile, true), true) << program << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true), true).emit(program);
} catch (const std::exception &bug) {
std::cerr << bug.what() << std::endl;
return 1;
Expand Down
4 changes: 2 additions & 2 deletions backends/bmv2/simple_switch/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ int main(int argc, char *const argv[]) {
}
std::istream inJson(&fb);
JSONLoader jsonFileLoader(inJson);
if (jsonFileLoader.json == nullptr) {
if (!jsonFileLoader) {
::P4::error(ErrorType::ERR_IO, "%s: Not valid json input file", options.file);
return 1;
}
Expand All @@ -105,7 +105,7 @@ int main(int argc, char *const argv[]) {
if (::P4::errorCount() > 1 || toplevel == nullptr || toplevel->getMain() == nullptr)
return 1;
if (!options.dumpJsonFile.empty() && !options.loadIRFromJson)
JSONGenerator(*openFile(options.dumpJsonFile, true), true) << program << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true), true).emit(program);
} catch (const std::exception &bug) {
std::cerr << bug.what() << std::endl;
return 1;
Expand Down
4 changes: 2 additions & 2 deletions backends/dpdk/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int main(int argc, char *const argv[]) {
}
std::istream inJson(&fb);
JSONLoader jsonFileLoader(inJson);
if (jsonFileLoader.json == nullptr) {
if (!jsonFileLoader) {
::P4::error(ErrorType::ERR_INVALID, "Not valid input file");
return 1;
}
Expand Down Expand Up @@ -136,7 +136,7 @@ int main(int argc, char *const argv[]) {
if (::P4::errorCount() > 1 || toplevel == nullptr || toplevel->getMain() == nullptr)
return 1;
if (!options.dumpJsonFile.empty())
JSONGenerator(*openFile(options.dumpJsonFile, true), true) << program << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true), true).emit(program);
} catch (const std::exception &bug) {
std::cerr << bug.what() << std::endl;
return 1;
Expand Down
4 changes: 2 additions & 2 deletions backends/ebpf/p4c-ebpf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void compile(EbpfOptions &options) {

std::istream inJson(&fb);
JSONLoader jsonFileLoader(inJson);
if (jsonFileLoader.json == nullptr) {
if (!jsonFileLoader) {
::P4::error(ErrorType::ERR_IO, "%s: Not valid input file", options.file);
return;
}
Expand Down Expand Up @@ -84,7 +84,7 @@ void compile(EbpfOptions &options) {
midend.addDebugHook(hook);
auto toplevel = midend.run(options, program);
if (!options.dumpJsonFile.empty())
JSONGenerator(*openFile(options.dumpJsonFile, true)) << program << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true)).emit(program);
if (::P4::errorCount() > 0) return;

EBPF::run_ebpf_backend(options, toplevel, &midend.refMap, &midend.typeMap);
Expand Down
4 changes: 2 additions & 2 deletions backends/graphs/p4c-graphs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ int main(int argc, char *const argv[]) {

std::istream inJson(&fb);
JSONLoader jsonFileLoader(inJson);
if (jsonFileLoader.json == nullptr) {
if (!jsonFileLoader) {
::P4::error(ErrorType::ERR_IO, "Not valid input file");
return 1;
}
Expand Down Expand Up @@ -181,7 +181,7 @@ int main(int argc, char *const argv[]) {
try {
top = midEnd.process(program);
if (!options.dumpJsonFile.empty())
JSONGenerator(*openFile(options.dumpJsonFile, true)) << program << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true)).emit(program);
} catch (const std::exception &bug) {
std::cerr << bug.what() << std::endl;
return 1;
Expand Down
6 changes: 3 additions & 3 deletions backends/p4test/p4test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,17 +185,17 @@ int main(int argc, char *const argv[]) {
}
if (program) {
if (!options.dumpJsonFile.empty())
JSONGenerator(*openFile(options.dumpJsonFile, true), true) << program << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true), true).emit(program);
if (options.debugJson) {
std::stringstream ss1, ss2;
JSONGenerator gen1(ss1), gen2(ss2);
gen1 << program;
gen1.emit(program);

const IR::Node *node = nullptr;
JSONLoader loader(ss1);
loader >> node;

gen2 << node;
gen2.emit(node);
if (ss1.str() != ss2.str()) {
error(ErrorType::ERR_UNEXPECTED, "json mismatch");
std::ofstream t1("t1.json"), t2("t2.json");
Expand Down
18 changes: 7 additions & 11 deletions backends/p4tools/common/core/z3_solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,15 +299,11 @@ const IR::Literal *Z3Solver::toLiteral(const z3::expr &e, const IR::Type *type)
}

void Z3Solver::toJSON(JSONGenerator &json) const {
json << json.indent << "{\n";
json.indent++;
json << json.indent << "\"checkpoints\" : " << checkpoints;
json << ",\n";
json << json.indent << "\"declarations\" : " << declaredVarsById;
json << ",\n";
json << json.indent << "\"assertions\" : " << p4Assertions;
json.indent--;
json << json.indent << "}\n";
auto state = json.begin_object();
json.emit("checkpoints", checkpoints);
json.emit("declarations", declaredVarsById);
json.emit("assertions", p4Assertions);
json.end_object(state);
}

void Z3Solver::addZ3Pushes(size_t &chkIndex, size_t asrtIndex) {
Expand Down Expand Up @@ -344,13 +340,13 @@ Z3Solver::Z3Solver(bool isIncremental, std::optional<std::istream *> inOpt)
JSONLoader loader(*inOpt.value());

JSONLoader solverCheckpoints(loader, "checkpoints");
BUG_CHECK(solverCheckpoints.json->is<JsonVector>(),
BUG_CHECK(solverCheckpoints.is<JsonVector>(),
"Z3 solver loading: can't find list of checkpoint");
solverCheckpoints >> checkpoints;

// loading all assertions
JSONLoader solverAssertions(loader, "assertions");
BUG_CHECK(solverAssertions.json->is<JsonVector>(),
BUG_CHECK(solverAssertions.is<JsonVector>(),
"Z3 solver loading: can't find list of assertions");
safe_vector<const Constraint *> assertions;
solverAssertions >> assertions;
Expand Down
2 changes: 1 addition & 1 deletion backends/tc/tc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ int main(int argc, char *const argv[]) {
return 1;
}
if (!options.dumpJsonFile.empty())
JSONGenerator(*openFile(options.dumpJsonFile, true)) << toplevel << std::endl;
JSONGenerator(*openFile(options.dumpJsonFile, true)).emit(toplevel);
} catch (const Util::P4CExceptionBase &bug) {
std::cerr << bug.what() << std::endl;
return 1;
Expand Down
6 changes: 3 additions & 3 deletions backends/tofino/bf-p4c/ir/arch.def
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ class P4Thread {
const IR::P4Control *mau = nullptr;
const IR::P4Control *deparser = nullptr;
toJSON {
json << json.indent << "\"parsers\" : " << parsers << "," << std::endl
<< json.indent << "\"mau\" : " << mau << "," << std::endl
<< json.indent << "\"deparser\" : " << deparser; }
json.emit("parsers", parsers);
json.emit("mau", mau);
json.emit("deparser", deparser); }
fromJSON {
IR::BFN::P4Thread * thread = new IR::BFN::P4Thread();
json.load("parsers", thread->parsers);
Expand Down
8 changes: 4 additions & 4 deletions backends/tofino/bf-p4c/ir/tofino.def
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ class BFN::Pipe {
hw_constrained_fields == a.hw_constrained_fields;
}
toJSON {
json << json.indent << "\"parser\" : " << parsers << "," << std::endl
<< json.indent << "\"mau\" : " << mau << "," << std::endl
<< json.indent << "\"deparser\" : " << deparser << std::endl
<< json.indent << "\"hw_constrained_fields\" : " << hw_constrained_fields; }
json.emit("parser", parsers);
json.emit("mau", mau);
json.emit("deparser", deparser);
json.emit("hw_constrained_fields", hw_constrained_fields); }
fromJSON {
IR::BFN::Pipe::thread_t * thread = new IR::BFN::Pipe::thread_t();
json.load("parsers", thread->parsers);
Expand Down
11 changes: 6 additions & 5 deletions backends/tofino/bf-p4c/ir/unique_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ static const char *attached_id_to_str[] = {"", "tind", "idletime", "sta
static const char *speciality_to_str[] = {"", "atcam", "dleft"};

void UniqueAttachedId::toJSON(P4::JSONGenerator &json) const {
json << json.indent << "\"name\": " << name << ",\n"
<< json.indent << "\"type\": " << type << ",\n";
json.emit("name", name);
json.emit("type", type);
}

UniqueAttachedId UniqueAttachedId::fromJSON(P4::JSONLoader &json) {
UniqueAttachedId uai;
if (!json.json) return uai;
json.load("name", uai.name);
json.load("type", uai.type);
if (json) {
json.load("name", uai.name);
json.load("type", uai.type);
}
return uai;
}

Expand Down
18 changes: 9 additions & 9 deletions backends/tofino/bf-p4c/mau/hash_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,14 +542,14 @@ bool IR::MAU::HashFunction::convertPolynomialExtern(const IR::GlobalRef *ref) {
}

void IR::MAU::HashFunction::toJSON(JSONGenerator &json) const {
json << json.indent << "\"type\": " << static_cast<int>(type) << ",\n"
<< json.indent << "\"size\": " << size << ",\n"
<< json.indent << "\"msb\": " << msb << ",\n"
<< json.indent << "\"reverse\": " << reverse << ",\n"
<< json.indent << "\"poly\": " << poly << ",\n"
<< json.indent << "\"init\": " << init << ",\n"
<< json.indent << "\"xor\": " << final_xor << ",\n"
<< json.indent << "\"extend\": " << extend;
json.emit("type", static_cast<int>(type));
json.emit("size", size);
json.emit("msb", msb);
json.emit("reverse", reverse);
json.emit("poly", poly);
json.emit("init", init);
json.emit("xor", final_xor);
json.emit("extend", extend);
}

void IR::MAU::HashFunction::build_algorithm_t(bfn_hash_algorithm_ *alg) const {
Expand Down Expand Up @@ -580,7 +580,7 @@ void IR::MAU::HashFunction::build_algorithm_t(bfn_hash_algorithm_ *alg) const {
}

IR::MAU::HashFunction *IR::MAU::HashFunction::fromJSON(JSONLoader &json) {
if (!json.json) return nullptr;
if (!json) return nullptr;
auto *rv = new HashFunction;
int type = 0;
json.load("type", type);
Expand Down
2 changes: 1 addition & 1 deletion backends/tofino/bf-p4c/mau/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct TableResourceAlloc {
meter_format.clear();
meter_xbar.reset();
}
void toJSON(P4::JSONGenerator &json) const { json << "null"; }
void toJSON(P4::JSONGenerator &json) const { json.emit(nullptr); }
static TableResourceAlloc *fromJSON(P4::JSONLoader &) { return nullptr; }

void merge_instr(const TableResourceAlloc *);
Expand Down
2 changes: 1 addition & 1 deletion backends/tofino/bf-p4c/p4c-barefoot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ int main(int ac, char **av) {
// Print out the IR for p4i after frontend (--toJson "-" signifies stdout)
auto &irFile = irFilePath != "-" ? *openFile(irFilePath, false) : std::cout;
LOG3("IR dump after frontend to " << irFilePath);
JSONGenerator(irFile, true) << program << std::endl;
JSONGenerator(irFile, true).emit(program);
}

#if BAREFOOT_INTERNAL
Expand Down
29 changes: 13 additions & 16 deletions backends/tofino/bf-p4c/parde/clot/clot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,20 @@ void Clot::set_slices(cstring parser_state, const std::vector<const PHV::FieldSl
}
}

void Clot::toJSON(JSONGenerator &json) const { json << *this; }
void Clot::toJSON(JSONGenerator &json) const {
json.emit("tag", tag);
json.emit("gress", gress);
json.emit("pov_bit", pov_bit);
json.emit("stack_depth", stack_depth);
json.emit("stack_inc", stack_inc);
}

/* static */ Clot *Clot::fromJSON(JSONLoader &json) {
if (auto *v = json.json->to<JsonString>()) return new Clot(cstring(v->c_str()));
BUG("Couldn't decode JSON value to clot");
return new Clot();
Clot::Clot(JSONLoader &json) {
json.load("tag", tag);
json.load("gress", gress);
json.load("pov_bit", pov_bit);
json.load("stack_depth", stack_depth);
json.load("stack_inc", stack_inc);
}

std::ostream &operator<<(std::ostream &out, const Clot &clot) { return out << "CLOT " << clot.tag; }
Expand All @@ -209,14 +217,3 @@ std::ostream &operator<<(std::ostream &out, const Clot *clot) {
else
return out << "(nullptr)";
}

P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const Clot &clot) {
return out << clot.toString();
}

P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const Clot *clot) {
if (clot)
return out << *clot;
else
return out << "(nullptr)";
}
5 changes: 2 additions & 3 deletions backends/tofino/bf-p4c/parde/clot/clot.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ class Clot final : public LiftCompare<Clot> {

/// JSON serialization/deserialization.
void toJSON(JSONGenerator &json) const;
static Clot *fromJSON(JSONLoader &json);
explicit Clot(JSONLoader &json);
static Clot *fromJSON(JSONLoader &json) { return new Clot(json); }

/// Identifies the hardware CLOT associated with this object.
unsigned tag;
Expand Down Expand Up @@ -185,7 +186,5 @@ class Clot final : public LiftCompare<Clot> {

std::ostream &operator<<(std::ostream &out, const Clot &clot);
std::ostream &operator<<(std::ostream &out, const Clot *clot);
P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const Clot &clot);
P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const Clot *clot);

#endif /* BACKENDS_TOFINO_BF_P4C_PARDE_CLOT_CLOT_H_ */
17 changes: 13 additions & 4 deletions backends/tofino/bf-p4c/parde/marshal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,26 @@
#include "marshal.h"

#include "ir/ir.h"
#include "ir/json_generator.h"
#include "ir/json_loader.h"

std::string MarshaledFrom::toString() const {
std::stringstream tmp;
tmp << *this;
return tmp.str();
}

void MarshaledFrom::toJSON(JSONGenerator &json) const { json << *this; }
void MarshaledFrom::toJSON(JSONGenerator &json) const {
json.emit("gress", gress);
json.emit("field_name", field_name);
json.emit("pre_padding", pre_padding);
}

/* static */
MarshaledFrom MarshaledFrom::fromJSON(JSONLoader &) {
BUG("Uninmplemented");
return MarshaledFrom();
MarshaledFrom MarshaledFrom::fromJSON(JSONLoader &json) {
MarshaledFrom rv;
json.load("gress", rv.gress);
json.load("field_name", rv.field_name);
json.load("pre_padding", rv.pre_padding);
return rv;
}
5 changes: 0 additions & 5 deletions backends/tofino/bf-p4c/parde/marshal.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ inline std::ostream &operator<<(std::ostream &s, const MarshaledFrom &m) {
return s;
}

inline JSONGenerator &operator<<(JSONGenerator &out, const MarshaledFrom &c) {
c.toJSON(out);
return out;
}

} // namespace P4

#endif /* PARDE_MARSHAL_H_ */
8 changes: 2 additions & 6 deletions backends/tofino/bf-p4c/parde/match_register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,11 @@ MatchRegister::MatchRegister(cstring n) : name(n), id(s_id++) {
BUG("Invalid parser match register %s", name);
}

void MatchRegister::toJSON(JSONGenerator &json) const { json << *this; }
void MatchRegister::toJSON(JSONGenerator &json) const { json.emit(toString()); }

/* static */
MatchRegister MatchRegister::fromJSON(JSONLoader &json) {
if (auto *v = json.json->to<JsonString>()) return MatchRegister(cstring(v->c_str()));
if (json.is<JsonString>()) return MatchRegister(json.as<JsonString>());
BUG("Couldn't decode JSON value to parser match register");
return MatchRegister();
}

P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const MatchRegister &c) {
return out << c.toString();
}
Loading

0 comments on commit 79d1a85

Please sign in to comment.