Only one instance of base_type() getting a NewRef instead of AdoptRef
fixed in merge.  All other changes are superficial formatting and
factoring.

* 'leaks' of https://github.com/MaxKellermann/zeek: (22 commits)
  Stmt: use class IntrusivePtr
  Stmt: remove unused default constructors and `friend` declarations
  Val: remove unimplemented prototype recover_val()
  Val: cast_value_to_type() returns IntrusivePtr
  Val: use IntrusivePtr in check_and_promote()
  Val: use nullptr instead of 0
  zeekygen: use class IntrusivePtr
  ID: use class IntrusivePtr
  Expr: use class IntrusivePtr
  Var: copy Location to stack, to fix use-after-free crash bug
  Scope: lookup_ID() and install_ID() return IntrusivePtr<ID>
  Scope: delete duplicate locals
  EventRegistry: automatically delete EventHandlers
  main: destroy event_registry after iosource_mgr
  zeekygen/IdentifierInfo: delete duplicate fields
  main: free the global scope in terminate_bro()
  Scope: pop_scope() returns IntrusivePtr<>
  Scope: unref all inits in destructor
  Var: pass IntrusivePtr to add_global(), add_local() etc.
  plugin/ComponentManager: hold a reference to the EnumType
  ...
This commit is contained in:
Jon Siwek 2020-02-28 00:42:17 -08:00
commit cf196bb148
41 changed files with 1864 additions and 2095 deletions

View file

