/home/travis/build/MoarVM/MoarVM/src/core/callsite.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Callsite argument flags. */ |
2 | | #define MVM_CALLSITE_ARG_MASK 31 |
3 | | typedef enum { |
4 | | /* Argument is an object. */ |
5 | | MVM_CALLSITE_ARG_OBJ = 1, |
6 | | |
7 | | /* Argument is a native integer, signed. */ |
8 | | MVM_CALLSITE_ARG_INT = 2, |
9 | | |
10 | | /* Argument is a native floating point number. */ |
11 | | MVM_CALLSITE_ARG_NUM = 4, |
12 | | |
13 | | /* Argument is a native NFG string (MVMString REPR). */ |
14 | | MVM_CALLSITE_ARG_STR = 8, |
15 | | |
16 | | /* Argument is named. The name is placed in the MVMCallsite. */ |
17 | | MVM_CALLSITE_ARG_NAMED = 32, |
18 | | |
19 | | /* Argument is flattened. What this means is up to the target. */ |
20 | | MVM_CALLSITE_ARG_FLAT = 64, |
21 | | |
22 | | /* Argument is flattened and named. */ |
23 | | MVM_CALLSITE_ARG_FLAT_NAMED = 128 |
24 | | } MVMCallsiteFlags; |
25 | | |
26 | | typedef enum { |
27 | | /* Zero argument callsite. */ |
28 | | MVM_CALLSITE_ID_NULL_ARGS, |
29 | | |
30 | | /* Dummy, invocant-arg callsite. Taken from coerce.c; |
31 | | * OBJ */ |
32 | | MVM_CALLSITE_ID_INV_ARG, |
33 | | |
34 | | /* Callsite for container store. Taken from containers.c; |
35 | | * OBJ, OBJ */ |
36 | | MVM_CALLSITE_ID_TWO_OBJ, |
37 | | |
38 | | /* Callsite for method not found errors. Taken from 6model.c; |
39 | | * OBJ, STR */ |
40 | | MVM_CALLSITE_ID_METH_NOT_FOUND, |
41 | | |
42 | | /* Callsite for finding methods. Taken from 6model.c; |
43 | | * OBJ, OBJ, STR */ |
44 | | MVM_CALLSITE_ID_FIND_METHOD, |
45 | | |
46 | | /* Callsite for typechecks. Taken from 6model.c; |
47 | | * OBJ, OBJ, OBJ */ |
48 | | MVM_CALLSITE_ID_TYPECHECK, |
49 | | |
50 | | /* Callsite OBJ, INT */ |
51 | | MVM_CALLSITE_ID_OBJ_INT, |
52 | | |
53 | | /* Callsite OBJ, INT */ |
54 | | MVM_CALLSITE_ID_OBJ_NUM, |
55 | | |
56 | | /* Callsite OBJ, STR */ |
57 | | MVM_CALLSITE_ID_OBJ_STR, |
58 | | |
59 | | /* Callsite INT, INT */ |
60 | | MVM_CALLSITE_ID_INT_INT, |
61 | | } MVMCommonCallsiteID; |
62 | | |
63 | | /* A callsite entry is just one of the above flags. */ |
64 | | typedef MVMuint8 MVMCallsiteEntry; |
65 | | |
66 | | /* A callsite is an argument count, a bunch of flags, and names of named |
67 | | * arguments (excluding any flattening ones). Note that it does not contain |
68 | | * the argument values; this is the *statically known* things about the |
69 | | * callsite and is immutable. It describes how to process the callsite |
70 | | * memory buffer. */ |
71 | | struct MVMCallsite { |
72 | | /* The set of flags. */ |
73 | | MVMCallsiteEntry *arg_flags; |
74 | | |
75 | | /* The number of arg flags. */ |
76 | | MVMuint16 flag_count; |
77 | | |
78 | | /* The total argument count (including 2 for each named arg). */ |
79 | | MVMuint16 arg_count; |
80 | | |
81 | | /* Number of positionals, including flattening positionals but |
82 | | * excluding named positionals. */ |
83 | | MVMuint16 num_pos; |
84 | | |
85 | | /* Whether it has any flattening args. */ |
86 | | MVMuint8 has_flattening; |
87 | | |
88 | | /* Whether it has been interned (which means it is suitable for using in |
89 | | * specialization). */ |
90 | | MVMuint8 is_interned; |
91 | | |
92 | | /* Cached version of this callsite with an extra invocant arg. */ |
93 | | MVMCallsite *with_invocant; |
94 | | |
95 | | /* Names of named arguments, in the order that they are passed (and thus |
96 | | * matching the flags). Note that named flattening args do not have an |
97 | | * entry here, even though they come in the nameds section. */ |
98 | | MVMString **arg_names; |
99 | | }; |
100 | | |
101 | | /* Minimum callsite size is due to certain things internally expecting us to |
102 | | * have that many slots available (e.g. find_method(how, obj, name)). */ |
103 | | #define MVM_MIN_CALLSITE_SIZE 3 |
104 | | |
105 | | /* Maximum arity + 1 that we'll intern callsites by. */ |
106 | | #define MVM_INTERN_ARITY_LIMIT 8 |
107 | | |
108 | | /* Interned callsites data structure. */ |
109 | | struct MVMCallsiteInterns { |
110 | | /* Array of callsites, by arity. */ |
111 | | MVMCallsite **by_arity[MVM_INTERN_ARITY_LIMIT]; |
112 | | |
113 | | /* Number of callsites we have interned by arity. */ |
114 | | MVMint32 num_by_arity[MVM_INTERN_ARITY_LIMIT]; |
115 | | }; |
116 | | |
117 | | /* Initialize the "common" callsites */ |
118 | | void MVM_callsite_initialize_common(MVMThreadContext *tc); |
119 | | |
120 | | /* Get any of the "common" callsites */ |
121 | | MVM_PUBLIC MVMCallsite *MVM_callsite_get_common(MVMThreadContext *tc, MVMCommonCallsiteID id); |
122 | | |
123 | | int MVM_callsite_is_common(MVMCallsite *cs); |
124 | | |
125 | | void MVM_callsite_destroy(MVMCallsite *cs); |
126 | | |
127 | | MVMCallsite *MVM_callsite_copy(MVMThreadContext *tc, const MVMCallsite *cs); |
128 | | |
129 | | /* Callsite interning function. */ |
130 | | MVM_PUBLIC void MVM_callsite_try_intern(MVMThreadContext *tc, MVMCallsite **cs); |
131 | | |
132 | | /* Count the number of nameds (excluding flattening). */ |
133 | 0 | MVM_STATIC_INLINE MVMuint16 MVM_callsite_num_nameds(MVMThreadContext *tc, const MVMCallsite *cs) { |
134 | 0 | MVMuint16 i = cs->num_pos; |
135 | 0 | MVMuint16 nameds = 0; |
136 | 0 | while (i < cs->flag_count) { |
137 | 0 | if (!(cs->arg_flags[i] & MVM_CALLSITE_ARG_FLAT_NAMED)) |
138 | 0 | nameds++; |
139 | 0 | i++; |
140 | 0 | } |
141 | 0 | return nameds; |
142 | 0 | } |