mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 10:08:20 +00:00
"if ( ... ) &analyze" language feature
This commit is contained in:
parent
052cda9df0
commit
9f4da24644
6 changed files with 207 additions and 62 deletions
66
src/Var.cc
66
src/Var.cc
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "zeek/ActivationManager.h"
|
||||
#include "zeek/Desc.h"
|
||||
#include "zeek/EventRegistry.h"
|
||||
#include "zeek/Expr.h"
|
||||
|
@ -234,7 +235,7 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
|||
{
|
||||
if ( IsFunc(id->GetType()->Tag()) )
|
||||
add_prototype(id, t.get(), attr.get(), init);
|
||||
else
|
||||
else if ( activation_mgr->IsActivated() )
|
||||
id->Error("already defined", init.get());
|
||||
|
||||
return;
|
||||
|
@ -405,7 +406,18 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
|||
void add_global(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
||||
std::unique_ptr<std::vector<AttrPtr>> attr, DeclType dt)
|
||||
{
|
||||
make_var(id, std::move(t), c, std::move(init), std::move(attr), dt, true);
|
||||
bool do_init = activation_mgr->IsActivated();
|
||||
|
||||
if ( dt == VAR_REDEF )
|
||||
{
|
||||
activation_mgr->AddingRedef(id, c, init, attr);
|
||||
|
||||
if ( ! do_init )
|
||||
// Don't actually change the attributes.
|
||||
attr = nullptr;
|
||||
}
|
||||
|
||||
make_var(id, std::move(t), c, std::move(init), std::move(attr), dt, do_init);
|
||||
}
|
||||
|
||||
StmtPtr add_local(IDPtr id, TypePtr t, InitClass c, ExprPtr init,
|
||||
|
@ -711,6 +723,8 @@ void begin_func(IDPtr id, const char* module_name, FunctionFlavor flavor, bool i
|
|||
else if ( is_redef )
|
||||
id->Error("redef of not-previously-declared value");
|
||||
|
||||
bool is_activated = activation_mgr->IsActivated();
|
||||
|
||||
if ( id->HasVal() )
|
||||
{
|
||||
FunctionFlavor id_flavor = id->GetVal()->AsFunc()->Flavor();
|
||||
|
@ -724,12 +738,17 @@ void begin_func(IDPtr id, const char* module_name, FunctionFlavor flavor, bool i
|
|||
case FUNC_FLAVOR_EVENT:
|
||||
case FUNC_FLAVOR_HOOK:
|
||||
if ( is_redef )
|
||||
// Clear out value so it will be replaced.
|
||||
id->SetVal(nullptr);
|
||||
{
|
||||
activation_mgr->RedefingHandler(id);
|
||||
|
||||
if ( ! is_activated )
|
||||
// Clear out value so it will be replaced.
|
||||
id->SetVal(nullptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FUNC_FLAVOR_FUNCTION:
|
||||
if ( ! id->IsRedefinable() )
|
||||
if ( ! id->IsRedefinable() && is_activated )
|
||||
id->Error("already defined", t.get());
|
||||
break;
|
||||
|
||||
|
@ -753,12 +772,15 @@ void begin_func(IDPtr id, const char* module_name, FunctionFlavor flavor, bool i
|
|||
if ( ! check_params(i, prototype, args, canon_args, module_name) )
|
||||
break;
|
||||
|
||||
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(), ATTR_DEPRECATED) )
|
||||
current_scope()->GetID()->MakeDeprecated(depr_attr->GetExpr());
|
||||
if ( is_activated )
|
||||
{
|
||||
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(), ATTR_DEPRECATED) )
|
||||
current_scope()->GetID()->MakeDeprecated(depr_attr->GetExpr());
|
||||
|
||||
// Reset the AST node statistics to track afresh for this function.
|
||||
Stmt::ResetNumStmts();
|
||||
Expr::ResetNumExprs();
|
||||
// Reset the AST node statistics to track afresh for this function.
|
||||
Stmt::ResetNumStmts();
|
||||
Expr::ResetNumExprs();
|
||||
}
|
||||
}
|
||||
|
||||
class OuterIDBindingFinder : public TraversalCallback
|
||||
|
@ -846,7 +868,7 @@ void end_func(StmtPtr body, const char* module_name, bool free_of_conditionals)
|
|||
oi->num_stmts = Stmt::GetNumStmts();
|
||||
oi->num_exprs = Expr::GetNumExprs();
|
||||
|
||||
auto ingredients = std::make_unique<FunctionIngredients>(pop_scope(), std::move(body),
|
||||
auto ingredients = std::make_shared<FunctionIngredients>(pop_scope(), std::move(body),
|
||||
module_name);
|
||||
auto id = ingredients->GetID();
|
||||
if ( ! id->HasVal() )
|
||||
|
@ -854,27 +876,27 @@ void end_func(StmtPtr body, const char* module_name, bool free_of_conditionals)
|
|||
auto f = make_intrusive<ScriptFunc>(id);
|
||||
id->SetVal(make_intrusive<FuncVal>(std::move(f)));
|
||||
id->SetConst();
|
||||
activation_mgr->AddingGlobalVal(id);
|
||||
}
|
||||
|
||||
id->GetVal()->AsFunc()->AddBody(ingredients->Body(), ingredients->Inits(),
|
||||
ingredients->FrameSize(), ingredients->Priority(),
|
||||
ingredients->Groups());
|
||||
|
||||
script_coverage_mgr.AddFunction(id, ingredients->Body());
|
||||
|
||||
auto func_ptr = cast_intrusive<FuncVal>(id->GetVal())->AsFuncPtr();
|
||||
auto func = cast_intrusive<ScriptFunc>(func_ptr);
|
||||
func->SetScope(ingredients->Scope());
|
||||
|
||||
for ( const auto& group : ingredients->Groups() )
|
||||
group->AddFunc(func);
|
||||
activation_mgr->AddingBody(id, ingredients);
|
||||
|
||||
analyze_func(std::move(func));
|
||||
if ( activation_mgr->IsActivated() )
|
||||
{
|
||||
func->AddBody(ingredients->Body(), ingredients->Inits(), ingredients->FrameSize(),
|
||||
ingredients->Priority(), ingredients->Groups());
|
||||
|
||||
// Note: ideally, something would take ownership of this memory until the
|
||||
// end of script execution, but that's essentially the same as the
|
||||
// lifetime of the process at the moment, so ok to "leak" it.
|
||||
ingredients.release();
|
||||
for ( const auto& group : ingredients->Groups() )
|
||||
group->AddFunc(func);
|
||||
|
||||
analyze_func(std::move(func));
|
||||
}
|
||||
}
|
||||
|
||||
IDPList gather_outer_ids(ScopePtr scope, StmtPtr body)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue