1/* 2Copyright (C) 2001-2014, Parrot Foundation. 3 4=head1 NAME 5 6src/pmc/multisub.pmc - MultiSub PMC 7 8=head1 DESCRIPTION 9 10A container for multi-dispatched subs. 11 12This class inherits from ResizablePMCArray and provides an Array of 13Sub PMCs with the same short name, but different long names. 14 15=head2 Functions 16 17=over 4 18 19=cut 20 21*/ 22 23#include "pmc/pmc_callcontext.h" 24 25/* HEADERIZER HFILE: none */ 26/* HEADERIZER BEGIN: static */ 27/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 28 29static void check_is_valid_sub(PARROT_INTERP, ARGIN(PMC * sub)) 30 __attribute__nonnull__(1) 31 __attribute__nonnull__(2); 32 33#define ASSERT_ARGS_check_is_valid_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 34 PARROT_ASSERT_ARG(interp) \ 35 , PARROT_ASSERT_ARG(sub)) 36/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 37/* HEADERIZER END: static */ 38 39/* 40 41=item C<static void check_is_valid_sub(PARROT_INTERP, PMC * sub)> 42 43TK 44 45=cut 46 47*/ 48 49static void 50check_is_valid_sub(PARROT_INTERP, ARGIN(PMC * sub)) 51{ 52 ASSERT_ARGS(check_is_valid_sub) 53 STRING * const invokable_str = CONST_STRING(interp, "invokable"); 54 if (!VTABLE_does(interp, sub, invokable_str)) 55 Parrot_ex_throw_from_c_noargs(interp, EXCEPTION_INVALID_OPERATION, 56 "attempt to add non-invokable PMC"); 57} 58 59pmclass MultiSub 60 extends ResizablePMCArray 61 auto_attrs 62 provides array 63 provides invokable { 64 65 VTABLE STRING * get_string() :no_wb { 66 PMC * const sub0 = VTABLE_get_pmc_keyed_int(INTERP, SELF, 0); 67 /*if (PMC_IS_NULL(sub0)) 68 return STRINGNULL;*/ 69 STRING * const name = VTABLE_get_string(INTERP, sub0); 70 return name; 71 } 72 73 VTABLE void push_pmc(PMC *value) :manual_wb { 74 check_is_valid_sub(INTERP, value); 75 SUPER(value); 76 } 77 78 VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) :manual_wb { 79 check_is_valid_sub(INTERP, value); 80 SUPER(key, value); 81 } 82 83 VTABLE opcode_t *invoke(void *next) :no_wb { 84 PMC * const sig_obj = CONTEXT(INTERP)->current_sig; 85 PMC * const func = Parrot_mmd_sort_manhattan_by_sig_pmc(INTERP, 86 SELF, sig_obj); 87 88 if (PMC_IS_NULL(func)) 89 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_METHOD_NOT_FOUND, 90 "No applicable candidates found to dispatch to for '%Ss'", 91 VTABLE_get_string(INTERP, SELF)); 92 return VTABLE_invoke(INTERP, func, next); 93 } 94} 95 96/* 97 98=back 99 100=head1 SEE ALSO 101 102F<src/multidispatch.c>, 103 104=cut 105 106*/ 107 108/* 109 * Local variables: 110 * c-file-style: "parrot" 111 * End: 112 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' : 113 */ 114