[pure-lang-svn] SF.net SVN: pure-lang: [124] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-05-24 18:14:02
|
Revision: 124 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=124&view=rev Author: agraef Date: 2008-05-24 11:14:05 -0700 (Sat, 24 May 2008) Log Message: ----------- Fix memory allocation bugs in exception handling. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/runtime.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-24 18:12:16 UTC (rev 123) +++ pure/trunk/interpreter.cc 2008-05-24 18:14:05 UTC (rev 124) @@ -437,7 +437,7 @@ globals g; save_globals(g); pure_expr *e, *res = eval(x, e); - if (!res && e) pure_freenew(e); + if (!res && e) pure_free(e); restore_globals(g); return res; } @@ -462,7 +462,7 @@ globals g; save_globals(g); pure_expr *e, *res = defn(pat, x, e); - if (!res && e) pure_freenew(e); + if (!res && e) pure_free(e); restore_globals(g); return res; } @@ -744,7 +744,7 @@ if (e) { msg << "unhandled exception '" << e << "' while evaluating '" << *x << "'"; - pure_freenew(e); + pure_free(e); } else msg << "unhandled exception while evaluating '" << *x << "'"; throw err(msg.str()); @@ -769,7 +769,7 @@ if (e) { msg << "unhandled exception '" << e << "' while evaluating '" << "let " << r->lhs << " = " << r->rhs << "'"; - pure_freenew(e); + pure_free(e); } else msg << "failed match while evaluating '" << "let " << r->lhs << " = " << r->rhs << "'"; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-05-24 18:12:16 UTC (rev 123) +++ pure/trunk/runtime.cc 2008-05-24 18:14:05 UTC (rev 124) @@ -612,10 +612,7 @@ abort(); // no exception handler, bail out else { interp.estk.front().e = e; - if (e) { - assert(e->refc > 0); - pure_unref_internal(e); - } + assert(!e || e->refc > 0); longjmp(interp.estk.front().jmp, 1); } } @@ -672,21 +669,25 @@ size_t sz = interp.estk.front().sz; pure_expr *e = interp.estk.front().e; interp.estk.pop_front(); + assert(!e || e->refc > 0); + // make sure that we don't accidentally collect the exception value + if (e) e->refc++; // collect garbage pure_expr *tmps = interp.tmps; while (tmps) { pure_expr *next = tmps->xp; - if (tmps != e) pure_freenew(tmps); + pure_freenew(tmps); tmps = next; } for (size_t i = interp.sstk_sz; i-- > sz; ) if (interp.sstk[i] && interp.sstk[i]->refc > 0) pure_free_internal(interp.sstk[i]); interp.sstk_sz = sz; - if (!e) e = pure_const(interp.symtab.void_sym().f); - assert(e); - pure_unref_internal(h); - pure_expr *res = pure_apply2(h, e); + if (e && e->refc > 1) e->refc--; + if (!e) + e = pure_new_internal(pure_const(interp.symtab.void_sym().f)); + assert(e && e->refc > 0); + pure_expr *res = pure_apply(h, e); assert(res); res->refc++; pure_free_internal(x); @@ -742,17 +743,21 @@ size_t sz = interp.estk.front().sz; e = interp.estk.front().e; interp.estk.pop_front(); + assert(!e || e->refc > 0); + // make sure that we don't accidentally collect the exception value + if (e) e->refc++; // collect garbage pure_expr *tmps = interp.tmps; while (tmps) { pure_expr *next = tmps->xp; - if (tmps != e) pure_freenew(tmps); + pure_freenew(tmps); tmps = next; } for (size_t i = interp.sstk_sz; i-- > sz; ) if (interp.sstk[i] && interp.sstk[i]->refc > 0) pure_free_internal(interp.sstk[i]); interp.sstk_sz = sz; + if (e && e->refc > 1) e->refc--; MEMDEBUG_SUMMARY(e) return 0; } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |