@@ -147,6 +147,7 @@ jl_value_t *jl_mk_builtin_func(const char *name, jl_fptr_t fptr)
147
147
li -> def = jl_new_method_uninit ();
148
148
li -> def -> name = sname ;
149
149
li -> def -> lambda_template = li ;
150
+ li -> def -> ambig = jl_nothing ;
150
151
jl_methtable_t * mt = jl_gf_mtable (f );
151
152
jl_typemap_insert (& mt -> cache , (jl_value_t * )mt , jl_anytuple_type , jl_emptysvec , NULL , jl_emptysvec , (jl_value_t * )li , 0 , & lambda_cache , NULL );
152
153
return f ;
@@ -681,26 +682,29 @@ static jl_lambda_info_t *cache_method(jl_methtable_t *mt, union jl_typemap_t *ca
681
682
return newmeth ;
682
683
}
683
684
684
- static jl_lambda_info_t * jl_mt_assoc_by_type (jl_methtable_t * mt , jl_datatype_t * tt , int cache , int inexact )
685
+ static jl_lambda_info_t * jl_mt_assoc_by_type (jl_methtable_t * mt , jl_datatype_t * tt , int cache , int inexact , jl_typemap_entry_t * * entry )
685
686
{
686
- jl_typemap_entry_t * m = NULL ;
687
+ * entry = NULL ;
687
688
jl_svec_t * env = jl_emptysvec ;
688
689
jl_method_t * func = NULL ;
689
690
jl_tupletype_t * sig = NULL ;
690
- JL_GC_PUSH4 (& env , & m , & func , & sig );
691
+ JL_GC_PUSH4 (& env , entry , & func , & sig );
691
692
692
- m = jl_typemap_assoc_by_type (mt -> defs , tt , & env , inexact , 1 , 0 );
693
- if (m == NULL ) {
693
+ * entry = jl_typemap_assoc_by_type (mt -> defs , tt , & env , inexact , 1 , 0 );
694
+ if (* entry == NULL ) {
694
695
JL_GC_POP ();
695
696
return NULL ;
696
697
}
697
698
698
- sig = join_tsig (tt , m -> sig );
699
+ jl_method_t * m = (* entry )-> func .method ;
700
+ sig = join_tsig (tt , (* entry )-> sig );
699
701
jl_lambda_info_t * nf ;
700
702
if (!cache )
701
- nf = jl_get_specialized (m -> func .method , sig , env );
702
- else
703
- nf = cache_method (mt , & mt -> cache , (jl_value_t * )mt , sig , tt , m , env );
703
+ nf = jl_get_specialized (m , sig , env );
704
+ else {
705
+ check_ambig_call (m , tt ); // if ambiguous, don't insert into cache
706
+ nf = cache_method (mt , & mt -> cache , (jl_value_t * )mt , sig , tt , * entry , env );
707
+ }
704
708
JL_GC_POP ();
705
709
return nf ;
706
710
}
@@ -959,34 +963,41 @@ jl_tupletype_t *arg_type_tuple(jl_value_t **args, size_t nargs)
959
963
}
960
964
961
965
jl_lambda_info_t * jl_method_lookup_by_type (jl_methtable_t * mt , jl_tupletype_t * types ,
962
- int cache , int inexact )
966
+ int cache , int inexact ,
967
+ jl_typemap_entry_t * * entry )
963
968
{
964
- jl_typemap_entry_t * m = jl_typemap_assoc_by_type (mt -> cache , types , NULL , 0 , 1 , jl_cachearg_offset (mt ));
969
+ * entry = jl_typemap_assoc_by_type (mt -> cache , types , NULL , 0 , 1 , jl_cachearg_offset (mt ));
965
970
jl_lambda_info_t * sf ;
966
- if (m ) {
967
- sf = m -> func .linfo ;
971
+ if (* entry ) {
972
+ sf = ( * entry ) -> func .linfo ;
968
973
}
969
974
else {
970
975
if (jl_is_leaf_type ((jl_value_t * )types )) cache = 1 ;
971
- sf = jl_mt_assoc_by_type (mt , types , cache , inexact );
976
+ sf = jl_mt_assoc_by_type (mt , types , cache , inexact , entry );
972
977
}
973
978
return sf ;
974
979
}
975
980
976
981
JL_DLLEXPORT int jl_method_exists (jl_methtable_t * mt , jl_tupletype_t * types )
977
982
{
978
- return jl_method_lookup_by_type (mt , types , 0 , 0 ) != NULL ;
983
+ jl_typemap_entry_t * entry ;
984
+ return jl_method_lookup_by_type (mt , types , 0 , 0 , & entry ) != NULL ;
979
985
}
980
986
981
- jl_lambda_info_t * jl_method_lookup (jl_methtable_t * mt , jl_value_t * * args , size_t nargs , int cache )
987
+ jl_lambda_info_t * jl_method_lookup (jl_methtable_t * mt , jl_value_t * * args , size_t nargs , int cache , jl_typemap_entry_t * * entry )
982
988
{
983
- jl_lambda_info_t * sf = jl_typemap_assoc_exact (mt -> cache , args , nargs , jl_cachearg_offset (mt ));
984
- if (sf == NULL ) {
989
+ jl_lambda_info_t * sf ;
990
+ * entry = jl_typemap_assoc_exact (mt -> cache , args , nargs , jl_cachearg_offset (mt ));
991
+ if (* entry == NULL ) {
985
992
jl_tupletype_t * tt = arg_type_tuple (args , nargs );
986
993
JL_GC_PUSH1 (& tt );
987
- sf = jl_mt_assoc_by_type (mt , tt , cache , 0 );
994
+ sf = jl_mt_assoc_by_type (mt , tt , cache , 0 , entry );
988
995
JL_GC_POP ();
989
996
}
997
+ else {
998
+ sf = (* entry )-> func .linfo ;
999
+ }
1000
+
990
1001
return sf ;
991
1002
}
992
1003
@@ -1020,13 +1031,17 @@ jl_lambda_info_t *jl_get_specialization1(jl_tupletype_t *types)
1020
1031
// most of the time sf is rooted in mt, but if the method is staged it may
1021
1032
// not be the case
1022
1033
JL_GC_PUSH1 (& sf );
1034
+ jl_typemap_entry_t * entry ;
1023
1035
JL_TRY {
1024
- sf = jl_method_lookup_by_type (mt , types , 1 , 1 );
1036
+ sf = jl_method_lookup_by_type (mt , types , 1 , 1 , & entry );
1025
1037
} JL_CATCH {
1026
1038
goto not_found ;
1027
1039
}
1028
1040
if (sf == NULL || sf -> code == NULL || sf -> inInference )
1029
1041
goto not_found ;
1042
+ jl_method_t * m = sf -> def ;
1043
+ if (m -> ambig != jl_nothing )
1044
+ check_ambig_call (m , types );
1030
1045
if (sf -> functionObjectsDecls .functionObject == NULL ) {
1031
1046
if (sf -> fptr != NULL )
1032
1047
goto not_found ;
@@ -1044,6 +1059,19 @@ JL_DLLEXPORT void jl_compile_hint(jl_tupletype_t *types)
1044
1059
(void )jl_get_specialization1 (types );
1045
1060
}
1046
1061
1062
+ void check_ambig_call (jl_method_t * m , jl_tupletype_t * types )
1063
+ {
1064
+ if (m -> ambig == jl_nothing )
1065
+ return ;
1066
+ for (size_t i = 0 ; i < jl_array_len (m -> ambig ); i ++ ) {
1067
+ jl_method_t * mambig = (jl_method_t * )jl_cellref (m -> ambig , i );
1068
+ if (jl_type_intersection ((jl_value_t * )mambig -> sig ,
1069
+ (jl_value_t * )types ) != (jl_value_t * )jl_bottom_type ) {
1070
+ jl_error ("ambiguous" );
1071
+ }
1072
+ }
1073
+ }
1074
+
1047
1075
// add type of `f` to front of argument tuple type
1048
1076
jl_tupletype_t * jl_argtype_with_function (jl_function_t * f , jl_tupletype_t * types )
1049
1077
{
@@ -1483,27 +1511,33 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs)
1483
1511
if no generic match, use the concrete one even if inexact
1484
1512
otherwise instantiate the generic method and use it
1485
1513
*/
1486
- jl_lambda_info_t * mfunc = jl_typemap_assoc_exact (mt -> cache , args , nargs , jl_cachearg_offset (mt ));
1487
-
1514
+ jl_typemap_entry_t * entry = jl_typemap_assoc_exact (mt -> cache , args , nargs , jl_cachearg_offset (mt ));
1515
+ jl_lambda_info_t * mfunc = NULL ;
1488
1516
jl_tupletype_t * tt = NULL ;
1489
- if (mfunc == NULL ) {
1517
+ if (entry == NULL ) {
1490
1518
// cache miss case
1491
1519
tt = arg_type_tuple (args , nargs );
1492
1520
// if running inference overwrites this particular method, it becomes
1493
1521
// unreachable from the method table, so root mfunc.
1494
1522
JL_GC_PUSH2 (& tt , & mfunc );
1495
- mfunc = jl_mt_assoc_by_type (mt , tt , 1 , 0 );
1523
+ mfunc = jl_mt_assoc_by_type (mt , tt , 1 , 0 , & entry );
1496
1524
1497
1525
if (mfunc == NULL ) {
1498
1526
#ifdef JL_TRACE
1499
1527
if (error_en )
1500
1528
show_call (F , args , nargs );
1501
1529
#endif
1502
1530
JL_GC_POP ();
1531
+ jl_method_t * m = entry -> func .method ;
1532
+ if (m -> ambig != jl_nothing )
1533
+ check_ambig_call (m , tt );
1503
1534
jl_no_method_error ((jl_function_t * )F , args , nargs );
1504
1535
// unreachable
1505
1536
}
1506
1537
}
1538
+ else {
1539
+ mfunc = entry -> func .linfo ;
1540
+ }
1507
1541
#ifdef JL_TRACE
1508
1542
if (traceen )
1509
1543
jl_printf (JL_STDOUT , " at %s:%d\n" , jl_symbol_name (mfunc -> file ), mfunc -> line );
@@ -1524,11 +1558,11 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs)
1524
1558
JL_DLLEXPORT jl_value_t * jl_gf_invoke_lookup (jl_datatype_t * types )
1525
1559
{
1526
1560
jl_methtable_t * mt = ((jl_datatype_t * )jl_tparam0 (types ))-> name -> mt ;
1527
- jl_typemap_entry_t * m = jl_typemap_assoc_by_type (mt -> defs , types , /*don't record env*/ NULL ,
1561
+ jl_typemap_entry_t * entry = jl_typemap_assoc_by_type (mt -> defs , types , /*don't record env*/ NULL ,
1528
1562
/*exact match*/ 0 , /*subtype*/ 1 , /*offs*/ 0 );
1529
- if (!m )
1563
+ if (!entry )
1530
1564
return jl_nothing ;
1531
- return (jl_value_t * )m ;
1565
+ return (jl_value_t * )entry ;
1532
1566
}
1533
1567
1534
1568
// invoke()
@@ -1551,36 +1585,38 @@ jl_value_t *jl_gf_invoke(jl_tupletype_t *types0, jl_value_t **args, size_t nargs
1551
1585
jl_value_t * gf = args [0 ];
1552
1586
types = (jl_datatype_t * )jl_argtype_with_function (gf , (jl_tupletype_t * )types0 );
1553
1587
jl_methtable_t * mt = jl_gf_mtable (gf );
1554
- jl_typemap_entry_t * m = (jl_typemap_entry_t * )jl_gf_invoke_lookup (types );
1588
+ jl_typemap_entry_t * entry = (jl_typemap_entry_t * )jl_gf_invoke_lookup (types );
1555
1589
1556
- if ((jl_value_t * )m == jl_nothing ) {
1590
+ if ((jl_value_t * )entry == jl_nothing ) {
1557
1591
jl_no_method_error_bare (gf , (jl_value_t * )types0 );
1558
1592
// unreachable
1559
1593
}
1560
1594
1561
1595
// now we have found the matching definition.
1562
1596
// next look for or create a specialization of this definition.
1563
1597
1564
- jl_lambda_info_t * mfunc ;
1565
- if (m -> func .method -> invokes .unknown == NULL )
1566
- mfunc = NULL ;
1567
- else
1568
- mfunc = jl_typemap_assoc_exact (m -> func .method -> invokes , args , nargs , jl_cachearg_offset (mt ));
1569
- if (mfunc == NULL ) {
1598
+ jl_lambda_info_t * mfunc = NULL ;
1599
+ jl_typemap_entry_t * tm = NULL ;
1600
+ if (entry -> func .method -> invokes .unknown != NULL )
1601
+ tm = jl_typemap_assoc_exact (entry -> func .method -> invokes , args , nargs , jl_cachearg_offset (mt ));
1602
+ if (tm == NULL ) {
1570
1603
tt = arg_type_tuple (args , nargs );
1571
- if (m -> tvars != jl_emptysvec ) {
1604
+ if (entry -> tvars != jl_emptysvec ) {
1572
1605
jl_value_t * ti =
1573
- jl_lookup_match ((jl_value_t * )tt , (jl_value_t * )m -> sig , & tpenv , m -> tvars );
1606
+ jl_lookup_match ((jl_value_t * )tt , (jl_value_t * )entry -> sig , & tpenv , entry -> tvars );
1574
1607
assert (ti != (jl_value_t * )jl_bottom_type );
1575
1608
(void )ti ;
1576
1609
}
1577
- sig = join_tsig (tt , m -> sig );
1578
- jl_method_t * func = m -> func .method ;
1610
+ sig = join_tsig (tt , entry -> sig );
1611
+ jl_method_t * func = entry -> func .method ;
1579
1612
1580
1613
if (func -> invokes .unknown == NULL )
1581
1614
func -> invokes .unknown = jl_nothing ;
1582
1615
1583
- mfunc = cache_method (mt , & m -> func .method -> invokes , m -> func .value , sig , tt , m , tpenv );
1616
+ mfunc = cache_method (mt , & func -> invokes , entry -> func .value , sig , tt , entry , tpenv );
1617
+ }
1618
+ else {
1619
+ mfunc = tm -> func .linfo ;
1584
1620
}
1585
1621
JL_GC_POP ();
1586
1622
if (mfunc -> inInference || mfunc -> inCompile ) {
0 commit comments