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.
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
14
* Will give you the address of an STable PMC. Thus everything in here
15
* should work with little more than this assumption.
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).
25
#include "parrot/exceptions.h"
26
#include "parrot/events.h"
27
#include "../6model/sixmodelobject.h"
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
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)) {
40
return VTABLE_get_attr_keyed(interp, var, spec->value_slot.class_handle,
41
spec->value_slot.attr_name);
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);
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);
63
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
64
"Cannot look up attributes in a type object");
68
pmclass SixModelObject manual_attrs dynpmc group nqp {
69
/* ********************************************** *
70
* These methods are mapped to 6model primitives. *
71
* ********************************************** */
74
/* Mark the common bits. */
75
SixModelObjectCommonalities *obj = (SixModelObjectCommonalities *)PMC_data(SELF);
77
Parrot_gc_mark_PMC_alive(interp, obj->stable);
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));
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.
93
STable *st = STABLE(SELF);
95
st->REPR->gc_free(interp, _self);
98
VTABLE PMC * find_method(STRING *name) {
99
PMC *decont = decontainerize(interp, SELF);
100
return STABLE(decont)->find_method(interp, decont, name, NO_HINT);
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);
111
Parrot_ex_throw_from_c_args(interp, NULL, 1,
112
"Class handle in attribute lookup must be a SixModelObject");
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);
122
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
123
"Cannot bind attributes in a type object");
126
Parrot_ex_throw_from_c_args(interp, NULL, 1,
127
"Class handle in attribute bind must be a SixModelObject");
131
VTABLE STRING * name() {
132
return VTABLE_get_string(interp, VTABLE_get_class(interp, SELF));
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);
156
/* XXX Hack for Parrot issue which needs invokable on stuff. */
157
VTABLE INTVAL does(STRING *what) {
159
return Parrot_str_equal(interp, what, CONST_STRING(interp, "invokable"));
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));
169
VTABLE PMC *clone() {
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");
175
/* ********************************************************* *
176
* These v-table methods are overridable by a 6model object. *
177
* ********************************************************* */
179
VTABLE INTVAL defined() {
180
PMC *decont = decontainerize(interp, SELF);
181
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
196
VTABLE FLOATVAL get_number() {
197
PMC *decont = decontainerize(interp, SELF);
198
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
213
VTABLE INTVAL get_integer() {
214
PMC *decont = decontainerize(interp, SELF);
215
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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;
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);
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);
255
VTABLE INTVAL get_bool() {
256
PMC *decont = decontainerize(interp, SELF);
257
if (STABLE(decont)->boolification_spec) {
258
PMC *old_ctx, *cappy;
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))
276
unnum = REPR(decont)->box_funcs->get_num(interp, STABLE(decont), OBJECT_BODY(decont));
278
case BOOL_MODE_UNBOX_STR_NOT_EMPTY:
279
if (!IS_CONCRETE(decont))
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))
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);
299
return !mp_iszero(&((P6bigintBody *)r->box_funcs->get_boxed_ref(interp,
300
STABLE(decont), OBJECT_BODY(decont), bigint_repr_id))->i);
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));
316
return SELF.get_pmc_keyed_str(VTABLE_get_string(interp, key));
319
PMC *decont = decontainerize(interp, SELF);
320
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
341
return REPR(decont)->ass_funcs->at_key_boxed(interp, STABLE(decont),
342
OBJECT_BODY(decont), VTABLE_get_string(interp, key));
346
VTABLE PMC * get_pmc_keyed_int(INTVAL key) {
347
PMC *decont = decontainerize(interp, SELF);
348
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
369
return REPR(decont)->pos_funcs->at_pos_boxed(interp, STABLE(decont),
370
OBJECT_BODY(decont), key);
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;
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);
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);
396
return REPR(decont)->ass_funcs->at_key_boxed(interp, STABLE(decont),
397
OBJECT_BODY(decont), key);
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);
405
SELF.set_pmc_keyed_str(VTABLE_get_string(interp, key), value);
408
PMC *decont = decontainerize(interp, SELF);
409
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
429
REPR(decont)->ass_funcs->bind_key_boxed(interp, STABLE(decont),
430
OBJECT_BODY(decont), VTABLE_get_string(interp, key), value);
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;
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);
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);
456
REPR(decont)->pos_funcs->bind_pos_boxed(interp, STABLE(decont),
457
OBJECT_BODY(decont), key, value);
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;
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);
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);
482
REPR(decont)->ass_funcs->bind_key_boxed(interp, STABLE(decont),
483
OBJECT_BODY(decont), key, value);
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));
491
return SELF.exists_keyed_str(VTABLE_get_string(interp, key));
494
PMC *decont = decontainerize(interp, SELF);
495
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
516
return REPR(decont)->ass_funcs->exists_key(interp, STABLE(decont),
517
OBJECT_BODY(decont), VTABLE_get_string(interp, key));
521
VTABLE INTVAL exists_keyed_int(INTVAL key) {
522
PMC *decont = decontainerize(interp, SELF);
523
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
540
VTABLE INTVAL exists_keyed_str(STRING *key) {
541
PMC *decont = decontainerize(interp, SELF);
542
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
563
return REPR(decont)->ass_funcs->exists_key(interp, STABLE(decont),
564
OBJECT_BODY(decont), key);
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));
572
SELF.delete_keyed_str(VTABLE_get_string(interp, key));
575
PMC *decont = decontainerize(interp, SELF);
576
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
596
REPR(decont)->ass_funcs->delete_key(interp, STABLE(decont),
597
OBJECT_BODY(decont), VTABLE_get_string(interp, key));
601
VTABLE void delete_keyed_int(INTVAL key) {
602
PMC *decont = decontainerize(interp, SELF);
603
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
619
VTABLE void delete_keyed_str(STRING *key) {
620
PMC *decont = decontainerize(interp, SELF);
621
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
641
REPR(decont)->ass_funcs->delete_key(interp, STABLE(decont),
642
OBJECT_BODY(decont), key);
645
VTABLE void unshift_pmc(PMC *value) {
646
PMC *decont = decontainerize(interp, SELF);
647
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
667
REPR(decont)->pos_funcs->unshift_boxed(interp, STABLE(decont),
668
OBJECT_BODY(decont), value);
671
VTABLE void push_pmc(PMC *value) {
672
PMC *decont = decontainerize(interp, SELF);
673
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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);
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);
693
REPR(decont)->pos_funcs->push_boxed(interp, STABLE(decont),
694
OBJECT_BODY(decont), value);
697
VTABLE opcode_t *invoke(void *next) {
698
PMC *decont = decontainerize(interp, SELF);
700
/* First, see if we've an invocation spec. */
701
InvocationSpec *is = STABLE(decont)->invocation_spec;
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);
709
return VTABLE_invoke(interp, is->invocation_handler, next);
713
/* Otherwise - for back-compat - fall back to Parrot v-table mapping. */
715
PMC **vt = STABLE(decont)->parrot_vtable_mapping;
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;
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);
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;
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);
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);
764
* c-file-style: "parrot"
766
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :