From fc7ce090eaaf1f9afefedd20fb63ca4b3a41eb39 Mon Sep 17 00:00:00 2001 From: Teddy Date: Thu, 15 Aug 2013 22:26:31 +0800 Subject: fix mem leak in ext_repr --- model.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 21 deletions(-) (limited to 'model.h') diff --git a/model.h b/model.h index 797631d..ab5dcc6 100644 --- a/model.h +++ b/model.h @@ -10,7 +10,6 @@ using std::string; typedef unsigned char FrameType; typedef unsigned char NumLvl; -const int CLS_RET_ADDR = 1 << 0; const int CLS_EVAL_OBJ = 1 << 1; const int CLS_PAR_BRA = 1 << 2; @@ -21,11 +20,10 @@ const int CLS_CONTAINER = 1 << 20; #define TO_PAIR(ptr) \ (static_cast(ptr)) - /** @class FrameObj - * Objects that can be held in the evaluation stack + * Objects that can be held in the parsing stack */ -class FrameObj { +class FrameObj {/*{{{*/ protected: /** * Report the type of the FrameObj, which can avoid the use of @@ -34,19 +32,21 @@ class FrameObj { FrameType ftype; public: /** - * Construct an EvalObj - * @param ftype the type of the FrameObj (CLS_EVAL_OBJ for an EvalObj, - * CLS_RET_ADDR for a return address) + * Construct a FrameObj + * @param ftype describes the type of the FrameObj (CLS_EVAL_OBJ for an EvalObj, + * CLS_PAR_BRA for a bracket) */ FrameObj(FrameType ftype); + /** + * The destructor + */ virtual ~FrameObj() {} /** * Tell whether the object is a bracket, according to ftype * @return true for yes */ bool is_parse_bracket(); -}; - +};/*}}}*/ class ObjEntry; class Pair; @@ -54,7 +54,7 @@ class ReprCons; /** @class EvalObj * Objects that represents a value in evaluation */ -class EvalObj : public FrameObj { +class EvalObj : public FrameObj {/*{{{*/ protected: /** * Report the type of the EvalObj, which can avoid the use of @@ -62,25 +62,31 @@ class EvalObj : public FrameObj { */ int otype; public: - ObjEntry *gc_obj; + /** + * The pointer to the corresponding record in GC + */ + ObjEntry *gc_rec; /** * Construct an EvalObj - * @param otype the type of the EvalObj (CLS_PAIR_OBJ for a - * construction, CLS_SIM_OBJ for a simple object), which defaults to - * CLS_SIM_OBJ + * @param otype the type of the EvalObj (CLS_PAIR_OBJ for a pair, + * CLS_SIM_OBJ for a simple object), which defaults to CLS_SIM_OBJ, etc. */ EvalObj(int otype = CLS_SIM_OBJ); + /** + * The destructor + */ ~EvalObj(); /** Check if the object is a simple object (instead of a call * invocation) - * @return true if the object is not a construction (Pair) + * @return true if the object is not a pair or an empty list * */ bool is_simple_obj(); /** Check if the object is a symobl */ bool is_sym_obj(); /** Check if the object is an operator */ bool is_opt_obj(); - /** Check if the object is a Pair */ + /** Check if the object is a pair (notice that an empty list does + * not counts as a pair here) */ bool is_pair_obj(); /** Check if the object is a number */ bool is_num_obj(); @@ -92,34 +98,57 @@ class EvalObj : public FrameObj { bool is_prom_obj(); /** Check if the object is a vector */ bool is_vect_obj(); + /** Check if the object is a container */ bool is_container(); + /** Get `otype`, used by some routines for efficiency issues */ int get_otype(); + /** Dummy function, actually used by OptObj, called before the actual + * invocation */ virtual void prepare(Pair *pc); /** Any EvalObj has its external representation */ string ext_repr(); - /** Always true for all EvalObjs except BoolObj */ + /** Always true for all other EvalObjs except BoolObj */ virtual bool is_true(); - /** External representation construction */ + /** External representation construction, used by `ext_repr()` */ virtual ReprCons *get_repr_cons() = 0; -}; +};/*}}}*/ /** @class ParseBracket * To indiate a left bracket when parsing, used in the parse_stack */ class ParseBracket : public FrameObj {/*{{{*/ public: - unsigned char btype; /**< The type of the bracket */ + /** The type of the bracket */ + unsigned char btype; /** Construct a ParseBracket object */ ParseBracket(unsigned char btype); };/*}}}*/ +/** @class Container + * Describes the kind of EvalObjs which may cause circular reference issue, + * different from some "direct" objects, such as BoolObj, NumberObj... + */ class Container: public EvalObj {/*{{{*/ public: - bool keep; + /** true if the object is still in use, its value is set and read temporarily, + * check `gc.cpp` */ + bool keep; + /** the counter used when resolving circular references, see `gc.cpp` */ size_t gc_refs; + /** Constructor, does an "or" bit operation on the otype provided by + * its subclasses, i.e. to mark CLS_CONTAINER. + * The mark will not be not enforced if the `override` is + * true. */ Container(int otype = 0, bool override = false); + /** + * Decrease the gc_refs of the objects referenced by this container. + * Used by circular ref resolver to detect the cycle. + */ virtual void gc_decrement() = 0; + /** Push the objects referenced by this container to the queue via the pointer `tail`. Used in the phase of + * marking `keep`. + */ virtual void gc_trigger(EvalObj ** &tail) = 0; };/*}}}*/ -- cgit v1.2.3