fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / pmc / default.pmc
bloba7c33df6862d3c55e90c26ca6e0a15805582bbe1
1 /*
2 Copyright (C) 2001-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/default.pmc - Abstract root class
9 =head1 DESCRIPTION
11 These are the vtable functions for the default PMC class.
13 All methods which are not defined here get a default implementation
14 generated from F<src/vtable.tbl> by F<tools/build/pmc2c.pl>.
16 =head2 Functions
18 =over 4
20 =cut
24 #define INT2KEY(i, k) key_new_integer((i), (k))
26 /* HEADERIZER HFILE: none */
27 /* HEADERIZER BEGIN: static */
28 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
30 PARROT_CANNOT_RETURN_NULL
31 PARROT_WARN_UNUSED_RESULT
32 static STRING * caller(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc))
33         __attribute__nonnull__(1);
35 PARROT_DOES_NOT_RETURN
36 static void cant_do_method(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), int index)
37         __attribute__nonnull__(1);
39 PARROT_DOES_NOT_RETURN
40 static void cant_do_write_method(PARROT_INTERP,
41     ARGIN_NULLOK(PMC *pmc),
42     int index)
43         __attribute__nonnull__(1);
45 PARROT_WARN_UNUSED_RESULT
46 PARROT_CAN_RETURN_NULL
47 static PMC* check_get_std_props(PARROT_INTERP,
48     ARGIN(const PMC *self),
49     ARGIN(const STRING *key))
50         __attribute__nonnull__(1)
51         __attribute__nonnull__(2)
52         __attribute__nonnull__(3);
54 PARROT_WARN_UNUSED_RESULT
55 static INTVAL check_set_std_props(PARROT_INTERP,
56     ARGMOD(PMC *pmc),
57     ARGIN(const STRING *key),
58     ARGIN(PMC *value))
59         __attribute__nonnull__(1)
60         __attribute__nonnull__(2)
61         __attribute__nonnull__(3)
62         __attribute__nonnull__(4)
63         FUNC_MODIFIES(*pmc);
65 static INTVAL has_pending_std_props(ARGIN(const PMC *self))
66         __attribute__nonnull__(1);
68 PARROT_CANNOT_RETURN_NULL
69 PARROT_WARN_UNUSED_RESULT
70 static PMC* make_prop_hash(PARROT_INTERP, ARGMOD(PMC *self))
71         __attribute__nonnull__(1)
72         __attribute__nonnull__(2)
73         FUNC_MODIFIES(*self);
75 static void propagate_std_props(PARROT_INTERP,
76     ARGIN(PMC *self),
77     ARGIN(PMC *prop_hash))
78         __attribute__nonnull__(1)
79         __attribute__nonnull__(2)
80         __attribute__nonnull__(3);
82 #define ASSERT_ARGS_caller __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
83        PARROT_ASSERT_ARG(interp))
84 #define ASSERT_ARGS_cant_do_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
85        PARROT_ASSERT_ARG(interp))
86 #define ASSERT_ARGS_cant_do_write_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
87        PARROT_ASSERT_ARG(interp))
88 #define ASSERT_ARGS_check_get_std_props __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
89        PARROT_ASSERT_ARG(interp) \
90     , PARROT_ASSERT_ARG(self) \
91     , PARROT_ASSERT_ARG(key))
92 #define ASSERT_ARGS_check_set_std_props __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
93        PARROT_ASSERT_ARG(interp) \
94     , PARROT_ASSERT_ARG(pmc) \
95     , PARROT_ASSERT_ARG(key) \
96     , PARROT_ASSERT_ARG(value))
97 #define ASSERT_ARGS_has_pending_std_props __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
98        PARROT_ASSERT_ARG(self))
99 #define ASSERT_ARGS_make_prop_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
100        PARROT_ASSERT_ARG(interp) \
101     , PARROT_ASSERT_ARG(self))
102 #define ASSERT_ARGS_propagate_std_props __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
103        PARROT_ASSERT_ARG(interp) \
104     , PARROT_ASSERT_ARG(self) \
105     , PARROT_ASSERT_ARG(prop_hash))
106 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
107 /* HEADERIZER END: static */
111 =item C<static STRING * caller(PARROT_INTERP, PMC *pmc)>
113 Returns a C string for the name of C<*pmc>.
115 =cut
119 PARROT_CANNOT_RETURN_NULL
120 PARROT_WARN_UNUSED_RESULT
121 static STRING *
122 caller(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc))
124     ASSERT_ARGS(caller)
126     return !PMC_IS_NULL(pmc) && pmc->vtable && pmc->vtable->whoami
127                 ? VTABLE_name(interp, pmc)
128                 : CONST_STRING(interp, "(null)");
133 =item C<static void cant_do_method(PARROT_INTERP, PMC *pmc, int index)>
135 Throws an exception "$methname() not implemented in class '$class'", used by
136 all unimplemented messages.
138 =cut
142 PARROT_DOES_NOT_RETURN
143 static void
144 cant_do_method(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), int index)
146     ASSERT_ARGS(cant_do_method)
148     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ILL_INHERIT,
149             "%s() not implemented in class '%Ss'",
150             Parrot_get_vtable_name(interp, index),
151             caller(interp, pmc));
157 =item C<static void cant_do_write_method(PARROT_INTERP, PMC *pmc, int index)>
159 Throws an exception "$methname() on read-only instance of '$class'", used by
160 all updating messages on read-only instances.
162 =cut
166 PARROT_DOES_NOT_RETURN
167 static void
168 cant_do_write_method(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), int index)
170     ASSERT_ARGS(cant_do_write_method)
172     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_WRITE_TO_CONSTCLASS,
173             "%s() in read-only instance of '%Ss'",
174             Parrot_get_vtable_name(interp, index),
175             caller(interp, pmc));
180 =item C<static INTVAL check_set_std_props(PARROT_INTERP, PMC *pmc, const STRING
181 *key, PMC *value)>
183 Called from C<setprop()>.
185 Returns a true value if C<setprop()> can avoid actually setting a property
186 in the prophash. If it returns true, the property setting will be reflected
187 in a future call to C<propagate_std_props()>
189 =cut
193 PARROT_WARN_UNUSED_RESULT
194 static INTVAL
195 check_set_std_props(PARROT_INTERP, ARGMOD(PMC *pmc), ARGIN(const STRING *key), ARGIN(PMC *value))
197     ASSERT_ARGS(check_set_std_props)
199     /*
200      * s2 in Parrot_str_equal is freed here
201      */
202     if (Parrot_str_equal(interp, key, CONST_STRING(interp, "_ro"))) {
203         /* pmc should set/clear readonly */
204         const INTVAL on = VTABLE_get_bool(interp, value);
206         /* morph to Const/normal class or readonly class */
207         if (on && (pmc->vtable->flags & VTABLE_HAS_CONST_TOO))
208             pmc->vtable = interp->vtables[pmc->vtable->base_type + 1];
209         else if (!on && (pmc->vtable->flags & (VTABLE_IS_CONST_FLAG)))
210             VTABLE_morph(interp, pmc, interp->vtables[pmc->vtable->base_type - 1]->pmc_class);
211         else if (on && (pmc->vtable->flags & VTABLE_HAS_READONLY_FLAG))
212             pmc->vtable = pmc->vtable->ro_variant_vtable;
213         else if (!on && (pmc->vtable->flags & VTABLE_IS_READONLY_FLAG)
214                 && pmc->vtable->ro_variant_vtable)
215             pmc->vtable = pmc->vtable->ro_variant_vtable;
216         else
217             return 0;
219         return 1;
220     }
222     return 0;
227 =item C<static void propagate_std_props(PARROT_INTERP, PMC *self, PMC
228 *prop_hash)>
230 Set pending standard properties in C<prop_hash>.
232 =cut
236 static void
237 propagate_std_props(PARROT_INTERP, ARGIN(PMC *self), ARGIN(PMC *prop_hash))
239     ASSERT_ARGS(propagate_std_props)
241     if (self->vtable->flags & (VTABLE_IS_CONST_FLAG | VTABLE_IS_READONLY_FLAG)){
242         PMC * const pmc_true  = Parrot_pmc_new_init_int(interp,
243                 enum_class_Integer, 1);
244         VTABLE_set_pmc_keyed_str(interp, prop_hash, CONST_STRING(interp, "_ro"), pmc_true);
245     }
250 =item C<static INTVAL has_pending_std_props(const PMC *self)>
252 Returns true if propagate_std_props() would create a non-empty prophash.
254 =cut
258 static INTVAL
259 has_pending_std_props(ARGIN(const PMC *self))
261     ASSERT_ARGS(has_pending_std_props)
263     if (self->vtable->flags & (VTABLE_IS_CONST_FLAG | VTABLE_IS_READONLY_FLAG))
264         return 1;
265     else
266         return 0;
272 =item C<static PMC* check_get_std_props(PARROT_INTERP, const PMC *self, const
273 STRING *key)>
275 Checks if we can infer the value of C<key> property from C<self> without
276 looking at its prophash. Returns C<PMCNULL> if not, returns the value otherwise.
278 =cut
281 PARROT_WARN_UNUSED_RESULT
282 PARROT_CAN_RETURN_NULL
283 static PMC*
284 check_get_std_props(PARROT_INTERP, ARGIN(const PMC *self), ARGIN(const STRING *key))
286     ASSERT_ARGS(check_get_std_props)
288     if ((self->vtable->flags & (VTABLE_IS_CONST_FLAG | VTABLE_IS_READONLY_FLAG))
289        && Parrot_str_equal(interp, key, CONST_STRING(interp, "_ro"))) {
290         PMC * const ret_val = Parrot_pmc_new_init_int(interp,
291                 enum_class_Integer, 1);
292         return ret_val;
293     }
294     else
295         return PMCNULL;
300 =item C<static PMC* make_prop_hash(PARROT_INTERP, PMC *self)>
302 Create a property hash for C<self>. Returns the created hash. Inferred
303 properties will be added to the hash.
305 =cut
309 PARROT_CANNOT_RETURN_NULL
310 PARROT_WARN_UNUSED_RESULT
311 static PMC*
312 make_prop_hash(PARROT_INTERP, ARGMOD(PMC *self))
314     ASSERT_ARGS(make_prop_hash)
316     PMC * const prop = Parrot_pmc_new(interp, enum_class_Hash);
317     propagate_std_props(interp, self, prop);
318     return prop;
321 pmclass default abstract {
325 =back
327 =head2 Methods
329 =over 4
331 =item C<void init()>
333 Does nothing.
335 =cut
339     VTABLE void init() {
340     }
344 =item C<void init_pmc(PMC *initializer)>
346 With a null C<initializer>, calls C<init()>, else throws an exception.
348 =cut
352     VTABLE void init_pmc(PMC *initializer) {
353         if (PMC_IS_NULL(initializer))
354             SELF.init();
355         else
356             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_ILL_INHERIT,
357                 "init_pmc() not implemented in class '%Ss'",
358                 caller(INTERP, SELF));
359     }
363 =item C<void init_int(INTVAL initvalue)>
365 Calls C<init()> and C<set_integer_native(initvalue)>.
366 Default implementation to allow more usages of init_int without having to
367 implement it everywhere.
369 =cut
373     VTABLE void init_int(INTVAL initvalue) {
374         SELF.init();
375         SELF.set_integer_native(initvalue);
376     }
380 =item C<void destroy()>
382 Does nothing.
384 =cut
388     VTABLE void destroy() {
389     }
393 =item C<PMC *instantiate(PMC *init)>
395 Default fallback. Creates a new PMC of the type of the class SELF and
396 calls init().
398 =cut
402     VTABLE PMC *instantiate(PMC *init) {
403         const INTVAL type = VTABLE_type(INTERP, SELF);
405         /* Ensure no looping, as Parrot_pmc_new calls the instantiate vtable entry for
406          * classes. */
407         if (PObj_is_class_TEST(SELF))
408             Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
409                     "All high-level classes should override instantiate");
411         if (!PMC_IS_NULL(init))
412             return Parrot_pmc_new_init(INTERP, type, init);
414         return Parrot_pmc_new(INTERP, type);
415     }
419 =item C<void mark()>
421 Panics with a "no custom mark routine defined" error message.
423 =cut
427     VTABLE void mark() {
428         PANIC(INTERP, "custom_mark flag set but no custom mark routine defined");
429     }
433 =item C<PMC *getprop(STRING *key)>
435 Returns the property for C<*key>. If no property is defined then the
436 NULL PMC is returned.
438 =cut
442     VTABLE PMC *getprop(STRING *key) {
443         if (PMC_IS_NULL(PMC_metadata(SELF)))
444             return check_get_std_props(INTERP, SELF, key);
445         else
446             return VTABLE_get_pmc_keyed_str(INTERP, PMC_metadata(SELF), key);
447     }
451 =item C<void setprop(STRING *key, PMC *value)>
453 Sets the property for C<*key> to C<*value>.
455 =cut
459     VTABLE void setprop(STRING *key, PMC *value) {
460         if (check_set_std_props(INTERP, SELF, key, value))
461             return;
463         if (PMC_IS_NULL(PMC_metadata(SELF)))
464             PMC_metadata(SELF) = make_prop_hash(INTERP, SELF);
466         VTABLE_set_pmc_keyed_str(INTERP, PMC_metadata(SELF), key, value);
467     }
471 =item C<void delprop(STRING *key)>
473 Deletes the property for C<*key>.
475 =cut
479     VTABLE void delprop(STRING *key) {
480         if (!PMC_IS_NULL(PMC_metadata(SELF)))
481             VTABLE_delete_keyed_str(INTERP, PMC_metadata(SELF), key);
482     }
486 =item C<PMC *getprops()>
488 Returns the PMC's properties or the NULL PMC if no properties exist.
490 =cut
494     VTABLE PMC *getprops() {
495         if (PMC_IS_NULL(PMC_metadata(SELF))) {
496             if (has_pending_std_props(SELF))
497                 PMC_metadata(SELF) = make_prop_hash(INTERP, SELF);
498             else
499                 return PMCNULL;
500         }
502         return PMC_metadata(SELF);
503     }
507 =item C<INTVAL type()>
509 Returns the PMC's type.
511 =cut
515     VTABLE INTVAL type() {
516         return SELF->vtable->base_type;
517     }
521 =item C<STRING *name()>
523 Returns the name of the PMC.
525 =cut
529     VTABLE STRING *name() {
530         return SELF->vtable->whoami;
531     }
536 =item C<void PMC *add_attribute(STRING *name, PMC *type)>
538 Throws an exception, as you can only add an attribute to something Class-y or
539 Role-y.
541 =cut
545     VTABLE void add_attribute(STRING *name, PMC *type) {
546         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
547             "Cannot add attribute to non-class");
548     }
552 =item C<PMC *get_namespace>
554 Return the namespace for this PMC.
556 =item C<PMC *find_method(STRING *method_name)>
558 Looks up the method for C<*method_name> and returns it. If no method is
559 found then C<NULL> is returned.
561 =item C<void add_method(STRING *method_name, PMC *sub)>
563 Store the method as a global in the namespace of this class.
565 =cut
569     VTABLE PMC *get_namespace() {
571         /* Because singletons are shared between interpreters, we need to make
572          * special effort to use the right namespace for method lookups.
573          * Note that this trick won't work if the singleton inherits from
574          * something else (because the MRO will still be shared).
575          * Having this code here avoids creating a special case for singletons
576          * elsewhere.
577          */
579         return INTERP->vtables[SELF->vtable->base_type]->_namespace;
580     }
583     VTABLE PMC *find_method(STRING *method_name) {
584         return Parrot_find_method_with_cache(INTERP, SELF, method_name);
585     }
587     VTABLE void add_method(STRING *method_name, PMC *sub_pmc) {
588         VTABLE_set_pmc_keyed_str(INTERP, SELF->vtable->_namespace,
589                                  method_name, sub_pmc);
590     }
593 =item C<INTVAL get_integer_keyed_int(INTVAL key)>
595 Converts C<key> to a PMC key and returns the result of calling
596 C<get_integer_keyed()> with it.
598 =cut
602     VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
603         PMC *const r_key = INT2KEY(INTERP, key);
604         return SELF.get_integer_keyed(r_key);
605     }
609 =item C<FLOATVAL get_number_keyed_int(INTVAL key)>
611 Converts C<key> to a PMC key and returns the result of calling
612 C<get_number_keyed()> with it.
614 =cut
618     VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
619         PMC *const r_key = INT2KEY(INTERP, key);
620         return SELF.get_number_keyed(r_key);
621     }
626 =item C<STRING *get_string_keyed_int(INTVAL key)>
628 Converts C<key> to a PMC key and returns the result of calling
629 C<get_string_keyed()> with it.
631 =cut
635     VTABLE STRING *get_string_keyed_int(INTVAL key) {
636         PMC *const r_key = INT2KEY(INTERP, key);
637         return SELF.get_string_keyed(r_key);
638     }
642 =item C<PMC *get_pmc_keyed_int(INTVAL key)>
644 Converts C<key> to a PMC key and returns the result of calling
645 C<get_pmc_keyed()> with it.
647 =cut
651     VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
652         PMC *const r_key = INT2KEY(INTERP, key);
653         return SELF.get_pmc_keyed(r_key);
654     }
658 =item C<void *get_pointer()>
660 Returns the address of the PMC.
662 =cut
666     VTABLE void *get_pointer() {
667         return SELF;
668     }
672 =item C<INTVAL is_same(PMC *value)>
674 Returns whether the PMC is the same PMC as C<value> (whether they're the
675 same pointer).
677 =cut
681     VTABLE INTVAL is_same(PMC *value) {
682         return SELF == value;
683     }
687 =item C<void assign_pmc(PMC *value)>
689 =item C<void assign_string_native(PMC *value)>
691 Defaults fall back to C<set_pmc> and C<set_string_native>.
693 =cut
697     VTABLE void assign_pmc(PMC *value) {
698         STRING * const undef = CONST_STRING(INTERP, "Undef");
700         if (VTABLE_isa(INTERP, value, undef))
701             Parrot_pmc_reuse(INTERP, SELF, value->vtable->base_type, 0);
702         else
703             SELF.set_pmc(value);
704     }
706     VTABLE void assign_string_native(STRING *value) {
707         SELF.set_string_native(value);
708     }
712 =item C<void morph(PMC* type)>
714 Changes the PMC to a PMC of a new type
716 =cut
720     VTABLE void morph(PMC* type) {
721         Parrot_pmc_reuse(INTERP, SELF, VTABLE_get_integer(INTERP, type), 0);
722     }
726 =item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
728 Converts C<key> to a PMC key and calls C<set_integer_keyed()> with it
729 and C<value>.
731 =cut
735     VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
736         PMC *const r_key = INT2KEY(INTERP, key);
737         SELF.set_integer_keyed(r_key, value);
738     }
742 =item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
744 Converts C<key> to a PMC key and calls C<set_number_keyed()> with it
745 and C<value>.
747 =cut
751     VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
752         PMC *const r_key = INT2KEY(INTERP, key);
753         SELF.set_number_keyed(r_key, value);
754     }
758 =item C<void set_string_keyed_int(INTVAL key, STRING *string)>
760 Converts C<key> to a PMC key and calls C<set_string_keyed()> with it
761 and C<value>.
763 =cut
767     VTABLE void set_string_keyed_int(INTVAL key, STRING *string) {
768         PMC *const r_key = INT2KEY(INTERP, key);
769         SELF.set_string_keyed(r_key, string);
770     }
774 =item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
776 Converts C<key> to a PMC key and calls C<set_pmc_keyed()> with it
777 and C<value>.
779 =cut
783     VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
784         PMC *const r_key = INT2KEY(INTERP, key);
785         SELF.set_pmc_keyed(r_key, value);
786     }
790 =item C<INTVAL hashvalue()>
792 Calculate hashvalue for PMC. Default behaviour stringify and use string.
794 =cut
798     INTVAL hashvalue() {
799         STRING *s = SELF.get_string();
800         return Parrot_str_to_hashval(INTERP, s);
801     }
805 =item C<INTVAL is_equal(PMC *value)>
807 Default fallback. Performs a multiple dispatch call for 'is_equal'.
809 =cut
813     VTABLE INTVAL is_equal(PMC *value) {
814         INTVAL retval;
815         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
816                 "is_equal", "PP->I", SELF, value, &retval);
818         return retval;
819     }
823 =item C<INTVAL is_equal_num(PMC *value)>
825 Default fallback. Performs a multiple dispatch call for 'is_equal_num'.
827 =cut
831     VTABLE INTVAL is_equal_num(PMC *value) {
832         INTVAL retval;
833         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
834                 "is_equal_num", "PP->I", SELF, value, &retval);
836         return retval;
837     }
841 =item C<INTVAL is_equal_string(PMC *value)>
843 Default fallback. Performs a multiple dispatch call for 'is_equal'.
845 =cut
849     VTABLE INTVAL is_equal_string(PMC *value) {
850         INTVAL retval;
851         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
852                 "is_equal_string", "PP->I", SELF, value, &retval);
854         return retval;
855     }
859 =item C<INTVAL exists_keyed_int(INTVAL key)>
861 Converts C<key> to a PMC key and returns the result of calling
862 C<exists_keyed()> with it.
864 =cut
868     VTABLE INTVAL exists_keyed_int(INTVAL key) {
869         PMC *const r_key = INT2KEY(INTERP, key);
870         return SELF.exists_keyed(r_key);
871     }
875 =item C<INTVAL defined()>
877 Returns true.
879 =cut
883     VTABLE INTVAL defined() {
884         return 1;
885     }
889 =item C<INTVAL defined_keyed_int(INTVAL key)>
891 Converts C<key> to a PMC key and returns the result of calling
892 C<defined_keyed()> with it.
894 =cut
898     VTABLE INTVAL defined_keyed_int(INTVAL key) {
899         PMC *const r_key = INT2KEY(INTERP, key);
900         return SELF.defined_keyed(r_key);
901     }
905 =item C<void delete_keyed_int(INTVAL key)>
907 Converts C<key> to a PMC key and calls C<delete_keyed()> with it.
909 =cut
913     VTABLE void delete_keyed_int(INTVAL key) {
914         PMC *const r_key = INT2KEY(INTERP, key);
915         SELF.delete_keyed(r_key);
916     }
920 =item C<INTVAL can(STRING *method)>
922 Reports whether the PMC "can" perform C<method>.
923 If the PMC implements the vtable function C<method>,
924 true (1) is returned; otherwise, false (0) is returned.
926 =cut
930     VTABLE INTVAL can(STRING *method) {
931         return !PMC_IS_NULL(VTABLE_find_method(INTERP, SELF, method));
932     }
936 =item C<INTVAL does(STRING *interface_name)>
938 Reports whether the PMC "does" perform C<interface_name>.
939 If the interface C<interface_name> is found in the PMC's interface list,
940 true (1) is returned; otherwise, false (0) is returned.
942 =cut
946     VTABLE INTVAL does(STRING *interface_name) {
947         return Parrot_pmc_type_does(INTERP, interface_name, SELF->vtable->base_type);
948     }
952 =item C<INTVAL does_pmc(PMC *role)>
954 Reports whether the PMC "does" the C<role>.
956 =cut
960     VTABLE INTVAL does_pmc(PMC *role) {
961         UNUSED(role)
962         /* No C-level roles yet. */
963         return 0;
964     }
968 =item C<INTVAL isa_pmc(PMC *_class)>
970 Reports whether the PMC "isa" C<_class>.
971 If the class C<_class> is found in the PMC's class hierarchy,
972 true (1) is returned; otherwise, false (0) is returned.
974 =cut
978     VTABLE INTVAL isa_pmc(PMC *lookup) {
979         if (PMC_IS_NULL(lookup))
980             return 0;
981         else {
982             Hash   * const isa_hash = SELF->vtable->isa_hash;
983             STRING * const pmc_name = VTABLE_get_string(INTERP, lookup);
984             return parrot_hash_exists(INTERP, isa_hash, pmc_name);
985         }
986     }
990 =item C<INTVAL isa(STRING *_class)>
992 Reports whether the PMC "isa" C<_class>.
993 If the class C<_class> is found in the PMC's class hierarchy,
994 true (1) is returned; otherwise, false (0) is returned.
996 =cut
1000     VTABLE INTVAL isa(STRING *_class) {
1001         if (SELF->vtable->whoami == _class)
1002             return 1;
1003         else {
1004             const Hash * const isa_hash = SELF->vtable->isa_hash;
1005             if (!isa_hash)
1006                 return Parrot_str_equal(INTERP, SELF->vtable->whoami, _class);
1008             return parrot_hash_exists(INTERP, isa_hash, (void *)_class);
1009         }
1010     }
1014 =item C<PMC *inspect_str(STRING *what)>
1016 Provides introspection of a specific piece of information about the PMC.
1018 =cut
1022     VTABLE PMC *inspect_str(STRING *name) {
1023         if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "flags"))) {
1024             PMC *found = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
1025                     (INTVAL)PObj_get_FLAGS(SELF));
1026             return found;
1027         }
1028         else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "mro"))) {
1029             return VTABLE_clone(INTERP, SELF->vtable->mro);
1030         }
1031         else
1032             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
1033                 "Unknown introspection value '%S'", name);
1034     }
1038 =item C<PMC *inspect()>
1040 Returns a Hash describing the class, with key/value pairs as described in
1041 inspect_str.
1043 =cut
1046     VTABLE PMC *inspect() {
1047         PMC    * const metadata    = Parrot_pmc_new(INTERP, enum_class_Hash);
1048         STRING * const flags_str   = CONST_STRING(INTERP, "flags");
1050         VTABLE_set_pmc_keyed_str(INTERP, metadata, flags_str,
1051             VTABLE_inspect_str(INTERP, SELF, flags_str));
1053         return metadata;
1054     }
1058 =item C<PMC *get_class()>
1060 Returns SELF. A PMC is its own class.
1062 =cut
1065     VTABLE PMC *get_class() {
1066         PMC * const ns     = VTABLE_get_namespace(INTERP, SELF);
1067         PMC *_class = PMCNULL;
1069         if (!PMC_IS_NULL(ns))
1070             _class = VTABLE_get_class(INTERP, ns);
1072         if (PMC_IS_NULL(_class)) {
1073             const INTVAL type      = VTABLE_type(INTERP, SELF);
1074             return Parrot_pmc_new_init_int(INTERP, enum_class_PMCProxy, type);
1075         }
1077         return _class;
1079     }
1083 =item C<PMC *get_attr_keyed(PMC *key, STRING *name)>
1085 Default version of keyed attribute lookups. Discards the key and does a lookup
1086 by the string name passed in.
1088 =item C<void set_attr_keyed(PMC *key, STRING *name, PMC *value)>
1090 Default version of keyed attribute set. Discards the key and does a set by
1091 the string name passed in.
1093 =cut
1096     VTABLE PMC *get_attr_keyed(PMC *key, STRING *name) {
1097         UNUSED(key)
1098         return VTABLE_get_attr_str(INTERP, SELF, name);
1099     }
1101     VTABLE void set_attr_keyed(PMC *key, STRING *name, PMC *value) {
1102         UNUSED(key)
1103         VTABLE_set_attr_str(INTERP, SELF, name, value);
1104     }
1108 =item C<void add_parent(PMC *parent)>
1110 Add class C<parent> to the list of our parents.
1112 =cut
1116     VTABLE void add_parent(PMC *parent) {
1117         UNUSED(parent)
1118         if (!PObj_is_class_TEST(SELF))
1119             Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
1120                 "Only classes can be subclassed");
1122         Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
1123                 "All classes should override add_parent");
1124     }
1128 =item C<void visit(PMC *info)>
1130 Used by GC to mark the PMC.
1132 =cut
1136     VTABLE void visit(PMC *info) {
1137     }
1141 =item C<PMC* clone()>
1143 Clones this PMC.  By default, this just does a freeze and thaw.
1145 =cut
1149     VTABLE PMC* clone() {
1150         return Parrot_thaw(INTERP, Parrot_freeze(INTERP, SELF));
1151     }
1155 =item C<void freeze(PMC *info)>
1157 Does nothing.
1159 =cut
1163     VTABLE void freeze(PMC *info) {
1164         UNUSED(info)
1165         /* default - no action */
1166     }
1170 =item C<void thaw(PMC *info)>
1172 Initializes the PMC during unarchiving.
1174 =cut
1178     VTABLE void thaw(PMC *info) {
1179         /* default - initialize the PMC */
1180         SELF.init();
1181     }
1185 =item C<void thawfinish(PMC *info)>
1187 Does nothing.
1189 =cut
1193     VTABLE void thawfinish(PMC *info) {
1194         UNUSED(info)
1195         /* default - no action */
1196     }
1200 =item C<PMC *add(PMC *value, PMC *dest)>
1202 Default fallback. Performs a multiple dispatch call for 'add'.
1204 =cut
1208     VTABLE PMC *add(PMC *value, PMC *dest) {
1209         PMC *result = PMCNULL;
1210         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1211                 "add", "PPP->P", SELF, value, dest, &result);
1212         return result;
1213     }
1217 =item C<PMC *add_int(INTVAL value, PMC *dest)>
1219 Default fallback. Performs a multiple dispatch call for 'add_int'.
1221 =cut
1225     VTABLE PMC *add_int(INTVAL value, PMC *dest) {
1226         PMC *result = PMCNULL;
1227         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1228                 "add_int", "PIP->P", SELF, value, dest, &result);
1229         return result;
1230     }
1234 =item C<PMC *add_float(FLOATVAL value, PMC *dest)>
1236 Default fallback. Performs a multiple dispatch call for 'add_float'.
1238 =cut
1242     VTABLE PMC *add_float(FLOATVAL value, PMC *dest) {
1243         dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
1245         VTABLE_set_number_native(INTERP, dest,
1246                 SELF.get_number() + value);
1247         return dest;
1248     }
1252 =item C<void i_add(PMC *value)>
1254 Default fallback. Performs a multiple dispatch call for 'i_add'.
1256 =cut
1260     VTABLE void i_add(PMC *value) {
1261         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1262                 "i_add", "PP", SELF, value);
1263     }
1267 =item C<void i_add_int(INTVAL value)>
1269 Default fallback. Performs a multiple dispatch call for 'i_add_int'.
1271 =cut
1275     VTABLE void i_add_int(INTVAL value) {
1276         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1277                 "i_add_int", "PI", SELF, value);
1278     }
1282 =item C<void i_add_float(FLOATVAL value)>
1284 Default fallback. Performs a multiple dispatch call for 'i_add_float'.
1286 =cut
1290     VTABLE void i_add_float(FLOATVAL value) {
1291         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1292                 "i_add_float", "PN", SELF, value);
1293     }
1297 =item C<PMC *subtract(PMC *value, PMC *dest)>
1299 Default fallback. Performs a multiple dispatch call for 'subtract'.
1301 =cut
1305     VTABLE PMC *subtract(PMC *value, PMC *dest) {
1306         PMC *result = PMCNULL;
1307         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1308                 "subtract", "PPP->P", SELF, value, dest, &result);
1309         return result;
1310     }
1314 =item C<PMC *subtract_int(INTVAL value, PMC *dest)>
1316 Default fallback. Performs a multiple dispatch call for 'subtract_int'.
1318 =cut
1322     VTABLE PMC *subtract_int(INTVAL value, PMC *dest) {
1323         PMC *result = PMCNULL;
1324         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1325                 "subtract_int", "PIP->P", SELF, value, dest, &result);
1326         return result;
1327     }
1331 =item C<PMC *subtract_float(FLOATVAL value, PMC *dest)>
1333 Default fallback. Performs a multiple dispatch call for 'subtract_float'.
1335 =cut
1339     VTABLE PMC *subtract_float(FLOATVAL value, PMC *dest) {
1340         PMC *result = PMCNULL;
1341         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1342                 "subtract_float", "PNP->P", SELF, value, dest, &result);
1343         return result;
1344     }
1348 =item C<void i_subtract(PMC *value)>
1350 Default fallback. Performs a multiple dispatch call for 'i_subtract'.
1352 =cut
1356     VTABLE void i_subtract(PMC *value) {
1357         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1358                 "i_subtract", "PP", SELF, value);
1359     }
1363 =item C<void i_subtract_int(INTVAL value)>
1365 Default fallback. Performs a multiple dispatch call for 'i_subtract_int'.
1367 =cut
1371     VTABLE void i_subtract_int(INTVAL value) {
1372         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1373                 "i_subtract_int", "PI", SELF, value);
1374     }
1378 =item C<void i_subtract_float(FLOATVAL value)>
1380 Default fallback. Performs a multiple dispatch call for 'i_subtract_float'.
1382 =cut
1386     VTABLE void i_subtract_float(FLOATVAL value) {
1387         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1388                 "i_subtract_float", "PN", SELF, value);
1389     }
1393 =item C<PMC *multiply(PMC *value, PMC *dest)>
1395 Default fallback. Performs a multiple dispatch call for 'multiply'.
1397 =cut
1401     VTABLE PMC *multiply(PMC *value, PMC *dest) {
1402         PMC *result = PMCNULL;
1403         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1404                 "multiply", "PPP->P", SELF, value, dest, &result);
1405         return result;
1406     }
1410 =item C<PMC *multiply_int(INTVAL value, PMC *dest)>
1412 Default fallback. Performs a multiple dispatch call for 'multiply_int'.
1414 =cut
1418     VTABLE PMC *multiply_int(INTVAL value, PMC *dest) {
1419         PMC *result = PMCNULL;
1420         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1421                 "multiply_int", "PIP->P", SELF, value, dest, &result);
1422         return result;
1423     }
1427 =item C<PMC *multiply_float(FLOATVAL value, PMC *dest)>
1429 Default fallback. Performs a multiple dispatch call for 'multiply_float'.
1431 =cut
1435     VTABLE PMC *multiply_float(FLOATVAL value, PMC *dest) {
1436         PMC *result = PMCNULL;
1437         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1438                 "multiply_float", "PNP->P", SELF, value, dest, &result);
1439         return result;
1440     }
1444 =item C<void i_multiply(PMC *value)>
1446 Default fallback. Performs a multiple dispatch call for 'i_multiply'.
1448 =cut
1452     VTABLE void i_multiply(PMC *value) {
1453         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1454                 "i_multiply", "PP", SELF, value);
1455     }
1459 =item C<void i_multiply_int(INTVAL value)>
1461 Default fallback. Performs a multiple dispatch call for 'i_multiply_int'.
1463 =cut
1467     VTABLE void i_multiply_int(INTVAL value) {
1468         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1469                 "i_multiply_int", "PI", SELF, value);
1470     }
1474 =item C<void i_multiply_float(FLOATVAL value)>
1476 Default fallback. Performs a multiple dispatch call for 'i_multiply_float'.
1478 =cut
1482     VTABLE void i_multiply_float(FLOATVAL value) {
1483         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1484                 "i_multiply_float", "PN", SELF, value);
1485     }
1489 =item C<PMC *divide(PMC *value, PMC *dest)>
1491 Default fallback. Performs a multiple dispatch call for 'divide'.
1493 =cut
1497     VTABLE PMC *divide(PMC *value, PMC *dest) {
1498         PMC *result = PMCNULL;
1499         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1500                 "divide", "PPP->P", SELF, value, dest, &result);
1501         return result;
1502     }
1506 =item C<PMC *divide_int(INTVAL value, PMC *dest)>
1508 Default fallback. Performs a multiple dispatch call for 'divide_int'.
1510 =cut
1514     VTABLE PMC *divide_int(INTVAL value, PMC *dest) {
1515         PMC *result = PMCNULL;
1516         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1517                 "divide_int", "PIP->P", SELF, value, dest, &result);
1518         return result;
1519     }
1523 =item C<PMC *divide_float(FLOATVAL value, PMC *dest)>
1525 Default fallback. Performs a multiple dispatch call for 'divide_float'.
1527 =cut
1531     VTABLE PMC *divide_float(FLOATVAL value, PMC *dest) {
1532         PMC *result = PMCNULL;
1533         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1534                 "divide_float", "PNP->P", SELF, value, dest, &result);
1535         return result;
1536     }
1540 =item C<void i_divide(PMC *value)>
1542 Default fallback. Performs a multiple dispatch call for 'i_divide'.
1544 =cut
1548     VTABLE void i_divide(PMC *value) {
1549         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1550                 "i_divide", "PP", SELF, value);
1551     }
1555 =item C<void i_divide_int(INTVAL value)>
1557 Default fallback. Performs a multiple dispatch call for 'i_divide_int'.
1559 =cut
1563     VTABLE void i_divide_int(INTVAL value) {
1564         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1565                 "i_divide_int", "PI", SELF, value);
1566     }
1570 =item C<void i_divide_float(FLOATVAL value)>
1572 Default fallback. Performs a multiple dispatch call for 'i_divide_float'.
1574 =cut
1578     VTABLE void i_divide_float(FLOATVAL value) {
1579         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1580                 "i_divide_float", "PN", SELF, value);
1581     }
1585 =item C<PMC *floor_divide(PMC *value, PMC *dest)>
1587 Default fallback. Performs a multiple dispatch call for 'floor_divide'.
1589 =cut
1593     VTABLE PMC *floor_divide(PMC *value, PMC *dest) {
1594         PMC *result = PMCNULL;
1595         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1596                 "floor_divide", "PPP->P", SELF, value, dest, &result);
1597         return result;
1598     }
1602 =item C<PMC *floor_divide_int(INTVAL value, PMC *dest)>
1604 Default fallback. Performs a multiple dispatch call for 'floor_divide_int'.
1606 =cut
1610     VTABLE PMC *floor_divide_int(INTVAL value, PMC *dest) {
1611         PMC *result = PMCNULL;
1612         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1613                 "floor_divide_int", "PIP->P", SELF, value, dest, &result);
1614         return result;
1615     }
1619 =item C<PMC *floor_divide_float(FLOATVAL value, PMC *dest)>
1621 Default fallback. Performs a multiple dispatch call for 'floor_divide_float'.
1623 =cut
1627     VTABLE PMC *floor_divide_float(FLOATVAL value, PMC *dest) {
1628         PMC *result = PMCNULL;
1629         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1630                 "floor_divide_float", "PNP->P", SELF, value, dest, &result);
1631         return result;
1632     }
1636 =item C<void i_floor_divide(PMC *value)>
1638 Default fallback. Performs a multiple dispatch call for 'i_floor_divide'.
1640 =cut
1644     VTABLE void i_floor_divide(PMC *value) {
1645         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1646                 "i_floor_divide", "PP", SELF, value);
1647     }
1651 =item C<void i_floor_divide_int(INTVAL value)>
1653 Default fallback. Performs a multiple dispatch call for 'i_floor_divide_int'.
1655 =cut
1659     VTABLE void i_floor_divide_int(INTVAL value) {
1660         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1661                 "i_floor_divide_int", "PI", SELF, value);
1662     }
1666 =item C<void i_floor_divide_float(FLOATVAL value)>
1668 Default fallback. Performs a multiple dispatch call for 'i_floor_divide_float'.
1670 =cut
1674     VTABLE void i_floor_divide_float(FLOATVAL value) {
1675         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1676                 "i_floor_divide_float", "PN", SELF, value);
1677     }
1681 =item C<PMC *modulus(PMC *value, PMC *dest)>
1683 Default fallback. Performs a multiple dispatch call for 'modulus'.
1685 =cut
1689     VTABLE PMC *modulus(PMC *value, PMC *dest) {
1690         PMC *result = PMCNULL;
1691         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1692                 "modulus", "PPP->P", SELF, value, dest, &result);
1693         return result;
1694     }
1698 =item C<PMC *modulus_int(INTVAL value, PMC *dest)>
1700 Default fallback. Performs a multiple dispatch call for 'modulus_int'.
1702 =cut
1706     VTABLE PMC *modulus_int(INTVAL value, PMC *dest) {
1707         PMC *result = PMCNULL;
1708         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1709                 "modulus_int", "PIP->P", SELF, value, dest, &result);
1710         return result;
1711     }
1715 =item C<PMC *modulus_float(FLOATVAL value, PMC *dest)>
1717 Default fallback. Performs a multiple dispatch call for 'modulus_float'.
1719 =cut
1723     VTABLE PMC *modulus_float(FLOATVAL value, PMC *dest) {
1724         PMC *result = PMCNULL;
1725         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1726                 "modulus_float", "PNP->P", SELF, value, dest, &result);
1727         return result;
1728     }
1732 =item C<void i_modulus(PMC *value)>
1734 Default fallback. Performs a multiple dispatch call for 'i_modulus'.
1736 =cut
1740     VTABLE void i_modulus(PMC *value) {
1741         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1742                 "i_modulus", "PP", SELF, value);
1743     }
1747 =item C<void i_modulus_int(INTVAL value)>
1749 Default fallback. Performs a multiple dispatch call for 'i_modulus_int'.
1751 =cut
1755     VTABLE void i_modulus_int(INTVAL value) {
1756         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1757                 "i_modulus_int", "PI", SELF, value);
1758     }
1762 =item C<void i_modulus_float(FLOATVAL value)>
1764 Default fallback. Performs a multiple dispatch call for 'i_modulus_float'.
1766 =cut
1770     VTABLE void i_modulus_float(FLOATVAL value) {
1771         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1772                 "i_modulus_float", "PN", SELF, value);
1773     }
1777 =item C<INTVAL cmp(PMC *value)>
1779 Default fallback. Performs a multiple dispatch call for 'cmp'.
1781 =cut
1785     VTABLE INTVAL cmp(PMC *value) {
1786         INTVAL retval;
1788         /* Don't multidispatch if you've got two pointers to the same PMC. They
1789          * are equal. */
1790         if (SELF == value)
1791             return 0;
1793         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1794                 "cmp", "PP->I", SELF, value, &retval);
1796         return retval;
1797     }
1801 =item C<INTVAL cmp_num(PMC *value)>
1803 Default fallback. Performs a multiple dispatch call for 'cmp_num'.
1805 =cut
1809     VTABLE INTVAL cmp_num(PMC *value) {
1810         INTVAL retval;
1811         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1812                 "cmp_num", "PP->I", SELF, value, &retval);
1814         return retval;
1815     }
1819 =item C<INTVAL cmp_string(PMC *value)>
1821 Default fallback. Performs a multiple dispatch call for 'cmp_string'.
1823 =cut
1827     VTABLE INTVAL cmp_string(PMC *value) {
1828         INTVAL retval;
1829         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1830                 "cmp_string", "PP->I", SELF, value, &retval);
1832         return retval;
1833     }
1837 =item C<PMC *cmp_pmc(PMC *value)>
1839 Default fallback. Performs a multiple dispatch call for 'cmp_pmc'.
1841 =cut
1845     VTABLE PMC *cmp_pmc(PMC *value) {
1846         PMC *retval;
1848         /* Don't multidispatch if you've got two pointers to the same PMC. They
1849          * are equal. */
1850         if (SELF == value)
1851             return NULL;
1853         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1854                 "cmp_pmc", "PP->P", SELF, value, &retval);
1856         return retval;
1857     }
1861 =item C<PMC *concatenate(PMC *value, PMC *dest)>
1863 Default fallback. Performs a multiple dispatch call for 'concatenate'.
1865 =cut
1869     VTABLE PMC *concatenate(PMC *value, PMC *dest) {
1870         PMC *result = PMCNULL;
1871         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1872                 "concatenate", "PPP->P", SELF, value, dest, &result);
1873         return result;
1874     }
1878 =item C<PMC *concatenate_str(STRING *value, PMC *dest)>
1880 Default fallback. Performs a multiple dispatch call for 'concatenate_str'.
1882 =cut
1886     VTABLE PMC *concatenate_str(STRING *value, PMC *dest) {
1887         PMC *result = PMCNULL;
1888         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1889                 "concatenate_str", "PSP->P", SELF, value, dest, &result);
1890         return result;
1891     }
1895 =item C<void i_concatenate(PMC *value)>
1897 Default fallback. Performs a multiple dispatch call for 'i_concatenate'.
1899 =cut
1903     VTABLE void i_concatenate(PMC *value) {
1904         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1905                 "i_concatenate", "PP", SELF, value);
1906     }
1910 =item C<void i_concatenate_str(STRING *value)>
1912 Default fallback. Performs a multiple dispatch call for 'i_concatenate_str'.
1914 =cut
1918     VTABLE void i_concatenate_str(STRING *value) {
1919         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1920                 "i_concatenate_str", "PS", SELF, value);
1921     }
1925 =item C<PMC *repeat(PMC *value, PMC *dest)>
1927 Default fallback. Performs a multiple dispatch call for 'repeat'.
1929 =cut
1933     VTABLE PMC *repeat(PMC *value, PMC *dest) {
1934         PMC *result = PMCNULL;
1935         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1936                 "repeat", "PPP->P", SELF, value, dest, &result);
1937         return result;
1938     }
1942 =item C<PMC *repeat_int(INTVAL value, PMC *dest)>
1944 Default fallback. Performs a multiple dispatch call for 'repeat_int'.
1946 =cut
1950     VTABLE PMC *repeat_int(INTVAL value, PMC *dest) {
1951         PMC *result = PMCNULL;
1952         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1953                 "repeat_int", "PIP->P", SELF, value, dest, &result);
1954         return result;
1955     }
1959 =item C<void i_repeat(PMC *value)>
1961 Default fallback. Performs a multiple dispatch call for 'i_repeat'.
1963 =cut
1967     VTABLE void i_repeat(PMC *value) {
1968         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1969                 "i_repeat", "PP", SELF, value);
1970     }
1974 =item C<void i_repeat_int(INTVAL value)>
1976 Default fallback. Performs a multiple dispatch call for 'i_repeat_int'.
1978 =cut
1982     VTABLE void i_repeat_int(INTVAL value) {
1983         Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1984                 "i_repeat_int", "PI", SELF, value);
1985     }
1990 =back
1992 =cut
1997  * Local variables:
1998  *   c-file-style: "parrot"
1999  * End:
2000  * vim: expandtab shiftwidth=4:
2001  */