mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 15:18:20 +00:00
Call parent constructor from LambdaExpr.
This commit is contained in:
parent
f47390f66a
commit
409f27955b
10 changed files with 37 additions and 51 deletions
|
@ -1 +1 @@
|
|||
Subproject commit f9b347738f1edff486d64fe8c8fdfea2e6c98996
|
||||
Subproject commit 539c2d82534345c62ba9a20c2e98ea5cbdea9c7e
|
2
doc
2
doc
|
@ -1 +1 @@
|
|||
Subproject commit d57b3ad38b2b1ecfd9f1d51699b5fcb785178bf7
|
||||
Subproject commit 69a337c5c7958014566f138bfbce9ce95db47b3d
|
|
@ -30,7 +30,7 @@ const char* expr_name(BroExprTag t)
|
|||
"=", "~", "[]", "$", "?$", "[=]",
|
||||
"table()", "set()", "vector()",
|
||||
"$=", "in", "<<>>",
|
||||
"()", "event", "schedule",
|
||||
"()", "function()", "event", "schedule",
|
||||
"coerce", "record_coerce", "table_coerce",
|
||||
"sizeof", "flatten", "cast", "is", "[:]="
|
||||
};
|
||||
|
@ -4323,7 +4323,7 @@ void CallExpr::ExprDescribe(ODesc* d) const
|
|||
}
|
||||
|
||||
LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
||||
std::shared_ptr<id_list> outer_ids)
|
||||
std::shared_ptr<id_list> outer_ids) : Expr(EXPR_LAMBDA)
|
||||
{
|
||||
this->ingredients = std::move(ingredients);
|
||||
this->outer_ids = std::move(outer_ids);
|
||||
|
@ -4333,6 +4333,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
|||
|
||||
Val* LambdaExpr::Eval(Frame* f) const
|
||||
{
|
||||
reporter->Warning("eval lambda");
|
||||
BroFunc* lamb = new BroFunc(
|
||||
ingredients->id,
|
||||
ingredients->body,
|
||||
|
@ -4347,10 +4348,8 @@ Val* LambdaExpr::Eval(Frame* f) const
|
|||
|
||||
void LambdaExpr::ExprDescribe(ODesc* d) const
|
||||
{
|
||||
d->Add("Lambda Expression");
|
||||
d->Add("{");
|
||||
d->Add(expr_name(Tag()));
|
||||
ingredients->body->Describe(d);
|
||||
d->Add("}");
|
||||
}
|
||||
|
||||
TraversalCode LambdaExpr::Traverse(TraversalCallback* cb) const
|
||||
|
|
15
src/Expr.h
15
src/Expr.h
|
@ -43,6 +43,7 @@ typedef enum {
|
|||
EXPR_IN,
|
||||
EXPR_LIST,
|
||||
EXPR_CALL,
|
||||
EXPR_LAMBDA,
|
||||
EXPR_EVENT,
|
||||
EXPR_SCHEDULE,
|
||||
EXPR_ARITH_COERCE,
|
||||
|
@ -952,15 +953,11 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
// Class to handle the creation of anonymous functions with closures.
|
||||
|
||||
// Facts:
|
||||
// - LambdaExpr creates a new BroFunc on every call to Eval.
|
||||
// - LambdaExpr must be given all the information to create a BroFunc on
|
||||
// construction except for the closure.
|
||||
// - The closure for created BroFuncs is the frame that the LambdaExpr is
|
||||
// evaluated in.
|
||||
|
||||
/**
|
||||
* Class that represents an anonymous function expression in Zeek.
|
||||
* On evaluation, captures the frame that it is evaluated in. This becomes
|
||||
* the closure for the instance of the function that it creates.
|
||||
*/
|
||||
class LambdaExpr : public Expr {
|
||||
public:
|
||||
LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
||||
|
|
12
src/Frame.cc
12
src/Frame.cc
|
@ -217,7 +217,7 @@ ClosureFrame::~ClosureFrame()
|
|||
|
||||
Val* ClosureFrame::GetElement(ID* id) const
|
||||
{
|
||||
if ( ClosureContains(id) )
|
||||
if ( CaptureContains(id) )
|
||||
return ClosureFrame::GatherFromClosure(this, id);
|
||||
|
||||
return this->NthElement(id->Offset());
|
||||
|
@ -225,7 +225,7 @@ Val* ClosureFrame::GetElement(ID* id) const
|
|||
|
||||
void ClosureFrame::SetElement(const ID* id, Val* v)
|
||||
{
|
||||
if ( ClosureContains(id) )
|
||||
if ( CaptureContains(id) )
|
||||
ClosureFrame::SetInClosure(this, id, v);
|
||||
else
|
||||
this->Frame::SetElement(id->Offset(), v);
|
||||
|
@ -250,7 +250,7 @@ Frame* ClosureFrame::SelectiveClone(id_list* choose)
|
|||
loop_over_list(*choose, i)
|
||||
{
|
||||
ID* we = (*choose)[i];
|
||||
if ( ClosureContains(we) )
|
||||
if ( CaptureContains(we) )
|
||||
us.append(we);
|
||||
else
|
||||
them.append(we);
|
||||
|
@ -282,7 +282,7 @@ Val* ClosureFrame::GatherFromClosure(const Frame* start, const ID* id)
|
|||
if ( ! conductor )
|
||||
return start->NthElement(id->Offset());
|
||||
|
||||
if (conductor->ClosureContains(id))
|
||||
if (conductor->CaptureContains(id))
|
||||
return ClosureFrame::GatherFromClosure(conductor->closure, id);
|
||||
|
||||
return conductor->NthElement(id->Offset());
|
||||
|
@ -295,14 +295,14 @@ void ClosureFrame::SetInClosure(Frame* start, const ID* id, Val* val)
|
|||
if ( ! conductor )
|
||||
start->SetElement(id->Offset(), val);
|
||||
|
||||
else if (conductor->ClosureContains(id))
|
||||
else if (conductor->CaptureContains(id))
|
||||
ClosureFrame::SetInClosure(conductor->closure, id, val);
|
||||
|
||||
else
|
||||
conductor->Frame::SetElement(id->Offset(), val);
|
||||
}
|
||||
|
||||
bool ClosureFrame::ClosureContains(const ID* i) const
|
||||
bool ClosureFrame::CaptureContains(const ID* i) const
|
||||
{
|
||||
const char* target = i->Name();
|
||||
return std::any_of(closure_elements.begin(), closure_elements.end(),
|
||||
|
|
29
src/Frame.h
29
src/Frame.h
|
@ -18,7 +18,8 @@ class Val;
|
|||
class Frame : public BroObj {
|
||||
public:
|
||||
Frame(int size, const BroFunc* func, const val_list *fn_args);
|
||||
// The constructed frame becomes a view of the input frame. No copying is done.
|
||||
// Constructs a copy or view of other. If a view is constructed the
|
||||
// destructor will not change other's state on deletion.
|
||||
Frame(const Frame* other, bool is_view = false);
|
||||
~Frame() override;
|
||||
|
||||
|
@ -95,19 +96,11 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
// Class that allows for lookups in both a closure frame and a regular frame
|
||||
// according to a list of outer IDs passed into the constructor.
|
||||
|
||||
// Facts:
|
||||
// - A ClosureFrame is created from two frames: a closure and a regular frame.
|
||||
// - ALL operations except Get/SetElement operations operate on the regular frame.
|
||||
// - A ClosureFrame requires a list of outside ID's captured by the closure.
|
||||
// - Get/Set operations on those IDs will be performed on the closure frame.
|
||||
|
||||
// ClosureFrame allows functions that generate functions to be passed between
|
||||
// different sized frames and still properly capture their closures. It also allows for
|
||||
// cleaner handling of closures.
|
||||
|
||||
/**
|
||||
* Class that allows for actions in both a regular frame and a closure frame
|
||||
* according to a list of outer IDs captured in the closure passed into the
|
||||
* constructor.
|
||||
*/
|
||||
class ClosureFrame : public Frame {
|
||||
public:
|
||||
ClosureFrame(Frame* closure, Frame* body,
|
||||
|
@ -122,14 +115,12 @@ private:
|
|||
Frame* closure;
|
||||
Frame* body;
|
||||
|
||||
// Searches the start frame and all sub-frame's closures for a value corresponding
|
||||
// to the id. Returns it when its found. Will fail with little grace if the value
|
||||
// does not actually exist in any of the sub-frames.
|
||||
// Both of these assume that it has already been verified that id is
|
||||
// in the start frame.
|
||||
static Val* GatherFromClosure(const Frame* start, const ID* id);
|
||||
// Moves through the closure frames and associates val with id.
|
||||
static void SetInClosure(Frame* start, const ID* id, Val* val);
|
||||
|
||||
bool ClosureContains(const ID* i) const;
|
||||
bool CaptureContains(const ID* i) const;
|
||||
|
||||
std::vector<const char*> closure_elements;
|
||||
};
|
||||
|
|
|
@ -530,7 +530,7 @@ std::unique_ptr<function_ingredients> gather_function_ingredients(Stmt* body)
|
|||
ingredients->priority = get_func_priotity(attrs);
|
||||
ingredients->body = body;
|
||||
|
||||
return std::move(ingredients);
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
Val* internal_val(const char* name)
|
||||
|
@ -555,7 +555,7 @@ std::shared_ptr<id_list> gather_outer_ids(Scope* scope, Stmt* body)
|
|||
for ( size_t i = 0; i < cb.outer_id_references.size(); ++i )
|
||||
idl->append(cb.outer_id_references[i]->Id());
|
||||
|
||||
return std::move(idl);
|
||||
return idl;
|
||||
}
|
||||
|
||||
Val* internal_const_val(const char* name)
|
||||
|
|
|
@ -26,8 +26,7 @@ extern void add_type(ID* id, BroType* t, attr_list* attr);
|
|||
extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||
int is_redef, FuncType* t, attr_list* attrs = nullptr);
|
||||
extern void end_func(Stmt* body);
|
||||
extern std::unique_ptr<function_ingredients>
|
||||
gather_function_ingredients(Stmt* body);
|
||||
extern std::unique_ptr<function_ingredients> gather_function_ingredients(Stmt* body);
|
||||
extern std::shared_ptr<id_list> gather_outer_ids(Scope* scope, Stmt* body);
|
||||
|
||||
extern Val* internal_val(const char* name);
|
||||
|
|
|
@ -31,7 +31,7 @@ expect: client
|
|||
client
|
||||
expect: client
|
||||
client
|
||||
expect: unknown-22. outside-5
|
||||
expect: unknown-33. outside-5
|
||||
unknown-33. outside-5
|
||||
|
||||
expect: unknown-11. outside-4
|
||||
|
@ -42,5 +42,5 @@ expect: client
|
|||
client
|
||||
expect: client
|
||||
client
|
||||
expect: unknown-22. outside-5
|
||||
expect: unknown-33. outside-5
|
||||
unknown-33. outside-5
|
||||
|
|
|
@ -102,7 +102,7 @@ event zeek_init()
|
|||
|
||||
print "expect: client";
|
||||
print dogs[3];
|
||||
print "expect: unknown-22. outside-5";
|
||||
print "expect: unknown-33. outside-5";
|
||||
print dogs[33];
|
||||
|
||||
print "";
|
||||
|
@ -126,7 +126,7 @@ event zeek_init()
|
|||
|
||||
print "expect: client";
|
||||
print dogs_also[3];
|
||||
print "expect: unknown-22. outside-5";
|
||||
print "expect: unknown-33. outside-5";
|
||||
print dogs_also[33];
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue