From 0690c1c9c01dd5889dbfccf2da6cb99f5c4e151b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 3 Nov 2003 20:30:40 +0000 Subject: * Work around problems with the ATerm library. The ATerm library doesn't search the heap for pointers to ATerms when garbage collecting. As a result, C++ containers such as `map' will cause pointer to be hidden from the garbage collector, causing crashes. Instead, we now use ATermTables. --- src/fix-ng/eval.cc | 56 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 22 deletions(-) (limited to 'src/fix-ng/eval.cc') diff --git a/src/fix-ng/eval.cc b/src/fix-ng/eval.cc index 726bc5daeb..90b7ff29f2 100644 --- a/src/fix-ng/eval.cc +++ b/src/fix-ng/eval.cc @@ -5,6 +5,7 @@ EvalState::EvalState() + : normalForms(32768, 75) { blackHole = ATmake("BlackHole()"); if (!blackHole) throw Error("cannot build black hole"); @@ -20,32 +21,43 @@ Expr getAttr(EvalState & state, Expr e, const string & name) /* Substitute an argument set into the body of a function. */ static Expr substArgs(Expr body, ATermList formals, Expr arg) { - Subs subs; + ATermMap subs; Expr undefined = ATmake("Undefined"); /* Get the formal arguments. */ while (!ATisEmpty(formals)) { + ATerm t = ATgetFirst(formals); char * s; - if (!ATmatch(ATgetFirst(formals), "", &s)) + if (!ATmatch(t, "", &s)) abort(); /* can't happen */ - subs[s] = undefined; + subs.set(t, undefined); formals = ATgetNext(formals); } /* Get the actual arguments, and check that they match with the formals. */ - Attrs args; + ATermMap args; queryAllAttrs(arg, args); - for (Attrs::iterator i = args.begin(); i != args.end(); i++) { - if (subs.find(i->first) == subs.end()) - throw badTerm(format("argument `%1%' not declared") % i->first, arg); - subs[i->first] = i->second; + for (ATermList keys = args.keys(); !ATisEmpty(keys); + keys = ATgetNext(keys)) + { + Expr key = ATgetFirst(keys); + Expr cur = subs.get(key); + if (!cur) + throw badTerm(format("argument `%1%' not declared") + % aterm2String(key), arg); + subs.set(key, args.get(key)); } /* Check that all arguments are defined. */ - for (Subs::iterator i = subs.begin(); i != subs.end(); i++) - if (i->second == undefined) - throw badTerm(format("formal argument `%1%' missing") % i->first, arg); + for (ATermList keys = subs.keys(); !ATisEmpty(keys); + keys = ATgetNext(keys)) + { + Expr key = ATgetFirst(keys); + if (subs.get(key) == undefined) + throw badTerm(format("formal argument `%1%' missing") + % aterm2String(key), arg); + } return substitute(subs, body); } @@ -59,26 +71,26 @@ static Expr substArgs(Expr body, ATermList formals, Expr arg) ATerm expandRec(ATerm e, ATermList bnds) { /* Create the substitution list. */ - Subs subs; + ATermMap subs; ATermList bs = bnds; while (!ATisEmpty(bs)) { char * s; Expr e2; if (!ATmatch(ATgetFirst(bs), "Bind(, )", &s, &e2)) abort(); /* can't happen */ - subs[s] = ATmake("Select(, )", e, s); + subs.set(s, ATmake("Select(, )", e, s)); bs = ATgetNext(bs); } /* Create the non-recursive set. */ - Attrs as; + ATermMap as; bs = bnds; while (!ATisEmpty(bs)) { char * s; Expr e2; if (!ATmatch(ATgetFirst(bs), "Bind(, )", &s, &e2)) abort(); /* can't happen */ - as[s] = substitute(subs, e2); + as.set(s, substitute(subs, e2)); bs = ATgetNext(bs); } @@ -205,18 +217,18 @@ Expr evalExpr(EvalState & state, Expr e) /* Consult the memo table to quickly get the normal form of previously evaluated expressions. */ - NormalForms::iterator i = state.normalForms.find(e); - if (i != state.normalForms.end()) { - if (i->second == state.blackHole) + Expr nf = state.normalForms.get(e); + if (nf) { + if (nf == state.blackHole) throw badTerm("infinite recursion", e); state.nrCached++; - return i->second; + return nf; } /* Otherwise, evaluate and memoize. */ - state.normalForms[e] = state.blackHole; - Expr nf = evalExpr2(state, e); - state.normalForms[e] = nf; + state.normalForms.set(e, state.blackHole); + nf = evalExpr2(state, e); + state.normalForms.set(e, nf); return nf; } -- cgit 1.4.1