Merge remote-tracking branch 'origin/topic/zeke/closures'

This commit is contained in:
Robin Sommer 2019-07-29 22:07:40 +00:00
commit 13c373086d
47 changed files with 2537 additions and 511 deletions

View file

@ -4,10 +4,15 @@
#define func_h
#include <utility>
#include <memory>
#include <broker/data.hh>
#include <broker/expected.hh>
#include "BroList.h"
#include "Obj.h"
#include "Debug.h"
#include "Frame.h"
class Val;
class ListExpr;
@ -44,7 +49,7 @@ public:
// Add a new event handler to an existing function (event).
virtual void AddBody(Stmt* new_body, id_list* new_inits,
int new_frame_size, int priority = 0);
size_t new_frame_size, int priority = 0);
virtual void SetScope(Scope* newscope) { scope = newscope; }
virtual Scope* GetScope() const { return scope; }
@ -59,6 +64,8 @@ public:
void Describe(ODesc* d) const override = 0;
virtual void DescribeDebug(ODesc* d, const val_list* args) const;
virtual Func* DoClone();
virtual TraversalCode Traverse(TraversalCallback* cb) const;
uint32 GetUniqueFuncID() const { return unique_id; }
@ -68,6 +75,9 @@ public:
protected:
Func();
// Copies this function's state into other.
void CopyStateInto(Func* other) const;
// Helper function for handling result of plugin hook.
std::pair<bool, Val*> HandlePluginResult(std::pair<bool, Val*> plugin_result, val_list* args, function_flavor flavor) const;
@ -83,16 +93,41 @@ protected:
class BroFunc : public Func {
public:
BroFunc(ID* id, Stmt* body, id_list* inits, int frame_size, int priority);
BroFunc(ID* id, Stmt* body, id_list* inits, size_t frame_size, int priority);
~BroFunc() override;
int IsPure() const override;
Val* Call(val_list* args, Frame* parent) const override;
void AddBody(Stmt* new_body, id_list* new_inits, int new_frame_size,
int priority) override;
/**
* Adds adds a closure to the function. Closures are cloned and
* future calls to BroFunc methods will not modify *f*.
*
* @param ids IDs that are captured by the closure.
* @param f the closure to be captured.
*/
void AddClosure(id_list ids, Frame* f);
int FrameSize() const { return frame_size; }
/**
* Replaces the current closure with one built from *data*
*
* @param data a serialized closure
*/
bool UpdateClosure(const broker::vector& data);
/**
* Serializes this function's closure.
*
* @return a serialized version of the function's closure.
*/
broker::expected<broker::data> SerializeClosure() const;
void AddBody(Stmt* new_body, id_list* new_inits,
size_t new_frame_size, int priority) override;
/** Sets this function's outer_id list. */
void SetOuterIDs(id_list ids)
{ outer_ids = std::move(ids); }
void Describe(ODesc* d) const override;
@ -100,7 +135,26 @@ protected:
BroFunc() : Func(BRO_FUNC) {}
Stmt* AddInits(Stmt* body, id_list* inits);
int frame_size;
/**
* Clones this function along with its closures.
*/
Func* DoClone() override;
/**
* Performs a selective clone of *f* using the IDs that were
* captured in the function's closure.
*
* @param f the frame to be cloned.
*/
void SetClosureFrame(Frame* f);
private:
size_t frame_size;
// List of the outer IDs used in the function.
id_list outer_ids;
// The frame the BroFunc was initialized in.
Frame* closure = nullptr;
};
typedef Val* (*built_in_func)(Frame* frame, val_list* args);
@ -136,6 +190,17 @@ struct CallInfo {
const val_list* args;
};
// Struct that collects all the specifics defining a Func. Used for BroFuncs
// with closures.
struct function_ingredients {
ID* id;
Stmt* body;
id_list* inits;
int frame_size;
int priority;
Scope* scope;
};
extern vector<CallInfo> call_stack;
extern std::string render_call_stack();