Move catch for function recursion detection.

Catching this at ModuleInstantiation::evaluate() should ensure the whole
function call is terminated with the first exception. Otherwise function
calls with multiple recursion points (e.g. function f(x) = f(x) + f(x);)
will still descent into the recursion multiple times.
master
Torsten Paul 2014-12-04 19:40:15 +01:00
parent b894166dea
commit 407da2ea8c
3 changed files with 16 additions and 8 deletions

View File

@ -162,6 +162,14 @@ bool Context::has_local_variable(const std::string &name) const
return variables.find(name) != variables.end();
}
/**
* This is separated because PRINTB uses quite a lot of stack space
* and the methods using it evaluate_function() and instantiate_module()
* are called often when recursive functions or modules are evaluated.
*
* @param what what is ignored
* @param name name of the ignored object
*/
static void print_ignore_warning(const char *what, const char *name)
{
PRINTB("WARNING: Ignoring unknown %s '%s'.", what % name);

View File

@ -27,12 +27,7 @@ ValuePtr EvalContext::getArgValue(size_t i, const Context *ctx) const
const Assignment &arg = this->eval_arguments[i];
ValuePtr v;
if (arg.second) {
try {
v = arg.second->evaluate(ctx ? ctx : this);
}
catch (RecursionException &e) {
PRINT(e.what());
}
v = arg.second->evaluate(ctx ? ctx : this);
}
return v;
}

View File

@ -153,8 +153,13 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const
PRINT("New eval ctx:");
c.dump(NULL, this);
#endif
AbstractNode *node = ctx->instantiate_module(*this, &c); // Passes c as evalctx
return node;
try {
AbstractNode *node = ctx->instantiate_module(*this, &c); // Passes c as evalctx
return node;
} catch (RecursionException &e) {
PRINT(e.what());
return NULL;
}
}
std::vector<AbstractNode*> ModuleInstantiation::instantiateChildren(const Context *evalctx) const