mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
final changes for -O C++ feature completeness, mainly "when" statement support
This commit is contained in:
parent
48f1e4df42
commit
56140046d3
9 changed files with 191 additions and 33 deletions
|
@ -66,6 +66,10 @@ void CPPCompile::GenStmt(const Stmt* s)
|
|||
GenSwitchStmt(static_cast<const SwitchStmt*>(s));
|
||||
break;
|
||||
|
||||
case STMT_WHEN:
|
||||
GenWhenStmt(static_cast<const WhenStmt*>(s));
|
||||
break;
|
||||
|
||||
case STMT_FOR:
|
||||
GenForStmt(s->AsForStmt());
|
||||
break;
|
||||
|
@ -91,10 +95,6 @@ void CPPCompile::GenStmt(const Stmt* s)
|
|||
case STMT_FALLTHROUGH:
|
||||
break;
|
||||
|
||||
case STMT_WHEN:
|
||||
ASSERT(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
reporter->InternalError("bad statement type in CPPCompile::GenStmt");
|
||||
}
|
||||
|
@ -163,23 +163,26 @@ void CPPCompile::GenReturnStmt(const ReturnStmt* r)
|
|||
{
|
||||
auto e = r->StmtExpr();
|
||||
|
||||
if ( ! ret_type || ! e || e->GetType()->Tag() == TYPE_VOID || in_hook )
|
||||
if ( in_hook )
|
||||
Emit("return true;");
|
||||
|
||||
else if ( ! e && ret_type && ret_type->Tag() != TYPE_VOID )
|
||||
// This occurs for ExpressionlessReturnOkay() functions.
|
||||
Emit("return nullptr;");
|
||||
|
||||
else if ( ! ret_type || ! e || e->GetType()->Tag() == TYPE_VOID )
|
||||
Emit("return;");
|
||||
|
||||
else
|
||||
{
|
||||
if ( in_hook )
|
||||
Emit("return true;");
|
||||
else
|
||||
Emit("return;");
|
||||
auto gt = ret_type->Tag() == TYPE_ANY ? GEN_VAL_PTR : GEN_NATIVE;
|
||||
auto ret = GenExpr(e, gt);
|
||||
|
||||
return;
|
||||
if ( e->GetType()->Tag() == TYPE_ANY )
|
||||
ret = GenericValPtrToGT(ret, ret_type, gt);
|
||||
|
||||
Emit("return %s;", ret);
|
||||
}
|
||||
|
||||
auto gt = ret_type->Tag() == TYPE_ANY ? GEN_VAL_PTR : GEN_NATIVE;
|
||||
auto ret = GenExpr(e, gt);
|
||||
|
||||
if ( e->GetType()->Tag() == TYPE_ANY )
|
||||
ret = GenericValPtrToGT(ret, ret_type, gt);
|
||||
|
||||
Emit("return %s;", ret);
|
||||
}
|
||||
|
||||
void CPPCompile::GenAddStmt(const ExprStmt* es)
|
||||
|
@ -384,6 +387,68 @@ void CPPCompile::GenValueSwitchStmt(const Expr* e, const case_list* cases)
|
|||
Emit("}");
|
||||
}
|
||||
|
||||
void CPPCompile::GenWhenStmt(const WhenStmt* w)
|
||||
{
|
||||
auto wi = w->Info();
|
||||
auto wl = wi->Lambda();
|
||||
|
||||
if ( ! wl )
|
||||
reporter->FatalError("cannot compile deprecated \"when\" statement");
|
||||
|
||||
auto is_return = wi->IsReturn() ? "true" : "false";
|
||||
auto timeout = wi->TimeoutExpr();
|
||||
auto timeout_val = timeout ? GenExpr(timeout, GEN_NATIVE) : "-1.0";
|
||||
auto loc = w->GetLocationInfo();
|
||||
|
||||
Emit("{ // begin a new scope for internal variables");
|
||||
|
||||
Emit("static WhenInfo* CPP__wi = nullptr;");
|
||||
Emit("static IDSet CPP__w_globals;");
|
||||
|
||||
NL();
|
||||
|
||||
Emit("if ( ! CPP__wi )");
|
||||
StartBlock();
|
||||
Emit("CPP__wi = new WhenInfo(%s);", is_return);
|
||||
for ( auto& wg : wi->WhenExprGlobals() )
|
||||
Emit("CPP__w_globals.insert(find_global__CPP(\"%s\").get());", wg->Name());
|
||||
EndBlock();
|
||||
NL();
|
||||
|
||||
Emit("std::vector<ValPtr> CPP__local_aggrs;");
|
||||
for ( auto l : wi->WhenExprLocals() )
|
||||
if ( IsAggr(l->GetType()) )
|
||||
Emit("CPP__local_aggrs.emplace_back(%s);", IDNameStr(l));
|
||||
|
||||
Emit("CPP__wi->Instantiate(%s);", GenExpr(wi->Lambda(), GEN_NATIVE));
|
||||
|
||||
// We need a new frame for the trigger to unambiguously associate
|
||||
// with, in case we're called multiple times with our existing frame.
|
||||
Emit("auto new_frame = make_intrusive<Frame>(0, nullptr, nullptr);");
|
||||
Emit("auto curr_t = f__CPP->GetTrigger();");
|
||||
Emit("auto curr_assoc = f__CPP->GetTriggerAssoc();");
|
||||
Emit("new_frame->SetTrigger({NewRef{}, curr_t});");
|
||||
Emit("new_frame->SetTriggerAssoc(curr_assoc);");
|
||||
|
||||
Emit("auto t = new trigger::Trigger(CPP__wi, %s, CPP__w_globals, CPP__local_aggrs, "
|
||||
"new_frame.get(), "
|
||||
"nullptr);",
|
||||
timeout_val);
|
||||
|
||||
auto loc_str = util::fmt("%s:%d-%d", loc->filename, loc->first_line, loc->last_line);
|
||||
Emit("t->SetName(\"%s\");", loc_str);
|
||||
|
||||
if ( ret_type && ret_type->Tag() != TYPE_VOID )
|
||||
{
|
||||
Emit("ValPtr retval = {NewRef{}, curr_t->Lookup(curr_assoc)};");
|
||||
Emit("if ( ! retval )");
|
||||
Emit("\tthrow DelayedCallException();");
|
||||
Emit("return %s;", GenericValPtrToGT("retval", ret_type, GEN_NATIVE));
|
||||
}
|
||||
|
||||
Emit("}");
|
||||
}
|
||||
|
||||
void CPPCompile::GenForStmt(const ForStmt* f)
|
||||
{
|
||||
Emit("{ // begin a new scope for the internal loop vars");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue