$ ./miniperl -e 'DESTROY{warn "destruction"} sub foo { bless([]), return $x } scalar foo, warn outside' outside at -e line 1. destruction at -e line 1. $ ./miniperl -e 'DESTROY{warn "destruction"} sub foo { if(shift) { bless([]), return $x } else { foo(1) } } scalar foo, warn outside' destruction at -e line 1. outside at -e line 1. Why, in the first example, does the value leak out of the subroutine before being destroyed, whereas in the second case it is destroyed on sub exit? What is the reasoning behind it? Commit a29cdaf07aa5 introduced the FREETMPS calls in pp_leavesub and pp_return: commit a29cdaf07aa5601e42ae4955cc0f168e91a7c385 Author: Ilya Zakharevich <ilya@math.berkeley.edu> Date: Sat Jun 20 17:45:03 1998 -0400 Avoid temporaries on recursion Message-Id: <199806210145.VAA21629@monk.mps.ohio-state.edu> p4raw-id: //depot/perl@1187 (Commit 959e367355 added the refcnt tricks to prevent things from being freed prematurely.) nntp.perl.org doesn’t have that message, so I can’t find out the reasoning behind it (i.e., why it only applies to recursion). I suspect that the most common case (no recursion) needs to be kept fast, while recursive calls could accumulate a lot of temps. But I don’t see why nested calls to different subroutines wouldn’t likewise accumulate a lot of them. I bring this up because I noticed that the lvalue-returning code (which was in pp_hot.c:pp_leavesublv in 5.14.0, but is now in pp_ctl.c:S_return_lvalues) doesn’t call FREETMPS in lvalue context. I was trying to figure out why. I was going to write a test for it and then make it do so, when I encountered the discrepancy noted above.Thread Next