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

Fix for Issue #8, pkt.rewrite_field #9

Merged
merged 1 commit into from
May 7, 2015
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
Fix for Issue #8, pkt.rewrite_field
* This was unintentionally removed in the last cleanup, adding it back.
* Also adding support for $ip.dst = XXX style syntax
* This is an ugly commit, please bear with it until I figure out the
  structure of the language, especially w.r.t. proto:: type fields.

Signed-off-by: Brenden Blanco <[email protected]>
  • Loading branch information
Brenden Blanco committed May 7, 2015
commit 44b93de0816932a09c185009cc43fce4401a3b99
79 changes: 46 additions & 33 deletions src/cc/codegen_llvm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -315,30 +315,34 @@ StatusTuple CodegenLLVM::visit_ident_expr_node(IdentExprNode *n) {

StatusTuple CodegenLLVM::visit_assign_expr_node(AssignExprNode *n) {
if (n->bitop_) {
TRY2(n->id_->accept(this));
TRY2(n->lhs_->accept(this));
emit(" = (");
TRY2(n->id_->accept(this));
emit(" & ~((((%s)1 << %d) - 1) << %d)) | (", bits_to_uint(n->id_->bit_width_),
TRY2(n->lhs_->accept(this));
emit(" & ~((((%s)1 << %d) - 1) << %d)) | (", bits_to_uint(n->lhs_->bit_width_),
n->bitop_->bit_width_, n->bitop_->bit_offset_);
TRY2(n->rhs_->accept(this));
emit(" << %d)", n->bitop_->bit_offset_);
return mkstatus_(n, "unsupported");
} else {
if (n->id_->flags_[ExprNode::PROTO]) {
auto f = n->id_->struct_type_->field(n->id_->sub_name_);
emit("bpf_dins(%s%s + %zu, %zu, %zu, ", n->id_->decl_->scope_id(), n->id_->c_str(),
f->bit_offset_ >> 3, f->bit_offset_ & 0x7, f->bit_width_);
TRY2(n->rhs_->accept(this));
emit(")");
if (n->lhs_->flags_[ExprNode::PROTO]) {
// auto f = n->lhs_->struct_type_->field(n->id_->sub_name_);
// emit("bpf_dins(%s%s + %zu, %zu, %zu, ", n->id_->decl_->scope_id(), n->id_->c_str(),
// f->bit_offset_ >> 3, f->bit_offset_ & 0x7, f->bit_width_);
// TRY2(n->rhs_->accept(this));
// emit(")");
return mkstatus_(n, "unsupported");
} else {
TRY2(n->rhs_->accept(this));
Value *rhs = pop_expr();
TRY2(n->id_->accept(this));
Value *lhs = pop_expr();
if (!n->rhs_->is_ref())
rhs = B.CreateIntCast(rhs, cast<PointerType>(lhs->getType())->getElementType(), false);
B.CreateStore(rhs, lhs);
if (n->lhs_->is_pkt()) {
TRY2(n->lhs_->accept(this));
} else {
Value *rhs = pop_expr();
TRY2(n->lhs_->accept(this));
Value *lhs = pop_expr();
if (!n->rhs_->is_ref())
rhs = B.CreateIntCast(rhs, cast<PointerType>(lhs->getType())->getElementType(), false);
B.CreateStore(rhs, lhs);
}
}
}
return mkstatus(0);
Expand Down Expand Up @@ -682,6 +686,12 @@ StatusTuple CodegenLLVM::emit_log(MethodCallExprNode *n) {
return mkstatus(0);
}

StatusTuple CodegenLLVM::emit_packet_rewrite_field(MethodCallExprNode *n) {
TRY2(n->args_[1]->accept(this));
TRY2(n->args_[0]->accept(this));
return mkstatus(0);
}

StatusTuple CodegenLLVM::emit_atomic_add(MethodCallExprNode *n) {
TRY2(n->args_[0]->accept(this));
Value *lhs = B.CreateBitCast(pop_expr(), Type::getInt64PtrTy(ctx()));
Expand Down Expand Up @@ -741,6 +751,8 @@ StatusTuple CodegenLLVM::visit_method_call_expr_node(MethodCallExprNode *n) {
TRY2(emit_table_update(n));
} else if (n->id_->sub_name_ == "delete") {
TRY2(emit_table_delete(n));
} else if (n->id_->sub_name_ == "rewrite_field" && n->id_->name_ == "pkt") {
TRY2(emit_packet_rewrite_field(n));
}
} else if (n->id_->name_ == "atomic_add") {
TRY2(emit_atomic_add(n));
Expand Down Expand Up @@ -952,24 +964,25 @@ StatusTuple CodegenLLVM::visit_struct_variable_decl_stmt_node(StructVariableDecl
ConstantPointerNull *const_null = ConstantPointerNull::get(cast<PointerType>(ptr_stype));
B.CreateStore(const_null, ptr_a);
} else {
string var = n->scope_id() + n->id_->name_;
/* zero initialize array to be filled in with packet header */
emit("uint64_t __%s[%zu] = {}; uint8_t *%s = (uint8_t*)__%s;",
var.c_str(), ((decl->bit_width_ >> 3) + 7) >> 3, var.c_str(), var.c_str());
for (auto it = n->init_.begin(); it != n->init_.end(); ++it) {
auto asn = static_cast<AssignExprNode*>(it->get());
if (auto f = decl->field(asn->id_->sub_name_)) {
size_t bit_offset = f->bit_offset_;
size_t bit_width = f->bit_width_;
if (asn->bitop_) {
bit_offset += f->bit_width_ - (asn->bitop_->bit_offset_ + asn->bitop_->bit_width_);
bit_width = std::min(bit_width - asn->bitop_->bit_offset_, asn->bitop_->bit_width_);
}
emit(" bpf_dins(%s + %zu, %zu, %zu, ", var.c_str(), bit_offset >> 3, bit_offset & 0x7, bit_width);
TRY2(asn->rhs_->accept(this));
emit(");");
}
}
return mkstatus_(n, "unsupported");
// string var = n->scope_id() + n->id_->name_;
// /* zero initialize array to be filled in with packet header */
// emit("uint64_t __%s[%zu] = {}; uint8_t *%s = (uint8_t*)__%s;",
// var.c_str(), ((decl->bit_width_ >> 3) + 7) >> 3, var.c_str(), var.c_str());
// for (auto it = n->init_.begin(); it != n->init_.end(); ++it) {
// auto asn = static_cast<AssignExprNode*>(it->get());
// if (auto f = decl->field(asn->id_->sub_name_)) {
// size_t bit_offset = f->bit_offset_;
// size_t bit_width = f->bit_width_;
// if (asn->bitop_) {
// bit_offset += f->bit_width_ - (asn->bitop_->bit_offset_ + asn->bitop_->bit_width_);
// bit_width = std::min(bit_width - asn->bitop_->bit_offset_, asn->bitop_->bit_width_);
// }
// emit(" bpf_dins(%s + %zu, %zu, %zu, ", var.c_str(), bit_offset >> 3, bit_offset & 0x7, bit_width);
// TRY2(asn->rhs_->accept(this));
// emit(");");
// }
// }
}
} else {
if (n->is_pointer()) {
Expand Down
13 changes: 0 additions & 13 deletions src/cc/codegen_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,7 @@ class CodegenLLVM : public Visitor {
STATUS_RETURN emit_table_lookup(MethodCallExprNode* n);
STATUS_RETURN emit_table_update(MethodCallExprNode* n);
STATUS_RETURN emit_table_delete(MethodCallExprNode* n);
STATUS_RETURN emit_channel_push(MethodCallExprNode* n);
STATUS_RETURN emit_channel_push_generic(MethodCallExprNode* n);
STATUS_RETURN emit_log(MethodCallExprNode* n);
STATUS_RETURN emit_packet_forward(MethodCallExprNode* n);
STATUS_RETURN emit_packet_replicate(MethodCallExprNode* n);
STATUS_RETURN emit_packet_clone_forward(MethodCallExprNode* n);
STATUS_RETURN emit_packet_forward_self(MethodCallExprNode* n);
STATUS_RETURN emit_packet_drop(MethodCallExprNode* n);
STATUS_RETURN emit_packet_broadcast(MethodCallExprNode* n);
STATUS_RETURN emit_packet_multicast(MethodCallExprNode* n);
STATUS_RETURN emit_packet_push_header(MethodCallExprNode* n);
STATUS_RETURN emit_packet_pop_header(MethodCallExprNode* n);
STATUS_RETURN emit_packet_push_vlan(MethodCallExprNode* n);
STATUS_RETURN emit_packet_pop_vlan(MethodCallExprNode* n);
STATUS_RETURN emit_packet_rewrite_field(MethodCallExprNode* n);
STATUS_RETURN emit_atomic_add(MethodCallExprNode* n);
STATUS_RETURN emit_cksum(MethodCallExprNode* n);
Expand Down
16 changes: 12 additions & 4 deletions src/cc/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class ExprNode : public Node {
typedef unique_ptr<ExprNode> Ptr;
virtual StatusTuple accept(Visitor* v) = 0;
enum expr_type { STRUCT, INTEGER, STRING, VOID, UNKNOWN };
enum prop_flag { READ = 0, WRITE, PROTO, IS_LHS, IS_REF, LAST };
enum prop_flag { READ = 0, WRITE, PROTO, IS_LHS, IS_REF, IS_PKT, LAST };
expr_type typeof_;
StructDeclStmtNode *struct_type_;
size_t bit_width_;
Expand All @@ -165,6 +165,7 @@ class ExprNode : public Node {
}
bool is_lhs() const { return flags_[IS_LHS]; }
bool is_ref() const { return flags_[IS_REF]; }
bool is_pkt() const { return flags_[IS_PKT]; }
};

typedef vector<ExprNode::Ptr> ExprNodeList;
Expand Down Expand Up @@ -244,11 +245,18 @@ class AssignExprNode : public ExprNode {
public:
DECLARE(AssignExprNode)

IdentExprNode::Ptr id_;
//IdentExprNode *id_;
ExprNode::Ptr lhs_;
ExprNode::Ptr rhs_;
AssignExprNode(IdentExprNode::Ptr id, ExprNode::Ptr rhs)
: id_(move(id)), rhs_(move(rhs)) {
id_->flags_[ExprNode::IS_LHS] = true;
: lhs_(move(id)), rhs_(move(rhs)) {
//id_ = (IdentExprNode *)lhs_.get();
lhs_->flags_[ExprNode::IS_LHS] = true;
}
AssignExprNode(ExprNode::Ptr lhs, ExprNode::Ptr rhs)
: lhs_(move(lhs)), rhs_(move(rhs)) {
//id_ = nullptr;
lhs_->flags_[ExprNode::IS_LHS] = true;
}
};

Expand Down
3 changes: 2 additions & 1 deletion src/cc/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ StructVariableDeclStmtNode *Parser::variable_add(StructVariableDeclStmtNode *dec
for (auto arg = args->begin(); arg != args->end(); ++arg) {
// decorate with the name of this decl
auto n = static_cast<AssignExprNode *>(arg->get());
n->id_->prepend_dot(decl->id_->name_);
auto id = static_cast<IdentExprNode *>(n->lhs_.get());
id->prepend_dot(decl->id_->name_);
}
} else {
fprintf(stderr, "must use key = value syntax\n");
Expand Down
5 changes: 5 additions & 0 deletions src/cc/parser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,9 @@ assign_expr
| dotted_ident bitop TEQUAL expr
{ $$ = new AssignExprNode(IdentExprNode::Ptr($1), ExprNode::Ptr($4)); $$->bitop_ = BitopExprNode::Ptr($2);
parser.set_loc($$, @$); }
| expr TEQUAL expr
{ $$ = new AssignExprNode(ExprNode::Ptr($1), ExprNode::Ptr($3));
parser.set_loc($$, @$); }
;

return_expr
Expand All @@ -471,9 +474,11 @@ expr
parser.set_loc($$, @$); }
| TDOLLAR dotted_ident
{ $$ = new PacketExprNode(IdentExprNode::Ptr($2));
$$->flags_[ExprNode::IS_PKT] = true;
parser.set_loc($$, @$); }
| TDOLLAR dotted_ident bitop
{ $$ = new PacketExprNode(IdentExprNode::Ptr($2)); $$->bitop_ = BitopExprNode::Ptr($3);
$$->flags_[ExprNode::IS_PKT] = true;
parser.set_loc($$, @$); }
| TGOTO scoped_ident
{ $$ = new GotoExprNode(IdentExprNode::Ptr($2), false);
Expand Down
2 changes: 1 addition & 1 deletion src/cc/printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ StatusTuple Printer::visit_ident_expr_node(IdentExprNode* n) {
}

StatusTuple Printer::visit_assign_expr_node(AssignExprNode* n) {
TRY2(n->id_->accept(this));
TRY2(n->lhs_->accept(this));
fprintf(out_, " = ");
TRY2(n->rhs_->accept(this));
return mkstatus(0);
Expand Down
16 changes: 10 additions & 6 deletions src/cc/type_check.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ StatusTuple TypeCheck::visit_ident_expr_node(IdentExprNode *n) {

StatusTuple TypeCheck::visit_assign_expr_node(AssignExprNode *n) {
/// @todo check lhs is assignable
TRY2(n->id_->accept(this));
if (n->id_->typeof_ == ExprNode::STRUCT) {
TRY2(n->lhs_->accept(this));
if (n->lhs_->typeof_ == ExprNode::STRUCT) {
TRY2(n->rhs_->accept(this));
if (n->rhs_->typeof_ != ExprNode::STRUCT)
return mkstatus_(n, "Right-hand side of assignment must be a struct");
} else {
if (n->id_->typeof_ != ExprNode::INTEGER)
if (n->lhs_->typeof_ != ExprNode::INTEGER)
return mkstatus_(n, "Left-hand side of assignment must be a numeric type");
if (!n->id_->flags_[ExprNode::WRITE])
if (!n->lhs_->flags_[ExprNode::WRITE])
return mkstatus_(n, "Left-hand side of assignment is read-only");
TRY2(n->rhs_->accept(this));
if (n->rhs_->typeof_ != ExprNode::INTEGER)
Expand All @@ -173,7 +173,7 @@ StatusTuple TypeCheck::visit_packet_expr_node(PacketExprNode *n) {
else
n->bit_width_ = sub_decl->bit_width_;
}
n->flags_[ExprNode::WRITE] = false;
n->flags_[ExprNode::WRITE] = true;
return mkstatus(0);
}

Expand Down Expand Up @@ -305,6 +305,9 @@ StatusTuple TypeCheck::visit_method_call_expr_node(MethodCallExprNode *n) {
TRY2(check_update_method(n));
} else if (n->id_->sub_name_ == "delete") {
TRY2(check_delete_method(n));
} else if (n->id_->sub_name_ == "rewrite_field" && n->id_->name_ == "pkt") {
TRY2(expect_method_arg(n, 2));
n->args_[0]->flags_[ExprNode::IS_LHS] = true;
}
} else if (n->id_->name_ == "log") {
if (n->args_.size() < 1)
Expand Down Expand Up @@ -382,7 +385,8 @@ StatusTuple TypeCheck::visit_struct_variable_decl_stmt_node(StructVariableDeclSt
set<string> used;
for (auto i = n->init_.begin(); i != n->init_.end(); ++i) {
auto asn = static_cast<AssignExprNode*>(i->get());
used.insert(asn->id_->sub_name_);
auto id = static_cast<IdentExprNode *>(asn->lhs_.get());
used.insert(id->sub_name_);
}
for (auto f = type->stmts_.begin(); f != type->stmts_.end(); ++f) {
if (used.find((*f)->id_->name_) == used.end()) {
Expand Down
3 changes: 2 additions & 1 deletion tests/jit/test2.b
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ u32 main (struct proto::skbuff *skb) {
on_valid(xleaf) {
incr_cksum(@ip.hchecksum, orig_dip, xleaf.xdip);
incr_cksum(@ip.hchecksum, orig_sip, xleaf.xsip);
// the below are equivalent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

pkt.rewrite_field($ip.dst, xleaf.xdip);
pkt.rewrite_field($ip.src, xleaf.xsip);
$ip.src = xleaf.xsip;
atomic_add(xleaf.xlated_pkts, 1);
}
}
Expand Down