mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
Merge branch 'leaks' of https://github.com/MaxKellermann/zeek
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:
commit
cf196bb148
41 changed files with 1864 additions and 2095 deletions
54
CHANGES
54
CHANGES
|
@ -1,4 +1,58 @@
|
||||||
|
|
||||||
|
3.2.0-dev.190 | 2020-02-28 00:42:17 -0800
|
||||||
|
|
||||||
|
* Stmt: use class IntrusivePtr (Max Kellermann)
|
||||||
|
|
||||||
|
* Stmt: remove unused default constructors and `friend` declarations (Max Kellermann)
|
||||||
|
|
||||||
|
* Val: remove unimplemented prototype recover_val() (Max Kellermann)
|
||||||
|
|
||||||
|
* Val: cast_value_to_type() returns IntrusivePtr (Max Kellermann)
|
||||||
|
|
||||||
|
* Val: use IntrusivePtr in check_and_promote() (Max Kellermann)
|
||||||
|
|
||||||
|
* Val: use nullptr instead of 0 (Max Kellermann)
|
||||||
|
|
||||||
|
* zeekygen: use class IntrusivePtr (Max Kellermann)
|
||||||
|
|
||||||
|
* ID: use class IntrusivePtr (Max Kellermann)
|
||||||
|
|
||||||
|
* Expr: use class IntrusivePtr (Max Kellermann)
|
||||||
|
|
||||||
|
* Var: copy Location to stack, to fix use-after-free crash bug (Max Kellermann)
|
||||||
|
|
||||||
|
* Scope: lookup_ID() and install_ID() return IntrusivePtr<ID> (Max Kellermann)
|
||||||
|
|
||||||
|
* Scope: delete duplicate locals (Max Kellermann)
|
||||||
|
|
||||||
|
* EventRegistry: automatically delete EventHandlers (Max Kellermann)
|
||||||
|
|
||||||
|
* main: destroy event_registry after iosource_mgr (Max Kellermann)
|
||||||
|
|
||||||
|
Fixes use-after-free bugs because PcapSource::Close() queues an event.
|
||||||
|
|
||||||
|
* zeekygen/IdentifierInfo: delete duplicate fields (Max Kellermann)
|
||||||
|
|
||||||
|
* main: free the global scope in terminate_bro() (Max Kellermann)
|
||||||
|
|
||||||
|
Make valgrind a bit happier.
|
||||||
|
|
||||||
|
* Scope: pop_scope() returns IntrusivePtr<> (Max Kellermann)
|
||||||
|
|
||||||
|
* Scope: unref all inits in destructor (Max Kellermann)
|
||||||
|
|
||||||
|
* Var: pass IntrusivePtr to add_global(), add_local() etc. (Max Kellermann)
|
||||||
|
|
||||||
|
* plugin/ComponentManager: hold a reference to the EnumType (Max Kellermann)
|
||||||
|
|
||||||
|
Use class IntrusivePtr<>.
|
||||||
|
|
||||||
|
* Type: fix use-after-free bug in VectorType::ShallowClone() (Max Kellermann)
|
||||||
|
|
||||||
|
The new VectorType instance needs a new reference to the `yield_type`.
|
||||||
|
|
||||||
|
* Var: fix crash when redeclaring a function with different args (Max Kellermann)
|
||||||
|
|
||||||
3.2.0-dev.167 | 2020-02-27 14:24:55 -0800
|
3.2.0-dev.167 | 2020-02-27 14:24:55 -0800
|
||||||
|
|
||||||
* Expr: use fmt instead of sprintf (Tim Wojtulewicz, Corelight)
|
* Expr: use fmt instead of sprintf (Tim Wojtulewicz, Corelight)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
3.2.0-dev.167
|
3.2.0-dev.190
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
#include "Desc.h"
|
#include "Desc.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "threading/SerialTypes.h"
|
#include "threading/SerialTypes.h"
|
||||||
|
|
||||||
const char* attr_name(attr_tag t)
|
const char* attr_name(attr_tag t)
|
||||||
|
@ -109,10 +110,8 @@ void Attr::DescribeReST(ODesc* d, bool shorten) const
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Val* v = expr->Eval(0);
|
|
||||||
ODesc dd;
|
ODesc dd;
|
||||||
v->Describe(&dd);
|
expr->Eval(nullptr)->Describe(&dd);
|
||||||
Unref(v);
|
|
||||||
string s = dd.Description();
|
string s = dd.Description();
|
||||||
|
|
||||||
for ( size_t i = 0; i < s.size(); ++i )
|
for ( size_t i = 0; i < s.size(); ++i )
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "Scope.h"
|
#include "Scope.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
#include "Stmt.h"
|
#include "Stmt.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
@ -246,7 +247,7 @@ BreakCode DbgBreakpoint::HasHit()
|
||||||
if ( condition.size() )
|
if ( condition.size() )
|
||||||
{
|
{
|
||||||
// TODO: ### evaluate using debugger frame too
|
// TODO: ### evaluate using debugger frame too
|
||||||
Val* yes = dbg_eval_expr(condition.c_str());
|
auto yes = dbg_eval_expr(condition.c_str());
|
||||||
|
|
||||||
if ( ! yes )
|
if ( ! yes )
|
||||||
{
|
{
|
||||||
|
@ -260,7 +261,6 @@ BreakCode DbgBreakpoint::HasHit()
|
||||||
if ( ! IsIntegral(yes->Type()->Tag()) &&
|
if ( ! IsIntegral(yes->Type()->Tag()) &&
|
||||||
! IsBool(yes->Type()->Tag()) )
|
! IsBool(yes->Type()->Tag()) )
|
||||||
{
|
{
|
||||||
Unref(yes);
|
|
||||||
PrintHitMsg();
|
PrintHitMsg();
|
||||||
debug_msg("Breakpoint condition should return an integral type");
|
debug_msg("Breakpoint condition should return an integral type");
|
||||||
return bcHitAndDelete;
|
return bcHitAndDelete;
|
||||||
|
@ -269,11 +269,8 @@ BreakCode DbgBreakpoint::HasHit()
|
||||||
yes->CoerceToInt();
|
yes->CoerceToInt();
|
||||||
if ( yes->IsZero() )
|
if ( yes->IsZero() )
|
||||||
{
|
{
|
||||||
Unref(yes);
|
|
||||||
return bcNoHit;
|
return bcNoHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(yes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int repcount = GetRepeatCount();
|
int repcount = GetRepeatCount();
|
||||||
|
|
18
src/Debug.cc
18
src/Debug.cc
|
@ -16,10 +16,12 @@ using namespace std;
|
||||||
#include "DebugCmds.h"
|
#include "DebugCmds.h"
|
||||||
#include "DbgBreakpoint.h"
|
#include "DbgBreakpoint.h"
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
#include "Stmt.h"
|
#include "Stmt.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Scope.h"
|
#include "Scope.h"
|
||||||
#include "PolicyFile.h"
|
#include "PolicyFile.h"
|
||||||
#include "Desc.h"
|
#include "Desc.h"
|
||||||
|
@ -195,13 +197,13 @@ void get_first_statement(Stmt* list, Stmt*& first, Location& loc)
|
||||||
static void parse_function_name(vector<ParseLocationRec>& result,
|
static void parse_function_name(vector<ParseLocationRec>& result,
|
||||||
ParseLocationRec& plr, const string& s)
|
ParseLocationRec& plr, const string& s)
|
||||||
{ // function name
|
{ // function name
|
||||||
ID* id = lookup_ID(s.c_str(), current_module.c_str());
|
auto id = lookup_ID(s.c_str(), current_module.c_str());
|
||||||
|
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
{
|
{
|
||||||
string fullname = make_full_var_name(current_module.c_str(), s.c_str());
|
string fullname = make_full_var_name(current_module.c_str(), s.c_str());
|
||||||
debug_msg("Function %s not defined.\n", fullname.c_str());
|
debug_msg("Function %s not defined.\n", fullname.c_str());
|
||||||
plr.type = plrUnknown;
|
plr.type = plrUnknown;
|
||||||
Unref(id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +211,6 @@ static void parse_function_name(vector<ParseLocationRec>& result,
|
||||||
{
|
{
|
||||||
debug_msg("Function %s not declared.\n", id->Name());
|
debug_msg("Function %s not declared.\n", id->Name());
|
||||||
plr.type = plrUnknown;
|
plr.type = plrUnknown;
|
||||||
Unref(id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +218,6 @@ static void parse_function_name(vector<ParseLocationRec>& result,
|
||||||
{
|
{
|
||||||
debug_msg("Function %s declared but not defined.\n", id->Name());
|
debug_msg("Function %s declared but not defined.\n", id->Name());
|
||||||
plr.type = plrUnknown;
|
plr.type = plrUnknown;
|
||||||
Unref(id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,12 +228,9 @@ static void parse_function_name(vector<ParseLocationRec>& result,
|
||||||
{
|
{
|
||||||
debug_msg("Function %s is a built-in function\n", id->Name());
|
debug_msg("Function %s is a built-in function\n", id->Name());
|
||||||
plr.type = plrUnknown;
|
plr.type = plrUnknown;
|
||||||
Unref(id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(id);
|
|
||||||
|
|
||||||
Stmt* body = 0; // the particular body we care about; 0 = all
|
Stmt* body = 0; // the particular body we care about; 0 = all
|
||||||
|
|
||||||
if ( bodies.size() == 1 )
|
if ( bodies.size() == 1 )
|
||||||
|
@ -951,7 +948,7 @@ extern YYLTYPE yylloc; // holds start line and column of token
|
||||||
extern int line_number;
|
extern int line_number;
|
||||||
extern const char* filename;
|
extern const char* filename;
|
||||||
|
|
||||||
Val* dbg_eval_expr(const char* expr)
|
IntrusivePtr<Val> dbg_eval_expr(const char* expr)
|
||||||
{
|
{
|
||||||
// Push the current frame's associated scope.
|
// Push the current frame's associated scope.
|
||||||
// Note: g_debugger_state.curr_frame_idx is the user-visible number,
|
// Note: g_debugger_state.curr_frame_idx is the user-visible number,
|
||||||
|
@ -968,7 +965,10 @@ Val* dbg_eval_expr(const char* expr)
|
||||||
|
|
||||||
const BroFunc* func = frame->GetFunction();
|
const BroFunc* func = frame->GetFunction();
|
||||||
if ( func )
|
if ( func )
|
||||||
|
{
|
||||||
|
Ref(func->GetScope());
|
||||||
push_existing_scope(func->GetScope());
|
push_existing_scope(func->GetScope());
|
||||||
|
}
|
||||||
|
|
||||||
// ### Possibly push a debugger-local scope?
|
// ### Possibly push a debugger-local scope?
|
||||||
|
|
||||||
|
@ -983,7 +983,7 @@ Val* dbg_eval_expr(const char* expr)
|
||||||
yylloc.first_line = yylloc.last_line = line_number = 1;
|
yylloc.first_line = yylloc.last_line = line_number = 1;
|
||||||
|
|
||||||
// Parse the thing into an expr.
|
// Parse the thing into an expr.
|
||||||
Val* result = 0;
|
IntrusivePtr<Val> result;
|
||||||
if ( yyparse() )
|
if ( yyparse() )
|
||||||
{
|
{
|
||||||
if ( g_curr_debug_error )
|
if ( g_curr_debug_error )
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
template <class T> class IntrusivePtr;
|
||||||
class Val;
|
class Val;
|
||||||
class Stmt;
|
class Stmt;
|
||||||
|
|
||||||
|
@ -159,7 +160,7 @@ int dbg_handle_debug_input(); // read a line and then have it executed
|
||||||
int dbg_execute_command(const char* cmd);
|
int dbg_execute_command(const char* cmd);
|
||||||
|
|
||||||
// Interactive expression evaluation.
|
// Interactive expression evaluation.
|
||||||
Val* dbg_eval_expr(const char* expr);
|
IntrusivePtr<Val> dbg_eval_expr(const char* expr);
|
||||||
|
|
||||||
// Extra debugging facilities.
|
// Extra debugging facilities.
|
||||||
// TODO: current connections, memory allocated, other internal data structures.
|
// TODO: current connections, memory allocated, other internal data structures.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "Desc.h"
|
#include "Desc.h"
|
||||||
#include "DbgBreakpoint.h"
|
#include "DbgBreakpoint.h"
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
#include "Stmt.h"
|
#include "Stmt.h"
|
||||||
|
@ -564,13 +565,12 @@ int dbg_cmd_print(DebugCmd cmd, const vector<string>& args)
|
||||||
expr += " ";
|
expr += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* val = dbg_eval_expr(expr.c_str());
|
auto val = dbg_eval_expr(expr.c_str());
|
||||||
|
|
||||||
if ( val )
|
if ( val )
|
||||||
{
|
{
|
||||||
ODesc d;
|
ODesc d;
|
||||||
val->Describe(&d);
|
val->Describe(&d);
|
||||||
Unref(val);
|
|
||||||
debug_msg("%s\n", d.Description());
|
debug_msg("%s\n", d.Description());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -38,7 +38,7 @@ FuncType* EventHandler::FType(bool check_export)
|
||||||
if ( type )
|
if ( type )
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
ID* id = lookup_ID(name, current_module.c_str(), false, false,
|
auto id = lookup_ID(name, current_module.c_str(), false, false,
|
||||||
check_export);
|
check_export);
|
||||||
|
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
|
@ -48,8 +48,6 @@ FuncType* EventHandler::FType(bool check_export)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
type = id->Type()->AsFuncType();
|
type = id->Type()->AsFuncType();
|
||||||
Unref(id);
|
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,19 @@
|
||||||
#include "RE.h"
|
#include "RE.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
|
|
||||||
|
EventRegistry::EventRegistry() = default;
|
||||||
|
EventRegistry::~EventRegistry() noexcept = default;
|
||||||
|
|
||||||
void EventRegistry::Register(EventHandlerPtr handler)
|
void EventRegistry::Register(EventHandlerPtr handler)
|
||||||
{
|
{
|
||||||
handlers[string(handler->Name())] = handler.Ptr();
|
handlers[string(handler->Name())] = std::unique_ptr<EventHandler>(handler.Ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler* EventRegistry::Lookup(const string& name)
|
EventHandler* EventRegistry::Lookup(const string& name)
|
||||||
{
|
{
|
||||||
auto it = handlers.find(name);
|
auto it = handlers.find(name);
|
||||||
if ( it != handlers.end() )
|
if ( it != handlers.end() )
|
||||||
return it->second;
|
return it->second.get();
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +26,7 @@ EventRegistry::string_list EventRegistry::Match(RE_Matcher* pattern)
|
||||||
|
|
||||||
for ( const auto& entry : handlers )
|
for ( const auto& entry : handlers )
|
||||||
{
|
{
|
||||||
EventHandler* v = entry.second;
|
EventHandler* v = entry.second.get();
|
||||||
if ( v->LocalHandler() && pattern->MatchExactly(v->Name()) )
|
if ( v->LocalHandler() && pattern->MatchExactly(v->Name()) )
|
||||||
names.push_back(entry.first);
|
names.push_back(entry.first);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +40,7 @@ EventRegistry::string_list EventRegistry::UnusedHandlers()
|
||||||
|
|
||||||
for ( const auto& entry : handlers )
|
for ( const auto& entry : handlers )
|
||||||
{
|
{
|
||||||
EventHandler* v = entry.second;
|
EventHandler* v = entry.second.get();
|
||||||
if ( v->LocalHandler() && ! v->Used() )
|
if ( v->LocalHandler() && ! v->Used() )
|
||||||
names.push_back(entry.first);
|
names.push_back(entry.first);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +54,7 @@ EventRegistry::string_list EventRegistry::UsedHandlers()
|
||||||
|
|
||||||
for ( const auto& entry : handlers )
|
for ( const auto& entry : handlers )
|
||||||
{
|
{
|
||||||
EventHandler* v = entry.second;
|
EventHandler* v = entry.second.get();
|
||||||
if ( v->LocalHandler() && v->Used() )
|
if ( v->LocalHandler() && v->Used() )
|
||||||
names.push_back(entry.first);
|
names.push_back(entry.first);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +78,7 @@ void EventRegistry::PrintDebug()
|
||||||
{
|
{
|
||||||
for ( const auto& entry : handlers )
|
for ( const auto& entry : handlers )
|
||||||
{
|
{
|
||||||
EventHandler* v = entry.second;
|
EventHandler* v = entry.second.get();
|
||||||
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
|
fprintf(stderr, "Registered event %s (%s handler / %s)\n", v->Name(),
|
||||||
v->LocalHandler()? "local" : "no",
|
v->LocalHandler()? "local" : "no",
|
||||||
*v ? "active" : "not active"
|
*v ? "active" : "not active"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -16,8 +17,8 @@ class RE_Matcher;
|
||||||
// The registry keeps track of all events that we provide or handle.
|
// The registry keeps track of all events that we provide or handle.
|
||||||
class EventRegistry {
|
class EventRegistry {
|
||||||
public:
|
public:
|
||||||
EventRegistry() { }
|
EventRegistry();
|
||||||
~EventRegistry() { }
|
~EventRegistry() noexcept;
|
||||||
|
|
||||||
void Register(EventHandlerPtr handler);
|
void Register(EventHandlerPtr handler);
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ public:
|
||||||
void PrintDebug();
|
void PrintDebug();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, EventHandler*> handlers;
|
std::map<std::string, std::unique_ptr<EventHandler>> handlers;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EventRegistry* event_registry;
|
extern EventRegistry* event_registry;
|
||||||
|
|
1833
src/Expr.cc
1833
src/Expr.cc
File diff suppressed because it is too large
Load diff
349
src/Expr.h
349
src/Expr.h
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// BRO expressions.
|
|
||||||
|
|
||||||
#include "BroList.h"
|
#include "BroList.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
#include "EventHandler.h"
|
#include "EventHandler.h"
|
||||||
|
@ -58,6 +57,7 @@ enum BroExprTag : int {
|
||||||
|
|
||||||
extern const char* expr_name(BroExprTag t);
|
extern const char* expr_name(BroExprTag t);
|
||||||
|
|
||||||
|
template <class T> class IntrusivePtr;
|
||||||
class Stmt;
|
class Stmt;
|
||||||
class Frame;
|
class Frame;
|
||||||
class ListExpr;
|
class ListExpr;
|
||||||
|
@ -72,16 +72,14 @@ struct function_ingredients;
|
||||||
|
|
||||||
class Expr : public BroObj {
|
class Expr : public BroObj {
|
||||||
public:
|
public:
|
||||||
BroType* Type() const { return type; }
|
BroType* Type() const { return type.get(); }
|
||||||
BroExprTag Tag() const { return tag; }
|
BroExprTag Tag() const { return tag; }
|
||||||
|
|
||||||
~Expr() override;
|
|
||||||
|
|
||||||
Expr* Ref() { ::Ref(this); return this; }
|
Expr* Ref() { ::Ref(this); return this; }
|
||||||
|
|
||||||
// Evaluates the expression and returns a corresponding Val*,
|
// Evaluates the expression and returns a corresponding Val*,
|
||||||
// or nil if the expression's value isn't fixed.
|
// or nil if the expression's value isn't fixed.
|
||||||
virtual Val* Eval(Frame* f) const = 0;
|
virtual IntrusivePtr<Val> Eval(Frame* f) const = 0;
|
||||||
|
|
||||||
// Same, but the context is that we are adding an element
|
// Same, but the context is that we are adding an element
|
||||||
// into the given aggregate of the given type. Note that
|
// into the given aggregate of the given type. Note that
|
||||||
|
@ -91,12 +89,11 @@ public:
|
||||||
const;
|
const;
|
||||||
|
|
||||||
// Assign to the given value, if appropriate.
|
// Assign to the given value, if appropriate.
|
||||||
virtual void Assign(Frame* f, Val* v);
|
virtual void Assign(Frame* f, IntrusivePtr<Val> v);
|
||||||
|
|
||||||
// Returns the type corresponding to this expression interpreted
|
// Returns the type corresponding to this expression interpreted
|
||||||
// as an initialization. The type should be Unref()'d when done
|
// as an initialization. Returns nil if the initialization is illegal.
|
||||||
// using it. Returns nil if the initialization is illegal.
|
virtual IntrusivePtr<BroType> InitType() const;
|
||||||
virtual BroType* InitType() const;
|
|
||||||
|
|
||||||
// Returns true if this expression, interpreted as an initialization,
|
// Returns true if this expression, interpreted as an initialization,
|
||||||
// constitutes a record element, false otherwise. If the TypeDecl*
|
// constitutes a record element, false otherwise. If the TypeDecl*
|
||||||
|
@ -109,7 +106,7 @@ public:
|
||||||
// with the given type. If "aggr" is non-nil, then this expression
|
// with the given type. If "aggr" is non-nil, then this expression
|
||||||
// is an element of the given aggregate, and it is added to it
|
// is an element of the given aggregate, and it is added to it
|
||||||
// accordingly.
|
// accordingly.
|
||||||
virtual Val* InitVal(const BroType* t, Val* aggr) const;
|
virtual IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const;
|
||||||
|
|
||||||
// True if the expression has no side effects, false otherwise.
|
// True if the expression has no side effects, false otherwise.
|
||||||
virtual bool IsPure() const;
|
virtual bool IsPure() const;
|
||||||
|
@ -145,7 +142,7 @@ public:
|
||||||
// Return the expression converted to L-value form. If expr
|
// Return the expression converted to L-value form. If expr
|
||||||
// cannot be used as an L-value, reports an error and returns
|
// cannot be used as an L-value, reports an error and returns
|
||||||
// the current value of expr (this is the default method).
|
// the current value of expr (this is the default method).
|
||||||
virtual Expr* MakeLvalue();
|
virtual IntrusivePtr<Expr> MakeLvalue();
|
||||||
|
|
||||||
// Marks the expression as one requiring (or at least appearing
|
// Marks the expression as one requiring (or at least appearing
|
||||||
// with) parentheses. Used for pretty-printing.
|
// with) parentheses. Used for pretty-printing.
|
||||||
|
@ -214,7 +211,7 @@ protected:
|
||||||
// Puts the expression in canonical form.
|
// Puts the expression in canonical form.
|
||||||
virtual void Canonicize();
|
virtual void Canonicize();
|
||||||
|
|
||||||
void SetType(BroType* t);
|
void SetType(IntrusivePtr<BroType> t);
|
||||||
|
|
||||||
// Reports the given error and sets the expression's type to
|
// Reports the given error and sets the expression's type to
|
||||||
// TYPE_ERROR.
|
// TYPE_ERROR.
|
||||||
|
@ -225,21 +222,19 @@ protected:
|
||||||
void RuntimeErrorWithCallStack(const std::string& msg) const;
|
void RuntimeErrorWithCallStack(const std::string& msg) const;
|
||||||
|
|
||||||
BroExprTag tag;
|
BroExprTag tag;
|
||||||
BroType* type = nullptr;
|
IntrusivePtr<BroType> type;
|
||||||
|
|
||||||
bool paren;
|
bool paren;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NameExpr : public Expr {
|
class NameExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
explicit NameExpr(ID* id, bool const_init = false);
|
explicit NameExpr(IntrusivePtr<ID> id, bool const_init = false);
|
||||||
~NameExpr() override;
|
|
||||||
|
|
||||||
ID* Id() const { return id; }
|
ID* Id() const { return id.get(); }
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
void Assign(Frame* f, Val* v) override;
|
void Assign(Frame* f, IntrusivePtr<Val> v) override;
|
||||||
Expr* MakeLvalue() override;
|
IntrusivePtr<Expr> MakeLvalue() override;
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
@ -247,91 +242,89 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
ID* id;
|
IntrusivePtr<ID> id;
|
||||||
bool in_const_init;
|
bool in_const_init;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConstExpr : public Expr {
|
class ConstExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
explicit ConstExpr(Val* val);
|
explicit ConstExpr(IntrusivePtr<Val> val);
|
||||||
~ConstExpr() override;
|
|
||||||
|
|
||||||
Val* Value() const { return val; }
|
Val* Value() const { return val.get(); }
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
Val* val;
|
IntrusivePtr<Val> val;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnaryExpr : public Expr {
|
class UnaryExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
Expr* Op() const { return op; }
|
Expr* Op() const { return op.get(); }
|
||||||
|
|
||||||
// UnaryExpr::Eval correctly handles vector types. Any child
|
// UnaryExpr::Eval correctly handles vector types. Any child
|
||||||
// class that overrides Eval() should be modified to handle
|
// class that overrides Eval() should be modified to handle
|
||||||
// vectors correctly as necessary.
|
// vectors correctly as necessary.
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
|
UnaryExpr(BroExprTag arg_tag, IntrusivePtr<Expr> arg_op);
|
||||||
~UnaryExpr() override;
|
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
// Returns the expression folded using the given constant.
|
// Returns the expression folded using the given constant.
|
||||||
virtual Val* Fold(Val* v) const;
|
virtual IntrusivePtr<Val> Fold(Val* v) const;
|
||||||
|
|
||||||
Expr* op;
|
IntrusivePtr<Expr> op;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BinaryExpr : public Expr {
|
class BinaryExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
Expr* Op1() const { return op1; }
|
Expr* Op1() const { return op1.get(); }
|
||||||
Expr* Op2() const { return op2; }
|
Expr* Op2() const { return op2.get(); }
|
||||||
|
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
|
|
||||||
// BinaryExpr::Eval correctly handles vector types. Any child
|
// BinaryExpr::Eval correctly handles vector types. Any child
|
||||||
// class that overrides Eval() should be modified to handle
|
// class that overrides Eval() should be modified to handle
|
||||||
// vectors correctly as necessary.
|
// vectors correctly as necessary.
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
BinaryExpr(BroExprTag arg_tag,
|
||||||
: Expr(arg_tag), op1(arg_op1), op2(arg_op2)
|
IntrusivePtr<Expr> arg_op1, IntrusivePtr<Expr> arg_op2)
|
||||||
|
: Expr(arg_tag), op1(std::move(arg_op1)), op2(std::move(arg_op2))
|
||||||
{
|
{
|
||||||
if ( ! (arg_op1 && arg_op2) )
|
if ( ! (op1 && op2) )
|
||||||
return;
|
return;
|
||||||
if ( op1->IsError() || op2->IsError() )
|
if ( op1->IsError() || op2->IsError() )
|
||||||
SetError();
|
SetError();
|
||||||
}
|
}
|
||||||
~BinaryExpr() override;
|
|
||||||
|
|
||||||
// Returns the expression folded using the given constants.
|
// Returns the expression folded using the given constants.
|
||||||
virtual Val* Fold(Val* v1, Val* v2) const;
|
virtual IntrusivePtr<Val> Fold(Val* v1, Val* v2) const;
|
||||||
|
|
||||||
// Same for when the constants are strings.
|
// Same for when the constants are strings.
|
||||||
virtual Val* StringFold(Val* v1, Val* v2) const;
|
virtual IntrusivePtr<Val> StringFold(Val* v1, Val* v2) const;
|
||||||
|
|
||||||
// Same for when the constants are patterns.
|
// Same for when the constants are patterns.
|
||||||
virtual Val* PatternFold(Val* v1, Val* v2) const;
|
virtual IntrusivePtr<Val> PatternFold(Val* v1, Val* v2) const;
|
||||||
|
|
||||||
// Same for when the constants are sets.
|
// Same for when the constants are sets.
|
||||||
virtual Val* SetFold(Val* v1, Val* v2) const;
|
virtual IntrusivePtr<Val> SetFold(Val* v1, Val* v2) const;
|
||||||
|
|
||||||
// Same for when the constants are addresses or subnets.
|
// Same for when the constants are addresses or subnets.
|
||||||
virtual Val* AddrFold(Val* v1, Val* v2) const;
|
virtual IntrusivePtr<Val> AddrFold(Val* v1, Val* v2) const;
|
||||||
virtual Val* SubNetFold(Val* v1, Val* v2) const;
|
virtual IntrusivePtr<Val> SubNetFold(Val* v1, Val* v2) const;
|
||||||
|
|
||||||
int BothConst() const { return op1->IsConst() && op2->IsConst(); }
|
int BothConst() const { return op1->IsConst() && op2->IsConst(); }
|
||||||
|
|
||||||
|
@ -347,149 +340,148 @@ protected:
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
Expr* op1;
|
IntrusivePtr<Expr> op1;
|
||||||
Expr* op2;
|
IntrusivePtr<Expr> op2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CloneExpr : public UnaryExpr {
|
class CloneExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit CloneExpr(Expr* op);
|
explicit CloneExpr(IntrusivePtr<Expr> op);
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IncrExpr : public UnaryExpr {
|
class IncrExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
IncrExpr(BroExprTag tag, Expr* op);
|
IncrExpr(BroExprTag tag, IntrusivePtr<Expr> op);
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
Val* DoSingleEval(Frame* f, Val* v) const;
|
IntrusivePtr<Val> DoSingleEval(Frame* f, Val* v) const;
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComplementExpr : public UnaryExpr {
|
class ComplementExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit ComplementExpr(Expr* op);
|
explicit ComplementExpr(IntrusivePtr<Expr> op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotExpr : public UnaryExpr {
|
class NotExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit NotExpr(Expr* op);
|
explicit NotExpr(IntrusivePtr<Expr> op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PosExpr : public UnaryExpr {
|
class PosExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit PosExpr(Expr* op);
|
explicit PosExpr(IntrusivePtr<Expr> op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NegExpr : public UnaryExpr {
|
class NegExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit NegExpr(Expr* op);
|
explicit NegExpr(IntrusivePtr<Expr> op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SizeExpr : public UnaryExpr {
|
class SizeExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit SizeExpr(Expr* op);
|
explicit SizeExpr(IntrusivePtr<Expr> op);
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddExpr : public BinaryExpr {
|
class AddExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
AddExpr(Expr* op1, Expr* op2);
|
AddExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
void Canonicize() override;
|
void Canonicize() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddToExpr : public BinaryExpr {
|
class AddToExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
AddToExpr(Expr* op1, Expr* op2);
|
AddToExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RemoveFromExpr : public BinaryExpr {
|
class RemoveFromExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
RemoveFromExpr(Expr* op1, Expr* op2);
|
RemoveFromExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SubExpr : public BinaryExpr {
|
class SubExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
SubExpr(Expr* op1, Expr* op2);
|
SubExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimesExpr : public BinaryExpr {
|
class TimesExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
TimesExpr(Expr* op1, Expr* op2);
|
TimesExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
void Canonicize() override;
|
void Canonicize() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DivideExpr : public BinaryExpr {
|
class DivideExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
DivideExpr(Expr* op1, Expr* op2);
|
DivideExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* AddrFold(Val* v1, Val* v2) const override;
|
IntrusivePtr<Val> AddrFold(Val* v1, Val* v2) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModExpr : public BinaryExpr {
|
class ModExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
ModExpr(Expr* op1, Expr* op2);
|
ModExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoolExpr : public BinaryExpr {
|
class BoolExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
BoolExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
BoolExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const;
|
IntrusivePtr<Val> DoSingleEval(Frame* f, IntrusivePtr<Val> v1, Expr* op2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BitExpr : public BinaryExpr {
|
class BitExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
BitExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
BitExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
};
|
};
|
||||||
|
|
||||||
class EqExpr : public BinaryExpr {
|
class EqExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
EqExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
void Canonicize() override;
|
void Canonicize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v1, Val* v2) const override;
|
IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RelExpr : public BinaryExpr {
|
class RelExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
RelExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
RelExpr(BroExprTag tag, IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
void Canonicize() override;
|
void Canonicize() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CondExpr : public Expr {
|
class CondExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
CondExpr(Expr* op1, Expr* op2, Expr* op3);
|
CondExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, IntrusivePtr<Expr> op3);
|
||||||
~CondExpr() override;
|
|
||||||
|
|
||||||
const Expr* Op1() const { return op1; }
|
const Expr* Op1() const { return op1.get(); }
|
||||||
const Expr* Op2() const { return op2; }
|
const Expr* Op2() const { return op2.get(); }
|
||||||
const Expr* Op3() const { return op3; }
|
const Expr* Op3() const { return op3.get(); }
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
@ -497,31 +489,31 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
Expr* op1;
|
IntrusivePtr<Expr> op1;
|
||||||
Expr* op2;
|
IntrusivePtr<Expr> op2;
|
||||||
Expr* op3;
|
IntrusivePtr<Expr> op3;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RefExpr : public UnaryExpr {
|
class RefExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit RefExpr(Expr* op);
|
explicit RefExpr(IntrusivePtr<Expr> op);
|
||||||
|
|
||||||
void Assign(Frame* f, Val* v) override;
|
void Assign(Frame* f, IntrusivePtr<Val> v) override;
|
||||||
Expr* MakeLvalue() override;
|
IntrusivePtr<Expr> MakeLvalue() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AssignExpr : public BinaryExpr {
|
class AssignExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
// If val is given, evaluating this expression will always yield the val
|
// If val is given, evaluating this expression will always yield the val
|
||||||
// yet still perform the assignment. Used for triggers.
|
// yet still perform the assignment. Used for triggers.
|
||||||
AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0);
|
AssignExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2, int is_init,
|
||||||
~AssignExpr() override;
|
IntrusivePtr<Val> val = nullptr, attr_list* attrs = nullptr);
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
|
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
|
||||||
BroType* InitType() const override;
|
IntrusivePtr<BroType> InitType() const override;
|
||||||
bool IsRecordElement(TypeDecl* td) const override;
|
bool IsRecordElement(TypeDecl* td) const override;
|
||||||
Val* InitVal(const BroType* t, Val* aggr) const override;
|
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -529,18 +521,20 @@ protected:
|
||||||
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
|
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
|
||||||
|
|
||||||
int is_init;
|
int is_init;
|
||||||
Val* val; // optional
|
IntrusivePtr<Val> val; // optional
|
||||||
};
|
};
|
||||||
|
|
||||||
class IndexSliceAssignExpr : public AssignExpr {
|
class IndexSliceAssignExpr : public AssignExpr {
|
||||||
public:
|
public:
|
||||||
IndexSliceAssignExpr(Expr* op1, Expr* op2, int is_init);
|
IndexSliceAssignExpr(IntrusivePtr<Expr> op1,
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Expr> op2, int is_init);
|
||||||
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IndexExpr : public BinaryExpr {
|
class IndexExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
IndexExpr(Expr* op1, ListExpr* op2, bool is_slice = false);
|
IndexExpr(IntrusivePtr<Expr> op1,
|
||||||
|
IntrusivePtr<ListExpr> op2, bool is_slice = false);
|
||||||
|
|
||||||
bool CanAdd() const override;
|
bool CanAdd() const override;
|
||||||
bool CanDel() const override;
|
bool CanDel() const override;
|
||||||
|
@ -548,19 +542,19 @@ public:
|
||||||
void Add(Frame* f) override;
|
void Add(Frame* f) override;
|
||||||
void Delete(Frame* f) override;
|
void Delete(Frame* f) override;
|
||||||
|
|
||||||
void Assign(Frame* f, Val* v) override;
|
void Assign(Frame* f, IntrusivePtr<Val> v) override;
|
||||||
Expr* MakeLvalue() override;
|
IntrusivePtr<Expr> MakeLvalue() override;
|
||||||
|
|
||||||
// Need to override Eval since it can take a vector arg but does
|
// Need to override Eval since it can take a vector arg but does
|
||||||
// not necessarily return a vector.
|
// not necessarily return a vector.
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
bool IsSlice() const { return is_slice; }
|
bool IsSlice() const { return is_slice; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v1, Val* v2) const override;
|
IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -569,7 +563,7 @@ protected:
|
||||||
|
|
||||||
class FieldExpr : public UnaryExpr {
|
class FieldExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
FieldExpr(Expr* op, const char* field_name);
|
FieldExpr(IntrusivePtr<Expr> op, const char* field_name);
|
||||||
~FieldExpr() override;
|
~FieldExpr() override;
|
||||||
|
|
||||||
int Field() const { return field; }
|
int Field() const { return field; }
|
||||||
|
@ -577,13 +571,13 @@ public:
|
||||||
|
|
||||||
bool CanDel() const override;
|
bool CanDel() const override;
|
||||||
|
|
||||||
void Assign(Frame* f, Val* v) override;
|
void Assign(Frame* f, IntrusivePtr<Val> v) override;
|
||||||
void Delete(Frame* f) override;
|
void Delete(Frame* f) override;
|
||||||
|
|
||||||
Expr* MakeLvalue() override;
|
IntrusivePtr<Expr> MakeLvalue() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -596,13 +590,13 @@ protected:
|
||||||
// "rec?$$attrname" is true if the attribute attrname is not nil.
|
// "rec?$$attrname" is true if the attribute attrname is not nil.
|
||||||
class HasFieldExpr : public UnaryExpr {
|
class HasFieldExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
HasFieldExpr(Expr* op, const char* field_name);
|
HasFieldExpr(IntrusivePtr<Expr> op, const char* field_name);
|
||||||
~HasFieldExpr() override;
|
~HasFieldExpr() override;
|
||||||
|
|
||||||
const char* FieldName() const { return field_name; }
|
const char* FieldName() const { return field_name; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -612,28 +606,28 @@ protected:
|
||||||
|
|
||||||
class RecordConstructorExpr : public UnaryExpr {
|
class RecordConstructorExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit RecordConstructorExpr(ListExpr* constructor_list);
|
explicit RecordConstructorExpr(IntrusivePtr<ListExpr> constructor_list);
|
||||||
~RecordConstructorExpr() override;
|
~RecordConstructorExpr() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* InitVal(const BroType* t, Val* aggr) const override;
|
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TableConstructorExpr : public UnaryExpr {
|
class TableConstructorExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
TableConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
|
||||||
BroType* arg_type = 0);
|
IntrusivePtr<BroType> arg_type = nullptr);
|
||||||
~TableConstructorExpr() override { Unref(attrs); }
|
~TableConstructorExpr() override { Unref(attrs); }
|
||||||
|
|
||||||
Attributes* Attrs() { return attrs; }
|
Attributes* Attrs() { return attrs; }
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* InitVal(const BroType* t, Val* aggr) const override;
|
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -642,16 +636,16 @@ protected:
|
||||||
|
|
||||||
class SetConstructorExpr : public UnaryExpr {
|
class SetConstructorExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
SetConstructorExpr(IntrusivePtr<ListExpr> constructor_list, attr_list* attrs,
|
||||||
BroType* arg_type = 0);
|
IntrusivePtr<BroType> arg_type = nullptr);
|
||||||
~SetConstructorExpr() override { Unref(attrs); }
|
~SetConstructorExpr() override { Unref(attrs); }
|
||||||
|
|
||||||
Attributes* Attrs() { return attrs; }
|
Attributes* Attrs() { return attrs; }
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* InitVal(const BroType* t, Val* aggr) const override;
|
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -660,19 +654,20 @@ protected:
|
||||||
|
|
||||||
class VectorConstructorExpr : public UnaryExpr {
|
class VectorConstructorExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
|
explicit VectorConstructorExpr(IntrusivePtr<ListExpr> constructor_list,
|
||||||
|
IntrusivePtr<BroType> arg_type = nullptr);
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* InitVal(const BroType* t, Val* aggr) const override;
|
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FieldAssignExpr : public UnaryExpr {
|
class FieldAssignExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
FieldAssignExpr(const char* field_name, Expr* value);
|
FieldAssignExpr(const char* field_name, IntrusivePtr<Expr> value);
|
||||||
|
|
||||||
const char* FieldName() const { return field_name.c_str(); }
|
const char* FieldName() const { return field_name.c_str(); }
|
||||||
|
|
||||||
|
@ -687,21 +682,21 @@ protected:
|
||||||
|
|
||||||
class ArithCoerceExpr : public UnaryExpr {
|
class ArithCoerceExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
ArithCoerceExpr(Expr* op, TypeTag t);
|
ArithCoerceExpr(IntrusivePtr<Expr> op, TypeTag t);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* FoldSingleVal(Val* v, InternalTypeTag t) const;
|
IntrusivePtr<Val> FoldSingleVal(Val* v, InternalTypeTag t) const;
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RecordCoerceExpr : public UnaryExpr {
|
class RecordCoerceExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
RecordCoerceExpr(Expr* op, RecordType* r);
|
RecordCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<RecordType> r);
|
||||||
~RecordCoerceExpr() override;
|
~RecordCoerceExpr() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* InitVal(const BroType* t, Val* aggr) const override;
|
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
|
|
||||||
// For each super-record slot, gives subrecord slot with which to
|
// For each super-record slot, gives subrecord slot with which to
|
||||||
// fill it.
|
// fill it.
|
||||||
|
@ -711,30 +706,30 @@ protected:
|
||||||
|
|
||||||
class TableCoerceExpr : public UnaryExpr {
|
class TableCoerceExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
TableCoerceExpr(Expr* op, TableType* r);
|
TableCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<TableType> r);
|
||||||
~TableCoerceExpr() override;
|
~TableCoerceExpr() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VectorCoerceExpr : public UnaryExpr {
|
class VectorCoerceExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
VectorCoerceExpr(Expr* op, VectorType* v);
|
VectorCoerceExpr(IntrusivePtr<Expr> op, IntrusivePtr<VectorType> v);
|
||||||
~VectorCoerceExpr() override;
|
~VectorCoerceExpr() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An internal operator for flattening array indices that are records
|
// An internal operator for flattening array indices that are records
|
||||||
// into a list of individual values.
|
// into a list of individual values.
|
||||||
class FlattenExpr : public UnaryExpr {
|
class FlattenExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
explicit FlattenExpr(Expr* op);
|
explicit FlattenExpr(IntrusivePtr<Expr> op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
|
|
||||||
int num_fields;
|
int num_fields;
|
||||||
};
|
};
|
||||||
|
@ -755,53 +750,52 @@ protected:
|
||||||
|
|
||||||
class ScheduleExpr : public Expr {
|
class ScheduleExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
ScheduleExpr(Expr* when, EventExpr* event);
|
ScheduleExpr(IntrusivePtr<Expr> when, IntrusivePtr<EventExpr> event);
|
||||||
~ScheduleExpr() override;
|
|
||||||
|
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
Expr* When() const { return when; }
|
Expr* When() const { return when.get(); }
|
||||||
EventExpr* Event() const { return event; }
|
EventExpr* Event() const { return event.get(); }
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
Expr* when;
|
IntrusivePtr<Expr> when;
|
||||||
EventExpr* event;
|
IntrusivePtr<EventExpr> event;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InExpr : public BinaryExpr {
|
class InExpr : public BinaryExpr {
|
||||||
public:
|
public:
|
||||||
InExpr(Expr* op1, Expr* op2);
|
InExpr(IntrusivePtr<Expr> op1, IntrusivePtr<Expr> op2);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v1, Val* v2) const override;
|
IntrusivePtr<Val> Fold(Val* v1, Val* v2) const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CallExpr : public Expr {
|
class CallExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
CallExpr(Expr* func, ListExpr* args, bool in_hook = false);
|
CallExpr(IntrusivePtr<Expr> func, IntrusivePtr<ListExpr> args,
|
||||||
~CallExpr() override;
|
bool in_hook = false);
|
||||||
|
|
||||||
Expr* Func() const { return func; }
|
Expr* Func() const { return func.get(); }
|
||||||
ListExpr* Args() const { return args; }
|
ListExpr* Args() const { return args.get(); }
|
||||||
|
|
||||||
bool IsPure() const override;
|
bool IsPure() const override;
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
Expr* func;
|
IntrusivePtr<Expr> func;
|
||||||
ListExpr* args;
|
IntrusivePtr<ListExpr> args;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -815,7 +809,7 @@ public:
|
||||||
LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
||||||
id_list outer_ids);
|
id_list outer_ids);
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -830,14 +824,13 @@ private:
|
||||||
|
|
||||||
class EventExpr : public Expr {
|
class EventExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
EventExpr(const char* name, ListExpr* args);
|
EventExpr(const char* name, IntrusivePtr<ListExpr> args);
|
||||||
~EventExpr() override;
|
|
||||||
|
|
||||||
const char* Name() const { return name.c_str(); }
|
const char* Name() const { return name.c_str(); }
|
||||||
ListExpr* Args() const { return args; }
|
ListExpr* Args() const { return args.get(); }
|
||||||
EventHandlerPtr Handler() const { return handler; }
|
EventHandlerPtr Handler() const { return handler; }
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
|
@ -846,16 +839,16 @@ protected:
|
||||||
|
|
||||||
string name;
|
string name;
|
||||||
EventHandlerPtr handler;
|
EventHandlerPtr handler;
|
||||||
ListExpr* args;
|
IntrusivePtr<ListExpr> args;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListExpr : public Expr {
|
class ListExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
ListExpr();
|
ListExpr();
|
||||||
explicit ListExpr(Expr* e);
|
explicit ListExpr(IntrusivePtr<Expr> e);
|
||||||
~ListExpr() override;
|
~ListExpr() override;
|
||||||
|
|
||||||
void Append(Expr* e);
|
void Append(IntrusivePtr<Expr> e);
|
||||||
|
|
||||||
const expr_list& Exprs() const { return exprs; }
|
const expr_list& Exprs() const { return exprs; }
|
||||||
expr_list& Exprs() { return exprs; }
|
expr_list& Exprs() { return exprs; }
|
||||||
|
@ -866,17 +859,17 @@ public:
|
||||||
// True if the entire list represents constant values.
|
// True if the entire list represents constant values.
|
||||||
bool AllConst() const;
|
bool AllConst() const;
|
||||||
|
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
|
|
||||||
BroType* InitType() const override;
|
IntrusivePtr<BroType> InitType() const override;
|
||||||
Val* InitVal(const BroType* t, Val* aggr) const override;
|
IntrusivePtr<Val> InitVal(const BroType* t, IntrusivePtr<Val> aggr) const override;
|
||||||
Expr* MakeLvalue() override;
|
IntrusivePtr<Expr> MakeLvalue() override;
|
||||||
void Assign(Frame* f, Val* v) override;
|
void Assign(Frame* f, IntrusivePtr<Val> v) override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* AddSetInit(const BroType* t, Val* aggr) const;
|
IntrusivePtr<Val> AddSetInit(const BroType* t, IntrusivePtr<Val> aggr) const;
|
||||||
|
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -886,29 +879,28 @@ protected:
|
||||||
|
|
||||||
class RecordAssignExpr : public ListExpr {
|
class RecordAssignExpr : public ListExpr {
|
||||||
public:
|
public:
|
||||||
RecordAssignExpr(Expr* record, Expr* init_list, int is_init);
|
RecordAssignExpr(IntrusivePtr<Expr> record, IntrusivePtr<Expr> init_list, int is_init);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastExpr : public UnaryExpr {
|
class CastExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
CastExpr(Expr* op, BroType* t);
|
CastExpr(IntrusivePtr<Expr> op, IntrusivePtr<BroType> t);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Eval(Frame* f) const override;
|
IntrusivePtr<Val> Eval(Frame* f) const override;
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IsExpr : public UnaryExpr {
|
class IsExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
IsExpr(Expr* op, BroType* t);
|
IsExpr(IntrusivePtr<Expr> op, IntrusivePtr<BroType> t);
|
||||||
virtual ~IsExpr();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* Fold(Val* v) const override;
|
IntrusivePtr<Val> Fold(Val* v) const override;
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BroType* t;
|
IntrusivePtr<BroType> t;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Val* Expr::ExprVal() const
|
inline Val* Expr::ExprVal() const
|
||||||
|
@ -919,7 +911,8 @@ inline Val* Expr::ExprVal() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decides whether to return an AssignExpr or a RecordAssignExpr.
|
// Decides whether to return an AssignExpr or a RecordAssignExpr.
|
||||||
Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init);
|
IntrusivePtr<Expr> get_assign_expr(IntrusivePtr<Expr> op1,
|
||||||
|
IntrusivePtr<Expr> op2, int is_init);
|
||||||
|
|
||||||
// Type-check the given expression(s) against the given type(s). Complain
|
// Type-check the given expression(s) against the given type(s). Complain
|
||||||
// if the expression cannot match the given type, returning 0. If it can
|
// if the expression cannot match the given type, returning 0. If it can
|
||||||
|
|
17
src/Func.cc
17
src/Func.cc
|
@ -387,7 +387,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = body.stmts->Exec(f, flow);
|
result = body.stmts->Exec(f, flow).release();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( InterpreterException& e )
|
catch ( InterpreterException& e )
|
||||||
|
@ -606,15 +606,14 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name,
|
||||||
name = make_full_var_name(GLOBAL_MODULE_NAME, arg_name);
|
name = make_full_var_name(GLOBAL_MODULE_NAME, arg_name);
|
||||||
is_pure = arg_is_pure;
|
is_pure = arg_is_pure;
|
||||||
|
|
||||||
ID* id = lookup_ID(Name(), GLOBAL_MODULE_NAME, false);
|
auto id = lookup_ID(Name(), GLOBAL_MODULE_NAME, false);
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
reporter->InternalError("built-in function %s missing", Name());
|
reporter->InternalError("built-in function %s missing", Name());
|
||||||
if ( id->HasVal() )
|
if ( id->HasVal() )
|
||||||
reporter->InternalError("built-in function %s multiply defined", Name());
|
reporter->InternalError("built-in function %s multiply defined", Name());
|
||||||
|
|
||||||
type = id->Type()->Ref();
|
type = id->Type()->Ref();
|
||||||
id->SetVal(new Val(this));
|
id->SetVal(make_intrusive<Val>(this));
|
||||||
Unref(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BuiltinFunc::~BuiltinFunc()
|
BuiltinFunc::~BuiltinFunc()
|
||||||
|
@ -816,7 +815,7 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* fmt_str_val = fmt_str_arg->Eval(0);
|
auto fmt_str_val = fmt_str_arg->Eval(nullptr);
|
||||||
|
|
||||||
if ( fmt_str_val )
|
if ( fmt_str_val )
|
||||||
{
|
{
|
||||||
|
@ -830,7 +829,6 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
|
||||||
|
|
||||||
if ( ! *fmt_str )
|
if ( ! *fmt_str )
|
||||||
{
|
{
|
||||||
Unref(fmt_str_val);
|
|
||||||
call->Error("format string ends with bare '%'");
|
call->Error("format string ends with bare '%'");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -842,13 +840,11 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
|
||||||
|
|
||||||
if ( args.length() != num_fmt + 1 )
|
if ( args.length() != num_fmt + 1 )
|
||||||
{
|
{
|
||||||
Unref(fmt_str_val);
|
|
||||||
call->Error("mismatch between format string to fmt() and number of arguments passed");
|
call->Error("mismatch between format string to fmt() and number of arguments passed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(fmt_str_val);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -869,7 +865,8 @@ static int get_func_priority(const attr_list& attrs)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* v = a->AttrExpr()->Eval(0);
|
auto v = a->AttrExpr()->Eval(nullptr);
|
||||||
|
|
||||||
if ( ! v )
|
if ( ! v )
|
||||||
{
|
{
|
||||||
a->Error("cannot evaluate attribute expression");
|
a->Error("cannot evaluate attribute expression");
|
||||||
|
@ -878,13 +875,11 @@ static int get_func_priority(const attr_list& attrs)
|
||||||
|
|
||||||
if ( ! IsIntegral(v->Type()->Tag()) )
|
if ( ! IsIntegral(v->Type()->Tag()) )
|
||||||
{
|
{
|
||||||
Unref(v);
|
|
||||||
a->Error("expression is not of integral type");
|
a->Error("expression is not of integral type");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
priority = v->InternalInt();
|
priority = v->InternalInt();
|
||||||
Unref(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return priority;
|
return priority;
|
||||||
|
|
107
src/ID.cc
107
src/ID.cc
|
@ -26,9 +26,7 @@ ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
|
||||||
scope = arg_scope;
|
scope = arg_scope;
|
||||||
is_export = arg_is_export;
|
is_export = arg_is_export;
|
||||||
is_option = false;
|
is_option = false;
|
||||||
type = 0;
|
|
||||||
val = 0;
|
val = 0;
|
||||||
attrs = 0;
|
|
||||||
is_const = false;
|
is_const = false;
|
||||||
is_enum_const = false;
|
is_enum_const = false;
|
||||||
is_type = false;
|
is_type = false;
|
||||||
|
@ -43,11 +41,6 @@ ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
|
||||||
ID::~ID()
|
ID::~ID()
|
||||||
{
|
{
|
||||||
delete [] name;
|
delete [] name;
|
||||||
Unref(type);
|
|
||||||
Unref(attrs);
|
|
||||||
|
|
||||||
for ( auto element : option_handlers )
|
|
||||||
Unref(element.second);
|
|
||||||
|
|
||||||
if ( ! weak_ref )
|
if ( ! weak_ref )
|
||||||
Unref(val);
|
Unref(val);
|
||||||
|
@ -58,9 +51,9 @@ string ID::ModuleName() const
|
||||||
return extract_module_name(name);
|
return extract_module_name(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::SetType(BroType* t)
|
void ID::SetType(IntrusivePtr<BroType> t)
|
||||||
{
|
{
|
||||||
Unref(type); type = t;
|
type = std::move(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::ClearVal()
|
void ID::ClearVal()
|
||||||
|
@ -71,12 +64,12 @@ void ID::ClearVal()
|
||||||
val = 0;
|
val = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::SetVal(Val* v, bool arg_weak_ref)
|
void ID::SetVal(IntrusivePtr<Val> v, bool arg_weak_ref)
|
||||||
{
|
{
|
||||||
if ( ! weak_ref )
|
if ( ! weak_ref )
|
||||||
Unref(val);
|
Unref(val);
|
||||||
|
|
||||||
val = v;
|
val = v.release();
|
||||||
weak_ref = arg_weak_ref;
|
weak_ref = arg_weak_ref;
|
||||||
Modified();
|
Modified();
|
||||||
|
|
||||||
|
@ -104,11 +97,11 @@ void ID::SetVal(Val* v, bool arg_weak_ref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::SetVal(Val* v, init_class c)
|
void ID::SetVal(IntrusivePtr<Val> v, init_class c)
|
||||||
{
|
{
|
||||||
if ( c == INIT_NONE || c == INIT_FULL )
|
if ( c == INIT_NONE || c == INIT_FULL )
|
||||||
{
|
{
|
||||||
SetVal(v);
|
SetVal(std::move(v));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +110,9 @@ void ID::SetVal(Val* v, init_class c)
|
||||||
(type->Tag() != TYPE_VECTOR || c == INIT_REMOVE) )
|
(type->Tag() != TYPE_VECTOR || c == INIT_REMOVE) )
|
||||||
{
|
{
|
||||||
if ( c == INIT_EXTRA )
|
if ( c == INIT_EXTRA )
|
||||||
Error("+= initializer only applies to tables, sets, vectors and patterns", v);
|
Error("+= initializer only applies to tables, sets, vectors and patterns", v.get());
|
||||||
else
|
else
|
||||||
Error("-= initializer only applies to tables and sets", v);
|
Error("-= initializer only applies to tables and sets", v.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -128,7 +121,7 @@ void ID::SetVal(Val* v, init_class c)
|
||||||
{
|
{
|
||||||
if ( ! val )
|
if ( ! val )
|
||||||
{
|
{
|
||||||
SetVal(v);
|
SetVal(std::move(v));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -140,11 +133,9 @@ void ID::SetVal(Val* v, init_class c)
|
||||||
v->RemoveFrom(val);
|
v->RemoveFrom(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::SetVal(Expr* ev, init_class c)
|
void ID::SetVal(IntrusivePtr<Expr> ev, init_class c)
|
||||||
{
|
{
|
||||||
Attr* a = attrs->FindAttr(c == INIT_EXTRA ?
|
Attr* a = attrs->FindAttr(c == INIT_EXTRA ?
|
||||||
ATTR_ADD_FUNC : ATTR_DEL_FUNC);
|
ATTR_ADD_FUNC : ATTR_DEL_FUNC);
|
||||||
|
@ -152,7 +143,7 @@ void ID::SetVal(Expr* ev, init_class c)
|
||||||
if ( ! a )
|
if ( ! a )
|
||||||
Internal("no add/delete function in ID::SetVal");
|
Internal("no add/delete function in ID::SetVal");
|
||||||
|
|
||||||
EvalFunc(a->AttrExpr(), ev);
|
EvalFunc({NewRef{}, a->AttrExpr()}, std::move(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ID::IsRedefinable() const
|
bool ID::IsRedefinable() const
|
||||||
|
@ -160,11 +151,10 @@ bool ID::IsRedefinable() const
|
||||||
return FindAttr(ATTR_REDEF) != 0;
|
return FindAttr(ATTR_REDEF) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::SetAttrs(Attributes* a)
|
void ID::SetAttrs(IntrusivePtr<Attributes> a)
|
||||||
{
|
{
|
||||||
Unref(attrs);
|
|
||||||
attrs = 0;
|
attrs = 0;
|
||||||
AddAttrs(a);
|
AddAttrs(std::move(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::UpdateValAttrs()
|
void ID::UpdateValAttrs()
|
||||||
|
@ -173,10 +163,10 @@ void ID::UpdateValAttrs()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( val && val->Type()->Tag() == TYPE_TABLE )
|
if ( val && val->Type()->Tag() == TYPE_TABLE )
|
||||||
val->AsTableVal()->SetAttrs(attrs);
|
val->AsTableVal()->SetAttrs(attrs.get());
|
||||||
|
|
||||||
if ( val && val->Type()->Tag() == TYPE_FILE )
|
if ( val && val->Type()->Tag() == TYPE_FILE )
|
||||||
val->AsFile()->SetAttrs(attrs);
|
val->AsFile()->SetAttrs(attrs.get());
|
||||||
|
|
||||||
if ( Type()->Tag() == TYPE_FUNC )
|
if ( Type()->Tag() == TYPE_FUNC )
|
||||||
{
|
{
|
||||||
|
@ -222,7 +212,7 @@ void ID::MakeDeprecated(Expr* deprecation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
attr_list* attr = new attr_list{new Attr(ATTR_DEPRECATED, deprecation)};
|
attr_list* attr = new attr_list{new Attr(ATTR_DEPRECATED, deprecation)};
|
||||||
AddAttrs(new Attributes(attr, Type(), false, IsGlobal()));
|
AddAttrs(make_intrusive<Attributes>(attr, Type(), false, IsGlobal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
string ID::GetDeprecationWarning() const
|
string ID::GetDeprecationWarning() const
|
||||||
|
@ -245,12 +235,12 @@ string ID::GetDeprecationWarning() const
|
||||||
return fmt("deprecated (%s): %s", Name(), result.c_str());
|
return fmt("deprecated (%s): %s", Name(), result.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::AddAttrs(Attributes* a)
|
void ID::AddAttrs(IntrusivePtr<Attributes> a)
|
||||||
{
|
{
|
||||||
if ( attrs )
|
if ( attrs )
|
||||||
attrs->AddAttrs(a);
|
attrs->AddAttrs(a.release());
|
||||||
else
|
else
|
||||||
attrs = a;
|
attrs = std::move(a);
|
||||||
|
|
||||||
UpdateValAttrs();
|
UpdateValAttrs();
|
||||||
}
|
}
|
||||||
|
@ -272,55 +262,20 @@ void ID::SetOption()
|
||||||
if ( ! IsRedefinable() )
|
if ( ! IsRedefinable() )
|
||||||
{
|
{
|
||||||
attr_list* attr = new attr_list{new Attr(ATTR_REDEF)};
|
attr_list* attr = new attr_list{new Attr(ATTR_REDEF)};
|
||||||
AddAttrs(new Attributes(attr, Type(), false, IsGlobal()));
|
AddAttrs(make_intrusive<Attributes>(attr, Type(), false, IsGlobal()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::EvalFunc(Expr* ef, Expr* ev)
|
void ID::EvalFunc(IntrusivePtr<Expr> ef, IntrusivePtr<Expr> ev)
|
||||||
{
|
{
|
||||||
Expr* arg1 = new ConstExpr(val->Ref());
|
auto arg1 = make_intrusive<ConstExpr>(IntrusivePtr{NewRef{}, val});
|
||||||
ListExpr* args = new ListExpr();
|
auto args = make_intrusive<ListExpr>();
|
||||||
args->Append(arg1);
|
args->Append(std::move(arg1));
|
||||||
args->Append(ev->Ref());
|
args->Append(std::move(ev));
|
||||||
|
auto ce = make_intrusive<CallExpr>(std::move(ef), std::move(args));
|
||||||
CallExpr* ce = new CallExpr(ef->Ref(), args);
|
SetVal(ce->Eval(nullptr));
|
||||||
|
|
||||||
SetVal(ce->Eval(0));
|
|
||||||
Unref(ce);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void ID::CopyFrom(const ID* id)
|
|
||||||
{
|
|
||||||
is_export = id->is_export;
|
|
||||||
is_const = id->is_const;
|
|
||||||
is_enum_const = id->is_enum_const;
|
|
||||||
is_type = id->is_type;
|
|
||||||
offset = id->offset ;
|
|
||||||
infer_return_type = id->infer_return_type;
|
|
||||||
|
|
||||||
if ( id->type )
|
|
||||||
Ref(id->type);
|
|
||||||
if ( id->val && ! id->weak_ref )
|
|
||||||
Ref(id->val);
|
|
||||||
if ( id->attrs )
|
|
||||||
Ref(id->attrs);
|
|
||||||
|
|
||||||
Unref(type);
|
|
||||||
Unref(attrs);
|
|
||||||
if ( ! weak_ref )
|
|
||||||
Unref(val);
|
|
||||||
|
|
||||||
type = id->type;
|
|
||||||
val = id->val;
|
|
||||||
attrs = id->attrs;
|
|
||||||
weak_ref = id->weak_ref;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
UpdateValID();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TraversalCode ID::Traverse(TraversalCallback* cb) const
|
TraversalCode ID::Traverse(TraversalCallback* cb) const
|
||||||
{
|
{
|
||||||
TraversalCode tc = cb->PreID(this);
|
TraversalCode tc = cb->PreID(this);
|
||||||
|
@ -359,7 +314,7 @@ TraversalCode ID::Traverse(TraversalCallback* cb) const
|
||||||
void ID::Error(const char* msg, const BroObj* o2)
|
void ID::Error(const char* msg, const BroObj* o2)
|
||||||
{
|
{
|
||||||
BroObj::Error(msg, o2, 1);
|
BroObj::Error(msg, o2, 1);
|
||||||
SetType(error_type());
|
SetType({AdoptRef{}, error_type()});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ID::Describe(ODesc* d) const
|
void ID::Describe(ODesc* d) const
|
||||||
|
@ -582,9 +537,9 @@ void ID::UpdateValID()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ID::AddOptionHandler(Func* callback, int priority)
|
void ID::AddOptionHandler(IntrusivePtr<Func> callback, int priority)
|
||||||
{
|
{
|
||||||
option_handlers.insert({priority, callback});
|
option_handlers.emplace(priority, std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Func*> ID::GetOptionHandlers() const
|
vector<Func*> ID::GetOptionHandlers() const
|
||||||
|
@ -594,6 +549,6 @@ vector<Func*> ID::GetOptionHandlers() const
|
||||||
// a lot...
|
// a lot...
|
||||||
vector<Func*> v;
|
vector<Func*> v;
|
||||||
for ( auto& element : option_handlers )
|
for ( auto& element : option_handlers )
|
||||||
v.push_back(element.second);
|
v.push_back(element.second.get());
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
30
src/ID.h
30
src/ID.h
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Obj.h"
|
#include "Obj.h"
|
||||||
#include "Attr.h"
|
#include "Attr.h"
|
||||||
#include "Notifier.h"
|
#include "Notifier.h"
|
||||||
|
@ -35,9 +36,9 @@ public:
|
||||||
|
|
||||||
std::string ModuleName() const;
|
std::string ModuleName() const;
|
||||||
|
|
||||||
void SetType(BroType* t);
|
void SetType(IntrusivePtr<BroType> t);
|
||||||
BroType* Type() { return type; }
|
BroType* Type() { return type.get(); }
|
||||||
const BroType* Type() const { return type; }
|
const BroType* Type() const { return type.get(); }
|
||||||
|
|
||||||
void MakeType() { is_type = true; }
|
void MakeType() { is_type = true; }
|
||||||
BroType* AsType() { return is_type ? Type() : 0; }
|
BroType* AsType() { return is_type ? Type() : 0; }
|
||||||
|
@ -51,10 +52,10 @@ public:
|
||||||
// reference to the Val, the Val will be destroyed (naturally,
|
// reference to the Val, the Val will be destroyed (naturally,
|
||||||
// you have to take care that it will not be accessed via
|
// you have to take care that it will not be accessed via
|
||||||
// the ID afterwards).
|
// the ID afterwards).
|
||||||
void SetVal(Val* v, bool weak_ref = false);
|
void SetVal(IntrusivePtr<Val> v, bool weak_ref = false);
|
||||||
|
|
||||||
void SetVal(Val* v, init_class c);
|
void SetVal(IntrusivePtr<Val> v, init_class c);
|
||||||
void SetVal(Expr* ev, init_class c);
|
void SetVal(IntrusivePtr<Expr> ev, init_class c);
|
||||||
|
|
||||||
bool HasVal() const { return val != 0; }
|
bool HasVal() const { return val != 0; }
|
||||||
Val* ID_Val() { return val; }
|
Val* ID_Val() { return val; }
|
||||||
|
@ -75,11 +76,11 @@ public:
|
||||||
|
|
||||||
bool IsRedefinable() const;
|
bool IsRedefinable() const;
|
||||||
|
|
||||||
void SetAttrs(Attributes* attr);
|
void SetAttrs(IntrusivePtr<Attributes> attr);
|
||||||
void AddAttrs(Attributes* attr);
|
void AddAttrs(IntrusivePtr<Attributes> attr);
|
||||||
void RemoveAttr(attr_tag a);
|
void RemoveAttr(attr_tag a);
|
||||||
void UpdateValAttrs();
|
void UpdateValAttrs();
|
||||||
Attributes* Attrs() const { return attrs; }
|
Attributes* Attrs() const { return attrs.get(); }
|
||||||
|
|
||||||
Attr* FindAttr(attr_tag t) const;
|
Attr* FindAttr(attr_tag t) const;
|
||||||
|
|
||||||
|
@ -108,12 +109,11 @@ public:
|
||||||
bool HasOptionHandlers() const
|
bool HasOptionHandlers() const
|
||||||
{ return !option_handlers.empty(); }
|
{ return !option_handlers.empty(); }
|
||||||
|
|
||||||
// Takes ownership of callback.
|
void AddOptionHandler(IntrusivePtr<Func> callback, int priority);
|
||||||
void AddOptionHandler(Func* callback, int priority);
|
|
||||||
std::vector<Func*> GetOptionHandlers() const;
|
std::vector<Func*> GetOptionHandlers() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void EvalFunc(Expr* ef, Expr* ev);
|
void EvalFunc(IntrusivePtr<Expr> ef, IntrusivePtr<Expr> ev);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void UpdateValID();
|
void UpdateValID();
|
||||||
|
@ -122,13 +122,13 @@ protected:
|
||||||
const char* name;
|
const char* name;
|
||||||
IDScope scope;
|
IDScope scope;
|
||||||
bool is_export;
|
bool is_export;
|
||||||
BroType* type;
|
IntrusivePtr<BroType> type;
|
||||||
bool is_const, is_enum_const, is_type, is_option;
|
bool is_const, is_enum_const, is_type, is_option;
|
||||||
int offset;
|
int offset;
|
||||||
Val* val;
|
Val* val;
|
||||||
Attributes* attrs;
|
IntrusivePtr<Attributes> attrs;
|
||||||
// contains list of functions that are called when an option changes
|
// contains list of functions that are called when an option changes
|
||||||
std::multimap<int, Func*> option_handlers;
|
std::multimap<int, IntrusivePtr<Func>> option_handlers;
|
||||||
|
|
||||||
bool infer_return_type;
|
bool infer_return_type;
|
||||||
bool weak_ref;
|
bool weak_ref;
|
||||||
|
|
|
@ -194,7 +194,7 @@ void net_init(const std::optional<std::string>& interface,
|
||||||
writefile, pkt_dumper->ErrorMsg());
|
writefile, pkt_dumper->ErrorMsg());
|
||||||
|
|
||||||
if ( ID* id = global_scope()->Lookup("trace_output_file") )
|
if ( ID* id = global_scope()->Lookup("trace_output_file") )
|
||||||
id->SetVal(new StringVal(writefile));
|
id->SetVal(make_intrusive<StringVal>(writefile));
|
||||||
else
|
else
|
||||||
reporter->Error("trace_output_file not defined in bro.init");
|
reporter->Error("trace_output_file not defined in bro.init");
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "RuleCondition.h"
|
#include "RuleCondition.h"
|
||||||
#include "BroString.h"
|
#include "BroString.h"
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "IntSet.h"
|
#include "IntSet.h"
|
||||||
#include "IP.h"
|
#include "IP.h"
|
||||||
#include "analyzer/Analyzer.h"
|
#include "analyzer/Analyzer.h"
|
||||||
|
@ -1268,17 +1269,14 @@ void RuleMatcher::DumpStateStats(BroFile* f, RuleHdrTest* hdr_test)
|
||||||
|
|
||||||
static Val* get_bro_val(const char* label)
|
static Val* get_bro_val(const char* label)
|
||||||
{
|
{
|
||||||
ID* id = lookup_ID(label, GLOBAL_MODULE_NAME, false);
|
auto id = lookup_ID(label, GLOBAL_MODULE_NAME, false);
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
{
|
{
|
||||||
rules_error("unknown script-level identifier", label);
|
rules_error("unknown script-level identifier", label);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* rval = id->ID_Val();
|
return id->ID_Val();
|
||||||
Unref(id);
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
38
src/Scope.cc
38
src/Scope.cc
|
@ -5,6 +5,7 @@
|
||||||
#include "Scope.h"
|
#include "Scope.h"
|
||||||
#include "Desc.h"
|
#include "Desc.h"
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
#include "module_util.h"
|
#include "module_util.h"
|
||||||
|
@ -56,8 +57,15 @@ Scope::~Scope()
|
||||||
|
|
||||||
Unref(scope_id);
|
Unref(scope_id);
|
||||||
Unref(return_type);
|
Unref(return_type);
|
||||||
|
|
||||||
|
if ( inits )
|
||||||
|
{
|
||||||
|
for ( const auto& i : *inits )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
delete inits;
|
delete inits;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ID* Scope::GenerateTemporary(const char* name)
|
ID* Scope::GenerateTemporary(const char* name)
|
||||||
{
|
{
|
||||||
|
@ -119,8 +127,9 @@ TraversalCode Scope::Traverse(TraversalCallback* cb) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ID* lookup_ID(const char* name, const char* curr_module, bool no_global,
|
IntrusivePtr<ID> lookup_ID(const char* name, const char* curr_module,
|
||||||
bool same_module_only, bool check_export)
|
bool no_global, bool same_module_only,
|
||||||
|
bool check_export)
|
||||||
{
|
{
|
||||||
string fullname = make_full_var_name(curr_module, name);
|
string fullname = make_full_var_name(curr_module, name);
|
||||||
|
|
||||||
|
@ -137,8 +146,7 @@ ID* lookup_ID(const char* name, const char* curr_module, bool no_global,
|
||||||
reporter->Error("identifier is not exported: %s",
|
reporter->Error("identifier is not exported: %s",
|
||||||
fullname.c_str());
|
fullname.c_str());
|
||||||
|
|
||||||
Ref(id);
|
return {NewRef{}, id};
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,16 +156,13 @@ ID* lookup_ID(const char* name, const char* curr_module, bool no_global,
|
||||||
string globalname = make_full_var_name(GLOBAL_MODULE_NAME, name);
|
string globalname = make_full_var_name(GLOBAL_MODULE_NAME, name);
|
||||||
ID* id = global_scope()->Lookup(globalname);
|
ID* id = global_scope()->Lookup(globalname);
|
||||||
if ( id )
|
if ( id )
|
||||||
{
|
return {NewRef{}, id};
|
||||||
Ref(id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID* install_ID(const char* name, const char* module_name,
|
IntrusivePtr<ID> install_ID(const char* name, const char* module_name,
|
||||||
bool is_global, bool is_export)
|
bool is_global, bool is_export)
|
||||||
{
|
{
|
||||||
if ( scopes.empty() && ! is_global )
|
if ( scopes.empty() && ! is_global )
|
||||||
|
@ -175,13 +180,14 @@ ID* install_ID(const char* name, const char* module_name,
|
||||||
|
|
||||||
string full_name = make_full_var_name(module_name, name);
|
string full_name = make_full_var_name(module_name, name);
|
||||||
|
|
||||||
ID* id = new ID(full_name.data(), scope, is_export);
|
auto id = make_intrusive<ID>(full_name.data(), scope, is_export);
|
||||||
|
|
||||||
if ( SCOPE_FUNCTION != scope )
|
if ( SCOPE_FUNCTION != scope )
|
||||||
global_scope()->Insert(std::move(full_name), id);
|
global_scope()->Insert(std::move(full_name), IntrusivePtr{id}.release());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id->SetOffset(top_scope->Length());
|
id->SetOffset(top_scope->Length());
|
||||||
top_scope->Insert(std::move(full_name), id);
|
top_scope->Insert(std::move(full_name), IntrusivePtr{id}.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
@ -198,21 +204,17 @@ void push_scope(ID* id, attr_list* attrs)
|
||||||
scopes.push_back(top_scope);
|
scopes.push_back(top_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope* pop_scope()
|
IntrusivePtr<Scope> pop_scope()
|
||||||
{
|
{
|
||||||
if ( scopes.empty() )
|
if ( scopes.empty() )
|
||||||
reporter->InternalError("scope underflow");
|
reporter->InternalError("scope underflow");
|
||||||
scopes.pop_back();
|
scopes.pop_back();
|
||||||
|
|
||||||
Scope* old_top = top_scope;
|
Scope* old_top = top_scope;
|
||||||
// Don't delete the scope; keep it around for later name resolution
|
|
||||||
// in the debugger.
|
|
||||||
// ### SERIOUS MEMORY LEAK!?
|
|
||||||
// delete top_scope;
|
|
||||||
|
|
||||||
top_scope = scopes.empty() ? nullptr : scopes.back();
|
top_scope = scopes.empty() ? nullptr : scopes.back();
|
||||||
|
|
||||||
return old_top;
|
return {AdoptRef{}, old_top};
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope* current_scope()
|
Scope* current_scope()
|
||||||
|
|
31
src/Scope.h
31
src/Scope.h
|
@ -10,6 +10,7 @@
|
||||||
#include "BroList.h"
|
#include "BroList.h"
|
||||||
#include "TraverseTypes.h"
|
#include "TraverseTypes.h"
|
||||||
|
|
||||||
|
template <class T> class IntrusivePtr;
|
||||||
class ID;
|
class ID;
|
||||||
class BroType;
|
class BroType;
|
||||||
class ListVal;
|
class ListVal;
|
||||||
|
@ -20,9 +21,10 @@ public:
|
||||||
~Scope() override;
|
~Scope() override;
|
||||||
|
|
||||||
template<typename N>
|
template<typename N>
|
||||||
ID* Lookup(N &&name) const
|
ID* Lookup(N&& name) const
|
||||||
{
|
{
|
||||||
const auto& entry = local.find(std::forward<N>(name));
|
const auto& entry = local.find(std::forward<N>(name));
|
||||||
|
|
||||||
if ( entry != local.end() )
|
if ( entry != local.end() )
|
||||||
return entry->second;
|
return entry->second;
|
||||||
|
|
||||||
|
@ -30,12 +32,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename N>
|
template<typename N>
|
||||||
void Insert(N &&name, ID* id) { local[std::forward<N>(name)] = id; }
|
void Insert(N&& name, ID* id)
|
||||||
|
{
|
||||||
|
auto [it, inserted] = local.emplace(std::forward<N>(name), id);
|
||||||
|
|
||||||
|
if ( ! inserted )
|
||||||
|
{
|
||||||
|
Unref(it->second);
|
||||||
|
it->second = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename N>
|
template<typename N>
|
||||||
ID* Remove(N &&name)
|
ID* Remove(N&& name)
|
||||||
{
|
{
|
||||||
const auto& entry = local.find(std::forward<N>(name));
|
const auto& entry = local.find(std::forward<N>(name));
|
||||||
|
|
||||||
if ( entry != local.end() )
|
if ( entry != local.end() )
|
||||||
{
|
{
|
||||||
ID* id = entry->second;
|
ID* id = entry->second;
|
||||||
|
@ -78,18 +90,19 @@ protected:
|
||||||
extern bool in_debug;
|
extern bool in_debug;
|
||||||
|
|
||||||
// If no_global is true, don't search in the default "global" namespace.
|
// If no_global is true, don't search in the default "global" namespace.
|
||||||
// This passed ownership of a ref'ed ID to the caller.
|
extern IntrusivePtr<ID> lookup_ID(const char* name, const char* module,
|
||||||
extern ID* lookup_ID(const char* name, const char* module,
|
bool no_global = false,
|
||||||
bool no_global = false, bool same_module_only = false,
|
bool same_module_only = false,
|
||||||
bool check_export = true);
|
bool check_export = true);
|
||||||
extern ID* install_ID(const char* name, const char* module_name,
|
|
||||||
|
extern IntrusivePtr<ID> install_ID(const char* name, const char* module_name,
|
||||||
bool is_global, bool is_export);
|
bool is_global, bool is_export);
|
||||||
|
|
||||||
extern void push_scope(ID* id, attr_list* attrs);
|
extern void push_scope(ID* id, attr_list* attrs);
|
||||||
extern void push_existing_scope(Scope* scope);
|
extern void push_existing_scope(Scope* scope);
|
||||||
|
|
||||||
// Returns the one popped off; it's not deleted.
|
// Returns the one popped off.
|
||||||
extern Scope* pop_scope();
|
extern IntrusivePtr<Scope> pop_scope();
|
||||||
extern Scope* current_scope();
|
extern Scope* current_scope();
|
||||||
extern Scope* global_scope();
|
extern Scope* global_scope();
|
||||||
|
|
||||||
|
|
296
src/Stmt.cc
296
src/Stmt.cc
|
@ -130,11 +130,9 @@ void Stmt::AccessStats(ODesc* d) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprListStmt::ExprListStmt(BroStmtTag t, ListExpr* arg_l)
|
ExprListStmt::ExprListStmt(BroStmtTag t, IntrusivePtr<ListExpr> arg_l)
|
||||||
: Stmt(t)
|
: Stmt(t), l(std::move(arg_l))
|
||||||
{
|
{
|
||||||
l = arg_l;
|
|
||||||
|
|
||||||
const expr_list& e = l->Exprs();
|
const expr_list& e = l->Exprs();
|
||||||
for ( const auto& expr : e )
|
for ( const auto& expr : e )
|
||||||
{
|
{
|
||||||
|
@ -143,28 +141,25 @@ ExprListStmt::ExprListStmt(BroStmtTag t, ListExpr* arg_l)
|
||||||
Error("value of type void illegal");
|
Error("value of type void illegal");
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLocationInfo(arg_l->GetLocationInfo());
|
SetLocationInfo(l->GetLocationInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprListStmt::~ExprListStmt()
|
ExprListStmt::~ExprListStmt() = default;
|
||||||
{
|
|
||||||
Unref(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
last_access = network_time;
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
|
||||||
val_list* vals = eval_list(f, l);
|
val_list* vals = eval_list(f, l.get());
|
||||||
if ( vals )
|
if ( vals )
|
||||||
{
|
{
|
||||||
Val* result = DoExec(vals, flow);
|
auto result = DoExec(vals, flow);
|
||||||
delete_vals(vals);
|
delete_vals(vals);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprListStmt::Describe(ODesc* d) const
|
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)
|
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);
|
||||||
assert(id->IsEnumConst());
|
assert(id->IsEnumConst());
|
||||||
|
|
||||||
|
@ -212,7 +207,7 @@ static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Val* print_log(val_list* vals)
|
static void print_log(val_list* vals)
|
||||||
{
|
{
|
||||||
auto plval = lookup_enum_val("Log", "PRINTLOG");
|
auto plval = lookup_enum_val("Log", "PRINTLOG");
|
||||||
auto record = make_intrusive<RecordVal>(internal_type("Log::PrintLogInfo")->AsRecordType());
|
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(0, new Val(current_time(), TYPE_TIME));
|
||||||
record->Assign(1, vec.release());
|
record->Assign(1, vec.release());
|
||||||
log_mgr->Write(plval.get(), record.get());
|
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();
|
RegisterAccess();
|
||||||
|
|
||||||
|
@ -245,7 +239,7 @@ Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
|
||||||
{
|
{
|
||||||
f = (*vals)[0]->AsFile();
|
f = (*vals)[0]->AsFile();
|
||||||
if ( ! f->IsOpen() )
|
if ( ! f->IsOpen() )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
++offset;
|
++offset;
|
||||||
}
|
}
|
||||||
|
@ -257,12 +251,18 @@ Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
|
||||||
case BifEnum::Log::REDIRECT_NONE:
|
case BifEnum::Log::REDIRECT_NONE:
|
||||||
break;
|
break;
|
||||||
case BifEnum::Log::REDIRECT_ALL:
|
case BifEnum::Log::REDIRECT_ALL:
|
||||||
return print_log(vals);
|
{
|
||||||
|
print_log(vals);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
case BifEnum::Log::REDIRECT_STDOUT:
|
case BifEnum::Log::REDIRECT_STDOUT:
|
||||||
if ( f->File() == stdout )
|
if ( f->File() == stdout )
|
||||||
|
{
|
||||||
// Should catch even printing to a "manually opened" stdout file,
|
// Should catch even printing to a "manually opened" stdout file,
|
||||||
// like "/dev/stdout" or "-".
|
// like "/dev/stdout" or "-".
|
||||||
return print_log(vals);
|
print_log(vals);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
reporter->InternalError("unknown Log::PrintLogType value: %d",
|
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);
|
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() )
|
if ( e && e->IsPure() )
|
||||||
Warn("expression value ignored");
|
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 )
|
if ( e )
|
||||||
SetLocationInfo(e->GetLocationInfo());
|
SetLocationInfo(e->GetLocationInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprStmt::~ExprStmt()
|
ExprStmt::~ExprStmt() = default;
|
||||||
{
|
|
||||||
Unref(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Val* ExprStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
IntrusivePtr<Val> ExprStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
|
||||||
Val* v = e->Eval(f);
|
auto v = e->Eval(f);
|
||||||
|
|
||||||
if ( v )
|
if ( v )
|
||||||
{
|
return DoExec(f, v.get(), flow);
|
||||||
Val* ret_val = DoExec(f, v, flow);
|
|
||||||
Unref(v);
|
|
||||||
return ret_val;
|
|
||||||
}
|
|
||||||
else
|
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
|
int ExprStmt::IsPure() const
|
||||||
|
@ -379,29 +369,25 @@ TraversalCode ExprStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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()) )
|
if ( ! e->IsError() && ! IsBool(e->Type()->Tag()) )
|
||||||
e->Error("conditional in test must be boolean");
|
e->Error("conditional in test must be boolean");
|
||||||
|
|
||||||
const Location* loc1 = arg_s1->GetLocationInfo();
|
const Location* loc1 = s1->GetLocationInfo();
|
||||||
const Location* loc2 = arg_s2->GetLocationInfo();
|
const Location* loc2 = s2->GetLocationInfo();
|
||||||
SetLocationInfo(loc1, loc2);
|
SetLocationInfo(loc1, loc2);
|
||||||
}
|
}
|
||||||
|
|
||||||
IfStmt::~IfStmt()
|
IfStmt::~IfStmt() = default;
|
||||||
{
|
|
||||||
Unref(s1);
|
|
||||||
Unref(s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
// 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);
|
f->SetNextStmt(do_stmt);
|
||||||
|
|
||||||
|
@ -409,9 +395,9 @@ Val* IfStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
||||||
{ // ### Abort or something
|
{ // ### 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
|
{ // ### 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]);
|
return get_last_stmt_tag(stmts->Stmts()[len - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Case::Case(ListExpr* arg_expr_cases, id_list* arg_type_cases, Stmt* arg_s)
|
Case::Case(IntrusivePtr<ListExpr> arg_expr_cases, id_list* arg_type_cases,
|
||||||
: expr_cases(arg_expr_cases), type_cases(arg_type_cases), s(arg_s)
|
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());
|
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()
|
Case::~Case()
|
||||||
{
|
{
|
||||||
Unref(expr_cases);
|
|
||||||
Unref(s);
|
|
||||||
|
|
||||||
for ( const auto& id : *type_cases )
|
for ( const auto& id : *type_cases )
|
||||||
Unref(id);
|
Unref(id);
|
||||||
|
|
||||||
|
@ -609,8 +594,9 @@ void SwitchStmt::Init()
|
||||||
case_label_value_map.SetDeleteFunc(int_del_func);
|
case_label_value_map.SetDeleteFunc(int_del_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
|
SwitchStmt::SwitchStmt(IntrusivePtr<Expr> index, case_list* arg_cases)
|
||||||
ExprStmt(STMT_SWITCH, index), cases(arg_cases), default_case_idx(-1)
|
: ExprStmt(STMT_SWITCH, std::move(index)),
|
||||||
|
cases(arg_cases), default_case_idx(-1)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
|
@ -632,7 +618,7 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
|
||||||
|
|
||||||
if ( ! le->Type()->AsTypeList()->AllMatch(e->Type(), false) )
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,10 +656,10 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
|
||||||
|
|
||||||
if ( ne->Id()->IsConst() )
|
if ( ne->Id()->IsConst() )
|
||||||
{
|
{
|
||||||
Val* v = ne->Eval(0);
|
auto v = ne->Eval(0);
|
||||||
|
|
||||||
if ( v )
|
if ( v )
|
||||||
Unref(exprs.replace(j, new ConstExpr(v)));
|
Unref(exprs.replace(j, new ConstExpr(std::move(v))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -820,16 +806,16 @@ std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const
|
||||||
return std::make_pair(label_idx, label_id);
|
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);
|
auto m = FindCaseLabelMatch(v);
|
||||||
int matching_label_idx = m.first;
|
int matching_label_idx = m.first;
|
||||||
ID* matching_id = m.second;
|
ID* matching_id = m.second;
|
||||||
|
|
||||||
if ( matching_label_idx == -1 )
|
if ( matching_label_idx == -1 )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
for ( int i = matching_label_idx; i < cases->length(); ++i )
|
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 )
|
if ( matching_id )
|
||||||
{
|
{
|
||||||
auto cv = cast_value_to_type(v, matching_id->Type());
|
auto cv = cast_value_to_type(v, matching_id->Type());
|
||||||
f->SetElement(matching_id, cv);
|
f->SetElement(matching_id, cv.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
@ -905,7 +891,7 @@ TraversalCode SwitchStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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() )
|
if ( ! e->CanAdd() )
|
||||||
Error("illegal add statement");
|
Error("illegal add statement");
|
||||||
|
@ -916,12 +902,12 @@ int AddStmt::IsPure() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* AddStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
IntrusivePtr<Val> AddStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
e->Add(f);
|
e->Add(f);
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -938,7 +924,7 @@ TraversalCode AddStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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() )
|
if ( e->IsError() )
|
||||||
return;
|
return;
|
||||||
|
@ -952,12 +938,12 @@ int DelStmt::IsPure() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* DelStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
IntrusivePtr<Val> DelStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
e->Delete(f);
|
e->Delete(f);
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TraversalCode DelStmt::Traverse(TraversalCallback* cb) const
|
TraversalCode DelStmt::Traverse(TraversalCallback* cb) const
|
||||||
|
@ -973,12 +959,12 @@ TraversalCode DelStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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();
|
RegisterAccess();
|
||||||
val_list* args = eval_list(f, event_expr->Args());
|
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;
|
flow = FLOW_NEXT;
|
||||||
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TraversalCode EventStmt::Traverse(TraversalCallback* cb) const
|
TraversalCode EventStmt::Traverse(TraversalCallback* cb) const
|
||||||
|
@ -1007,19 +992,16 @@ TraversalCode EventStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
HANDLE_TC_STMT_POST(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
WhileStmt::WhileStmt(Expr* arg_loop_condition, Stmt* arg_body)
|
WhileStmt::WhileStmt(IntrusivePtr<Expr> arg_loop_condition,
|
||||||
: loop_condition(arg_loop_condition), body(arg_body)
|
IntrusivePtr<Stmt> arg_body)
|
||||||
|
: loop_condition(std::move(arg_loop_condition)), body(std::move(arg_body))
|
||||||
{
|
{
|
||||||
if ( ! loop_condition->IsError() &&
|
if ( ! loop_condition->IsError() &&
|
||||||
! IsBool(loop_condition->Type()->Tag()) )
|
! IsBool(loop_condition->Type()->Tag()) )
|
||||||
loop_condition->Error("while conditional must be boolean");
|
loop_condition->Error("while conditional must be boolean");
|
||||||
}
|
}
|
||||||
|
|
||||||
WhileStmt::~WhileStmt()
|
WhileStmt::~WhileStmt() = default;
|
||||||
{
|
|
||||||
Unref(loop_condition);
|
|
||||||
Unref(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
int WhileStmt::IsPure() const
|
int WhileStmt::IsPure() const
|
||||||
{
|
{
|
||||||
|
@ -1060,23 +1042,20 @@ TraversalCode WhileStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
Val* rval = 0;
|
IntrusivePtr<Val> rval;
|
||||||
|
|
||||||
for ( ; ; )
|
for ( ; ; )
|
||||||
{
|
{
|
||||||
Val* cond = loop_condition->Eval(f);
|
auto cond = loop_condition->Eval(f);
|
||||||
|
|
||||||
if ( ! cond )
|
if ( ! cond )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bool cont = cond->AsBool();
|
if ( ! cond->AsBool() )
|
||||||
Unref(cond);
|
|
||||||
|
|
||||||
if ( ! cont )
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
@ -1092,8 +1071,8 @@ Val* WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
|
ForStmt::ForStmt(id_list* arg_loop_vars, IntrusivePtr<Expr> loop_expr)
|
||||||
: ExprStmt(STMT_FOR, loop_expr)
|
: ExprStmt(STMT_FOR, std::move(loop_expr))
|
||||||
{
|
{
|
||||||
loop_vars = arg_loop_vars;
|
loop_vars = arg_loop_vars;
|
||||||
body = 0;
|
body = 0;
|
||||||
|
@ -1119,8 +1098,8 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete add_local((*loop_vars)[i],
|
add_local({NewRef{}, (*loop_vars)[i]},
|
||||||
ind_type->Ref(), INIT_NONE,
|
{NewRef{}, ind_type}, INIT_NONE,
|
||||||
0, 0, VAR_REGULAR);
|
0, 0, VAR_REGULAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1115,7 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
|
||||||
|
|
||||||
BroType* t = (*loop_vars)[0]->Type();
|
BroType* t = (*loop_vars)[0]->Type();
|
||||||
if ( ! t )
|
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);
|
INIT_NONE, 0, 0, VAR_REGULAR);
|
||||||
|
|
||||||
else if ( ! IsIntegral(t->Tag()) )
|
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();
|
BroType* t = (*loop_vars)[0]->Type();
|
||||||
if ( ! t )
|
if ( ! t )
|
||||||
delete add_local((*loop_vars)[0],
|
add_local({NewRef{}, (*loop_vars)[0]},
|
||||||
base_type(TYPE_STRING),
|
{AdoptRef{}, base_type(TYPE_STRING)},
|
||||||
INIT_NONE, 0, 0, VAR_REGULAR);
|
INIT_NONE, 0, 0, VAR_REGULAR);
|
||||||
|
|
||||||
else if ( t->Tag() != TYPE_STRING )
|
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");
|
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::ForStmt(id_list* arg_loop_vars,
|
||||||
: ForStmt(arg_loop_vars, loop_expr)
|
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() )
|
if ( e->Type()->IsTable() )
|
||||||
{
|
{
|
||||||
|
@ -1187,7 +1167,7 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr, ID* val_var)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete add_local(value_var, yield_type->Ref(), INIT_NONE,
|
add_local(value_var, {NewRef{}, yield_type}, INIT_NONE,
|
||||||
0, 0, VAR_REGULAR);
|
0, 0, VAR_REGULAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1200,14 +1180,11 @@ ForStmt::~ForStmt()
|
||||||
for ( const auto& var : *loop_vars )
|
for ( const auto& var : *loop_vars )
|
||||||
Unref(var);
|
Unref(var);
|
||||||
delete loop_vars;
|
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 )
|
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();
|
const PDict<TableEntryVal>* loop_vals = tv->AsTable();
|
||||||
|
|
||||||
if ( ! loop_vals->Length() )
|
if ( ! loop_vals->Length() )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
HashKey* k;
|
HashKey* k;
|
||||||
TableEntryVal* current_tev;
|
TableEntryVal* current_tev;
|
||||||
|
@ -1226,7 +1203,7 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
||||||
delete k;
|
delete k;
|
||||||
|
|
||||||
if ( value_var )
|
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++ )
|
for ( int i = 0; i < ind_lv->Length(); i++ )
|
||||||
f->SetElement((*loop_vars)[i], ind_lv->Index(i)->Ref());
|
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);
|
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();
|
RegisterAccess();
|
||||||
flow = FLOW_LOOP;
|
flow = FLOW_LOOP;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NextStmt::IsPure() const
|
int NextStmt::IsPure() const
|
||||||
|
@ -1383,11 +1360,11 @@ TraversalCode NextStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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();
|
RegisterAccess();
|
||||||
flow = FLOW_BREAK;
|
flow = FLOW_BREAK;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BreakStmt::IsPure() const
|
int BreakStmt::IsPure() const
|
||||||
|
@ -1410,11 +1387,11 @@ TraversalCode BreakStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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();
|
RegisterAccess();
|
||||||
flow = FLOW_FALLTHROUGH;
|
flow = FLOW_FALLTHROUGH;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FallthroughStmt::IsPure() const
|
int FallthroughStmt::IsPure() const
|
||||||
|
@ -1437,7 +1414,8 @@ TraversalCode FallthroughStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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();
|
Scope* s = current_scope();
|
||||||
|
|
||||||
|
@ -1472,10 +1450,14 @@ ReturnStmt::ReturnStmt(Expr* arg_e) : ExprStmt(STMT_RETURN, arg_e)
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
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();
|
RegisterAccess();
|
||||||
flow = FLOW_RETURN;
|
flow = FLOW_RETURN;
|
||||||
|
@ -1483,7 +1465,7 @@ Val* ReturnStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
if ( e )
|
if ( e )
|
||||||
return e->Eval(f);
|
return e->Eval(f);
|
||||||
else
|
else
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReturnStmt::Describe(ODesc* d) const
|
void ReturnStmt::Describe(ODesc* d) const
|
||||||
|
@ -1514,7 +1496,7 @@ StmtList::~StmtList()
|
||||||
Unref(stmt);
|
Unref(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* StmtList::Exec(Frame* f, stmt_flow_type& flow) const
|
IntrusivePtr<Val> StmtList::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
@ -1527,9 +1509,9 @@ Val* StmtList::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{ // ### Abort or something
|
{ // ### 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
|
{ // ### Abort or something
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1537,7 +1519,7 @@ Val* StmtList::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StmtList::IsPure() const
|
int StmtList::IsPure() const
|
||||||
|
@ -1593,7 +1575,7 @@ TraversalCode StmtList::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
@ -1610,9 +1592,9 @@ Val* EventBodyList::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{ // ### Abort or something
|
{ // ### 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
|
{ // ### Abort or something
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1621,7 +1603,7 @@ Val* EventBodyList::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
stmt_flow_type ft = FLOW_RETURN;
|
stmt_flow_type ft = FLOW_RETURN;
|
||||||
(void) post_execute_stmt(f->GetNextStmt(), f, 0, &ft);
|
(void) post_execute_stmt(f->GetNextStmt(), f, 0, &ft);
|
||||||
|
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventBodyList::Describe(ODesc* d) const
|
void EventBodyList::Describe(ODesc* d) const
|
||||||
|
@ -1666,7 +1648,7 @@ InitStmt::~InitStmt()
|
||||||
delete inits;
|
delete inits;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
IntrusivePtr<Val> InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
@ -1694,7 +1676,7 @@ Val* InitStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
f->SetElement(aggr, v);
|
f->SetElement(aggr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitStmt::Describe(ODesc* d) const
|
void InitStmt::Describe(ODesc* d) const
|
||||||
|
@ -1730,11 +1712,11 @@ TraversalCode InitStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
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();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NullStmt::IsPure() const
|
int NullStmt::IsPure() const
|
||||||
|
@ -1759,18 +1741,15 @@ TraversalCode NullStmt::Traverse(TraversalCallback* cb) const
|
||||||
HANDLE_TC_STMT_POST(tc);
|
HANDLE_TC_STMT_POST(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
WhenStmt::WhenStmt(Expr* arg_cond, Stmt* arg_s1, Stmt* arg_s2,
|
WhenStmt::WhenStmt(IntrusivePtr<Expr> arg_cond,
|
||||||
Expr* arg_timeout, bool arg_is_return)
|
IntrusivePtr<Stmt> arg_s1, IntrusivePtr<Stmt> arg_s2,
|
||||||
: Stmt(STMT_WHEN)
|
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(cond);
|
||||||
assert(arg_s1);
|
assert(s1);
|
||||||
|
|
||||||
cond = arg_cond;
|
|
||||||
s1 = arg_s1;
|
|
||||||
s2 = arg_s2;
|
|
||||||
timeout = arg_timeout;
|
|
||||||
is_return = arg_is_return;
|
|
||||||
|
|
||||||
if ( ! cond->IsError() && ! IsBool(cond->Type()->Tag()) )
|
if ( ! cond->IsError() && ! IsBool(cond->Type()->Tag()) )
|
||||||
cond->Error("conditional in test must be boolean");
|
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()
|
WhenStmt::~WhenStmt() = default;
|
||||||
{
|
|
||||||
Unref(cond);
|
|
||||||
Unref(s1);
|
|
||||||
Unref(s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
Val* WhenStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
IntrusivePtr<Val> WhenStmt::Exec(Frame* f, stmt_flow_type& flow) const
|
||||||
{
|
{
|
||||||
RegisterAccess();
|
RegisterAccess();
|
||||||
flow = FLOW_NEXT;
|
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.
|
// The new trigger object will take care of its own deletion.
|
||||||
new trigger::Trigger(cond, s1, s2, timeout, f, is_return, location);
|
new trigger::Trigger(IntrusivePtr{cond}.release(),
|
||||||
|
IntrusivePtr{s1}.release(),
|
||||||
return 0;
|
IntrusivePtr{s2}.release(),
|
||||||
|
IntrusivePtr{timeout}.release(),
|
||||||
|
f, is_return, location);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WhenStmt::IsPure() const
|
int WhenStmt::IsPure() const
|
||||||
|
|
180
src/Stmt.h
180
src/Stmt.h
|
@ -26,7 +26,7 @@ public:
|
||||||
|
|
||||||
~Stmt() override;
|
~Stmt() override;
|
||||||
|
|
||||||
virtual Val* Exec(Frame* f, stmt_flow_type& flow) const = 0;
|
virtual IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const = 0;
|
||||||
|
|
||||||
Stmt* Ref() { ::Ref(this); return this; }
|
Stmt* Ref() { ::Ref(this); return this; }
|
||||||
|
|
||||||
|
@ -85,116 +85,105 @@ protected:
|
||||||
|
|
||||||
class ExprListStmt : public Stmt {
|
class ExprListStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
const ListExpr* ExprList() const { return l; }
|
const ListExpr* ExprList() const { return l.get(); }
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ExprListStmt() { l = 0; }
|
ExprListStmt(BroStmtTag t, IntrusivePtr<ListExpr> arg_l);
|
||||||
ExprListStmt(BroStmtTag t, ListExpr* arg_l);
|
|
||||||
|
|
||||||
~ExprListStmt() override;
|
~ExprListStmt() override;
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
virtual Val* DoExec(val_list* vals, stmt_flow_type& flow) const = 0;
|
virtual IntrusivePtr<Val> DoExec(val_list* vals, stmt_flow_type& flow) const = 0;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
void PrintVals(ODesc* d, val_list* vals, int offset) const;
|
void PrintVals(ODesc* d, val_list* vals, int offset) const;
|
||||||
|
|
||||||
ListExpr* l;
|
IntrusivePtr<ListExpr> l;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PrintStmt : public ExprListStmt {
|
class PrintStmt : public ExprListStmt {
|
||||||
public:
|
public:
|
||||||
explicit PrintStmt(ListExpr* l) : ExprListStmt(STMT_PRINT, l) { }
|
template<typename L>
|
||||||
|
explicit PrintStmt(L&& l) : ExprListStmt(STMT_PRINT, std::forward<L>(l)) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
IntrusivePtr<Val> DoExec(val_list* vals, stmt_flow_type& flow) const override;
|
||||||
PrintStmt() {}
|
|
||||||
|
|
||||||
Val* DoExec(val_list* vals, stmt_flow_type& flow) const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExprStmt : public Stmt {
|
class ExprStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
explicit ExprStmt(Expr* e);
|
explicit ExprStmt(IntrusivePtr<Expr> e);
|
||||||
~ExprStmt() override;
|
~ExprStmt() override;
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
const Expr* StmtExpr() const { return e; }
|
const Expr* StmtExpr() const { return e.get(); }
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
ExprStmt(BroStmtTag t, IntrusivePtr<Expr> e);
|
||||||
ExprStmt() { e = 0; }
|
|
||||||
ExprStmt(BroStmtTag t, Expr* e);
|
|
||||||
|
|
||||||
virtual Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const;
|
virtual IntrusivePtr<Val> DoExec(Frame* f, Val* v, stmt_flow_type& flow) const;
|
||||||
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
Expr* e;
|
IntrusivePtr<Expr> e;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IfStmt : public ExprStmt {
|
class IfStmt : public ExprStmt {
|
||||||
public:
|
public:
|
||||||
IfStmt(Expr* test, Stmt* s1, Stmt* s2);
|
IfStmt(IntrusivePtr<Expr> test, IntrusivePtr<Stmt> s1, IntrusivePtr<Stmt> s2);
|
||||||
~IfStmt() override;
|
~IfStmt() override;
|
||||||
|
|
||||||
const Stmt* TrueBranch() const { return s1; }
|
const Stmt* TrueBranch() const { return s1.get(); }
|
||||||
const Stmt* FalseBranch() const { return s2; }
|
const Stmt* FalseBranch() const { return s2.get(); }
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
IntrusivePtr<Val> DoExec(Frame* f, Val* v, stmt_flow_type& flow) const override;
|
||||||
IfStmt() { s1 = s2 = 0; }
|
|
||||||
|
|
||||||
Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const override;
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
Stmt* s1;
|
IntrusivePtr<Stmt> s1;
|
||||||
Stmt* s2;
|
IntrusivePtr<Stmt> s2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Case : public BroObj {
|
class Case : public BroObj {
|
||||||
public:
|
public:
|
||||||
Case(ListExpr* c, id_list* types, Stmt* arg_s);
|
Case(IntrusivePtr<ListExpr> c, id_list* types, IntrusivePtr<Stmt> arg_s);
|
||||||
~Case() override;
|
~Case() override;
|
||||||
|
|
||||||
const ListExpr* ExprCases() const { return expr_cases; }
|
const ListExpr* ExprCases() const { return expr_cases.get(); }
|
||||||
ListExpr* ExprCases() { return expr_cases; }
|
ListExpr* ExprCases() { return expr_cases.get(); }
|
||||||
|
|
||||||
const id_list* TypeCases() const { return type_cases; }
|
const id_list* TypeCases() const { return type_cases; }
|
||||||
id_list* TypeCases() { return type_cases; }
|
id_list* TypeCases() { return type_cases; }
|
||||||
|
|
||||||
const Stmt* Body() const { return s; }
|
const Stmt* Body() const { return s.get(); }
|
||||||
Stmt* Body() { return s; }
|
Stmt* Body() { return s.get(); }
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const;
|
TraversalCode Traverse(TraversalCallback* cb) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
IntrusivePtr<ListExpr> expr_cases;
|
||||||
Case() { expr_cases = 0; type_cases = 0; s = 0; }
|
|
||||||
|
|
||||||
ListExpr* expr_cases;
|
|
||||||
id_list* type_cases;
|
id_list* type_cases;
|
||||||
Stmt* s;
|
IntrusivePtr<Stmt> s;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef PList<Case> case_list;
|
typedef PList<Case> case_list;
|
||||||
|
|
||||||
class SwitchStmt : public ExprStmt {
|
class SwitchStmt : public ExprStmt {
|
||||||
public:
|
public:
|
||||||
SwitchStmt(Expr* index, case_list* cases);
|
SwitchStmt(IntrusivePtr<Expr> index, case_list* cases);
|
||||||
~SwitchStmt() override;
|
~SwitchStmt() override;
|
||||||
|
|
||||||
const case_list* Cases() const { return cases; }
|
const case_list* Cases() const { return cases; }
|
||||||
|
@ -204,10 +193,7 @@ public:
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
IntrusivePtr<Val> DoExec(Frame* f, Val* v, stmt_flow_type& flow) const override;
|
||||||
SwitchStmt() { cases = 0; default_case_idx = -1; comp_hash = 0; }
|
|
||||||
|
|
||||||
Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const override;
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
// Initialize composite hash and case label map.
|
// Initialize composite hash and case label map.
|
||||||
|
@ -238,51 +224,40 @@ protected:
|
||||||
|
|
||||||
class AddStmt : public ExprStmt {
|
class AddStmt : public ExprStmt {
|
||||||
public:
|
public:
|
||||||
explicit AddStmt(Expr* e);
|
explicit AddStmt(IntrusivePtr<Expr> e);
|
||||||
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class Stmt;
|
|
||||||
AddStmt() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DelStmt : public ExprStmt {
|
class DelStmt : public ExprStmt {
|
||||||
public:
|
public:
|
||||||
explicit DelStmt(Expr* e);
|
explicit DelStmt(IntrusivePtr<Expr> e);
|
||||||
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class Stmt;
|
|
||||||
DelStmt() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventStmt : public ExprStmt {
|
class EventStmt : public ExprStmt {
|
||||||
public:
|
public:
|
||||||
explicit EventStmt(EventExpr* e);
|
explicit EventStmt(IntrusivePtr<EventExpr> e);
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
IntrusivePtr<EventExpr> event_expr;
|
||||||
EventStmt() { event_expr = 0; }
|
|
||||||
|
|
||||||
EventExpr* event_expr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class WhileStmt : public Stmt {
|
class WhileStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WhileStmt(Expr* loop_condition, Stmt* body);
|
WhileStmt(IntrusivePtr<Expr> loop_condition, IntrusivePtr<Stmt> body);
|
||||||
~WhileStmt() override;
|
~WhileStmt() override;
|
||||||
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
@ -292,29 +267,24 @@ public:
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
WhileStmt()
|
IntrusivePtr<Expr> loop_condition;
|
||||||
{ loop_condition = 0; body = 0; }
|
IntrusivePtr<Stmt> body;
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
|
||||||
|
|
||||||
Expr* loop_condition;
|
|
||||||
Stmt* body;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ForStmt : public ExprStmt {
|
class ForStmt : public ExprStmt {
|
||||||
public:
|
public:
|
||||||
ForStmt(id_list* loop_vars, Expr* loop_expr);
|
ForStmt(id_list* loop_vars, IntrusivePtr<Expr> loop_expr);
|
||||||
// Special constructor for key value for loop.
|
// Special constructor for key value for loop.
|
||||||
ForStmt(id_list* loop_vars, Expr* loop_expr, ID* val_var);
|
ForStmt(id_list* loop_vars, IntrusivePtr<Expr> loop_expr, IntrusivePtr<ID> val_var);
|
||||||
~ForStmt() override;
|
~ForStmt() override;
|
||||||
|
|
||||||
void AddBody(Stmt* arg_body) { body = arg_body; }
|
void AddBody(IntrusivePtr<Stmt> arg_body) { body = std::move(arg_body); }
|
||||||
|
|
||||||
const id_list* LoopVar() const { return loop_vars; }
|
const id_list* LoopVar() const { return loop_vars; }
|
||||||
const Expr* LoopExpr() const { return e; }
|
const Expr* LoopExpr() const { return e.get(); }
|
||||||
const Stmt* LoopBody() const { return body; }
|
const Stmt* LoopBody() const { return body.get(); }
|
||||||
|
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
|
@ -323,23 +293,20 @@ public:
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
IntrusivePtr<Val> DoExec(Frame* f, Val* v, stmt_flow_type& flow) const override;
|
||||||
ForStmt() { loop_vars = 0; body = 0; }
|
|
||||||
|
|
||||||
Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const override;
|
|
||||||
|
|
||||||
id_list* loop_vars;
|
id_list* loop_vars;
|
||||||
Stmt* body;
|
IntrusivePtr<Stmt> body;
|
||||||
// Stores the value variable being used for a key value for loop.
|
// Stores the value variable being used for a key value for loop.
|
||||||
// Always set to nullptr unless special constructor is called.
|
// Always set to nullptr unless special constructor is called.
|
||||||
ID* value_var = nullptr;
|
IntrusivePtr<ID> value_var;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NextStmt : public Stmt {
|
class NextStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
NextStmt() : Stmt(STMT_NEXT) { }
|
NextStmt() : Stmt(STMT_NEXT) { }
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
@ -353,7 +320,7 @@ class BreakStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
BreakStmt() : Stmt(STMT_BREAK) { }
|
BreakStmt() : Stmt(STMT_BREAK) { }
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
@ -367,7 +334,7 @@ class FallthroughStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
FallthroughStmt() : Stmt(STMT_FALLTHROUGH) { }
|
FallthroughStmt() : Stmt(STMT_FALLTHROUGH) { }
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
@ -379,15 +346,11 @@ protected:
|
||||||
|
|
||||||
class ReturnStmt : public ExprStmt {
|
class ReturnStmt : public ExprStmt {
|
||||||
public:
|
public:
|
||||||
explicit ReturnStmt(Expr* e);
|
explicit ReturnStmt(IntrusivePtr<Expr> e);
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class Stmt;
|
|
||||||
ReturnStmt() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StmtList : public Stmt {
|
class StmtList : public Stmt {
|
||||||
|
@ -395,7 +358,7 @@ public:
|
||||||
StmtList();
|
StmtList();
|
||||||
~StmtList() override;
|
~StmtList() override;
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
const stmt_list& Stmts() const { return stmts; }
|
const stmt_list& Stmts() const { return stmts; }
|
||||||
stmt_list& Stmts() { return stmts; }
|
stmt_list& Stmts() { return stmts; }
|
||||||
|
@ -415,7 +378,7 @@ public:
|
||||||
EventBodyList() : StmtList()
|
EventBodyList() : StmtList()
|
||||||
{ topmost = false; tag = STMT_EVENT_BODY_LIST; }
|
{ topmost = false; tag = STMT_EVENT_BODY_LIST; }
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -433,7 +396,7 @@ public:
|
||||||
|
|
||||||
~InitStmt() override;
|
~InitStmt() override;
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
|
|
||||||
const id_list* Inits() const { return inits; }
|
const id_list* Inits() const { return inits; }
|
||||||
|
|
||||||
|
@ -442,9 +405,6 @@ public:
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Stmt;
|
|
||||||
InitStmt() { inits = 0; }
|
|
||||||
|
|
||||||
id_list* inits;
|
id_list* inits;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -452,7 +412,7 @@ class NullStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
NullStmt() : Stmt(STMT_NULL) { }
|
NullStmt() : Stmt(STMT_NULL) { }
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
@ -463,27 +423,27 @@ public:
|
||||||
class WhenStmt : public Stmt {
|
class WhenStmt : public Stmt {
|
||||||
public:
|
public:
|
||||||
// s2 is null if no timeout block given.
|
// s2 is null if no timeout block given.
|
||||||
WhenStmt(Expr* cond, Stmt* s1, Stmt* s2, Expr* timeout, bool is_return);
|
WhenStmt(IntrusivePtr<Expr> cond,
|
||||||
|
IntrusivePtr<Stmt> s1, IntrusivePtr<Stmt> s2,
|
||||||
|
IntrusivePtr<Expr> timeout, bool is_return);
|
||||||
~WhenStmt() override;
|
~WhenStmt() override;
|
||||||
|
|
||||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
IntrusivePtr<Val> Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||||
int IsPure() const override;
|
int IsPure() const override;
|
||||||
|
|
||||||
const Expr* Cond() const { return cond; }
|
const Expr* Cond() const { return cond.get(); }
|
||||||
const Stmt* Body() const { return s1; }
|
const Stmt* Body() const { return s1.get(); }
|
||||||
const Expr* TimeoutExpr() const { return timeout; }
|
const Expr* TimeoutExpr() const { return timeout.get(); }
|
||||||
const Stmt* TimeoutBody() const { return s2; }
|
const Stmt* TimeoutBody() const { return s2.get(); }
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WhenStmt() { cond = 0; s1 = s2 = 0; timeout = 0; is_return = 0; }
|
IntrusivePtr<Expr> cond;
|
||||||
|
IntrusivePtr<Stmt> s1;
|
||||||
Expr* cond;
|
IntrusivePtr<Stmt> s2;
|
||||||
Stmt* s1;
|
IntrusivePtr<Expr> timeout;
|
||||||
Stmt* s2;
|
|
||||||
Expr* timeout;
|
|
||||||
bool is_return;
|
bool is_return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -63,13 +63,10 @@ TraversalCode TriggerTraversalCallback::PreExpr(const Expr* expr)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Val* v = e->Eval(trigger->frame);
|
auto v = e->Eval(trigger->frame);
|
||||||
|
|
||||||
if ( v )
|
if ( v )
|
||||||
{
|
trigger->Register(v.get());
|
||||||
trigger->Register(v);
|
|
||||||
Unref(v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch ( InterpreterException& )
|
catch ( InterpreterException& )
|
||||||
{ /* Already reported */ }
|
{ /* Already reported */ }
|
||||||
|
@ -157,7 +154,7 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
|
||||||
arg_frame->SetDelayed();
|
arg_frame->SetDelayed();
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* timeout_val = nullptr;
|
IntrusivePtr<Val> timeout_val;
|
||||||
|
|
||||||
if ( arg_timeout )
|
if ( arg_timeout )
|
||||||
{
|
{
|
||||||
|
@ -172,7 +169,6 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
|
||||||
if ( timeout_val )
|
if ( timeout_val )
|
||||||
{
|
{
|
||||||
timeout_value = timeout_val->AsInterval();
|
timeout_value = timeout_val->AsInterval();
|
||||||
Unref(timeout_val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we don't get deleted if somebody calls a method like
|
// Make sure we don't get deleted if somebody calls a method like
|
||||||
|
@ -271,7 +267,7 @@ bool Trigger::Eval()
|
||||||
|
|
||||||
f->SetTrigger(this);
|
f->SetTrigger(this);
|
||||||
|
|
||||||
Val* v = nullptr;
|
IntrusivePtr<Val> v;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -294,7 +290,6 @@ bool Trigger::Eval()
|
||||||
{
|
{
|
||||||
// Not true. Perhaps next time...
|
// Not true. Perhaps next time...
|
||||||
DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is false", Name());
|
DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is false", Name());
|
||||||
Unref(v);
|
|
||||||
Unref(f);
|
Unref(f);
|
||||||
Init();
|
Init();
|
||||||
return false;
|
return false;
|
||||||
|
@ -303,8 +298,7 @@ bool Trigger::Eval()
|
||||||
DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is true, executing",
|
DBG_LOG(DBG_NOTIFIERS, "%s: trigger condition is true, executing",
|
||||||
Name());
|
Name());
|
||||||
|
|
||||||
Unref(v);
|
v = nullptr;
|
||||||
v = 0;
|
|
||||||
stmt_flow_type flow;
|
stmt_flow_type flow;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -327,12 +321,11 @@ bool Trigger::Eval()
|
||||||
delete [] pname;
|
delete [] pname;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
trigger->Cache(frame->GetCall(), v);
|
trigger->Cache(frame->GetCall(), v.get());
|
||||||
trigger->Release();
|
trigger->Release();
|
||||||
frame->ClearTrigger();
|
frame->ClearTrigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(v);
|
|
||||||
Unref(f);
|
Unref(f);
|
||||||
|
|
||||||
if ( timer )
|
if ( timer )
|
||||||
|
@ -353,12 +346,12 @@ void Trigger::Timeout()
|
||||||
if ( timeout_stmts )
|
if ( timeout_stmts )
|
||||||
{
|
{
|
||||||
stmt_flow_type flow;
|
stmt_flow_type flow;
|
||||||
Frame* f = frame->Clone();
|
IntrusivePtr<Frame> f{AdoptRef{}, frame->Clone()};
|
||||||
Val* v = 0;
|
IntrusivePtr<Val> v;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
v = timeout_stmts->Exec(f, flow);
|
v = timeout_stmts->Exec(f.get(), flow);
|
||||||
}
|
}
|
||||||
catch ( InterpreterException& e )
|
catch ( InterpreterException& e )
|
||||||
{ /* Already reported. */ }
|
{ /* Already reported. */ }
|
||||||
|
@ -375,13 +368,10 @@ void Trigger::Timeout()
|
||||||
DBG_LOG(DBG_NOTIFIERS, "%s: trigger has parent %s, caching timeout result", Name(), pname);
|
DBG_LOG(DBG_NOTIFIERS, "%s: trigger has parent %s, caching timeout result", Name(), pname);
|
||||||
delete [] pname;
|
delete [] pname;
|
||||||
#endif
|
#endif
|
||||||
trigger->Cache(frame->GetCall(), v);
|
trigger->Cache(frame->GetCall(), v.get());
|
||||||
trigger->Release();
|
trigger->Release();
|
||||||
frame->ClearTrigger();
|
frame->ClearTrigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(v);
|
|
||||||
Unref(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Disable();
|
Disable();
|
||||||
|
|
81
src/Type.cc
81
src/Type.cc
|
@ -417,8 +417,7 @@ SetType::SetType(TypeList* ind, ListExpr* arg_elements) : TableType(ind, 0)
|
||||||
|
|
||||||
for ( int i = 2; t && i < tl->length(); ++i )
|
for ( int i = 2; t && i < tl->length(); ++i )
|
||||||
{
|
{
|
||||||
BroType* t_new =
|
BroType* t_new = merge_types(t, (*tl)[i]);
|
||||||
merge_types(t, (*tl)[i]);
|
|
||||||
Unref(t);
|
Unref(t);
|
||||||
t = t_new;
|
t = t_new;
|
||||||
}
|
}
|
||||||
|
@ -705,7 +704,7 @@ Val* RecordType::FieldDefault(int field) const
|
||||||
|
|
||||||
const Attr* def_attr = td->attrs->FindAttr(ATTR_DEFAULT);
|
const Attr* def_attr = td->attrs->FindAttr(ATTR_DEFAULT);
|
||||||
|
|
||||||
return def_attr ? def_attr->AttrExpr()->Eval(0) : 0;
|
return def_attr ? def_attr->AttrExpr()->Eval(nullptr).release() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RecordType::FieldOffset(const char* field) const
|
int RecordType::FieldOffset(const char* field) const
|
||||||
|
@ -1172,18 +1171,18 @@ void EnumType::CheckAndAddName(const string& module_name, const char* name,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID* id = lookup_ID(name, module_name.c_str());
|
auto id = lookup_ID(name, module_name.c_str());
|
||||||
|
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
{
|
{
|
||||||
id = install_ID(name, module_name.c_str(), true, is_export);
|
id = install_ID(name, module_name.c_str(), true, is_export);
|
||||||
id->SetType(this->Ref());
|
id->SetType({NewRef{}, this});
|
||||||
id->SetEnumConst();
|
id->SetEnumConst();
|
||||||
|
|
||||||
if ( deprecation )
|
if ( deprecation )
|
||||||
id->MakeDeprecated(deprecation);
|
id->MakeDeprecated(deprecation);
|
||||||
|
|
||||||
zeekygen_mgr->Identifier(id);
|
zeekygen_mgr->Identifier(std::move(id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1195,13 +1194,10 @@ void EnumType::CheckAndAddName(const string& module_name, const char* name,
|
||||||
|| (id->HasVal() && val != id->ID_Val()->AsEnum())
|
|| (id->HasVal() && val != id->ID_Val()->AsEnum())
|
||||||
|| (names.find(fullname) != names.end() && names[fullname] != val) )
|
|| (names.find(fullname) != names.end() && names[fullname] != val) )
|
||||||
{
|
{
|
||||||
Unref(id);
|
|
||||||
reporter->Error("identifier or enumerator value in enumerated type definition already exists");
|
reporter->Error("identifier or enumerator value in enumerated type definition already exists");
|
||||||
SetError();
|
SetError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AddNameInternal(module_name, name, val, is_export);
|
AddNameInternal(module_name, name, val, is_export);
|
||||||
|
@ -1357,6 +1353,9 @@ VectorType::VectorType(BroType* element_type)
|
||||||
|
|
||||||
VectorType* VectorType::ShallowClone()
|
VectorType* VectorType::ShallowClone()
|
||||||
{
|
{
|
||||||
|
if ( yield_type )
|
||||||
|
yield_type->Ref();
|
||||||
|
|
||||||
return new VectorType(yield_type);
|
return new VectorType(yield_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2065,19 +2064,19 @@ BroType* init_type(Expr* init)
|
||||||
{
|
{
|
||||||
if ( init->Tag() != EXPR_LIST )
|
if ( init->Tag() != EXPR_LIST )
|
||||||
{
|
{
|
||||||
BroType* t = init->InitType();
|
auto t = init->InitType();
|
||||||
|
|
||||||
if ( ! t )
|
if ( ! t )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
if ( t->Tag() == TYPE_LIST &&
|
if ( t->Tag() == TYPE_LIST &&
|
||||||
t->AsTypeList()->Types()->length() != 1 )
|
t->AsTypeList()->Types()->length() != 1 )
|
||||||
{
|
{
|
||||||
init->Error("list used in scalar initialization");
|
init->Error("list used in scalar initialization");
|
||||||
Unref(t);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return t.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
ListExpr* init_list = init->AsListExpr();
|
ListExpr* init_list = init->AsListExpr();
|
||||||
|
@ -2086,77 +2085,59 @@ BroType* init_type(Expr* init)
|
||||||
if ( el.length() == 0 )
|
if ( el.length() == 0 )
|
||||||
{
|
{
|
||||||
init->Error("empty list in untyped initialization");
|
init->Error("empty list in untyped initialization");
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Could be a record, a set, or a list of table elements.
|
// Could be a record, a set, or a list of table elements.
|
||||||
Expr* e0 = el[0];
|
Expr* e0 = el[0];
|
||||||
|
|
||||||
if ( e0->IsRecordElement(0) )
|
if ( e0->IsRecordElement(0) )
|
||||||
// ListExpr's know how to build a record from their
|
// ListExpr's know how to build a record from their
|
||||||
// components.
|
// components.
|
||||||
return init_list->InitType();
|
return init_list->InitType().release();
|
||||||
|
|
||||||
BroType* t = e0->InitType();
|
auto t = e0->InitType();
|
||||||
if ( t )
|
|
||||||
{
|
|
||||||
BroType* old_t = t;
|
|
||||||
t = reduce_type(t);
|
|
||||||
|
|
||||||
if ( t )
|
if ( t )
|
||||||
// reduce_type() does not return a referenced pointer, but we want
|
t = {NewRef{}, reduce_type(t.get())};
|
||||||
// to own a reference, so create one here
|
|
||||||
Ref(t);
|
|
||||||
|
|
||||||
// reduce_type() does not adopt our reference passed as parameter, so
|
|
||||||
// we need to release it (after the Ref() call above)
|
|
||||||
Unref(old_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! t )
|
if ( ! t )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
for ( int i = 1; t && i < el.length(); ++i )
|
for ( int i = 1; t && i < el.length(); ++i )
|
||||||
{
|
{
|
||||||
BroType* el_t = el[i]->InitType();
|
auto el_t = el[i]->InitType();
|
||||||
BroType* ti = el_t ? reduce_type(el_t) : 0;
|
BroType* ti = el_t ? reduce_type(el_t.get()) : 0;
|
||||||
|
|
||||||
if ( ! ti )
|
if ( ! ti )
|
||||||
{
|
return nullptr;
|
||||||
Unref(t);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( same_type(t, ti) )
|
if ( same_type(t.get(), ti) )
|
||||||
{
|
|
||||||
Unref(ti);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
BroType* t_merge = merge_types(t, ti);
|
t = IntrusivePtr<BroType>{AdoptRef{}, merge_types(t.get(), ti)};
|
||||||
Unref(t);
|
|
||||||
Unref(ti);
|
|
||||||
t = t_merge;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! t )
|
if ( ! t )
|
||||||
{
|
{
|
||||||
init->Error("type error in initialization");
|
init->Error("type error in initialization");
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( t->Tag() == TYPE_TABLE && ! t->AsTableType()->IsSet() )
|
if ( t->Tag() == TYPE_TABLE && ! t->AsTableType()->IsSet() )
|
||||||
// A list of table elements.
|
// A list of table elements.
|
||||||
return t;
|
return t.release();
|
||||||
|
|
||||||
// A set. If the index type isn't yet a type list, make
|
// A set. If the index type isn't yet a type list, make
|
||||||
// it one, as that's what's required for creating a set type.
|
// it one, as that's what's required for creating a set type.
|
||||||
if ( t->Tag() != TYPE_LIST )
|
if ( t->Tag() != TYPE_LIST )
|
||||||
{
|
{
|
||||||
TypeList* tl = new TypeList(t);
|
auto tl = make_intrusive<TypeList>(t.get()->Ref());
|
||||||
tl->Append(t);
|
tl->Append(t.release());
|
||||||
t = tl;
|
t = std::move(tl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SetType(t->AsTypeList(), 0);
|
return new SetType(t.release()->AsTypeList(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_atomic_type(const BroType* t)
|
bool is_atomic_type(const BroType* t)
|
||||||
|
|
|
@ -699,16 +699,16 @@ extern OpaqueType* x509_opaque_type;
|
||||||
extern OpaqueType* ocsp_resp_opaque_type;
|
extern OpaqueType* ocsp_resp_opaque_type;
|
||||||
extern OpaqueType* paraglob_type;
|
extern OpaqueType* paraglob_type;
|
||||||
|
|
||||||
// Returns the Bro basic (non-parameterized) type with the given type.
|
// Returns the basic (non-parameterized) type with the given type.
|
||||||
// The reference count of the type is not increased.
|
// The reference count of the type is not increased.
|
||||||
BroType* base_type_no_ref(TypeTag tag);
|
BroType* base_type_no_ref(TypeTag tag);
|
||||||
|
|
||||||
// Returns the BRO basic (non-parameterized) type with the given type.
|
// Returns the basic (non-parameterized) type with the given type.
|
||||||
// The caller assumes responsibility for a reference to the type.
|
// The caller assumes responsibility for a reference to the type.
|
||||||
inline BroType* base_type(TypeTag tag)
|
inline BroType* base_type(TypeTag tag)
|
||||||
{ return base_type_no_ref(tag)->Ref(); }
|
{ return base_type_no_ref(tag)->Ref(); }
|
||||||
|
|
||||||
// Returns the BRO basic error type.
|
// Returns the basic error type.
|
||||||
inline BroType* error_type() { return base_type(TYPE_ERROR); }
|
inline BroType* error_type() { return base_type(TYPE_ERROR); }
|
||||||
|
|
||||||
// True if the two types are equivalent. If is_init is true then the test is
|
// True if the two types are equivalent. If is_init is true then the test is
|
||||||
|
|
118
src/Val.cc
118
src/Val.cc
|
@ -1745,14 +1745,14 @@ Val* TableVal::Default(Val* index)
|
||||||
record_promotion_compatible(dtype->AsRecordType(),
|
record_promotion_compatible(dtype->AsRecordType(),
|
||||||
ytype->AsRecordType()) )
|
ytype->AsRecordType()) )
|
||||||
{
|
{
|
||||||
Expr* coerce = new RecordCoerceExpr(def_attr->AttrExpr()->Ref(),
|
auto coerce = make_intrusive<RecordCoerceExpr>(
|
||||||
ytype->AsRecordType());
|
IntrusivePtr{NewRef{}, def_attr->AttrExpr()},
|
||||||
def_val = coerce->Eval(0);
|
IntrusivePtr{NewRef{}, ytype->AsRecordType()});
|
||||||
Unref(coerce);
|
def_val = coerce->Eval(0).release();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
def_val = def_attr->AttrExpr()->Eval(0);
|
def_val = def_attr->AttrExpr()->Eval(0).release();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! def_val )
|
if ( ! def_val )
|
||||||
|
@ -1958,7 +1958,7 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IntrusivePtr<Val> thefunc{AdoptRef{}, change_func->Eval(nullptr)};
|
auto thefunc = change_func->Eval(nullptr);
|
||||||
|
|
||||||
if ( ! thefunc )
|
if ( ! thefunc )
|
||||||
{
|
{
|
||||||
|
@ -2250,7 +2250,7 @@ void TableVal::InitDefaultFunc(Frame* f)
|
||||||
ytype->AsRecordType()) )
|
ytype->AsRecordType()) )
|
||||||
return; // TableVal::Default will handle this.
|
return; // TableVal::Default will handle this.
|
||||||
|
|
||||||
def_val = def_attr->AttrExpr()->Eval(f);
|
def_val = def_attr->AttrExpr()->Eval(f).release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableVal::InitTimer(double delay)
|
void TableVal::InitTimer(double delay)
|
||||||
|
@ -2375,9 +2375,8 @@ double TableVal::GetExpireTime()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Val* timeout = expire_time->Eval(0);
|
auto timeout = expire_time->Eval(nullptr);
|
||||||
interval = (timeout ? timeout->AsInterval() : -1);
|
interval = (timeout ? timeout->AsInterval() : -1);
|
||||||
Unref(timeout);
|
|
||||||
}
|
}
|
||||||
catch ( InterpreterException& e )
|
catch ( InterpreterException& e )
|
||||||
{
|
{
|
||||||
|
@ -2407,7 +2406,7 @@ double TableVal::CallExpireFunc(Val* idx)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Val* vf = expire_func->Eval(0);
|
auto vf = expire_func->Eval(nullptr);
|
||||||
|
|
||||||
if ( ! vf )
|
if ( ! vf )
|
||||||
{
|
{
|
||||||
|
@ -2419,7 +2418,6 @@ double TableVal::CallExpireFunc(Val* idx)
|
||||||
if ( vf->Type()->Tag() != TYPE_FUNC )
|
if ( vf->Type()->Tag() != TYPE_FUNC )
|
||||||
{
|
{
|
||||||
vf->Error("not a function");
|
vf->Error("not a function");
|
||||||
Unref(vf);
|
|
||||||
Unref(idx);
|
Unref(idx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2467,8 +2465,6 @@ double TableVal::CallExpireFunc(Val* idx)
|
||||||
secs = result->AsInterval();
|
secs = result->AsInterval();
|
||||||
Unref(result);
|
Unref(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(vf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( InterpreterException& e )
|
catch ( InterpreterException& e )
|
||||||
|
@ -2574,8 +2570,8 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t)
|
||||||
for ( int i = 0; i < n; ++i )
|
for ( int i = 0; i < n; ++i )
|
||||||
{
|
{
|
||||||
Attributes* a = t->FieldDecl(i)->attrs;
|
Attributes* a = t->FieldDecl(i)->attrs;
|
||||||
Attr* def_attr = a ? a->FindAttr(ATTR_DEFAULT) : 0;
|
Attr* def_attr = a ? a->FindAttr(ATTR_DEFAULT) : nullptr;
|
||||||
Val* def = def_attr ? def_attr->AttrExpr()->Eval(0) : 0;
|
auto def = def_attr ? def_attr->AttrExpr()->Eval(nullptr) : nullptr;
|
||||||
BroType* type = t->FieldDecl(i)->type;
|
BroType* type = t->FieldDecl(i)->type;
|
||||||
|
|
||||||
if ( def && type->Tag() == TYPE_RECORD &&
|
if ( def && type->Tag() == TYPE_RECORD &&
|
||||||
|
@ -2585,8 +2581,7 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t)
|
||||||
Val* tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType());
|
Val* tmp = def->AsRecordVal()->CoerceTo(type->AsRecordType());
|
||||||
if ( tmp )
|
if ( tmp )
|
||||||
{
|
{
|
||||||
Unref(def);
|
def = {AdoptRef{}, tmp};
|
||||||
def = tmp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2595,18 +2590,16 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t)
|
||||||
TypeTag tag = type->Tag();
|
TypeTag tag = type->Tag();
|
||||||
|
|
||||||
if ( tag == TYPE_RECORD )
|
if ( tag == TYPE_RECORD )
|
||||||
def = new RecordVal(type->AsRecordType());
|
def = make_intrusive<RecordVal>(type->AsRecordType());
|
||||||
|
|
||||||
else if ( tag == TYPE_TABLE )
|
else if ( tag == TYPE_TABLE )
|
||||||
def = new TableVal(type->AsTableType(), a);
|
def = make_intrusive<TableVal>(type->AsTableType(), a);
|
||||||
|
|
||||||
else if ( tag == TYPE_VECTOR )
|
else if ( tag == TYPE_VECTOR )
|
||||||
def = new VectorVal(type->AsVectorType());
|
def = make_intrusive<VectorVal>(type->AsVectorType());
|
||||||
}
|
}
|
||||||
|
|
||||||
vl->push_back(def ? def->Ref() : 0);
|
vl->push_back(def.release());
|
||||||
|
|
||||||
Unref(def);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2707,12 +2700,13 @@ RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphan
|
||||||
// Check for allowable optional fields is outside the loop, below.
|
// Check for allowable optional fields is outside the loop, below.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( ar_t->FieldType(t_i)->Tag() == TYPE_RECORD
|
if ( ar_t->FieldType(t_i)->Tag() == TYPE_RECORD &&
|
||||||
&& ! same_type(ar_t->FieldType(t_i), v->Type()) )
|
! same_type(ar_t->FieldType(t_i), v->Type()) )
|
||||||
{
|
{
|
||||||
Expr* rhs = new ConstExpr(v->Ref());
|
auto rhs = make_intrusive<ConstExpr>(IntrusivePtr{NewRef{}, v});
|
||||||
Expr* e = new RecordCoerceExpr(rhs, ar_t->FieldType(t_i)->AsRecordType());
|
auto e = make_intrusive<RecordCoerceExpr>(std::move(rhs),
|
||||||
ar->Assign(t_i, e->Eval(0));
|
IntrusivePtr{NewRef{}, ar_t->FieldType(t_i)->AsRecordType()});
|
||||||
|
ar->Assign(t_i, e->Eval(nullptr).release());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3041,10 +3035,12 @@ void VectorVal::ValDescribe(ODesc* d) const
|
||||||
d->Add("]");
|
d->Add("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* expr_location)
|
IntrusivePtr<Val> check_and_promote(IntrusivePtr<Val> v, const BroType* t,
|
||||||
|
int is_init,
|
||||||
|
const Location* expr_location)
|
||||||
{
|
{
|
||||||
if ( ! v )
|
if ( ! v )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
BroType* vt = v->Type();
|
BroType* vt = v->Type();
|
||||||
|
|
||||||
|
@ -3065,20 +3061,18 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* ex
|
||||||
if ( same_type(t, vt, is_init) )
|
if ( same_type(t, vt, is_init) )
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
t->Error("type clash", v, 0, expr_location);
|
t->Error("type clash", v.get(), 0, expr_location);
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! BothArithmetic(t_tag, v_tag) &&
|
if ( ! BothArithmetic(t_tag, v_tag) &&
|
||||||
(! IsArithmetic(v_tag) || t_tag != TYPE_TIME || ! v->IsZero()) )
|
(! IsArithmetic(v_tag) || t_tag != TYPE_TIME || ! v->IsZero()) )
|
||||||
{
|
{
|
||||||
if ( t_tag == TYPE_LIST || v_tag == TYPE_LIST )
|
if ( t_tag == TYPE_LIST || v_tag == TYPE_LIST )
|
||||||
t->Error("list mixed with scalar", v, 0, expr_location);
|
t->Error("list mixed with scalar", v.get(), 0, expr_location);
|
||||||
else
|
else
|
||||||
t->Error("arithmetic mixed with non-arithmetic", v, 0, expr_location);
|
t->Error("arithmetic mixed with non-arithmetic", v.get(), 0, expr_location);
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( v_tag == t_tag )
|
if ( v_tag == t_tag )
|
||||||
|
@ -3089,9 +3083,8 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* ex
|
||||||
TypeTag mt = max_type(t_tag, v_tag);
|
TypeTag mt = max_type(t_tag, v_tag);
|
||||||
if ( mt != t_tag )
|
if ( mt != t_tag )
|
||||||
{
|
{
|
||||||
t->Error("over-promotion of arithmetic value", v, 0, expr_location);
|
t->Error("over-promotion of arithmetic value", v.get(), 0, expr_location);
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3103,55 +3096,50 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* ex
|
||||||
// Already has the right internal type.
|
// Already has the right internal type.
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
Val* promoted_v;
|
IntrusivePtr<Val> promoted_v;
|
||||||
|
|
||||||
switch ( it ) {
|
switch ( it ) {
|
||||||
case TYPE_INTERNAL_INT:
|
case TYPE_INTERNAL_INT:
|
||||||
if ( ( vit == TYPE_INTERNAL_UNSIGNED || vit == TYPE_INTERNAL_DOUBLE ) && Val::WouldOverflow(vt, t, v) )
|
if ( ( vit == TYPE_INTERNAL_UNSIGNED || vit == TYPE_INTERNAL_DOUBLE ) && Val::WouldOverflow(vt, t, v.get()) )
|
||||||
{
|
{
|
||||||
t->Error("overflow promoting from unsigned/double to signed arithmetic value", v, 0, expr_location);
|
t->Error("overflow promoting from unsigned/double to signed arithmetic value", v.get(), 0, expr_location);
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else if ( t_tag == TYPE_INT )
|
else if ( t_tag == TYPE_INT )
|
||||||
promoted_v = val_mgr->GetInt(v->CoerceToInt());
|
promoted_v = {AdoptRef{}, val_mgr->GetInt(v->CoerceToInt())};
|
||||||
else // enum
|
else // enum
|
||||||
{
|
{
|
||||||
reporter->InternalError("bad internal type in check_and_promote()");
|
reporter->InternalError("bad internal type in check_and_promote()");
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_INTERNAL_UNSIGNED:
|
case TYPE_INTERNAL_UNSIGNED:
|
||||||
if ( ( vit == TYPE_INTERNAL_DOUBLE || vit == TYPE_INTERNAL_INT) && Val::WouldOverflow(vt, t, v) )
|
if ( ( vit == TYPE_INTERNAL_DOUBLE || vit == TYPE_INTERNAL_INT) && Val::WouldOverflow(vt, t, v.get()) )
|
||||||
{
|
{
|
||||||
t->Error("overflow promoting from signed/double to unsigned arithmetic value", v, 0, expr_location);
|
t->Error("overflow promoting from signed/double to unsigned arithmetic value", v.get(), 0, expr_location);
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else if ( t_tag == TYPE_COUNT || t_tag == TYPE_COUNTER )
|
else if ( t_tag == TYPE_COUNT || t_tag == TYPE_COUNTER )
|
||||||
promoted_v = val_mgr->GetCount(v->CoerceToUnsigned());
|
promoted_v = {AdoptRef{}, val_mgr->GetCount(v->CoerceToUnsigned())};
|
||||||
else // port
|
else // port
|
||||||
{
|
{
|
||||||
reporter->InternalError("bad internal type in check_and_promote()");
|
reporter->InternalError("bad internal type in check_and_promote()");
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_INTERNAL_DOUBLE:
|
case TYPE_INTERNAL_DOUBLE:
|
||||||
promoted_v = new Val(v->CoerceToDouble(), t_tag);
|
promoted_v = make_intrusive<Val>(v->CoerceToDouble(), t_tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
reporter->InternalError("bad internal type in check_and_promote()");
|
reporter->InternalError("bad internal type in check_and_promote()");
|
||||||
Unref(v);
|
return nullptr;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(v);
|
|
||||||
return promoted_v;
|
return promoted_v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3222,30 +3210,30 @@ void delete_vals(val_list* vals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* cast_value_to_type(Val* v, BroType* t)
|
IntrusivePtr<Val> cast_value_to_type(Val* v, BroType* t)
|
||||||
{
|
{
|
||||||
// Note: when changing this function, adapt all three of
|
// Note: when changing this function, adapt all three of
|
||||||
// cast_value_to_type()/can_cast_value_to_type()/can_cast_value_to_type().
|
// cast_value_to_type()/can_cast_value_to_type()/can_cast_value_to_type().
|
||||||
|
|
||||||
if ( ! v )
|
if ( ! v )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
// Always allow casting to same type. This also covers casting 'any'
|
// Always allow casting to same type. This also covers casting 'any'
|
||||||
// to the actual type.
|
// to the actual type.
|
||||||
if ( same_type(v->Type(), t) )
|
if ( same_type(v->Type(), t) )
|
||||||
return v->Ref();
|
return {NewRef{}, v};
|
||||||
|
|
||||||
if ( same_type(v->Type(), bro_broker::DataVal::ScriptDataType()) )
|
if ( same_type(v->Type(), bro_broker::DataVal::ScriptDataType()) )
|
||||||
{
|
{
|
||||||
auto dv = v->AsRecordVal()->Lookup(0);
|
auto dv = v->AsRecordVal()->Lookup(0);
|
||||||
|
|
||||||
if ( ! dv )
|
if ( ! dv )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
return static_cast<bro_broker::DataVal *>(dv)->castTo(t).release();
|
return static_cast<bro_broker::DataVal*>(dv)->castTo(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_cast_value_to_type(const Val* v, BroType* t)
|
bool can_cast_value_to_type(const Val* v, BroType* t)
|
||||||
|
|
14
src/Val.h
14
src/Val.h
|
@ -29,6 +29,7 @@ using std::string;
|
||||||
|
|
||||||
template <class T> class IntrusivePtr;
|
template <class T> class IntrusivePtr;
|
||||||
template<typename T> class PDict;
|
template<typename T> class PDict;
|
||||||
|
template <class T> class IntrusivePtr;
|
||||||
class IterCookie;
|
class IterCookie;
|
||||||
|
|
||||||
class Val;
|
class Val;
|
||||||
|
@ -1018,13 +1019,9 @@ protected:
|
||||||
// Unref()'ing the original. If not a match, generates an error message
|
// Unref()'ing the original. If not a match, generates an error message
|
||||||
// and returns nil, also Unref()'ing v. If is_init is true, then
|
// and returns nil, also Unref()'ing v. If is_init is true, then
|
||||||
// the checking is done in the context of an initialization.
|
// the checking is done in the context of an initialization.
|
||||||
extern Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* expr_location = nullptr);
|
extern IntrusivePtr<Val> check_and_promote(IntrusivePtr<Val> v,
|
||||||
|
const BroType* t, int is_init,
|
||||||
// Given a pointer to where a Val's core (i.e., its BRO value) resides,
|
const Location* expr_location = nullptr);
|
||||||
// returns a corresponding newly-created or Ref()'d Val. ptr must already
|
|
||||||
// be properly aligned. Returns the size of the core in bytes in 'n'.
|
|
||||||
// If t corresponds to a variable-length type, n must give the size on entry.
|
|
||||||
Val* recover_val(void* ptr, BroType* t, int& n);
|
|
||||||
|
|
||||||
extern int same_val(const Val* v1, const Val* v2);
|
extern int same_val(const Val* v1, const Val* v2);
|
||||||
extern int same_atomic_val(const Val* v1, const Val* v2);
|
extern int same_atomic_val(const Val* v1, const Val* v2);
|
||||||
|
@ -1036,10 +1033,9 @@ extern void delete_vals(val_list* vals);
|
||||||
inline bool is_vector(Val* v) { return v->Type()->Tag() == TYPE_VECTOR; }
|
inline bool is_vector(Val* v) { return v->Type()->Tag() == TYPE_VECTOR; }
|
||||||
|
|
||||||
// Returns v casted to type T if the type supports that. Returns null if not.
|
// Returns v casted to type T if the type supports that. Returns null if not.
|
||||||
// The returned value will be ref'ed.
|
|
||||||
//
|
//
|
||||||
// Note: This implements the script-level cast operator.
|
// Note: This implements the script-level cast operator.
|
||||||
extern Val* cast_value_to_type(Val* v, BroType* t);
|
extern IntrusivePtr<Val> cast_value_to_type(Val* v, BroType* t);
|
||||||
|
|
||||||
// Returns true if v can be casted to type T. If so, check_and_cast() will
|
// Returns true if v can be casted to type T. If so, check_and_cast() will
|
||||||
// succeed as well.
|
// succeed as well.
|
||||||
|
|
213
src/Var.cc
213
src/Var.cc
|
@ -8,6 +8,7 @@
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Stmt.h"
|
#include "Stmt.h"
|
||||||
#include "Scope.h"
|
#include "Scope.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
|
@ -15,11 +16,12 @@
|
||||||
#include "Traverse.h"
|
#include "Traverse.h"
|
||||||
#include "module_util.h"
|
#include "module_util.h"
|
||||||
|
|
||||||
static Val* init_val(Expr* init, const BroType* t, Val* aggr)
|
static IntrusivePtr<Val> init_val(Expr* init, const BroType* t,
|
||||||
|
IntrusivePtr<Val> aggr)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return init->InitVal(t, aggr);
|
return init->InitVal(t, std::move(aggr));
|
||||||
}
|
}
|
||||||
catch ( InterpreterException& e )
|
catch ( InterpreterException& e )
|
||||||
{
|
{
|
||||||
|
@ -27,22 +29,22 @@ static Val* init_val(Expr* init, const BroType* t, Val* aggr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
static void make_var(ID* id, IntrusivePtr<BroType> t, init_class c,
|
||||||
attr_list* attr, decl_type dt, int do_init)
|
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt,
|
||||||
|
int do_init)
|
||||||
{
|
{
|
||||||
if ( id->Type() )
|
if ( id->Type() )
|
||||||
{
|
{
|
||||||
if ( id->IsRedefinable() || (! init && attr) )
|
if ( id->IsRedefinable() || (! init && attr) )
|
||||||
{
|
{
|
||||||
BroObj* redef_obj = init ? (BroObj*) init : (BroObj*) t;
|
BroObj* redef_obj = init ? (BroObj*) init.get() : (BroObj*) t.get();
|
||||||
if ( dt != VAR_REDEF )
|
if ( dt != VAR_REDEF )
|
||||||
id->Warn("redefinition requires \"redef\"", redef_obj, 1);
|
id->Warn("redefinition requires \"redef\"", redef_obj, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( dt != VAR_REDEF || init || ! attr )
|
else if ( dt != VAR_REDEF || init || ! attr )
|
||||||
{
|
{
|
||||||
id->Error("already defined", init);
|
id->Error("already defined", init.get());
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,29 +54,26 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
||||||
if ( ! id->Type() )
|
if ( ! id->Type() )
|
||||||
{
|
{
|
||||||
id->Error("\"redef\" used but not previously defined");
|
id->Error("\"redef\" used but not previously defined");
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! t )
|
if ( ! t )
|
||||||
t = id->Type();
|
t = {NewRef{}, id->Type()};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( id->Type() && id->Type()->Tag() != TYPE_ERROR )
|
if ( id->Type() && id->Type()->Tag() != TYPE_ERROR )
|
||||||
{
|
{
|
||||||
if ( dt != VAR_REDEF &&
|
if ( dt != VAR_REDEF &&
|
||||||
(! init || ! do_init || (! t && ! (t = init_type(init)))) )
|
(! init || ! do_init || (! t && ! (t = {AdoptRef{}, init_type(init.get())}))) )
|
||||||
{
|
{
|
||||||
id->Error("already defined", init);
|
id->Error("already defined", init.get());
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow redeclaration in order to initialize.
|
// Allow redeclaration in order to initialize.
|
||||||
if ( ! same_type(t, id->Type()) )
|
if ( ! same_type(t.get(), id->Type()) )
|
||||||
{
|
{
|
||||||
id->Error("redefinition changes type", init);
|
id->Error("redefinition changes type", init.get());
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,13 +87,11 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
||||||
{
|
{
|
||||||
if ( init )
|
if ( init )
|
||||||
{
|
{
|
||||||
id->Error("double initialization", init);
|
id->Error("double initialization", init.get());
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref(elements);
|
init = {NewRef{}, elements};
|
||||||
init = elements;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,48 +100,38 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
||||||
if ( ! init )
|
if ( ! init )
|
||||||
{
|
{
|
||||||
id->Error("no type given");
|
id->Error("no type given");
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = init_type(init);
|
t = {AdoptRef{}, init_type(init.get())};
|
||||||
if ( ! t )
|
if ( ! t )
|
||||||
{
|
{
|
||||||
id->SetType(error_type());
|
id->SetType({AdoptRef{}, error_type()});
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
Ref(t);
|
|
||||||
|
|
||||||
id->SetType(t);
|
id->SetType(t);
|
||||||
|
|
||||||
if ( attr )
|
if ( attr )
|
||||||
id->AddAttrs(new Attributes(attr, t, false, id->IsGlobal()));
|
id->AddAttrs(make_intrusive<Attributes>(attr, t.get(), false, id->IsGlobal()));
|
||||||
|
|
||||||
if ( init )
|
if ( init )
|
||||||
{
|
{
|
||||||
switch ( init->Tag() ) {
|
switch ( init->Tag() ) {
|
||||||
case EXPR_TABLE_CONSTRUCTOR:
|
case EXPR_TABLE_CONSTRUCTOR:
|
||||||
{
|
{
|
||||||
TableConstructorExpr* ctor = (TableConstructorExpr*) init;
|
TableConstructorExpr* ctor = (TableConstructorExpr*) init.get();
|
||||||
if ( ctor->Attrs() )
|
if ( ctor->Attrs() )
|
||||||
{
|
id->AddAttrs({NewRef{}, ctor->Attrs()});
|
||||||
::Ref(ctor->Attrs());
|
|
||||||
id->AddAttrs(ctor->Attrs());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXPR_SET_CONSTRUCTOR:
|
case EXPR_SET_CONSTRUCTOR:
|
||||||
{
|
{
|
||||||
SetConstructorExpr* ctor = (SetConstructorExpr*) init;
|
SetConstructorExpr* ctor = (SetConstructorExpr*) init.get();
|
||||||
if ( ctor->Attrs() )
|
if ( ctor->Attrs() )
|
||||||
{
|
id->AddAttrs({NewRef{}, ctor->Attrs()});
|
||||||
::Ref(ctor->Attrs());
|
|
||||||
id->AddAttrs(ctor->Attrs());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -168,40 +155,38 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
||||||
|
|
||||||
else if ( dt != VAR_REDEF || init || ! attr )
|
else if ( dt != VAR_REDEF || init || ! attr )
|
||||||
{
|
{
|
||||||
Val* aggr;
|
IntrusivePtr<Val> aggr;
|
||||||
|
|
||||||
if ( t->Tag() == TYPE_RECORD )
|
if ( t->Tag() == TYPE_RECORD )
|
||||||
{
|
{
|
||||||
aggr = new RecordVal(t->AsRecordType());
|
aggr = make_intrusive<RecordVal>(t->AsRecordType());
|
||||||
|
|
||||||
if ( init && t )
|
if ( init && t )
|
||||||
// Have an initialization and type is not deduced.
|
// Have an initialization and type is not deduced.
|
||||||
init = new RecordCoerceExpr(init, t->AsRecordType());
|
init = make_intrusive<RecordCoerceExpr>(std::move(init),
|
||||||
|
IntrusivePtr{NewRef{}, t->AsRecordType()});
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( t->Tag() == TYPE_TABLE )
|
else if ( t->Tag() == TYPE_TABLE )
|
||||||
aggr = new TableVal(t->AsTableType(), id->Attrs());
|
aggr = make_intrusive<TableVal>(t->AsTableType(), id->Attrs());
|
||||||
|
|
||||||
else if ( t->Tag() == TYPE_VECTOR )
|
else if ( t->Tag() == TYPE_VECTOR )
|
||||||
aggr = new VectorVal(t->AsVectorType());
|
aggr = make_intrusive<VectorVal>(t->AsVectorType());
|
||||||
|
|
||||||
else
|
IntrusivePtr<Val> v;
|
||||||
aggr = 0;
|
|
||||||
|
|
||||||
Val* v = 0;
|
|
||||||
if ( init )
|
if ( init )
|
||||||
{
|
{
|
||||||
v = init_val(init, t, aggr);
|
v = init_val(init.get(), t.get(), aggr);
|
||||||
|
|
||||||
if ( ! v )
|
if ( ! v )
|
||||||
{
|
|
||||||
Unref(init);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( aggr )
|
if ( aggr )
|
||||||
id->SetVal(aggr, c);
|
id->SetVal(std::move(aggr), c);
|
||||||
else if ( v )
|
else if ( v )
|
||||||
id->SetVal(v, c);
|
id->SetVal(std::move(v), c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,8 +206,6 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
||||||
id->SetOption();
|
id->SetOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(init);
|
|
||||||
|
|
||||||
id->UpdateValAttrs();
|
id->UpdateValAttrs();
|
||||||
|
|
||||||
if ( t && t->Tag() == TYPE_FUNC &&
|
if ( t && t->Tag() == TYPE_FUNC &&
|
||||||
|
@ -233,70 +216,77 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
||||||
// we can later access the ID even if no implementations have been
|
// we can later access the ID even if no implementations have been
|
||||||
// defined.
|
// defined.
|
||||||
Func* f = new BroFunc(id, 0, 0, 0, 0);
|
Func* f = new BroFunc(id, 0, 0, 0, 0);
|
||||||
id->SetVal(new Val(f));
|
id->SetVal(make_intrusive<Val>(f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void add_global(ID* id, BroType* t, init_class c, Expr* init,
|
void add_global(ID* id, IntrusivePtr<BroType> t, init_class c,
|
||||||
|
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt)
|
||||||
|
{
|
||||||
|
make_var(id, std::move(t), c, std::move(init), attr, dt, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id, IntrusivePtr<BroType> t,
|
||||||
|
init_class c, IntrusivePtr<Expr> init,
|
||||||
attr_list* attr, decl_type dt)
|
attr_list* attr, decl_type dt)
|
||||||
{
|
{
|
||||||
make_var(id, t, c, init, attr, dt, 1);
|
make_var(id.get(), std::move(t), c, init, attr, dt, 0);
|
||||||
}
|
|
||||||
|
|
||||||
Stmt* add_local(ID* id, BroType* t, init_class c, Expr* init,
|
|
||||||
attr_list* attr, decl_type dt)
|
|
||||||
{
|
|
||||||
make_var(id, t, c, init ? init->Ref() : init, attr, dt, 0);
|
|
||||||
|
|
||||||
if ( init )
|
if ( init )
|
||||||
{
|
{
|
||||||
if ( c != INIT_FULL )
|
if ( c != INIT_FULL )
|
||||||
id->Error("can't use += / -= for initializations of local variables");
|
id->Error("can't use += / -= for initializations of local variables");
|
||||||
|
|
||||||
Ref(id);
|
// copy Location to the stack, because AssignExpr may free "init"
|
||||||
|
const Location location = init->GetLocationInfo() ?
|
||||||
Expr* name_expr = new NameExpr(id, dt == VAR_CONST);
|
*init->GetLocationInfo() : no_location;
|
||||||
Stmt* stmt =
|
|
||||||
new ExprStmt(new AssignExpr(name_expr, init, 0, 0,
|
|
||||||
id->Attrs() ? id->Attrs()->Attrs() : 0 ));
|
|
||||||
stmt->SetLocationInfo(init->GetLocationInfo());
|
|
||||||
|
|
||||||
|
auto name_expr = make_intrusive<NameExpr>(id, dt == VAR_CONST);
|
||||||
|
auto attrs = id->Attrs() ? id->Attrs()->Attrs() : nullptr;
|
||||||
|
auto assign_expr = make_intrusive<AssignExpr>(std::move(name_expr),
|
||||||
|
std::move(init), 0,
|
||||||
|
nullptr, attrs);
|
||||||
|
auto stmt = make_intrusive<ExprStmt>(std::move(assign_expr));
|
||||||
|
stmt->SetLocationInfo(&location);
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current_scope()->AddInit(id);
|
current_scope()->AddInit(id.release());
|
||||||
return new NullStmt;
|
return make_intrusive<NullStmt>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Expr* add_and_assign_local(ID* id, Expr* init, Val* val)
|
extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
|
||||||
|
IntrusivePtr<Expr> init,
|
||||||
|
IntrusivePtr<Val> val)
|
||||||
{
|
{
|
||||||
make_var(id, 0, INIT_FULL, init->Ref(), 0, VAR_REGULAR, 0);
|
make_var(id.get(), 0, INIT_FULL, init, 0, VAR_REGULAR, 0);
|
||||||
Ref(id);
|
auto name_expr = make_intrusive<NameExpr>(std::move(id));
|
||||||
return new AssignExpr(new NameExpr(id), init, 0, val);
|
return make_intrusive<AssignExpr>(std::move(name_expr), std::move(init),
|
||||||
|
0, std::move(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_type(ID* id, BroType* t, attr_list* attr)
|
void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr)
|
||||||
{
|
{
|
||||||
string new_type_name = id->Name();
|
string new_type_name = id->Name();
|
||||||
string old_type_name = t->GetName();
|
string old_type_name = t->GetName();
|
||||||
BroType* tnew = 0;
|
IntrusivePtr<BroType> tnew;
|
||||||
|
|
||||||
if ( (t->Tag() == TYPE_RECORD || t->Tag() == TYPE_ENUM) &&
|
if ( (t->Tag() == TYPE_RECORD || t->Tag() == TYPE_ENUM) &&
|
||||||
old_type_name.empty() )
|
old_type_name.empty() )
|
||||||
// An extensible type (record/enum) being declared for first time.
|
// An extensible type (record/enum) being declared for first time.
|
||||||
tnew = t;
|
tnew = std::move(t);
|
||||||
else
|
else
|
||||||
// Clone the type to preserve type name aliasing.
|
// Clone the type to preserve type name aliasing.
|
||||||
tnew = t->ShallowClone();
|
tnew = {AdoptRef{}, t->ShallowClone()};
|
||||||
|
|
||||||
BroType::AddAlias(new_type_name, tnew);
|
BroType::AddAlias(new_type_name, tnew.get());
|
||||||
|
|
||||||
if ( new_type_name != old_type_name && ! old_type_name.empty() )
|
if ( new_type_name != old_type_name && ! old_type_name.empty() )
|
||||||
BroType::AddAlias(old_type_name, tnew);
|
BroType::AddAlias(old_type_name, tnew.get());
|
||||||
|
|
||||||
tnew->SetName(id->Name());
|
tnew->SetName(id->Name());
|
||||||
|
|
||||||
|
@ -304,7 +294,7 @@ void add_type(ID* id, BroType* t, attr_list* attr)
|
||||||
id->MakeType();
|
id->MakeType();
|
||||||
|
|
||||||
if ( attr )
|
if ( attr )
|
||||||
id->SetAttrs(new Attributes(attr, tnew, false, false));
|
id->SetAttrs(make_intrusive<Attributes>(attr, tnew.get(), false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transfer_arg_defaults(RecordType* args, RecordType* recv)
|
static void transfer_arg_defaults(RecordType* args, RecordType* recv)
|
||||||
|
@ -348,23 +338,24 @@ static bool has_attr(const attr_list* al, attr_tag tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||||
int is_redef, FuncType* t, attr_list* attrs)
|
int is_redef, IntrusivePtr<FuncType> t, attr_list* attrs)
|
||||||
{
|
{
|
||||||
if ( flavor == FUNC_FLAVOR_EVENT )
|
if ( flavor == FUNC_FLAVOR_EVENT )
|
||||||
{
|
{
|
||||||
const BroType* yt = t->YieldType();
|
const BroType* yt = t->YieldType();
|
||||||
|
|
||||||
if ( yt && yt->Tag() != TYPE_VOID )
|
if ( yt && yt->Tag() != TYPE_VOID )
|
||||||
id->Error("event cannot yield a value", t);
|
id->Error("event cannot yield a value", t.get());
|
||||||
|
|
||||||
t->ClearYieldType(flavor);
|
t->ClearYieldType(flavor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( id->Type() )
|
if ( id->Type() )
|
||||||
{
|
{
|
||||||
if ( ! same_type(id->Type(), t) )
|
if ( ! same_type(id->Type(), t.get()) )
|
||||||
id->Type()->Error("incompatible types", t);
|
id->Type()->Error("incompatible types", t.get());
|
||||||
|
|
||||||
|
else
|
||||||
// If a previous declaration of the function had &default params,
|
// If a previous declaration of the function had &default params,
|
||||||
// automatically transfer any that are missing (convenience so that
|
// automatically transfer any that are missing (convenience so that
|
||||||
// implementations don't need to specify the &default expression again).
|
// implementations don't need to specify the &default expression again).
|
||||||
|
@ -379,7 +370,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||||
function_flavor id_flavor = id->ID_Val()->AsFunc()->Flavor();
|
function_flavor id_flavor = id->ID_Val()->AsFunc()->Flavor();
|
||||||
|
|
||||||
if ( id_flavor != flavor )
|
if ( id_flavor != flavor )
|
||||||
id->Error("inconsistent function flavor", t);
|
id->Error("inconsistent function flavor", t.get());
|
||||||
|
|
||||||
switch ( id_flavor ) {
|
switch ( id_flavor ) {
|
||||||
|
|
||||||
|
@ -411,15 +402,13 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||||
for ( int i = 0; i < num_args; ++i )
|
for ( int i = 0; i < num_args; ++i )
|
||||||
{
|
{
|
||||||
TypeDecl* arg_i = args->FieldDecl(i);
|
TypeDecl* arg_i = args->FieldDecl(i);
|
||||||
ID* arg_id = lookup_ID(arg_i->id, module_name);
|
auto arg_id = lookup_ID(arg_i->id, module_name);
|
||||||
|
|
||||||
if ( arg_id && ! arg_id->IsGlobal() )
|
if ( arg_id && ! arg_id->IsGlobal() )
|
||||||
arg_id->Error("argument name used twice");
|
arg_id->Error("argument name used twice");
|
||||||
|
|
||||||
Unref(arg_id);
|
|
||||||
|
|
||||||
arg_id = install_ID(arg_i->id, module_name, false, false);
|
arg_id = install_ID(arg_i->id, module_name, false, false);
|
||||||
arg_id->SetType(arg_i->type->Ref());
|
arg_id->SetType({NewRef{}, arg_i->type});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Attr* depr_attr = find_attr(attrs, ATTR_DEPRECATED) )
|
if ( Attr* depr_attr = find_attr(attrs, ATTR_DEPRECATED) )
|
||||||
|
@ -482,9 +471,10 @@ TraversalCode OuterIDBindingFinder::PostExpr(const Expr* expr)
|
||||||
return TC_CONTINUE;
|
return TC_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_func(Stmt* body)
|
void end_func(IntrusivePtr<Stmt> body)
|
||||||
{
|
{
|
||||||
auto ingredients = std::make_unique<function_ingredients>(pop_scope(), body);
|
auto ingredients = std::make_unique<function_ingredients>(
|
||||||
|
pop_scope().release(), body.release());
|
||||||
|
|
||||||
if ( streq(ingredients->id->Name(), "anonymous-function") )
|
if ( streq(ingredients->id->Name(), "anonymous-function") )
|
||||||
{
|
{
|
||||||
|
@ -511,7 +501,7 @@ void end_func(Stmt* body)
|
||||||
ingredients->frame_size,
|
ingredients->frame_size,
|
||||||
ingredients->priority);
|
ingredients->priority);
|
||||||
|
|
||||||
ingredients->id->SetVal(new Val(f));
|
ingredients->id->SetVal(make_intrusive<Val>(f));
|
||||||
ingredients->id->SetConst();
|
ingredients->id->SetConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,14 +514,12 @@ void end_func(Stmt* body)
|
||||||
|
|
||||||
Val* internal_val(const char* name)
|
Val* internal_val(const char* name)
|
||||||
{
|
{
|
||||||
ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
||||||
|
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
reporter->InternalError("internal variable %s missing", name);
|
reporter->InternalError("internal variable %s missing", name);
|
||||||
|
|
||||||
Val* rval = id->ID_Val();
|
return id->ID_Val();
|
||||||
Unref(id);
|
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id_list gather_outer_ids(Scope* scope, Stmt* body)
|
id_list gather_outer_ids(Scope* scope, Stmt* body)
|
||||||
|
@ -556,24 +544,20 @@ id_list gather_outer_ids(Scope* scope, Stmt* body)
|
||||||
|
|
||||||
Val* internal_const_val(const char* name)
|
Val* internal_const_val(const char* name)
|
||||||
{
|
{
|
||||||
ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
reporter->InternalError("internal variable %s missing", name);
|
reporter->InternalError("internal variable %s missing", name);
|
||||||
|
|
||||||
if ( ! id->IsConst() )
|
if ( ! id->IsConst() )
|
||||||
reporter->InternalError("internal variable %s is not constant", name);
|
reporter->InternalError("internal variable %s is not constant", name);
|
||||||
|
|
||||||
Val* rval = id->ID_Val();
|
return id->ID_Val();
|
||||||
Unref(id);
|
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* opt_internal_val(const char* name)
|
Val* opt_internal_val(const char* name)
|
||||||
{
|
{
|
||||||
ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
||||||
Val* rval = id ? id->ID_Val() : 0;
|
return id ? id->ID_Val() : nullptr;
|
||||||
Unref(id);
|
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double opt_internal_double(const char* name)
|
double opt_internal_double(const char* name)
|
||||||
|
@ -597,23 +581,22 @@ bro_uint_t opt_internal_unsigned(const char* name)
|
||||||
StringVal* opt_internal_string(const char* name)
|
StringVal* opt_internal_string(const char* name)
|
||||||
{
|
{
|
||||||
Val* v = opt_internal_val(name);
|
Val* v = opt_internal_val(name);
|
||||||
return v ? v->AsStringVal() : 0;
|
return v ? v->AsStringVal() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableVal* opt_internal_table(const char* name)
|
TableVal* opt_internal_table(const char* name)
|
||||||
{
|
{
|
||||||
Val* v = opt_internal_val(name);
|
Val* v = opt_internal_val(name);
|
||||||
return v ? v->AsTableVal() : 0;
|
return v ? v->AsTableVal() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListVal* internal_list_val(const char* name)
|
ListVal* internal_list_val(const char* name)
|
||||||
{
|
{
|
||||||
ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
Val* v = id->ID_Val();
|
Val* v = id->ID_Val();
|
||||||
Unref(id);
|
|
||||||
|
|
||||||
if ( v )
|
if ( v )
|
||||||
{
|
{
|
||||||
|
@ -631,18 +614,16 @@ ListVal* internal_list_val(const char* name)
|
||||||
reporter->InternalError("internal variable %s is not a list", name);
|
reporter->InternalError("internal variable %s is not a list", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BroType* internal_type(const char* name)
|
BroType* internal_type(const char* name)
|
||||||
{
|
{
|
||||||
ID* id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
auto id = lookup_ID(name, GLOBAL_MODULE_NAME);
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
reporter->InternalError("internal type %s missing", name);
|
reporter->InternalError("internal type %s missing", name);
|
||||||
|
|
||||||
BroType* rval = id->Type();
|
return id->Type();
|
||||||
Unref(id);
|
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Func* internal_func(const char* name)
|
Func* internal_func(const char* name)
|
||||||
|
@ -651,7 +632,7 @@ Func* internal_func(const char* name)
|
||||||
if ( v )
|
if ( v )
|
||||||
return v->AsFunc();
|
return v->AsFunc();
|
||||||
else
|
else
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandlerPtr internal_handler(const char* name)
|
EventHandlerPtr internal_handler(const char* name)
|
||||||
|
|
25
src/Var.h
25
src/Var.h
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
|
|
||||||
|
@ -16,17 +17,25 @@ class ListVal;
|
||||||
|
|
||||||
typedef enum { VAR_REGULAR, VAR_CONST, VAR_REDEF, VAR_OPTION, } decl_type;
|
typedef enum { VAR_REGULAR, VAR_CONST, VAR_REDEF, VAR_OPTION, } decl_type;
|
||||||
|
|
||||||
extern void add_global(ID* id, BroType* t, init_class c, Expr* init,
|
extern void add_global(ID* id, IntrusivePtr<BroType> t, init_class c,
|
||||||
attr_list* attr, decl_type dt);
|
IntrusivePtr<Expr> init, attr_list* attr, decl_type dt);
|
||||||
extern Stmt* add_local(ID* id, BroType* t, init_class c, Expr* init,
|
|
||||||
attr_list* attr, decl_type dt);
|
|
||||||
extern Expr* add_and_assign_local(ID* id, Expr* init, Val* val = 0);
|
|
||||||
|
|
||||||
extern void add_type(ID* id, BroType* t, attr_list* attr);
|
extern IntrusivePtr<Stmt> add_local(IntrusivePtr<ID> id,
|
||||||
|
IntrusivePtr<BroType> t, init_class c,
|
||||||
|
IntrusivePtr<Expr> init, attr_list* attr,
|
||||||
|
decl_type dt);
|
||||||
|
|
||||||
|
extern IntrusivePtr<Expr> add_and_assign_local(IntrusivePtr<ID> id,
|
||||||
|
IntrusivePtr<Expr> init,
|
||||||
|
IntrusivePtr<Val> val = nullptr);
|
||||||
|
|
||||||
|
extern void add_type(ID* id, IntrusivePtr<BroType> t, attr_list* attr);
|
||||||
|
|
||||||
extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||||
int is_redef, FuncType* t, attr_list* attrs = nullptr);
|
int is_redef, IntrusivePtr<FuncType> t,
|
||||||
extern void end_func(Stmt* body);
|
attr_list* attrs = nullptr);
|
||||||
|
|
||||||
|
extern void end_func(IntrusivePtr<Stmt> body);
|
||||||
|
|
||||||
// Gather all IDs referenced inside a body that aren't part of a given scope.
|
// Gather all IDs referenced inside a body that aren't part of a given scope.
|
||||||
extern id_list gather_outer_ids(Scope* scope, Stmt* body);
|
extern id_list gather_outer_ids(Scope* scope, Stmt* body);
|
||||||
|
|
|
@ -1210,7 +1210,7 @@ bool Manager::ProcessIdentifierUpdate(broker::zeek::IdentifierUpdate iu)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
id->SetVal(val.release());
|
id->SetVal(std::move(val));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -973,7 +973,7 @@ bool Manager::UnrollRecordType(vector<Field*> *fields, const RecordType *rec,
|
||||||
{
|
{
|
||||||
string name = nameprepend + rec->FieldName(i);
|
string name = nameprepend + rec->FieldName(i);
|
||||||
const char* secondary = 0;
|
const char* secondary = 0;
|
||||||
Val* c = nullptr;
|
IntrusivePtr<Val> c;
|
||||||
TypeTag ty = rec->FieldType(i)->Tag();
|
TypeTag ty = rec->FieldType(i)->Tag();
|
||||||
TypeTag st = TYPE_VOID;
|
TypeTag st = TYPE_VOID;
|
||||||
bool optional = false;
|
bool optional = false;
|
||||||
|
@ -1001,7 +1001,6 @@ bool Manager::UnrollRecordType(vector<Field*> *fields, const RecordType *rec,
|
||||||
optional = true;
|
optional = true;
|
||||||
|
|
||||||
Field* field = new Field(name.c_str(), secondary, ty, st, optional);
|
Field* field = new Field(name.c_str(), secondary, ty, st, optional);
|
||||||
Unref(c);
|
|
||||||
fields->push_back(field);
|
fields->push_back(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2622,7 +2621,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co
|
||||||
string enum_string(val->val.string_val.data, val->val.string_val.length);
|
string enum_string(val->val.string_val.data, val->val.string_val.length);
|
||||||
|
|
||||||
// let's try looking it up by global ID.
|
// let's try looking it up by global ID.
|
||||||
ID* id = lookup_ID(enum_string.c_str(), GLOBAL_MODULE_NAME);
|
auto id = lookup_ID(enum_string.c_str(), GLOBAL_MODULE_NAME);
|
||||||
if ( ! id || ! id->IsEnumConst() )
|
if ( ! id || ! id->IsEnumConst() )
|
||||||
{
|
{
|
||||||
Warning(i, "Value '%s' for stream '%s' is not a valid enum.",
|
Warning(i, "Value '%s' for stream '%s' is not a valid enum.",
|
||||||
|
|
|
@ -298,16 +298,19 @@ void terminate_bro()
|
||||||
plugin_mgr->FinishPlugins();
|
plugin_mgr->FinishPlugins();
|
||||||
|
|
||||||
delete zeekygen_mgr;
|
delete zeekygen_mgr;
|
||||||
delete event_registry;
|
|
||||||
delete analyzer_mgr;
|
delete analyzer_mgr;
|
||||||
delete file_mgr;
|
delete file_mgr;
|
||||||
// broker_mgr, timer_mgr, and supervisor are deleted via iosource_mgr
|
// broker_mgr, timer_mgr, and supervisor are deleted via iosource_mgr
|
||||||
delete iosource_mgr;
|
delete iosource_mgr;
|
||||||
|
delete event_registry;
|
||||||
delete log_mgr;
|
delete log_mgr;
|
||||||
delete reporter;
|
delete reporter;
|
||||||
delete plugin_mgr;
|
delete plugin_mgr;
|
||||||
delete val_mgr;
|
delete val_mgr;
|
||||||
|
|
||||||
|
// free the global scope
|
||||||
|
pop_scope();
|
||||||
|
|
||||||
reporter = 0;
|
reporter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,7 +717,7 @@ int main(int argc, char** argv)
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
reporter->InternalError("global cmd_line_bpf_filter not defined");
|
reporter->InternalError("global cmd_line_bpf_filter not defined");
|
||||||
|
|
||||||
id->SetVal(new StringVal(*options.pcap_filter));
|
id->SetVal(make_intrusive<StringVal>(*options.pcap_filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto all_signature_files = options.signature_files;
|
auto all_signature_files = options.signature_files;
|
||||||
|
|
|
@ -33,7 +33,7 @@ static bool call_option_handlers_and_set_value(StringVal* name, ID* i, Val* val,
|
||||||
}
|
}
|
||||||
|
|
||||||
// clone to prevent changes
|
// clone to prevent changes
|
||||||
i->SetVal(val->Clone());
|
i->SetVal({AdoptRef{}, val->Clone()});
|
||||||
Unref(val); // Either ref'd once or function call result.
|
Unref(val); // Either ref'd once or function call result.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,6 @@ function Option::set_change_handler%(ID: string, on_change: any, priority: int &
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* func = on_change->AsFunc();
|
auto* func = on_change->AsFunc();
|
||||||
Ref(func);
|
i->AddOptionHandler({NewRef{}, func}, -priority);
|
||||||
i->AddOptionHandler(func, -priority);
|
|
||||||
return val_mgr->GetBool(1);
|
return val_mgr->GetBool(1);
|
||||||
%}
|
%}
|
||||||
|
|
327
src/parse.y
327
src/parse.y
|
@ -82,6 +82,7 @@
|
||||||
#include "Desc.h"
|
#include "Desc.h"
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Stmt.h"
|
#include "Stmt.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
#include "Var.h"
|
#include "Var.h"
|
||||||
|
@ -311,157 +312,157 @@ expr:
|
||||||
| TOK_COPY '(' expr ')'
|
| TOK_COPY '(' expr ')'
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new CloneExpr($3);
|
$$ = new CloneExpr({AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_INCR expr
|
| TOK_INCR expr
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new IncrExpr(EXPR_INCR, $2);
|
$$ = new IncrExpr(EXPR_INCR, {AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_DECR expr
|
| TOK_DECR expr
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new IncrExpr(EXPR_DECR, $2);
|
$$ = new IncrExpr(EXPR_DECR, {AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| '!' expr
|
| '!' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new NotExpr($2);
|
$$ = new NotExpr({AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| '~' expr
|
| '~' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new ComplementExpr($2);
|
$$ = new ComplementExpr({AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| '-' expr %prec '!'
|
| '-' expr %prec '!'
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new NegExpr($2);
|
$$ = new NegExpr({AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| '+' expr %prec '!'
|
| '+' expr %prec '!'
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new PosExpr($2);
|
$$ = new PosExpr({AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '+' expr
|
| expr '+' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new AddExpr($1, $3);
|
$$ = new AddExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_ADD_TO expr
|
| expr TOK_ADD_TO expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new AddToExpr($1, $3);
|
$$ = new AddToExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '-' expr
|
| expr '-' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new SubExpr($1, $3);
|
$$ = new SubExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_REMOVE_FROM expr
|
| expr TOK_REMOVE_FROM expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new RemoveFromExpr($1, $3);
|
$$ = new RemoveFromExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '*' expr
|
| expr '*' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new TimesExpr($1, $3);
|
$$ = new TimesExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '/' expr
|
| expr '/' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new DivideExpr($1, $3);
|
$$ = new DivideExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '%' expr
|
| expr '%' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new ModExpr($1, $3);
|
$$ = new ModExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '&' expr
|
| expr '&' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new BitExpr(EXPR_AND, $1, $3);
|
$$ = new BitExpr(EXPR_AND, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '|' expr
|
| expr '|' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new BitExpr(EXPR_OR, $1, $3);
|
$$ = new BitExpr(EXPR_OR, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '^' expr
|
| expr '^' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new BitExpr(EXPR_XOR, $1, $3);
|
$$ = new BitExpr(EXPR_XOR, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_AND_AND expr
|
| expr TOK_AND_AND expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new BoolExpr(EXPR_AND_AND, $1, $3);
|
$$ = new BoolExpr(EXPR_AND_AND, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_OR_OR expr
|
| expr TOK_OR_OR expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new BoolExpr(EXPR_OR_OR, $1, $3);
|
$$ = new BoolExpr(EXPR_OR_OR, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_EQ expr
|
| expr TOK_EQ expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new EqExpr(EXPR_EQ, $1, $3);
|
$$ = new EqExpr(EXPR_EQ, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_NE expr
|
| expr TOK_NE expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new EqExpr(EXPR_NE, $1, $3);
|
$$ = new EqExpr(EXPR_NE, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '<' expr
|
| expr '<' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new RelExpr(EXPR_LT, $1, $3);
|
$$ = new RelExpr(EXPR_LT, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_LE expr
|
| expr TOK_LE expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new RelExpr(EXPR_LE, $1, $3);
|
$$ = new RelExpr(EXPR_LE, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '>' expr
|
| expr '>' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new RelExpr(EXPR_GT, $1, $3);
|
$$ = new RelExpr(EXPR_GT, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_GE expr
|
| expr TOK_GE expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new RelExpr(EXPR_GE, $1, $3);
|
$$ = new RelExpr(EXPR_GE, {AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '?' expr ':' expr
|
| expr '?' expr ':' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @5);
|
set_location(@1, @5);
|
||||||
$$ = new CondExpr($1, $3, $5);
|
$$ = new CondExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}, {AdoptRef{}, $5});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '=' expr
|
| expr '=' expr
|
||||||
|
@ -473,19 +474,20 @@ expr:
|
||||||
" in arbitrary expression contexts, only"
|
" in arbitrary expression contexts, only"
|
||||||
" as a statement");
|
" as a statement");
|
||||||
|
|
||||||
$$ = get_assign_expr($1, $3, in_init);
|
$$ = get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $3}, in_init).release();
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_LOCAL local_id '=' expr
|
| TOK_LOCAL local_id '=' expr
|
||||||
{
|
{
|
||||||
set_location(@2, @4);
|
set_location(@2, @4);
|
||||||
$$ = add_and_assign_local($2, $4, val_mgr->GetBool(1));
|
$$ = add_and_assign_local({AdoptRef{}, $2}, {AdoptRef{}, $4},
|
||||||
|
{AdoptRef{}, val_mgr->GetBool(1)}).release();
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '[' expr_list ']'
|
| expr '[' expr_list ']'
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new IndexExpr($1, $3);
|
$$ = new IndexExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| index_slice
|
| index_slice
|
||||||
|
@ -493,13 +495,13 @@ expr:
|
||||||
| expr '$' TOK_ID
|
| expr '$' TOK_ID
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new FieldExpr($1, $3);
|
$$ = new FieldExpr({AdoptRef{}, $1}, $3);
|
||||||
}
|
}
|
||||||
|
|
||||||
| '$' TOK_ID '=' expr
|
| '$' TOK_ID '=' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new FieldAssignExpr($2, $4);
|
$$ = new FieldAssignExpr($2, {AdoptRef{}, $4});
|
||||||
}
|
}
|
||||||
|
|
||||||
| '$' TOK_ID func_params '='
|
| '$' TOK_ID func_params '='
|
||||||
|
@ -507,28 +509,29 @@ expr:
|
||||||
func_hdr_location = @1;
|
func_hdr_location = @1;
|
||||||
func_id = current_scope()->GenerateTemporary("anonymous-function");
|
func_id = current_scope()->GenerateTemporary("anonymous-function");
|
||||||
func_id->SetInferReturnType(true);
|
func_id->SetInferReturnType(true);
|
||||||
begin_func(func_id,
|
begin_func(func_id, current_module.c_str(), FUNC_FLAVOR_FUNCTION,
|
||||||
current_module.c_str(),
|
0, {AdoptRef{}, $3});
|
||||||
FUNC_FLAVOR_FUNCTION,
|
|
||||||
0,
|
|
||||||
$3);
|
|
||||||
}
|
}
|
||||||
func_body
|
func_body
|
||||||
{
|
{
|
||||||
$$ = new FieldAssignExpr($2, new ConstExpr(func_id->ID_Val()->Ref()));
|
$$ = new FieldAssignExpr($2,
|
||||||
|
make_intrusive<ConstExpr>(
|
||||||
|
IntrusivePtr<Val>{NewRef{}, func_id->ID_Val()}));
|
||||||
Unref(func_id);
|
Unref(func_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_IN expr
|
| expr TOK_IN expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new InExpr($1, $3);
|
$$ = new InExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_NOT_IN expr
|
| expr TOK_NOT_IN expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new NotExpr(new InExpr($1, $3));
|
$$ = new NotExpr(make_intrusive<InExpr>(
|
||||||
|
IntrusivePtr<Expr>{AdoptRef{}, $1},
|
||||||
|
IntrusivePtr<Expr>{AdoptRef{}, $3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
| '[' expr_list ']'
|
| '[' expr_list ']'
|
||||||
|
@ -551,7 +554,7 @@ expr:
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( is_record_ctor )
|
if ( is_record_ctor )
|
||||||
$$ = new RecordConstructorExpr($2);
|
$$ = new RecordConstructorExpr({AdoptRef{}, $2});
|
||||||
else
|
else
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
@ -559,33 +562,33 @@ expr:
|
||||||
| '[' ']'
|
| '[' ']'
|
||||||
{
|
{
|
||||||
// We interpret this as an empty record constructor.
|
// We interpret this as an empty record constructor.
|
||||||
$$ = new RecordConstructorExpr(new ListExpr);
|
$$ = new RecordConstructorExpr(make_intrusive<ListExpr>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
| TOK_RECORD '(' expr_list ')'
|
| TOK_RECORD '(' expr_list ')'
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new RecordConstructorExpr($3);
|
$$ = new RecordConstructorExpr({AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_TABLE '(' { ++in_init; } opt_expr_list ')' { --in_init; }
|
| TOK_TABLE '(' { ++in_init; } opt_expr_list ')' { --in_init; }
|
||||||
opt_attr
|
opt_attr
|
||||||
{ // the ++in_init fixes up the parsing of "[x] = y"
|
{ // the ++in_init fixes up the parsing of "[x] = y"
|
||||||
set_location(@1, @5);
|
set_location(@1, @5);
|
||||||
$$ = new TableConstructorExpr($4, $7);
|
$$ = new TableConstructorExpr({AdoptRef{}, $4}, $7);
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_SET '(' opt_expr_list ')' opt_attr
|
| TOK_SET '(' opt_expr_list ')' opt_attr
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new SetConstructorExpr($3, $5);
|
$$ = new SetConstructorExpr({AdoptRef{}, $3}, $5);
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_VECTOR '(' opt_expr_list ')'
|
| TOK_VECTOR '(' opt_expr_list ')'
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new VectorConstructorExpr($3);
|
$$ = new VectorConstructorExpr({AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr '('
|
| expr '('
|
||||||
|
@ -611,20 +614,27 @@ expr:
|
||||||
{
|
{
|
||||||
switch ( ctor_type->Tag() ) {
|
switch ( ctor_type->Tag() ) {
|
||||||
case TYPE_RECORD:
|
case TYPE_RECORD:
|
||||||
$$ = new RecordCoerceExpr(new RecordConstructorExpr($4),
|
{
|
||||||
ctor_type->AsRecordType());
|
auto rce = make_intrusive<RecordConstructorExpr>(
|
||||||
|
IntrusivePtr<ListExpr>{AdoptRef{}, $4});
|
||||||
|
IntrusivePtr<RecordType> rt{NewRef{}, ctor_type->AsRecordType()};
|
||||||
|
$$ = new RecordCoerceExpr(std::move(rce), std::move(rt));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_TABLE:
|
case TYPE_TABLE:
|
||||||
if ( ctor_type->IsTable() )
|
if ( ctor_type->IsTable() )
|
||||||
$$ = new TableConstructorExpr($4, 0, ctor_type);
|
$$ = new TableConstructorExpr({AdoptRef{}, $4}, 0,
|
||||||
|
{NewRef{}, ctor_type});
|
||||||
else
|
else
|
||||||
$$ = new SetConstructorExpr($4, 0, ctor_type);
|
$$ = new SetConstructorExpr({AdoptRef{}, $4}, 0,
|
||||||
|
{NewRef{}, ctor_type});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_VECTOR:
|
case TYPE_VECTOR:
|
||||||
$$ = new VectorConstructorExpr($4, ctor_type);
|
$$ = new VectorConstructorExpr({AdoptRef{}, $4},
|
||||||
|
{NewRef{}, ctor_type});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -634,7 +644,7 @@ expr:
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
$$ = new CallExpr($1, $4, in_hook > 0);
|
$$ = new CallExpr({AdoptRef{}, $1}, {AdoptRef{}, $4}, in_hook > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_HOOK { ++in_hook; } expr
|
| TOK_HOOK { ++in_hook; } expr
|
||||||
|
@ -649,7 +659,7 @@ expr:
|
||||||
| expr TOK_HAS_FIELD TOK_ID
|
| expr TOK_HAS_FIELD TOK_ID
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new HasFieldExpr($1, $3);
|
$$ = new HasFieldExpr({AdoptRef{}, $1}, $3);
|
||||||
}
|
}
|
||||||
|
|
||||||
| anonymous_function
|
| anonymous_function
|
||||||
|
@ -658,14 +668,14 @@ expr:
|
||||||
| TOK_SCHEDULE expr '{' event '}'
|
| TOK_SCHEDULE expr '{' event '}'
|
||||||
{
|
{
|
||||||
set_location(@1, @5);
|
set_location(@1, @5);
|
||||||
$$ = new ScheduleExpr($2, $4);
|
$$ = new ScheduleExpr({AdoptRef{}, $2}, {AdoptRef{}, $4});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_ID
|
| TOK_ID
|
||||||
{
|
{
|
||||||
set_location(@1);
|
set_location(@1);
|
||||||
|
auto id = lookup_ID($1, current_module.c_str());
|
||||||
|
|
||||||
ID* id = lookup_ID($1, current_module.c_str());
|
|
||||||
if ( ! id )
|
if ( ! id )
|
||||||
{
|
{
|
||||||
if ( ! in_debug )
|
if ( ! in_debug )
|
||||||
|
@ -686,12 +696,14 @@ expr:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if ( id->IsDeprecated() )
|
||||||
|
reporter->Warning("%s", id->GetDeprecationWarning().c_str());
|
||||||
|
|
||||||
if ( ! id->Type() )
|
if ( ! id->Type() )
|
||||||
{
|
{
|
||||||
id->Error("undeclared variable");
|
id->Error("undeclared variable");
|
||||||
id->SetType(error_type());
|
id->SetType({AdoptRef{}, error_type()});
|
||||||
Ref(id);
|
$$ = new NameExpr(std::move(id));
|
||||||
$$ = new NameExpr(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( id->IsEnumConst() )
|
else if ( id->IsEnumConst() )
|
||||||
|
@ -701,25 +713,19 @@ expr:
|
||||||
id->Name());
|
id->Name());
|
||||||
if ( intval < 0 )
|
if ( intval < 0 )
|
||||||
reporter->InternalError("enum value not found for %s", id->Name());
|
reporter->InternalError("enum value not found for %s", id->Name());
|
||||||
$$ = new ConstExpr(t->GetVal(intval));
|
$$ = new ConstExpr({AdoptRef{}, t->GetVal(intval)});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Ref(id);
|
$$ = new NameExpr(std::move(id));
|
||||||
$$ = new NameExpr(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( id->IsDeprecated() )
|
|
||||||
reporter->Warning("%s", id->GetDeprecationWarning().c_str());
|
|
||||||
|
|
||||||
Unref(id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_CONSTANT
|
| TOK_CONSTANT
|
||||||
{
|
{
|
||||||
set_location(@1);
|
set_location(@1);
|
||||||
$$ = new ConstExpr($1);
|
$$ = new ConstExpr({AdoptRef{}, $1});
|
||||||
}
|
}
|
||||||
|
|
||||||
| '/' { begin_RE(); } TOK_PATTERN_TEXT TOK_PATTERN_END
|
| '/' { begin_RE(); } TOK_PATTERN_TEXT TOK_PATTERN_END
|
||||||
|
@ -733,30 +739,30 @@ expr:
|
||||||
re->MakeCaseInsensitive();
|
re->MakeCaseInsensitive();
|
||||||
|
|
||||||
re->Compile();
|
re->Compile();
|
||||||
$$ = new ConstExpr(new PatternVal(re));
|
$$ = new ConstExpr(make_intrusive<PatternVal>(re));
|
||||||
}
|
}
|
||||||
|
|
||||||
| '|' expr '|' %prec '('
|
| '|' expr '|' %prec '('
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
auto e = $2;
|
IntrusivePtr<Expr> e{AdoptRef{}, $2};
|
||||||
|
|
||||||
if ( IsIntegral(e->Type()->Tag()) )
|
if ( IsIntegral(e->Type()->Tag()) )
|
||||||
e = new ArithCoerceExpr(e, TYPE_INT);
|
e = make_intrusive<ArithCoerceExpr>(std::move(e), TYPE_INT);
|
||||||
|
|
||||||
$$ = new SizeExpr(e);
|
$$ = new SizeExpr(std::move(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_AS type
|
| expr TOK_AS type
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new CastExpr($1, $3);
|
$$ = new CastExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_IS type
|
| expr TOK_IS type
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new IsExpr($1, $3);
|
$$ = new IsExpr({AdoptRef{}, $1}, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -764,13 +770,13 @@ expr_list:
|
||||||
expr_list ',' expr
|
expr_list ',' expr
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$1->Append($3);
|
$1->Append({AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr
|
| expr
|
||||||
{
|
{
|
||||||
set_location(@1);
|
set_location(@1);
|
||||||
$$ = new ListExpr($1);
|
$$ = new ListExpr({AdoptRef{}, $1});
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1089,27 +1095,31 @@ decl:
|
||||||
|
|
||||||
| TOK_GLOBAL def_global_id opt_type init_class opt_init opt_attr ';'
|
| TOK_GLOBAL def_global_id opt_type init_class opt_init opt_attr ';'
|
||||||
{
|
{
|
||||||
add_global($2, $3, $4, $5, $6, VAR_REGULAR);
|
IntrusivePtr id{AdoptRef{}, $2};
|
||||||
zeekygen_mgr->Identifier($2);
|
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5}, $6, VAR_REGULAR);
|
||||||
|
zeekygen_mgr->Identifier(std::move(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_OPTION def_global_id opt_type init_class opt_init opt_attr ';'
|
| TOK_OPTION def_global_id opt_type init_class opt_init opt_attr ';'
|
||||||
{
|
{
|
||||||
add_global($2, $3, $4, $5, $6, VAR_OPTION);
|
IntrusivePtr id{AdoptRef{}, $2};
|
||||||
zeekygen_mgr->Identifier($2);
|
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5}, $6, VAR_OPTION);
|
||||||
|
zeekygen_mgr->Identifier(std::move(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_CONST def_global_id opt_type init_class opt_init opt_attr ';'
|
| TOK_CONST def_global_id opt_type init_class opt_init opt_attr ';'
|
||||||
{
|
{
|
||||||
add_global($2, $3, $4, $5, $6, VAR_CONST);
|
IntrusivePtr id{AdoptRef{}, $2};
|
||||||
zeekygen_mgr->Identifier($2);
|
add_global(id.get(), {AdoptRef{}, $3}, $4, {AdoptRef{}, $5}, $6, VAR_CONST);
|
||||||
|
zeekygen_mgr->Identifier(std::move(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_REDEF global_id opt_type init_class opt_init opt_attr ';'
|
| TOK_REDEF global_id opt_type init_class opt_init opt_attr ';'
|
||||||
{
|
{
|
||||||
IntrusivePtr<Expr> e{NewRef{}, $5};
|
IntrusivePtr id{AdoptRef{}, $2};
|
||||||
add_global($2, $3, $4, $5, $6, VAR_REDEF);
|
IntrusivePtr<Expr> init{AdoptRef{}, $5};
|
||||||
zeekygen_mgr->Redef($2, ::filename, $4, $5);
|
add_global(id.get(), {AdoptRef{}, $3}, $4, init, $6, VAR_REDEF);
|
||||||
|
zeekygen_mgr->Redef(id.get(), ::filename, $4, init.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_REDEF TOK_ENUM global_id TOK_ADD_TO '{'
|
| TOK_REDEF TOK_ENUM global_id TOK_ADD_TO '{'
|
||||||
|
@ -1136,12 +1146,13 @@ decl:
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_TYPE global_id ':'
|
| TOK_TYPE global_id ':'
|
||||||
{ cur_decl_type_id = $2; zeekygen_mgr->StartType($2); }
|
{ cur_decl_type_id = $2; zeekygen_mgr->StartType({NewRef{}, $2}); }
|
||||||
type opt_attr ';'
|
type opt_attr ';'
|
||||||
{
|
{
|
||||||
cur_decl_type_id = 0;
|
cur_decl_type_id = 0;
|
||||||
add_type($2, $5, $6);
|
IntrusivePtr id{AdoptRef{}, $2};
|
||||||
zeekygen_mgr->Identifier($2);
|
add_type(id.get(), {AdoptRef{}, $5}, $6);
|
||||||
|
zeekygen_mgr->Identifier(std::move(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
| func_hdr { func_hdr_location = @1; } func_body
|
| func_hdr { func_hdr_location = @1; } func_body
|
||||||
|
@ -1171,10 +1182,11 @@ conditional:
|
||||||
func_hdr:
|
func_hdr:
|
||||||
TOK_FUNCTION def_global_id func_params opt_attr
|
TOK_FUNCTION def_global_id func_params opt_attr
|
||||||
{
|
{
|
||||||
begin_func($2, current_module.c_str(),
|
IntrusivePtr id{AdoptRef{}, $2};
|
||||||
FUNC_FLAVOR_FUNCTION, 0, $3, $4);
|
begin_func(id.get(), current_module.c_str(),
|
||||||
|
FUNC_FLAVOR_FUNCTION, 0, {NewRef{}, $3}, $4);
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
zeekygen_mgr->Identifier($2);
|
zeekygen_mgr->Identifier(std::move(id));
|
||||||
}
|
}
|
||||||
| TOK_EVENT event_id func_params opt_attr
|
| TOK_EVENT event_id func_params opt_attr
|
||||||
{
|
{
|
||||||
|
@ -1186,7 +1198,7 @@ func_hdr:
|
||||||
}
|
}
|
||||||
|
|
||||||
begin_func($2, current_module.c_str(),
|
begin_func($2, current_module.c_str(),
|
||||||
FUNC_FLAVOR_EVENT, 0, $3, $4);
|
FUNC_FLAVOR_EVENT, 0, {NewRef{}, $3}, $4);
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
| TOK_HOOK def_global_id func_params opt_attr
|
| TOK_HOOK def_global_id func_params opt_attr
|
||||||
|
@ -1194,13 +1206,13 @@ func_hdr:
|
||||||
$3->ClearYieldType(FUNC_FLAVOR_HOOK);
|
$3->ClearYieldType(FUNC_FLAVOR_HOOK);
|
||||||
$3->SetYieldType(base_type(TYPE_BOOL));
|
$3->SetYieldType(base_type(TYPE_BOOL));
|
||||||
begin_func($2, current_module.c_str(),
|
begin_func($2, current_module.c_str(),
|
||||||
FUNC_FLAVOR_HOOK, 0, $3, $4);
|
FUNC_FLAVOR_HOOK, 0, {NewRef{}, $3}, $4);
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
| TOK_REDEF TOK_EVENT event_id func_params opt_attr
|
| TOK_REDEF TOK_EVENT event_id func_params opt_attr
|
||||||
{
|
{
|
||||||
begin_func($3, current_module.c_str(),
|
begin_func($3, current_module.c_str(),
|
||||||
FUNC_FLAVOR_EVENT, 1, $4, $5);
|
FUNC_FLAVOR_EVENT, 1, {NewRef{}, $4}, $5);
|
||||||
$$ = $4;
|
$$ = $4;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -1221,7 +1233,7 @@ func_body:
|
||||||
'}'
|
'}'
|
||||||
{
|
{
|
||||||
set_location(func_hdr_location, @5);
|
set_location(func_hdr_location, @5);
|
||||||
end_func($3);
|
end_func({AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1250,7 +1262,7 @@ anonymous_function:
|
||||||
|
|
||||||
// Gather the ingredients for a BroFunc from the current scope
|
// Gather the ingredients for a BroFunc from the current scope
|
||||||
auto ingredients = std::make_unique<function_ingredients>(current_scope(), $5);
|
auto ingredients = std::make_unique<function_ingredients>(current_scope(), $5);
|
||||||
id_list outer_ids = gather_outer_ids(pop_scope(), $5);
|
id_list outer_ids = gather_outer_ids(pop_scope().get(), $5);
|
||||||
|
|
||||||
$$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids));
|
$$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids));
|
||||||
}
|
}
|
||||||
|
@ -1260,7 +1272,7 @@ begin_func:
|
||||||
func_params
|
func_params
|
||||||
{
|
{
|
||||||
$$ = current_scope()->GenerateTemporary("anonymous-function");
|
$$ = current_scope()->GenerateTemporary("anonymous-function");
|
||||||
begin_func($$, current_module.c_str(), FUNC_FLAVOR_FUNCTION, 0, $1);
|
begin_func($$, current_module.c_str(), FUNC_FLAVOR_FUNCTION, 0, {AdoptRef{}, $1});
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1304,15 +1316,21 @@ index_slice:
|
||||||
expr '[' opt_expr ':' opt_expr ']'
|
expr '[' opt_expr ':' opt_expr ']'
|
||||||
{
|
{
|
||||||
set_location(@1, @6);
|
set_location(@1, @6);
|
||||||
Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0));
|
|
||||||
Expr* high = $5 ? $5 : new SizeExpr($1->Ref());
|
auto low = $3 ? IntrusivePtr<Expr>{AdoptRef{}, $3} :
|
||||||
|
make_intrusive<ConstExpr>(
|
||||||
|
IntrusivePtr<Val>{AdoptRef{}, val_mgr->GetCount(0)});
|
||||||
|
|
||||||
|
auto high = $5 ? IntrusivePtr<Expr>{AdoptRef{}, $5} :
|
||||||
|
make_intrusive<SizeExpr>(
|
||||||
|
IntrusivePtr<Expr>{NewRef{}, $1});
|
||||||
|
|
||||||
if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) )
|
if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) )
|
||||||
reporter->Error("slice notation must have integral values as indexes");
|
reporter->Error("slice notation must have integral values as indexes");
|
||||||
|
|
||||||
ListExpr* le = new ListExpr(low);
|
auto le = make_intrusive<ListExpr>(std::move(low));
|
||||||
le->Append(high);
|
le->Append(std::move(high));
|
||||||
$$ = new IndexExpr($1, le, true);
|
$$ = new IndexExpr({AdoptRef{}, $1}, std::move(le), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_attr:
|
opt_attr:
|
||||||
|
@ -1367,7 +1385,7 @@ attr:
|
||||||
| TOK_ATTR_DEPRECATED '=' TOK_CONSTANT
|
| TOK_ATTR_DEPRECATED '=' TOK_CONSTANT
|
||||||
{
|
{
|
||||||
if ( IsString($3->Type()->Tag()) )
|
if ( IsString($3->Type()->Tag()) )
|
||||||
$$ = new Attr(ATTR_DEPRECATED, new ConstExpr($3));
|
$$ = new Attr(ATTR_DEPRECATED, new ConstExpr({AdoptRef{}, $3}));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ODesc d;
|
ODesc d;
|
||||||
|
@ -1392,7 +1410,7 @@ stmt:
|
||||||
| TOK_PRINT expr_list ';' opt_no_test
|
| TOK_PRINT expr_list ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new PrintStmt($2);
|
$$ = new PrintStmt(IntrusivePtr{AdoptRef{}, $2});
|
||||||
if ( ! $4 )
|
if ( ! $4 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1400,7 +1418,7 @@ stmt:
|
||||||
| TOK_EVENT event ';' opt_no_test
|
| TOK_EVENT event ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new EventStmt($2);
|
$$ = new EventStmt({AdoptRef{}, $2});
|
||||||
if ( ! $4 )
|
if ( ! $4 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1408,29 +1426,29 @@ stmt:
|
||||||
| TOK_IF '(' expr ')' stmt
|
| TOK_IF '(' expr ')' stmt
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new IfStmt($3, $5, new NullStmt());
|
$$ = new IfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, make_intrusive<NullStmt>());
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_IF '(' expr ')' stmt TOK_ELSE stmt
|
| TOK_IF '(' expr ')' stmt TOK_ELSE stmt
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new IfStmt($3, $5, $7);
|
$$ = new IfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, {AdoptRef{}, $7});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_SWITCH expr '{' case_list '}'
|
| TOK_SWITCH expr '{' case_list '}'
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new SwitchStmt($2, $4);
|
$$ = new SwitchStmt({AdoptRef{}, $2}, $4);
|
||||||
}
|
}
|
||||||
|
|
||||||
| for_head stmt
|
| for_head stmt
|
||||||
{
|
{
|
||||||
$1->AsForStmt()->AddBody($2);
|
$1->AsForStmt()->AddBody({AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_WHILE '(' expr ')' stmt
|
| TOK_WHILE '(' expr ')' stmt
|
||||||
{
|
{
|
||||||
$$ = new WhileStmt($3, $5);
|
$$ = new WhileStmt({AdoptRef{}, $3}, {AdoptRef{}, $5});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_NEXT ';' opt_no_test
|
| TOK_NEXT ';' opt_no_test
|
||||||
|
@ -1468,7 +1486,7 @@ stmt:
|
||||||
| TOK_RETURN expr ';' opt_no_test
|
| TOK_RETURN expr ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new ReturnStmt($2);
|
$$ = new ReturnStmt({AdoptRef{}, $2});
|
||||||
if ( ! $4 )
|
if ( ! $4 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1476,7 +1494,7 @@ stmt:
|
||||||
| TOK_ADD expr ';' opt_no_test
|
| TOK_ADD expr ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new AddStmt($2);
|
$$ = new AddStmt({AdoptRef{}, $2});
|
||||||
if ( ! $4 )
|
if ( ! $4 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1484,7 +1502,7 @@ stmt:
|
||||||
| TOK_DELETE expr ';' opt_no_test
|
| TOK_DELETE expr ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new DelStmt($2);
|
$$ = new DelStmt({AdoptRef{}, $2});
|
||||||
if ( ! $4 )
|
if ( ! $4 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1492,7 +1510,8 @@ stmt:
|
||||||
| TOK_LOCAL local_id opt_type init_class opt_init opt_attr ';' opt_no_test
|
| TOK_LOCAL local_id opt_type init_class opt_init opt_attr ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @7);
|
set_location(@1, @7);
|
||||||
$$ = add_local($2, $3, $4, $5, $6, VAR_REGULAR);
|
$$ = add_local({AdoptRef{}, $2}, {AdoptRef{}, $3}, $4,
|
||||||
|
{AdoptRef{}, $5}, $6, VAR_REGULAR).release();
|
||||||
if ( ! $8 )
|
if ( ! $8 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1500,7 +1519,8 @@ stmt:
|
||||||
| TOK_CONST local_id opt_type init_class opt_init opt_attr ';' opt_no_test
|
| TOK_CONST local_id opt_type init_class opt_init opt_attr ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @6);
|
set_location(@1, @6);
|
||||||
$$ = add_local($2, $3, $4, $5, $6, VAR_CONST);
|
$$ = add_local({AdoptRef{}, $2}, {AdoptRef{}, $3}, $4,
|
||||||
|
{AdoptRef{}, $5}, $6, VAR_CONST).release();
|
||||||
if ( ! $8 )
|
if ( ! $8 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1508,13 +1528,15 @@ stmt:
|
||||||
| TOK_WHEN '(' expr ')' stmt
|
| TOK_WHEN '(' expr ')' stmt
|
||||||
{
|
{
|
||||||
set_location(@3, @5);
|
set_location(@3, @5);
|
||||||
$$ = new WhenStmt($3, $5, 0, 0, false);
|
$$ = new WhenStmt({AdoptRef{}, $3}, {AdoptRef{}, $5},
|
||||||
|
nullptr, nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
| TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
||||||
{
|
{
|
||||||
set_location(@3, @9);
|
set_location(@3, @9);
|
||||||
$$ = new WhenStmt($3, $5, $10, $7, false);
|
$$ = new WhenStmt({AdoptRef{}, $3}, {AdoptRef{}, $5},
|
||||||
|
{AdoptRef{}, $10}, {AdoptRef{}, $7}, false);
|
||||||
if ( $9 )
|
if ( $9 )
|
||||||
brofiler.DecIgnoreDepth();
|
brofiler.DecIgnoreDepth();
|
||||||
}
|
}
|
||||||
|
@ -1523,13 +1545,15 @@ stmt:
|
||||||
| TOK_RETURN TOK_WHEN '(' expr ')' stmt
|
| TOK_RETURN TOK_WHEN '(' expr ')' stmt
|
||||||
{
|
{
|
||||||
set_location(@4, @6);
|
set_location(@4, @6);
|
||||||
$$ = new WhenStmt($4, $6, 0, 0, true);
|
$$ = new WhenStmt({AdoptRef{}, $4}, {AdoptRef{}, $6}, nullptr,
|
||||||
|
nullptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_RETURN TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
| TOK_RETURN TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
|
||||||
{
|
{
|
||||||
set_location(@4, @10);
|
set_location(@4, @10);
|
||||||
$$ = new WhenStmt($4, $6, $11, $8, true);
|
$$ = new WhenStmt({AdoptRef{}, $4}, {AdoptRef{}, $6},
|
||||||
|
{AdoptRef{}, $11}, {AdoptRef{}, $8}, true);
|
||||||
if ( $10 )
|
if ( $10 )
|
||||||
brofiler.DecIgnoreDepth();
|
brofiler.DecIgnoreDepth();
|
||||||
}
|
}
|
||||||
|
@ -1537,7 +1561,8 @@ stmt:
|
||||||
| index_slice '=' expr ';' opt_no_test
|
| index_slice '=' expr ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
$$ = new ExprStmt(get_assign_expr($1, $3, in_init));
|
$$ = new ExprStmt(get_assign_expr({AdoptRef{}, $1},
|
||||||
|
{AdoptRef{}, $3}, in_init));
|
||||||
|
|
||||||
if ( ! $5 )
|
if ( ! $5 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
|
@ -1546,7 +1571,7 @@ stmt:
|
||||||
| expr ';' opt_no_test
|
| expr ';' opt_no_test
|
||||||
{
|
{
|
||||||
set_location(@1, @2);
|
set_location(@1, @2);
|
||||||
$$ = new ExprStmt($1);
|
$$ = new ExprStmt({AdoptRef{}, $1});
|
||||||
if ( ! $3 )
|
if ( ! $3 )
|
||||||
brofiler.AddStmt($$);
|
brofiler.AddStmt($$);
|
||||||
}
|
}
|
||||||
|
@ -1576,8 +1601,8 @@ event:
|
||||||
TOK_ID '(' opt_expr_list ')'
|
TOK_ID '(' opt_expr_list ')'
|
||||||
{
|
{
|
||||||
set_location(@1, @4);
|
set_location(@1, @4);
|
||||||
|
auto id = lookup_ID($1, current_module.c_str());
|
||||||
|
|
||||||
ID* id = lookup_ID($1, current_module.c_str());
|
|
||||||
if ( id )
|
if ( id )
|
||||||
{
|
{
|
||||||
if ( ! id->IsGlobal() )
|
if ( ! id->IsGlobal() )
|
||||||
|
@ -1585,13 +1610,12 @@ event:
|
||||||
yyerror(fmt("local identifier \"%s\" cannot be used to reference an event", $1));
|
yyerror(fmt("local identifier \"%s\" cannot be used to reference an event", $1));
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( id->IsDeprecated() )
|
if ( id->IsDeprecated() )
|
||||||
reporter->Warning("%s", id->GetDeprecationWarning().c_str());
|
reporter->Warning("%s", id->GetDeprecationWarning().c_str());
|
||||||
|
|
||||||
Unref(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$$ = new EventExpr($1, $3);
|
$$ = new EventExpr($1, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1604,13 +1628,13 @@ case_list:
|
||||||
|
|
||||||
case:
|
case:
|
||||||
TOK_CASE expr_list ':' stmt_list
|
TOK_CASE expr_list ':' stmt_list
|
||||||
{ $$ = new Case($2, 0, $4); }
|
{ $$ = new Case({AdoptRef{}, $2}, 0, {AdoptRef{}, $4}); }
|
||||||
|
|
|
|
||||||
TOK_CASE case_type_list ':' stmt_list
|
TOK_CASE case_type_list ':' stmt_list
|
||||||
{ $$ = new Case(0, $2, $4); }
|
{ $$ = new Case(nullptr, $2, {AdoptRef{}, $4}); }
|
||||||
|
|
|
|
||||||
TOK_DEFAULT ':' stmt_list
|
TOK_DEFAULT ':' stmt_list
|
||||||
{ $$ = new Case(0, 0, $3); }
|
{ $$ = new Case(nullptr, 0, {AdoptRef{}, $3}); }
|
||||||
;
|
;
|
||||||
|
|
||||||
case_type_list:
|
case_type_list:
|
||||||
|
@ -1628,25 +1652,22 @@ case_type:
|
||||||
TOK_TYPE type
|
TOK_TYPE type
|
||||||
{
|
{
|
||||||
$$ = new ID(0, SCOPE_FUNCTION, 0);
|
$$ = new ID(0, SCOPE_FUNCTION, 0);
|
||||||
$$->SetType($2);
|
$$->SetType({AdoptRef{}, $2});
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_TYPE type TOK_AS TOK_ID
|
| TOK_TYPE type TOK_AS TOK_ID
|
||||||
{
|
{
|
||||||
const char* name = $4;
|
const char* name = $4;
|
||||||
BroType* type = $2;
|
IntrusivePtr<BroType> type{AdoptRef{}, $2};
|
||||||
ID* case_var = lookup_ID(name, current_module.c_str());
|
auto case_var = lookup_ID(name, current_module.c_str());
|
||||||
|
|
||||||
if ( case_var && case_var->IsGlobal() )
|
if ( case_var && case_var->IsGlobal() )
|
||||||
case_var->Error("already a global identifier");
|
case_var->Error("already a global identifier");
|
||||||
else
|
else
|
||||||
{
|
|
||||||
Unref(case_var);
|
|
||||||
case_var = install_ID(name, current_module.c_str(), false, false);
|
case_var = install_ID(name, current_module.c_str(), false, false);
|
||||||
}
|
|
||||||
|
|
||||||
add_local(case_var, type, INIT_NONE, 0, 0, VAR_REGULAR);
|
add_local(case_var, std::move(type), INIT_NONE, 0, 0, VAR_REGULAR);
|
||||||
$$ = case_var;
|
$$ = case_var.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
for_head:
|
for_head:
|
||||||
|
@ -1658,7 +1679,7 @@ for_head:
|
||||||
// body so that we execute these actions - defining
|
// body so that we execute these actions - defining
|
||||||
// the local variable - prior to parsing the body,
|
// the local variable - prior to parsing the body,
|
||||||
// which might refer to the variable.
|
// which might refer to the variable.
|
||||||
ID* loop_var = lookup_ID($3, current_module.c_str());
|
auto loop_var = lookup_ID($3, current_module.c_str());
|
||||||
|
|
||||||
if ( loop_var )
|
if ( loop_var )
|
||||||
{
|
{
|
||||||
|
@ -1668,20 +1689,19 @@ for_head:
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Unref(loop_var);
|
|
||||||
loop_var = install_ID($3, current_module.c_str(),
|
loop_var = install_ID($3, current_module.c_str(),
|
||||||
false, false);
|
false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
id_list* loop_vars = new id_list;
|
id_list* loop_vars = new id_list;
|
||||||
loop_vars->push_back(loop_var);
|
loop_vars->push_back(loop_var.release());
|
||||||
|
|
||||||
$$ = new ForStmt(loop_vars, $5);
|
$$ = new ForStmt(loop_vars, {AdoptRef{}, $5});
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
TOK_FOR '(' '[' local_id_list ']' TOK_IN expr ')'
|
TOK_FOR '(' '[' local_id_list ']' TOK_IN expr ')'
|
||||||
{
|
{
|
||||||
$$ = new ForStmt($4, $7);
|
$$ = new ForStmt($4, {AdoptRef{}, $7});
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
TOK_FOR '(' TOK_ID ',' TOK_ID TOK_IN expr ')'
|
TOK_FOR '(' TOK_ID ',' TOK_ID TOK_IN expr ')'
|
||||||
|
@ -1691,8 +1711,8 @@ for_head:
|
||||||
|
|
||||||
// Check for previous definitions of key and
|
// Check for previous definitions of key and
|
||||||
// value variables.
|
// value variables.
|
||||||
ID* key_var = lookup_ID($3, module);
|
auto key_var = lookup_ID($3, module);
|
||||||
ID* val_var = lookup_ID($5, module);
|
auto val_var = lookup_ID($5, module);
|
||||||
|
|
||||||
// Validate previous definitions as needed.
|
// Validate previous definitions as needed.
|
||||||
if ( key_var )
|
if ( key_var )
|
||||||
|
@ -1712,9 +1732,9 @@ for_head:
|
||||||
val_var = install_ID($5, module, false, false);
|
val_var = install_ID($5, module, false, false);
|
||||||
|
|
||||||
id_list* loop_vars = new id_list;
|
id_list* loop_vars = new id_list;
|
||||||
loop_vars->push_back(key_var);
|
loop_vars->push_back(key_var.release());
|
||||||
|
|
||||||
$$ = new ForStmt(loop_vars, $7, val_var);
|
$$ = new ForStmt(loop_vars, {AdoptRef{}, $7}, std::move(val_var));
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
TOK_FOR '(' '[' local_id_list ']' ',' TOK_ID TOK_IN expr ')'
|
TOK_FOR '(' '[' local_id_list ']' ',' TOK_ID TOK_IN expr ')'
|
||||||
|
@ -1723,7 +1743,7 @@ for_head:
|
||||||
const char* module = current_module.c_str();
|
const char* module = current_module.c_str();
|
||||||
|
|
||||||
// Validate value variable
|
// Validate value variable
|
||||||
ID* val_var = lookup_ID($7, module);
|
auto val_var = lookup_ID($7, module);
|
||||||
|
|
||||||
if ( val_var )
|
if ( val_var )
|
||||||
{
|
{
|
||||||
|
@ -1733,7 +1753,7 @@ for_head:
|
||||||
else
|
else
|
||||||
val_var = install_ID($7, module, false, false);
|
val_var = install_ID($7, module, false, false);
|
||||||
|
|
||||||
$$ = new ForStmt($4, $9, val_var);
|
$$ = new ForStmt($4, {AdoptRef{}, $9}, std::move(val_var));
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1751,8 +1771,8 @@ local_id:
|
||||||
TOK_ID
|
TOK_ID
|
||||||
{
|
{
|
||||||
set_location(@1);
|
set_location(@1);
|
||||||
|
$$ = lookup_ID($1, current_module.c_str()).release();
|
||||||
|
|
||||||
$$ = lookup_ID($1, current_module.c_str());
|
|
||||||
if ( $$ )
|
if ( $$ )
|
||||||
{
|
{
|
||||||
if ( $$->IsGlobal() )
|
if ( $$->IsGlobal() )
|
||||||
|
@ -1763,7 +1783,7 @@ local_id:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$$ = install_ID($1, current_module.c_str(),
|
$$ = install_ID($1, current_module.c_str(),
|
||||||
false, is_export);
|
false, is_export).release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -1787,8 +1807,9 @@ global_or_event_id:
|
||||||
TOK_ID
|
TOK_ID
|
||||||
{
|
{
|
||||||
set_location(@1);
|
set_location(@1);
|
||||||
|
$$ = lookup_ID($1, current_module.c_str(), false,
|
||||||
|
defining_global_ID).release();
|
||||||
|
|
||||||
$$ = lookup_ID($1, current_module.c_str(), false, defining_global_ID);
|
|
||||||
if ( $$ )
|
if ( $$ )
|
||||||
{
|
{
|
||||||
if ( ! $$->IsGlobal() )
|
if ( ! $$->IsGlobal() )
|
||||||
|
@ -1813,7 +1834,7 @@ global_or_event_id:
|
||||||
current_module.c_str() : 0;
|
current_module.c_str() : 0;
|
||||||
|
|
||||||
$$ = install_ID($1, module_name,
|
$$ = install_ID($1, module_name,
|
||||||
true, is_export);
|
true, is_export).release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -1823,7 +1844,7 @@ resolve_id:
|
||||||
TOK_ID
|
TOK_ID
|
||||||
{
|
{
|
||||||
set_location(@1);
|
set_location(@1);
|
||||||
$$ = lookup_ID($1, current_module.c_str());
|
$$ = lookup_ID($1, current_module.c_str()).release();
|
||||||
|
|
||||||
if ( ! $$ )
|
if ( ! $$ )
|
||||||
reporter->Error("identifier not defined: %s", $1);
|
reporter->Error("identifier not defined: %s", $1);
|
||||||
|
@ -1846,19 +1867,19 @@ opt_no_test_block:
|
||||||
|
|
||||||
opt_deprecated:
|
opt_deprecated:
|
||||||
TOK_ATTR_DEPRECATED
|
TOK_ATTR_DEPRECATED
|
||||||
{ $$ = new ConstExpr(new StringVal("")); }
|
{ $$ = new ConstExpr(make_intrusive<StringVal>("")); }
|
||||||
|
|
|
|
||||||
TOK_ATTR_DEPRECATED '=' TOK_CONSTANT
|
TOK_ATTR_DEPRECATED '=' TOK_CONSTANT
|
||||||
{
|
{
|
||||||
if ( IsString($3->Type()->Tag()) )
|
if ( IsString($3->Type()->Tag()) )
|
||||||
$$ = new ConstExpr($3);
|
$$ = new ConstExpr({AdoptRef{}, $3});
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ODesc d;
|
ODesc d;
|
||||||
$3->Describe(&d);
|
$3->Describe(&d);
|
||||||
reporter->Error("'&deprecated=%s' must use a string literal",
|
reporter->Error("'&deprecated=%s' must use a string literal",
|
||||||
d.Description());
|
d.Description());
|
||||||
$$ = new ConstExpr(new StringVal(""));
|
$$ = new ConstExpr(make_intrusive<StringVal>(""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
#include "Var.h" // for add_type()
|
#include "Var.h" // for add_type()
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
|
@ -121,7 +122,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string module; /**< Script layer module in which component tags live. */
|
string module; /**< Script layer module in which component tags live. */
|
||||||
EnumType* tag_enum_type; /**< Enum type of component tags. */
|
IntrusivePtr<EnumType> tag_enum_type; /**< Enum type of component tags. */
|
||||||
map<string, C*> components_by_name;
|
map<string, C*> components_by_name;
|
||||||
map<T, C*> components_by_tag;
|
map<T, C*> components_by_tag;
|
||||||
map<int, C*> components_by_val;
|
map<int, C*> components_by_val;
|
||||||
|
@ -129,12 +130,12 @@ private:
|
||||||
|
|
||||||
template <class T, class C>
|
template <class T, class C>
|
||||||
ComponentManager<T, C>::ComponentManager(const string& arg_module, const string& local_id)
|
ComponentManager<T, C>::ComponentManager(const string& arg_module, const string& local_id)
|
||||||
: module(arg_module)
|
: module(arg_module),
|
||||||
|
tag_enum_type(make_intrusive<EnumType>(module + "::" + local_id))
|
||||||
{
|
{
|
||||||
tag_enum_type = new EnumType(module + "::" + local_id);
|
auto id = install_ID(local_id.c_str(), module.c_str(), true, true);
|
||||||
::ID* id = install_ID(local_id.c_str(), module.c_str(), true, true);
|
add_type(id.get(), tag_enum_type, 0);
|
||||||
add_type(id, tag_enum_type, 0);
|
zeekygen_mgr->Identifier(std::move(id));
|
||||||
zeekygen_mgr->Identifier(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class C>
|
template <class T, class C>
|
||||||
|
@ -158,7 +159,7 @@ list<C*> ComponentManager<T, C>::GetComponents() const
|
||||||
template <class T, class C>
|
template <class T, class C>
|
||||||
EnumType* ComponentManager<T, C>::GetTagEnumType() const
|
EnumType* ComponentManager<T, C>::GetTagEnumType() const
|
||||||
{
|
{
|
||||||
return tag_enum_type;
|
return tag_enum_type.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class C>
|
template <class T, class C>
|
||||||
|
|
19
src/scan.l
19
src/scan.l
|
@ -20,6 +20,7 @@
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
#include "Stmt.h"
|
#include "Stmt.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
#include "Var.h"
|
#include "Var.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
@ -746,10 +747,10 @@ void do_atif(Expr* expr)
|
||||||
|
|
||||||
LocalNameFinder cb;
|
LocalNameFinder cb;
|
||||||
expr->Traverse(&cb);
|
expr->Traverse(&cb);
|
||||||
Val* val = 0;
|
IntrusivePtr<Val> val;
|
||||||
|
|
||||||
if ( cb.local_names.empty() )
|
if ( cb.local_names.empty() )
|
||||||
val = expr->Eval(0);
|
val = expr->Eval(nullptr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < cb.local_names.size(); ++i )
|
for ( size_t i = 0; i < cb.local_names.size(); ++i )
|
||||||
|
@ -767,38 +768,32 @@ void do_atif(Expr* expr)
|
||||||
if_stack.push_back(current_depth);
|
if_stack.push_back(current_depth);
|
||||||
BEGIN(IGNORE);
|
BEGIN(IGNORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_atifdef(const char* id)
|
void do_atifdef(const char* id)
|
||||||
{
|
{
|
||||||
++current_depth;
|
++current_depth;
|
||||||
|
|
||||||
ID* i;
|
auto i = lookup_ID(id, current_module.c_str());
|
||||||
|
|
||||||
if ( ! (i = lookup_ID(id, current_module.c_str())) )
|
if ( ! i )
|
||||||
{
|
{
|
||||||
if_stack.push_back(current_depth);
|
if_stack.push_back(current_depth);
|
||||||
BEGIN(IGNORE);
|
BEGIN(IGNORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_atifndef(const char *id)
|
void do_atifndef(const char *id)
|
||||||
{
|
{
|
||||||
++current_depth;
|
++current_depth;
|
||||||
|
|
||||||
ID* i;
|
auto i = lookup_ID(id, current_module.c_str());
|
||||||
|
|
||||||
if ( (i = lookup_ID(id, current_module.c_str())) )
|
if ( i )
|
||||||
{
|
{
|
||||||
if_stack.push_back(current_depth);
|
if_stack.push_back(current_depth);
|
||||||
BEGIN(IGNORE);
|
BEGIN(IGNORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_atelse()
|
void do_atelse()
|
||||||
|
|
|
@ -1233,7 +1233,7 @@ bool Supervisor::SupervisedNode::InitCluster() const
|
||||||
cluster_nodes->Assign(key.get(), val.release());
|
cluster_nodes->Assign(key.get(), val.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster_manager_is_logger_id->SetVal(val_mgr->GetBool(! has_logger));
|
cluster_manager_is_logger_id->SetVal({AdoptRef{}, val_mgr->GetBool(! has_logger)});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,22 +11,17 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace zeekygen;
|
using namespace zeekygen;
|
||||||
|
|
||||||
IdentifierInfo::IdentifierInfo(ID* arg_id, ScriptInfo* script)
|
IdentifierInfo::IdentifierInfo(IntrusivePtr<ID> arg_id, ScriptInfo* script)
|
||||||
: Info(),
|
: Info(),
|
||||||
comments(), id(arg_id), initial_val(), redefs(), fields(),
|
comments(), id(std::move(arg_id)), initial_val(), redefs(), fields(),
|
||||||
last_field_seen(), declaring_script(script)
|
last_field_seen(), declaring_script(script)
|
||||||
{
|
{
|
||||||
Ref(id);
|
|
||||||
|
|
||||||
if ( id->ID_Val() && (id->IsOption() || id->IsRedefinable()) )
|
if ( id->ID_Val() && (id->IsOption() || id->IsRedefinable()) )
|
||||||
initial_val = id->ID_Val()->Clone();
|
initial_val = {AdoptRef{}, id->ID_Val()->Clone()};
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentifierInfo::~IdentifierInfo()
|
IdentifierInfo::~IdentifierInfo()
|
||||||
{
|
{
|
||||||
Unref(id);
|
|
||||||
Unref(initial_val);
|
|
||||||
|
|
||||||
for ( redef_list::const_iterator it = redefs.begin(); it != redefs.end();
|
for ( redef_list::const_iterator it = redefs.begin(); it != redefs.end();
|
||||||
++it )
|
++it )
|
||||||
delete *it;
|
delete *it;
|
||||||
|
@ -51,7 +46,15 @@ void IdentifierInfo::AddRecordField(const TypeDecl* field,
|
||||||
rf->field = new TypeDecl(*field);
|
rf->field = new TypeDecl(*field);
|
||||||
rf->from_script = script;
|
rf->from_script = script;
|
||||||
rf->comments = comments;
|
rf->comments = comments;
|
||||||
fields[rf->field->id] = rf;
|
|
||||||
|
auto [it, inserted] = fields.emplace(rf->field->id, rf);
|
||||||
|
|
||||||
|
if ( ! inserted )
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
it->second = rf;
|
||||||
|
}
|
||||||
|
|
||||||
last_field_seen = rf;
|
last_field_seen = rf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Info.h"
|
#include "Info.h"
|
||||||
|
#include "IntrusivePtr.h"
|
||||||
#include "ID.h"
|
#include "ID.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -31,7 +32,7 @@ public:
|
||||||
* @param script The info object associated with the script in which \a id
|
* @param script The info object associated with the script in which \a id
|
||||||
* is declared.
|
* is declared.
|
||||||
*/
|
*/
|
||||||
IdentifierInfo(ID* id, ScriptInfo* script);
|
IdentifierInfo(IntrusivePtr<ID> id, ScriptInfo* script);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dtor. Releases any references to script-level objects.
|
* Dtor. Releases any references to script-level objects.
|
||||||
|
@ -42,7 +43,7 @@ public:
|
||||||
* Returns the initial value of the identifier.
|
* Returns the initial value of the identifier.
|
||||||
*/
|
*/
|
||||||
Val* InitialVal() const
|
Val* InitialVal() const
|
||||||
{ return initial_val; }
|
{ return initial_val.get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a comment associated with the identifier. If the identifier is a
|
* Add a comment associated with the identifier. If the identifier is a
|
||||||
|
@ -96,7 +97,7 @@ public:
|
||||||
* @return the script-level ID tracked by this info object.
|
* @return the script-level ID tracked by this info object.
|
||||||
*/
|
*/
|
||||||
ID* GetID() const
|
ID* GetID() const
|
||||||
{ return id; }
|
{ return id.get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The script which declared the script-level identifier.
|
* @return The script which declared the script-level identifier.
|
||||||
|
@ -177,8 +178,8 @@ private:
|
||||||
typedef std::map<std::string, RecordField*> record_field_map;
|
typedef std::map<std::string, RecordField*> record_field_map;
|
||||||
|
|
||||||
std::vector<std::string> comments;
|
std::vector<std::string> comments;
|
||||||
ID* id;
|
IntrusivePtr<ID> id;
|
||||||
Val* initial_val;
|
IntrusivePtr<Val> initial_val;
|
||||||
redef_list redefs;
|
redef_list redefs;
|
||||||
record_field_map fields;
|
record_field_map fields;
|
||||||
RecordField* last_field_seen;
|
RecordField* last_field_seen;
|
||||||
|
|
|
@ -215,7 +215,7 @@ void Manager::ModuleUsage(const string& path, const string& module)
|
||||||
module.c_str(), name.c_str());
|
module.c_str(), name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentifierInfo* Manager::CreateIdentifierInfo(ID* id, ScriptInfo* script)
|
IdentifierInfo* Manager::CreateIdentifierInfo(IntrusivePtr<ID> id, ScriptInfo* script)
|
||||||
{
|
{
|
||||||
auto prev = identifiers.GetInfo(id->Name());
|
auto prev = identifiers.GetInfo(id->Name());
|
||||||
IdentifierInfo* rval = prev ? prev : new IdentifierInfo(id, script);
|
IdentifierInfo* rval = prev ? prev : new IdentifierInfo(id, script);
|
||||||
|
@ -245,7 +245,7 @@ IdentifierInfo* Manager::CreateIdentifierInfo(ID* id, ScriptInfo* script)
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::StartType(ID* id)
|
void Manager::StartType(IntrusivePtr<ID> id)
|
||||||
{
|
{
|
||||||
if ( disabled )
|
if ( disabled )
|
||||||
return;
|
return;
|
||||||
|
@ -262,7 +262,7 @@ void Manager::StartType(ID* id)
|
||||||
|
|
||||||
if ( ! script_info )
|
if ( ! script_info )
|
||||||
{
|
{
|
||||||
WarnMissingScript("identifier", id, script);
|
WarnMissingScript("identifier", id.get(), script);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ static bool IsEnumType(ID* id)
|
||||||
return id->AsType() ? id->AsType()->Tag() == TYPE_ENUM : false;
|
return id->AsType() ? id->AsType()->Tag() == TYPE_ENUM : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::Identifier(ID* id)
|
void Manager::Identifier(IntrusivePtr<ID> id)
|
||||||
{
|
{
|
||||||
if ( disabled )
|
if ( disabled )
|
||||||
return;
|
return;
|
||||||
|
@ -326,7 +326,7 @@ void Manager::Identifier(ID* id)
|
||||||
|
|
||||||
if ( ! script_info )
|
if ( ! script_info )
|
||||||
{
|
{
|
||||||
WarnMissingScript("identifier", id, script);
|
WarnMissingScript("identifier", id.get(), script);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,14 +109,14 @@ public:
|
||||||
* Signal that a record or enum type is now being parsed.
|
* Signal that a record or enum type is now being parsed.
|
||||||
* @param id The record or enum type identifier.
|
* @param id The record or enum type identifier.
|
||||||
*/
|
*/
|
||||||
void StartType(ID* id);
|
void StartType(IntrusivePtr<ID> id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a script-level identifier for which information/documentation
|
* Register a script-level identifier for which information/documentation
|
||||||
* will be gathered.
|
* will be gathered.
|
||||||
* @param id The script-level identifier.
|
* @param id The script-level identifier.
|
||||||
*/
|
*/
|
||||||
void Identifier(ID* id);
|
void Identifier(IntrusivePtr<ID> id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a record-field for which information/documentation will be
|
* Register a record-field for which information/documentation will be
|
||||||
|
@ -214,7 +214,7 @@ private:
|
||||||
typedef std::vector<std::string> comment_buffer_t;
|
typedef std::vector<std::string> comment_buffer_t;
|
||||||
typedef std::map<std::string, comment_buffer_t> comment_buffer_map_t;
|
typedef std::map<std::string, comment_buffer_t> comment_buffer_map_t;
|
||||||
|
|
||||||
IdentifierInfo* CreateIdentifierInfo(ID* id, ScriptInfo* script);
|
IdentifierInfo* CreateIdentifierInfo(IntrusivePtr<ID> id, ScriptInfo* script);
|
||||||
|
|
||||||
bool disabled;
|
bool disabled;
|
||||||
comment_buffer_t comment_buffer; // For whatever next identifier comes in.
|
comment_buffer_t comment_buffer; // For whatever next identifier comes in.
|
||||||
|
|
|
@ -258,12 +258,12 @@ void ScriptInfo::DoInitPostScript()
|
||||||
if ( name == "base/frameworks/input/main.zeek" )
|
if ( name == "base/frameworks/input/main.zeek" )
|
||||||
{
|
{
|
||||||
auto id = global_scope()->Lookup("Input::Reader");
|
auto id = global_scope()->Lookup("Input::Reader");
|
||||||
types.push_back(new IdentifierInfo(id, this));
|
types.push_back(new IdentifierInfo({NewRef{}, id}, this));
|
||||||
}
|
}
|
||||||
else if ( name == "base/frameworks/logging/main.zeek" )
|
else if ( name == "base/frameworks/logging/main.zeek" )
|
||||||
{
|
{
|
||||||
auto id = global_scope()->Lookup("Log::Writer");
|
auto id = global_scope()->Lookup("Log::Writer");
|
||||||
types.push_back(new IdentifierInfo(id, this));
|
types.push_back(new IdentifierInfo({NewRef{}, id}, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue