diff options
author | Brandon Black <blblack@gmail.com> | 2007-06-28 10:58:32 -0500 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2007-06-29 08:29:09 +0000 |
commit | fdef73f9d3c637571d3ab9a9d73990f87b1ad2d9 (patch) | |
tree | 5bedbff7fdf57eee6981ad2852d233375db48f84 | |
parent | 3cd6a7dc6a90f93ec089ff4d02e1086c787c8c3f (diff) | |
download | perl-fdef73f9d3c637571d3ab9a9d73990f87b1ad2d9.tar.gz |
Re: valgrind findings
From: "Brandon Black" <blblack@gmail.com>
Message-ID: <84621a60706281358o3b379b20k2c1e53566587d79b@mail.gmail.com>
p4raw-id: //depot/perl@31501
-rw-r--r-- | mro.c | 15 |
1 files changed, 11 insertions, 4 deletions
@@ -87,6 +87,7 @@ AV* Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level) { AV* retval; + AV* tmp_retval; /* mortal to avoid leaks */ GV** gvp; GV* gv; AV* av; @@ -113,8 +114,8 @@ Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level) /* not in cache, make a new one */ - retval = newAV(); - av_push(retval, newSVpv(stashname, 0)); /* add ourselves at the top */ + tmp_retval = (AV*)sv_2mortal((SV*)newAV()); + av_push(tmp_retval, newSVpv(stashname, 0)); /* add ourselves at the top */ /* fetch our @ISA */ gvp = (GV**)hv_fetchs(stash, "ISA", FALSE); @@ -146,7 +147,9 @@ Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level) } else { /* otherwise, recurse into ourselves for the MRO - of this @ISA member, and append their MRO to ours */ + of this @ISA member, and append their MRO to ours. + The recursive call could throw an exception, which + has memory management implications here (tmp_retval) */ const AV *const subrv = mro_get_linear_isa_dfs(basestash, level + 1); @@ -157,12 +160,16 @@ Perl_mro_get_linear_isa_dfs(pTHX_ HV *stash, I32 level) SV *const subsv = *subrv_p++; if(!hv_exists_ent(stored, subsv, 0)) { hv_store_ent(stored, subsv, &PL_sv_undef, 0); - av_push(retval, newSVsv(subsv)); + av_push(tmp_retval, newSVsv(subsv)); } } } } + /* make the real retval out of tmp_retval, now that we're + past the exception dangers */ + retval = av_make(AvFILLp(tmp_retval)+1, AvARRAY(tmp_retval)); + /* we don't want anyone modifying the cache entry but us, and we do so by replacing it completely */ SvREADONLY_on(retval); |