Author: chromatic
Date: Fri Jun 15 01:42:22 2007
New Revision: 19019
Modified:
trunk/src/pmc/sub.pmc
trunk/t/op/calling.t
Log:
[GC] Increase context refcount as necessary (RT #43006 and #42790, Bram Geron).
Modified: trunk/src/pmc/sub.pmc
==============================================================================
--- trunk/src/pmc/sub.pmc (original)
+++ trunk/src/pmc/sub.pmc Fri Jun 15 01:42:22 2007
@@ -279,11 +279,12 @@
/* set context of the sub */
sub->ctx = context;
- if (PObj_get_FLAGS(SELF) & SUB_FLAG_IS_OUTER) {
- /* don't destroy context */
+ /* don't destroy context */
+ if (PObj_get_FLAGS(SELF) & SUB_FLAG_IS_OUTER)
ccont->vtable = interp->vtables[enum_class_Continuation];
- context->ref_count++;
- }
+
+ /* reference counting should work */
+ context->ref_count++;
if (!PMC_IS_NULL(INTERP->current_object)) {
context->current_object = INTERP->current_object;
@@ -320,7 +321,7 @@
PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL;
context->caller_ctx = caller_ctx->caller_ctx;
- Parrot_free_context(INTERP, caller_ctx, 1);
+ Parrot_free_context(INTERP, caller_ctx, 0);
}
}
Modified: trunk/t/op/calling.t
==============================================================================
--- trunk/t/op/calling.t (original)
+++ trunk/t/op/calling.t Fri Jun 15 01:42:22 2007
@@ -7,7 +7,7 @@
use lib qw( . lib ../lib ../../lib );
use Test::More;
-use Parrot::Test tests => 94;
+use Parrot::Test tests => 95;
=head1 NAME
@@ -2408,6 +2408,45 @@
Have bar: 2
OUTPUT
+pir_output_is( <<'CODE', <<'OUTPUT', "Tail call without arguments should not
free the context when a closure depends on it" );
+.sub main :main
+ $P0 = create_closure_and_run_it()
+.end
+
+.sub create_closure_and_run_it
+ P0 = new "Integer"
+ P0 = 3
+ .lex "val", P0
+ P2 = get_global "myclosure"
+ P1 = newclosure P2
+ # There is a closure depending on our current context, so this shouldn't
+ # free it.
+ .return P1()
+.end
+
+.sub myclosure :outer(create_closure_and_run_it)
+ P1 = find_lex "val"
+ say P1
+ donothing()
+ P1 = find_lex "val"
+ say P1
+ .return ()
+.end
+
+.sub donothing
+ P0 = new "Integer"
+ P0 = 5
+ # This creates a new binding that is not accessible by the
+ # caller (myclosure)
+ .lex "val", P0
+ P2 = null
+ P1 = null
+.end
+CODE
+3
+3
+OUTPUT
+
# Local Variables:
# mode: cperl
# cperl-indent-level: 4