1/*
2Copyright (C) 2001-2014, Parrot Foundation.
3
4=head1 NAME
5
6src/pmc/default.pmc - default PMC
7
8=head1 DESCRIPTION
9
10These are the vtable functions for the default PMC class, the abstract
11root class.
12
13All methods which are not defined here get a default implementation
14generated from F<src/vtable.tbl> by F<tools/build/pmc2c.pl>.
15
16=head2 Functions
17
18=over 4
19
20=cut
21
22*/
23
24#define INT2KEY(i, k) Parrot_key_new_integer((i), (k))
25
26/* HEADERIZER HFILE: none */
27/* HEADERIZER BEGIN: static */
28/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
29
30PARROT_CANNOT_RETURN_NULL
31PARROT_WARN_UNUSED_RESULT
32static STRING * caller(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc))
33        __attribute__nonnull__(1);
34
35PARROT_DOES_NOT_RETURN
36static void cant_do_method(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), int index)
37        __attribute__nonnull__(1);
38
39PARROT_DOES_NOT_RETURN
40static void cant_do_write_method(PARROT_INTERP,
41    ARGIN_NULLOK(PMC *pmc),
42    int index)
43        __attribute__nonnull__(1);
44
45#define ASSERT_ARGS_caller __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
46       PARROT_ASSERT_ARG(interp))
47#define ASSERT_ARGS_cant_do_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
48       PARROT_ASSERT_ARG(interp))
49#define ASSERT_ARGS_cant_do_write_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
50       PARROT_ASSERT_ARG(interp))
51/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
52/* HEADERIZER END: static */
53
54/*
55
56=item C<static STRING * caller(PARROT_INTERP, PMC *pmc)>
57
58Returns a C string for the name of C<*pmc>.
59
60=cut
61
62*/
63
64PARROT_CANNOT_RETURN_NULL
65PARROT_WARN_UNUSED_RESULT
66static STRING *
67caller(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc))
68{
69    ASSERT_ARGS(caller)
70
71    return !PMC_IS_NULL(pmc) && pmc->vtable && pmc->vtable->whoami
72                ? VTABLE_name(interp, pmc)
73                : CONST_STRING(interp, "(null)");
74}
75
76/*
77
78=item C<static void cant_do_method(PARROT_INTERP, PMC *pmc, int index)>
79
80Throws an exception "$methname() not implemented in class '$class'", used by
81all unimplemented messages.
82
83=cut
84
85*/
86
87PARROT_DOES_NOT_RETURN
88static void
89cant_do_method(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), int index)
90{
91    ASSERT_ARGS(cant_do_method)
92
93    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ILL_INHERIT,
94            "%s() not implemented in class '%Ss'",
95            Parrot_get_vtable_name(interp, index),
96            caller(interp, pmc));
97}
98
99
100/*
101
102=item C<static void cant_do_write_method(PARROT_INTERP, PMC *pmc, int index)>
103
104Throws an exception "$methname() on read-only instance of '$class'", used by
105all updating messages on read-only instances.
106
107=cut
108
109*/
110
111PARROT_DOES_NOT_RETURN
112static void
113cant_do_write_method(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), int index)
114{
115    ASSERT_ARGS(cant_do_write_method)
116
117    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_WRITE_TO_CONSTCLASS,
118            "%s() in read-only instance of '%Ss'",
119            Parrot_get_vtable_name(interp, index),
120            caller(interp, pmc));
121}
122
123pmclass default abstract {
124
125/*
126
127=back
128
129=head2 Methods
130
131=over 4
132
133=item C<void init()>
134
135Does nothing.
136
137=cut
138
139*/
140
141    VTABLE void init() :no_wb {
142        UNUSED(INTERP);
143        UNUSED(SELF);
144    }
145
146/*
147
148=item C<void init_pmc(PMC *initializer)>
149
150With a null C<initializer>, calls C<init()>, else throws an exception.
151
152=cut
153
154*/
155
156    VTABLE void init_pmc(PMC *initializer) {
157        if (PMC_IS_NULL(initializer))
158            SELF.init();
159        else
160            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_ILL_INHERIT,
161                "init_pmc() not implemented in class '%Ss'",
162                caller(INTERP, SELF));
163    }
164
165/*
166
167=item C<void init_int(INTVAL initvalue)>
168
169Calls C<init()> and C<set_integer_native(initvalue)>.
170Default implementation to allow more usages of init_int without having to
171implement it everywhere.
172
173=cut
174
175*/
176
177    VTABLE void init_int(INTVAL initvalue) :manual_wb {
178        SELF.init();
179        SELF.set_integer_native(initvalue);
180    }
181
182/*
183
184=item C<void destroy()>
185
186Does nothing.
187
188=cut
189
190*/
191
192    VTABLE void destroy() :no_wb {
193        UNUSED(INTERP);
194        UNUSED(SELF);
195    }
196
197/*
198
199=item C<PMC *instantiate(PMC *init)>
200
201Default fallback. Creates a new PMC of the type of the class SELF and
202calls init().
203
204=cut
205
206*/
207
208    VTABLE PMC *instantiate(PMC *init) :no_wb {
209        const INTVAL type = VTABLE_type(INTERP, SELF);
210
211        /* Ensure no looping, as Parrot_pmc_new calls the instantiate vtable entry for
212         * classes. */
213        if (PObj_is_class_TEST(SELF))
214            Parrot_ex_throw_from_c_noargs(INTERP, EXCEPTION_INVALID_OPERATION,
215                    "All high-level classes should override instantiate");
216
217        if (!PMC_IS_NULL(init))
218            return Parrot_pmc_new_init(INTERP, type, init);
219
220        return Parrot_pmc_new(INTERP, type);
221    }
222
223/*
224
225=item C<void mark()>
226
227Panics with a "no custom mark routine defined" error message.
228
229=cut
230
231*/
232
233    VTABLE void mark() :no_wb {
234        UNUSED(SELF);
235        PANIC(INTERP, "custom_mark flag set but no custom mark routine defined");
236    }
237
238/*
239
240=item C<INTVAL type()>
241
242Returns the PMC's type.
243
244=cut
245
246*/
247
248    VTABLE INTVAL type() :no_wb {
249        UNUSED(INTERP);
250        return SELF->vtable->base_type;
251    }
252
253/*
254
255=item C<STRING *name()>
256
257Returns the name of the PMC.
258
259=cut
260
261*/
262
263    VTABLE STRING *name() :no_wb {
264        UNUSED(INTERP);
265        return SELF->vtable->whoami;
266    }
267
268
269/*
270
271=item C<void PMC *add_attribute(STRING *name, PMC *type)>
272
273Throws an exception, as you can only add an attribute to something Class-y or
274Role-y.
275
276=cut
277
278*/
279
280    VTABLE void add_attribute(STRING *name, PMC *type) :no_wb {
281        UNUSED(name);
282        UNUSED(type);
283        UNUSED(SELF);
284        Parrot_ex_throw_from_c_noargs(INTERP, EXCEPTION_INVALID_OPERATION,
285            "Cannot add attribute to non-class");
286    }
287
288/*
289
290=item C<PMC *get_namespace>
291
292Return the namespace for this PMC.
293
294=item C<PMC *find_method(STRING *method_name)>
295
296Looks up the method for C<*method_name> and returns it. If no method is
297found then C<NULL> is returned.
298
299=item C<void add_method(STRING *method_name, PMC *sub)>
300
301Store the method as a global in the namespace of this class.
302
303=cut
304
305*/
306
307    VTABLE PMC *get_namespace() :no_wb {
308
309        /* Because singletons are shared between interpreters, we need to make
310         * special effort to use the right namespace for method lookups.
311         * Note that this trick won't work if the singleton inherits from
312         * something else (because the MRO will still be shared).
313         * Having this code here avoids creating a special case for singletons
314         * elsewhere.
315         */
316
317        return INTERP->vtables[SELF->vtable->base_type]->_namespace;
318    }
319
320
321    VTABLE PMC *find_method(STRING *method_name) :no_wb {
322        return Parrot_find_method_with_cache(INTERP, SELF, method_name);
323    }
324
325    VTABLE void add_method(STRING *method_name, PMC *sub_pmc) {
326        VTABLE_set_pmc_keyed_str(INTERP, SELF->vtable->_namespace,
327                                 method_name, sub_pmc);
328    }
329/*
330
331=item C<INTVAL get_integer_keyed_int(INTVAL key)>
332
333Converts C<key> to a PMC key and returns the result of calling
334C<get_integer_keyed()> with it.
335
336=cut
337
338*/
339
340    VTABLE INTVAL get_integer_keyed_int(INTVAL key) :no_wb {
341        PMC *const r_key = INT2KEY(INTERP, key);
342        return SELF.get_integer_keyed(r_key);
343    }
344
345/*
346
347=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
348
349Converts C<key> to a PMC key and returns the result of calling
350C<get_number_keyed()> with it.
351
352=cut
353
354*/
355
356    VTABLE FLOATVAL get_number_keyed_int(INTVAL key) :no_wb {
357        PMC *const r_key = INT2KEY(INTERP, key);
358        return SELF.get_number_keyed(r_key);
359    }
360
361
362/*
363
364=item C<STRING *get_string_keyed_int(INTVAL key)>
365
366Converts C<key> to a PMC key and returns the result of calling
367C<get_string_keyed()> with it.
368
369=cut
370
371*/
372
373    VTABLE STRING *get_string_keyed_int(INTVAL key) :no_wb {
374        PMC *const r_key = INT2KEY(INTERP, key);
375        return SELF.get_string_keyed(r_key);
376    }
377
378/*
379
380=item C<PMC *get_pmc_keyed_int(INTVAL key)>
381
382Converts C<key> to a PMC key and returns the result of calling
383C<get_pmc_keyed()> with it.
384
385=cut
386
387*/
388
389    VTABLE PMC *get_pmc_keyed_int(INTVAL key) :no_wb {
390        PMC *const r_key = INT2KEY(INTERP, key);
391        return SELF.get_pmc_keyed(r_key);
392    }
393
394/*
395
396=item C<INTVAL is_same(PMC *value)>
397
398Returns whether the PMC is the same PMC as C<value> (whether they're the
399same pointer).
400
401=cut
402
403*/
404
405    VTABLE INTVAL is_same(PMC *value) :no_wb {
406        UNUSED(INTERP);
407        return SELF == value;
408    }
409
410/*
411
412=item C<void assign_pmc(PMC *value)>
413
414=item C<void assign_string_native(PMC *value)>
415
416Defaults fall back to C<set_pmc> and C<set_string_native>.
417
418=cut
419
420*/
421
422    VTABLE void assign_pmc(PMC *value) :manual_wb {
423        STRING * const undef = CONST_STRING(INTERP, "Undef");
424
425        if (VTABLE_isa(INTERP, value, undef))
426        {
427            Parrot_pmc_reuse(INTERP, SELF, value->vtable->base_type, 0);
428            PARROT_GC_WRITE_BARRIER(INTERP, SELF);
429        }
430        else
431            SELF.set_pmc(value);
432    }
433
434    VTABLE void assign_string_native(STRING *value) :manual_wb {
435        SELF.set_string_native(value);
436    }
437
438/*
439
440=item C<void morph(PMC* type)>
441
442Changes the PMC to a PMC of a new type
443
444=cut
445
446*/
447
448    VTABLE void morph(PMC* type) {
449        Parrot_pmc_reuse(INTERP, SELF, VTABLE_get_integer(INTERP, type), 0);
450    }
451
452/*
453
454=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
455
456Converts C<key> to a PMC key and calls C<set_integer_keyed()> with it
457and C<value>.
458
459=cut
460
461*/
462
463    VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) :manual_wb {
464        PMC *const r_key = INT2KEY(INTERP, key);
465        SELF.set_integer_keyed(r_key, value);
466    }
467
468/*
469
470=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
471
472Converts C<key> to a PMC key and calls C<set_number_keyed()> with it
473and C<value>.
474
475=cut
476
477*/
478
479    VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) :manual_wb {
480        PMC *const r_key = INT2KEY(INTERP, key);
481        SELF.set_number_keyed(r_key, value);
482    }
483
484/*
485
486=item C<void set_string_keyed_int(INTVAL key, STRING *string)>
487
488Converts C<key> to a PMC key and calls C<set_string_keyed()> with it
489and C<value>.
490
491=cut
492
493*/
494
495    VTABLE void set_string_keyed_int(INTVAL key, STRING *string) :manual_wb {
496        PMC *const r_key = INT2KEY(INTERP, key);
497        SELF.set_string_keyed(r_key, string);
498    }
499
500/*
501
502=item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
503
504Converts C<key> to a PMC key and calls C<set_pmc_keyed()> with it
505and C<value>.
506
507=cut
508
509*/
510
511    VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) :manual_wb {
512        PMC *const r_key = INT2KEY(INTERP, key);
513        SELF.set_pmc_keyed(r_key, value);
514    }
515
516/*
517
518=item C<INTVAL hashvalue()>
519
520Calculate hashvalue for PMC. Default behaviour stringify and use string.
521
522=cut
523
524*/
525
526    VTABLE INTVAL hashvalue() :no_wb {
527        STRING * const s = SELF.get_string();
528        return STRING_hash(INTERP, s, INTERP->hash_seed);
529    }
530
531/*
532
533=item C<INTVAL is_equal(PMC *value)>
534
535Default fallback. Performs a multiple dispatch call for 'is_equal'.
536
537=cut
538
539*/
540
541    VTABLE INTVAL is_equal(PMC *value) :no_wb {
542        INTVAL retval;
543        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
544                "is_equal", "PP->I", SELF, value, &retval);
545
546        return retval;
547    }
548
549/*
550
551=item C<INTVAL is_equal_num(PMC *value)>
552
553Default fallback. Performs a multiple dispatch call for 'is_equal_num'.
554
555=cut
556
557*/
558
559    VTABLE INTVAL is_equal_num(PMC *value) :no_wb {
560        INTVAL retval;
561        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
562                "is_equal_num", "PP->I", SELF, value, &retval);
563
564        return retval;
565    }
566
567/*
568
569=item C<INTVAL is_equal_string(PMC *value)>
570
571Default fallback. Performs a multiple dispatch call for 'is_equal'.
572
573=cut
574
575*/
576
577    VTABLE INTVAL is_equal_string(PMC *value) :no_wb {
578        INTVAL retval;
579        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
580                "is_equal_string", "PP->I", SELF, value, &retval);
581
582        return retval;
583    }
584
585/*
586
587=item C<INTVAL exists_keyed_int(INTVAL key)>
588
589Converts C<key> to a PMC key and returns the result of calling
590C<exists_keyed()> with it.
591
592=cut
593
594*/
595
596    VTABLE INTVAL exists_keyed_int(INTVAL key) :no_wb {
597        PMC *const r_key = INT2KEY(INTERP, key);
598        return SELF.exists_keyed(r_key);
599    }
600
601/*
602
603=item C<INTVAL defined()>
604
605Returns true.
606
607=cut
608
609*/
610
611    VTABLE INTVAL defined() :no_wb {
612        UNUSED(INTERP);
613        UNUSED(SELF);
614        return 1;
615    }
616
617/*
618
619=item C<INTVAL defined_keyed_int(INTVAL key)>
620
621Converts C<key> to a PMC key and returns the result of calling
622C<defined_keyed()> with it.
623
624=cut
625
626*/
627
628    VTABLE INTVAL defined_keyed_int(INTVAL key) :no_wb {
629        PMC *const r_key = INT2KEY(INTERP, key);
630        return SELF.defined_keyed(r_key);
631    }
632
633/*
634
635=item C<void delete_keyed_int(INTVAL key)>
636
637Converts C<key> to a PMC key and calls C<delete_keyed()> with it.
638
639=cut
640
641*/
642
643    VTABLE void delete_keyed_int(INTVAL key) :manual_wb {
644        PMC *const r_key = INT2KEY(INTERP, key);
645        SELF.delete_keyed(r_key);
646    }
647
648/*
649
650=item C<INTVAL does(STRING *interface_name)>
651
652Reports whether the PMC "does" perform C<interface_name>.
653If the interface C<interface_name> is found in the PMC's interface list,
654true (1) is returned; otherwise, false (0) is returned.
655
656=cut
657
658*/
659
660    VTABLE INTVAL does(STRING *interface_name) :no_wb {
661        return Parrot_pmc_type_does(INTERP, interface_name, SELF->vtable->base_type);
662    }
663
664/*
665
666=item C<INTVAL does_pmc(PMC *role)>
667
668Reports whether the PMC "does" the C<role>.
669
670=cut
671
672*/
673
674    VTABLE INTVAL does_pmc(PMC *role) :no_wb {
675        UNUSED(INTERP);
676        UNUSED(SELF);
677        UNUSED(role);
678        /* No C-level roles yet. */
679        return 0;
680    }
681
682/*
683
684=item C<INTVAL isa_pmc(PMC *_class)>
685
686Reports whether the PMC "isa" C<_class>.
687If the class C<_class> is found in the PMC's class hierarchy,
688true (1) is returned; otherwise, false (0) is returned.
689
690=cut
691
692*/
693
694    VTABLE INTVAL isa_pmc(PMC *lookup) :no_wb {
695        if (PMC_IS_NULL(lookup))
696            return 0;
697        else {
698            Hash   * const isa_hash = SELF->vtable->isa_hash;
699            STRING * const pmc_name = VTABLE_get_string(INTERP, lookup);
700            return Parrot_hash_exists(INTERP, isa_hash, pmc_name);
701        }
702    }
703
704/*
705
706=item C<INTVAL isa(STRING *_class)>
707
708Reports whether the PMC "isa" C<_class>.
709If the class C<_class> is found in the PMC's class hierarchy,
710true (1) is returned; otherwise, false (0) is returned.
711
712=cut
713
714*/
715
716    VTABLE INTVAL isa(STRING *_class) :no_wb {
717        if (SELF->vtable->whoami == _class)
718            return 1;
719        else {
720            const Hash * const isa_hash = SELF->vtable->isa_hash;
721            if (!isa_hash)
722                return STRING_equal(INTERP, SELF->vtable->whoami, _class);
723
724            return Parrot_hash_exists(INTERP, isa_hash, (void *)_class);
725        }
726    }
727
728/*
729
730=item C<PMC *inspect_str(STRING *what)>
731
732Provides introspection of a specific piece of information about the PMC.
733
734=cut
735
736*/
737
738    VTABLE PMC *inspect_str(STRING *name) :no_wb {
739        if (STRING_equal(INTERP, name, CONST_STRING(INTERP, "flags"))) {
740            PMC * const found = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
741                    (INTVAL)PObj_get_FLAGS(SELF));
742            return found;
743        }
744        else if (STRING_equal(INTERP, name, CONST_STRING(INTERP, "mro"))) {
745            return VTABLE_clone(INTERP, SELF->vtable->mro);
746        }
747        else
748            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
749                "Unknown introspection value '%S'", name);
750    }
751
752/*
753
754=item C<PMC *inspect()>
755
756Returns a Hash describing the class, with key/value pairs as described in
757inspect_str.
758
759=cut
760
761*/
762    VTABLE PMC *inspect() :no_wb {
763        PMC    * const metadata    = Parrot_pmc_new(INTERP, enum_class_Hash);
764        STRING * const flags_str   = CONST_STRING(INTERP, "flags");
765
766        VTABLE_set_pmc_keyed_str(INTERP, metadata, flags_str,
767            VTABLE_inspect_str(INTERP, SELF, flags_str));
768
769        return metadata;
770    }
771
772/*
773
774=item C<PMC *get_class()>
775
776Returns the class or PMCProxy of the type of the PMC.
777
778=cut
779
780*/
781    VTABLE PMC *get_class() :no_wb {
782        PMC * const ns     = VTABLE_get_namespace(INTERP, SELF);
783        PMC *_class = PMCNULL;
784
785        if (!PMC_IS_NULL(ns))
786            _class = VTABLE_get_class(INTERP, ns);
787
788        if (PMC_IS_NULL(_class)) {
789            const INTVAL type      = VTABLE_type(INTERP, SELF);
790            return Parrot_pmc_new_init_int(INTERP, enum_class_PMCProxy, type);
791        }
792
793        return _class;
794
795    }
796
797/*
798
799=item C<PMC *get_attr_keyed(PMC *key, STRING *name)>
800
801Default version of keyed attribute lookups. Discards the key and does a lookup
802by the string name passed in.
803
804=item C<void set_attr_keyed(PMC *key, STRING *name, PMC *value)>
805
806Default version of keyed attribute set. Discards the key and does a set by
807the string name passed in.
808
809=cut
810
811*/
812    VTABLE PMC *get_attr_keyed(PMC *key, STRING *name) :no_wb {
813        UNUSED(key);
814        return VTABLE_get_attr_str(INTERP, SELF, name);
815    }
816
817    VTABLE void set_attr_keyed(PMC *key, STRING *name, PMC *value) :manual_wb {
818        UNUSED(key);
819        VTABLE_set_attr_str(INTERP, SELF, name, value);
820    }
821
822/*
823
824=item C<void add_parent(PMC *parent)>
825
826Add class C<parent> to the list of our parents.
827
828=cut
829
830*/
831
832    VTABLE void add_parent(PMC *parent) {
833        UNUSED(parent);
834        if (!PObj_is_class_TEST(SELF))
835            Parrot_ex_throw_from_c_noargs(INTERP, EXCEPTION_INVALID_OPERATION,
836                "Only classes can be subclassed");
837
838        Parrot_ex_throw_from_c_noargs(INTERP, EXCEPTION_INVALID_OPERATION,
839                "All classes should override add_parent");
840    }
841
842/*
843
844=item C<void visit(PMC *info)>
845
846Used by GC to mark the PMC.
847
848=cut
849
850*/
851
852    VTABLE void visit(PMC *info) :no_wb {
853        UNUSED(INTERP);
854        UNUSED(SELF);
855        UNUSED(info);
856    }
857
858/*
859
860=item C<PMC* clone()>
861
862Clones this PMC.  By default, this just does a freeze and thaw.
863
864=cut
865
866*/
867
868    VTABLE PMC* clone() :no_wb {
869        return Parrot_thaw(INTERP, Parrot_freeze(INTERP, SELF));
870    }
871
872/*
873
874=item C<void freeze(PMC *info)>
875
876Does nothing.
877
878=cut
879
880*/
881
882    VTABLE void freeze(PMC *info) :no_wb {
883        UNUSED(INTERP);
884        UNUSED(SELF);
885        UNUSED(info);
886        /* default - no action */
887    }
888
889/*
890
891=item C<void thaw(PMC *info)>
892
893Initializes the PMC during unarchiving.
894
895=cut
896
897*/
898
899    VTABLE void thaw(PMC *info) :manual_wb { /* WB in init */
900        UNUSED(info);
901        /* default - initialize the PMC */
902        SELF.init();
903    }
904
905/*
906
907=item C<void thawfinish(PMC *info)>
908
909Does nothing.
910
911=cut
912
913*/
914
915    VTABLE void thawfinish(PMC *info) :no_wb {
916        UNUSED(INTERP);
917        UNUSED(SELF);
918        UNUSED(info);
919        /* default - no action */
920    }
921
922/*
923
924=item C<PMC *add(PMC *value, PMC *dest)>
925
926Default fallback. Performs a multiple dispatch call for 'add'.
927
928=cut
929
930*/
931
932    VTABLE PMC *add(PMC *value, PMC *dest) :no_wb {
933        PMC *result = PMCNULL;
934        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
935                "add", "PPP->P", SELF, value, dest, &result);
936        return result;
937    }
938
939/*
940
941=item C<PMC *add_int(INTVAL value, PMC *dest)>
942
943Default fallback. Performs a multiple dispatch call for 'add_int'.
944
945=cut
946
947*/
948
949    VTABLE PMC *add_int(INTVAL value, PMC *dest) :no_wb {
950        PMC *result = PMCNULL;
951        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
952                "add_int", "PIP->P", SELF, value, dest, &result);
953        return result;
954    }
955
956/*
957
958=item C<PMC *add_float(FLOATVAL value, PMC *dest)>
959
960Default fallback. Performs a multiple dispatch call for 'add_float'.
961
962=cut
963
964*/
965
966    VTABLE PMC *add_float(FLOATVAL value, PMC *dest) :no_wb {
967        dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
968
969        VTABLE_set_number_native(INTERP, dest,
970                SELF.get_number() + value);
971        return dest;
972    }
973
974/*
975
976=item C<void i_add(PMC *value)>
977
978Default fallback. Performs a multiple dispatch call for 'i_add'.
979
980=cut
981
982*/
983
984    VTABLE void i_add(PMC *value) {
985        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
986                "i_add", "PP", SELF, value);
987    }
988
989/*
990
991=item C<void i_add_int(INTVAL value)>
992
993Default fallback. Performs a multiple dispatch call for 'i_add_int'.
994
995=cut
996
997*/
998
999    VTABLE void i_add_int(INTVAL value) {
1000        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1001                "i_add_int", "PI", SELF, value);
1002    }
1003
1004/*
1005
1006=item C<void i_add_float(FLOATVAL value)>
1007
1008Default fallback. Performs a multiple dispatch call for 'i_add_float'.
1009
1010=cut
1011
1012*/
1013
1014    VTABLE void i_add_float(FLOATVAL value) {
1015        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1016                "i_add_float", "PN", SELF, value);
1017    }
1018
1019/*
1020
1021=item C<PMC *subtract(PMC *value, PMC *dest)>
1022
1023Default fallback. Performs a multiple dispatch call for 'subtract'.
1024
1025=cut
1026
1027*/
1028
1029    VTABLE PMC *subtract(PMC *value, PMC *dest) :no_wb {
1030        PMC *result = PMCNULL;
1031        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1032                "subtract", "PPP->P", SELF, value, dest, &result);
1033        return result;
1034    }
1035
1036/*
1037
1038=item C<PMC *subtract_int(INTVAL value, PMC *dest)>
1039
1040Default fallback. Performs a multiple dispatch call for 'subtract_int'.
1041
1042=cut
1043
1044*/
1045
1046    VTABLE PMC *subtract_int(INTVAL value, PMC *dest) :no_wb {
1047        PMC *result = PMCNULL;
1048        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1049                "subtract_int", "PIP->P", SELF, value, dest, &result);
1050        return result;
1051    }
1052
1053/*
1054
1055=item C<PMC *subtract_float(FLOATVAL value, PMC *dest)>
1056
1057Default fallback. Performs a multiple dispatch call for 'subtract_float'.
1058
1059=cut
1060
1061*/
1062
1063    VTABLE PMC *subtract_float(FLOATVAL value, PMC *dest) :no_wb {
1064        PMC *result = PMCNULL;
1065        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1066                "subtract_float", "PNP->P", SELF, value, dest, &result);
1067        return result;
1068    }
1069
1070/*
1071
1072=item C<void i_subtract(PMC *value)>
1073
1074Default fallback. Performs a multiple dispatch call for 'i_subtract'.
1075
1076=cut
1077
1078*/
1079
1080    VTABLE void i_subtract(PMC *value) {
1081        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1082                "i_subtract", "PP", SELF, value);
1083    }
1084
1085/*
1086
1087=item C<void i_subtract_int(INTVAL value)>
1088
1089Default fallback. Performs a multiple dispatch call for 'i_subtract_int'.
1090
1091=cut
1092
1093*/
1094
1095    VTABLE void i_subtract_int(INTVAL value) {
1096        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1097                "i_subtract_int", "PI", SELF, value);
1098    }
1099
1100/*
1101
1102=item C<void i_subtract_float(FLOATVAL value)>
1103
1104Default fallback. Performs a multiple dispatch call for 'i_subtract_float'.
1105
1106=cut
1107
1108*/
1109
1110    VTABLE void i_subtract_float(FLOATVAL value) {
1111        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1112                "i_subtract_float", "PN", SELF, value);
1113    }
1114
1115/*
1116
1117=item C<PMC *multiply(PMC *value, PMC *dest)>
1118
1119Default fallback. Performs a multiple dispatch call for 'multiply'.
1120
1121=cut
1122
1123*/
1124
1125    VTABLE PMC *multiply(PMC *value, PMC *dest) :no_wb {
1126        PMC *result = PMCNULL;
1127        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1128                "multiply", "PPP->P", SELF, value, dest, &result);
1129        return result;
1130    }
1131
1132/*
1133
1134=item C<PMC *multiply_int(INTVAL value, PMC *dest)>
1135
1136Default fallback. Performs a multiple dispatch call for 'multiply_int'.
1137
1138=cut
1139
1140*/
1141
1142    VTABLE PMC *multiply_int(INTVAL value, PMC *dest) :no_wb {
1143        PMC *result = PMCNULL;
1144        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1145                "multiply_int", "PIP->P", SELF, value, dest, &result);
1146        return result;
1147    }
1148
1149/*
1150
1151=item C<PMC *multiply_float(FLOATVAL value, PMC *dest)>
1152
1153Default fallback. Performs a multiple dispatch call for 'multiply_float'.
1154
1155=cut
1156
1157*/
1158
1159    VTABLE PMC *multiply_float(FLOATVAL value, PMC *dest) :no_wb {
1160        PMC *result = PMCNULL;
1161        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1162                "multiply_float", "PNP->P", SELF, value, dest, &result);
1163        return result;
1164    }
1165
1166/*
1167
1168=item C<void i_multiply(PMC *value)>
1169
1170Default fallback. Performs a multiple dispatch call for 'i_multiply'.
1171
1172=cut
1173
1174*/
1175
1176    VTABLE void i_multiply(PMC *value) {
1177        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1178                "i_multiply", "PP", SELF, value);
1179    }
1180
1181/*
1182
1183=item C<void i_multiply_int(INTVAL value)>
1184
1185Default fallback. Performs a multiple dispatch call for 'i_multiply_int'.
1186
1187=cut
1188
1189*/
1190
1191    VTABLE void i_multiply_int(INTVAL value) {
1192        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1193                "i_multiply_int", "PI", SELF, value);
1194    }
1195
1196/*
1197
1198=item C<void i_multiply_float(FLOATVAL value)>
1199
1200Default fallback. Performs a multiple dispatch call for 'i_multiply_float'.
1201
1202=cut
1203
1204*/
1205
1206    VTABLE void i_multiply_float(FLOATVAL value) {
1207        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1208                "i_multiply_float", "PN", SELF, value);
1209    }
1210
1211/*
1212
1213=item C<PMC *divide(PMC *value, PMC *dest)>
1214
1215Default fallback. Performs a multiple dispatch call for 'divide'.
1216
1217=cut
1218
1219*/
1220
1221    VTABLE PMC *divide(PMC *value, PMC *dest) :no_wb {
1222        PMC *result = PMCNULL;
1223        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1224                "divide", "PPP->P", SELF, value, dest, &result);
1225        return result;
1226    }
1227
1228/*
1229
1230=item C<PMC *divide_int(INTVAL value, PMC *dest)>
1231
1232Default fallback. Performs a multiple dispatch call for 'divide_int'.
1233
1234=cut
1235
1236*/
1237
1238    VTABLE PMC *divide_int(INTVAL value, PMC *dest) :no_wb {
1239        PMC *result = PMCNULL;
1240        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1241                "divide_int", "PIP->P", SELF, value, dest, &result);
1242        return result;
1243    }
1244
1245/*
1246
1247=item C<PMC *divide_float(FLOATVAL value, PMC *dest)>
1248
1249Default fallback. Performs a multiple dispatch call for 'divide_float'.
1250
1251=cut
1252
1253*/
1254
1255    VTABLE PMC *divide_float(FLOATVAL value, PMC *dest) :no_wb {
1256        PMC *result = PMCNULL;
1257        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1258                "divide_float", "PNP->P", SELF, value, dest, &result);
1259        return result;
1260    }
1261
1262/*
1263
1264=item C<void i_divide(PMC *value)>
1265
1266Default fallback. Performs a multiple dispatch call for 'i_divide'.
1267
1268=cut
1269
1270*/
1271
1272    VTABLE void i_divide(PMC *value) {
1273        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1274                "i_divide", "PP", SELF, value);
1275    }
1276
1277/*
1278
1279=item C<void i_divide_int(INTVAL value)>
1280
1281Default fallback. Performs a multiple dispatch call for 'i_divide_int'.
1282
1283=cut
1284
1285*/
1286
1287    VTABLE void i_divide_int(INTVAL value) {
1288        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1289                "i_divide_int", "PI", SELF, value);
1290    }
1291
1292/*
1293
1294=item C<void i_divide_float(FLOATVAL value)>
1295
1296Default fallback. Performs a multiple dispatch call for 'i_divide_float'.
1297
1298=cut
1299
1300*/
1301
1302    VTABLE void i_divide_float(FLOATVAL value) {
1303        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1304                "i_divide_float", "PN", SELF, value);
1305    }
1306
1307/*
1308
1309=item C<PMC *floor_divide(PMC *value, PMC *dest)>
1310
1311Default fallback. Performs a multiple dispatch call for 'floor_divide'.
1312
1313=cut
1314
1315*/
1316
1317    VTABLE PMC *floor_divide(PMC *value, PMC *dest) :no_wb {
1318        PMC *result = PMCNULL;
1319        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1320                "floor_divide", "PPP->P", SELF, value, dest, &result);
1321        return result;
1322    }
1323
1324/*
1325
1326=item C<PMC *floor_divide_int(INTVAL value, PMC *dest)>
1327
1328Default fallback. Performs a multiple dispatch call for 'floor_divide_int'.
1329
1330=cut
1331
1332*/
1333
1334    VTABLE PMC *floor_divide_int(INTVAL value, PMC *dest) :no_wb {
1335        PMC *result = PMCNULL;
1336        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1337                "floor_divide_int", "PIP->P", SELF, value, dest, &result);
1338        return result;
1339    }
1340
1341/*
1342
1343=item C<PMC *floor_divide_float(FLOATVAL value, PMC *dest)>
1344
1345Default fallback. Performs a multiple dispatch call for 'floor_divide_float'.
1346
1347=cut
1348
1349*/
1350
1351    VTABLE PMC *floor_divide_float(FLOATVAL value, PMC *dest) :no_wb {
1352        PMC *result = PMCNULL;
1353        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1354                "floor_divide_float", "PNP->P", SELF, value, dest, &result);
1355        return result;
1356    }
1357
1358/*
1359
1360=item C<void i_floor_divide(PMC *value)>
1361
1362Default fallback. Performs a multiple dispatch call for 'i_floor_divide'.
1363
1364=cut
1365
1366*/
1367
1368    VTABLE void i_floor_divide(PMC *value) {
1369        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1370                "i_floor_divide", "PP", SELF, value);
1371    }
1372
1373/*
1374
1375=item C<void i_floor_divide_int(INTVAL value)>
1376
1377Default fallback. Performs a multiple dispatch call for 'i_floor_divide_int'.
1378
1379=cut
1380
1381*/
1382
1383    VTABLE void i_floor_divide_int(INTVAL value) {
1384        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1385                "i_floor_divide_int", "PI", SELF, value);
1386    }
1387
1388/*
1389
1390=item C<void i_floor_divide_float(FLOATVAL value)>
1391
1392Default fallback. Performs a multiple dispatch call for 'i_floor_divide_float'.
1393
1394=cut
1395
1396*/
1397
1398    VTABLE void i_floor_divide_float(FLOATVAL value) {
1399        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1400                "i_floor_divide_float", "PN", SELF, value);
1401    }
1402
1403/*
1404
1405=item C<PMC *modulus(PMC *value, PMC *dest)>
1406
1407Default fallback. Performs a multiple dispatch call for 'modulus'.
1408
1409=cut
1410
1411*/
1412
1413    VTABLE PMC *modulus(PMC *value, PMC *dest) :no_wb {
1414        PMC *result = PMCNULL;
1415        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1416                "modulus", "PPP->P", SELF, value, dest, &result);
1417        return result;
1418    }
1419
1420/*
1421
1422=item C<PMC *modulus_int(INTVAL value, PMC *dest)>
1423
1424Default fallback. Performs a multiple dispatch call for 'modulus_int'.
1425
1426=cut
1427
1428*/
1429
1430    VTABLE PMC *modulus_int(INTVAL value, PMC *dest) :no_wb {
1431        PMC *result = PMCNULL;
1432        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1433                "modulus_int", "PIP->P", SELF, value, dest, &result);
1434        return result;
1435    }
1436
1437/*
1438
1439=item C<PMC *modulus_float(FLOATVAL value, PMC *dest)>
1440
1441Default fallback. Performs a multiple dispatch call for 'modulus_float'.
1442
1443=cut
1444
1445*/
1446
1447    VTABLE PMC *modulus_float(FLOATVAL value, PMC *dest) :no_wb {
1448        PMC *result = PMCNULL;
1449        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1450                "modulus_float", "PNP->P", SELF, value, dest, &result);
1451        return result;
1452    }
1453
1454/*
1455
1456=item C<void i_modulus(PMC *value)>
1457
1458Default fallback. Performs a multiple dispatch call for 'i_modulus'.
1459
1460=cut
1461
1462*/
1463
1464    VTABLE void i_modulus(PMC *value) {
1465        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1466                "i_modulus", "PP", SELF, value);
1467    }
1468
1469/*
1470
1471=item C<void i_modulus_int(INTVAL value)>
1472
1473Default fallback. Performs a multiple dispatch call for 'i_modulus_int'.
1474
1475=cut
1476
1477*/
1478
1479    VTABLE void i_modulus_int(INTVAL value) {
1480        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1481                "i_modulus_int", "PI", SELF, value);
1482    }
1483
1484/*
1485
1486=item C<void i_modulus_float(FLOATVAL value)>
1487
1488Default fallback. Performs a multiple dispatch call for 'i_modulus_float'.
1489
1490=cut
1491
1492*/
1493
1494    VTABLE void i_modulus_float(FLOATVAL value) {
1495        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1496                "i_modulus_float", "PN", SELF, value);
1497    }
1498
1499/*
1500
1501=item C<INTVAL cmp(PMC *value)>
1502
1503Default fallback. Performs a multiple dispatch call for 'cmp'.
1504
1505=cut
1506
1507*/
1508
1509    VTABLE INTVAL cmp(PMC *value) :no_wb {
1510        INTVAL retval;
1511
1512        /* Don't multidispatch if you've got two pointers to the same PMC. They
1513         * are equal. */
1514        if (SELF == value)
1515            return 0;
1516
1517        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1518                "cmp", "PP->I", SELF, value, &retval);
1519
1520        return retval;
1521    }
1522
1523/*
1524
1525=item C<INTVAL cmp_num(PMC *value)>
1526
1527Default fallback. Performs a multiple dispatch call for 'cmp_num'.
1528
1529=cut
1530
1531*/
1532
1533    VTABLE INTVAL cmp_num(PMC *value) :no_wb {
1534        INTVAL retval;
1535        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1536                "cmp_num", "PP->I", SELF, value, &retval);
1537
1538        return retval;
1539    }
1540
1541/*
1542
1543=item C<INTVAL cmp_string(PMC *value)>
1544
1545Default fallback. Performs a multiple dispatch call for 'cmp_string'.
1546
1547=cut
1548
1549*/
1550
1551    VTABLE INTVAL cmp_string(PMC *value) :no_wb {
1552        INTVAL retval;
1553        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1554                "cmp_string", "PP->I", SELF, value, &retval);
1555
1556        return retval;
1557    }
1558
1559/*
1560
1561=item C<PMC *cmp_pmc(PMC *value)>
1562
1563Default fallback. Performs a multiple dispatch call for 'cmp_pmc'.
1564
1565=cut
1566
1567*/
1568
1569    VTABLE PMC *cmp_pmc(PMC *value) :no_wb {
1570        PMC *retval;
1571
1572        /* Don't multidispatch if you've got two pointers to the same PMC. They
1573         * are equal. */
1574        if (SELF == value)
1575            return NULL;
1576
1577        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1578                "cmp_pmc", "PP->P", SELF, value, &retval);
1579
1580        return retval;
1581    }
1582
1583/*
1584
1585=item C<PMC *concatenate(PMC *value, PMC *dest)>
1586
1587Default fallback. Performs a multiple dispatch call for 'concatenate'.
1588
1589=cut
1590
1591*/
1592
1593    VTABLE PMC *concatenate(PMC *value, PMC *dest) :no_wb {
1594        PMC *result = PMCNULL;
1595        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1596                "concatenate", "PPP->P", SELF, value, dest, &result);
1597        return result;
1598    }
1599
1600/*
1601
1602=item C<PMC *concatenate_str(STRING *value, PMC *dest)>
1603
1604Default fallback. Performs a multiple dispatch call for 'concatenate_str'.
1605
1606=cut
1607
1608*/
1609
1610    VTABLE PMC *concatenate_str(STRING *value, PMC *dest) :no_wb {
1611        PMC *result = PMCNULL;
1612        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1613                "concatenate_str", "PSP->P", SELF, value, dest, &result);
1614        return result;
1615    }
1616
1617/*
1618
1619=item C<void i_concatenate(PMC *value)>
1620
1621Default fallback. Performs a multiple dispatch call for 'i_concatenate'.
1622
1623=cut
1624
1625*/
1626
1627    VTABLE void i_concatenate(PMC *value) {
1628        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1629                "i_concatenate", "PP", SELF, value);
1630    }
1631
1632/*
1633
1634=item C<void i_concatenate_str(STRING *value)>
1635
1636Default fallback. Performs a multiple dispatch call for 'i_concatenate_str'.
1637
1638=cut
1639
1640*/
1641
1642    VTABLE void i_concatenate_str(STRING *value) {
1643        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1644                "i_concatenate_str", "PS", SELF, value);
1645    }
1646
1647/*
1648
1649=item C<PMC *repeat(PMC *value, PMC *dest)>
1650
1651Default fallback. Performs a multiple dispatch call for 'repeat'.
1652
1653=cut
1654
1655*/
1656
1657    VTABLE PMC *repeat(PMC *value, PMC *dest) :no_wb {
1658        PMC *result = PMCNULL;
1659        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1660                "repeat", "PPP->P", SELF, value, dest, &result);
1661        return result;
1662    }
1663
1664/*
1665
1666=item C<PMC *repeat_int(INTVAL value, PMC *dest)>
1667
1668Default fallback. Performs a multiple dispatch call for 'repeat_int'.
1669
1670=cut
1671
1672*/
1673
1674    VTABLE PMC *repeat_int(INTVAL value, PMC *dest) :no_wb {
1675        PMC *result = PMCNULL;
1676        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1677                "repeat_int", "PIP->P", SELF, value, dest, &result);
1678        return result;
1679    }
1680
1681/*
1682
1683=item C<void i_repeat(PMC *value)>
1684
1685Default fallback. Performs a multiple dispatch call for 'i_repeat'.
1686
1687=cut
1688
1689*/
1690
1691    VTABLE void i_repeat(PMC *value) {
1692        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1693                "i_repeat", "PP", SELF, value);
1694    }
1695
1696/*
1697
1698=item C<void i_repeat_int(INTVAL value)>
1699
1700Default fallback. Performs a multiple dispatch call for 'i_repeat_int'.
1701
1702=cut
1703
1704*/
1705
1706    VTABLE void i_repeat_int(INTVAL value) {
1707        Parrot_mmd_multi_dispatch_from_c_args(INTERP,
1708                "i_repeat_int", "PI", SELF, value);
1709    }
1710}
1711
1712/*
1713
1714=back
1715
1716=cut
1717
1718*/
1719
1720/*
1721 * Local variables:
1722 *   c-file-style: "parrot"
1723 * End:
1724 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
1725 */
1726