~ubuntu-branches/ubuntu/vivid/nqp/vivid-proposed

« back to all changes in this revision

Viewing changes to src/pmc/sixmodelobject.pmc

  • Committer: Package Import Robot
  • Author(s): Alessandro Ghedini
  • Date: 2013-11-01 12:09:18 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20131101120918-kx51sl0sxl3exsxi
Tags: 2013.10-1
* New upstream release
* Bump versioned (Build-)Depends on parrot
* Update patches
* Install new README.pod
* Fix vcs-field-not-canonical
* Do not install rubyish examples
* Do not Depends on parrot-devel anymore
* Add 07_disable-serialization-tests.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* A SixModelObject PMC is what actually represents an object so far as
2
 
 * the actual end user is concerned. While STable and REPR exist as
3
 
 * PMCs, they are not designed to ever really leak into user space.
4
 
 * This, on the other hand, is. In fact, pretty much everything that
5
 
 * the user ever touches will be an instance of this PMC.
6
 
 *
7
 
 * This PMC itself, however, doesn't actually contain much logic at
8
 
 * all. Mostly, it maps the Parrot world view to the Perl 6 object
9
 
 * model one. Actual object semantics are provided by the intersection
10
 
 * of the REPR and the HOW, both of which are pointed at by the STable.
11
 
 * The only thing that you can be sure of if you have a SixModelObject
12
 
 * PMC is that:
13
 
 *     PMC_data(SELF)[0]
14
 
 * Will give you the address of an STable PMC. Thus everything in here
15
 
 * should work with little more than this assumption.
16
 
 *
17
 
 * Note that this PMC is also never created directly. Instead, only a
18
 
 * REPR can create it, and in doing so it will set the data pointer to
19
 
 * point to something that can store the attributes etc and that has its
20
 
 * first element being a pointer to the STable. Thus even GC marking is
21
 
 * delegated to the REPR, since only it knows how a given object is laid
22
 
 * out (since that depends on the representation).
23
 
 */
24
 
 
25
 
#include "parrot/exceptions.h"
26
 
#include "parrot/events.h"
27
 
#include "../6model/sixmodelobject.h"
28
 
 
29
 
/* We need to know how to boolify bigints. Really need something better,
30
 
 * but this will do for now. */
31
 
#include "../../3rdparty/libtommath/tommath.h"
32
 
#include "../6model/reprs/P6bigint.h"
33
 
#define bigint_repr_id 11
34
 
 
35
 
PMC * decontainerize(PARROT_INTERP, PMC *var) {
36
 
    ContainerSpec *spec = STABLE(var)->container_spec;
37
 
    if (spec && IS_CONCRETE(var)) {
38
 
        if (!PMC_IS_NULL(spec->value_slot.class_handle)) {
39
 
            /* Just get slot. */
40
 
            return VTABLE_get_attr_keyed(interp, var, spec->value_slot.class_handle,
41
 
                spec->value_slot.attr_name);
42
 
        }
43
 
        else {
44
 
            /* Invoke FETCH method. */
45
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
46
 
            PMC *meth    = spec->fetch_method;
47
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
48
 
            VTABLE_push_pmc(interp, cappy, var);
49
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
50
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
51
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
52
 
            return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
53
 
        }
54
 
    }
55
 
    return var;
56
 
}
57
 
 
58
 
/* Looks up an attribute, after checking we don't have a type object. */
59
 
static PMC *get_attr(PARROT_INTERP, PMC *self, PMC *handle, STRING *name, INTVAL hint) {
60
 
    if (IS_CONCRETE(self))
61
 
        return REPR(self)->attr_funcs->get_attribute_boxed(interp, STABLE(self), OBJECT_BODY(self), handle, name, hint);
62
 
    else
63
 
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
64
 
            "Cannot look up attributes in a type object");
65
 
}
66
 
 
67
 
 
68
 
pmclass SixModelObject manual_attrs dynpmc group nqp {
69
 
    /* ********************************************** *
70
 
     * These methods are mapped to 6model primitives. *
71
 
     * ********************************************** */
72
 
 
73
 
    VTABLE void mark() {
74
 
        /* Mark the common bits. */
75
 
        SixModelObjectCommonalities *obj = (SixModelObjectCommonalities *)PMC_data(SELF);
76
 
        if (obj->stable)
77
 
            Parrot_gc_mark_PMC_alive(interp, obj->stable);
78
 
        if (obj->sc)
79
 
            Parrot_gc_mark_PMC_alive(interp, obj->sc);
80
 
        if (IS_CONCRETE(SELF) && REPR(SELF)->gc_mark)
81
 
            REPR(SELF)->gc_mark(interp, STABLE(SELF), OBJECT_BODY(SELF));
82
 
    }
83
 
 
84
 
    VTABLE void destroy() {
85
 
        /* Delegate to the representation. 
86
 
         * XXX There's a really nasty problem here. Since the GC provides no
87
 
         * promises about ordering, the s-table may get collected before the
88
 
         * last object pointing to it (a situation that arises when we have
89
 
         * anonymous types). That means the REPR - which knows how to free
90
 
         * the object - may be unreachable by the time we get here. Oops.
91
 
         * For now, just leak the type object memory.
92
 
         */
93
 
        STable *st = STABLE(SELF);
94
 
        if (st)
95
 
            st->REPR->gc_free(interp, _self);
96
 
    }
97
 
 
98
 
    VTABLE PMC * find_method(STRING *name) {
99
 
        PMC *decont = decontainerize(interp, SELF);
100
 
        return STABLE(decont)->find_method(interp, decont, name, NO_HINT);
101
 
    }
102
 
 
103
 
    VTABLE PMC* get_attr_keyed(PMC *class_handle, STRING *name) {
104
 
        if (class_handle->vtable->base_type == SELF->vtable->base_type) {
105
 
            PMC *handle = decontainerize(interp, class_handle);
106
 
            PMC *result = get_attr(interp, SELF, handle, name, NO_HINT);
107
 
            PARROT_GC_WRITE_BARRIER(interp, SELF);
108
 
            return result;
109
 
        }
110
 
        else {
111
 
            Parrot_ex_throw_from_c_args(interp, NULL, 1,
112
 
                "Class handle in attribute lookup must be a SixModelObject");
113
 
        }
114
 
    }
115
 
 
116
 
    VTABLE void set_attr_keyed(PMC *class_handle, STRING *name, PMC *value) {
117
 
        if (class_handle->vtable->base_type == SELF->vtable->base_type) {
118
 
            PMC *handle = decontainerize(interp, class_handle);
119
 
            if (IS_CONCRETE(SELF))
120
 
                REPR(SELF)->attr_funcs->bind_attribute_boxed(interp, STABLE(SELF), OBJECT_BODY(SELF), handle, name, NO_HINT, value);
121
 
            else
122
 
                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
123
 
                    "Cannot bind attributes in a type object");
124
 
        }
125
 
        else {
126
 
            Parrot_ex_throw_from_c_args(interp, NULL, 1,
127
 
                "Class handle in attribute bind must be a SixModelObject");
128
 
        }
129
 
    }
130
 
    
131
 
    VTABLE STRING * name() {
132
 
        return VTABLE_get_string(interp, VTABLE_get_class(interp, SELF));
133
 
    }
134
 
    
135
 
    VTABLE PMC * get_class() {
136
 
        PMC *decont    = decontainerize(interp, SELF);
137
 
        PMC *how       = STABLE(decont)->HOW;
138
 
        PMC *name_meth = VTABLE_find_method(interp, how, CONST_STRING(interp, "name"));
139
 
        if (!PMC_IS_NULL(name_meth)) {
140
 
            PMC *old_ctx   = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
141
 
            PMC *cappy     = Parrot_pmc_new(interp, enum_class_CallContext);
142
 
            INTVAL tf      = CONTEXT_STRUCT(CURRENT_CONTEXT(interp))->trace_flags;
143
 
            CONTEXT_STRUCT(CURRENT_CONTEXT(interp))->trace_flags = 0;
144
 
            VTABLE_push_pmc(interp, cappy, how);
145
 
            VTABLE_push_pmc(interp, cappy, decont);
146
 
            Parrot_pcc_invoke_from_sig_object(interp, name_meth, cappy);
147
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
148
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
149
 
            CONTEXT_STRUCT(CURRENT_CONTEXT(interp))->trace_flags = tf;
150
 
            return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
151
 
        }
152
 
        else
153
 
            return SUPER();
154
 
    }
155
 
    
156
 
    /* XXX Hack for Parrot issue which needs invokable on stuff. */
157
 
    VTABLE INTVAL does(STRING *what) {
158
 
        UNUSED(SELF)
159
 
        return Parrot_str_equal(interp, what, CONST_STRING(interp, "invokable"));
160
 
    }
161
 
    
162
 
    VTABLE INTVAL can(STRING *name) {
163
 
        PMC *decont = decontainerize(interp, SELF);
164
 
        PMC *meth   = STABLE(decont)->find_method(interp, decont, name, NO_HINT);
165
 
        return !PMC_IS_NULL(meth) &&
166
 
            (meth->vtable->base_type != decont->vtable->base_type || IS_CONCRETE(meth));
167
 
    }
