convert scopes to be managed using IntrusivePtr's

This commit is contained in:
Vern Paxson 2021-05-30 17:20:29 -07:00
parent f2f041b63b
commit efd03d41f8
16 changed files with 41 additions and 48 deletions

View file

@ -972,10 +972,7 @@ ValPtr dbg_eval_expr(const char* expr)
const ScriptFunc* func = frame->GetFunction(); const ScriptFunc* 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?

View file

@ -61,7 +61,7 @@ static void lookup_global_symbols_regex(const string& orig_regex, vector<ID*>& m
return; return;
} }
Scope* global = global_scope(); auto global = global_scope();
const auto& syms = global->Vars(); const auto& syms = global->Vars();
ID* nextid; ID* nextid;

View file

@ -4554,9 +4554,9 @@ void LambdaExpr::CheckCaptures()
} }
} }
Scope* LambdaExpr::GetScope() const ScopePtr LambdaExpr::GetScope() const
{ {
return ingredients->scope.get(); return ingredients->scope;
} }
ValPtr LambdaExpr::Eval(Frame* f) const ValPtr LambdaExpr::Eval(Frame* f) const

View file

@ -27,6 +27,7 @@ class Frame;
class Scope; class Scope;
struct function_ingredients; struct function_ingredients;
using IDPtr = IntrusivePtr<ID>; using IDPtr = IntrusivePtr<ID>;
using ScopePtr = IntrusivePtr<Scope>;
enum BroExprTag : int { enum BroExprTag : int {
EXPR_ANY = -1, EXPR_ANY = -1,
@ -1341,7 +1342,7 @@ public:
ValPtr Eval(Frame* f) const override; ValPtr Eval(Frame* f) const override;
TraversalCode Traverse(TraversalCallback* cb) const override; TraversalCode Traverse(TraversalCallback* cb) const override;
Scope* GetScope() const; ScopePtr GetScope() const;
// Optimization-related: // Optimization-related:
ExprPtr Duplicate() override; ExprPtr Duplicate() override;

View file

@ -201,8 +201,8 @@ void Func::DescribeDebug(ODesc* d, const Args* args) const
detail::TraversalCode Func::Traverse(detail::TraversalCallback* cb) const detail::TraversalCode Func::Traverse(detail::TraversalCallback* cb) const
{ {
// FIXME: Make a fake scope for builtins? // FIXME: Make a fake scope for builtins?
detail::Scope* old_scope = cb->current_scope; auto old_scope = cb->current_scope;
cb->current_scope = scope.get(); cb->current_scope = scope;
detail::TraversalCode tc = cb->PreFunction(this); detail::TraversalCode tc = cb->PreFunction(this);
HANDLE_TC_STMT_PRE(tc); HANDLE_TC_STMT_PRE(tc);

View file

@ -12,7 +12,7 @@
#include "zeek/ZeekList.h" #include "zeek/ZeekList.h"
#include "zeek/Stmt.h" #include "zeek/Stmt.h"
#include "zeek/Obj.h" #include "zeek/Obj.h"
#include "zeek/IntrusivePtr.h" #include "zeek/Scope.h"
#include "zeek/Type.h" /* for function_flavor */ #include "zeek/Type.h" /* for function_flavor */
#include "zeek/TraverseTypes.h" #include "zeek/TraverseTypes.h"
#include "zeek/ZeekArgs.h" #include "zeek/ZeekArgs.h"
@ -103,7 +103,7 @@ public:
size_t new_frame_size, int priority = 0); size_t new_frame_size, int priority = 0);
virtual void SetScope(detail::ScopePtr newscope); virtual void SetScope(detail::ScopePtr newscope);
virtual detail::Scope* GetScope() const { return scope.get(); } virtual detail::ScopePtr GetScope() const { return scope; }
const FuncTypePtr& GetType() const const FuncTypePtr& GetType() const
{ return type; } { return type; }

View file

@ -12,10 +12,8 @@
namespace zeek::detail { namespace zeek::detail {
using scope_list = PList<Scope>; static std::vector<ScopePtr> scopes;
static ScopePtr top_scope;
static scope_list scopes;
static Scope* top_scope;
Scope::Scope(IDPtr id, Scope::Scope(IDPtr id,
std::unique_ptr<std::vector<AttrPtr>> al) std::unique_ptr<std::vector<AttrPtr>> al)
@ -117,7 +115,7 @@ const IDPtr& lookup_ID(const char* name, const char* curr_module,
bool need_export = check_export && (ID_module != GLOBAL_MODULE_NAME && bool need_export = check_export && (ID_module != GLOBAL_MODULE_NAME &&
ID_module != curr_module); ID_module != curr_module);
for ( int i = scopes.length() - 1; i >= 0; --i ) for ( int i = scopes.size() - 1; i >= 0; --i )
{ {
const auto& id = scopes[i]->Find(fullname); const auto& id = scopes[i]->Find(fullname);
@ -172,16 +170,15 @@ IDPtr install_ID(const char* name, const char* module_name,
return id; return id;
} }
void push_existing_scope(Scope* scope) void push_existing_scope(ScopePtr scope)
{ {
top_scope = scope; top_scope = scope;
scopes.push_back(scope); scopes.push_back(scope);
} }
void push_scope(IDPtr id, void push_scope(IDPtr id, std::unique_ptr<std::vector<AttrPtr>> attrs)
std::unique_ptr<std::vector<AttrPtr>> attrs)
{ {
top_scope = new Scope(std::move(id), std::move(attrs)); top_scope = make_intrusive<Scope>(std::move(id), std::move(attrs));
scopes.push_back(top_scope); scopes.push_back(top_scope);
} }
@ -191,19 +188,19 @@ ScopePtr pop_scope()
reporter->InternalError("scope underflow"); reporter->InternalError("scope underflow");
scopes.pop_back(); scopes.pop_back();
Scope* old_top = top_scope; auto old_top = top_scope;
top_scope = scopes.empty() ? nullptr : scopes.back(); top_scope = scopes.empty() ? nullptr : scopes.back();
return {AdoptRef{}, old_top}; return old_top;
} }
Scope* current_scope() ScopePtr current_scope()
{ {
return top_scope; return top_scope;
} }
Scope* global_scope() ScopePtr global_scope()
{ {
return scopes.empty() ? 0 : scopes.front(); return scopes.empty() ? 0 : scopes.front();
} }

View file

@ -96,12 +96,12 @@ extern IDPtr install_ID(
bool is_global, bool is_export); bool is_global, bool is_export);
extern void push_scope(IDPtr id, std::unique_ptr<std::vector<AttrPtr>> attrs); extern void push_scope(IDPtr id, std::unique_ptr<std::vector<AttrPtr>> attrs);
extern void push_existing_scope(Scope* scope); extern void push_existing_scope(ScopePtr scope);
// Returns the one popped off. // Returns the one popped off.
extern ScopePtr pop_scope(); extern ScopePtr pop_scope();
extern Scope* current_scope(); extern ScopePtr current_scope();
extern Scope* global_scope(); extern ScopePtr global_scope();
// Current module (identified by its name). // Current module (identified by its name).
extern std::string current_module; extern std::string current_module;

View file

@ -1514,7 +1514,7 @@ TraversalCode FallthroughStmt::Traverse(TraversalCallback* cb) const
ReturnStmt::ReturnStmt(ExprPtr arg_e) ReturnStmt::ReturnStmt(ExprPtr arg_e)
: ExprStmt(STMT_RETURN, std::move(arg_e)) : ExprStmt(STMT_RETURN, std::move(arg_e))
{ {
Scope* s = current_scope(); auto s = current_scope();
if ( ! s || ! s->GetID() ) if ( ! s || ! s->GetID() )
{ {

View file

@ -2,6 +2,7 @@
#pragma once #pragma once
#include "zeek/Scope.h"
#include "zeek/TraverseTypes.h" #include "zeek/TraverseTypes.h"
namespace zeek { namespace zeek {
@ -10,7 +11,6 @@ class Func;
namespace detail { namespace detail {
class Scope;
class Stmt; class Stmt;
class Expr; class Expr;
class ID; class ID;
@ -38,7 +38,7 @@ public:
virtual TraversalCode PreDecl(const ID*) { return TC_CONTINUE; } virtual TraversalCode PreDecl(const ID*) { return TC_CONTINUE; }
virtual TraversalCode PostDecl(const ID*) { return TC_CONTINUE; } virtual TraversalCode PostDecl(const ID*) { return TC_CONTINUE; }
Scope* current_scope; ScopePtr current_scope;
}; };
TraversalCode traverse_all(TraversalCallback* cb); TraversalCode traverse_all(TraversalCallback* cb);

View file

@ -672,7 +672,7 @@ void begin_func(IDPtr id, const char* module_name,
class OuterIDBindingFinder : public TraversalCallback { class OuterIDBindingFinder : public TraversalCallback {
public: public:
OuterIDBindingFinder(Scope* s) OuterIDBindingFinder(ScopePtr s)
{ {
scopes.emplace_back(s); scopes.emplace_back(s);
} }
@ -680,7 +680,7 @@ public:
TraversalCode PreExpr(const Expr*) override; TraversalCode PreExpr(const Expr*) override;
TraversalCode PostExpr(const Expr*) override; TraversalCode PostExpr(const Expr*) override;
std::vector<Scope*> scopes; std::vector<ScopePtr> scopes;
std::unordered_set<ID*> outer_id_references; std::unordered_set<ID*> outer_id_references;
}; };
@ -766,7 +766,7 @@ void end_func(StmtPtr body)
ingredients.release(); ingredients.release();
} }
IDPList gather_outer_ids(Scope* scope, Stmt* body) IDPList gather_outer_ids(ScopePtr scope, StmtPtr body)
{ {
OuterIDBindingFinder cb(scope); OuterIDBindingFinder cb(scope);
body->Traverse(&cb); body->Traverse(&cb);

View file

@ -20,6 +20,7 @@ class Expr;
class Scope; class Scope;
class Stmt; class Stmt;
using StmtPtr = IntrusivePtr<Stmt>; using StmtPtr = IntrusivePtr<Stmt>;
using ScopePtr = IntrusivePtr<Scope>;
enum DeclType { VAR_REGULAR, VAR_CONST, VAR_REDEF, VAR_OPTION, }; enum DeclType { VAR_REGULAR, VAR_CONST, VAR_REDEF, VAR_OPTION, };
@ -41,7 +42,7 @@ extern void begin_func(IDPtr id, const char* module_name, FunctionFlavor flavor,
extern void end_func(StmtPtr body); extern void end_func(StmtPtr 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 IDPList gather_outer_ids(Scope* scope, Stmt* body); extern IDPList gather_outer_ids(ScopePtr scope, StmtPtr body);
} // namespace detail } // namespace detail
} // namespace zeek } // namespace zeek

View file

@ -1327,9 +1327,8 @@ lambda_body:
// Gather the ingredients for a Func from the // Gather the ingredients for a Func from the
// current scope. // current scope.
auto ingredients = std::make_unique<function_ingredients>( auto ingredients = std::make_unique<function_ingredients>(
IntrusivePtr{NewRef{}, current_scope()}, current_scope(), IntrusivePtr{AdoptRef{}, $3});
IntrusivePtr{AdoptRef{}, $3}); auto outer_ids = gather_outer_ids(pop_scope(), ingredients->body);
IDPList outer_ids = gather_outer_ids(pop_scope().get(), ingredients->body.get());
$$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids)); $$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids));
} }

View file

@ -10,7 +10,7 @@
namespace zeek::detail { namespace zeek::detail {
void RD_Decorate::TraverseFunction(const Func* f, Scope* scope, StmtPtr body) void RD_Decorate::TraverseFunction(const Func* f, ScopePtr scope, StmtPtr body)
{ {
func_flavor = f->Flavor(); func_flavor = f->Flavor();

View file

@ -54,11 +54,8 @@ public:
{ } { }
// Traverses the given function body, using the first two // Traverses the given function body, using the first two
// arguments for context. "scope" is a Scope* rather than // arguments for context.
// a ScopePtr because the various scope management functions void TraverseFunction(const Func* f, ScopePtr scope, StmtPtr body);
// (e.g., push_existing_scope(), current_scope()) traffic in
// Scope*'s.
void TraverseFunction(const Func* f, Scope* scope, StmtPtr body);
TraversalCode PreStmt(const Stmt*) override; TraversalCode PreStmt(const Stmt*) override;
TraversalCode PostStmt(const Stmt*) override; TraversalCode PostStmt(const Stmt*) override;

View file

@ -28,9 +28,11 @@ void (*CPP_init_hook)() = nullptr;
// Tracks all of the loaded functions (including event handlers and hooks). // Tracks all of the loaded functions (including event handlers and hooks).
static std::vector<FuncInfo> funcs; static std::vector<FuncInfo> funcs;
static ZAMCompiler* ZAM = nullptr;
void optimize_func(ScriptFunc* f, std::shared_ptr<ProfileFunc> pf, void optimize_func(ScriptFunc* f, std::shared_ptr<ProfileFunc> pf,
ScopePtr scope_ptr, StmtPtr& body, ScopePtr scope, StmtPtr& body,
AnalyOpt& analysis_options) AnalyOpt& analysis_options)
{ {
if ( reporter->Errors() > 0 ) if ( reporter->Errors() > 0 )
@ -57,7 +59,6 @@ void optimize_func(ScriptFunc* f, std::shared_ptr<ProfileFunc> pf,
return; return;
} }
auto scope = scope_ptr.release();
push_existing_scope(scope); push_existing_scope(scope);
auto rc = std::make_shared<Reducer>(); auto rc = std::make_shared<Reducer>();
@ -162,8 +163,8 @@ void analyze_func(ScriptFuncPtr f)
*analysis_options.only_func != f->Name() ) *analysis_options.only_func != f->Name() )
return; return;
funcs.emplace_back(f, ScopePtr{NewRef{}, f->GetScope()}, funcs.emplace_back(f, f->GetScope(), f->CurrentBody(),
f->CurrentBody(), f->CurrentPriority()); f->CurrentPriority());
} }
const FuncInfo* analyze_global_stmts(Stmt* stmts) const FuncInfo* analyze_global_stmts(Stmt* stmts)
@ -182,7 +183,7 @@ const FuncInfo* analyze_global_stmts(Stmt* stmts)
StmtPtr stmts_p{NewRef{}, stmts}; StmtPtr stmts_p{NewRef{}, stmts};
auto sf = make_intrusive<ScriptFunc>(id, stmts_p, empty_inits, sc->Length(), 0); auto sf = make_intrusive<ScriptFunc>(id, stmts_p, empty_inits, sc->Length(), 0);
funcs.emplace_back(sf, ScopePtr{NewRef{}, sc}, stmts_p, 0); funcs.emplace_back(sf, sc, stmts_p, 0);
return &funcs.back(); return &funcs.back();
} }