@ -130,11 +130,9 @@ void Stmt::AccessStats(ODesc* d) const
}
}
ExprListStmt::ExprListStmt(BroStmtTag t, ListExpr* arg_l)
: Stmt(t)
ExprListStmt::ExprListStmt(BroStmtTag t, IntrusivePtr<ListExpr> arg_l)
: Stmt(t), l(std::move(arg_l))
{
l = arg_l;
const expr_list& e = l->Exprs();
for ( const auto& expr : e )
{
@ -143,28 +141,25 @@ ExprListStmt::ExprListStmt(BroStmtTag t, ListExpr* arg_l)
Error("value of type void illegal");
}
SetLocationInfo(arg_l->GetLocationInfo());
SetLocationInfo(l->GetLocationInfo());
}
ExprListStmt::~ExprListStmt()
{
Unref(l);
}
ExprListStmt::~ExprListStmt() = default;
Val* ExprListStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> ExprListStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
last_access = network_time;
flow = FLOW_NEXT;
val_list* vals = eval_list(f, l);
val_list* vals = eval_list(f, l.get());
if ( vals )
{
Val* result = DoExec(vals, flow);
auto result = DoExec(vals, flow);
delete_vals(vals);
return result;
}
else
return 0;
return nullptr;
}
void ExprListStmt::Describe(ODesc* d) const
@ -199,7 +194,7 @@ static BroFile* print_stdout = 0;
static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char* name)
{
ID* id = lookup_ID(name, module_name);
auto id = lookup_ID(name, module_name);
assert(id);
assert(id->IsEnumConst());
@ -212,7 +207,7 @@ static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char
return rval;
}
static Val* print_log(val_list* vals)
static void print_log(val_list* vals)
{
auto plval = lookup_enum_val("Log", "PRINTLOG");
auto record = make_intrusive<RecordVal>(internal_type("Log::PrintLogInfo")->AsRecordType());
@ -228,10 +223,9 @@ static Val* print_log(val_list* vals)
record->Assign(0, new Val(current_time(), TYPE_TIME));
record->Assign(1, vec.release());
log_mgr->Write(plval.get(), record.get());
return nullptr;
}
Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
IntrusivePtr<Val> PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
{
RegisterAccess();
@ -245,7 +239,7 @@ Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
{
f = (*vals)[0]->AsFile();
if ( ! f->IsOpen() )
return 0;
return nullptr;
++offset;
}
@ -257,12 +251,18 @@ Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
case BifEnum::Log::REDIRECT_NONE:
break;
case BifEnum::Log::REDIRECT_ALL:
return print_log(vals);
{
print_log(vals);
return nullptr;
}
case BifEnum::Log::REDIRECT_STDOUT:
if ( f->File() == stdout )
{
// Should catch even printing to a "manually opened" stdout file,
// like "/dev/stdout" or "-".
return print_log(vals);
print_log(vals);
return nullptr;
}
break;
default:
reporter->InternalError("unknown Log::PrintLogType value: %d",
@ -291,51 +291,41 @@ Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
f->Write("\n", 1);
}
return 0;
return nullptr;
}
ExprStmt::ExprStmt(Expr* arg_e) : Stmt(STMT_EXPR)
ExprStmt::ExprStmt(IntrusivePtr<Expr> arg_e) : Stmt(STMT_EXPR), e(std::move(arg_e))
{
e = arg_e;
if ( e && e->IsPure() )
Warn("expression value ignored");
SetLocationInfo(arg_e->GetLocationInfo());
SetLocationInfo(e->GetLocationInfo());
}
ExprStmt::ExprStmt(BroStmtTag t, Expr* arg_e) : Stmt(t)
ExprStmt::ExprStmt(BroStmtTag t, IntrusivePtr<Expr> arg_e) : Stmt(t), e(std::move(arg_e))
{
e = arg_e;
if ( e )
SetLocationInfo(e->GetLocationInfo());
}
ExprStmt::~ExprStmt()
{
Unref(e);
}
ExprStmt::~ExprStmt() = default;
Val* ExprStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> ExprStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
Val* v = e->Eval(f);
auto v = e->Eval(f);
if ( v )
{
Val* ret_val = DoExec(f, v, flow);
Unref(v);
return ret_val;
}
return DoExec(f, v.get(), flow);
else
return 0;
return nullptr;
}
Val* ExprStmt::DoExec(Frame* /* f */, Val* /* v */, stmt_flow_type& /* flow */) const
IntrusivePtr<Val> ExprStmt::DoExec(Frame* /* f */, Val* /* v */, stmt_flow_type& /* flow */) const
{
return 0;
return nullptr;
}
int ExprStmt::IsPure() const
@ -379,29 +369,25 @@ TraversalCode ExprStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
IfStmt::IfStmt(Expr* test, Stmt* arg_s1, Stmt* arg_s2) : ExprStmt(STMT_IF, test)
IfStmt::IfStmt(IntrusivePtr<Expr> test,
IntrusivePtr<Stmt> arg_s1, IntrusivePtr<Stmt> arg_s2)
: ExprStmt(STMT_IF, std::move(test)),
s1(std::move(arg_s1)), s2(std::move(arg_s2))
{
s1 = arg_s1;
s2 = arg_s2;
if ( ! e->IsError() && ! IsBool(e->Type()->Tag()) )
e->Error("conditional in test must be boolean");
const Location* loc1 = arg_s1->GetLocationInfo();
const Location* loc2 = arg_s2->GetLocationInfo();
const Location* loc1 = s1->GetLocationInfo();
const Location* loc2 = s2->GetLocationInfo();
SetLocationInfo(loc1, loc2);
}
IfStmt::~IfStmt()
{
Unref(s1);
Unref(s2);
}
IfStmt::~IfStmt() = default;
Val* IfStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
IntrusivePtr<Val> IfStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
{
// Treat 0 as false, but don't require 1 for true.
Stmt* do_stmt = v->IsZero() ? s2 : s1;
Stmt* do_stmt = v->IsZero() ? s2.get() : s1.get();
f->SetNextStmt(do_stmt);
@ -409,9 +395,9 @@ Val* IfStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
{ // ### Abort or something
}
Val* result = do_stmt->Exec(f, flow);
auto result = do_stmt->Exec(f, flow);
if ( ! post_execute_stmt(do_stmt, f, result, &flow) )
if ( ! post_execute_stmt(do_stmt, f, result.get(), &flow) )
{ // ### Abort or something
}
@ -483,8 +469,10 @@ static BroStmtTag get_last_stmt_tag(const Stmt* stmt)
return get_last_stmt_tag(stmts->Stmts()[len - 1]);
}
Case::Case(ListExpr* arg_expr_cases, id_list* arg_type_cases, Stmt* arg_s)
: expr_cases(arg_expr_cases), type_cases(arg_type_cases), s(arg_s)
Case::Case(IntrusivePtr<ListExpr> arg_expr_cases, id_list* arg_type_cases,
IntrusivePtr<Stmt> arg_s)
: expr_cases(std::move(arg_expr_cases)), type_cases(arg_type_cases),
s(std::move(arg_s))
{
BroStmtTag t = get_last_stmt_tag(Body());
@ -494,9 +482,6 @@ Case::Case(ListExpr* arg_expr_cases, id_list* arg_type_cases, Stmt* arg_s)
Case::~Case()
{
Unref(expr_cases);
Unref(s);
for ( const auto& id : *type_cases )
Unref(id);
@ -609,8 +594,9 @@ void SwitchStmt::Init()
case_label_value_map.SetDeleteFunc(int_del_func);
}
SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
ExprStmt(STMT_SWITCH, index), cases(arg_cases), default_case_idx(-1)
SwitchStmt::SwitchStmt(IntrusivePtr<Expr> index, case_list* arg_cases)
: ExprStmt(STMT_SWITCH, std::move(index)),
cases(arg_cases), default_case_idx(-1)
{
Init();
@ -632,7 +618,7 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
if ( ! le->Type()->AsTypeList()->AllMatch(e->Type(), false) )
{
le->Error("case expression type differs from switch type", e);
le->Error("case expression type differs from switch type", e.get());
continue;
}
@ -670,10 +656,10 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
if ( ne->Id()->IsConst() )
{
Val* v = ne->Eval(0);
auto v = ne->Eval(0);
if ( v )
Unref(exprs.replace(j, new ConstExpr(v)));
Unref(exprs.replace(j, new ConstExpr(std::move(v))));
}
}
break;
@ -820,16 +806,16 @@ std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const
return std::make_pair(label_idx, label_id);
}
Val* SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
IntrusivePtr<Val> SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
{
Val* rval = 0;
IntrusivePtr<Val> rval;
auto m = FindCaseLabelMatch(v);
int matching_label_idx = m.first;
ID* matching_id = m.second;
if ( matching_label_idx == -1 )
return 0;
return nullptr;
for ( int i = matching_label_idx; i < cases->length(); ++i )
{
@ -838,7 +824,7 @@ Val* SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
if ( matching_id )
{
auto cv = cast_value_to_type(v, matching_id->Type());
f->SetElement(matching_id, cv);
f->SetElement(matching_id, cv.release());
}
flow = FLOW_NEXT;
@ -905,7 +891,7 @@ TraversalCode SwitchStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
AddStmt::AddStmt(Expr* arg_e) : ExprStmt(STMT_ADD, arg_e)
AddStmt::AddStmt(IntrusivePtr<Expr> arg_e) : ExprStmt(STMT_ADD, std::move(arg_e))
{
if ( ! e->CanAdd() )
Error("illegal add statement");
@ -916,12 +902,12 @@ int AddStmt::IsPure() const
return 0;
}
Val* AddStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> AddStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
e->Add(f);
return 0;
return nullptr;
}
@ -938,7 +924,7 @@ TraversalCode AddStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
DelStmt::DelStmt(Expr* arg_e) : ExprStmt(STMT_DELETE, arg_e)
DelStmt::DelStmt(IntrusivePtr<Expr> arg_e) : ExprStmt(STMT_DELETE, std::move(arg_e))
{
if ( e->IsError() )
return;
@ -952,12 +938,12 @@ int DelStmt::IsPure() const
return 0;
}
Val* DelStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> DelStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
e->Delete(f);
return 0;
return nullptr;
}
TraversalCode DelStmt::Traverse(TraversalCallback* cb) const
@ -973,12 +959,12 @@ TraversalCode DelStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
EventStmt::EventStmt(EventExpr* arg_e) : ExprStmt(STMT_EVENT, arg_e)
EventStmt::EventStmt(IntrusivePtr<EventExpr> arg_e)
: ExprStmt(STMT_EVENT, arg_e), event_expr(std::move(arg_e))
{
event_expr = arg_e;
}
Val* EventStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> EventStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
val_list* args = eval_list(f, event_expr->Args());
@ -990,8 +976,7 @@ Val* EventStmt::Exec(Frame* f, stmt_flow_type& flow) const
}
flow = FLOW_NEXT;
return 0;
return nullptr;
}
TraversalCode EventStmt::Traverse(TraversalCallback* cb) const
@ -1007,19 +992,16 @@ TraversalCode EventStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
WhileStmt::WhileStmt(Expr* arg_loop_condition, Stmt* arg_body)
: loop_condition(arg_loop_condition), body(arg_body)
WhileStmt::WhileStmt(IntrusivePtr<Expr> arg_loop_condition,
IntrusivePtr<Stmt> arg_body)
: loop_condition(std::move(arg_loop_condition)), body(std::move(arg_body))
{
if ( ! loop_condition->IsError() &&
! IsBool(loop_condition->Type()->Tag()) )
loop_condition->Error("while conditional must be boolean");
}
WhileStmt::~WhileStmt()
{
Unref(loop_condition);
Unref(body);
}
WhileStmt::~WhileStmt() = default;
int WhileStmt::IsPure() const
{
@ -1060,23 +1042,20 @@ TraversalCode WhileStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
Val* WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
Val* rval = 0;
IntrusivePtr<Val> rval;
for ( ; ; )
{
Val* cond = loop_condition->Eval(f);
auto cond = loop_condition->Eval(f);
if ( ! cond )
break;
bool cont = cond->AsBool();
Unref(cond);
if ( ! cont )
if ( ! cond->AsBool() )
break;
flow = FLOW_NEXT;
@ -1092,8 +1071,8 @@ Val* WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const
return rval;
}
ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
: ExprStmt(STMT_FOR, loop_expr)
ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr<Expr> loop_expr)
: ExprStmt(STMT_FOR, std::move(loop_expr))
{
loop_vars = arg_loop_vars;
body = 0;
@ -1119,8 +1098,8 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
else
{
delete add_local((*loop_vars)[i],
ind_type->Ref(), INIT_NONE,
add_local({NewRef{}, (*loop_vars)[i]},
{NewRef{}, ind_type}, INIT_NONE,
0, 0, VAR_REGULAR);
}
}
@ -1136,7 +1115,7 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
BroType* t = (*loop_vars)[0]->Type();
if ( ! t )
delete add_local((*loop_vars)[0], base_type(TYPE_COUNT),
add_local({NewRef{}, (*loop_vars)[0]}, {AdoptRef{}, base_type(TYPE_COUNT)},
INIT_NONE, 0, 0, VAR_REGULAR);
else if ( ! IsIntegral(t->Tag()) )
@ -1156,8 +1135,8 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
BroType* t = (*loop_vars)[0]->Type();
if ( ! t )
delete add_local((*loop_vars)[0],
base_type(TYPE_STRING),
add_local({NewRef{}, (*loop_vars)[0]},
{AdoptRef{}, base_type(TYPE_STRING)},
INIT_NONE, 0, 0, VAR_REGULAR);
else if ( t->Tag() != TYPE_STRING )
@ -1170,10 +1149,11 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
e->Error("target to iterate over must be a table, set, vector, or string");
}
ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr, ID* val_var)
: ForStmt(arg_loop_vars, loop_expr)
ForStmt::ForStmt(id_list* arg_loop_vars,
IntrusivePtr<Expr> loop_expr, IntrusivePtr<ID> val_var)
: ForStmt(arg_loop_vars, std::move(loop_expr))
{
value_var = val_var;
value_var = std::move(val_var);
if ( e->Type()->IsTable() )
{
@ -1187,7 +1167,7 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr, ID* val_var)
}
else
{
delete add_local(value_var, yield_type->Ref(), INIT_NONE,
add_local(value_var, {NewRef{}, yield_type}, INIT_NONE,
0, 0, VAR_REGULAR);
}
}
@ -1200,14 +1180,11 @@ ForStmt::~ForStmt()
for ( const auto& var : *loop_vars )
Unref(var);
delete loop_vars;
Unref(value_var);
Unref(body);
}
Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
{
Val* ret = 0;
IntrusivePtr<Val> ret;
if ( v->Type()->Tag() == TYPE_TABLE )
{
@ -1215,7 +1192,7 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
const PDict<TableEntryVal>* loop_vals = tv->AsTable();
if ( ! loop_vals->Length() )
return 0;
return nullptr;
HashKey* k;
TableEntryVal* current_tev;
@ -1226,7 +1203,7 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
delete k;
if ( value_var )
f->SetElement(value_var, current_tev->Value()->Ref());
f->SetElement(value_var.get(), current_tev->Value()->Ref());
for ( int i = 0; i < ind_lv->Length(); i++ )
f->SetElement((*loop_vars)[i], ind_lv->Index(i)->Ref());
@ -1356,11 +1333,11 @@ TraversalCode ForStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
Val* NextStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
IntrusivePtr<Val> NextStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_LOOP;
return 0;
return nullptr;
}
int NextStmt::IsPure() const
@ -1383,11 +1360,11 @@ TraversalCode NextStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
Val* BreakStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
IntrusivePtr<Val> BreakStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_BREAK;
return 0;
return nullptr;
}
int BreakStmt::IsPure() const
@ -1410,11 +1387,11 @@ TraversalCode BreakStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
Val* FallthroughStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
IntrusivePtr<Val> FallthroughStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_FALLTHROUGH;
return 0;
return nullptr;
}
int FallthroughStmt::IsPure() const
@ -1437,7 +1414,8 @@ TraversalCode FallthroughStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
ReturnStmt::ReturnStmt(Expr* arg_e) : ExprStmt(STMT_RETURN, arg_e)
ReturnStmt::ReturnStmt(IntrusivePtr<Expr> arg_e)
: ExprStmt(STMT_RETURN, std::move(arg_e))
{
Scope* s = current_scope();
@ -1472,10 +1450,14 @@ ReturnStmt::ReturnStmt(Expr* arg_e) : ExprStmt(STMT_RETURN, arg_e)
}
else
(void) check_and_promote_expr(e, yt);
{
Expr* e_ = e.release();
(void) check_and_promote_expr(e_, yt);
e = {AdoptRef{}, e_};
}
}
Val* ReturnStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> ReturnStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_RETURN;
@ -1483,7 +1465,7 @@ Val* ReturnStmt::Exec(Frame* f, stmt_flow_type& flow) const
if ( e )
return e->Eval(f);
else
return 0;
return nullptr;
}
void ReturnStmt::Describe(ODesc* d) const
@ -1514,7 +1496,7 @@ StmtList::~StmtList()
Unref(stmt);
}
Val* StmtList::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> StmtList::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
@ -1527,9 +1509,9 @@ Val* StmtList::Exec(Frame* f, stmt_flow_type& flow) const
{ // ### Abort or something
}
Val* result = stmt->Exec(f, flow);
auto result = stmt->Exec(f, flow);
if ( ! post_execute_stmt(stmt, f, result, &flow) )
if ( ! post_execute_stmt(stmt, f, result.get(), &flow) )
{ // ### Abort or something
}
@ -1537,7 +1519,7 @@ Val* StmtList::Exec(Frame* f, stmt_flow_type& flow) const
return result;
}
return 0;
return nullptr;
}
int StmtList::IsPure() const
@ -1593,7 +1575,7 @@ TraversalCode StmtList::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
Val* EventBodyList::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> EventBodyList::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
@ -1610,9 +1592,9 @@ Val* EventBodyList::Exec(Frame* f, stmt_flow_type& flow) const
{ // ### Abort or something
}
Val* result = stmt->Exec(f, flow);
auto result = stmt->Exec(f, flow);
if ( ! post_execute_stmt(stmt, f, result, &flow) )
if ( ! post_execute_stmt(stmt, f, result.get(), &flow) )
{ // ### Abort or something
}
}
@ -1621,7 +1603,7 @@ Val* EventBodyList::Exec(Frame* f, stmt_flow_type& flow) const
stmt_flow_type ft = FLOW_RETURN;
(void) post_execute_stmt(f->GetNextStmt(), f, 0, &ft);
return 0;
return nullptr;
}
void EventBodyList::Describe(ODesc* d) const
@ -1666,7 +1648,7 @@ InitStmt::~InitStmt()
delete inits;
}
Val* InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
@ -1694,7 +1676,7 @@ Val* InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
f->SetElement(aggr, v);
}
return 0;
return nullptr;
}
void InitStmt::Describe(ODesc* d) const
@ -1730,11 +1712,11 @@ TraversalCode InitStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
Val* NullStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
IntrusivePtr<Val> NullStmt::Exec(Frame* /* f */, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
return 0;
return nullptr;
}
int NullStmt::IsPure() const
@ -1759,18 +1741,15 @@ TraversalCode NullStmt::Traverse(TraversalCallback* cb) const
HANDLE_TC_STMT_POST(tc);
}
WhenStmt::WhenStmt(Expr* arg_cond, Stmt* arg_s1, Stmt* arg_s2,
Expr* arg_timeout, bool arg_is_return)
: Stmt(STMT_WHEN)
WhenStmt::WhenStmt(IntrusivePtr<Expr> arg_cond,
IntrusivePtr<Stmt> arg_s1, IntrusivePtr<Stmt> arg_s2,
IntrusivePtr<Expr> arg_timeout, bool arg_is_return)
: Stmt(STMT_WHEN),
cond(std::move(arg_cond)), s1(std::move(arg_s1)), s2(std::move(arg_s2)),
timeout(std::move(arg_timeout)), is_return(arg_is_return)
{
assert(arg_cond);
assert(arg_s1);
cond = arg_cond;
s1 = arg_s1;
s2 = arg_s2;
timeout = arg_timeout;
is_return = arg_is_return;
assert(cond);
assert(s1);
if ( ! cond->IsError() && ! IsBool(cond->Type()->Tag()) )
cond->Error("conditional in test must be boolean");
@ -1786,29 +1765,20 @@ WhenStmt::WhenStmt(Expr* arg_cond, Stmt* arg_s1, Stmt* arg_s2,
}
}
WhenStmt::~WhenStmt()
{
Unref(cond);
Unref(s1);
Unref(s2);
}
WhenStmt::~WhenStmt() = default;
Val* WhenStmt::Exec(Frame* f, stmt_flow_type& flow) const
IntrusivePtr<Val> WhenStmt::Exec(Frame* f, stmt_flow_type& flow) const
{
RegisterAccess();
flow = FLOW_NEXT;
::Ref(cond);
::Ref(s1);
if ( s2 )
::Ref(s2);
if ( timeout )
::Ref(timeout);
// The new trigger object will take care of its own deletion.
new trigger::Trigger(cond, s1, s2, timeout, f, is_return, location);
return 0;
new trigger::Trigger(IntrusivePtr{cond}.release(),
IntrusivePtr{s1}.release(),
IntrusivePtr{s2}.release(),
IntrusivePtr{timeout}.release(),
f, is_return, location);
return nullptr;
}
int WhenStmt::IsPure() const