168
 
    
169
 
    VTABLE PMC *clone() {
170
 
        UNUSED(SELF)
171
 
        Parrot_ex_throw_from_c_args(interp, NULL, 1,
172
 
            "SixModelObject does not support the clone v-table; consider using the repr_clone op instead");
173
 
    }
174
 
 
175
 
    /* ********************************************************* *
176
 
     * These v-table methods are overridable by a 6model object. *
177
 
     * ********************************************************* */
178
 
 
179
 
    VTABLE INTVAL defined() {
180
 
        PMC *decont = decontainerize(interp, SELF);
181
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
182
 
        PMC *meth;
183
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_DEFINED])) {
184
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
185
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
186
 
            VTABLE_push_pmc(interp, cappy, decont);
187
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
188
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
189
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
190
 
            return VTABLE_get_integer_keyed_int(interp, cappy, 0);
191
 
        }
192
 
        else
193
 
            return SUPER();
194
 
    }
195
 
 
196
 
    VTABLE FLOATVAL get_number() {
197
 
        PMC *decont = decontainerize(interp, SELF);
198
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
199
 
        PMC *meth;
200
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_GET_NUMBER])) {
201
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
202
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
203
 
            VTABLE_push_pmc(interp, cappy, decont);
204
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
205
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
206
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
207
 
            return VTABLE_get_number_keyed_int(interp, cappy, 0);
208
 
        }
209
 
        else
210
 
            return SUPER();
211
 
    }
212
 
 
213
 
    VTABLE INTVAL get_integer() {
214
 
        PMC *decont = decontainerize(interp, SELF);
215
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
216
 
        PMC *meth;
217
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_GET_INTEGER])) {
218
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
219
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
220
 
            VTABLE_push_pmc(interp, cappy, decont);
221
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
222
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
223
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
224
 
            return VTABLE_get_integer_keyed_int(interp, cappy, 0);
225
 
        }
226
 
        else
227
 
            return SUPER();
228
 
    }
229
 
 
230
 
    VTABLE STRING * get_string() {
231
 
        PMC *decont = decontainerize(interp, SELF);
232
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
233
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
234
 
        PMC *meth;
235
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_GET_STRING])) {
236
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
237
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
238
 
            VTABLE_push_pmc(interp, cappy, decont);
239
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
240
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
241
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
242
 
            return VTABLE_get_string_keyed_int(interp, cappy, 0);
243
 
        }
244
 
        else if (vth && vth[PARROT_VTABLE_SLOT_GET_STRING].class_handle) {
245
 
            PMC *val = get_attr(interp, decont,
246
 
                                vth[PARROT_VTABLE_SLOT_GET_STRING].class_handle,
247
 
                                vth[PARROT_VTABLE_SLOT_GET_STRING].attr_name,
248
 
                                vth[PARROT_VTABLE_SLOT_GET_STRING].hint);
249
 
            return VTABLE_get_string(interp, val);
250
 
        }
251
 
        else
252
 
            return SUPER();
253
 
    }
