@@ -307,6 +307,7 @@ _PyCode_Quicken(PyCodeObject *code)
307
307
#define SPEC_FAIL_NOT_PY_FUNCTION 7
308
308
309
309
310
+ #define SPEC_FAIL_LOAD_GLOBAL_NON_DICT 17
310
311
#define SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT 18
311
312
312
313
/* Attributes */
@@ -332,6 +333,8 @@ _PyCode_Quicken(PyCodeObject *code)
332
333
#define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26
333
334
#define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27
334
335
#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28
336
+ #define SPEC_FAIL_ATTR_NOT_IN_KEYS 29
337
+ #define SPEC_FAIL_ATTR_NOT_IN_DICT 30
335
338
336
339
/* Binary subscr and store subscr */
337
340
@@ -448,41 +451,44 @@ static bool function_check_args(PyObject *o, int expected_argcount, int opcode);
448
451
static uint32_t function_get_version (PyObject * o , int opcode );
449
452
450
453
static int
451
- specialize_module_load_attr (PyObject * owner , _Py_CODEUNIT * instr ,
452
- PyObject * name , int opcode , int opcode_module )
453
- {
454
+ specialize_module_load_attr (
455
+ PyObject * owner , _Py_CODEUNIT * instr , PyObject * name
456
+ ) {
454
457
_PyAttrCache * cache = (_PyAttrCache * )(instr + 1 );
455
458
PyModuleObject * m = (PyModuleObject * )owner ;
456
459
assert ((owner -> ob_type -> tp_flags & Py_TPFLAGS_MANAGED_DICT ) == 0 );
457
460
PyDictObject * dict = (PyDictObject * )m -> md_dict ;
458
461
if (dict == NULL ) {
459
- SPECIALIZATION_FAIL (opcode , SPEC_FAIL_NO_DICT );
462
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_NO_DICT );
460
463
return -1 ;
461
464
}
462
465
if (dict -> ma_keys -> dk_kind != DICT_KEYS_UNICODE ) {
463
- SPECIALIZATION_FAIL (opcode , SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT );
466
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT );
464
467
return -1 ;
465
468
}
466
469
Py_ssize_t index = _PyDict_LookupIndex (dict , & _Py_ID (__getattr__ ));
467
470
assert (index != DKIX_ERROR );
468
471
if (index != DKIX_EMPTY ) {
469
- SPECIALIZATION_FAIL (opcode , SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND );
472
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND );
470
473
return -1 ;
471
474
}
472
475
index = _PyDict_LookupIndex (dict , name );
473
476
assert (index != DKIX_ERROR );
474
477
if (index != (uint16_t )index ) {
475
- SPECIALIZATION_FAIL (opcode , SPEC_FAIL_OUT_OF_RANGE );
478
+ SPECIALIZATION_FAIL (LOAD_ATTR ,
479
+ index == DKIX_EMPTY ?
480
+ SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND :
481
+ SPEC_FAIL_OUT_OF_RANGE );
476
482
return -1 ;
477
483
}
478
484
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState (dict -> ma_keys );
479
485
if (keys_version == 0 ) {
480
- SPECIALIZATION_FAIL (opcode , SPEC_FAIL_OUT_OF_VERSIONS );
486
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OUT_OF_VERSIONS );
481
487
return -1 ;
482
488
}
483
489
write_u32 (cache -> version , keys_version );
484
490
cache -> index = (uint16_t )index ;
485
- _py_set_opocde (instr , opcode_module );
491
+ _py_set_opocde (instr , LOAD_ATTR_MODULE );
486
492
return 0 ;
487
493
}
488
494
@@ -629,7 +635,10 @@ specialize_dict_access(
629
635
Py_ssize_t index = _PyDictKeys_StringLookup (keys , name );
630
636
assert (index != DKIX_ERROR );
631
637
if (index != (uint16_t )index ) {
632
- SPECIALIZATION_FAIL (base_op , SPEC_FAIL_OUT_OF_RANGE );
638
+ SPECIALIZATION_FAIL (base_op ,
639
+ index == DKIX_EMPTY ?
640
+ SPEC_FAIL_ATTR_NOT_IN_KEYS :
641
+ SPEC_FAIL_OUT_OF_RANGE );
633
642
return 0 ;
634
643
}
635
644
write_u32 (cache -> version , type -> tp_version_tag );
@@ -646,7 +655,10 @@ specialize_dict_access(
646
655
Py_ssize_t index =
647
656
_PyDict_LookupIndex (dict , name );
648
657
if (index != (uint16_t )index ) {
649
- SPECIALIZATION_FAIL (base_op , SPEC_FAIL_OUT_OF_RANGE );
658
+ SPECIALIZATION_FAIL (base_op ,
659
+ index == DKIX_EMPTY ?
660
+ SPEC_FAIL_ATTR_NOT_IN_DICT :
661
+ SPEC_FAIL_OUT_OF_RANGE );
650
662
return 0 ;
651
663
}
652
664
cache -> index = (uint16_t )index ;
@@ -674,8 +686,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
674
686
goto fail ;
675
687
}
676
688
if (PyModule_CheckExact (owner )) {
677
- if (specialize_module_load_attr (owner , instr , name , LOAD_ATTR ,
678
- LOAD_ATTR_MODULE ))
689
+ if (specialize_module_load_attr (owner , instr , name ))
679
690
{
680
691
goto fail ;
681
692
}
@@ -702,7 +713,9 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
702
713
goto success ;
703
714
}
704
715
}
705
- SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_METHOD );
716
+ else {
717
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_METHOD );
718
+ }
706
719
goto fail ;
707
720
}
708
721
case PROPERTY :
@@ -1076,7 +1089,6 @@ PyObject *descr, DescriptorClassification kind)
1076
1089
*/
1077
1090
write_u32 (cache -> type_version , owner_cls -> tp_version_tag );
1078
1091
write_obj (cache -> descr , descr );
1079
- // Fall through.
1080
1092
return 1 ;
1081
1093
fail :
1082
1094
return 0 ;
@@ -1092,6 +1104,7 @@ _Py_Specialize_LoadGlobal(
1092
1104
_PyLoadGlobalCache * cache = (_PyLoadGlobalCache * )(instr + 1 );
1093
1105
assert (PyUnicode_CheckExact (name ));
1094
1106
if (!PyDict_CheckExact (globals )) {
1107
+ SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_LOAD_GLOBAL_NON_DICT );
1095
1108
goto fail ;
1096
1109
}
1097
1110
PyDictKeysObject * globals_keys = ((PyDictObject * )globals )-> ma_keys ;
@@ -1101,15 +1114,17 @@ _Py_Specialize_LoadGlobal(
1101
1114
}
1102
1115
Py_ssize_t index = _PyDictKeys_StringLookup (globals_keys , name );
1103
1116
if (index == DKIX_ERROR ) {
1104
- SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT );
1117
+ SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_EXPECTED_ERROR );
1105
1118
goto fail ;
1106
1119
}
1107
1120
if (index != DKIX_EMPTY ) {
1108
1121
if (index != (uint16_t )index ) {
1122
+ SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_OUT_OF_RANGE );
1109
1123
goto fail ;
1110
1124
}
1111
1125
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState (globals_keys );
1112
1126
if (keys_version == 0 ) {
1127
+ SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_OUT_OF_VERSIONS );
1113
1128
goto fail ;
1114
1129
}
1115
1130
cache -> index = (uint16_t )index ;
@@ -1118,6 +1133,7 @@ _Py_Specialize_LoadGlobal(
1118
1133
goto success ;
1119
1134
}
1120
1135
if (!PyDict_CheckExact (builtins )) {
1136
+ SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_LOAD_GLOBAL_NON_DICT );
1121
1137
goto fail ;
1122
1138
}
1123
1139
PyDictKeysObject * builtin_keys = ((PyDictObject * )builtins )-> ma_keys ;
@@ -1127,10 +1143,11 @@ _Py_Specialize_LoadGlobal(
1127
1143
}
1128
1144
index = _PyDictKeys_StringLookup (builtin_keys , name );
1129
1145
if (index == DKIX_ERROR ) {
1130
- SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT );
1146
+ SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_EXPECTED_ERROR );
1131
1147
goto fail ;
1132
1148
}
1133
1149
if (index != (uint16_t )index ) {
1150
+ SPECIALIZATION_FAIL (LOAD_GLOBAL , SPEC_FAIL_OUT_OF_RANGE );
1134
1151
goto fail ;
1135
1152
}
1136
1153
uint32_t globals_version = _PyDictKeys_GetVersionForCurrentState (globals_keys );
0 commit comments