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
|
11
src/Expr.cc
11
src/Expr.cc
|
@ -30,7 +30,7 @@ const char* expr_name(BroExprTag t)
|
||||||
"=", "~", "[]", "$", "?$", "[=]",
|
"=", "~", "[]", "$", "?$", "[=]",
|
||||||
"table()", "set()", "vector()",
|
"table()", "set()", "vector()",
|
||||||
"$=", "in", "<<>>",
|
"$=", "in", "<<>>",
|
||||||
"()", "event", "schedule",
|
"()", "function()", "event", "schedule",
|
||||||
"coerce", "record_coerce", "table_coerce",
|
"coerce", "record_coerce", "table_coerce",
|
||||||
"sizeof", "flatten", "cast", "is", "[:]="
|
"sizeof", "flatten", "cast", "is", "[:]="
|
||||||
};
|
};
|
||||||
|
@ -4323,7 +4323,7 @@ void CallExpr::ExprDescribe(ODesc* d) const
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
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->ingredients = std::move(ingredients);
|
||||||
this->outer_ids = std::move(outer_ids);
|
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
|
Val* LambdaExpr::Eval(Frame* f) const
|
||||||
{
|
{
|
||||||
|
reporter->Warning("eval lambda");
|
||||||
BroFunc* lamb = new BroFunc(
|
BroFunc* lamb = new BroFunc(
|
||||||
ingredients->id,
|
ingredients->id,
|
||||||
ingredients->body,
|
ingredients->body,
|
||||||
|
@ -4347,10 +4348,8 @@ Val* LambdaExpr::Eval(Frame* f) const
|
||||||
|
|
||||||
void LambdaExpr::ExprDescribe(ODesc* d) const
|
void LambdaExpr::ExprDescribe(ODesc* d) const
|
||||||
{
|
{
|
||||||
d->Add("Lambda Expression");
|
d->Add(expr_name(Tag()));
|
||||||
d->Add("{");
|
ingredients->body->Describe(d);
|
||||||
ingredients->body->Describe(d);
|
|
||||||
d->Add("}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TraversalCode LambdaExpr::Traverse(TraversalCallback* cb) const
|
TraversalCode LambdaExpr::Traverse(TraversalCallback* cb) const
|
||||||
|
|
15
src/Expr.h
15
src/Expr.h
|
@ -43,6 +43,7 @@ typedef enum {
|
||||||
EXPR_IN,
|
EXPR_IN,
|
||||||
EXPR_LIST,
|
EXPR_LIST,
|
||||||
EXPR_CALL,
|
EXPR_CALL,
|
||||||
|
EXPR_LAMBDA,
|
||||||
EXPR_EVENT,
|
EXPR_EVENT,
|
||||||
EXPR_SCHEDULE,
|
EXPR_SCHEDULE,
|
||||||
EXPR_ARITH_COERCE,
|
EXPR_ARITH_COERCE,
|
||||||
|
@ -952,15 +953,11 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Class to handle the creation of anonymous functions with closures.
|
/**
|
||||||
|
* Class that represents an anonymous function expression in Zeek.
|
||||||
// Facts:
|
* On evaluation, captures the frame that it is evaluated in. This becomes
|
||||||
// - LambdaExpr creates a new BroFunc on every call to Eval.
|
* the closure for the instance of the function that it creates.
|
||||||
// - 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 LambdaExpr : public Expr {
|
class LambdaExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
LambdaExpr(std::unique_ptr<function_ingredients> ingredients,
|
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
|
Val* ClosureFrame::GetElement(ID* id) const
|
||||||
{
|
{
|
||||||
if ( ClosureContains(id) )
|
if ( CaptureContains(id) )
|
||||||
return ClosureFrame::GatherFromClosure(this, id);
|
return ClosureFrame::GatherFromClosure(this, id);
|
||||||
|
|
||||||
return this->NthElement(id->Offset());
|
return this->NthElement(id->Offset());
|
||||||
|
@ -225,7 +225,7 @@ Val* ClosureFrame::GetElement(ID* id) const
|
||||||
|
|
||||||
void ClosureFrame::SetElement(const ID* id, Val* v)
|
void ClosureFrame::SetElement(const ID* id, Val* v)
|
||||||
{
|
{
|
||||||
if ( ClosureContains(id) )
|
if ( CaptureContains(id) )
|
||||||
ClosureFrame::SetInClosure(this, id, v);
|
ClosureFrame::SetInClosure(this, id, v);
|
||||||
else
|
else
|
||||||
this->Frame::SetElement(id->Offset(), v);
|
this->Frame::SetElement(id->Offset(), v);
|
||||||
|
@ -250,7 +250,7 @@ Frame* ClosureFrame::SelectiveClone(id_list* choose)
|
||||||
loop_over_list(*choose, i)
|
loop_over_list(*choose, i)
|
||||||
{
|
{
|
||||||
ID* we = (*choose)[i];
|
ID* we = (*choose)[i];
|
||||||
if ( ClosureContains(we) )
|
if ( CaptureContains(we) )
|
||||||
us.append(we);
|
us.append(we);
|
||||||
else
|
else
|
||||||
them.append(we);
|
them.append(we);
|
||||||
|
@ -282,7 +282,7 @@ Val* ClosureFrame::GatherFromClosure(const Frame* start, const ID* id)
|
||||||
if ( ! conductor )
|
if ( ! conductor )
|
||||||
return start->NthElement(id->Offset());
|
return start->NthElement(id->Offset());
|
||||||
|
|
||||||
if (conductor->ClosureContains(id))
|
if (conductor->CaptureContains(id))
|
||||||
return ClosureFrame::GatherFromClosure(conductor->closure, id);
|
return ClosureFrame::GatherFromClosure(conductor->closure, id);
|
||||||
|
|
||||||
return conductor->NthElement(id->Offset());
|
return conductor->NthElement(id->Offset());
|
||||||
|
@ -295,14 +295,14 @@ void ClosureFrame::SetInClosure(Frame* start, const ID* id, Val* val)
|
||||||
if ( ! conductor )
|
if ( ! conductor )
|
||||||
start->SetElement(id->Offset(), val);
|
start->SetElement(id->Offset(), val);
|
||||||
|
|
||||||
else if (conductor->ClosureContains(id))
|
else if (conductor->CaptureContains(id))
|
||||||
ClosureFrame::SetInClosure(conductor->closure, id, val);
|
ClosureFrame::SetInClosure(conductor->closure, id, val);
|
||||||
|
|
||||||
else
|
else
|
||||||
conductor->Frame::SetElement(id->Offset(), val);
|
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();
|
const char* target = i->Name();
|
||||||
return std::any_of(closure_elements.begin(), closure_elements.end(),
|
return std::any_of(closure_elements.begin(), closure_elements.end(),
|
||||||
|
|
31
src/Frame.h
31
src/Frame.h
|
@ -18,8 +18,9 @@ class Val;
|
||||||
class Frame : public BroObj {
|
class Frame : public BroObj {
|
||||||
public:
|
public:
|
||||||
Frame(int size, const BroFunc* func, const val_list *fn_args);
|
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
|
||||||
Frame(const Frame* other, bool is_view = false);
|
// destructor will not change other's state on deletion.
|
||||||
|
Frame(const Frame* other, bool is_view = false);
|
||||||
~Frame() override;
|
~Frame() override;
|
||||||
|
|
||||||
Val* NthElement(int n) const { return frame[n]; }
|
Val* NthElement(int n) const { return frame[n]; }
|
||||||
|
@ -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.
|
* 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
|
||||||
// Facts:
|
* constructor.
|
||||||
// - 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 ClosureFrame : public Frame {
|
class ClosureFrame : public Frame {
|
||||||
public:
|
public:
|
||||||
ClosureFrame(Frame* closure, Frame* body,
|
ClosureFrame(Frame* closure, Frame* body,
|
||||||
|
@ -122,14 +115,12 @@ private:
|
||||||
Frame* closure;
|
Frame* closure;
|
||||||
Frame* body;
|
Frame* body;
|
||||||
|
|
||||||
// Searches the start frame and all sub-frame's closures for a value corresponding
|
// Both of these assume that it has already been verified that id is
|
||||||
// to the id. Returns it when its found. Will fail with little grace if the value
|
// in the start frame.
|
||||||
// does not actually exist in any of the sub-frames.
|
|
||||||
static Val* GatherFromClosure(const Frame* start, const ID* id);
|
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);
|
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;
|
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->priority = get_func_priotity(attrs);
|
||||||
ingredients->body = body;
|
ingredients->body = body;
|
||||||
|
|
||||||
return std::move(ingredients);
|
return ingredients;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* internal_val(const char* name)
|
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 )
|
for ( size_t i = 0; i < cb.outer_id_references.size(); ++i )
|
||||||
idl->append(cb.outer_id_references[i]->Id());
|
idl->append(cb.outer_id_references[i]->Id());
|
||||||
|
|
||||||
return std::move(idl);
|
return idl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* internal_const_val(const char* name)
|
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,
|
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, FuncType* t, attr_list* attrs = nullptr);
|
||||||
extern void end_func(Stmt* body);
|
extern void end_func(Stmt* body);
|
||||||
extern std::unique_ptr<function_ingredients>
|
extern std::unique_ptr<function_ingredients> gather_function_ingredients(Stmt* body);
|
||||||
gather_function_ingredients(Stmt* body);
|
|
||||||
extern std::shared_ptr<id_list> gather_outer_ids(Scope* scope, Stmt* body);
|
extern std::shared_ptr<id_list> gather_outer_ids(Scope* scope, Stmt* body);
|
||||||
|
|
||||||
extern Val* internal_val(const char* name);
|
extern Val* internal_val(const char* name);
|
||||||
|
|
|
@ -31,7 +31,7 @@ expect: client
|
||||||
client
|
client
|
||||||
expect: client
|
expect: client
|
||||||
client
|
client
|
||||||
expect: unknown-22. outside-5
|
expect: unknown-33. outside-5
|
||||||
unknown-33. outside-5
|
unknown-33. outside-5
|
||||||
|
|
||||||
expect: unknown-11. outside-4
|
expect: unknown-11. outside-4
|
||||||
|
@ -42,5 +42,5 @@ expect: client
|
||||||
client
|
client
|
||||||
expect: client
|
expect: client
|
||||||
client
|
client
|
||||||
expect: unknown-22. outside-5
|
expect: unknown-33. outside-5
|
||||||
unknown-33. outside-5
|
unknown-33. outside-5
|
||||||
|
|
|
@ -102,7 +102,7 @@ event zeek_init()
|
||||||
|
|
||||||
print "expect: client";
|
print "expect: client";
|
||||||
print dogs[3];
|
print dogs[3];
|
||||||
print "expect: unknown-22. outside-5";
|
print "expect: unknown-33. outside-5";
|
||||||
print dogs[33];
|
print dogs[33];
|
||||||
|
|
||||||
print "";
|
print "";
|
||||||
|
@ -126,7 +126,7 @@ event zeek_init()
|
||||||
|
|
||||||
print "expect: client";
|
print "expect: client";
|
||||||
print dogs_also[3];
|
print dogs_also[3];
|
||||||
print "expect: unknown-22. outside-5";
|
print "expect: unknown-33. outside-5";
|
||||||
print dogs_also[33];
|
print dogs_also[33];
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue