Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[P4Testgen] Fix append and prepend invocation. #4306

Merged
merged 2 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions backends/p4tools/common/lib/trace_event_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,28 @@ const Expression *Expression::apply(Transform &visitor) const {
}

const Expression *Expression::evaluate(const Model &model, bool doComplete) const {
if (Taint::hasTaint(value)) {
return new Expression(&Taint::TAINTED_STRING_LITERAL, label);
const IR::Expression *evaluatedValue = nullptr;
if (const auto *structExpr = value->to<IR::StructExpression>()) {
evaluatedValue = model.evaluateStructExpr(structExpr, doComplete);
} else if (const auto *listExpr = value->to<IR::BaseListExpression>()) {
evaluatedValue = model.evaluateListExpr(listExpr, doComplete);
vlstill marked this conversation as resolved.
Show resolved Hide resolved
} else if (Taint::hasTaint(value)) {
evaluatedValue = &Taint::TAINTED_STRING_LITERAL;
} else {
evaluatedValue = model.evaluate(value, doComplete);
}
return new Expression(model.evaluate(value, doComplete), label);
return new Expression(evaluatedValue, label);
}

void Expression::print(std::ostream &os) const {
// Convert the assignment to a string and strip any new lines.
// TODO: Maybe there is a better way to format newlines?
std::stringstream exprStream;
value->dbprint(exprStream);
auto expString = exprStream.str();
expString.erase(std::remove(expString.begin(), expString.end(), '\n'), expString.cend());
Generic::print(os);
os << ": " << formatHexExpr(value, {true});
os << ": " << expString;
}

/* =============================================================================================
Expand Down Expand Up @@ -154,9 +167,9 @@ const AssignmentStatement *AssignmentStatement::apply(Transform &visitor) const
const AssignmentStatement *AssignmentStatement::evaluate(const Model &model,
bool doComplete) const {
const IR::Expression *right = nullptr;
if (auto structExpr = stmt.right->to<IR::StructExpression>()) {
if (const auto *structExpr = stmt.right->to<IR::StructExpression>()) {
right = model.evaluateStructExpr(structExpr, doComplete);
} else if (auto listExpr = stmt.right->to<IR::BaseListExpression>()) {
} else if (const auto *listExpr = stmt.right->to<IR::BaseListExpression>()) {
right = model.evaluateListExpr(listExpr, doComplete);
} else if (Taint::hasTaint(stmt.right)) {
right = &Taint::TAINTED_STRING_LITERAL;
Expand Down
45 changes: 13 additions & 32 deletions backends/p4tools/modules/testgen/core/small_step/extern_stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,29 +164,17 @@ void ExprStepper::evalInternalExternMethodCall(const IR::MethodCallExpression *c
auto &nextState = state.clone();
const auto *prependType = state.resolveType(prependVar->type);

if (prependType->is<IR::Type_StructLike>()) {
auto prependRef = ToolsVariables::convertReference(prependVar);
// We only support flat assignments, so retrieve all fields from the input
// argument.
const auto flatFields = nextState.getFlatFields(prependRef);
// Iterate through the fields in reverse order.
vlstill marked this conversation as resolved.
Show resolved Hide resolved
// We need to append in reverse order since we are prepending to the input
nextState.add(*new TraceEvents::Expression(prependVar, "PrependToProgramHeader"));
// Prepend the field to the packet buffer.
if (const auto *structExpr = prependVar->to<IR::StructExpression>()) {
auto exprList = IR::flattenStructExpression(structExpr);
// We need to prepend in reverse order since we are prepending to the input
// packet.
for (auto fieldIt = flatFields.rbegin(); fieldIt != flatFields.rend(); ++fieldIt) {
const auto &fieldRef = *fieldIt;
// Prepend the field to the packet buffer.
nextState.prependToPacketBuffer(nextState.get(fieldRef));
for (auto fieldIt = exprList.rbegin(); fieldIt != exprList.rend(); ++fieldIt) {
nextState.prependToPacketBuffer(*fieldIt);
}
} else if (prependType->is<IR::Type_Bits>()) {
if (!(prependVar->is<IR::Member>() || prependVar->is<IR::PathExpression>() ||
prependVar->is<IR::TaintExpression>() || prependVar->is<IR::Constant>())) {
TESTGEN_UNIMPLEMENTED("Prepend input %1% of type %2% not supported",
prependVar, prependVar->type);
}
// Prepend the field to the packet buffer.
nextState.add(*new TraceEvents::Expression(prependVar, "PrependToProgramHeader"));
vlstill marked this conversation as resolved.
Show resolved Hide resolved
nextState.prependToPacketBuffer(prependVar);

} else {
TESTGEN_UNIMPLEMENTED("Prepend input %1% of type %2% not supported", prependVar,
prependType);
Expand All @@ -210,21 +198,14 @@ void ExprStepper::evalInternalExternMethodCall(const IR::MethodCallExpression *c
auto &nextState = state.clone();
const auto *appendType = state.resolveType(appendVar->type);

if (appendType->is<IR::Type_StructLike>()) {
auto appendRef = ToolsVariables::convertReference(appendVar);
// We only support flat assignments, so retrieve all fields from the input
// argument.
const auto flatFields = nextState.getFlatFields(appendRef);
for (const auto &fieldRef : flatFields) {
nextState.appendToPacketBuffer(nextState.get(fieldRef));
nextState.add(*new TraceEvents::Expression(appendVar, "AppendToProgramHeader"));
// Append the field to the packet buffer.
if (const auto *structExpr = appendVar->to<IR::StructExpression>()) {
auto exprList = IR::flattenStructExpression(structExpr);
for (const auto *expr : exprList) {
nextState.appendToPacketBuffer(expr);
}
} else if (appendType->is<IR::Type_Bits>()) {
if (!(appendVar->is<IR::Member>() || appendVar->is<IR::PathExpression>() ||
appendVar->is<IR::TaintExpression>() || appendVar->is<IR::Constant>())) {
TESTGEN_UNIMPLEMENTED("append input %1% of type %2% not supported", appendVar,
appendVar->type);
}
nextState.add(*new TraceEvents::Expression(appendVar, "AppendToProgramHeader"));
nextState.appendToPacketBuffer(appendVar);
} else {
TESTGEN_UNIMPLEMENTED("Append input %1% of type %2% not supported", appendVar,
Expand Down
Loading