//
// (C) Copyright 2011-2012 Sergey A. Babkin.
// This file is a part of Triceps.
// See the file COPYRIGHT for the copyright notice and license information
//
//
// The mark for Unit's execution frame.
#ifndef __Triceps_FrameMark_h__
#define __Triceps_FrameMark_h__
#include <common/Common.h>
namespace TRICEPS_NS {
class Unit;
class UnitFrame;
// The FrameMark is used to mark the frame where a loop starts,
// to later fork there the records for the next iteration of the loop.
class FrameMark : public Starget
{
friend class Unit;
friend class UnitFrame;
public:
FrameMark(const string &name) :
name_(name),
unit_(NULL),
frame_(NULL)
{ }
~FrameMark()
{
assert(frame_ == NULL);
}
const string &getName() const
{
return name_;
}
// A way for unit to check that the mark points to it.
// Also used in XS code.
Unit *getUnit() const
{
return unit_;
}
protected:
string name_;
// if frame_ is NULL, unit_ and next_ are also guaranteed to be NULL
Unit *unit_; // where the mark points, gets set together with frame_
UnitFrame *frame_; // what is marked (not Autoref, to avoid circular references)
Autoref <FrameMark> next_; // there may be multiple marks on a frame, forming a list
///////////// API for Unit ///////////////////////////////
// Clear recursively the whole list of marks starting from this mark.
// When a frame gets popped, it uses this function to clear all its marks.
void clear();
// Reset this mark to NULLs.
void reset()
{
next_ = NULL;
frame_ = NULL;
unit_ = NULL;
}
// Go recursively through the list and drop a mark from it.
// When a mark that is still active gets reused, it is removed
// from the old list before being put onto the new list.
//
// @param what - the mark to remove from the list
void dropFromList(FrameMark *what);
// Add this mark to a frame's list.
// @param unit - unit owning the frame
// @param frame - frame where it's added
// @param list - the previous contents of the frame's list
void set(Unit *unit, UnitFrame *frame, Onceref<FrameMark> list)
{
frame_ = frame;
unit_ = unit;
next_ = list;
}
// A way for the Unit to find, what frame is marked.
UnitFrame *getFrame() const
{
return frame_;
}
private:
FrameMark(const FrameMark &);
void operator=(const FrameMark &);
};
}; // TRICEPS_NS
#endif // __Triceps_FrameMark_h__