254
 
 
255
 
    VTABLE INTVAL get_bool() {
256
 
        PMC *decont = decontainerize(interp, SELF);
257
 
        if (STABLE(decont)->boolification_spec) {
258
 
            PMC      *old_ctx, *cappy;
259
 
            FLOATVAL unnum;
260
 
            STRING   *unstr;
261
 
            switch (STABLE(decont)->boolification_spec->mode) {
262
 
                case BOOL_MODE_CALL_METHOD:
263
 
                    old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
264
 
                    cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
265
 
                    VTABLE_push_pmc(interp, cappy, SELF);
266
 
                    Parrot_pcc_invoke_from_sig_object(interp, STABLE(decont)->boolification_spec->method, cappy);
267
 
                    cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
268
 
                    Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
269
 
                    return VTABLE_get_bool(interp, VTABLE_get_pmc_keyed_int(interp, cappy, 0));
270
 
                case BOOL_MODE_UNBOX_INT:
271
 
                    return IS_CONCRETE(decont) &&
272
 
                        REPR(decont)->box_funcs->get_int(interp, STABLE(decont), OBJECT_BODY(decont));
273
 
                case BOOL_MODE_UNBOX_NUM:
274
 
                    if (!IS_CONCRETE(decont))
275
 
                        return 0;
276
 
                    unnum = REPR(decont)->box_funcs->get_num(interp, STABLE(decont), OBJECT_BODY(decont));
277
 
                    return unnum != 0.0;
278
 
                case BOOL_MODE_UNBOX_STR_NOT_EMPTY:
279
 
                    if (!IS_CONCRETE(decont))
280
 
                        return 0;
281
 
                    unstr = REPR(decont)->box_funcs->get_str(interp, STABLE(decont), OBJECT_BODY(decont));
282
 
                    return !STRING_IS_NULL(unstr) &&
283
 
                        !Parrot_str_equal(interp, unstr, CONST_STRING(interp, ""));
284
 
                case BOOL_MODE_UNBOX_STR_NOT_EMPTY_OR_ZERO:
285
 
                    if (!IS_CONCRETE(decont))
286
 
                        return 0;
287
 
                    unstr = REPR(decont)->box_funcs->get_str(interp, STABLE(decont), OBJECT_BODY(decont));
288
 
                    return !STRING_IS_NULL(unstr) &&
289
 
                        !Parrot_str_equal(interp, unstr, CONST_STRING(interp, "")) &&
290
 
                        !Parrot_str_equal(interp, unstr, CONST_STRING(interp, "0"));
291
 
                case BOOL_MODE_NOT_TYPE_OBJECT:
292
 
                    return IS_CONCRETE(decont);
293
 
                case BOOL_MODE_BIGINT:
294
 
                    if (IS_CONCRETE(decont)) {
295
 
                        struct SixModel_REPROps *r = REPR(decont);
296
 
                        if (r->ID == bigint_repr_id)
297
 
                            return !mp_iszero(&((P6bigintInstance *)PMC_data(decont))->body.i);
298
 
                        else
299
 
                            return !mp_iszero(&((P6bigintBody *)r->box_funcs->get_boxed_ref(interp,
300
 
                                STABLE(decont), OBJECT_BODY(decont), bigint_repr_id))->i);
301
 
                    }
302
 
                    return 0;
303
 
                default:
304
 
                    return SUPER();
305
 
            }
306
 
        }
307
 
        else
308
 
            return SUPER();
309
 
    }
310
 
    
311
 
    VTABLE PMC * get_pmc_keyed(PMC *key) {
312
 
        if (key->vtable->base_type == enum_class_Key) {
313
 
            if (PObj_get_FLAGS(key) & KEY_integer_FLAG)
314
 
                return SELF.get_pmc_keyed_int(VTABLE_get_integer(interp, key));
315
 
            else
316
 
                return SELF.get_pmc_keyed_str(VTABLE_get_string(interp, key));
317
 
        }
318
 
        else {
319
 
            PMC *decont = decontainerize(interp, SELF);
320
 
            PMC **vt = STABLE(decont)->parrot_vtable_mapping;
321
 
            PMC *meth;
322
 
            AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
323
 
            if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_GET_PMC_KEYED])) {
324
 
                PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
325
 
                PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
326
 
                VTABLE_push_pmc(interp, cappy, decont);
327
 
                VTABLE_push_pmc(interp, cappy, key);
328
 
                Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
329
 
                cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
330
 
                Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
331
 
                return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
332
 
            }
333
 
            else if (vth && vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED].class_handle) {
334
 
                PMC *val = get_attr(interp, decont,
335
 
                                    vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED].class_handle,
336
 
                                    vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED].attr_name,
337
 
                                    vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED].hint);
338
 
                return VTABLE_get_pmc_keyed(interp, val, key);
339
 
            }
340
 
            else
341
 
                return REPR(decont)->ass_funcs->at_key_boxed(interp, STABLE(decont),
342
 
                    OBJECT_BODY(decont), VTABLE_get_string(interp, key));
343
 
        }
344
 
    }
345
 
    
346
 
    VTABLE PMC * get_pmc_keyed_int(INTVAL key) {
347
 
        PMC *decont = decontainerize(interp, SELF);
348
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
349
 
        PMC *meth;
350
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
351
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_GET_PMC_KEYED_INT])) {
352
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
353
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
354
 
            VTABLE_push_pmc(interp, cappy, decont);
355
 
            VTABLE_push_integer(interp, cappy, key);
356
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
357
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
358
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
359
 
            return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
360
 
        }
361
 
        else if (vth && vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_INT].class_handle) {
362
 
            PMC *val = get_attr(interp, decont,
363
 
                                vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_INT].class_handle,
364
 
                                vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_INT].attr_name,
365
 
                                vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_INT].hint);
366
 
            return VTABLE_get_pmc_keyed_int(interp, val, key);
367
 
        }
368
 
        else
369
 
            return REPR(decont)->pos_funcs->at_pos_boxed(interp, STABLE(decont),
370
 
                OBJECT_BODY(decont), key);
371
 
    }
372
 
 
373
 
    VTABLE PMC * get_pmc_keyed_str(STRING *key) {
374
 
        PMC *decont = decontainerize(interp, SELF);
375
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
376
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
377
 
        PMC *meth;
378
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_GET_PMC_KEYED_STR])) {
379
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
380
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
381
 
            VTABLE_push_pmc(interp, cappy, decont);
382
 
            VTABLE_push_string(interp, cappy, key);
383
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
384
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
385
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
386
 
            return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
387
 
        }
388
 
        else if (vth && vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_STR].class_handle) {
389
 
            PMC *val = get_attr(interp, decont,
390
 
                                vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_STR].class_handle,
391
 
                                vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_STR].attr_name,
392
 
                                vth[PARROT_VTABLE_SLOT_GET_PMC_KEYED_STR].hint);
393
 
            return VTABLE_get_pmc_keyed_str(interp, val, key);
394
 
        }
395
 
        else
396
 
            return REPR(decont)->ass_funcs->at_key_boxed(interp, STABLE(decont),
397
 
                OBJECT_BODY(decont), key);
398
 
    }
399
 
    
400
 
    VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
401
 
        if (key->vtable->base_type == enum_class_Key) {
402
 
            if (PObj_get_FLAGS(key) & KEY_integer_FLAG)
403
 
                SELF.set_pmc_keyed_int(VTABLE_get_integer(interp, key), value);
404
 
            else
405
 
                SELF.set_pmc_keyed_str(VTABLE_get_string(interp, key), value);
406
 
        }
407
 
        else {
408
 
            PMC *decont = decontainerize(interp, SELF);
409
 
            PMC **vt = STABLE(decont)->parrot_vtable_mapping;
410
 
            PMC *meth;
411
 
            AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
412
 
            if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_SET_PMC_KEYED])) {
413
 
                PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
414
 
                PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
415
 
                VTABLE_push_pmc(interp, cappy, decont);
416
 
                VTABLE_push_pmc(interp, cappy, key);
417
 
                VTABLE_push_pmc(interp, cappy, value);
418
 
                Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
419
 
                Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
420
 
            }
421
 
            else if (vth && vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED].class_handle) {
422
 
                PMC *val = get_attr(interp, decont,
423
 
                                    vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED].class_handle,
424
 
                                    vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED].attr_name,
425
 
                                    vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED].hint);
426
 
                VTABLE_set_pmc_keyed(interp, val, key, value);
427
 
            }
428
 
            else
429
 
              REPR(decont)->ass_funcs->bind_key_boxed(interp, STABLE(decont),
430
 
                OBJECT_BODY(decont), VTABLE_get_string(interp, key), value);
431
 
        }
432
 
    }
433
 
    
434
 
    VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
435
 
        PMC *decont = decontainerize(interp, SELF);
436
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
437
 
        PMC *meth;
438
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
439
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_SET_PMC_KEYED_INT])) {
440
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
441
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
442
 
            VTABLE_push_pmc(interp, cappy, decont);
443
 
            VTABLE_push_integer(interp, cappy, key);
444
 
            VTABLE_push_pmc(interp, cappy, value);
445
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
446
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
447
 
        }
448
 
        else if (vth && vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_INT].class_handle) {
449
 
            PMC *val = get_attr(interp, decont,
450
 
                                vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_INT].class_handle,
451
 
                                vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_INT].attr_name,
452
 
                                vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_INT].hint);
453
 
            VTABLE_set_pmc_keyed_int(interp, val, key, value);
454
 
        }
455
 
        else
456
 
            REPR(decont)->pos_funcs->bind_pos_boxed(interp, STABLE(decont),
457
 
                OBJECT_BODY(decont), key, value);
458
 
    }
459
 
    
460
 
    VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
461
 
        PMC *decont = decontainerize(interp, SELF);
462
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
463
 
        PMC *meth;
464
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
465
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_SET_PMC_KEYED_STR])) {
466
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
467
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
468
 
            VTABLE_push_pmc(interp, cappy, decont);
469
 
            VTABLE_push_string(interp, cappy, key);
470
 
            VTABLE_push_pmc(interp, cappy, value);
471
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
472
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
473
 
        }
474
 
        else if (vth && vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_STR].class_handle) {
475
 
            PMC *val = get_attr(interp, decont,
476
 
                                vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_STR].class_handle,
477
 
                                vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_STR].attr_name,
