mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
tracking of when statements/expressions occur in a "when" context
This commit is contained in:
parent
5a32e58e04
commit
9ada7ac4e7
6 changed files with 45 additions and 17 deletions
10
src/Expr.cc
10
src/Expr.cc
|
@ -2830,8 +2830,10 @@ ValPtr IndexSliceAssignExpr::Eval(Frame* f) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
IndexExpr::IndexExpr(ExprPtr arg_op1, ListExprPtr arg_op2, bool arg_is_slice)
|
||||
: BinaryExpr(EXPR_INDEX, std::move(arg_op1), std::move(arg_op2)), is_slice(arg_is_slice)
|
||||
IndexExpr::IndexExpr(ExprPtr arg_op1, ListExprPtr arg_op2, bool arg_is_slice,
|
||||
bool arg_is_inside_when)
|
||||
: BinaryExpr(EXPR_INDEX, std::move(arg_op1), std::move(arg_op2)), is_slice(arg_is_slice),
|
||||
is_inside_when(arg_is_inside_when)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
@ -4467,8 +4469,8 @@ ValPtr InExpr::Fold(Val* v1, Val* v2) const
|
|||
return val_mgr->Bool(res);
|
||||
}
|
||||
|
||||
CallExpr::CallExpr(ExprPtr arg_func, ListExprPtr arg_args, bool in_hook)
|
||||
: Expr(EXPR_CALL), func(std::move(arg_func)), args(std::move(arg_args))
|
||||
CallExpr::CallExpr(ExprPtr arg_func, ListExprPtr arg_args, bool in_hook, bool _in_when)
|
||||
: Expr(EXPR_CALL), func(std::move(arg_func)), args(std::move(arg_args)), in_when(_in_when)
|
||||
{
|
||||
if ( func->IsError() || args->IsError() )
|
||||
{
|
||||
|
|
17
src/Expr.h
17
src/Expr.h
|
@ -1005,7 +1005,7 @@ public:
|
|||
class IndexExpr : public BinaryExpr
|
||||
{
|
||||
public:
|
||||
IndexExpr(ExprPtr op1, ListExprPtr op2, bool is_slice = false);
|
||||
IndexExpr(ExprPtr op1, ListExprPtr op2, bool is_slice = false, bool is_inside_when = false);
|
||||
|
||||
bool CanAdd() const override;
|
||||
bool CanDel() const override;
|
||||
|
@ -1021,6 +1021,7 @@ public:
|
|||
ValPtr Eval(Frame* f) const override;
|
||||
|
||||
bool IsSlice() const { return is_slice; }
|
||||
bool IsInsideWhen() const { return is_inside_when; }
|
||||
|
||||
// Optimization-related:
|
||||
ExprPtr Duplicate() override;
|
||||
|
@ -1034,6 +1035,7 @@ protected:
|
|||
void ExprDescribe(ODesc* d) const override;
|
||||
|
||||
bool is_slice;
|
||||
bool is_inside_when;
|
||||
};
|
||||
|
||||
// The following execute the heart of IndexExpr functionality for
|
||||
|
@ -1059,6 +1061,13 @@ extern VectorValPtr vector_bool_select(VectorTypePtr vt, const VectorVal* v1, co
|
|||
// indices to select).
|
||||
extern VectorValPtr vector_int_select(VectorTypePtr vt, const VectorVal* v1, const VectorVal* v2);
|
||||
|
||||
// The following is used for index expressions that occur inside "when"
|
||||
// clauses. It tracks all the results produced by evaluating indexing
|
||||
// aggregates, so that if any of them are Modifiable(), the associated
|
||||
// Trigger can register interest in changes to them.
|
||||
//
|
||||
// One Fine Day we should do the equivalent for accessing fields in records,
|
||||
// too.
|
||||
class IndexExprWhen final : public IndexExpr
|
||||
{
|
||||
public:
|
||||
|
@ -1077,7 +1086,7 @@ public:
|
|||
}
|
||||
|
||||
IndexExprWhen(ExprPtr op1, ListExprPtr op2, bool is_slice = false)
|
||||
: IndexExpr(std::move(op1), std::move(op2), is_slice)
|
||||
: IndexExpr(std::move(op1), std::move(op2), is_slice, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1398,13 +1407,14 @@ protected:
|
|||
class CallExpr final : public Expr
|
||||
{
|
||||
public:
|
||||
CallExpr(ExprPtr func, ListExprPtr args, bool in_hook = false);
|
||||
CallExpr(ExprPtr func, ListExprPtr args, bool in_hook = false, bool in_when = false);
|
||||
|
||||
Expr* Func() const { return func.get(); }
|
||||
ListExpr* Args() const { return args.get(); }
|
||||
ListExprPtr ArgsPtr() const { return args; }
|
||||
|
||||
bool IsPure() const override;
|
||||
bool IsInWhen() const { return in_when; }
|
||||
|
||||
ValPtr Eval(Frame* f) const override;
|
||||
|
||||
|
@ -1424,6 +1434,7 @@ protected:
|
|||
|
||||
ExprPtr func;
|
||||
ListExprPtr args;
|
||||
bool in_when;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
14
src/parse.y
14
src/parse.y
|
@ -5,7 +5,7 @@
|
|||
// Switching parser table type fixes ambiguity problems.
|
||||
%define lr.type ielr
|
||||
|
||||
%expect 196
|
||||
%expect 195
|
||||
|
||||
%token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY
|
||||
%token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF
|
||||
|
@ -13,7 +13,8 @@
|
|||
%token TOK_CONSTANT TOK_COPY TOK_COUNT TOK_DEFAULT TOK_DELETE
|
||||
%token TOK_DOUBLE TOK_ELSE TOK_ENUM TOK_EVENT TOK_EXPORT TOK_FALLTHROUGH
|
||||
%token TOK_FILE TOK_FOR TOK_FUNCTION TOK_GLOBAL TOK_HOOK TOK_ID TOK_IF TOK_INT
|
||||
%token TOK_INTERVAL TOK_LIST TOK_LOCAL TOK_MODULE
|
||||
%token TOK_INTERVAL TOK_LIST TOK_MODULE
|
||||
%token TOK_LOCAL TOK_WHEN_LOCAL
|
||||
%token TOK_NEXT TOK_OF TOK_OPAQUE TOK_PATTERN TOK_PATTERN_END TOK_PATTERN_TEXT
|
||||
%token TOK_PORT TOK_PRINT TOK_RECORD TOK_REDEF
|
||||
%token TOK_REMOVE_FROM TOK_RETURN TOK_SCHEDULE TOK_SET
|
||||
|
@ -111,7 +112,7 @@ extern int conditional_epoch; // let's us track embedded conditionals
|
|||
// Whether the file we're currently parsing includes @if conditionals.
|
||||
extern bool current_file_has_conditionals;
|
||||
|
||||
YYLTYPE GetCurrentLocation();
|
||||
extern YYLTYPE GetCurrentLocation();
|
||||
extern int yyerror(const char[]);
|
||||
extern int brolex();
|
||||
|
||||
|
@ -133,7 +134,8 @@ extern Expr* g_curr_debug_expr;
|
|||
extern bool in_debug;
|
||||
extern const char* g_curr_debug_error;
|
||||
|
||||
static int in_when_cond = 0;
|
||||
extern int in_when_cond;
|
||||
|
||||
static int in_hook = 0;
|
||||
int in_init = 0;
|
||||
int in_record = 0;
|
||||
|
@ -618,7 +620,7 @@ expr:
|
|||
$$ = get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $3}, in_init).release();
|
||||
}
|
||||
|
||||
| TOK_LOCAL local_id '=' rhs
|
||||
| TOK_WHEN_LOCAL local_id '=' rhs
|
||||
{
|
||||
set_location(@2, @4);
|
||||
if ( ! locals_at_this_scope.empty() )
|
||||
|
@ -780,7 +782,7 @@ expr:
|
|||
}
|
||||
|
||||
else
|
||||
$$ = new CallExpr({AdoptRef{}, $1}, {AdoptRef{}, $4}, in_hook > 0);
|
||||
$$ = new CallExpr({AdoptRef{}, $1}, {AdoptRef{}, $4}, in_hook > 0, in_when_cond);
|
||||
}
|
||||
|
||||
| TOK_HOOK { ++in_hook; } expr
|
||||
|
|
|
@ -68,6 +68,10 @@ std::unordered_set<std::string> files_with_conditionals;
|
|||
|
||||
zeek::detail::int_list if_stack;
|
||||
|
||||
// Whether we're parsing a "when" conditional, for which we treat
|
||||
// the "local" keyword differently.
|
||||
int in_when_cond = 0;
|
||||
|
||||
int line_number = 1;
|
||||
const char* filename = 0; // Absolute path of file currently being parsed.
|
||||
const char* last_filename = 0; // Absolute path of last file parsed.
|
||||
|
@ -278,7 +282,7 @@ int return TOK_INT;
|
|||
interval return TOK_INTERVAL;
|
||||
is return TOK_IS;
|
||||
list return TOK_LIST;
|
||||
local return TOK_LOCAL;
|
||||
local return in_when_cond ? TOK_WHEN_LOCAL : TOK_LOCAL;
|
||||
module return TOK_MODULE;
|
||||
next return TOK_NEXT;
|
||||
of return TOK_OF;
|
||||
|
@ -586,7 +590,8 @@ YYLTYPE zeek::detail::GetCurrentLocation()
|
|||
return currloc;
|
||||
}
|
||||
|
||||
void zeek::detail::SetCurrentLocation(YYLTYPE currloc) {
|
||||
void zeek::detail::SetCurrentLocation(YYLTYPE currloc)
|
||||
{
|
||||
::filename = currloc.filename;
|
||||
line_number = currloc.first_line;
|
||||
}
|
||||
|
|
|
@ -1863,7 +1863,7 @@ ExprPtr IndexExpr::Duplicate()
|
|||
{
|
||||
auto op1_d = op1->Duplicate();
|
||||
auto op2_l = op2->Duplicate()->AsListExprPtr();
|
||||
return SetSucc(new IndexExpr(op1_d, op2_l, is_slice));
|
||||
return SetSucc(new IndexExpr(op1_d, op2_l, is_slice, is_inside_when));
|
||||
}
|
||||
|
||||
bool IndexExpr::HasReducedOps(Reducer* c) const
|
||||
|
|
|
@ -129,7 +129,15 @@ TraversalCode ProfileFunc::PreStmt(const Stmt* s)
|
|||
return TC_ABORTSTMT;
|
||||
|
||||
case STMT_WHEN:
|
||||
{
|
||||
++num_when_stmts;
|
||||
|
||||
auto w = s->AsWhenStmt();
|
||||
auto wi = w->Info();
|
||||
auto wl = wi ? wi->Lambda() : nullptr;
|
||||
if ( wl )
|
||||
lambdas.push_back(wl.get());
|
||||
}
|
||||
break;
|
||||
|
||||
case STMT_FOR:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue