1/*
2Copyright (C) 2001-2014, Parrot Foundation.
3
4=head1 NAME
5
6src/pmc/capture.pmc - Capture PMC
7
8=head1 DESCRIPTION
9
10These are the vtable functions for the Capture PMC.
11
12=head2 Functions
13
14=over 4
15
16=cut
17
18*/
19
20/* HEADERIZER HFILE: none */
21/* HEADERIZER BEGIN: static */
22/* HEADERIZER END: static */
23
24#define CAPTURE_array_CREATE(i, obj, arr) \
25    do { \
26        GETATTR_Capture_array((i), (obj), (arr)); \
27        if (!(arr)) { \
28            PObj_custom_mark_SET(obj); \
29            (arr) = Parrot_pmc_new((i), enum_class_ResizablePMCArray); \
30            SETATTR_Capture_array((i), (obj), (arr)); \
31            PARROT_GC_WRITE_BARRIER((i), (obj));  \
32        } \
33    } while (0)
34#define CAPTURE_hash_CREATE(i, obj, hsh) \
35    do { \
36        GETATTR_Capture_hash((i), (obj), (hsh)); \
37        if (!(hsh)) { \
38            PObj_custom_mark_SET(obj); \
39            (hsh) = Parrot_pmc_new((i), enum_class_Hash); \
40            SETATTR_Capture_hash((i), (obj), (hsh)); \
41            PARROT_GC_WRITE_BARRIER((i), (obj)); \
42        } \
43    } while (0)
44
45pmclass Capture auto_attrs {
46    ATTR PMC    *array;
47    ATTR PMC    *hash;
48
49/*
50
51=item C<PMC *clone()>
52
53Creates an identical copy of the Capture.
54
55=cut
56
57*/
58
59    VTABLE PMC *clone() :no_wb {
60        PMC *array, *hash;
61        PMC * const dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
62        GET_ATTR_array(INTERP, SELF, array);
63        GET_ATTR_hash(INTERP, SELF, hash);
64        if (!PMC_IS_NULL(array)) {
65            PObj_custom_mark_SET(dest);
66            array = VTABLE_clone(INTERP, array);
67            SET_ATTR_array(INTERP, dest, array);
68        }
69        if (!PMC_IS_NULL(hash)) {
70            PObj_custom_mark_SET(dest);
71            hash = VTABLE_clone(INTERP, hash);
72            SET_ATTR_hash(INTERP, dest, hash);
73        }
74
75        /* clone of parts can trigger GC. Explicitly WB dest */
76        PARROT_GC_WRITE_BARRIER(INTERP, dest);
77
78        return dest;
79    }
80
81/*
82
83=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
84
85=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
86
87=item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
88
89=item C<void set_string_keyed_int(INTVAL key, STRING *value)>
90
91Sets a value in the array component of the Capture.
92
93=cut
94
95*/
96
97    VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) :manual_wb {
98        PMC *array;
99
100        CAPTURE_array_CREATE(INTERP, SELF, array);
101        VTABLE_set_number_keyed_int(INTERP, array, key, value);
102    }
103
104    VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) :manual_wb {
105        PMC *array;
106
107        CAPTURE_array_CREATE(INTERP, SELF, array);
108        VTABLE_set_integer_keyed_int(INTERP, array, key, value);
109    }
110
111    VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) :manual_wb {
112        PMC *array;
113
114        CAPTURE_array_CREATE(INTERP, SELF, array);
115        VTABLE_set_pmc_keyed_int(INTERP, array, key, value);
116    }
117
118    VTABLE void set_string_keyed_int(INTVAL key, STRING *value) :manual_wb {
119        PMC *array;
120
121        CAPTURE_array_CREATE(INTERP, SELF, array);
122        VTABLE_set_string_keyed_int(INTERP, array, key, value);
123    }
124
125/*
126
127=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
128
129=item C<INTVAL get_integer_keyed_int(INTVAL key)>
130
131=item C<PMC *get_pmc_keyed_int(INTVAL key)>
132
133=item C<STRING *get_string_keyed_int(INTVAL key)>
134
135Retrieves a value in the array component of the Capture.
136
137=cut
138
139*/
140
141    VTABLE FLOATVAL get_number_keyed_int(INTVAL key) :no_wb {
142        PMC *array;
143
144        GET_ATTR_array(INTERP, SELF, array);
145        if (!array)
146            return 0.0;
147
148        return VTABLE_get_number_keyed_int(INTERP, array, key);
149    }
150
151    VTABLE INTVAL get_integer_keyed_int(INTVAL key) :no_wb {
152        PMC *array;
153
154        GET_ATTR_array(INTERP, SELF, array);
155        if (!array)
156            return 0;
157
158        return VTABLE_get_integer_keyed_int(INTERP, array, key);
159    }
160
161    VTABLE PMC *get_pmc_keyed_int(INTVAL key) :no_wb {
162        PMC *array;
163
164        GET_ATTR_array(INTERP, SELF, array);
165        if (!array)
166            return PMCNULL;
167
168        return VTABLE_get_pmc_keyed_int(INTERP, array, key);
169    }
170
171    VTABLE STRING *get_string_keyed_int(INTVAL key) :no_wb {
172        PMC *array;
173
174        GET_ATTR_array(INTERP, SELF, array);
175        if (!array)
176            return CONST_STRING(INTERP, "");
177
178        return VTABLE_get_string_keyed_int(INTERP, array, key);
179    }
180
181/*
182
183=item C<void push_float(FLOATVAL value)>
184
185=item C<void push_integer(INTVAL value)>
186
187=item C<void push_pmc(PMC *value)>
188
189=item C<void push_string(STRING *value)>
190
191Push a value onto the array component of the Capture.
192
193=item C<void unshift_float(FLOATVAL value)>
194
195=item C<void unshift_integer(INTVAL value)>
196
197=item C<void unshift_pmc(PMC *value)>
198
199=item C<void unshift_string(STRING *value)>
200
201Unshift a value onto the array component of the Capture.
202
203=cut
204
205*/
206
207    VTABLE void push_float(FLOATVAL value) :manual_wb {
208        PMC *array;
209
210        CAPTURE_array_CREATE(INTERP, SELF, array);
211        VTABLE_push_float(INTERP, array, value);
212    }
213
214    VTABLE void push_integer(INTVAL value) :manual_wb {
215        PMC *array;
216
217        CAPTURE_array_CREATE(INTERP, SELF, array);
218        VTABLE_push_integer(INTERP, array, value);
219    }
220
221    VTABLE void push_pmc(PMC *value) :manual_wb {
222        PMC *array;
223
224        CAPTURE_array_CREATE(INTERP, SELF, array);
225        VTABLE_push_pmc(INTERP, array, value);
226    }
227
228    VTABLE void push_string(STRING *value) :manual_wb {
229        PMC *array;
230
231        CAPTURE_array_CREATE(INTERP, SELF, array);
232        VTABLE_push_string(INTERP, array, value);
233    }
234
235    VTABLE void unshift_float(FLOATVAL value) :manual_wb {
236        PMC *array;
237
238        CAPTURE_array_CREATE(INTERP, SELF, array);
239        VTABLE_unshift_float(INTERP, array, value);
240    }
241
242    VTABLE void unshift_integer(INTVAL value) :manual_wb {
243        PMC *array;
244
245        CAPTURE_array_CREATE(INTERP, SELF, array);
246        VTABLE_unshift_integer(INTERP, array, value);
247    }
248
249    VTABLE void unshift_pmc(PMC *value) :manual_wb {
250        PMC *array;
251
252        CAPTURE_array_CREATE(INTERP, SELF, array);
253        VTABLE_unshift_pmc(INTERP, array, value);
254    }
255
256    VTABLE void unshift_string(STRING *value) :manual_wb {
257        PMC *array;
258
259        CAPTURE_array_CREATE(INTERP, SELF, array);
260        VTABLE_unshift_string(INTERP, array, value);
261    }
262
263/*
264
265=item C<FLOATVAL pop_float()>
266
267=item C<INTVAL pop_integer()>
268
269=item C<PMC *pop_pmc()>
270
271=item C<STRING *pop_string()>
272
273Pop a value from the array component of the Capture.
274
275=item C<FLOATVAL shift_float()>
276
277=item C<INTVAL shift_integer()>
278
279=item C<PMC *shift_pmc()>
280
281=item C<STRING *shift_string()>
282
283Shift a value from the array component of the Capture.
284
285=cut
286
287*/
288
289    VTABLE FLOATVAL pop_float() :manual_wb {
290        PMC *array;
291        FLOATVAL ret;
292
293        CAPTURE_array_CREATE(INTERP, SELF, array);
294        ret = VTABLE_pop_float(INTERP, array);
295        RETURN(FLOATVAL ret);
296    }
297
298    VTABLE INTVAL pop_integer() :manual_wb {
299        PMC *array;
300        INTVAL ret;
301
302        CAPTURE_array_CREATE(INTERP, SELF, array);
303        ret = VTABLE_pop_integer(INTERP, array);
304        RETURN(INTVAL ret);
305    }
306
307    VTABLE PMC *pop_pmc() :manual_wb {
308        PMC *array, *ret;
309
310        CAPTURE_array_CREATE(INTERP, SELF, array);
311        ret = VTABLE_pop_pmc(INTERP, array);
312        RETURN(PMC *ret);
313    }
314
315    VTABLE STRING *pop_string() :manual_wb {
316        PMC *array;
317        STRING *ret;
318
319        CAPTURE_array_CREATE(INTERP, SELF, array);
320        ret = VTABLE_pop_string(INTERP, array);
321        RETURN(STRING *ret);
322    }
323
324    VTABLE FLOATVAL shift_float() :manual_wb {
325        PMC *array;
326        FLOATVAL ret;
327
328        CAPTURE_array_CREATE(INTERP, SELF, array);
329        ret = VTABLE_shift_float(INTERP, array);
330        RETURN(FLOATVAL ret);
331    }
332
333    VTABLE INTVAL shift_integer() :manual_wb {
334        PMC *array;
335        INTVAL ret;
336
337        CAPTURE_array_CREATE(INTERP, SELF, array);
338        ret = VTABLE_shift_integer(INTERP, array);
339        RETURN(INTTVAL ret);
340    }
341
342    VTABLE PMC *shift_pmc() :manual_wb {
343        PMC *array, *ret;
344
345        CAPTURE_array_CREATE(INTERP, SELF, array);
346        ret = VTABLE_shift_pmc(INTERP, array);
347        RETURN(PMC *ret);
348    }
349
350    VTABLE STRING *shift_string() :manual_wb {
351        PMC *array;
352        STRING *ret;
353
354        CAPTURE_array_CREATE(INTERP, SELF, array);
355        ret = VTABLE_shift_string(INTERP, array);
356        RETURN(STRING *ret);
357    }
358
359/*
360
361=item C<INTVAL elements()>
362
363Return the number of elements in the array component of the Capture.
364
365=item C<INTVAL defined_keyed_int(INTVAL key)>
366
367Return true if element C<key> of the array component is defined.
368
369=item C<INTVAL exists_keyed_int(INTVAL key)>
370
371Return true if element C<key> of the array component exists.
372
373=item C<void delete_keyed_int(INTVAL key)>
374
375Delete the element corresponding to C<key> in the array component.
376
377=cut
378
379*/
380
381    VTABLE INTVAL elements() :no_wb {
382        PMC *array;
383
384        GET_ATTR_array(INTERP, SELF, array);
385
386        if (!array)
387            return 0;
388
389        return VTABLE_elements(INTERP, array);
390    }
391
392    VTABLE INTVAL defined_keyed_int(INTVAL key) :no_wb {
393        PMC *array;
394
395        GET_ATTR_array(INTERP, SELF, array);
396
397        if (!array)
398            return 0;
399
400        return VTABLE_defined_keyed_int(INTERP, array, key);
401    }
402
403    VTABLE INTVAL exists_keyed_int(INTVAL key) :no_wb {
404        PMC *array;
405
406        GET_ATTR_array(INTERP, SELF, array);
407
408        if (!array)
409            return 0;
410
411        return VTABLE_exists_keyed_int(INTERP, array, key);
412    }
413
414    VTABLE void delete_keyed_int(INTVAL key) :manual_wb {
415        PMC *array;
416
417        GET_ATTR_array(INTERP, SELF, array);
418
419        if (array) {
420            VTABLE_delete_keyed_int(INTERP, array, key);
421            PARROT_GC_WRITE_BARRIER(INTERP, SELF);
422        }
423    }
424
425/*
426
427=item C<void set_number_keyed(PMC *key, FLOATVAL value)>
428
429=item C<void set_integer_keyed(PMC *key, INTVAL value)>
430
431=item C<void set_pmc_keyed(PMC *key, PMC *value)>
432
433=item C<void set_string_keyed(PMC *key, STRING *value)>
434
435Sets a value in the hash component of the Capture.
436
437=cut
438
439*/
440
441    VTABLE void set_number_keyed(PMC *key, FLOATVAL value) :manual_wb {
442        PMC *hash;
443
444        CAPTURE_hash_CREATE(INTERP, SELF, hash);
445        VTABLE_set_number_keyed(INTERP, hash, key, value);
446    }
447
448    VTABLE void set_integer_keyed(PMC *key, INTVAL value) :manual_wb {
449        PMC *hash;
450
451        CAPTURE_hash_CREATE(INTERP, SELF, hash);
452        VTABLE_set_integer_keyed(INTERP, hash, key, value);
453    }
454
455    VTABLE void set_pmc_keyed(PMC *key, PMC *value) :manual_wb {
456        PMC *hash;
457
458        CAPTURE_hash_CREATE(INTERP, SELF, hash);
459        VTABLE_set_pmc_keyed(INTERP, hash, key, value);
460    }
461
462    VTABLE void set_string_keyed(PMC *key, STRING *value) :manual_wb {
463        PMC *hash;
464
465        CAPTURE_hash_CREATE(INTERP, SELF, hash);
466        VTABLE_set_string_keyed(INTERP, hash, key, value);
467    }
468
469/*
470
471=item C<FLOATVAL get_number_keyed(PMC *key)>
472
473=item C<INTVAL get_integer_keyed(PMC *key)>
474
475=item C<PMC *get_pmc_keyed(PMC *key)>
476
477=item C<STRING *get_string_keyed(PMC *key)>
478
479Retrieves a value from the hash component of the Capture.
480
481=cut
482
483*/
484
485    VTABLE FLOATVAL get_number_keyed(PMC *key) :no_wb {
486        PMC *hash;
487
488        GET_ATTR_hash(INTERP, SELF, hash);
489
490        if (!hash)
491            return 0.0;
492
493        return VTABLE_get_number_keyed(INTERP, hash, key);
494    }
495
496    VTABLE INTVAL get_integer_keyed(PMC *key) :no_wb {
497        PMC *hash;
498
499        GET_ATTR_hash(INTERP, SELF, hash);
500
501        if (!hash)
502            return 0;
503
504        return VTABLE_get_integer_keyed(INTERP, hash, key);
505    }
506
507    VTABLE PMC *get_pmc_keyed(PMC *key) :no_wb {
508        PMC *hash;
509
510        GET_ATTR_hash(INTERP, SELF, hash);
511
512        if (!hash)
513            return PMCNULL;
514
515        return VTABLE_get_pmc_keyed(INTERP, hash, key);
516    }
517
518    VTABLE STRING *get_string_keyed(PMC *key) :no_wb {
519        PMC *hash;
520
521        GET_ATTR_hash(INTERP, SELF, hash);
522
523        if (!hash)
524            return CONST_STRING(INTERP, "");
525
526        return VTABLE_get_string_keyed(INTERP, hash, key);
527    }
528
529/*
530
531=item C<void set_number_keyed_str(STRING *key, FLOATVAL value)>
532
533=item C<void set_integer_keyed_str(STRING *key, INTVAL value)>
534
535=item C<void set_pmc_keyed_str(STRING *key, PMC *value)>
536
537=item C<void set_string_keyed_str(STRING *key, STRING *value)>
538
539Sets a value in the hash component of the Capture.
540
541=cut
542
543*/
544
545    VTABLE void set_number_keyed_str(STRING *key, FLOATVAL value) :manual_wb {
546        PMC *hash;
547
548        CAPTURE_hash_CREATE(INTERP, SELF, hash);
549        VTABLE_set_number_keyed_str(INTERP, hash, key, value);
550    }
551
552    VTABLE void set_integer_keyed_str(STRING *key, INTVAL value) :manual_wb {
553        PMC *hash;
554
555        CAPTURE_hash_CREATE(INTERP, SELF, hash);
556        VTABLE_set_integer_keyed_str(INTERP, hash, key, value);
557    }
558
559    VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) :manual_wb {
560        PMC *hash;
561
562        CAPTURE_hash_CREATE(INTERP, SELF, hash);
563        VTABLE_set_pmc_keyed_str(INTERP, hash, key, value);
564    }
565
566    VTABLE void set_string_keyed_str(STRING *key, STRING *value) :manual_wb {
567        PMC *hash;
568
569        CAPTURE_hash_CREATE(INTERP, SELF, hash);
570        VTABLE_set_string_keyed_str(INTERP, hash, key, value);
571    }
572
573/*
574
575=item C<FLOATVAL get_number_keyed_str(STRING *key)>
576
577=item C<INTVAL get_integer_keyed_str(STRING *key)>
578
579=item C<PMC *get_pmc_keyed_str(STRING *key)>
580
581=item C<STRING *get_string_keyed_str(STRING *key)>
582
583Retrieves a value in the hash component of the Capture.
584
585=cut
586
587*/
588
589    VTABLE FLOATVAL get_number_keyed_str(STRING *key) :no_wb {
590        PMC *hash;
591
592        GET_ATTR_hash(INTERP, SELF, hash);
593
594        if (!hash)
595            return 0.0;
596
597        return VTABLE_get_number_keyed_str(INTERP, hash, key);
598    }
599
600    VTABLE INTVAL get_integer_keyed_str(STRING *key) :no_wb {
601        PMC *hash;
602
603        GET_ATTR_hash(INTERP, SELF, hash);
604
605        if (!hash)
606            return 0;
607
608        return VTABLE_get_integer_keyed_str(INTERP, hash, key);
609    }
610
611    VTABLE PMC *get_pmc_keyed_str(STRING *key) :no_wb {
612        PMC *hash;
613
614        GET_ATTR_hash(INTERP, SELF, hash);
615
616        if (!hash)
617            return PMCNULL;
618
619        return VTABLE_get_pmc_keyed_str(INTERP, hash, key);
620    }
621
622    VTABLE STRING *get_string_keyed_str(STRING *key) :no_wb {
623        PMC *hash;
624
625        GET_ATTR_hash(INTERP, SELF, hash);
626
627        if (!hash)
628            return CONST_STRING(INTERP, "");
629        return VTABLE_get_string_keyed_str(INTERP, hash, key);
630    }
631
632/*
633
634=item C<INTVAL defined_keyed(PMC *key)>
635
636Return true if element C<key> of the hash component is defined.
637
638=item C<INTVAL exists_keyed(PMC *key)>
639
640Return true if element C<key> of the hash component exists.
641
642=item C<void delete_keyed(PMC *key)>
643
644Delete the element corresponding to C<key> in the hash component.
645
646=cut
647
648*/
649
650    VTABLE INTVAL defined_keyed(PMC *key) :no_wb {
651        PMC *hash;
652
653        GET_ATTR_hash(INTERP, SELF, hash);
654
655        if (!hash)
656            return 0;
657
658        return VTABLE_defined_keyed(INTERP, hash, key);
659    }
660
661    VTABLE INTVAL exists_keyed(PMC *key) :no_wb {
662        PMC *hash;
663
664        GET_ATTR_hash(INTERP, SELF, hash);
665
666        if (!hash)
667            return 0;
668
669        return VTABLE_exists_keyed(INTERP, hash, key);
670    }
671
672    VTABLE void delete_keyed(PMC *key) :manual_wb {
673        PMC *hash;
674
675        GET_ATTR_hash(INTERP, SELF, hash);
676
677        if (hash) {
678            VTABLE_delete_keyed(INTERP, hash, key);
679            PARROT_GC_WRITE_BARRIER(INTERP, SELF);
680        }
681    }
682
683/*
684
685=item C<INTVAL defined_keyed_str(STRING *key)>
686
687Return true if element C<key> of the hash component is defined.
688
689=item C<INTVAL exists_keyed_str(STRING *key)>
690
691Return true if element C<key> of the hash component exists.
692
693=item C<void delete_keyed_str(STRING *key)>
694
695Delete the element corresponding to C<key> in the hash component.
696
697=cut
698
699*/
700
701    VTABLE INTVAL defined_keyed_str(STRING *key) :no_wb {
702        PMC *hash;
703
704        GET_ATTR_hash(INTERP, SELF, hash);
705
706        if (!hash)
707            return 0;
708        return VTABLE_defined_keyed_str(INTERP, hash, key);
709    }
710
711    VTABLE INTVAL exists_keyed_str(STRING *key) :no_wb {
712        PMC *hash;
713
714        GET_ATTR_hash(INTERP, SELF, hash);
715
716        if (!hash)
717            return 0;
718        return VTABLE_exists_keyed_str(INTERP, hash, key);
719    }
720
721    VTABLE void delete_keyed_str(STRING *key) :manual_wb {
722        PMC *hash;
723
724        GET_ATTR_hash(INTERP, SELF, hash);
725
726        if (hash) {
727            VTABLE_delete_keyed_str(INTERP, hash, key);
728            PARROT_GC_WRITE_BARRIER(INTERP, SELF);
729        }
730    }
731
732/*
733
734=item C<void set_pmc(PMC *capture)>
735
736Set this capture to hold the value of another.  If set to PMCNULL,
737erase the contents of the array and hash components.
738
739=cut
740
741*/
742
743    VTABLE void set_pmc(PMC *capture) {
744        if (PMC_IS_NULL(capture)) {
745            SET_ATTR_array(INTERP, SELF, NULL);
746            SET_ATTR_hash(INTERP, SELF, NULL);
747        }
748        else if (VTABLE_isa(INTERP, capture, CONST_STRING(INTERP, "Capture"))) {
749            PMC *array, *hash;
750            GET_ATTR_array(INTERP, capture, array);
751            GET_ATTR_hash(INTERP, capture, hash);
752            SET_ATTR_array(INTERP, SELF, array);
753            SET_ATTR_hash(INTERP, SELF, hash);
754            if (!PMC_IS_NULL(array) || !PMC_IS_NULL(hash))
755                PObj_custom_mark_SET(SELF);
756        }
757        else
758            Parrot_ex_throw_from_c_noargs(INTERP, EXCEPTION_INVALID_OPERATION,
759                "Can only set a capture to another capture");
760    }
761
762/*
763
764=item C<STRING get_string()>
765
766Return a string representation of the hash, showing class
767and memory address.
768
769=cut
770
771*/
772
773    VTABLE STRING *get_string() :no_wb {
774        const STRING * const classname = VTABLE_name(INTERP, SELF);
775        return Parrot_sprintf_c(INTERP, "%S[0x%lx]", classname, PTR2ULONG(SELF));
776    }
777
778/*
779
780=item C<void mark(void)>
781
782Mark the array.
783
784=cut
785
786*/
787
788    VTABLE void mark() :no_wb {
789        PMC *array, *hash;
790        GET_ATTR_array(INTERP, SELF, array);
791        GET_ATTR_hash(INTERP, SELF, hash);
792
793        Parrot_gc_mark_PMC_alive(INTERP, array);
794        Parrot_gc_mark_PMC_alive(INTERP, hash);
795    }
796
797/*
798
799=item C<void freeze()>
800
801=item C<void thaw()>
802
803Freeze/thaw Capture
804
805=cut
806
807*/
808
809    VTABLE void freeze(PMC *info) :no_wb {
810        PMC *array, *hash;
811        GET_ATTR_array(INTERP, SELF, array);
812        GET_ATTR_hash(INTERP, SELF, hash);
813
814        VTABLE_push_pmc(INTERP, info, array);
815        VTABLE_push_pmc(INTERP, info, hash);
816    }
817
818    VTABLE void thaw(PMC *info) {
819        PMC *tmp = VTABLE_shift_pmc(INTERP, info);
820        if (!PMC_IS_NULL(tmp)) {
821            SET_ATTR_array(INTERP, SELF, tmp);
822            PObj_custom_mark_SET(SELF);
823        }
824        tmp = VTABLE_shift_pmc(INTERP, info);
825        if (!PMC_IS_NULL(tmp)) {
826            SET_ATTR_hash(INTERP, SELF, tmp);
827            PObj_custom_mark_SET(SELF);
828        }
829    }
830/*
831
832=back
833
834=head2 Methods
835
836=over 4
837
838=cut
839
840*/
841
842    METHOD list() :manual_wb {
843        PMC *array;
844        PMC *capt;
845
846        /* XXX:  This workaround is for when we get here as
847                 part of a subclass of Capture */
848        if (PObj_is_object_TEST(SELF)) {
849            PMC    *classobj;
850            PMC    *ns = INTERP->root_namespace;
851
852            ns         = Parrot_ns_get_namespace_keyed_str(INTERP, ns, CONST_STRING(INTERP, "parrot"));
853            ns         = Parrot_ns_get_namespace_keyed_str(INTERP, ns, CONST_STRING(INTERP, "Capture"));
854            classobj   = Parrot_oo_get_class(INTERP, ns);
855            capt       = VTABLE_get_attr_keyed(INTERP, SELF, classobj, CONST_STRING(INTERP, "proxy"));
856        }
857        else
858            capt = SELF;
859
860        CAPTURE_array_CREATE(INTERP, capt, array);
861        RETURN(PMC *array);
862    }
863
864    METHOD hash() :manual_wb {
865        PMC *hash;
866        PMC *capt;
867        /* XXX:  This workaround is for when we get here as
868                 part of a subclass of Capture */
869        if (PObj_is_object_TEST(SELF)) {
870            STRING * const classname = CONST_STRING(INTERP, "Capture");
871            PMC    * const classobj  = Parrot_oo_get_class_str(INTERP, classname);
872
873            capt = VTABLE_get_attr_keyed(INTERP, SELF, classobj, CONST_STRING(INTERP, "proxy"));
874        }
875        else
876            capt = SELF;
877
878        CAPTURE_hash_CREATE(INTERP, capt, hash);
879
880        RETURN(PMC *hash);
881    }
882
883}
884
885/*
886
887=back
888
889=cut
890
891*/
892
893/*
894 * Local variables:
895 *   c-file-style: "parrot"
896 * End:
897 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
898 */
899