Changeset 0aab93ba05631253155d0cdd5059158cae7f269b

Show
Ignore:
Timestamp:
09/23/09 20:36:22 (3 years ago)
Author:
Antti-Juhani Kaijanaho <antti-juhani@…>
Children:
97ce4926752779cac0f6b8494b0cfdf096ee15f4
Parents:
130a42d34f091a92300eb9988d79070c9cd22deb
git-committer:
Antti-Juhani Kaijanaho <antti-juhani@…> (09/23/09 20:36:22)
Message:

[tlate::def] Set a limit to how many times a function can be called

The limit is of course arbitrary. The aim here is to protect against
overflowing the call stack with unbounded recursion in the template.

The downside of this fix is that it limits non-recursive calls as well.

A better fix would involve converting the evaluator into a bytecode
interpreter with an explicit call stack (this would allow monitoring
the actual stack usage instead of an indirect measure of calls).

Completes the fix of #12.

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

Location:
tlate
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • tlate/def.cc

    r26b574e r0aab93b  
    3333        class closure : public value  
    3434        { 
     35                std::string name; 
    3536                std::vector<std::string> parms; 
    3637                seq::ptr body; 
    3738                structured_value::ptr senv; 
     39                mutable size_t &eval_count; 
    3840                std::string fname; 
    3941                int line; 
     
    4244                typedef boost::shared_ptr<const closure> const_ptr; 
    4345 
    44                 closure(std::vector<std::string> parms, 
     46                closure(std::string name, 
     47                        std::vector<std::string> parms, 
    4548                        seq::ptr body, 
    4649                        structured_value::ptr senv, 
     50                        size_t &eval_count, 
    4751                        std::string fname, 
    4852                        int line) 
    49                         : parms(parms) 
     53                        : name(name) 
     54                        , parms(parms) 
    5055                        , body(body) 
    5156                        , senv(senv) 
     57                        , eval_count(eval_count) 
    5258                        , fname(fname) 
    5359                        , line(line) 
     
    6369                                       std::string fname, int line) const 
    6470        { 
     71                if (eval_count++ > 5000) 
     72                { 
     73                        logger::logline ll; 
     74                        ll << this->fname << ":" << this->line  
     75                           << ": too many calls to " << name; 
     76                        return empty_value::instance(); 
     77                } 
    6578                overriding_structured_value::ptr env 
    6679                        (new overriding_structured_value(senv)); 
     
    89102        def::def(scanner &sc) 
    90103                : tlate(sc.peekFileName(), sc.peekLineNo()) 
     104                , eval_count(0) 
    91105        { 
    92106                /* 
     
    132146                     it != bodyfvs.end(); it++) 
    133147                        senv->insert(*it, env->get(*it)); 
    134                 value::ptr cl(new closure(parms, body, senv, fname, line)); 
     148                value::ptr cl(new closure(name, parms, body, senv, eval_count, 
     149                                          fname, line)); 
    135150                senv->insert(name, cl); 
    136151                env->override(name, cl); 
  • tlate/def.hh

    r26b574e r0aab93b  
    3838                seq::ptr body; 
    3939                std::set<std::string> bodyfvs; 
     40                size_t eval_count; 
    4041        public: 
    4142                typedef boost::shared_ptr<def> ptr;