478
 
                                vth[PARROT_VTABLE_SLOT_SET_PMC_KEYED_STR].hint);
479
 
            VTABLE_set_pmc_keyed_str(interp, val, key, value);
480
 
        }
481
 
        else
482
 
            REPR(decont)->ass_funcs->bind_key_boxed(interp, STABLE(decont),
483
 
                OBJECT_BODY(decont), key, value);
484
 
    }
485
 
 
486
 
    VTABLE INTVAL exists_keyed(PMC *key) {
487
 
        if (key->vtable->base_type == enum_class_Key) {
488
 
            if (PObj_get_FLAGS(key) & KEY_integer_FLAG)
489
 
                return SELF.exists_keyed_int(VTABLE_get_integer(interp, key));
490
 
            else
491
 
                return SELF.exists_keyed_str(VTABLE_get_string(interp, key));
492
 
        }
493
 
        else {
494
 
            PMC *decont = decontainerize(interp, SELF);
495
 
            PMC **vt = STABLE(decont)->parrot_vtable_mapping;
496
 
            PMC *meth;
497
 
            AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
498
 
            if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_EXISTS_KEYED])) {
499
 
                PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
500
 
                PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
501
 
                VTABLE_push_pmc(interp, cappy, decont);
502
 
                VTABLE_push_pmc(interp, cappy, key);
503
 
                Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
504
 
                cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
505
 
                Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
506
 
                return VTABLE_get_integer_keyed_int(interp, cappy, 0);
507
 
            }
508
 
            else if (vth && vth[PARROT_VTABLE_SLOT_EXISTS_KEYED].class_handle) {
509
 
                PMC *val = get_attr(interp, decont,
510
 
                                    vth[PARROT_VTABLE_SLOT_EXISTS_KEYED].class_handle,
511
 
                                    vth[PARROT_VTABLE_SLOT_EXISTS_KEYED].attr_name,
512
 
                                    vth[PARROT_VTABLE_SLOT_EXISTS_KEYED].hint);
513
 
                return VTABLE_exists_keyed(interp, val, key);
514
 
            }
515
 
            else
516
 
                return REPR(decont)->ass_funcs->exists_key(interp, STABLE(decont),
517
 
                    OBJECT_BODY(decont), VTABLE_get_string(interp, key));
518
 
        }
519
 
    }
520
 
 
521
 
    VTABLE INTVAL exists_keyed_int(INTVAL key) {
522
 
        PMC *decont = decontainerize(interp, SELF);
523
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
524
 
        PMC *meth;
525
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
526
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_EXISTS_KEYED_INT])) {
527
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
528
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
529
 
            VTABLE_push_pmc(interp, cappy, decont);
530
 
            VTABLE_push_integer(interp, cappy, key);
531
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
532
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
533
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
534
 
            return VTABLE_get_integer_keyed_int(interp, cappy, 0);
535
 
        }
536
 
        else
537
 
            return SUPER(key);
538
 
    }
539
 
 
540
 
    VTABLE INTVAL exists_keyed_str(STRING *key) {
541
 
        PMC *decont = decontainerize(interp, SELF);
542
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
543
 
        PMC *meth;
544
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
545
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_EXISTS_KEYED_STR])) {
546
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
547
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
548
 
            VTABLE_push_pmc(interp, cappy, decont);
549
 
            VTABLE_push_string(interp, cappy, key);
550
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
551
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
552
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
553
 
            return VTABLE_get_integer_keyed_int(interp, cappy, 0);
554
 
        }
555
 
        else if (vth && vth[PARROT_VTABLE_SLOT_EXISTS_KEYED_STR].class_handle) {
556
 
            PMC *val = get_attr(interp, decont,
557
 
                                vth[PARROT_VTABLE_SLOT_EXISTS_KEYED_STR].class_handle,
558
 
                                vth[PARROT_VTABLE_SLOT_EXISTS_KEYED_STR].attr_name,
559
 
                                vth[PARROT_VTABLE_SLOT_EXISTS_KEYED_STR].hint);
560
 
            return VTABLE_exists_keyed_str(interp, val, key);
561
 
        }
562
 
        else
563
 
            return REPR(decont)->ass_funcs->exists_key(interp, STABLE(decont),
564
 
                OBJECT_BODY(decont), key);
565
 
    }
566
 
 
567
 
    VTABLE void delete_keyed(PMC *key) {
568
 
        if (key->vtable->base_type == enum_class_Key) {
569
 
            if (PObj_get_FLAGS(key) & KEY_integer_FLAG)
570
 
                SELF.delete_keyed_int(VTABLE_get_integer(interp, key));
571
 
            else
572
 
                SELF.delete_keyed_str(VTABLE_get_string(interp, key));
573
 
        }
574
 
        else {
575
 
            PMC *decont = decontainerize(interp, SELF);
576
 
            PMC **vt = STABLE(decont)->parrot_vtable_mapping;
577
 
            PMC *meth;
578
 
            AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
579
 
            if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_DELETE_KEYED])) {
580
 
                PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
581
 
                PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
582
 
                VTABLE_push_pmc(interp, cappy, decont);
583
 
                VTABLE_push_pmc(interp, cappy, key);
584
 
                Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
585
 
                cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
586
 
                Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
587
 
            }
588
 
            else if (vth && vth[PARROT_VTABLE_SLOT_DELETE_KEYED].class_handle) {
589
 
                PMC *val = get_attr(interp, decont,
590
 
                                    vth[PARROT_VTABLE_SLOT_DELETE_KEYED].class_handle,
591
 
                                    vth[PARROT_VTABLE_SLOT_DELETE_KEYED].attr_name,
592
 
                                    vth[PARROT_VTABLE_SLOT_DELETE_KEYED].hint);
593
 
                VTABLE_delete_keyed(interp, val, key);
594
 
            }
595
 
            else
596
 
                REPR(decont)->ass_funcs->delete_key(interp, STABLE(decont),
597
 
                    OBJECT_BODY(decont), VTABLE_get_string(interp, key));
598
 
        }
599
 
    }
600
 
 
601
 
    VTABLE void delete_keyed_int(INTVAL key) {
602
 
        PMC *decont = decontainerize(interp, SELF);
603
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
604
 
        PMC *meth;
605
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
606
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_DELETE_KEYED_INT])) {
607
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
608
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
609
 
            VTABLE_push_pmc(interp, cappy, decont);
610
 
            VTABLE_push_integer(interp, cappy, key);
611
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
612
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
613
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
614
 
        }
615
 
        else
616
 
            SUPER(key);
617
 
    }
618
 
 
619
 
    VTABLE void delete_keyed_str(STRING *key) {
620
 
        PMC *decont = decontainerize(interp, SELF);
621
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
622
 
        PMC *meth;
623
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
624
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_DELETE_KEYED_STR])) {
625
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
626
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
627
 
            VTABLE_push_pmc(interp, cappy, decont);
628
 
            VTABLE_push_string(interp, cappy, key);
629
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
630
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
631
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
632
 
        }
633
 
        else if (vth && vth[PARROT_VTABLE_SLOT_DELETE_KEYED_STR].class_handle) {
634
 
            PMC *val = get_attr(interp, decont,
635
 
                                vth[PARROT_VTABLE_SLOT_DELETE_KEYED_STR].class_handle,
636
 
                                vth[PARROT_VTABLE_SLOT_DELETE_KEYED_STR].attr_name,
637
 
                                vth[PARROT_VTABLE_SLOT_DELETE_KEYED_STR].hint);
638
 
            VTABLE_delete_keyed_str(interp, val, key);
639
 
        }
640
 
        else
641
 
            REPR(decont)->ass_funcs->delete_key(interp, STABLE(decont),
642
 
                OBJECT_BODY(decont), key);
643
 
    }
644
 
    
645
 
    VTABLE void unshift_pmc(PMC *value) {
646
 
        PMC *decont = decontainerize(interp, SELF);
647
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
648
 
        PMC *meth;
649
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
650
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_UNSHIFT_PMC])) {
651
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
652
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
653
 
            VTABLE_push_pmc(interp, cappy, decont);
654
 
            VTABLE_push_pmc(interp, cappy, value);
655
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
656
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
657
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
658
 
        }
659
 
        else if (vth && vth[PARROT_VTABLE_SLOT_UNSHIFT_PMC].class_handle) {
660
 
            PMC *val = get_attr(interp, decont,
661
 
                                vth[PARROT_VTABLE_SLOT_UNSHIFT_PMC].class_handle,
662
 
                                vth[PARROT_VTABLE_SLOT_UNSHIFT_PMC].attr_name,
663
 
                                vth[PARROT_VTABLE_SLOT_UNSHIFT_PMC].hint);
664
 
            VTABLE_unshift_pmc(interp, val, value);
665
 
        }
666
 
        else
667
 
            REPR(decont)->pos_funcs->unshift_boxed(interp, STABLE(decont),
668
 
                OBJECT_BODY(decont), value);
669
 
    }
