Ticket #950: gc.t--patch

File gc.t--patch, 17.4 KB (added by jrtayloriv, 12 years ago)

Finished version

Line 
1Index: t/op/gc.t
2===================================================================
3--- t/op/gc.t   (revision 40827)
4+++ t/op/gc.t   (working copy)
5@@ -1,20 +1,14 @@
6-#!perl
7+#! parrot
8 # Copyright (C) 2001-2009, Parrot Foundation.
9 # $Id$
10 
11-use strict;
12-use warnings;
13-use lib qw( . lib ../lib ../../lib );
14-use Test::More;
15-use Parrot::Test tests => 18;
16-
17 =head1 NAME
18 
19-t/op/gc.t - Garbage Collection
20+t/op/gc.t - Garbage collection
21 
22 =head1 SYNOPSIS
23 
24-        % prove t/op/gc.t
25+    % prove t/op/gc.t
26 
27 =head1 DESCRIPTION
28 
29@@ -23,117 +17,129 @@
30 
31 =cut
32 
33-pir_output_is( <<'CODE', '1', "sweep 1" );
34 .include 'interpinfo.pasm'
35+
36 .sub main :main
37-      $I1 = interpinfo .INTERPINFO_GC_MARK_RUNS  # How many GC mark runs have we done already?
38-      sweep 1
39-      $I2 = interpinfo .INTERPINFO_GC_MARK_RUNS  # Should be one more now
40-      $I3 = $I2 - $I1
41-      print $I3
42+    .include 'test_more.pir'
43+    plan(140)
44+
45+    sweep_1()
46+    sweep_0()
47+    sweep_0_need_destroy_obj()
48+    sweep_0_need_destroy_destroy_obj()
49+    collect_count()
50+    collect_toggle()
51+    collect_toggle_nested()
52+    vanishing_singleton_PMC()
53+    vanishing_ret_continuation()
54+    regsave_marked()
55+    recursion_and_exceptions()
56+    write_barrier_1()
57+    write_barrier_2()
58+    addr_registry_1()
59+    addr_registry_2_int()
60+    addr_registry_2_str()
61+    pmc_proxy_obj_mark()
62+    coro_context_ret_continuation()
63+    # END_OF_TESTS
64+
65 .end
66-CODE
67 
68-pir_output_is( <<'CODE', '0', "sweep 0" );
69-.include 'interpinfo.pasm'
70-.sub main :main
71-      $I1 = interpinfo .INTERPINFO_GC_MARK_RUNS   # How many GC mark runs have we done already?
72-      sweep 0
73-      $I2 = interpinfo .INTERPINFO_GC_MARK_RUNS  # Should be same
74-      $I3 = $I2 - $I1
75-      print $I3
76+.sub sweep_1
77+    $I1 = interpinfo .INTERPINFO_GC_MARK_RUNS  # How many GC mark runs have we done already?
78+    sweep 1
79+    $I2 = interpinfo .INTERPINFO_GC_MARK_RUNS  # Should be one more now
80+    $I3 = $I2 - $I1
81+    is($I3,1)
82 .end
83-CODE
84 
85-pasm_output_is( <<'CODE', '1', "sweep 0, with object that need destroy" );
86-      new P0, 'Undef'
87-      interpinfo I1, 2   # How many GC mark runs have we done already?
88-      needs_destroy P0
89-      sweep 0
90-      interpinfo I2, 2   # Should be one more now
91-      sub I3, I2, I1
92-      print I3
93-      end
94-CODE
95 
96-pasm_output_is( <<'CODE', '10', "sweep 0, with object that need destroy/destroy" );
97-      new P0, 'Undef'
98-      needs_destroy P0
99-      interpinfo I1, 2   # How many GC mark runs have we done already?
100-      new P0, 'Undef'    # kill object
101-      sweep 0
102-      interpinfo I2, 2   # Should be one more now
103-      sub I3, I2, I1
104-      sweep 0
105-      interpinfo I4, 2   # Should be same as last
106-      sub I5, I4, I2
107-      print I3           # These create PMCs that need early GC, so we need
108-      print I5           # to put them after the second sweep op.
109-      end
110-CODE
111+.sub sweep_0
112+    $I1 = interpinfo .INTERPINFO_GC_MARK_RUNS   # How many GC mark runs have we done already?
113+    sweep 0
114+    $I2 = interpinfo .INTERPINFO_GC_MARK_RUNS  # Should be same
115+    $I3 = $I2 - $I1
116+    is($I3,0)
117+.end
118 
119-pir_output_is( <<'CODE', '1', "collect" );
120-.include 'interpinfo.pasm'
121-.sub main :main
122-      $I1 = interpinfo .INTERPINFO_GC_COLLECT_RUNS   # How many garbage collections have we done already?
123-      collect
124-      $I2 = interpinfo .INTERPINFO_GC_COLLECT_RUNS  # Should be one more now
125-      $I3 = $I2 - $I1
126-      print $I3
127+
128+# sweep 0, with object that needs destroy/destroy
129+.sub sweep_0_need_destroy_obj
130+    $P0 = new 'Undef'
131+    $I1 = interpinfo .INTERPINFO_GC_MARK_RUNS   # How many GC mark runs have we done already?
132+    needs_destroy $P0
133+    sweep 0
134+    $I2 = interpinfo .INTERPINFO_GC_MARK_RUNS   # Should be one more now
135+    $I3 = $I2 - $I1
136+    is($I3,1)
137 .end
138-CODE
139 
140-pasm_output_is( <<'CODE', <<'OUTPUT', "collectoff/on" );
141-      interpinfo I1, 3
142-      collectoff
143-      collect
144-      interpinfo I2, 3
145-      sub I3, I2, I1
146-      print I3
147-      print "\n"
148 
149-      collecton
150-      collect
151-      interpinfo I4, 3
152-      sub I6, I4, I2
153-      print I6
154-      print "\n"
155+# sweep 0, with object that needs destroy/destroy
156+.sub sweep_0_need_destroy_destroy_obj
157+    $P0 = new 'Undef'
158+    needs_destroy $P0
159+    $I1 = interpinfo .INTERPINFO_GC_MARK_RUNS   # How many GC mark runs have we done already?
160+    $P0 = new 'Undef'  #kill object
161+    sweep 0
162+    $I2 = interpinfo .INTERPINFO_GC_MARK_RUNS   # Should be one more now
163+    $I3 = $I2 - $I1
164+    sweep 0
165+    $I4 = interpinfo .INTERPINFO_GC_MARK_RUNS   # Should be same as last
166+    $I5 = $I4 - $I2
167+    is($I3,1)
168+    is($I5,0)
169+.end
170 
171-      end
172-CODE
173-0
174-1
175-OUTPUT
176 
177-pasm_output_is( <<'CODE', <<'OUTPUT', "Nested collectoff/collecton" );
178-      interpinfo I1, 3
179-      collectoff
180-      collectoff
181-      collecton
182-      collect           # This shouldn't do anything...    #'
183-      interpinfo I2, 3
184-      sub I3, I2, I1
185-      print I3
186-      print "\n"
187+.sub collect_count
188+    $I1 = interpinfo .INTERPINFO_GC_COLLECT_RUNS   # How many garbage collections have we done already?
189+    collect
190+    $I2 = interpinfo .INTERPINFO_GC_COLLECT_RUNS  # Should be one more now
191+    $I3 = $I2 - $I1
192+    is($I3,1)
193+.end
194 
195-      collecton
196-      collect           # ... but this should
197-      interpinfo I4, 3
198-      sub I6, I4, I2
199-      print I6
200-      print "\n"
201 
202-      end
203-CODE
204-0
205-1
206-OUTPUT
207+.sub collect_toggle
208+    $I1 = interpinfo .INTERPINFO_GC_COLLECT_RUNS
209+    collectoff
210+    collect
211+    $I2 = interpinfo .INTERPINFO_GC_COLLECT_RUNS
212+    $I3 = $I2 - $I1
213+    is($I3,0)
214 
215-pir_output_is( <<'CODE', <<OUTPUT, "vanishing singleton PMC" );
216-.sub main :main
217+    collecton
218+    collect
219+    $I4 = interpinfo .INTERPINFO_GC_COLLECT_RUNS
220+    $I6 = $I4 - $I2
221+    is($I6,1)
222+.end
223+
224+
225+.sub collect_toggle_nested
226+    $I1 = interpinfo .INTERPINFO_GC_COLLECT_RUNS
227+    collectoff
228+    collectoff
229+    collecton
230+    collect           # This shouldn't do anything...    #'
231+    $I2 = interpinfo .INTERPINFO_GC_COLLECT_RUNS
232+    $I3 = $I2 - $I1
233+    is($I3,0)
234+
235+    collecton
236+    collect           # ... but this should
237+    $I4 = interpinfo .INTERPINFO_GC_COLLECT_RUNS
238+    $I6 = $I4 - $I2
239+    is($I6,1)
240+
241+.end
242+
243+
244+.sub vanishing_singleton_PMC
245     $P16 = new 'Env'
246     $P16['Foo'] = 'bar'
247-    $I16 = 100
248+    $I16 = 100    #Why 100?
249     $I17 = 0
250 
251     loop:
252@@ -141,38 +147,27 @@
253        _rand()
254        $I17 += 1
255        if $I17 <= $I16 goto loop
256-       say "ok"
257 .end
258 
259 .sub _rand
260     $P16 = new 'Env'
261     $P5 = $P16['Foo']
262+    is($P5, 'bar')
263     if $P5 != 'bar' goto err
264     .return()
265     err:
266-       say "singleton destroyed .Env = ."
267+       print "singleton destroyed .Env = ."
268        $P16 = new 'Env'
269        $S16 = typeof $P16
270        say $S16
271 .end
272+# END: vanishing_singleton_PMC
273 
274-CODE
275-ok
276-OUTPUT
277 
278-pir_output_is( <<'CODE', <<OUTPUT, "vanishing return continuation in method calls" );
279-.sub main :main
280-    .local pmc o, cl
281-    cl = newclass "Foo"
282-
283-    new o, "Foo"
284-    print "ok\n"
285-    end
286-.end
287-
288+# vanishing return continuation in method calls
289 .namespace ["Foo"]
290 .sub init :vtable :method
291-    print "init\n"
292+    ok(1, "entered init()")
293     sweep 1
294     new $P6, 'String'
295     set $P6, "hi"
296@@ -184,105 +179,81 @@
297     sweep 1
298     inc self
299     sweep 1
300-    print "back from _inc\n"
301+    ok(1, "leaving do_inc")
302 .end
303 
304 .sub __increment :method
305-    print "inc\n"
306+    ok(1, "in __increment")
307     sweep 1
308 .end
309-CODE
310-init
311-inc
312-back from _inc
313-ok
314-OUTPUT
315+.namespace [ ]
316 
317-pasm_output_is( <<'CODE', <<OUTPUT, "failing if regsave is not marked" );
318-    newclass P9, "Source"
319-    newclass P10, "Source::Buffer"
320-    new P12, "Source"
321+.sub vanishing_ret_continuation
322+    .local pmc o, cl
323+    cl = newclass 'Foo'
324+    o = new 'Foo'
325+    ok(1)
326+.end
327 
328-    set S20, P12
329-    print S20
330-    set S20, P12
331-    print S20
332-    end
333+# END: vanishing_return_continuation
334 
335+
336+
337+#Fail if regsave is not marked
338 .namespace ["Source"]
339-.pcc_sub __get_string:  # buffer
340-    get_params "0", P2
341-    getprop P12, "buffer", P2
342+.sub get_string :method :vtable # buffer
343+    $P4  = self
344+    $P2 = getprop "buffer", $P4
345     sweep 1
346-    unless_null P12, buffer_ok
347-    new P12, "Source::Buffer"
348-    new P14, 'String'
349-    set P14, "hello\n"
350-    setprop P12, "buf", P14
351-    setprop P2, "buffer", P12
352+    unless_null $P2, buffer_ok
353+    $P2 = new "Source::Buffer"
354+    $P3 = new "String"
355+    $P3 = "hello"
356+    $P2 = setprop "buf", $P3
357+    $P4  = setprop "buffer", $P2
358 buffer_ok:
359-    set_returns "0", P12
360-    returncc
361+    .return($P2)
362+.end
363 
364 .namespace ["Source::Buffer"]
365-.pcc_sub __get_string:
366-    get_params "0", P2
367+.sub get_string :method :vtable
368+    $P4 = self
369     sweep 1
370-    getprop P12, "buf", P2
371-    set S16, P12
372-    set_returns "0", S16
373-    returncc
374-CODE
375-hello
376-hello
377-OUTPUT
378+    $P2 = getprop "buf", $P4
379+    $S0 = $P2
380+    .return($S0)
381+.end
382 
383-# this is a stripped down version of imcc/t/syn/pcc_16
384-# s. also src/pmc/retcontinuation.pmc
385-pasm_output_is( <<'CODE', <<OUTPUT, "coro context and invalid return continuations" );
386-.pcc_sub main:
387-    .const 'Sub' P0 = "co1"
388-    set I20, 0
389-l:
390-    get_results ''
391-    set_args ''
392-    invokecc P0
393-    inc I20
394-    lt I20, 3, l
395-    print "done\n"
396-    end
397-.pcc_sub co1:
398-    get_params ''
399-    set P17, P1
400-col:
401-    print "coro\n"
402-    sweep 1
403-    yield
404-    branch col
405+.namespace [ ]
406 
407-CODE
408-coro
409-coro
410-coro
411-done
412-OUTPUT
413+.sub regsave_marked
414+    $P0  = newclass "Source"
415+    $P1 = newclass "Source::Buffer"
416+    $P2 = new "Source"
417 
418-pir_output_is( <<'CODE', <<OUTPUT, "Recursion and exceptions" );
419+    $S1 = $P2
420+    is($S1, "hello")
421 
422-# this did segfault with GC_DEBUG
423+    $S1 = $P2        #why are we doing this twice?
424+    is($S1, "hello")
425+.end
426 
427-.sub main :main
428+# end regsave_marked()
429+
430+
431+# Recursion and exceptions
432+# NOTE: this did segfault with GC_DEBUG
433+.sub recursion_and_exceptions
434     .local pmc n
435     $P0 = getinterp
436     $P0."recursion_limit"(10)
437-    newclass $P0, "b"
438+    $P0 = newclass "b"
439     $P0 = new "b"
440     $P1 = new 'Integer'
441     $P1 = 0
442     n = $P0."b11"($P1)
443-    print "ok 1\n"
444-    print n
445-    print "\n"
446+    ok(1)
447+    is(n,8)
448 .end
449 .namespace ["b"]
450 .sub b11 :method
451@@ -292,7 +263,8 @@
452     # store_lex -1, "n", n
453     n1 = new 'Integer'
454     n1 = n + 1
455-    push_eh catch
456+    push_eh catch    # we're going to catch an exception when recursion_depth
457+                     # is too large
458     n = self."b11"(n1)
459     # store_lex -1, "n", n
460     pop_eh
461@@ -300,233 +272,176 @@
462     # n = find_lex "n"
463     .return(n)
464 .end
465-CODE
466-ok 1
467-9
468-OUTPUT
469+.namespace [ ]
470 
471-pasm_output_is( <<'CODE', <<OUTPUT, "write barrier 1" );
472-    null I2
473-    set I3, 100
474+# write barrier 1
475+.sub write_barrier_1
476+    null $I2
477+    $I3 = 100
478 lp3:
479-    null I0
480-    set I1, 1000
481-    new P1, 'ResizablePMCArray'
482+    null $I0
483+    $I1 = 1000
484+    $P1 = new 'ResizablePMCArray'
485 lp1:
486-    new P2, 'ResizablePMCArray'
487-    new P0, 'Integer'
488-    set P0, I0
489-    set P2[0], P0
490-    set P1[I0], P2
491-    if I0, not_0
492-    needs_destroy P0
493-    # force marking past P2[0]
494+    $P2 = new 'ResizablePMCArray'
495+    $P0 = new 'Integer'
496+    $P0 = $I0
497+    $P2[0] = $P0
498+    $P1[$I0] = $P2
499+    if $I0, not_0
500+    needs_destroy $P0
501+    # force marking past $P2[0]
502     sweep 0
503 not_0:
504-    new P3, 'Undef'
505-    new P4, 'Undef'
506-    inc I0
507-    lt I0, I1, lp1
508+    $P3 = new 'Undef'
509+    $P4 = new 'Undef'
510+    inc $I0
511+    lt $I0, $I1, lp1
512 
513-    null I0
514+    null $I0
515     # trace 1
516 lp2:
517-    set P2, P1[I0]
518-    set P2, P2[0]
519-    eq P2, I0, ok
520+    $P2 = $P1[$I0]
521+    $P2 = $P2[0]
522+    eq $P2, $I0, ok
523     print "nok\n"
524     print "I0: "
525-    print I0
526+    print $I0
527     print " P2: "
528-    print P2
529+    print $P2
530     print " type: "
531-    typeof S0, P2
532-    print S0
533+    $S0 = typeof $P2
534+    print $S0
535     print " I2: "
536-    print I2
537+    print $I2
538     print "\n"
539     exit 1
540 ok:
541-    inc I0
542-    lt I0, I1, lp2
543-    inc I2
544-    lt I2, I3, lp3
545-    print "ok\n"
546-    end
547-CODE
548-ok
549-OUTPUT
550+    inc $I0
551+    lt $I0, $I1, lp2
552+    inc $I2
553+    lt $I2, $I3, lp3
554+    ok(1)
555+.end
556 
557-pasm_output_is( <<'CODE', <<OUTPUT, "write barrier 2 - hash" );
558-    null I2
559-    set I3, 100
560+
561+# write barrier 2 - hash
562+.sub write_barrier_2
563+    null $I2
564+    $I3 = 100
565 lp3:
566-    null I0
567-    set I1, 100
568-    new P1, 'Hash'
569+    null $I0
570+    $I1 = 100
571+    $P1 = new 'Hash'
572 lp1:
573-    new P2, 'Hash'
574-    new P0, 'Integer'
575-    set P0, I0
576-    set S0, I0
577-    set P2["first"], P0
578-    set P1[S0], P2
579-    if I0, not_0
580-    new P0, 'Integer'
581-    needs_destroy P0
582-    null P0
583+    $P2 = new 'Hash'
584+    $P0 = new 'Integer'
585+    $P0 = $I0
586+    $S0 = $I0
587+    $P2["first"] = $P0
588+    $P1[$S0] = $P2
589+    if $I0, not_0
590+    $P0 = new 'Integer'
591+    needs_destroy $P0
592+    null $P0
593     # force full sweep
594     sweep 0
595 not_0:
596-    new P3, 'Undef'
597-    new P4, 'Undef'
598-    inc I0
599-    lt I0, I1, lp1
600+    $P3 = new 'Undef'
601+    $P4 = new 'Undef'
602+    inc $I0
603+    lt $I0, $I1, lp1
604 
605-    null I0
606+    null $I0
607     # trace 1
608 lp2:
609-    set S0, I0
610-    set P2, P1[S0]
611-    set P2, P2["first"]
612-    eq P2, I0, ok
613+    $S0 = $I0
614+    $P2 = $P1[$S0]
615+    $P2 = $P2["first"]
616+    eq $P2, $I0, ok
617     print "nok\n"
618     print "I0: "
619-    print I0
620+    print $I0
621     print " P2: "
622-    print P2
623+    print $P2
624     print " type: "
625-    typeof S0, P2
626-    print S0
627+    $S0 = typeof $P2
628+    print $S0
629     print " I2: "
630-    print I2
631+    print $I2
632     print "\n"
633     exit 1
634 ok:
635-    inc I0
636-    lt I0, I1, lp2
637-    inc I2
638-    lt I2, I3, lp3
639-    print "ok\n"
640-    end
641-CODE
642-ok
643-OUTPUT
644-
645-pir_output_is( <<'CODE', <<'OUTPUT', "verify pmc proxy object marking" );
646-.sub main :main
647-    .local pmc cl, s, t
648-    cl = subclass "String", "X"
649-    addattribute cl, "o3"
650-    addattribute cl, "o4"
651-    s = new "X"
652-    $P0 = new 'String'
653-    $S0 = "ok" . " 3\n"
654-    $P0 = $S0
655-    setattribute s, "o3", $P0
656-    $P0 = new 'String'
657-    $S0 = "ok" . " 4\n"
658-    $P0 = $S0
659-    setattribute s, "o4", $P0
660-    null $P0
661-    null $S0
662-    null cl
663-    sweep 1
664-    s = "ok 1\n"
665-    print s
666-    .local int i
667-    i = 0
668-lp:
669-    t = new "X"
670-    inc i
671-    if i < 1000 goto lp
672-    t = "ok 2\n"
673-    print s
674-    print t
675-    $P0 = getattribute s, "o3"
676-    print $P0
677-    $P0 = getattribute s, "o4"
678-    print $P0
679+    inc $I0
680+    lt $I0, $I1, lp2
681+    inc $I2
682+    lt $I2, $I3, lp3
683+    ok(1)
684 .end
685-CODE
686-ok 1
687-ok 1
688-ok 2
689-ok 3
690-ok 4
691-OUTPUT
692 
693-pir_output_is( <<'CODE', <<'OUTPUT', "AddrRegistry 1" );
694-.sub main :main
695+
696+
697+# AddrRegistry 1
698+.sub addr_registry_1
699     .local pmc a, reg, nil
700     reg = new 'AddrRegistry'
701     a = new 'String'
702     null nil
703     $I0 = reg[a]
704     if $I0 == 0 goto ok1
705-    print "not "
706+    notok(1)
707 ok1:
708-    print "ok 1\n"
709+    ok(1, "ok 1")
710     reg[a] = nil
711     $I0 = reg[a]
712     if $I0 == 1 goto ok2
713-    print "not "
714+    notok(1)
715 ok2:
716-    print "ok 2\n"
717+    ok(1, "ok 2")
718     reg[a] = nil
719     $I0 = reg[a]
720     if $I0 == 2 goto ok3
721-    print "not "
722+    notok(1)
723 ok3:
724-    print "ok 3\n"
725-
726+    ok(1, "ok 3")
727     delete reg[a]
728     $I0 = reg[a]
729     if $I0 == 1 goto ok4
730-    print "not "
731+    notok(1)
732 ok4:
733-    print "ok 4\n"
734+    ok(1, "ok 4")
735     delete reg[a]
736     $I0 = reg[a]
737     if $I0 == 0 goto ok5
738-    print "not "
739+    notok(1)
740 ok5:
741-    print "ok 5\n"
742+    ok(1, "ok 5")
743 .end
744-CODE
745-ok 1
746-ok 2
747-ok 3
748-ok 4
749-ok 5
750-OUTPUT
751 
752-pir_output_is( <<'CODE', <<'OUTPUT', "AddrRegistry 2" );
753-.sub main :main
754+
755+# AddrRegistry 2
756+.sub addr_registry_2_int
757     .local pmc a, b, reg, nil
758     null nil
759     reg = new 'AddrRegistry'
760     a = new 'String'
761     b = new 'String'
762     $I0 = elements reg
763-    print $I0
764+    is($I0, 0)
765     reg[a] = nil
766     $I0 = elements reg
767-    print $I0
768+    is($I0, 1)
769     reg[a] = nil
770     $I0 = elements reg
771-    print $I0
772+    is($I0, 1)
773     reg[b] = nil
774     $I0 = elements reg
775-    print $I0
776-    print "\n"
777+    is($I0, 2)
778 .end
779-CODE
780-0112
781-OUTPUT
782 
783-pir_output_is( <<'CODE', <<'OUTPUT', "AddrRegistry 2" );
784-.sub main :main
785+
786+# AddrRegistry 2
787+.sub addr_registry_2_str
788     .local pmc a, b, c, reg, nil, it
789     null nil
790     reg = new 'AddrRegistry'
791@@ -551,13 +466,72 @@
792 done:
793     $P1.'sort'()
794     $S1 = join '', $P1
795-    print $S1
796-    print "\n"
797+    is($S1, 'k1k2k3')
798 .end
799-CODE
800-k1k2k3
801-OUTPUT
802 
803+# verify pmc proxy object marking
804+.sub pmc_proxy_obj_mark
805+    .local pmc cl, s, t
806+    cl = subclass "String", "X"
807+    addattribute cl, "o3"
808+    addattribute cl, "o4"
809+    s = new "X"
810+    $P0 = new 'String'
811+    $S0 = "ok" . " 3"
812+    $P0 = $S0
813+    setattribute s, "o3", $P0
814+    $P0 = new 'String'
815+    $S0 = "ok" . " 4"
816+    $P0 = $S0
817+    setattribute s, "o4", $P0
818+    null $P0
819+    null $S0
820+    null cl
821+    sweep 1
822+    s = "ok 1"
823+    is(s, "ok 1")
824+    .local int i
825+    i = 0
826+lp:
827+    t = new "X"
828+    inc i
829+    if i < 1000 goto lp
830+    t = "ok 2"
831+    is(s, "ok 1")
832+    is(t, "ok 2")
833+    $P0 = getattribute s, "o3"
834+    is($P0, "ok 3")
835+    $P0 = getattribute s, "o4"
836+    is($P0, "ok 4")
837+.end
838+
839+
840+# coro context and invalid return continuations
841+# this is a stripped down version of imcc/t/syn/pcc_16
842+# s. also src/pmc/retcontinuation.pmc
843+
844+.sub coro_context_ret_continuation
845+    .const 'Sub' $P0 = "co1"
846+    $I20 = 0
847+l:
848+    get_results ''
849+    set_args ''
850+    invokecc $P0
851+    inc $I20
852+    lt $I20, 3, l
853+    ok(1, "done\n")
854+.end
855+
856+.sub co1
857+    get_params ''
858+    $P17 = $P1
859+col:
860+    ok(1, "coro\n")
861+    sweep 1
862+    yield
863+    branch col
864+.end
865+
866 =head1 SEE ALSO
867 
868 F<examples/benchmarks/primes.c>,
869@@ -567,11 +541,9 @@
870 F<examples/benchmarks/primes2.c>,
871 F<examples/benchmarks/primes2.py>.
872 
873-=cut
874-
875 # Local Variables:
876 #   mode: cperl
877 #   cperl-indent-level: 4
878 #   fill-column: 100
879 # End:
880-# vim: expandtab shiftwidth=4:
881+# vim: expandtab shiftwidth=4 filetype=pir: