@@ -6,33 +6,54 @@ void MVM_callsite_try_intern(MVMThreadContext *tc, MVMCallsite **cs_ptr) {
6
6
MVMCallsiteInterns * interns = tc -> instance -> callsite_interns ;
7
7
MVMCallsite * cs = * cs_ptr ;
8
8
MVMint32 num_pos = cs -> num_pos ;
9
- MVMint32 i , found ;
9
+ MVMint32 num_flags = num_pos + (cs -> arg_count - num_pos ) / 2 ;
10
+ MVMint32 i , j , found ;
10
11
11
- /* Can't intern anything with named or flattening, for now. */
12
- if (cs -> arg_count != num_pos )
13
- return ;
12
+ /* Can't intern anything with flattening, for now. */
14
13
if (cs -> has_flattening )
15
14
return ;
16
15
17
16
/* Also can't intern past the max arity. */
18
- if (num_pos >= MVM_INTERN_ARITY_LIMIT )
17
+ if (num_flags >= MVM_INTERN_ARITY_LIMIT )
18
+ return ;
19
+
20
+ if (num_flags > num_pos && !cs -> arg_name )
19
21
return ;
20
22
23
+ for (j = 0 ; j < num_flags - num_pos ; j ++ ) {
24
+ if (!cs -> arg_name [j ])
25
+ return ;
26
+ }
27
+
21
28
/* Obtain mutex protecting interns store. */
22
29
uv_mutex_lock (& tc -> instance -> mutex_callsite_interns );
23
30
24
31
/* Search for a match. */
25
32
found = 0 ;
26
33
for (i = 0 ; i < interns -> num_by_arity [num_pos ]; i ++ ) {
27
- if (memcmp (interns -> by_arity [num_pos ][i ]-> arg_flags , cs -> arg_flags , num_pos ) == 0 ) {
34
+ if (cs -> arg_count != interns -> by_arity [num_pos ][i ]-> arg_count )
35
+ continue ;
36
+ if (memcmp (interns -> by_arity [num_pos ][i ]-> arg_flags , cs -> arg_flags , num_flags ) == 0 ) {
37
+ /* Now let's have a look at the named arguments. */
38
+ for (j = 0 ; j < num_flags - num_pos ; j ++ ) {
39
+ /* if any of the nameds are not known at this time, we skip this */
40
+ if ( !interns -> by_arity [num_pos ][i ]-> arg_name || !interns -> by_arity [num_pos ][i ]-> arg_name [j ]
41
+ || !MVM_string_equal (tc , cs -> arg_name [j ], interns -> by_arity [num_pos ][i ]-> arg_name [j ])) {
42
+ goto cancel ;
43
+ }
44
+ }
28
45
/* Got a match! Free the one we were passed and replace it with
29
46
* the interned one. */
30
47
if (num_pos )
31
48
free (cs -> arg_flags );
49
+ if (num_flags > num_pos )
50
+ free (cs -> arg_name );
32
51
free (cs );
33
52
* cs_ptr = interns -> by_arity [num_pos ][i ];
53
+ if (num_flags > num_pos )
54
+ printf ("interned a callsite with %d nameds\n" , num_flags - num_pos );
34
55
found = 1 ;
35
- break ;
56
+ cancel : break ;
36
57
}
37
58
}
38
59
0 commit comments