670
 
    
671
 
    VTABLE void push_pmc(PMC *value) {
672
 
        PMC *decont = decontainerize(interp, SELF);
673
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
674
 
        PMC *meth;
675
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
676
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_PUSH_PMC])) {
677
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
678
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
679
 
            VTABLE_push_pmc(interp, cappy, decont);
680
 
            VTABLE_push_pmc(interp, cappy, value);
681
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
682
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
683
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
684
 
        }
685
 
        else if (vth && vth[PARROT_VTABLE_SLOT_PUSH_PMC].class_handle) {
686
 
            PMC *val = get_attr(interp, decont,
687
 
                                vth[PARROT_VTABLE_SLOT_PUSH_PMC].class_handle,
688
 
                                vth[PARROT_VTABLE_SLOT_PUSH_PMC].attr_name,
689
 
                                vth[PARROT_VTABLE_SLOT_PUSH_PMC].hint);
690
 
            VTABLE_push_pmc(interp, val, value);
691
 
        }
692
 
        else
693
 
            REPR(decont)->pos_funcs->push_boxed(interp, STABLE(decont),
694
 
                OBJECT_BODY(decont), value);
695
 
    }
696
 
 
697
 
    VTABLE opcode_t *invoke(void *next) {
698
 
        PMC *decont = decontainerize(interp, SELF);
699
 
        
700
 
        /* First, see if we've an invocation spec. */
701
 
        InvocationSpec *is = STABLE(decont)->invocation_spec;
702
 
        if (is) {
703
 
            if (is->value_slot.class_handle) {
704
 
                PMC *val = get_attr(interp, decont, is->value_slot.class_handle,
705
 
                    is->value_slot.attr_name, is->value_slot.hint);
706
 
                return VTABLE_invoke(interp, val, next);
707
 
            }
708
 
            else {
709
 
                return VTABLE_invoke(interp, is->invocation_handler, next);
710
 
            }
711
 
        }
712
 
        
713
 
        /* Otherwise - for back-compat - fall back to Parrot v-table mapping. */
714
 
        else {
715
 
            PMC **vt = STABLE(decont)->parrot_vtable_mapping;
716
 
            PMC *meth;
717
 
            AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
718
 
            if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_INVOKE])) {
719
 
                PMC *cur_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
720
 
                VTABLE_unshift_pmc(interp, cur_ctx, decont);
721
 
                Parrot_pcc_invoke_from_sig_object(interp, meth, cur_ctx);
722
 
                return (opcode_t *)next;
723
 
            }
724
 
            else if (vth && vth[PARROT_VTABLE_SLOT_INVOKE].class_handle) {
725
 
                PMC *val = get_attr(interp, decont,
726
 
                                    vth[PARROT_VTABLE_SLOT_INVOKE].class_handle,
727
 
                                    vth[PARROT_VTABLE_SLOT_INVOKE].attr_name,
728
 
                                    vth[PARROT_VTABLE_SLOT_INVOKE].hint);
729
 
                return VTABLE_invoke(interp, val, next);
730
 
            }
731
 
            else
732
 
                return SUPER(next);
733
 
        }
734
 
    }
735
 
    
736
 
    VTABLE PMC * get_iter() {
737
 
        PMC *decont = decontainerize(interp, SELF);
738
 
        PMC **vt = STABLE(decont)->parrot_vtable_mapping;
739
 
        AttributeIdentifier *vth = STABLE(decont)->parrot_vtable_handler_mapping;
740
 
        PMC *meth;
741
 
        if (vt && !PMC_IS_NULL(meth = vt[PARROT_VTABLE_SLOT_GET_ITER])) {
742
 
            PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
743
 
            PMC *cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
744
 
            VTABLE_push_pmc(interp, cappy, decont);
745
 
            Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
746
 
            cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
747
 
            Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
748
 
            return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
749
 
        }
750
 
        else if (vth && vth[PARROT_VTABLE_SLOT_GET_ITER].class_handle) {
751
 
            PMC *val = get_attr(interp, decont,
752
 
                                vth[PARROT_VTABLE_SLOT_GET_ITER].class_handle,
753
 
                                vth[PARROT_VTABLE_SLOT_GET_ITER].attr_name,
754
 
                                vth[PARROT_VTABLE_SLOT_GET_ITER].hint);
755
 
            return VTABLE_get_iter(interp, val);
756
 
        }
757
 
        else
758
 
            return SUPER();
759
 
    }
760
 
}
761
 
 
762
 
/*
763
 
 * Local variables:
764
 
 *   c-file-style: "parrot"
765
 
 * End:
766
 
 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
767
 
 */