Branch data Line data Source code
1 : : // $Id: Stmt.h 6916 2009-09-24 20:48:36Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef stmt_h
6 : : #define stmt_h
7 : :
8 : : // BRO statements.
9 : :
10 : : #include "BroList.h"
11 : : #include "Obj.h"
12 : : #include "Expr.h"
13 : :
14 : : #include "StmtEnums.h"
15 : :
16 : : #include "TraverseTypes.h"
17 : :
18 : : class StmtList;
19 : : class ForStmt;
20 : :
21 : : class Stmt : public BroObj {
22 : : public:
23 : 0 : BroStmtTag Tag() const { return tag; }
24 : :
25 : : virtual ~Stmt();
26 : :
27 : : virtual Val* Exec(Frame* f, stmt_flow_type& flow) const = 0;
28 : :
29 : 0 : Stmt* Ref() { ::Ref(this); return this; }
30 : :
31 : 6757 : bool SetLocationInfo(const Location* loc)
32 : 6757 : { return Stmt::SetLocationInfo(loc, loc); }
33 : : bool SetLocationInfo(const Location* start, const Location* end);
34 : :
35 : : // Returns a fully simplified version of the statement (this
36 : : // may be the same statement, or a newly created one).
37 : : virtual Stmt* Simplify();
38 : :
39 : : // True if the statement has no side effects, false otherwise.
40 : : virtual int IsPure() const;
41 : :
42 : 5540 : StmtList* AsStmtList()
43 : : {
44 [ - + ]: 5540 : CHECK_TAG(tag, STMT_LIST, "Stmt::AsStmtList", stmt_name)
45 : 5540 : return (StmtList*) this;
46 : : }
47 : :
48 : 123 : ForStmt* AsForStmt()
49 : : {
50 [ - + ]: 123 : CHECK_TAG(tag, STMT_FOR, "Stmt::AsForStmt", stmt_name)
51 : 123 : return (ForStmt*) this;
52 : : }
53 : :
54 : 782263 : void RegisterAccess() const { last_access = network_time; access_count++; }
55 : : void AccessStats(ODesc* d) const;
56 : :
57 : : virtual void Describe(ODesc* d) const;
58 : :
59 : 0 : virtual void IncrBPCount() { ++breakpoint_count; }
60 : 0 : virtual void DecrBPCount()
61 : : {
62 [ # # ]: 0 : if ( breakpoint_count )
63 : 0 : --breakpoint_count;
64 : : else
65 : 0 : internal_error("breakpoint count decremented below 0");
66 : 0 : }
67 : :
68 : 0 : virtual unsigned int BPCount() const { return breakpoint_count; }
69 : :
70 : : bool Serialize(SerialInfo* info) const;
71 : : static Stmt* Unserialize(UnserialInfo* info, BroStmtTag want = STMT_ANY);
72 : :
73 : : virtual TraversalCode Traverse(TraversalCallback* cb) const = 0;
74 : :
75 : : protected:
76 : 0 : Stmt() {}
77 : : Stmt(BroStmtTag arg_tag);
78 : :
79 : : void AddTag(ODesc* d) const;
80 : : void DescribeDone(ODesc* d) const;
81 : :
82 : : DECLARE_ABSTRACT_SERIAL(Stmt);
83 : :
84 : : BroStmtTag tag;
85 : : int breakpoint_count; // how many breakpoints on this statement
86 : :
87 : : // FIXME: Learn the exact semantics of mutable.
88 : : mutable double last_access; // time of last execution
89 : : mutable uint32 access_count; // number of executions
90 : : };
91 : :
92 : : class ExprListStmt : public Stmt {
93 : : public:
94 : 0 : const ListExpr* ExprList() const { return l; }
95 : :
96 : : TraversalCode Traverse(TraversalCallback* cb) const;
97 : :
98 : : protected:
99 : 0 : ExprListStmt() { l = 0; }
100 : : ExprListStmt(BroStmtTag t, ListExpr* arg_l);
101 : :
102 : : virtual ~ExprListStmt();
103 : :
104 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
105 : : virtual Val* DoExec(val_list* vals, stmt_flow_type& flow) const = 0;
106 : :
107 : : Stmt* Simplify();
108 : : virtual Stmt* DoSimplify();
109 : :
110 : : void Describe(ODesc* d) const;
111 : : void PrintVals(ODesc* d, val_list* vals, int offset) const;
112 : :
113 : : DECLARE_ABSTRACT_SERIAL(ExprListStmt);
114 : :
115 : : ListExpr* l;
116 : : };
117 : :
118 [ # # ][ # # ]: 0 : class AlarmStmt : public ExprListStmt {
119 : : public:
120 : 9 : AlarmStmt(ListExpr* l) : ExprListStmt(STMT_ALARM, l) { }
121 : :
122 : : protected:
123 : : friend class Stmt;
124 : 0 : AlarmStmt() {}
125 : :
126 : : Val* DoExec(val_list* vals, stmt_flow_type& flow) const;
127 : :
128 : 0 : DECLARE_SERIAL(AlarmStmt);
129 : : };
130 : :
131 [ # # ][ # # ]: 0 : class PrintStmt : public ExprListStmt {
132 : : public:
133 : 272 : PrintStmt(ListExpr* l) : ExprListStmt(STMT_PRINT, l) { }
134 : :
135 : : protected:
136 : : friend class Stmt;
137 : 0 : PrintStmt() {}
138 : :
139 : : Val* DoExec(val_list* vals, stmt_flow_type& flow) const;
140 : :
141 : 0 : DECLARE_SERIAL(PrintStmt);
142 : : };
143 : :
144 : : class ExprStmt : public Stmt {
145 : : public:
146 : : ExprStmt(Expr* e);
147 : : virtual ~ExprStmt();
148 : :
149 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
150 : :
151 : 0 : const Expr* StmtExpr() const { return e; }
152 : :
153 : : void Describe(ODesc* d) const;
154 : :
155 : : TraversalCode Traverse(TraversalCallback* cb) const;
156 : :
157 : : protected:
158 : : friend class Stmt;
159 : 0 : ExprStmt() { e = 0; }
160 : : ExprStmt(BroStmtTag t, Expr* e);
161 : :
162 : : virtual Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const;
163 : :
164 : : Stmt* Simplify();
165 : : int IsPure() const;
166 : :
167 : : // Called by Simplify(), after the expression's been simplified.
168 : : virtual Stmt* DoSimplify();
169 : :
170 : 0 : DECLARE_SERIAL(ExprStmt);
171 : :
172 : : Expr* e;
173 : : };
174 : :
175 : : class IfStmt : public ExprStmt {
176 : : public:
177 : : IfStmt(Expr* test, Stmt* s1, Stmt* s2);
178 : : ~IfStmt();
179 : :
180 : 0 : const Stmt* TrueBranch() const { return s1; }
181 : 0 : const Stmt* FalseBranch() const { return s2; }
182 : :
183 : : void Describe(ODesc* d) const;
184 : :
185 : : TraversalCode Traverse(TraversalCallback* cb) const;
186 : :
187 : : protected:
188 : : friend class Stmt;
189 : 0 : IfStmt() { s1 = s2 = 0; }
190 : :
191 : : Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const;
192 : : Stmt* DoSimplify();
193 : : int IsPure() const;
194 : :
195 : 0 : DECLARE_SERIAL(IfStmt);
196 : :
197 : : Stmt* s1;
198 : : Stmt* s2;
199 : : };
200 : :
201 : : class Case : public BroObj {
202 : : public:
203 : 0 : Case(ListExpr* c, Stmt* arg_s) { cases = c; s = arg_s; }
204 : : ~Case();
205 : :
206 : 0 : const ListExpr* Cases() const { return cases; }
207 : 0 : ListExpr* Cases() { return cases; }
208 : :
209 : 0 : const Stmt* Body() const { return s; }
210 : 0 : Stmt* Body() { return s; }
211 : :
212 : : void Describe(ODesc* d) const;
213 : :
214 : : bool Serialize(SerialInfo* info) const;
215 : : static Case* Unserialize(UnserialInfo* info);
216 : :
217 : : TraversalCode Traverse(TraversalCallback* cb) const;
218 : :
219 : : protected:
220 : : friend class Stmt;
221 : 0 : Case() { cases = 0; s = 0; }
222 : :
223 : 0 : DECLARE_SERIAL(Case);
224 : :
225 : : ListExpr* cases;
226 : : Stmt* s;
227 : : };
228 : :
229 : : class SwitchStmt : public ExprStmt {
230 : : public:
231 : : SwitchStmt(Expr* index, case_list* cases);
232 : : ~SwitchStmt();
233 : :
234 : 0 : const case_list* Cases() const { return cases; }
235 : :
236 : : void Describe(ODesc* d) const;
237 : :
238 : : TraversalCode Traverse(TraversalCallback* cb) const;
239 : :
240 : : protected:
241 : : friend class Stmt;
242 : 0 : SwitchStmt() { cases = 0; }
243 : :
244 : : Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const;
245 : : Stmt* DoSimplify();
246 : : int IsPure() const;
247 : :
248 : 0 : DECLARE_SERIAL(SwitchStmt);
249 : :
250 : : case_list* cases;
251 : : };
252 : :
253 [ # # ][ # # ]: 0 : class AddStmt : public ExprStmt {
254 : : public:
255 : : AddStmt(Expr* e);
256 : :
257 : : int IsPure() const;
258 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
259 : :
260 : : TraversalCode Traverse(TraversalCallback* cb) const;
261 : :
262 : : protected:
263 : : friend class Stmt;
264 : 0 : AddStmt() {}
265 : :
266 : 0 : DECLARE_SERIAL(AddStmt);
267 : : };
268 : :
269 [ # # ][ # # ]: 0 : class DelStmt : public ExprStmt {
270 : : public:
271 : : DelStmt(Expr* e);
272 : :
273 : : int IsPure() const;
274 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
275 : :
276 : : TraversalCode Traverse(TraversalCallback* cb) const;
277 : :
278 : : protected:
279 : : friend class Stmt;
280 : 0 : DelStmt() {}
281 : :
282 : 0 : DECLARE_SERIAL(DelStmt);
283 : : };
284 : :
285 [ # # ][ # # ]: 0 : class EventStmt : public ExprStmt {
286 : : public:
287 : : EventStmt(EventExpr* e);
288 : :
289 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
290 : :
291 : : TraversalCode Traverse(TraversalCallback* cb) const;
292 : :
293 : : protected:
294 : : friend class Stmt;
295 : 0 : EventStmt() { event_expr = 0; }
296 : :
297 : 0 : DECLARE_SERIAL(EventStmt);
298 : :
299 : : EventExpr* event_expr;
300 : : };
301 : :
302 : : class ForStmt : public ExprStmt {
303 : : public:
304 : : ForStmt(id_list* loop_vars, Expr* loop_expr);
305 : : ~ForStmt();
306 : :
307 : 123 : void AddBody(Stmt* arg_body) { body = arg_body; }
308 : :
309 : 0 : const id_list* LoopVar() const { return loop_vars; }
310 : 0 : const Expr* LoopExpr() const { return e; }
311 : 0 : const Stmt* LoopBody() const { return body; }
312 : :
313 : : int IsPure() const;
314 : :
315 : : void Describe(ODesc* d) const;
316 : :
317 : : TraversalCode Traverse(TraversalCallback* cb) const;
318 : :
319 : : protected:
320 : : friend class Stmt;
321 : 0 : ForStmt() { loop_vars = 0; body = 0; }
322 : :
323 : : Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const;
324 : : Stmt* DoSimplify();
325 : :
326 : 0 : DECLARE_SERIAL(ForStmt);
327 : :
328 : : id_list* loop_vars;
329 : : Stmt* body;
330 : : };
331 : :
332 [ # # ][ # # ]: 0 : class NextStmt : public Stmt {
333 : : public:
334 : 8 : NextStmt() : Stmt(STMT_NEXT) { }
335 : :
336 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
337 : : int IsPure() const;
338 : :
339 : : void Describe(ODesc* d) const;
340 : :
341 : : TraversalCode Traverse(TraversalCallback* cb) const;
342 : :
343 : : protected:
344 : 0 : DECLARE_SERIAL(NextStmt);
345 : : };
346 : :
347 [ # # ][ # # ]: 0 : class BreakStmt : public Stmt {
348 : : public:
349 : 3 : BreakStmt() : Stmt(STMT_BREAK) { }
350 : :
351 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
352 : : int IsPure() const;
353 : :
354 : : void Describe(ODesc* d) const;
355 : :
356 : : TraversalCode Traverse(TraversalCallback* cb) const;
357 : :
358 : : protected:
359 : 0 : DECLARE_SERIAL(BreakStmt);
360 : : };
361 : :
362 [ + - ][ # # ]: 1 : class ReturnStmt : public ExprStmt {
363 : : public:
364 : : ReturnStmt(Expr* e);
365 : :
366 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
367 : :
368 : : void Describe(ODesc* d) const;
369 : :
370 : : protected:
371 : : friend class Stmt;
372 : 0 : ReturnStmt() {}
373 : :
374 : 0 : DECLARE_SERIAL(ReturnStmt);
375 : : };
376 : :
377 : : class StmtList : public Stmt {
378 : : public:
379 : : StmtList();
380 : : ~StmtList();
381 : :
382 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
383 : :
384 : 0 : const stmt_list& Stmts() const { return stmts; }
385 : 5694 : stmt_list& Stmts() { return stmts; }
386 : :
387 : : void Describe(ODesc* d) const;
388 : :
389 : : TraversalCode Traverse(TraversalCallback* cb) const;
390 : :
391 : : protected:
392 : : Stmt* Simplify();
393 : : int IsPure() const;
394 : :
395 : 0 : DECLARE_SERIAL(StmtList);
396 : :
397 : : stmt_list stmts;
398 : : };
399 : :
400 [ # # ][ # # ]: 0 : class EventBodyList : public StmtList {
401 : : public:
402 : 0 : EventBodyList() : StmtList()
403 : 0 : { topmost = false; tag = STMT_EVENT_BODY_LIST; }
404 : :
405 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
406 : :
407 : : void Describe(ODesc* d) const;
408 : :
409 : : // "Topmost" means that this is the main body of a function or event.
410 : : // void SetTopmost(bool is_topmost) { topmost = is_topmost; }
411 : : // bool IsTopmost() { return topmost; }
412 : :
413 : : protected:
414 : : Stmt* Simplify();
415 : :
416 : 0 : DECLARE_SERIAL(EventBodyList);
417 : :
418 : : bool topmost;
419 : : };
420 : :
421 : : class InitStmt : public Stmt {
422 : : public:
423 : 77 : InitStmt(id_list* arg_inits) : Stmt(STMT_INIT)
424 : : {
425 : 77 : inits = arg_inits;
426 [ + - + - ]: 77 : if ( arg_inits && arg_inits->length() )
[ + - ]
427 : 77 : SetLocationInfo((*arg_inits)[0]->GetLocationInfo());
428 : 77 : }
429 : :
430 : : ~InitStmt();
431 : :
432 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
433 : :
434 : 0 : const id_list* Inits() const { return inits; }
435 : :
436 : : void Describe(ODesc* d) const;
437 : :
438 : : TraversalCode Traverse(TraversalCallback* cb) const;
439 : :
440 : : protected:
441 : : friend class Stmt;
442 : 0 : InitStmt() { inits = 0; }
443 : :
444 : 0 : DECLARE_SERIAL(InitStmt);
445 : :
446 : : id_list* inits;
447 : : };
448 : :
449 [ + - ][ # # ]: 107 : class NullStmt : public Stmt {
450 : : public:
451 : 1551 : NullStmt() : Stmt(STMT_NULL) { }
452 : :
453 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
454 : : int IsPure() const;
455 : :
456 : : void Describe(ODesc* d) const;
457 : :
458 : : TraversalCode Traverse(TraversalCallback* cb) const;
459 : :
460 : : protected:
461 : 0 : DECLARE_SERIAL(NullStmt);
462 : : };
463 : :
464 : : class WhenStmt : public Stmt {
465 : : public:
466 : : // s2 is null if no timeout block given.
467 : : WhenStmt(Expr* cond, Stmt* s1, Stmt* s2, Expr* timeout, bool is_return);
468 : : ~WhenStmt();
469 : :
470 : : Val* Exec(Frame* f, stmt_flow_type& flow) const;
471 : : int IsPure() const;
472 : : Stmt* Simplify();
473 : :
474 : 0 : const Expr* Cond() const { return cond; }
475 : 0 : const Stmt* Body() const { return s1; }
476 : 0 : const Expr* TimeoutExpr() const { return timeout; }
477 : 0 : const Stmt* TimeoutBody() const { return s2; }
478 : :
479 : : void Describe(ODesc* d) const;
480 : :
481 : : TraversalCode Traverse(TraversalCallback* cb) const;
482 : :
483 : : protected:
484 : 0 : WhenStmt() { cond = 0; s1 = s2 = 0; timeout = 0; is_return = 0; }
485 : :
486 : 0 : DECLARE_SERIAL(WhenStmt);
487 : :
488 : : Expr* cond;
489 : : Stmt* s1;
490 : : Stmt* s2;
491 : : Expr* timeout;
492 : : bool is_return;
493 : : };
494 : :
495 : : extern Stmt* simplify_stmt(Stmt* s);
496 : : extern int same_stmt(const Stmt* s1, const Stmt* s2);
497 : :
498 : : #endif
|