Skip to content

Commit

Permalink
Fix ubpf errors?
Browse files Browse the repository at this point in the history
  • Loading branch information
fruffy committed Apr 29, 2024
1 parent 40c7e7d commit 3c4151c
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 1 deletion.
16 changes: 16 additions & 0 deletions backends/ebpf/ebpfProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,22 @@ void EBPFProgram::emitTypes(CodeBuilder *builder) {
type->emit(builder);
builder->newline();
}
if (const auto *method = d->to<IR::Method>()) {
if (method->srcInfo.isValid()) {
continue;
}
// Ignore methods originating from core.p4 and ubpf_model.p4 because they are already
// defined.
// TODO: Is there a more portable way to do this? Currently we check for a specific
// filename as the source of a method.
auto sourceName = std::filesystem::path(method->srcInfo.getSourceFile().c_str());
if (sourceName.filename() == "core.p4" || sourceName.filename() == "ubpf_model.p4") {
continue;
}
EBPFMethodDeclaration methodInstance(method);
methodInstance.emit(builder);
builder->newline();
}
}
}

Expand Down
54 changes: 53 additions & 1 deletion backends/ebpf/ebpfType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ EBPFType *EBPFTypeFactory::create(const IR::Type *type) {
auto canon = typeMap->getTypeType(type, true);
result = create(canon);
result = new EBPFTypeName(tn, result);
} else if (auto te = type->to<IR::Type_Enum>()) {
} else if (const auto *te = type->to<IR::Type_Enum>()) {
result = new EBPFEnumType(te);
} else if (auto te = type->to<IR::Type_Error>()) {
result = new EBPFErrorType(te);
} else if (auto ts = type->to<IR::Type_Stack>()) {
auto et = create(ts->elementType);
if (et == nullptr) return nullptr;
Expand Down Expand Up @@ -325,4 +327,54 @@ void EBPFEnumType::emit(EBPF::CodeBuilder *builder) {
builder->blockEnd(true);
}

////////////////////////////////////////////////////////////////

void EBPFErrorType::declare(EBPF::CodeBuilder *builder, cstring id, bool asPointer) {
builder->append("enum ");
builder->append(getType()->name);
if (asPointer) builder->append("*");
builder->append(" ");
builder->append(id);
}

void EBPFErrorType::declareInit(CodeBuilder *builder, cstring id, bool asPointer) {
declare(builder, id, asPointer);
}

void EBPFErrorType::emit(EBPF::CodeBuilder *builder) {
builder->append("enum ");
auto et = getType();
builder->append(et->name);
builder->blockStart();
for (auto m : et->members) {
builder->append(m->name);
builder->appendLine(",");
}
builder->blockEnd(true);
}

////////////////////////////////////////////////////////////////

EBPFMethodDeclaration::EBPFMethodDeclaration(const IR::Method *method) : method_(method) {}

void EBPFMethodDeclaration::emit(CodeBuilder *builder) {
auto *returnType = EBPFTypeFactory::instance->create(method_->type->returnType);
returnType->emit(builder);
builder->append(" ");
builder->append(method_->name);
builder->append("(");
for (const auto *parameter : method_->getParameters()->parameters) {
if (parameter->direction == IR::Direction::None ||
parameter->direction == IR::Direction::In) {
builder->append("const ");
}
auto *type = EBPFTypeFactory::instance->create(parameter->type);
type->declare(builder, parameter->name, false);
if (parameter != method_->getParameters()->parameters.back()) {
builder->append(", ");
}
}
builder->append(");");
}

} // namespace EBPF
29 changes: 29 additions & 0 deletions backends/ebpf/ebpfType.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,35 @@ class EBPFEnumType : public EBPFType, public EBPF::IHasWidth {
DECLARE_TYPEINFO(EBPFEnumType, EBPFType, IHasWidth);
};

class EBPFErrorType : public EBPFType, public EBPF::IHasWidth {
public:
explicit EBPFErrorType(const IR::Type_Error *type) : EBPFType(type) {}
void emit(CodeBuilder *builder) override;
void declare(CodeBuilder *builder, cstring id, bool asPointer) override;
void declareInit(CodeBuilder *builder, cstring id, bool asPointer) override;
void emitInitializer(CodeBuilder *builder) override { builder->append("0"); }
unsigned widthInBits() const override { return 32; }
unsigned implementationWidthInBits() const override { return 32; }
const IR::Type_Error *getType() const { return type->to<IR::Type_Error>(); }

DECLARE_TYPEINFO(EBPFErrorType, EBPFType, IHasWidth);
};

