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