#define _GUARD_TYPE_VERSION 318
#define _CHECK_MANAGED_OBJECT_HAS_VALUES 319
#define _LOAD_ATTR_INSTANCE_VALUE 320
-#define _LOAD_ATTR_SLOT 321
-#define _GUARD_DORV_VALUES 322
-#define _STORE_ATTR_INSTANCE_VALUE 323
-#define _STORE_ATTR_SLOT 324
-#define _IS_NONE 325
-#define _ITER_CHECK_LIST 326
-#define _ITER_JUMP_LIST 327
-#define _IS_ITER_EXHAUSTED_LIST 328
-#define _ITER_NEXT_LIST 329
-#define _ITER_CHECK_TUPLE 330
-#define _ITER_JUMP_TUPLE 331
-#define _IS_ITER_EXHAUSTED_TUPLE 332
-#define _ITER_NEXT_TUPLE 333
-#define _ITER_CHECK_RANGE 334
-#define _ITER_JUMP_RANGE 335
-#define _IS_ITER_EXHAUSTED_RANGE 336
-#define _ITER_NEXT_RANGE 337
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 338
-#define _GUARD_KEYS_VERSION 339
-#define _LOAD_ATTR_METHOD_WITH_VALUES 340
-#define _LOAD_ATTR_METHOD_NO_DICT 341
-#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 342
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 343
-#define _CHECK_PEP_523 344
-#define _CHECK_FUNCTION_EXACT_ARGS 345
-#define _CHECK_STACK_SPACE 346
-#define _INIT_CALL_PY_EXACT_ARGS 347
-#define _PUSH_FRAME 348
-#define _POP_JUMP_IF_FALSE 349
-#define _POP_JUMP_IF_TRUE 350
-#define _JUMP_TO_TOP 351
-#define _SAVE_CURRENT_IP 352
-#define _INSERT 353
+#define _CHECK_ATTR_MODULE 321
+#define _LOAD_ATTR_MODULE 322
+#define _CHECK_ATTR_WITH_HINT 323
+#define _LOAD_ATTR_WITH_HINT 324
+#define _LOAD_ATTR_SLOT 325
+#define _CHECK_ATTR_CLASS 326
+#define _LOAD_ATTR_CLASS 327
+#define _GUARD_DORV_VALUES 328
+#define _STORE_ATTR_INSTANCE_VALUE 329
+#define _STORE_ATTR_SLOT 330
+#define _IS_NONE 331
+#define _ITER_CHECK_LIST 332
+#define _ITER_JUMP_LIST 333
+#define _IS_ITER_EXHAUSTED_LIST 334
+#define _ITER_NEXT_LIST 335
+#define _ITER_CHECK_TUPLE 336
+#define _ITER_JUMP_TUPLE 337
+#define _IS_ITER_EXHAUSTED_TUPLE 338
+#define _ITER_NEXT_TUPLE 339
+#define _ITER_CHECK_RANGE 340
+#define _ITER_JUMP_RANGE 341
+#define _IS_ITER_EXHAUSTED_RANGE 342
+#define _ITER_NEXT_RANGE 343
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 344
+#define _GUARD_KEYS_VERSION 345
+#define _LOAD_ATTR_METHOD_WITH_VALUES 346
+#define _LOAD_ATTR_METHOD_NO_DICT 347
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 348
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 349
+#define _CHECK_ATTR_METHOD_LAZY_DICT 350
+#define _LOAD_ATTR_METHOD_LAZY_DICT 351
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 352
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 353
+#define _CHECK_PEP_523 354
+#define _CHECK_FUNCTION_EXACT_ARGS 355
+#define _CHECK_STACK_SPACE 356
+#define _INIT_CALL_PY_EXACT_ARGS 357
+#define _PUSH_FRAME 358
+#define _POP_JUMP_IF_FALSE 359
+#define _POP_JUMP_IF_TRUE 360
+#define _JUMP_TO_TOP 361
+#define _SAVE_CURRENT_IP 362
+#define _INSERT 363
extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump);
#ifdef NEED_OPCODE_METADATA
return 1;
case LOAD_ATTR_INSTANCE_VALUE:
return 1;
+ case _CHECK_ATTR_MODULE:
+ return 1;
+ case _LOAD_ATTR_MODULE:
+ return 1;
case LOAD_ATTR_MODULE:
return 1;
+ case _CHECK_ATTR_WITH_HINT:
+ return 1;
+ case _LOAD_ATTR_WITH_HINT:
+ return 1;
case LOAD_ATTR_WITH_HINT:
return 1;
case _LOAD_ATTR_SLOT:
return 1;
case LOAD_ATTR_SLOT:
return 1;
+ case _CHECK_ATTR_CLASS:
+ return 1;
+ case _LOAD_ATTR_CLASS:
+ return 1;
case LOAD_ATTR_CLASS:
return 1;
case LOAD_ATTR_PROPERTY:
return 1;
case LOAD_ATTR_METHOD_NO_DICT:
return 1;
+ case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
+ return 1;
case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
return 1;
+ case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
+ return 1;
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
return 1;
+ case _CHECK_ATTR_METHOD_LAZY_DICT:
+ return 1;
+ case _LOAD_ATTR_METHOD_LAZY_DICT:
+ return 1;
case LOAD_ATTR_METHOD_LAZY_DICT:
return 1;
case INSTRUMENTED_CALL:
return ((oparg & 1) ? 1 : 0) + 1;
case LOAD_ATTR_INSTANCE_VALUE:
return (oparg & 1 ? 1 : 0) + 1;
+ case _CHECK_ATTR_MODULE:
+ return 1;
+ case _LOAD_ATTR_MODULE:
+ return ((oparg & 1) ? 1 : 0) + 1;
case LOAD_ATTR_MODULE:
+ return (oparg & 1 ? 1 : 0) + 1;
+ case _CHECK_ATTR_WITH_HINT:
+ return 1;
+ case _LOAD_ATTR_WITH_HINT:
return ((oparg & 1) ? 1 : 0) + 1;
case LOAD_ATTR_WITH_HINT:
- return ((oparg & 1) ? 1 : 0) + 1;
+ return (oparg & 1 ? 1 : 0) + 1;
case _LOAD_ATTR_SLOT:
return ((oparg & 1) ? 1 : 0) + 1;
case LOAD_ATTR_SLOT:
return (oparg & 1 ? 1 : 0) + 1;
- case LOAD_ATTR_CLASS:
+ case _CHECK_ATTR_CLASS:
+ return 1;
+ case _LOAD_ATTR_CLASS:
return ((oparg & 1) ? 1 : 0) + 1;
+ case LOAD_ATTR_CLASS:
+ return (oparg & 1 ? 1 : 0) + 1;
case LOAD_ATTR_PROPERTY:
return 1;
case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
return 2;
case LOAD_ATTR_METHOD_NO_DICT:
return 2;
+ case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
+ return 1;
case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
return 1;
+ case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
+ return 1;
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
return 1;
+ case _CHECK_ATTR_METHOD_LAZY_DICT:
+ return 1;
+ case _LOAD_ATTR_METHOD_LAZY_DICT:
+ return 2;
case LOAD_ATTR_METHOD_LAZY_DICT:
return 2;
case INSTRUMENTED_CALL:
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
[_LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [_CHECK_ATTR_MODULE] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
+ [_LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [_CHECK_ATTR_WITH_HINT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
+ [_LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG },
[_LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [_CHECK_ATTR_CLASS] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
+ [_LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
[LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[_LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
[LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [_CHECK_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
+ [_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
[LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[INSTRUMENTED_CALL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
[LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
[LOAD_ATTR] = { .nuops = 1, .uops = { { LOAD_ATTR, 0, 0 } } },
[LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } },
+ [LOAD_ATTR_MODULE] = { .nuops = 2, .uops = { { _CHECK_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, 1, 3 } } },
+ [LOAD_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_WITH_HINT, 0, 0 }, { _LOAD_ATTR_WITH_HINT, 1, 3 } } },
[LOAD_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 } } },
+ [LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
[STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } },
[STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } },
[COMPARE_OP] = { .nuops = 1, .uops = { { COMPARE_OP, 0, 0 } } },
[PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } },
[LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } },
[LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } },
+ [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
+ [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } },
+ [LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 0, 0 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } },
[CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 9, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } },
[CALL_PY_EXACT_ARGS] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } },
[CALL_TYPE_1] = { .nuops = 1, .uops = { { CALL_TYPE_1, 0, 0 } } },
[_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION",
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
[_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
+ [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE",
+ [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
+ [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT",
+ [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
[_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
+ [_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS",
+ [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
[_GUARD_DORV_VALUES] = "_GUARD_DORV_VALUES",
[_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE",
[_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT",
[_GUARD_KEYS_VERSION] = "_GUARD_KEYS_VERSION",
[_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
[_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
+ [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
+ [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
+ [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT",
+ [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS",
[_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = "_INIT_CALL_BOUND_METHOD_EXACT_ARGS",
[_CHECK_PEP_523] = "_CHECK_PEP_523",
break;
}
+ case _CHECK_ATTR_MODULE: {
+ break;
+ }
+
+ case _LOAD_ATTR_MODULE: {
+ STACK_GROW(((oparg & 1) ? 1 : 0));
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
+ break;
+ }
+
+ case _CHECK_ATTR_WITH_HINT: {
+ break;
+ }
+
+ case _LOAD_ATTR_WITH_HINT: {
+ STACK_GROW(((oparg & 1) ? 1 : 0));
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
+ break;
+ }
+
case _LOAD_ATTR_SLOT: {
STACK_GROW(((oparg & 1) ? 1 : 0));
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
break;
}
+ case _CHECK_ATTR_CLASS: {
+ break;
+ }
+
+ case _LOAD_ATTR_CLASS: {
+ STACK_GROW(((oparg & 1) ? 1 : 0));
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - (oparg & 1 ? 1 : 0))), true);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-(oparg & 1 ? 1 : 0))), true);
+ break;
+ }
+
case _GUARD_DORV_VALUES: {
break;
}
break;
}
+ case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: {
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(0)), true);
+ break;
+ }
+
+ case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(0)), true);
+ break;
+ }
+
+ case _CHECK_ATTR_METHOD_LAZY_DICT: {
+ break;
+ }
+
+ case _LOAD_ATTR_METHOD_LAZY_DICT: {
+ STACK_GROW(1);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
+ break;
+ }
+
case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: {
break;
}
_LOAD_ATTR_INSTANCE_VALUE +
unused/5; // Skip over rest of cache
- inst(LOAD_ATTR_MODULE, (unused/1, type_version/2, index/1, unused/5, owner -- attr, null if (oparg & 1))) {
+ op(_CHECK_ATTR_MODULE, (type_version/2, owner -- owner)) {
DEOPT_IF(!PyModule_CheckExact(owner));
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
assert(dict != NULL);
DEOPT_IF(dict->ma_keys->dk_version != type_version);
+ }
+
+ op(_LOAD_ATTR_MODULE, (index/1, owner -- attr, null if (oparg & 1))) {
+ PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
assert(index < dict->ma_keys->dk_nentries);
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index;
DECREF_INPUTS();
}
- inst(LOAD_ATTR_WITH_HINT, (unused/1, type_version/2, index/1, unused/5, owner -- attr, null if (oparg & 1))) {
- PyTypeObject *tp = Py_TYPE(owner);
- assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version);
- assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
+ macro(LOAD_ATTR_MODULE) =
+ unused/1 +
+ _CHECK_ATTR_MODULE +
+ _LOAD_ATTR_MODULE +
+ unused/5;
+
+ op(_CHECK_ATTR_WITH_HINT, (owner -- owner)) {
+ assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
DEOPT_IF(_PyDictOrValues_IsValues(dorv));
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
DEOPT_IF(dict == NULL);
assert(PyDict_CheckExact((PyObject *)dict));
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- uint16_t hint = index;
+ }
+
+ op(_LOAD_ATTR_WITH_HINT, (hint/1, owner -- attr, null if (oparg & 1))) {
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (DK_IS_UNICODE(dict->ma_keys)) {
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint;
DEOPT_IF(ep->me_key != name);
DECREF_INPUTS();
}
+ macro(LOAD_ATTR_WITH_HINT) =
+ unused/1 +
+ _GUARD_TYPE_VERSION +
+ _CHECK_ATTR_WITH_HINT +
+ _LOAD_ATTR_WITH_HINT +
+ unused/5;
+
op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) {
char *addr = (char *)owner + index;
attr = *(PyObject **)addr;
_LOAD_ATTR_SLOT + // NOTE: This action may also deopt
unused/5;
- inst(LOAD_ATTR_CLASS, (unused/1, type_version/2, unused/2, descr/4, owner -- attr, null if (oparg & 1))) {
-
+ op(_CHECK_ATTR_CLASS, (type_version/2, owner -- owner)) {
DEOPT_IF(!PyType_Check(owner));
- DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version);
assert(type_version != 0);
+ DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version);
+
+ }
+ op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) {
STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ attr = Py_NewRef(descr);
null = NULL;
- attr = descr;
- assert(attr != NULL);
- Py_INCREF(attr);
DECREF_INPUTS();
}
+ macro(LOAD_ATTR_CLASS) =
+ unused/1 +
+ _CHECK_ATTR_CLASS +
+ unused/2 +
+ _LOAD_ATTR_CLASS;
+
inst(LOAD_ATTR_PROPERTY, (unused/1, type_version/2, func_version/2, fget/4, owner -- unused, unused if (0))) {
assert((oparg & 1) == 0);
DEOPT_IF(tstate->interp->eval_frame);
unused/2 +
_LOAD_ATTR_METHOD_NO_DICT;
- inst(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, owner -- attr, unused if (0))) {
+ op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr, unused if (0))) {
assert((oparg & 1) == 0);
- PyTypeObject *owner_cls = Py_TYPE(owner);
- assert(type_version != 0);
- DEOPT_IF(owner_cls->tp_version_tag != type_version);
- assert(owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
- DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv));
- PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
- DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
DECREF_INPUTS();
attr = Py_NewRef(descr);
}
- inst(LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, owner -- attr, unused if (0))) {
+ macro(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES) =
+ unused/1 +
+ _GUARD_TYPE_VERSION +
+ _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT +
+ _GUARD_KEYS_VERSION +
+ _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES;
+
+ op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr, unused if (0))) {
assert((oparg & 1) == 0);
- PyTypeObject *owner_cls = Py_TYPE(owner);
- assert(type_version != 0);
- DEOPT_IF(owner_cls->tp_version_tag != type_version);
- assert(owner_cls->tp_dictoffset == 0);
+ assert(Py_TYPE(owner)->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
DECREF_INPUTS();
attr = Py_NewRef(descr);
}
- inst(LOAD_ATTR_METHOD_LAZY_DICT, (unused/1, type_version/2, unused/2, descr/4, owner -- attr, self if (1))) {
- assert(oparg & 1);
- PyTypeObject *owner_cls = Py_TYPE(owner);
- DEOPT_IF(owner_cls->tp_version_tag != type_version);
- Py_ssize_t dictoffset = owner_cls->tp_dictoffset;
+ macro(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) =
+ unused/1 +
+ _GUARD_TYPE_VERSION +
+ unused/2 +
+ _LOAD_ATTR_NONDESCRIPTOR_NO_DICT;
+
+ op(_CHECK_ATTR_METHOD_LAZY_DICT, (owner -- owner)) {
+ Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset;
assert(dictoffset > 0);
PyObject *dict = *(PyObject **)((char *)owner + dictoffset);
/* This object has a __dict__, just not yet created */
DEOPT_IF(dict != NULL);
+ }
+
+ op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) {
+ assert(oparg & 1);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
self = owner;
}
+ macro(LOAD_ATTR_METHOD_LAZY_DICT) =
+ unused/1 +
+ _GUARD_TYPE_VERSION +
+ _CHECK_ATTR_METHOD_LAZY_DICT +
+ unused/2 +
+ _LOAD_ATTR_METHOD_LAZY_DICT;
+
inst(INSTRUMENTED_CALL, ( -- )) {
int is_meth = PEEK(oparg + 1) != NULL;
int total_args = oparg + is_meth;
break;
}
+ case _CHECK_ATTR_MODULE: {
+ PyObject *owner;
+ owner = stack_pointer[-1];
+ uint32_t type_version = (uint32_t)operand;
+ DEOPT_IF(!PyModule_CheckExact(owner), _CHECK_ATTR_MODULE);
+ PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
+ assert(dict != NULL);
+ DEOPT_IF(dict->ma_keys->dk_version != type_version, _CHECK_ATTR_MODULE);
+ break;
+ }
+
+ case _LOAD_ATTR_MODULE: {
+ PyObject *owner;
+ PyObject *attr;
+ PyObject *null = NULL;
+ owner = stack_pointer[-1];
+ uint16_t index = (uint16_t)operand;
+ PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
+ assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
+ assert(index < dict->ma_keys->dk_nentries);
+ PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index;
+ attr = ep->me_value;
+ DEOPT_IF(attr == NULL, _LOAD_ATTR_MODULE);
+ STAT_INC(LOAD_ATTR, hit);
+ Py_INCREF(attr);
+ null = NULL;
+ Py_DECREF(owner);
+ STACK_GROW(((oparg & 1) ? 1 : 0));
+ stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
+ if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
+ break;
+ }
+
+ case _CHECK_ATTR_WITH_HINT: {
+ PyObject *owner;
+ owner = stack_pointer[-1];
+ assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ DEOPT_IF(_PyDictOrValues_IsValues(dorv), _CHECK_ATTR_WITH_HINT);
+ PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
+ DEOPT_IF(dict == NULL, _CHECK_ATTR_WITH_HINT);
+ assert(PyDict_CheckExact((PyObject *)dict));
+ break;
+ }
+
+ case _LOAD_ATTR_WITH_HINT: {
+ PyObject *owner;
+ PyObject *attr;
+ PyObject *null = NULL;
+ owner = stack_pointer[-1];
+ uint16_t hint = (uint16_t)operand;
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
+ DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, _LOAD_ATTR_WITH_HINT);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ if (DK_IS_UNICODE(dict->ma_keys)) {
+ PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint;
+ DEOPT_IF(ep->me_key != name, _LOAD_ATTR_WITH_HINT);
+ attr = ep->me_value;
+ }
+ else {
+ PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint;
+ DEOPT_IF(ep->me_key != name, _LOAD_ATTR_WITH_HINT);
+ attr = ep->me_value;
+ }
+ DEOPT_IF(attr == NULL, _LOAD_ATTR_WITH_HINT);
+ STAT_INC(LOAD_ATTR, hit);
+ Py_INCREF(attr);
+ null = NULL;
+ Py_DECREF(owner);
+ STACK_GROW(((oparg & 1) ? 1 : 0));
+ stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
+ if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
+ break;
+ }
+
case _LOAD_ATTR_SLOT: {
PyObject *owner;
PyObject *attr;
break;
}
+ case _CHECK_ATTR_CLASS: {
+ PyObject *owner;
+ owner = stack_pointer[-1];
+ uint32_t type_version = (uint32_t)operand;
+ DEOPT_IF(!PyType_Check(owner), _CHECK_ATTR_CLASS);
+ assert(type_version != 0);
+ DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, _CHECK_ATTR_CLASS);
+ break;
+ }
+
+ case _LOAD_ATTR_CLASS: {
+ PyObject *owner;
+ PyObject *attr;
+ PyObject *null = NULL;
+ owner = stack_pointer[-1];
+ PyObject *descr = (PyObject *)operand;
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ attr = Py_NewRef(descr);
+ null = NULL;
+ Py_DECREF(owner);
+ STACK_GROW(((oparg & 1) ? 1 : 0));
+ stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
+ if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
+ break;
+ }
+
case _GUARD_DORV_VALUES: {
PyObject *owner;
owner = stack_pointer[-1];
break;
}
+ case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: {
+ PyObject *owner;
+ PyObject *attr;
+ owner = stack_pointer[-1];
+ PyObject *descr = (PyObject *)operand;
+ assert((oparg & 1) == 0);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ Py_DECREF(owner);
+ attr = Py_NewRef(descr);
+ stack_pointer[-1] = attr;
+ break;
+ }
+
+ case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
+ PyObject *owner;
+ PyObject *attr;
+ owner = stack_pointer[-1];
+ PyObject *descr = (PyObject *)operand;
+ assert((oparg & 1) == 0);
+ assert(Py_TYPE(owner)->tp_dictoffset == 0);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ Py_DECREF(owner);
+ attr = Py_NewRef(descr);
+ stack_pointer[-1] = attr;
+ break;
+ }
+
+ case _CHECK_ATTR_METHOD_LAZY_DICT: {
+ PyObject *owner;
+ owner = stack_pointer[-1];
+ Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset;
+ assert(dictoffset > 0);
+ PyObject *dict = *(PyObject **)((char *)owner + dictoffset);
+ /* This object has a __dict__, just not yet created */
+ DEOPT_IF(dict != NULL, _CHECK_ATTR_METHOD_LAZY_DICT);
+ break;
+ }
+
+ case _LOAD_ATTR_METHOD_LAZY_DICT: {
+ PyObject *owner;
+ PyObject *attr;
+ PyObject *self;
+ owner = stack_pointer[-1];
+ PyObject *descr = (PyObject *)operand;
+ assert(oparg & 1);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
+ attr = Py_NewRef(descr);
+ self = owner;
+ STACK_GROW(1);
+ stack_pointer[-2] = attr;
+ stack_pointer[-1] = self;
+ break;
+ }
+
case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: {
PyObject *null;
PyObject *callable;
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_MULTIPLY_INT
{
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_ADD_INT
{
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_SUBTRACT_INT
{
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_MULTIPLY_FLOAT
{
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_ADD_FLOAT
{
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_SUBTRACT_FLOAT
{
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_ADD_UNICODE
{
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
- DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
+ DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
+ DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
}
// _BINARY_OP_INPLACE_ADD_UNICODE
{
_Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP];
assert(true_next.op.code == STORE_FAST);
PyObject **target_local = &GETLOCAL(true_next.op.arg);
- DEOPT_IF(*target_local != left, BINARY_OP);
+ DEOPT_IF(*target_local != left, BINARY_OP);
STAT_INC(BINARY_OP, hit);
/* Handle `left = left + right` or `left += right` for str.
*
{
uint16_t version = read_u16(&next_instr[1].cache);
PyDictObject *dict = (PyDictObject *)GLOBALS();
- DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
- DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
+ DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
+ DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
assert(DK_IS_UNICODE(dict->ma_keys));
}
// _LOAD_GLOBAL_MODULE
PyDictObject *dict = (PyDictObject *)GLOBALS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
res = entries[index].me_value;
- DEOPT_IF(res == NULL, LOAD_GLOBAL);
+ DEOPT_IF(res == NULL, LOAD_GLOBAL);
Py_INCREF(res);
STAT_INC(LOAD_GLOBAL, hit);
null = NULL;
{
uint16_t version = read_u16(&next_instr[1].cache);
PyDictObject *dict = (PyDictObject *)GLOBALS();
- DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
- DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
+ DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
+ DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
assert(DK_IS_UNICODE(dict->ma_keys));
}
// _GUARD_BUILTINS_VERSION
{
uint16_t version = read_u16(&next_instr[2].cache);
PyDictObject *dict = (PyDictObject *)BUILTINS();
- DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
- DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
+ DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
+ DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
assert(DK_IS_UNICODE(dict->ma_keys));
}
// _LOAD_GLOBAL_BUILTINS
PyDictObject *bdict = (PyDictObject *)BUILTINS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys);
res = entries[index].me_value;
- DEOPT_IF(res == NULL, LOAD_GLOBAL);
+ DEOPT_IF(res == NULL, LOAD_GLOBAL);
Py_INCREF(res);
STAT_INC(LOAD_GLOBAL, hit);
null = NULL;
uint32_t type_version = read_u32(&next_instr[1].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
// _CHECK_MANAGED_OBJECT_HAS_VALUES
{
assert(Py_TYPE(owner)->tp_dictoffset < 0);
assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
- DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
+ DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
}
// _LOAD_ATTR_INSTANCE_VALUE
{
uint16_t index = read_u16(&next_instr[3].cache);
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
attr = _PyDictOrValues_GetValues(dorv)->values[index];
- DEOPT_IF(attr == NULL, LOAD_ATTR);
+ DEOPT_IF(attr == NULL, LOAD_ATTR);
STAT_INC(LOAD_ATTR, hit);
Py_INCREF(attr);
null = NULL;
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
+ // _CHECK_ATTR_MODULE
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- uint16_t index = read_u16(&next_instr[3].cache);
- DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR);
- PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
- assert(dict != NULL);
- DEOPT_IF(dict->ma_keys->dk_version != type_version, LOAD_ATTR);
- assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
- assert(index < dict->ma_keys->dk_nentries);
- PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index;
- attr = ep->me_value;
- DEOPT_IF(attr == NULL, LOAD_ATTR);
- STAT_INC(LOAD_ATTR, hit);
- Py_INCREF(attr);
- null = NULL;
- Py_DECREF(owner);
+ {
+ uint32_t type_version = read_u32(&next_instr[1].cache);
+ DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR);
+ PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
+ assert(dict != NULL);
+ DEOPT_IF(dict->ma_keys->dk_version != type_version, LOAD_ATTR);
+ }
+ // _LOAD_ATTR_MODULE
+ {
+ uint16_t index = read_u16(&next_instr[3].cache);
+ PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
+ assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
+ assert(index < dict->ma_keys->dk_nentries);
+ PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index;
+ attr = ep->me_value;
+ DEOPT_IF(attr == NULL, LOAD_ATTR);
+ STAT_INC(LOAD_ATTR, hit);
+ Py_INCREF(attr);
+ null = NULL;
+ Py_DECREF(owner);
+ }
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
+ // _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- uint16_t index = read_u16(&next_instr[3].cache);
- PyTypeObject *tp = Py_TYPE(owner);
- assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
- assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
- DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
- PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
- DEOPT_IF(dict == NULL, LOAD_ATTR);
- assert(PyDict_CheckExact((PyObject *)dict));
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- uint16_t hint = index;
- DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR);
- if (DK_IS_UNICODE(dict->ma_keys)) {
- PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint;
- DEOPT_IF(ep->me_key != name, LOAD_ATTR);
- attr = ep->me_value;
+ {
+ uint32_t type_version = read_u32(&next_instr[1].cache);
+ PyTypeObject *tp = Py_TYPE(owner);
+ assert(type_version != 0);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
- else {
- PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint;
- DEOPT_IF(ep->me_key != name, LOAD_ATTR);
- attr = ep->me_value;
+ // _CHECK_ATTR_WITH_HINT
+ {
+ assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
+ PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
+ DEOPT_IF(dict == NULL, LOAD_ATTR);
+ assert(PyDict_CheckExact((PyObject *)dict));
+ }
+ // _LOAD_ATTR_WITH_HINT
+ {
+ uint16_t hint = read_u16(&next_instr[3].cache);
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
+ DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ if (DK_IS_UNICODE(dict->ma_keys)) {
+ PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint;
+ DEOPT_IF(ep->me_key != name, LOAD_ATTR);
+ attr = ep->me_value;
+ }
+ else {
+ PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint;
+ DEOPT_IF(ep->me_key != name, LOAD_ATTR);
+ attr = ep->me_value;
+ }
+ DEOPT_IF(attr == NULL, LOAD_ATTR);
+ STAT_INC(LOAD_ATTR, hit);
+ Py_INCREF(attr);
+ null = NULL;
+ Py_DECREF(owner);
}
- DEOPT_IF(attr == NULL, LOAD_ATTR);
- STAT_INC(LOAD_ATTR, hit);
- Py_INCREF(attr);
- null = NULL;
- Py_DECREF(owner);
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
uint32_t type_version = read_u32(&next_instr[1].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
// _LOAD_ATTR_SLOT
{
uint16_t index = read_u16(&next_instr[3].cache);
char *addr = (char *)owner + index;
attr = *(PyObject **)addr;
- DEOPT_IF(attr == NULL, LOAD_ATTR);
+ DEOPT_IF(attr == NULL, LOAD_ATTR);
STAT_INC(LOAD_ATTR, hit);
Py_INCREF(attr);
null = NULL;
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
+ // _CHECK_ATTR_CLASS
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- PyObject *descr = read_obj(&next_instr[5].cache);
-
- DEOPT_IF(!PyType_Check(owner), LOAD_ATTR);
- DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, LOAD_ATTR);
- assert(type_version != 0);
-
- STAT_INC(LOAD_ATTR, hit);
- null = NULL;
- attr = descr;
- assert(attr != NULL);
- Py_INCREF(attr);
- Py_DECREF(owner);
+ {
+ uint32_t type_version = read_u32(&next_instr[1].cache);
+ DEOPT_IF(!PyType_Check(owner), LOAD_ATTR);
+ assert(type_version != 0);
+ DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, LOAD_ATTR);
+ }
+ // _LOAD_ATTR_CLASS
+ {
+ PyObject *descr = read_obj(&next_instr[5].cache);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ attr = Py_NewRef(descr);
+ null = NULL;
+ Py_DECREF(owner);
+ }
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
uint32_t type_version = read_u32(&next_instr[1].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
+ DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
}
// _GUARD_DORV_VALUES
{
assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
- DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR);
+ DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR);
}
// _STORE_ATTR_INSTANCE_VALUE
value = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
+ DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
}
// _STORE_ATTR_SLOT
value = stack_pointer[-2];
// _ITER_CHECK_LIST
iter = stack_pointer[-1];
{
- DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
+ DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
}
// _ITER_JUMP_LIST
{
// _ITER_CHECK_TUPLE
iter = stack_pointer[-1];
{
- DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER);
+ DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER);
}
// _ITER_JUMP_TUPLE
{
iter = stack_pointer[-1];
{
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
- DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
+ DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
}
// _ITER_JUMP_RANGE
{
uint32_t type_version = read_u32(&next_instr[1].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
// _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT
{
assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
- DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
+ DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
}
// _GUARD_KEYS_VERSION
{
uint32_t keys_version = read_u32(&next_instr[3].cache);
PyTypeObject *owner_cls = Py_TYPE(owner);
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
- DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
+ DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
}
// _LOAD_ATTR_METHOD_WITH_VALUES
{
uint32_t type_version = read_u32(&next_instr[1].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
- DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
// _LOAD_ATTR_METHOD_NO_DICT
{
TARGET(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES) {
PyObject *owner;
PyObject *attr;
+ // _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- uint32_t keys_version = read_u32(&next_instr[3].cache);
- PyObject *descr = read_obj(&next_instr[5].cache);
- assert((oparg & 1) == 0);
- PyTypeObject *owner_cls = Py_TYPE(owner);
- assert(type_version != 0);
- DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR);
- assert(owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
- DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
- PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
- DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
- STAT_INC(LOAD_ATTR, hit);
- assert(descr != NULL);
- Py_DECREF(owner);
- attr = Py_NewRef(descr);
+ {
+ uint32_t type_version = read_u32(&next_instr[1].cache);
+ PyTypeObject *tp = Py_TYPE(owner);
+ assert(type_version != 0);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
+ }
+ // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT
+ {
+ assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
+ PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
+ DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
+ }
+ // _GUARD_KEYS_VERSION
+ {
+ uint32_t keys_version = read_u32(&next_instr[3].cache);
+ PyTypeObject *owner_cls = Py_TYPE(owner);
+ PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
+ DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
+ }
+ // _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES
+ {
+ PyObject *descr = read_obj(&next_instr[5].cache);
+ assert((oparg & 1) == 0);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ Py_DECREF(owner);
+ attr = Py_NewRef(descr);
+ }
stack_pointer[-1] = attr;
next_instr += 9;
DISPATCH();
TARGET(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) {
PyObject *owner;
PyObject *attr;
+ // _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- PyObject *descr = read_obj(&next_instr[5].cache);
- assert((oparg & 1) == 0);
- PyTypeObject *owner_cls = Py_TYPE(owner);
- assert(type_version != 0);
- DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR);
- assert(owner_cls->tp_dictoffset == 0);
- STAT_INC(LOAD_ATTR, hit);
- assert(descr != NULL);
- Py_DECREF(owner);
- attr = Py_NewRef(descr);
+ {
+ uint32_t type_version = read_u32(&next_instr[1].cache);
+ PyTypeObject *tp = Py_TYPE(owner);
+ assert(type_version != 0);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
+ }
+ // _LOAD_ATTR_NONDESCRIPTOR_NO_DICT
+ {
+ PyObject *descr = read_obj(&next_instr[5].cache);
+ assert((oparg & 1) == 0);
+ assert(Py_TYPE(owner)->tp_dictoffset == 0);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ Py_DECREF(owner);
+ attr = Py_NewRef(descr);
+ }
stack_pointer[-1] = attr;
next_instr += 9;
DISPATCH();
PyObject *owner;
PyObject *attr;
PyObject *self;
+ // _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- PyObject *descr = read_obj(&next_instr[5].cache);
- assert(oparg & 1);
- PyTypeObject *owner_cls = Py_TYPE(owner);
- DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR);
- Py_ssize_t dictoffset = owner_cls->tp_dictoffset;
- assert(dictoffset > 0);
- PyObject *dict = *(PyObject **)((char *)owner + dictoffset);
- /* This object has a __dict__, just not yet created */
- DEOPT_IF(dict != NULL, LOAD_ATTR);
- STAT_INC(LOAD_ATTR, hit);
- assert(descr != NULL);
- assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
- attr = Py_NewRef(descr);
- self = owner;
+ {
+ uint32_t type_version = read_u32(&next_instr[1].cache);
+ PyTypeObject *tp = Py_TYPE(owner);
+ assert(type_version != 0);
+ DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
+ }
+ // _CHECK_ATTR_METHOD_LAZY_DICT
+ {
+ Py_ssize_t dictoffset = Py_TYPE(owner)->tp_dictoffset;
+ assert(dictoffset > 0);
+ PyObject *dict = *(PyObject **)((char *)owner + dictoffset);
+ /* This object has a __dict__, just not yet created */
+ DEOPT_IF(dict != NULL, LOAD_ATTR);
+ }
+ // _LOAD_ATTR_METHOD_LAZY_DICT
+ {
+ PyObject *descr = read_obj(&next_instr[5].cache);
+ assert(oparg & 1);
+ STAT_INC(LOAD_ATTR, hit);
+ assert(descr != NULL);
+ assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
+ attr = Py_NewRef(descr);
+ self = owner;
+ }
STACK_GROW(1);
stack_pointer[-2] = attr;
stack_pointer[-1] = self;
_PyInterpreterFrame *new_frame;
// _CHECK_PEP_523
{
- DEOPT_IF(tstate->interp->eval_frame, CALL);
+ DEOPT_IF(tstate->interp->eval_frame, CALL);
}
// _CHECK_CALL_BOUND_METHOD_EXACT_ARGS
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
{
- DEOPT_IF(null != NULL, CALL);
- DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
+ DEOPT_IF(null != NULL, CALL);
+ DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
}
// _INIT_CALL_BOUND_METHOD_EXACT_ARGS
{
callable = func;
{
uint32_t func_version = read_u32(&next_instr[1].cache);
- DEOPT_IF(!PyFunction_Check(callable), CALL);
+ DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
- DEOPT_IF(func->func_version != func_version, CALL);
+ DEOPT_IF(func->func_version != func_version, CALL);
PyCodeObject *code = (PyCodeObject *)func->func_code;
- DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
+ DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
}
// _CHECK_STACK_SPACE
{
PyFunctionObject *func = (PyFunctionObject *)callable;
PyCodeObject *code = (PyCodeObject *)func->func_code;
- DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
- DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
+ DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
+ DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
}
// _INIT_CALL_PY_EXACT_ARGS
args = stack_pointer - oparg;
_PyInterpreterFrame *new_frame;
// _CHECK_PEP_523
{
- DEOPT_IF(tstate->interp->eval_frame, CALL);
+ DEOPT_IF(tstate->interp->eval_frame, CALL);
}
// _CHECK_FUNCTION_EXACT_ARGS
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
{
uint32_t func_version = read_u32(&next_instr[1].cache);
- DEOPT_IF(!PyFunction_Check(callable), CALL);
+ DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
- DEOPT_IF(func->func_version != func_version, CALL);
+ DEOPT_IF(func->func_version != func_version, CALL);
PyCodeObject *code = (PyCodeObject *)func->func_code;
- DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
+ DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
}
// _CHECK_STACK_SPACE
{
PyFunctionObject *func = (PyFunctionObject *)callable;
PyCodeObject *code = (PyCodeObject *)func->func_code;
- DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
- DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
+ DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
+ DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
}
// _INIT_CALL_PY_EXACT_ARGS
args = stack_pointer - oparg;
out.write_raw(f"{space}if ({cond}) goto {label};\n")
elif m := re.match(r"(\s*)DEOPT_IF\((.+)\);\s*(?://.*)?$", line):
space, cond = m.groups()
+ space = extra + space
target = family.name if family else self.name
out.write_raw(f"{space}DEOPT_IF({cond}, {target});\n")
elif "DEOPT" in line:
filename = context.owner.filename
lineno = context.owner.tokens[context.begin].line
print(f"{filename}:{lineno}: ERROR: DEOPT_IF() must be all on one line")
+ out.write_raw(extra + line)
elif m := re.match(r"(\s*)DECREF_INPUTS\(\);\s*(?://.*)?$", line):
out.reset_lineno()
space = extra + m.group(1)