/// Methods are function signatures.
class EBPFMethodDeclaration : public EBPFObject {
private:
/// The underlying P4 method of this declaration.
const IR::Method *method_;

public:
explicit EBPFMethodDeclaration(const IR::Method *method);

/// Emit the signature declaration of this method in C-style form.
void emit(CodeBuilder *builder);

DECLARE_TYPEINFO(EBPFMethodDeclaration, EBPFObject);
};

} // namespace EBPF

#endif /* BACKENDS_EBPF_EBPFTYPE_H_ */
16 changes: 16 additions & 0 deletions backends/ubpf/ubpfProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,22 @@ void UBPFProgram::emitTypes(EBPF::CodeBuilder *builder) {
type->emit(builder);
builder->newline();
}
if (const auto *method = d->to<IR::Method>()) {
if (!method->srcInfo.isValid()) {
continue;
}
// Ignore methods originating from core.p4 and ubpf_model.p4 because they are already
// defined.
// TODO: Is there a more portable way to do this? Currently we check for a specific
// filename as the source of a method.
auto sourceName = std::filesystem::path(method->srcInfo.getSourceFile().c_str());
if (sourceName.filename() == "core.p4" || sourceName.filename() == "ubpf_model.p4") {
continue;
}
EBPF::EBPFMethodDeclaration methodInstance(method);
methodInstance.emit(builder);
builder->newline();
}
}
}

Expand Down
18 changes: 18 additions & 0 deletions backends/ubpf/ubpfType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ EBPF::EBPFType *UBPFTypeFactory::create(const IR::Type *type) {
result = new EBPF::EBPFTypeName(tn, result);
} else if (auto te = type->to<IR::Type_Enum>()) {
result = new UBPFEnumType(te);
} else if (auto te = type->to<IR::Type_Error>()) {
result = new UBPFErrorType(te);
} else if (auto ts = type->to<IR::Type_Stack>()) {
auto et = create(ts->elementType);
if (et == nullptr) return nullptr;
Expand Down Expand Up @@ -155,6 +157,7 @@ void UBPFStructType::declare(EBPF::CodeBuilder *builder, cstring id, bool asPoin
void UBPFStructType::declareInit(EBPF::CodeBuilder *builder, cstring id, bool asPointer) {
declare(builder, id, asPointer);
}

//////////////////////////////////////////////////////////

void UBPFEnumType::emit(EBPF::CodeBuilder *builder) {
Expand All @@ -172,6 +175,21 @@ void UBPFEnumType::emit(EBPF::CodeBuilder *builder) {

//////////////////////////////////////////////////////////

void UBPFErrorType::emit(EBPF::CodeBuilder *builder) {
builder->append("enum ");
auto et = getType();
builder->append(et->name);
builder->blockStart();
for (auto m : et->members) {
builder->append(m->name);
builder->appendLine(",");
}
builder->blockEnd(false);
builder->endOfStatement(true);
}

//////////////////////////////////////////////////////////

UBPFListType::UBPFListType(const IR::Type_List *lst) : EBPFType(lst) {
kind = "struct";
width = 0;
Expand Down
23 changes: 23 additions & 0 deletions backends/ubpf/ubpfType.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ class UBPFScalarType : public EBPF::EBPFScalarType {
DECLARE_TYPEINFO(UBPFScalarType, EBPF::EBPFScalarType);
};

class UBPFExternType : public EBPF::EBPFScalarType {
public:
explicit UBPFExternType(const IR::Type_Bits *bits) : EBPF::EBPFScalarType(bits) {}

void emit(EBPF::CodeBuilder *builder) override;

cstring getAsString();

void declare(EBPF::CodeBuilder *builder, cstring id, bool asPointer) override;
void declareInit(EBPF::CodeBuilder *builder, cstring id, bool asPointer) override;

DECLARE_TYPEINFO(UBPFExternType, EBPF::EBPFScalarType);
};

class UBPFStructType : public EBPF::EBPFStructType {
public:
explicit UBPFStructType(const IR::Type_StructLike *strct) : EBPF::EBPFStructType(strct) {}
Expand All @@ -77,6 +91,15 @@ class UBPFEnumType : public EBPF::EBPFEnumType {
DECLARE_TYPEINFO(UBPFEnumType, EBPF::EBPFEnumType);
};

class UBPFErrorType : public EBPF::EBPFErrorType {
public:
explicit UBPFErrorType(const IR::Type_Error *strct) : EBPF::EBPFErrorType(strct) {}

void emit(EBPF::CodeBuilder *builder) override;

DECLARE_TYPEINFO(UBPFErrorType, EBPF::EBPFErrorType);
};

class UBPFListType : public EBPF::EBPFType, public EBPF::IHasWidth {
class UBPFListElement : public ICastable {
public:
Expand Down

0 comments on commit 3c4151c

Please sign in to comment.