mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 18:48:20 +00:00
Func: use class IntrusivePtr
This commit is contained in:
parent
b18573c804
commit
a0c831a1bd
15 changed files with 89 additions and 146 deletions
104
src/Func.cc
104
src/Func.cc
|
@ -111,35 +111,36 @@ std::string render_call_stack()
|
|||
return rval;
|
||||
}
|
||||
|
||||
Func::Func() : scope(0), type(0)
|
||||
Func::Func()
|
||||
{
|
||||
unique_id = unique_ids.size();
|
||||
unique_ids.push_back(this);
|
||||
}
|
||||
|
||||
Func::Func(Kind arg_kind) : scope(0), kind(arg_kind), type(0)
|
||||
Func::Func(Kind arg_kind) : kind(arg_kind)
|
||||
{
|
||||
unique_id = unique_ids.size();
|
||||
unique_ids.push_back(this);
|
||||
}
|
||||
|
||||
Func::~Func()
|
||||
{
|
||||
Unref(type);
|
||||
}
|
||||
Func::~Func() = default;
|
||||
|
||||
void Func::AddBody(Stmt* /* new_body */, id_list* /* new_inits */,
|
||||
void Func::AddBody(IntrusivePtr<Stmt> /* new_body */, id_list* /* new_inits */,
|
||||
size_t /* new_frame_size */, int /* priority */)
|
||||
{
|
||||
Internal("Func::AddBody called");
|
||||
}
|
||||
|
||||
Func* Func::DoClone()
|
||||
void Func::SetScope(IntrusivePtr<Scope> newscope)
|
||||
{
|
||||
scope = std::move(newscope);
|
||||
}
|
||||
|
||||
IntrusivePtr<Func> Func::DoClone()
|
||||
{
|
||||
// By default, ok just to return a reference. Func does not have any state
|
||||
// that is different across instances.
|
||||
::Ref(this);
|
||||
return this;
|
||||
return {NewRef{}, this};
|
||||
}
|
||||
|
||||
void Func::DescribeDebug(ODesc* d, const val_list* args) const
|
||||
|
@ -180,7 +181,7 @@ TraversalCode Func::Traverse(TraversalCallback* cb) const
|
|||
{
|
||||
// FIXME: Make a fake scope for builtins?
|
||||
Scope* old_scope = cb->current_scope;
|
||||
cb->current_scope = scope;
|
||||
cb->current_scope = scope.get();
|
||||
|
||||
TraversalCode tc = cb->PreFunction(this);
|
||||
HANDLE_TC_STMT_PRE(tc);
|
||||
|
@ -206,13 +207,10 @@ TraversalCode Func::Traverse(TraversalCallback* cb) const
|
|||
|
||||
void Func::CopyStateInto(Func* other) const
|
||||
{
|
||||
std::for_each(bodies.begin(), bodies.end(), [](const Body& b) { Ref(b.stmts); });
|
||||
|
||||
other->bodies = bodies;
|
||||
other->scope = scope;
|
||||
other->kind = kind;
|
||||
|
||||
Ref(type);
|
||||
other->type = type;
|
||||
|
||||
other->name = name;
|
||||
|
@ -273,17 +271,17 @@ std::pair<bool, Val*> Func::HandlePluginResult(std::pair<bool, Val*> plugin_resu
|
|||
return plugin_result;
|
||||
}
|
||||
|
||||
BroFunc::BroFunc(ID* arg_id, Stmt* arg_body, id_list* aggr_inits,
|
||||
BroFunc::BroFunc(ID* arg_id, IntrusivePtr<Stmt> arg_body, id_list* aggr_inits,
|
||||
size_t arg_frame_size, int priority) : Func(BRO_FUNC)
|
||||
{
|
||||
name = arg_id->Name();
|
||||
type = arg_id->Type()->Ref();
|
||||
type = {NewRef{}, arg_id->Type()};
|
||||
frame_size = arg_frame_size;
|
||||
|
||||
if ( arg_body )
|
||||
{
|
||||
Body b;
|
||||
b.stmts = AddInits(arg_body, aggr_inits);
|
||||
b.stmts = AddInits(std::move(arg_body), aggr_inits);
|
||||
b.priority = priority;
|
||||
bodies.push_back(b);
|
||||
}
|
||||
|
@ -291,9 +289,6 @@ BroFunc::BroFunc(ID* arg_id, Stmt* arg_body, id_list* aggr_inits,
|
|||
|
||||
BroFunc::~BroFunc()
|
||||
{
|
||||
std::for_each(bodies.begin(), bodies.end(),
|
||||
[](Body& b) { Unref(b.stmts); });
|
||||
|
||||
if ( ! weak_closure_ref )
|
||||
Unref(closure);
|
||||
}
|
||||
|
@ -304,7 +299,7 @@ int BroFunc::IsPure() const
|
|||
[](const Body& b) { return b.stmts->IsPure(); });
|
||||
}
|
||||
|
||||
Val* BroFunc::Call(val_list* args, Frame* parent) const
|
||||
IntrusivePtr<Val> BroFunc::Call(val_list* args, Frame* parent) const
|
||||
{
|
||||
#ifdef PROFILE_BRO_FUNCTIONS
|
||||
DEBUG_MSG("Function: %s\n", Name());
|
||||
|
@ -321,7 +316,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
if( plugin_result.first )
|
||||
{
|
||||
Val *result = plugin_result.second;
|
||||
return result;
|
||||
return {AdoptRef{}, result};
|
||||
}
|
||||
|
||||
if ( bodies.empty() )
|
||||
|
@ -331,10 +326,10 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
for ( const auto& arg : *args )
|
||||
Unref(arg);
|
||||
|
||||
return Flavor() == FUNC_FLAVOR_HOOK ? val_mgr->GetTrue() : 0;
|
||||
return Flavor() == FUNC_FLAVOR_HOOK ? IntrusivePtr{AdoptRef{}, val_mgr->GetTrue()} : nullptr;
|
||||
}
|
||||
|
||||
Frame* f = new Frame(frame_size, this, args);
|
||||
auto f = make_intrusive<Frame>(frame_size, this, args);
|
||||
|
||||
if ( closure )
|
||||
f->CaptureClosure(closure, outer_ids);
|
||||
|
@ -346,7 +341,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
f->SetCall(parent->GetCall());
|
||||
}
|
||||
|
||||
g_frame_stack.push_back(f); // used for backtracing
|
||||
g_frame_stack.push_back(f.get()); // used for backtracing
|
||||
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
|
||||
call_stack.emplace_back(CallInfo{call_expr, this, args});
|
||||
|
||||
|
@ -360,7 +355,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
}
|
||||
|
||||
stmt_flow_type flow = FLOW_NEXT;
|
||||
Val* result = 0;
|
||||
IntrusivePtr<Val> result;
|
||||
|
||||
for ( const auto& body : bodies )
|
||||
{
|
||||
|
@ -368,8 +363,6 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
sample_logger->LocationSeen(
|
||||
body.stmts->GetLocationInfo());
|
||||
|
||||
Unref(result);
|
||||
|
||||
// Fill in the rest of the frame with the function's arguments.
|
||||
loop_over_list(*args, j)
|
||||
{
|
||||
|
@ -387,7 +380,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
|
||||
try
|
||||
{
|
||||
result = body.stmts->Exec(f, flow).release();
|
||||
result = body.stmts->Exec(f.get(), flow);
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
@ -397,7 +390,6 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
{
|
||||
g_frame_stack.pop_back();
|
||||
call_stack.pop_back();
|
||||
Unref(f);
|
||||
// Result not set b/c exception was thrown
|
||||
throw;
|
||||
}
|
||||
|
@ -418,13 +410,12 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
{
|
||||
// Ignore any return values of hook bodies, final return value
|
||||
// depends on whether a body returns as a result of break statement.
|
||||
Unref(result);
|
||||
result = 0;
|
||||
result = nullptr;
|
||||
|
||||
if ( flow == FLOW_BREAK )
|
||||
{
|
||||
// Short-circuit execution of remaining hook handler bodies.
|
||||
result = val_mgr->GetFalse();
|
||||
result = {AdoptRef{}, val_mgr->GetFalse()};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -440,7 +431,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
if ( Flavor() == FUNC_FLAVOR_HOOK )
|
||||
{
|
||||
if ( ! result )
|
||||
result = val_mgr->GetTrue();
|
||||
result = {AdoptRef{}, val_mgr->GetTrue()};
|
||||
}
|
||||
|
||||
// Warn if the function returns something, but we returned from
|
||||
|
@ -462,25 +453,21 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
|
||||
g_frame_stack.pop_back();
|
||||
|
||||
Unref(f);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void BroFunc::AddBody(Stmt* new_body, id_list* new_inits,
|
||||
void BroFunc::AddBody(IntrusivePtr<Stmt> new_body, id_list* new_inits,
|
||||
size_t new_frame_size, int priority)
|
||||
{
|
||||
if ( new_frame_size > frame_size )
|
||||
frame_size = new_frame_size;
|
||||
|
||||
new_body = AddInits(new_body, new_inits);
|
||||
new_body = AddInits(std::move(new_body), new_inits);
|
||||
|
||||
if ( Flavor() == FUNC_FLAVOR_FUNCTION )
|
||||
{
|
||||
// For functions, we replace the old body with the new one.
|
||||
assert(bodies.size() <= 1);
|
||||
for ( const auto& body : bodies )
|
||||
Unref(body.stmts);
|
||||
bodies.clear();
|
||||
}
|
||||
|
||||
|
@ -552,13 +539,13 @@ bool BroFunc::UpdateClosure(const broker::vector& data)
|
|||
}
|
||||
|
||||
|
||||
Func* BroFunc::DoClone()
|
||||
IntrusivePtr<Func> BroFunc::DoClone()
|
||||
{
|
||||
// BroFunc could hold a closure. In this case a clone of it must
|
||||
// store a copy of this closure.
|
||||
BroFunc* other = new BroFunc();
|
||||
auto other = IntrusivePtr{AdoptRef{}, new BroFunc()};
|
||||
|
||||
CopyStateInto(other);
|
||||
CopyStateInto(other.get());
|
||||
|
||||
other->frame_size = frame_size;
|
||||
other->closure = closure ? closure->SelectiveClone(outer_ids, this) : nullptr;
|
||||
|
@ -586,14 +573,14 @@ void BroFunc::Describe(ODesc* d) const
|
|||
}
|
||||
}
|
||||
|
||||
Stmt* BroFunc::AddInits(Stmt* body, id_list* inits)
|
||||
IntrusivePtr<Stmt> BroFunc::AddInits(IntrusivePtr<Stmt> body, id_list* inits)
|
||||
{
|
||||
if ( ! inits || inits->length() == 0 )
|
||||
return body;
|
||||
|
||||
StmtList* stmt_series = new StmtList;
|
||||
auto stmt_series = make_intrusive<StmtList>();
|
||||
stmt_series->Stmts().push_back(new InitStmt(inits));
|
||||
stmt_series->Stmts().push_back(body);
|
||||
stmt_series->Stmts().push_back(body.release());
|
||||
|
||||
return stmt_series;
|
||||
}
|
||||
|
@ -612,7 +599,7 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name,
|
|||
if ( id->HasVal() )
|
||||
reporter->InternalError("built-in function %s multiply defined", Name());
|
||||
|
||||
type = id->Type()->Ref();
|
||||
type = {NewRef{}, id->Type()};
|
||||
id->SetVal(make_intrusive<Val>(this));
|
||||
}
|
||||
|
||||
|
@ -625,7 +612,7 @@ int BuiltinFunc::IsPure() const
|
|||
return is_pure;
|
||||
}
|
||||
|
||||
Val* BuiltinFunc::Call(val_list* args, Frame* parent) const
|
||||
IntrusivePtr<Val> BuiltinFunc::Call(val_list* args, Frame* parent) const
|
||||
{
|
||||
#ifdef PROFILE_BRO_FUNCTIONS
|
||||
DEBUG_MSG("Function: %s\n", Name());
|
||||
|
@ -642,7 +629,7 @@ Val* BuiltinFunc::Call(val_list* args, Frame* parent) const
|
|||
if ( plugin_result.first )
|
||||
{
|
||||
Val *result = plugin_result.second;
|
||||
return result;
|
||||
return {AdoptRef{}, result};
|
||||
}
|
||||
|
||||
if ( g_trace_state.DoTrace() )
|
||||
|
@ -655,7 +642,7 @@ Val* BuiltinFunc::Call(val_list* args, Frame* parent) const
|
|||
|
||||
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
|
||||
call_stack.emplace_back(CallInfo{call_expr, this, args});
|
||||
Val* result = func(parent, args);
|
||||
IntrusivePtr<Val> result{AdoptRef{}, func(parent, args)};
|
||||
call_stack.pop_back();
|
||||
|
||||
for ( const auto& arg : *args )
|
||||
|
@ -885,29 +872,22 @@ static int get_func_priority(const attr_list& attrs)
|
|||
return priority;
|
||||
}
|
||||
|
||||
function_ingredients::function_ingredients(Scope* scope, Stmt* body)
|
||||
function_ingredients::function_ingredients(IntrusivePtr<Scope> scope, IntrusivePtr<Stmt> body)
|
||||
{
|
||||
frame_size = scope->Length();
|
||||
inits = scope->GetInits();
|
||||
|
||||
this->scope = scope;
|
||||
::Ref(this->scope);
|
||||
id = scope->ScopeID();
|
||||
::Ref(id);
|
||||
this->scope = std::move(scope);
|
||||
id = {NewRef{}, this->scope->ScopeID()};
|
||||
|
||||
auto attrs = scope->Attrs();
|
||||
auto attrs = this->scope->Attrs();
|
||||
|
||||
priority = (attrs ? get_func_priority(*attrs) : 0);
|
||||
this->body = body;
|
||||
::Ref(this->body);
|
||||
this->body = std::move(body);
|
||||
}
|
||||
|
||||
function_ingredients::~function_ingredients()
|
||||
{
|
||||
Unref(id);
|
||||
Unref(body);
|
||||
Unref(scope);
|
||||
|
||||
for ( const auto& i : *inits )
|
||||
Unref(i);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue