Revert "GH-128914: Remove conditional stack effects from `bytecodes.c` and the code generators (GH-128918)" (GH-129202)

The commit introduced a ~2.5-3% regression in the free threading build.

This reverts commit ab61d3f430.
This commit is contained in:
Sam Gross 2025-01-23 04:26:25 -05:00 committed by GitHub
parent d7d066c3ab
commit a10f99375e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
44 changed files with 1679 additions and 1460 deletions

View File

@ -75,8 +75,7 @@ the following command can be used to display the disassembly of
>>> dis.dis(myfunc) >>> dis.dis(myfunc)
2 RESUME 0 2 RESUME 0
<BLANKLINE> <BLANKLINE>
3 LOAD_GLOBAL 0 (len) 3 LOAD_GLOBAL 1 (len + NULL)
PUSH_NULL
LOAD_FAST 0 (alist) LOAD_FAST 0 (alist)
CALL 1 CALL 1
RETURN_VALUE RETURN_VALUE
@ -208,7 +207,6 @@ Example:
... ...
RESUME RESUME
LOAD_GLOBAL LOAD_GLOBAL
PUSH_NULL
LOAD_FAST LOAD_FAST
CALL CALL
RETURN_VALUE RETURN_VALUE
@ -1217,20 +1215,11 @@ iterations of the loop.
.. opcode:: LOAD_ATTR (namei) .. opcode:: LOAD_ATTR (namei)
Replaces ``STACK[-1]`` with ``getattr(STACK[-1], co_names[namei>>1])``. If the low bit of ``namei`` is not set, this replaces ``STACK[-1]`` with
``getattr(STACK[-1], co_names[namei>>1])``.
.. versionchanged:: 3.12 If the low bit of ``namei`` is set, this will attempt to load a method named
If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is ``co_names[namei>>1]`` from the ``STACK[-1]`` object. ``STACK[-1]`` is popped.
pushed to the stack before the attribute or unbound method respectively.
.. versionchanged:: 3.14
Reverted change from 3.12. The low bit of ``namei`` has no special meaning.
.. opcode:: LOAD_METHOD (namei)
Attempt to load a method named ``co_names[namei>>1]`` from the ``STACK[-1]`` object.
``STACK[-1]`` is popped.
This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the
correct name, the bytecode pushes the unbound method and ``STACK[-1]``. correct name, the bytecode pushes the unbound method and ``STACK[-1]``.
``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL` ``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL`
@ -1238,7 +1227,9 @@ iterations of the loop.
Otherwise, ``NULL`` and the object returned by Otherwise, ``NULL`` and the object returned by
the attribute lookup are pushed. the attribute lookup are pushed.
.. versionadded:: 3.14 .. versionchanged:: 3.12
If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is
pushed to the stack before the attribute or unbound method respectively.
.. opcode:: LOAD_SUPER_ATTR (namei) .. opcode:: LOAD_SUPER_ATTR (namei)
@ -1935,6 +1926,12 @@ but are replaced by real opcodes or removed before bytecode is generated.
This opcode is now a pseudo-instruction. This opcode is now a pseudo-instruction.
.. opcode:: LOAD_METHOD
Optimized unbound method lookup. Emitted as a ``LOAD_ATTR`` opcode
with a flag set in the arg.
.. _opcode_collections: .. _opcode_collections:
Opcode collections Opcode collections

View File

@ -334,8 +334,6 @@ extern void _Py_Specialize_LoadSuperAttr(_PyStackRef global_super, _PyStackRef c
_Py_CODEUNIT *instr, int load_method); _Py_CODEUNIT *instr, int load_method);
extern void _Py_Specialize_LoadAttr(_PyStackRef owner, _Py_CODEUNIT *instr, extern void _Py_Specialize_LoadAttr(_PyStackRef owner, _Py_CODEUNIT *instr,
PyObject *name); PyObject *name);
extern void _Py_Specialize_LoadMethod(_PyStackRef owner, _Py_CODEUNIT *instr,
PyObject *name);
extern void _Py_Specialize_StoreAttr(_PyStackRef owner, _Py_CODEUNIT *instr, extern void _Py_Specialize_StoreAttr(_PyStackRef owner, _Py_CODEUNIT *instr,
PyObject *name); PyObject *name);
extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins,

View File

@ -267,7 +267,6 @@ Known values:
Python 3.14a4 3612 (Add POP_ITER and INSTRUMENTED_POP_ITER) Python 3.14a4 3612 (Add POP_ITER and INSTRUMENTED_POP_ITER)
Python 3.14a4 3613 (Add LOAD_CONST_MORTAL instruction) Python 3.14a4 3613 (Add LOAD_CONST_MORTAL instruction)
Python 3.14a5 3614 (Add BINARY_OP_EXTEND) Python 3.14a5 3614 (Add BINARY_OP_EXTEND)
Python 3.14a5 3615 (Remove conditional stack effects)
Python 3.15 will start with 3650 Python 3.15 will start with 3650
@ -280,7 +279,7 @@ PC/launcher.c must also be updated.
*/ */
#define PYC_MAGIC_NUMBER 3615 #define PYC_MAGIC_NUMBER 3614
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */ (little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \ #define PYC_MAGIC_NUMBER_TOKEN \

View File

@ -76,7 +76,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
case BUILD_SET: case BUILD_SET:
return oparg; return oparg;
case BUILD_SLICE: case BUILD_SLICE:
return oparg; return 2 + ((oparg == 3) ? 1 : 0);
case BUILD_STRING: case BUILD_STRING:
return oparg; return oparg;
case BUILD_TUPLE: case BUILD_TUPLE:
@ -100,7 +100,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
case CALL_BUILTIN_O: case CALL_BUILTIN_O:
return 2 + oparg; return 2 + oparg;
case CALL_FUNCTION_EX: case CALL_FUNCTION_EX:
return 4; return 3 + (oparg & 1);
case CALL_INTRINSIC_1: case CALL_INTRINSIC_1:
return 1; return 1;
case CALL_INTRINSIC_2: case CALL_INTRINSIC_2:
@ -245,8 +245,6 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 0; return 0;
case INSTRUMENTED_LOAD_SUPER_ATTR: case INSTRUMENTED_LOAD_SUPER_ATTR:
return 0; return 0;
case INSTRUMENTED_LOAD_SUPER_METHOD:
return 0;
case INSTRUMENTED_NOT_TAKEN: case INSTRUMENTED_NOT_TAKEN:
return 0; return 0;
case INSTRUMENTED_POP_ITER: case INSTRUMENTED_POP_ITER:
@ -297,6 +295,12 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 1; return 1;
case LOAD_ATTR_INSTANCE_VALUE: case LOAD_ATTR_INSTANCE_VALUE:
return 1; return 1;
case LOAD_ATTR_METHOD_LAZY_DICT:
return 1;
case LOAD_ATTR_METHOD_NO_DICT:
return 1;
case LOAD_ATTR_METHOD_WITH_VALUES:
return 1;
case LOAD_ATTR_MODULE: case LOAD_ATTR_MODULE:
return 1; return 1;
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
@ -343,14 +347,6 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 0; return 0;
case LOAD_LOCALS: case LOAD_LOCALS:
return 0; return 0;
case LOAD_METHOD:
return 1;
case LOAD_METHOD_LAZY_DICT:
return 1;
case LOAD_METHOD_NO_DICT:
return 1;
case LOAD_METHOD_WITH_VALUES:
return 1;
case LOAD_NAME: case LOAD_NAME:
return 0; return 0;
case LOAD_SMALL_INT: case LOAD_SMALL_INT:
@ -361,9 +357,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 3; return 3;
case LOAD_SUPER_ATTR_ATTR: case LOAD_SUPER_ATTR_ATTR:
return 3; return 3;
case LOAD_SUPER_METHOD: case LOAD_SUPER_ATTR_METHOD:
return 3;
case LOAD_SUPER_METHOD_METHOD:
return 3; return 3;
case MAKE_CELL: case MAKE_CELL:
return 0; return 0;
@ -722,8 +716,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 0; return 0;
case INSTRUMENTED_LOAD_SUPER_ATTR: case INSTRUMENTED_LOAD_SUPER_ATTR:
return 0; return 0;
case INSTRUMENTED_LOAD_SUPER_METHOD:
return 0;
case INSTRUMENTED_NOT_TAKEN: case INSTRUMENTED_NOT_TAKEN:
return 0; return 0;
case INSTRUMENTED_POP_ITER: case INSTRUMENTED_POP_ITER:
@ -765,17 +757,23 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LIST_EXTEND: case LIST_EXTEND:
return 1 + (oparg-1); return 1 + (oparg-1);
case LOAD_ATTR: case LOAD_ATTR:
return 1; return 1 + (oparg & 1);
case LOAD_ATTR_CLASS: case LOAD_ATTR_CLASS:
return 1; return 1 + (oparg & 1);
case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK: case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK:
return 1; return 1 + (oparg & 1);
case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
return 1; return 1;
case LOAD_ATTR_INSTANCE_VALUE: case LOAD_ATTR_INSTANCE_VALUE:
return 1; return 1 + (oparg & 1);
case LOAD_ATTR_METHOD_LAZY_DICT:
return 2;
case LOAD_ATTR_METHOD_NO_DICT:
return 2;
case LOAD_ATTR_METHOD_WITH_VALUES:
return 2;
case LOAD_ATTR_MODULE: case LOAD_ATTR_MODULE:
return 1; return 1 + (oparg & 1);
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
return 1; return 1;
case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
@ -783,9 +781,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LOAD_ATTR_PROPERTY: case LOAD_ATTR_PROPERTY:
return 0; return 0;
case LOAD_ATTR_SLOT: case LOAD_ATTR_SLOT:
return 1; return 1 + (oparg & 1);
case LOAD_ATTR_WITH_HINT: case LOAD_ATTR_WITH_HINT:
return 1; return 1 + (oparg & 1);
case LOAD_BUILD_CLASS: case LOAD_BUILD_CLASS:
return 1; return 1;
case LOAD_CLOSURE: case LOAD_CLOSURE:
@ -813,21 +811,13 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LOAD_FROM_DICT_OR_GLOBALS: case LOAD_FROM_DICT_OR_GLOBALS:
return 1; return 1;
case LOAD_GLOBAL: case LOAD_GLOBAL:
return 1; return 1 + (oparg & 1);
case LOAD_GLOBAL_BUILTIN: case LOAD_GLOBAL_BUILTIN:
return 1; return 1 + (oparg & 1);
case LOAD_GLOBAL_MODULE: case LOAD_GLOBAL_MODULE:
return 1; return 1 + (oparg & 1);
case LOAD_LOCALS: case LOAD_LOCALS:
return 1; return 1;
case LOAD_METHOD:
return 2;
case LOAD_METHOD_LAZY_DICT:
return 2;
case LOAD_METHOD_NO_DICT:
return 2;
case LOAD_METHOD_WITH_VALUES:
return 2;
case LOAD_NAME: case LOAD_NAME:
return 1; return 1;
case LOAD_SMALL_INT: case LOAD_SMALL_INT:
@ -835,12 +825,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case LOAD_SPECIAL: case LOAD_SPECIAL:
return 2; return 2;
case LOAD_SUPER_ATTR: case LOAD_SUPER_ATTR:
return 1; return 1 + (oparg & 1);
case LOAD_SUPER_ATTR_ATTR: case LOAD_SUPER_ATTR_ATTR:
return 1; return 1;
case LOAD_SUPER_METHOD: case LOAD_SUPER_ATTR_METHOD:
return 2;
case LOAD_SUPER_METHOD_METHOD:
return 2; return 2;
case MAKE_CELL: case MAKE_CELL:
return 0; return 0;
@ -1070,7 +1058,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0; return 0;
} }
case BUILD_SLICE: { case BUILD_SLICE: {
*effect = 1 - oparg; *effect = -1 - ((oparg == 3) ? 1 : 0);
return 0; return 0;
} }
case BUILD_STRING: { case BUILD_STRING: {
@ -1126,7 +1114,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0; return 0;
} }
case CALL_FUNCTION_EX: { case CALL_FUNCTION_EX: {
*effect = 0; *effect = Py_MAX(0, -2 - (oparg & 1));
return 0; return 0;
} }
case CALL_INTRINSIC_1: { case CALL_INTRINSIC_1: {
@ -1427,10 +1415,6 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
*effect = 0; *effect = 0;
return 0; return 0;
} }
case INSTRUMENTED_LOAD_SUPER_METHOD: {
*effect = 0;
return 0;
}
case INSTRUMENTED_NOT_TAKEN: { case INSTRUMENTED_NOT_TAKEN: {
*effect = 0; *effect = 0;
return 0; return 0;
@ -1512,15 +1496,15 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0; return 0;
} }
case LOAD_ATTR: { case LOAD_ATTR: {
*effect = 1; *effect = Py_MAX(1, (oparg & 1));
return 0; return 0;
} }
case LOAD_ATTR_CLASS: { case LOAD_ATTR_CLASS: {
*effect = 0; *effect = Py_MAX(0, (oparg & 1));
return 0; return 0;
} }
case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK: { case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK: {
*effect = 0; *effect = Py_MAX(0, (oparg & 1));
return 0; return 0;
} }
case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: { case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: {
@ -1528,11 +1512,23 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0; return 0;
} }
case LOAD_ATTR_INSTANCE_VALUE: { case LOAD_ATTR_INSTANCE_VALUE: {
*effect = 0; *effect = Py_MAX(0, (oparg & 1));
return 0;
}
case LOAD_ATTR_METHOD_LAZY_DICT: {
*effect = 1;
return 0;
}
case LOAD_ATTR_METHOD_NO_DICT: {
*effect = 1;
return 0;
}
case LOAD_ATTR_METHOD_WITH_VALUES: {
*effect = 1;
return 0; return 0;
} }
case LOAD_ATTR_MODULE: { case LOAD_ATTR_MODULE: {
*effect = 1; *effect = Py_MAX(1, (oparg & 1));
return 0; return 0;
} }
case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: { case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
@ -1548,11 +1544,11 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0; return 0;
} }
case LOAD_ATTR_SLOT: { case LOAD_ATTR_SLOT: {
*effect = 0; *effect = Py_MAX(0, (oparg & 1));
return 0; return 0;
} }
case LOAD_ATTR_WITH_HINT: { case LOAD_ATTR_WITH_HINT: {
*effect = 1; *effect = Py_MAX(1, (oparg & 1));
return 0; return 0;
} }
case LOAD_BUILD_CLASS: { case LOAD_BUILD_CLASS: {
@ -1608,37 +1604,21 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0; return 0;
} }
case LOAD_GLOBAL: { case LOAD_GLOBAL: {
*effect = 1; *effect = Py_MAX(1, 1 + (oparg & 1));
return 0; return 0;
} }
case LOAD_GLOBAL_BUILTIN: { case LOAD_GLOBAL_BUILTIN: {
*effect = 1; *effect = Py_MAX(1, 1 + (oparg & 1));
return 0; return 0;
} }
case LOAD_GLOBAL_MODULE: { case LOAD_GLOBAL_MODULE: {
*effect = 1; *effect = Py_MAX(1, 1 + (oparg & 1));
return 0; return 0;
} }
case LOAD_LOCALS: { case LOAD_LOCALS: {
*effect = 1; *effect = 1;
return 0; return 0;
} }
case LOAD_METHOD: {
*effect = 1;
return 0;
}
case LOAD_METHOD_LAZY_DICT: {
*effect = 1;
return 0;
}
case LOAD_METHOD_NO_DICT: {
*effect = 1;
return 0;
}
case LOAD_METHOD_WITH_VALUES: {
*effect = 1;
return 0;
}
case LOAD_NAME: { case LOAD_NAME: {
*effect = 1; *effect = 1;
return 0; return 0;
@ -1652,18 +1632,14 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
return 0; return 0;
} }
case LOAD_SUPER_ATTR: { case LOAD_SUPER_ATTR: {
*effect = 0; *effect = Py_MAX(0, -2 + (oparg & 1));
return 0; return 0;
} }
case LOAD_SUPER_ATTR_ATTR: { case LOAD_SUPER_ATTR_ATTR: {
*effect = -2; *effect = -2;
return 0; return 0;
} }
case LOAD_SUPER_METHOD: { case LOAD_SUPER_ATTR_METHOD: {
*effect = 0;
return 0;
}
case LOAD_SUPER_METHOD_METHOD: {
*effect = -1; *effect = -1;
return 0; return 0;
} }
@ -1958,7 +1934,6 @@ enum InstructionFormat {
INSTR_FMT_IXC00 = 9, INSTR_FMT_IXC00 = 9,
INSTR_FMT_IXC000 = 10, INSTR_FMT_IXC000 = 10,
INSTR_FMT_IXC0000 = 11, INSTR_FMT_IXC0000 = 11,
INSTR_FMT_IXC00000000 = 12,
}; };
#define IS_VALID_OPCODE(OP) \ #define IS_VALID_OPCODE(OP) \
@ -1978,8 +1953,9 @@ enum InstructionFormat {
#define HAS_EXIT_FLAG (1024) #define HAS_EXIT_FLAG (1024)
#define HAS_PURE_FLAG (2048) #define HAS_PURE_FLAG (2048)
#define HAS_PASSTHROUGH_FLAG (4096) #define HAS_PASSTHROUGH_FLAG (4096)
#define HAS_ERROR_NO_POP_FLAG (8192) #define HAS_OPARG_AND_1_FLAG (8192)
#define HAS_NO_SAVE_IP_FLAG (16384) #define HAS_ERROR_NO_POP_FLAG (16384)
#define HAS_NO_SAVE_IP_FLAG (32768)
#define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG)) #define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG))
#define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG)) #define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG))
#define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG)) #define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG))
@ -1993,6 +1969,7 @@ enum InstructionFormat {
#define OPCODE_HAS_EXIT(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_EXIT_FLAG)) #define OPCODE_HAS_EXIT(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_EXIT_FLAG))
#define OPCODE_HAS_PURE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PURE_FLAG)) #define OPCODE_HAS_PURE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PURE_FLAG))
#define OPCODE_HAS_PASSTHROUGH(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PASSTHROUGH_FLAG)) #define OPCODE_HAS_PASSTHROUGH(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PASSTHROUGH_FLAG))
#define OPCODE_HAS_OPARG_AND_1(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_OPARG_AND_1_FLAG))
#define OPCODE_HAS_ERROR_NO_POP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_NO_POP_FLAG)) #define OPCODE_HAS_ERROR_NO_POP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_NO_POP_FLAG))
#define OPCODE_HAS_NO_SAVE_IP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NO_SAVE_IP_FLAG)) #define OPCODE_HAS_NO_SAVE_IP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NO_SAVE_IP_FLAG))
@ -2046,7 +2023,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
@ -2119,7 +2096,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, [INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IXC, 0 }, [INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IXC, 0 },
[INSTRUMENTED_LOAD_SUPER_METHOD] = { true, INSTR_FMT_IXC, 0 },
[INSTRUMENTED_NOT_TAKEN] = { true, INSTR_FMT_IX, 0 }, [INSTRUMENTED_NOT_TAKEN] = { true, INSTR_FMT_IX, 0 },
[INSTRUMENTED_POP_ITER] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, [INSTRUMENTED_POP_ITER] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, [INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
@ -2137,15 +2113,18 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, [LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_ATTR_CLASS] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG }, [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG }, [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG }, [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_MODULE] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG }, [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_SLOT] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_COMMON_CONSTANT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [LOAD_COMMON_CONSTANT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
@ -2160,20 +2139,15 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG }, [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG }, [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_METHOD] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_METHOD_LAZY_DICT] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_METHOD_NO_DICT] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG },
[LOAD_METHOD_WITH_VALUES] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
[LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SMALL_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [LOAD_SMALL_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[LOAD_SUPER_METHOD_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@ -2353,6 +2327,9 @@ _PyOpcode_macro_expansion[256] = {
[LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } }, [LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { .nuops = 3, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _GUARD_TYPE_VERSION, 2, 3 }, { _LOAD_ATTR_CLASS, 4, 5 } } }, [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { .nuops = 3, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _GUARD_TYPE_VERSION, 2, 3 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
[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_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_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } },
[LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } },
[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_MODULE] = { .nuops = 2, .uops = { { _CHECK_ATTR_MODULE_PUSH_KEYS, 2, 1 }, { _LOAD_ATTR_MODULE_FROM_KEYS, 1, 3 } } }, [LOAD_ATTR_MODULE] = { .nuops = 2, .uops = { { _CHECK_ATTR_MODULE_PUSH_KEYS, 2, 1 }, { _LOAD_ATTR_MODULE_FROM_KEYS, 1, 3 } } },
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } }, [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_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_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 } } },
@ -2373,15 +2350,11 @@ _PyOpcode_macro_expansion[256] = {
[LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION_PUSH_KEYS, 1, 2 }, { _LOAD_GLOBAL_BUILTINS_FROM_KEYS, 1, 3 } } }, [LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION_PUSH_KEYS, 1, 2 }, { _LOAD_GLOBAL_BUILTINS_FROM_KEYS, 1, 3 } } },
[LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION_PUSH_KEYS, 1, 1 }, { _LOAD_GLOBAL_MODULE_FROM_KEYS, 1, 3 } } }, [LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION_PUSH_KEYS, 1, 1 }, { _LOAD_GLOBAL_MODULE_FROM_KEYS, 1, 3 } } },
[LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } }, [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } },
[LOAD_METHOD] = { .nuops = 1, .uops = { { _LOAD_METHOD, 0, 0 } } },
[LOAD_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_METHOD_LAZY_DICT, 4, 5 } } },
[LOAD_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_METHOD_NO_DICT, 4, 5 } } },
[LOAD_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_METHOD_WITH_VALUES, 4, 5 } } },
[LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, 0, 0 } } }, [LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, 0, 0 } } },
[LOAD_SMALL_INT] = { .nuops = 1, .uops = { { _LOAD_SMALL_INT, 0, 0 } } }, [LOAD_SMALL_INT] = { .nuops = 1, .uops = { { _LOAD_SMALL_INT, 0, 0 } } },
[LOAD_SPECIAL] = { .nuops = 1, .uops = { { _LOAD_SPECIAL, 0, 0 } } }, [LOAD_SPECIAL] = { .nuops = 1, .uops = { { _LOAD_SPECIAL, 0, 0 } } },
[LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, 0, 0 } } }, [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, 0, 0 } } },
[LOAD_SUPER_METHOD_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_METHOD_METHOD, 0, 0 } } }, [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
[MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, 0, 0 } } }, [MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, 0, 0 } } },
[MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, 0, 0 } } }, [MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, 0, 0 } } },
[MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, 0, 0 } } }, [MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, 0, 0 } } },
@ -2551,7 +2524,6 @@ const char *_PyOpcode_OpName[266] = {
[INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD", [INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD",
[INSTRUMENTED_LINE] = "INSTRUMENTED_LINE", [INSTRUMENTED_LINE] = "INSTRUMENTED_LINE",
[INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR", [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
[INSTRUMENTED_LOAD_SUPER_METHOD] = "INSTRUMENTED_LOAD_SUPER_METHOD",
[INSTRUMENTED_NOT_TAKEN] = "INSTRUMENTED_NOT_TAKEN", [INSTRUMENTED_NOT_TAKEN] = "INSTRUMENTED_NOT_TAKEN",
[INSTRUMENTED_POP_ITER] = "INSTRUMENTED_POP_ITER", [INSTRUMENTED_POP_ITER] = "INSTRUMENTED_POP_ITER",
[INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE", [INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE",
@ -2577,6 +2549,9 @@ const char *_PyOpcode_OpName[266] = {
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = "LOAD_ATTR_CLASS_WITH_METACLASS_CHECK", [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = "LOAD_ATTR_CLASS_WITH_METACLASS_CHECK",
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
[LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
[LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
[LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
[LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
[LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT", [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
@ -2600,17 +2575,12 @@ const char *_PyOpcode_OpName[266] = {
[LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
[LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
[LOAD_LOCALS] = "LOAD_LOCALS", [LOAD_LOCALS] = "LOAD_LOCALS",
[LOAD_METHOD] = "LOAD_METHOD",
[LOAD_METHOD_LAZY_DICT] = "LOAD_METHOD_LAZY_DICT",
[LOAD_METHOD_NO_DICT] = "LOAD_METHOD_NO_DICT",
[LOAD_METHOD_WITH_VALUES] = "LOAD_METHOD_WITH_VALUES",
[LOAD_NAME] = "LOAD_NAME", [LOAD_NAME] = "LOAD_NAME",
[LOAD_SMALL_INT] = "LOAD_SMALL_INT", [LOAD_SMALL_INT] = "LOAD_SMALL_INT",
[LOAD_SPECIAL] = "LOAD_SPECIAL", [LOAD_SPECIAL] = "LOAD_SPECIAL",
[LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR", [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR",
[LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR", [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR",
[LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD", [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
[LOAD_SUPER_METHOD_METHOD] = "LOAD_SUPER_METHOD_METHOD",
[MAKE_CELL] = "MAKE_CELL", [MAKE_CELL] = "MAKE_CELL",
[MAKE_FUNCTION] = "MAKE_FUNCTION", [MAKE_FUNCTION] = "MAKE_FUNCTION",
[MAP_ADD] = "MAP_ADD", [MAP_ADD] = "MAP_ADD",
@ -2693,9 +2663,7 @@ const uint8_t _PyOpcode_Caches[256] = {
[STORE_ATTR] = 4, [STORE_ATTR] = 4,
[LOAD_GLOBAL] = 4, [LOAD_GLOBAL] = 4,
[LOAD_SUPER_ATTR] = 1, [LOAD_SUPER_ATTR] = 1,
[LOAD_SUPER_METHOD] = 1,
[LOAD_ATTR] = 9, [LOAD_ATTR] = 9,
[LOAD_METHOD] = 9,
[COMPARE_OP] = 1, [COMPARE_OP] = 1,
[CONTAINS_OP] = 1, [CONTAINS_OP] = 1,
[JUMP_BACKWARD] = 1, [JUMP_BACKWARD] = 1,
@ -2818,7 +2786,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
[INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD, [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
[INSTRUMENTED_LINE] = INSTRUMENTED_LINE, [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
[INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[INSTRUMENTED_LOAD_SUPER_METHOD] = INSTRUMENTED_LOAD_SUPER_METHOD,
[INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN, [INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
[INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER, [INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
[INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE, [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
@ -2840,6 +2807,9 @@ const uint8_t _PyOpcode_Deopt[256] = {
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = LOAD_ATTR, [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = LOAD_ATTR,
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR, [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
[LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
[LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
[LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
[LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
[LOAD_ATTR_MODULE] = LOAD_ATTR, [LOAD_ATTR_MODULE] = LOAD_ATTR,
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR, [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR,
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR, [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR,
@ -2862,17 +2832,12 @@ const uint8_t _PyOpcode_Deopt[256] = {
[LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
[LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
[LOAD_LOCALS] = LOAD_LOCALS, [LOAD_LOCALS] = LOAD_LOCALS,
[LOAD_METHOD] = LOAD_METHOD,
[LOAD_METHOD_LAZY_DICT] = LOAD_METHOD,
[LOAD_METHOD_NO_DICT] = LOAD_METHOD,
[LOAD_METHOD_WITH_VALUES] = LOAD_METHOD,
[LOAD_NAME] = LOAD_NAME, [LOAD_NAME] = LOAD_NAME,
[LOAD_SMALL_INT] = LOAD_SMALL_INT, [LOAD_SMALL_INT] = LOAD_SMALL_INT,
[LOAD_SPECIAL] = LOAD_SPECIAL, [LOAD_SPECIAL] = LOAD_SPECIAL,
[LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR, [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
[LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR, [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
[LOAD_SUPER_METHOD] = LOAD_SUPER_METHOD, [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
[LOAD_SUPER_METHOD_METHOD] = LOAD_SUPER_METHOD,
[MAKE_CELL] = MAKE_CELL, [MAKE_CELL] = MAKE_CELL,
[MAKE_FUNCTION] = MAKE_FUNCTION, [MAKE_FUNCTION] = MAKE_FUNCTION,
[MAP_ADD] = MAP_ADD, [MAP_ADD] = MAP_ADD,
@ -2941,6 +2906,8 @@ const uint8_t _PyOpcode_Deopt[256] = {
#endif // NEED_OPCODE_METADATA #endif // NEED_OPCODE_METADATA
#define EXTRA_CASES \ #define EXTRA_CASES \
case 118: \
case 119: \
case 120: \ case 120: \
case 121: \ case 121: \
case 122: \ case 122: \
@ -2974,6 +2941,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 231: \ case 231: \
case 232: \ case 232: \
case 233: \ case 233: \
case 234: \
; ;
struct pseudo_targets { struct pseudo_targets {
uint8_t as_sequence; uint8_t as_sequence;

View File

@ -159,7 +159,6 @@ extern "C" {
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
#define _INSTRUMENTED_LINE INSTRUMENTED_LINE #define _INSTRUMENTED_LINE INSTRUMENTED_LINE
#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR #define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
#define _INSTRUMENTED_LOAD_SUPER_METHOD INSTRUMENTED_LOAD_SUPER_METHOD
#define _INSTRUMENTED_NOT_TAKEN INSTRUMENTED_NOT_TAKEN #define _INSTRUMENTED_NOT_TAKEN INSTRUMENTED_NOT_TAKEN
#define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE #define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
@ -181,122 +180,127 @@ extern "C" {
#define _LIST_EXTEND LIST_EXTEND #define _LIST_EXTEND LIST_EXTEND
#define _LOAD_ATTR 410 #define _LOAD_ATTR 410
#define _LOAD_ATTR_CLASS 411 #define _LOAD_ATTR_CLASS 411
#define _LOAD_ATTR_CLASS_0 412
#define _LOAD_ATTR_CLASS_1 413
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
#define _LOAD_ATTR_INSTANCE_VALUE 412 #define _LOAD_ATTR_INSTANCE_VALUE 414
#define _LOAD_ATTR_MODULE 413 #define _LOAD_ATTR_INSTANCE_VALUE_0 415
#define _LOAD_ATTR_MODULE_FROM_KEYS 414 #define _LOAD_ATTR_INSTANCE_VALUE_1 416
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 415 #define _LOAD_ATTR_METHOD_LAZY_DICT 417
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 416 #define _LOAD_ATTR_METHOD_NO_DICT 418
#define _LOAD_ATTR_PROPERTY_FRAME 417 #define _LOAD_ATTR_METHOD_WITH_VALUES 419
#define _LOAD_ATTR_SLOT 418 #define _LOAD_ATTR_MODULE 420
#define _LOAD_ATTR_WITH_HINT 419 #define _LOAD_ATTR_MODULE_FROM_KEYS 421
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 422
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 423
#define _LOAD_ATTR_PROPERTY_FRAME 424
#define _LOAD_ATTR_SLOT 425
#define _LOAD_ATTR_SLOT_0 426
#define _LOAD_ATTR_SLOT_1 427
#define _LOAD_ATTR_WITH_HINT 428
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
#define _LOAD_BYTECODE 420 #define _LOAD_BYTECODE 429
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST #define _LOAD_CONST LOAD_CONST
#define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL #define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL
#define _LOAD_CONST_INLINE 421 #define _LOAD_CONST_INLINE 430
#define _LOAD_CONST_INLINE_BORROW 422 #define _LOAD_CONST_INLINE_BORROW 431
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 423 #define _LOAD_CONST_INLINE_BORROW_WITH_NULL 432
#define _LOAD_CONST_INLINE_WITH_NULL 424 #define _LOAD_CONST_INLINE_WITH_NULL 433
#define _LOAD_CONST_MORTAL LOAD_CONST_MORTAL #define _LOAD_CONST_MORTAL LOAD_CONST_MORTAL
#define _LOAD_DEREF LOAD_DEREF #define _LOAD_DEREF LOAD_DEREF
#define _LOAD_FAST 425 #define _LOAD_FAST 434
#define _LOAD_FAST_0 426 #define _LOAD_FAST_0 435
#define _LOAD_FAST_1 427 #define _LOAD_FAST_1 436
#define _LOAD_FAST_2 428 #define _LOAD_FAST_2 437
#define _LOAD_FAST_3 429 #define _LOAD_FAST_3 438
#define _LOAD_FAST_4 430 #define _LOAD_FAST_4 439
#define _LOAD_FAST_5 431 #define _LOAD_FAST_5 440
#define _LOAD_FAST_6 432 #define _LOAD_FAST_6 441
#define _LOAD_FAST_7 433 #define _LOAD_FAST_7 442
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FAST_CHECK LOAD_FAST_CHECK
#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST #define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
#define _LOAD_GLOBAL 434 #define _LOAD_GLOBAL 443
#define _LOAD_GLOBAL_BUILTINS 435 #define _LOAD_GLOBAL_BUILTINS 444
#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 436 #define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 445
#define _LOAD_GLOBAL_MODULE 437 #define _LOAD_GLOBAL_MODULE 446
#define _LOAD_GLOBAL_MODULE_FROM_KEYS 438 #define _LOAD_GLOBAL_MODULE_FROM_KEYS 447
#define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_METHOD 439
#define _LOAD_METHOD_LAZY_DICT 440
#define _LOAD_METHOD_NO_DICT 441
#define _LOAD_METHOD_WITH_VALUES 442
#define _LOAD_NAME LOAD_NAME #define _LOAD_NAME LOAD_NAME
#define _LOAD_SMALL_INT 443 #define _LOAD_SMALL_INT 448
#define _LOAD_SMALL_INT_0 444 #define _LOAD_SMALL_INT_0 449
#define _LOAD_SMALL_INT_1 445 #define _LOAD_SMALL_INT_1 450
#define _LOAD_SMALL_INT_2 446 #define _LOAD_SMALL_INT_2 451
#define _LOAD_SMALL_INT_3 447 #define _LOAD_SMALL_INT_3 452
#define _LOAD_SPECIAL LOAD_SPECIAL #define _LOAD_SPECIAL LOAD_SPECIAL
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_METHOD_METHOD LOAD_SUPER_METHOD_METHOD #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
#define _MAKE_CALLARGS_A_TUPLE 448 #define _MAKE_CALLARGS_A_TUPLE 453
#define _MAKE_CELL MAKE_CELL #define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION #define _MAKE_FUNCTION MAKE_FUNCTION
#define _MAKE_WARM 449 #define _MAKE_WARM 454
#define _MAP_ADD MAP_ADD #define _MAP_ADD MAP_ADD
#define _MATCH_CLASS MATCH_CLASS #define _MATCH_CLASS MATCH_CLASS
#define _MATCH_KEYS MATCH_KEYS #define _MATCH_KEYS MATCH_KEYS
#define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_MAPPING MATCH_MAPPING
#define _MATCH_SEQUENCE MATCH_SEQUENCE #define _MATCH_SEQUENCE MATCH_SEQUENCE
#define _MAYBE_EXPAND_METHOD 450 #define _MAYBE_EXPAND_METHOD 455
#define _MAYBE_EXPAND_METHOD_KW 451 #define _MAYBE_EXPAND_METHOD_KW 456
#define _MONITOR_CALL 452 #define _MONITOR_CALL 457
#define _MONITOR_JUMP_BACKWARD 453 #define _MONITOR_JUMP_BACKWARD 458
#define _MONITOR_RESUME 454 #define _MONITOR_RESUME 459
#define _NOP NOP #define _NOP NOP
#define _POP_EXCEPT POP_EXCEPT #define _POP_EXCEPT POP_EXCEPT
#define _POP_JUMP_IF_FALSE 455 #define _POP_JUMP_IF_FALSE 460
#define _POP_JUMP_IF_TRUE 456 #define _POP_JUMP_IF_TRUE 461
#define _POP_TOP POP_TOP #define _POP_TOP POP_TOP
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 457 #define _POP_TOP_LOAD_CONST_INLINE_BORROW 462
#define _PUSH_EXC_INFO PUSH_EXC_INFO #define _PUSH_EXC_INFO PUSH_EXC_INFO
#define _PUSH_FRAME 458 #define _PUSH_FRAME 463
#define _PUSH_NULL PUSH_NULL #define _PUSH_NULL PUSH_NULL
#define _PY_FRAME_GENERAL 459 #define _PY_FRAME_GENERAL 464
#define _PY_FRAME_KW 460 #define _PY_FRAME_KW 465
#define _QUICKEN_RESUME 461 #define _QUICKEN_RESUME 466
#define _REPLACE_WITH_TRUE 462 #define _REPLACE_WITH_TRUE 467
#define _RESUME_CHECK RESUME_CHECK #define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE #define _RETURN_VALUE RETURN_VALUE
#define _SAVE_RETURN_OFFSET 463 #define _SAVE_RETURN_OFFSET 468
#define _SEND 464 #define _SEND 469
#define _SEND_GEN_FRAME 465 #define _SEND_GEN_FRAME 470
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
#define _SET_ADD SET_ADD #define _SET_ADD SET_ADD
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
#define _SET_UPDATE SET_UPDATE #define _SET_UPDATE SET_UPDATE
#define _START_EXECUTOR 466 #define _START_EXECUTOR 471
#define _STORE_ATTR 467 #define _STORE_ATTR 472
#define _STORE_ATTR_INSTANCE_VALUE 468 #define _STORE_ATTR_INSTANCE_VALUE 473
#define _STORE_ATTR_SLOT 469 #define _STORE_ATTR_SLOT 474
#define _STORE_ATTR_WITH_HINT 470 #define _STORE_ATTR_WITH_HINT 475
#define _STORE_DEREF STORE_DEREF #define _STORE_DEREF STORE_DEREF
#define _STORE_FAST 471 #define _STORE_FAST 476
#define _STORE_FAST_0 472 #define _STORE_FAST_0 477
#define _STORE_FAST_1 473 #define _STORE_FAST_1 478
#define _STORE_FAST_2 474 #define _STORE_FAST_2 479
#define _STORE_FAST_3 475 #define _STORE_FAST_3 480
#define _STORE_FAST_4 476 #define _STORE_FAST_4 481
#define _STORE_FAST_5 477 #define _STORE_FAST_5 482
#define _STORE_FAST_6 478 #define _STORE_FAST_6 483
#define _STORE_FAST_7 479 #define _STORE_FAST_7 484
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
#define _STORE_GLOBAL STORE_GLOBAL #define _STORE_GLOBAL STORE_GLOBAL
#define _STORE_NAME STORE_NAME #define _STORE_NAME STORE_NAME
#define _STORE_SLICE 480 #define _STORE_SLICE 485
#define _STORE_SUBSCR 481 #define _STORE_SUBSCR 486
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT #define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT #define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
#define _SWAP SWAP #define _SWAP SWAP
#define _TIER2_RESUME_CHECK 482 #define _TIER2_RESUME_CHECK 487
#define _TO_BOOL 483 #define _TO_BOOL 488
#define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT #define _TO_BOOL_INT TO_BOOL_INT
#define _TO_BOOL_LIST TO_BOOL_LIST #define _TO_BOOL_LIST TO_BOOL_LIST
@ -306,13 +310,13 @@ extern "C" {
#define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT #define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX #define _UNPACK_EX UNPACK_EX
#define _UNPACK_SEQUENCE 484 #define _UNPACK_SEQUENCE 489
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST #define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE #define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE #define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
#define _WITH_EXCEPT_START WITH_EXCEPT_START #define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE #define _YIELD_VALUE YIELD_VALUE
#define MAX_UOP_ID 484 #define MAX_UOP_ID 489
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -127,8 +127,8 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_GLOBALS_VERSION] = HAS_DEOPT_FLAG, [_GUARD_GLOBALS_VERSION] = HAS_DEOPT_FLAG,
[_GUARD_GLOBALS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG, [_GUARD_GLOBALS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG,
[_GUARD_BUILTINS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG, [_GUARD_BUILTINS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG,
[_LOAD_GLOBAL_MODULE_FROM_KEYS] = HAS_DEOPT_FLAG, [_LOAD_GLOBAL_MODULE_FROM_KEYS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_LOAD_GLOBAL_BUILTINS_FROM_KEYS] = HAS_DEOPT_FLAG, [_LOAD_GLOBAL_BUILTINS_FROM_KEYS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_DELETE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_DELETE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_CELL] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_MAKE_CELL] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_DELETE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_DELETE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
@ -148,21 +148,26 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_LOAD_SUPER_METHOD_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_LOAD_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG, [_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG,
[_GUARD_TYPE_VERSION_AND_LOCK] = HAS_EXIT_FLAG, [_GUARD_TYPE_VERSION_AND_LOCK] = HAS_EXIT_FLAG,
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG, [_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG,
[_LOAD_ATTR_INSTANCE_VALUE] = HAS_DEOPT_FLAG, [_LOAD_ATTR_INSTANCE_VALUE_0] = HAS_DEOPT_FLAG,
[_LOAD_ATTR_INSTANCE_VALUE_1] = HAS_DEOPT_FLAG,
[_LOAD_ATTR_INSTANCE_VALUE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG,
[_CHECK_ATTR_MODULE_PUSH_KEYS] = HAS_DEOPT_FLAG, [_CHECK_ATTR_MODULE_PUSH_KEYS] = HAS_DEOPT_FLAG,
[_LOAD_ATTR_MODULE_FROM_KEYS] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_LOAD_ATTR_MODULE_FROM_KEYS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_ATTR_WITH_HINT] = HAS_EXIT_FLAG, [_CHECK_ATTR_WITH_HINT] = HAS_EXIT_FLAG,
[_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG, [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG,
[_LOAD_ATTR_SLOT] = HAS_DEOPT_FLAG, [_LOAD_ATTR_SLOT_0] = HAS_DEOPT_FLAG,
[_LOAD_ATTR_SLOT_1] = HAS_DEOPT_FLAG,
[_LOAD_ATTR_SLOT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG,
[_CHECK_ATTR_CLASS] = HAS_EXIT_FLAG, [_CHECK_ATTR_CLASS] = HAS_EXIT_FLAG,
[_LOAD_ATTR_CLASS] = 0, [_LOAD_ATTR_CLASS_0] = 0,
[_LOAD_ATTR_PROPERTY_FRAME] = HAS_DEOPT_FLAG, [_LOAD_ATTR_CLASS_1] = 0,
[_LOAD_ATTR_CLASS] = HAS_ARG_FLAG | HAS_OPARG_AND_1_FLAG,
[_LOAD_ATTR_PROPERTY_FRAME] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_GUARD_DORV_NO_DICT] = HAS_EXIT_FLAG, [_GUARD_DORV_NO_DICT] = HAS_EXIT_FLAG,
[_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG, [_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG,
[_STORE_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_STORE_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
@ -203,12 +208,12 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_PUSH_EXC_INFO] = 0, [_PUSH_EXC_INFO] = 0,
[_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG, [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG,
[_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG, [_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG,
[_LOAD_METHOD_WITH_VALUES] = 0, [_LOAD_ATTR_METHOD_WITH_VALUES] = HAS_ARG_FLAG,
[_LOAD_METHOD_NO_DICT] = 0, [_LOAD_ATTR_METHOD_NO_DICT] = HAS_ARG_FLAG,
[_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = 0, [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = HAS_ARG_FLAG,
[_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = 0, [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = HAS_ARG_FLAG,
[_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG, [_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
[_LOAD_METHOD_LAZY_DICT] = 0, [_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG,
[_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG, [_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
[_PY_FRAME_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_PY_FRAME_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_FUNCTION_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_CHECK_FUNCTION_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
@ -253,7 +258,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_EXPAND_METHOD_KW] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG, [_EXPAND_METHOD_KW] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_IS_NOT_PY_CALLABLE_KW] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_CHECK_IS_NOT_PY_CALLABLE_KW] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
[_CALL_KW_NON_PY] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_KW_NON_PY] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_CALLARGS_A_TUPLE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_MAKE_CALLARGS_A_TUPLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG, [_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG,
[_RETURN_GENERATOR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_RETURN_GENERATOR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
@ -280,9 +285,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_LOAD_CONST_INLINE_WITH_NULL] = HAS_PURE_FLAG, [_LOAD_CONST_INLINE_WITH_NULL] = HAS_PURE_FLAG,
[_LOAD_CONST_INLINE_BORROW_WITH_NULL] = HAS_PURE_FLAG, [_LOAD_CONST_INLINE_BORROW_WITH_NULL] = HAS_PURE_FLAG,
[_CHECK_FUNCTION] = HAS_DEOPT_FLAG, [_CHECK_FUNCTION] = HAS_DEOPT_FLAG,
[_LOAD_GLOBAL_MODULE] = HAS_DEOPT_FLAG, [_LOAD_GLOBAL_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_LOAD_GLOBAL_BUILTINS] = HAS_DEOPT_FLAG, [_LOAD_GLOBAL_BUILTINS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG, [_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG, [_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG,
[_START_EXECUTOR] = HAS_ESCAPES_FLAG, [_START_EXECUTOR] = HAS_ESCAPES_FLAG,
[_MAKE_WARM] = 0, [_MAKE_WARM] = 0,
@ -452,13 +457,22 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_LIST_EXTEND] = "_LIST_EXTEND", [_LIST_EXTEND] = "_LIST_EXTEND",
[_LOAD_ATTR] = "_LOAD_ATTR", [_LOAD_ATTR] = "_LOAD_ATTR",
[_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS", [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
[_LOAD_ATTR_CLASS_0] = "_LOAD_ATTR_CLASS_0",
[_LOAD_ATTR_CLASS_1] = "_LOAD_ATTR_CLASS_1",
[_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE", [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
[_LOAD_ATTR_INSTANCE_VALUE_0] = "_LOAD_ATTR_INSTANCE_VALUE_0",
[_LOAD_ATTR_INSTANCE_VALUE_1] = "_LOAD_ATTR_INSTANCE_VALUE_1",
[_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
[_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
[_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
[_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE", [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
[_LOAD_ATTR_MODULE_FROM_KEYS] = "_LOAD_ATTR_MODULE_FROM_KEYS", [_LOAD_ATTR_MODULE_FROM_KEYS] = "_LOAD_ATTR_MODULE_FROM_KEYS",
[_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT", [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
[_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
[_LOAD_ATTR_PROPERTY_FRAME] = "_LOAD_ATTR_PROPERTY_FRAME", [_LOAD_ATTR_PROPERTY_FRAME] = "_LOAD_ATTR_PROPERTY_FRAME",
[_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT", [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
[_LOAD_ATTR_SLOT_0] = "_LOAD_ATTR_SLOT_0",
[_LOAD_ATTR_SLOT_1] = "_LOAD_ATTR_SLOT_1",
[_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT", [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
[_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS", [_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS",
[_LOAD_COMMON_CONSTANT] = "_LOAD_COMMON_CONSTANT", [_LOAD_COMMON_CONSTANT] = "_LOAD_COMMON_CONSTANT",
@ -488,10 +502,6 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE", [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE",
[_LOAD_GLOBAL_MODULE_FROM_KEYS] = "_LOAD_GLOBAL_MODULE_FROM_KEYS", [_LOAD_GLOBAL_MODULE_FROM_KEYS] = "_LOAD_GLOBAL_MODULE_FROM_KEYS",
[_LOAD_LOCALS] = "_LOAD_LOCALS", [_LOAD_LOCALS] = "_LOAD_LOCALS",
[_LOAD_METHOD] = "_LOAD_METHOD",
[_LOAD_METHOD_LAZY_DICT] = "_LOAD_METHOD_LAZY_DICT",
[_LOAD_METHOD_NO_DICT] = "_LOAD_METHOD_NO_DICT",
[_LOAD_METHOD_WITH_VALUES] = "_LOAD_METHOD_WITH_VALUES",
[_LOAD_NAME] = "_LOAD_NAME", [_LOAD_NAME] = "_LOAD_NAME",
[_LOAD_SMALL_INT] = "_LOAD_SMALL_INT", [_LOAD_SMALL_INT] = "_LOAD_SMALL_INT",
[_LOAD_SMALL_INT_0] = "_LOAD_SMALL_INT_0", [_LOAD_SMALL_INT_0] = "_LOAD_SMALL_INT_0",
@ -500,7 +510,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_LOAD_SMALL_INT_3] = "_LOAD_SMALL_INT_3", [_LOAD_SMALL_INT_3] = "_LOAD_SMALL_INT_3",
[_LOAD_SPECIAL] = "_LOAD_SPECIAL", [_LOAD_SPECIAL] = "_LOAD_SPECIAL",
[_LOAD_SUPER_ATTR_ATTR] = "_LOAD_SUPER_ATTR_ATTR", [_LOAD_SUPER_ATTR_ATTR] = "_LOAD_SUPER_ATTR_ATTR",
[_LOAD_SUPER_METHOD_METHOD] = "_LOAD_SUPER_METHOD_METHOD", [_LOAD_SUPER_ATTR_METHOD] = "_LOAD_SUPER_ATTR_METHOD",
[_MAKE_CALLARGS_A_TUPLE] = "_MAKE_CALLARGS_A_TUPLE", [_MAKE_CALLARGS_A_TUPLE] = "_MAKE_CALLARGS_A_TUPLE",
[_MAKE_CELL] = "_MAKE_CELL", [_MAKE_CELL] = "_MAKE_CELL",
[_MAKE_FUNCTION] = "_MAKE_FUNCTION", [_MAKE_FUNCTION] = "_MAKE_FUNCTION",
@ -835,10 +845,8 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2; return 2;
case _LOAD_SUPER_ATTR_ATTR: case _LOAD_SUPER_ATTR_ATTR:
return 3; return 3;
case _LOAD_SUPER_METHOD_METHOD: case _LOAD_SUPER_ATTR_METHOD:
return 3; return 3;
case _LOAD_METHOD:
return 1;
case _LOAD_ATTR: case _LOAD_ATTR:
return 1; return 1;
case _GUARD_TYPE_VERSION: case _GUARD_TYPE_VERSION:
@ -847,6 +855,10 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0; return 0;
case _CHECK_MANAGED_OBJECT_HAS_VALUES: case _CHECK_MANAGED_OBJECT_HAS_VALUES:
return 0; return 0;
case _LOAD_ATTR_INSTANCE_VALUE_0:
return 1;
case _LOAD_ATTR_INSTANCE_VALUE_1:
return 1;
case _LOAD_ATTR_INSTANCE_VALUE: case _LOAD_ATTR_INSTANCE_VALUE:
return 1; return 1;
case _CHECK_ATTR_MODULE_PUSH_KEYS: case _CHECK_ATTR_MODULE_PUSH_KEYS:
@ -857,10 +869,18 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0; return 0;
case _LOAD_ATTR_WITH_HINT: case _LOAD_ATTR_WITH_HINT:
return 2; return 2;
case _LOAD_ATTR_SLOT_0:
return 1;
case _LOAD_ATTR_SLOT_1:
return 1;
case _LOAD_ATTR_SLOT: case _LOAD_ATTR_SLOT:
return 1; return 1;
case _CHECK_ATTR_CLASS: case _CHECK_ATTR_CLASS:
return 0; return 0;
case _LOAD_ATTR_CLASS_0:
return 1;
case _LOAD_ATTR_CLASS_1:
return 1;
case _LOAD_ATTR_CLASS: case _LOAD_ATTR_CLASS:
return 1; return 1;
case _LOAD_ATTR_PROPERTY_FRAME: case _LOAD_ATTR_PROPERTY_FRAME:
@ -945,9 +965,9 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0; return 0;
case _GUARD_KEYS_VERSION: case _GUARD_KEYS_VERSION:
return 0; return 0;
case _LOAD_METHOD_WITH_VALUES: case _LOAD_ATTR_METHOD_WITH_VALUES:
return 1; return 1;
case _LOAD_METHOD_NO_DICT: case _LOAD_ATTR_METHOD_NO_DICT:
return 1; return 1;
case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
return 1; return 1;
@ -955,7 +975,7 @@ int _PyUop_num_popped(int opcode, int oparg)
return 1; return 1;
case _CHECK_ATTR_METHOD_LAZY_DICT: case _CHECK_ATTR_METHOD_LAZY_DICT:
return 0; return 0;
case _LOAD_METHOD_LAZY_DICT: case _LOAD_ATTR_METHOD_LAZY_DICT:
return 1; return 1;
case _MAYBE_EXPAND_METHOD: case _MAYBE_EXPAND_METHOD:
return 2 + oparg; return 2 + oparg;
@ -1046,7 +1066,7 @@ int _PyUop_num_popped(int opcode, int oparg)
case _CALL_KW_NON_PY: case _CALL_KW_NON_PY:
return 3 + oparg; return 3 + oparg;
case _MAKE_CALLARGS_A_TUPLE: case _MAKE_CALLARGS_A_TUPLE:
return 2; return 1 + (oparg & 1);
case _MAKE_FUNCTION: case _MAKE_FUNCTION:
return 1; return 1;
case _SET_FUNCTION_ATTRIBUTE: case _SET_FUNCTION_ATTRIBUTE:
@ -1054,7 +1074,7 @@ int _PyUop_num_popped(int opcode, int oparg)
case _RETURN_GENERATOR: case _RETURN_GENERATOR:
return 0; return 0;
case _BUILD_SLICE: case _BUILD_SLICE:
return oparg; return 2 + ((oparg == 3) ? 1 : 0);
case _CONVERT_VALUE: case _CONVERT_VALUE:
return 1; return 1;
case _FORMAT_SIMPLE: case _FORMAT_SIMPLE:

195
Include/opcode_ids.h generated
View File

@ -14,55 +14,55 @@ extern "C" {
#define BINARY_SLICE 1 #define BINARY_SLICE 1
#define BINARY_SUBSCR 2 #define BINARY_SUBSCR 2
#define BINARY_OP_INPLACE_ADD_UNICODE 3 #define BINARY_OP_INPLACE_ADD_UNICODE 3
#define CALL_FUNCTION_EX 4 #define CHECK_EG_MATCH 4
#define CHECK_EG_MATCH 5 #define CHECK_EXC_MATCH 5
#define CHECK_EXC_MATCH 6 #define CLEANUP_THROW 6
#define CLEANUP_THROW 7 #define DELETE_SUBSCR 7
#define DELETE_SUBSCR 8 #define END_ASYNC_FOR 8
#define END_ASYNC_FOR 9 #define END_FOR 9
#define END_FOR 10 #define END_SEND 10
#define END_SEND 11 #define EXIT_INIT_CHECK 11
#define EXIT_INIT_CHECK 12 #define FORMAT_SIMPLE 12
#define FORMAT_SIMPLE 13 #define FORMAT_WITH_SPEC 13
#define FORMAT_WITH_SPEC 14 #define GET_AITER 14
#define GET_AITER 15 #define GET_ANEXT 15
#define GET_ANEXT 16 #define GET_ITER 16
#define RESERVED 17 #define RESERVED 17
#define GET_ITER 18 #define GET_LEN 18
#define GET_LEN 19 #define GET_YIELD_FROM_ITER 19
#define GET_YIELD_FROM_ITER 20 #define INTERPRETER_EXIT 20
#define INTERPRETER_EXIT 21 #define LOAD_BUILD_CLASS 21
#define LOAD_BUILD_CLASS 22 #define LOAD_LOCALS 22
#define LOAD_LOCALS 23 #define MAKE_FUNCTION 23
#define MAKE_FUNCTION 24 #define MATCH_KEYS 24
#define MATCH_KEYS 25 #define MATCH_MAPPING 25
#define MATCH_MAPPING 26 #define MATCH_SEQUENCE 26
#define MATCH_SEQUENCE 27 #define NOP 27
#define NOP 28 #define NOT_TAKEN 28
#define NOT_TAKEN 29 #define POP_EXCEPT 29
#define POP_EXCEPT 30 #define POP_ITER 30
#define POP_ITER 31 #define POP_TOP 31
#define POP_TOP 32 #define PUSH_EXC_INFO 32
#define PUSH_EXC_INFO 33 #define PUSH_NULL 33
#define PUSH_NULL 34 #define RETURN_GENERATOR 34
#define RETURN_GENERATOR 35 #define RETURN_VALUE 35
#define RETURN_VALUE 36 #define SETUP_ANNOTATIONS 36
#define SETUP_ANNOTATIONS 37 #define STORE_SLICE 37
#define STORE_SLICE 38 #define STORE_SUBSCR 38
#define STORE_SUBSCR 39 #define TO_BOOL 39
#define TO_BOOL 40 #define UNARY_INVERT 40
#define UNARY_INVERT 41 #define UNARY_NEGATIVE 41
#define UNARY_NEGATIVE 42 #define UNARY_NOT 42
#define UNARY_NOT 43 #define WITH_EXCEPT_START 43
#define WITH_EXCEPT_START 44 #define BINARY_OP 44
#define BINARY_OP 45 #define BUILD_LIST 45
#define BUILD_LIST 46 #define BUILD_MAP 46
#define BUILD_MAP 47 #define BUILD_SET 47
#define BUILD_SET 48 #define BUILD_SLICE 48
#define BUILD_SLICE 49 #define BUILD_STRING 49
#define BUILD_STRING 50 #define BUILD_TUPLE 50
#define BUILD_TUPLE 51 #define CALL 51
#define CALL 52 #define CALL_FUNCTION_EX 52
#define CALL_INTRINSIC_1 53 #define CALL_INTRINSIC_1 53
#define CALL_INTRINSIC_2 54 #define CALL_INTRINSIC_2 54
#define CALL_KW 55 #define CALL_KW 55
@ -100,36 +100,34 @@ extern "C" {
#define LOAD_FROM_DICT_OR_DEREF 87 #define LOAD_FROM_DICT_OR_DEREF 87
#define LOAD_FROM_DICT_OR_GLOBALS 88 #define LOAD_FROM_DICT_OR_GLOBALS 88
#define LOAD_GLOBAL 89 #define LOAD_GLOBAL 89
#define LOAD_METHOD 90 #define LOAD_NAME 90
#define LOAD_NAME 91 #define LOAD_SMALL_INT 91
#define LOAD_SMALL_INT 92 #define LOAD_SPECIAL 92
#define LOAD_SPECIAL 93 #define LOAD_SUPER_ATTR 93
#define LOAD_SUPER_ATTR 94 #define MAKE_CELL 94
#define LOAD_SUPER_METHOD 95 #define MAP_ADD 95
#define MAKE_CELL 96 #define MATCH_CLASS 96
#define MAP_ADD 97 #define POP_JUMP_IF_FALSE 97
#define MATCH_CLASS 98 #define POP_JUMP_IF_NONE 98
#define POP_JUMP_IF_FALSE 99 #define POP_JUMP_IF_NOT_NONE 99
#define POP_JUMP_IF_NONE 100 #define POP_JUMP_IF_TRUE 100
#define POP_JUMP_IF_NOT_NONE 101 #define RAISE_VARARGS 101
#define POP_JUMP_IF_TRUE 102 #define RERAISE 102
#define RAISE_VARARGS 103 #define SEND 103
#define RERAISE 104 #define SET_ADD 104
#define SEND 105 #define SET_FUNCTION_ATTRIBUTE 105
#define SET_ADD 106 #define SET_UPDATE 106
#define SET_FUNCTION_ATTRIBUTE 107 #define STORE_ATTR 107
#define SET_UPDATE 108 #define STORE_DEREF 108
#define STORE_ATTR 109 #define STORE_FAST 109
#define STORE_DEREF 110 #define STORE_FAST_LOAD_FAST 110
#define STORE_FAST 111 #define STORE_FAST_STORE_FAST 111
#define STORE_FAST_LOAD_FAST 112 #define STORE_GLOBAL 112
#define STORE_FAST_STORE_FAST 113 #define STORE_NAME 113
#define STORE_GLOBAL 114 #define SWAP 114
#define STORE_NAME 115 #define UNPACK_EX 115
#define SWAP 116 #define UNPACK_SEQUENCE 116
#define UNPACK_EX 117 #define YIELD_VALUE 117
#define UNPACK_SEQUENCE 118
#define YIELD_VALUE 119
#define RESUME 149 #define RESUME 149
#define BINARY_OP_ADD_FLOAT 150 #define BINARY_OP_ADD_FLOAT 150
#define BINARY_OP_ADD_INT 151 #define BINARY_OP_ADD_INT 151
@ -180,21 +178,21 @@ extern "C" {
#define LOAD_ATTR_CLASS_WITH_METACLASS_CHECK 196 #define LOAD_ATTR_CLASS_WITH_METACLASS_CHECK 196
#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 197 #define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 197
#define LOAD_ATTR_INSTANCE_VALUE 198 #define LOAD_ATTR_INSTANCE_VALUE 198
#define LOAD_ATTR_MODULE 199 #define LOAD_ATTR_METHOD_LAZY_DICT 199
#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 200 #define LOAD_ATTR_METHOD_NO_DICT 200
#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 201 #define LOAD_ATTR_METHOD_WITH_VALUES 201
#define LOAD_ATTR_PROPERTY 202 #define LOAD_ATTR_MODULE 202
#define LOAD_ATTR_SLOT 203 #define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 203
#define LOAD_ATTR_WITH_HINT 204 #define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 204
#define LOAD_CONST_IMMORTAL 205 #define LOAD_ATTR_PROPERTY 205
#define LOAD_CONST_MORTAL 206 #define LOAD_ATTR_SLOT 206
#define LOAD_GLOBAL_BUILTIN 207 #define LOAD_ATTR_WITH_HINT 207
#define LOAD_GLOBAL_MODULE 208 #define LOAD_CONST_IMMORTAL 208
#define LOAD_METHOD_LAZY_DICT 209 #define LOAD_CONST_MORTAL 209
#define LOAD_METHOD_NO_DICT 210 #define LOAD_GLOBAL_BUILTIN 210
#define LOAD_METHOD_WITH_VALUES 211 #define LOAD_GLOBAL_MODULE 211
#define LOAD_SUPER_ATTR_ATTR 212 #define LOAD_SUPER_ATTR_ATTR 212
#define LOAD_SUPER_METHOD_METHOD 213 #define LOAD_SUPER_ATTR_METHOD 213
#define RESUME_CHECK 214 #define RESUME_CHECK 214
#define SEND_GEN 215 #define SEND_GEN 215
#define STORE_ATTR_INSTANCE_VALUE 216 #define STORE_ATTR_INSTANCE_VALUE 216
@ -211,11 +209,10 @@ extern "C" {
#define UNPACK_SEQUENCE_LIST 227 #define UNPACK_SEQUENCE_LIST 227
#define UNPACK_SEQUENCE_TUPLE 228 #define UNPACK_SEQUENCE_TUPLE 228
#define UNPACK_SEQUENCE_TWO_TUPLE 229 #define UNPACK_SEQUENCE_TWO_TUPLE 229
#define INSTRUMENTED_END_FOR 234 #define INSTRUMENTED_END_FOR 235
#define INSTRUMENTED_POP_ITER 235 #define INSTRUMENTED_POP_ITER 236
#define INSTRUMENTED_END_SEND 236 #define INSTRUMENTED_END_SEND 237
#define INSTRUMENTED_LOAD_SUPER_ATTR 237 #define INSTRUMENTED_LOAD_SUPER_ATTR 238
#define INSTRUMENTED_LOAD_SUPER_METHOD 238
#define INSTRUMENTED_FOR_ITER 239 #define INSTRUMENTED_FOR_ITER 239
#define INSTRUMENTED_CALL_KW 240 #define INSTRUMENTED_CALL_KW 240
#define INSTRUMENTED_CALL_FUNCTION_EX 241 #define INSTRUMENTED_CALL_FUNCTION_EX 241
@ -244,9 +241,9 @@ extern "C" {
#define SETUP_WITH 264 #define SETUP_WITH 264
#define STORE_FAST_MAYBE_NULL 265 #define STORE_FAST_MAYBE_NULL 265
#define HAVE_ARGUMENT 44 #define HAVE_ARGUMENT 43
#define MIN_SPECIALIZED_OPCODE 150 #define MIN_SPECIALIZED_OPCODE 150
#define MIN_INSTRUMENTED_OPCODE 234 #define MIN_INSTRUMENTED_OPCODE 235
#ifdef __cplusplus #ifdef __cplusplus
} }

207
Lib/_opcode_metadata.py generated
View File

@ -59,9 +59,7 @@ _specializations = {
], ],
"LOAD_SUPER_ATTR": [ "LOAD_SUPER_ATTR": [
"LOAD_SUPER_ATTR_ATTR", "LOAD_SUPER_ATTR_ATTR",
], "LOAD_SUPER_ATTR_METHOD",
"LOAD_SUPER_METHOD": [
"LOAD_SUPER_METHOD_METHOD",
], ],
"LOAD_ATTR": [ "LOAD_ATTR": [
"LOAD_ATTR_INSTANCE_VALUE", "LOAD_ATTR_INSTANCE_VALUE",
@ -72,14 +70,12 @@ _specializations = {
"LOAD_ATTR_CLASS_WITH_METACLASS_CHECK", "LOAD_ATTR_CLASS_WITH_METACLASS_CHECK",
"LOAD_ATTR_PROPERTY", "LOAD_ATTR_PROPERTY",
"LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
"LOAD_ATTR_METHOD_WITH_VALUES",
"LOAD_ATTR_METHOD_NO_DICT",
"LOAD_ATTR_METHOD_LAZY_DICT",
"LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
"LOAD_ATTR_NONDESCRIPTOR_NO_DICT", "LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
], ],
"LOAD_METHOD": [
"LOAD_METHOD_WITH_VALUES",
"LOAD_METHOD_NO_DICT",
"LOAD_METHOD_LAZY_DICT",
],
"COMPARE_OP": [ "COMPARE_OP": [
"COMPARE_OP_FLOAT", "COMPARE_OP_FLOAT",
"COMPARE_OP_INT", "COMPARE_OP_INT",
@ -175,21 +171,21 @@ _specialized_opmap = {
'LOAD_ATTR_CLASS_WITH_METACLASS_CHECK': 196, 'LOAD_ATTR_CLASS_WITH_METACLASS_CHECK': 196,
'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 197, 'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 197,
'LOAD_ATTR_INSTANCE_VALUE': 198, 'LOAD_ATTR_INSTANCE_VALUE': 198,
'LOAD_ATTR_MODULE': 199, 'LOAD_ATTR_METHOD_LAZY_DICT': 199,
'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 200, 'LOAD_ATTR_METHOD_NO_DICT': 200,
'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 201, 'LOAD_ATTR_METHOD_WITH_VALUES': 201,
'LOAD_ATTR_PROPERTY': 202, 'LOAD_ATTR_MODULE': 202,
'LOAD_ATTR_SLOT': 203, 'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 203,
'LOAD_ATTR_WITH_HINT': 204, 'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 204,
'LOAD_CONST_IMMORTAL': 205, 'LOAD_ATTR_PROPERTY': 205,
'LOAD_CONST_MORTAL': 206, 'LOAD_ATTR_SLOT': 206,
'LOAD_GLOBAL_BUILTIN': 207, 'LOAD_ATTR_WITH_HINT': 207,
'LOAD_GLOBAL_MODULE': 208, 'LOAD_CONST_IMMORTAL': 208,
'LOAD_METHOD_LAZY_DICT': 209, 'LOAD_CONST_MORTAL': 209,
'LOAD_METHOD_NO_DICT': 210, 'LOAD_GLOBAL_BUILTIN': 210,
'LOAD_METHOD_WITH_VALUES': 211, 'LOAD_GLOBAL_MODULE': 211,
'LOAD_SUPER_ATTR_ATTR': 212, 'LOAD_SUPER_ATTR_ATTR': 212,
'LOAD_SUPER_METHOD_METHOD': 213, 'LOAD_SUPER_ATTR_METHOD': 213,
'RESUME_CHECK': 214, 'RESUME_CHECK': 214,
'SEND_GEN': 215, 'SEND_GEN': 215,
'STORE_ATTR_INSTANCE_VALUE': 216, 'STORE_ATTR_INSTANCE_VALUE': 216,
@ -216,54 +212,54 @@ opmap = {
'ENTER_EXECUTOR': 255, 'ENTER_EXECUTOR': 255,
'BINARY_SLICE': 1, 'BINARY_SLICE': 1,
'BINARY_SUBSCR': 2, 'BINARY_SUBSCR': 2,
'CALL_FUNCTION_EX': 4, 'CHECK_EG_MATCH': 4,
'CHECK_EG_MATCH': 5, 'CHECK_EXC_MATCH': 5,
'CHECK_EXC_MATCH': 6, 'CLEANUP_THROW': 6,
'CLEANUP_THROW': 7, 'DELETE_SUBSCR': 7,
'DELETE_SUBSCR': 8, 'END_ASYNC_FOR': 8,
'END_ASYNC_FOR': 9, 'END_FOR': 9,
'END_FOR': 10, 'END_SEND': 10,
'END_SEND': 11, 'EXIT_INIT_CHECK': 11,
'EXIT_INIT_CHECK': 12, 'FORMAT_SIMPLE': 12,
'FORMAT_SIMPLE': 13, 'FORMAT_WITH_SPEC': 13,
'FORMAT_WITH_SPEC': 14, 'GET_AITER': 14,
'GET_AITER': 15, 'GET_ANEXT': 15,
'GET_ANEXT': 16, 'GET_ITER': 16,
'GET_ITER': 18, 'GET_LEN': 18,
'GET_LEN': 19, 'GET_YIELD_FROM_ITER': 19,
'GET_YIELD_FROM_ITER': 20, 'INTERPRETER_EXIT': 20,
'INTERPRETER_EXIT': 21, 'LOAD_BUILD_CLASS': 21,
'LOAD_BUILD_CLASS': 22, 'LOAD_LOCALS': 22,
'LOAD_LOCALS': 23, 'MAKE_FUNCTION': 23,
'MAKE_FUNCTION': 24, 'MATCH_KEYS': 24,
'MATCH_KEYS': 25, 'MATCH_MAPPING': 25,
'MATCH_MAPPING': 26, 'MATCH_SEQUENCE': 26,
'MATCH_SEQUENCE': 27, 'NOP': 27,
'NOP': 28, 'NOT_TAKEN': 28,
'NOT_TAKEN': 29, 'POP_EXCEPT': 29,
'POP_EXCEPT': 30, 'POP_ITER': 30,
'POP_ITER': 31, 'POP_TOP': 31,
'POP_TOP': 32, 'PUSH_EXC_INFO': 32,
'PUSH_EXC_INFO': 33, 'PUSH_NULL': 33,
'PUSH_NULL': 34, 'RETURN_GENERATOR': 34,
'RETURN_GENERATOR': 35, 'RETURN_VALUE': 35,
'RETURN_VALUE': 36, 'SETUP_ANNOTATIONS': 36,
'SETUP_ANNOTATIONS': 37, 'STORE_SLICE': 37,
'STORE_SLICE': 38, 'STORE_SUBSCR': 38,
'STORE_SUBSCR': 39, 'TO_BOOL': 39,
'TO_BOOL': 40, 'UNARY_INVERT': 40,
'UNARY_INVERT': 41, 'UNARY_NEGATIVE': 41,
'UNARY_NEGATIVE': 42, 'UNARY_NOT': 42,
'UNARY_NOT': 43, 'WITH_EXCEPT_START': 43,
'WITH_EXCEPT_START': 44, 'BINARY_OP': 44,
'BINARY_OP': 45, 'BUILD_LIST': 45,
'BUILD_LIST': 46, 'BUILD_MAP': 46,
'BUILD_MAP': 47, 'BUILD_SET': 47,
'BUILD_SET': 48, 'BUILD_SLICE': 48,
'BUILD_SLICE': 49, 'BUILD_STRING': 49,
'BUILD_STRING': 50, 'BUILD_TUPLE': 50,
'BUILD_TUPLE': 51, 'CALL': 51,
'CALL': 52, 'CALL_FUNCTION_EX': 52,
'CALL_INTRINSIC_1': 53, 'CALL_INTRINSIC_1': 53,
'CALL_INTRINSIC_2': 54, 'CALL_INTRINSIC_2': 54,
'CALL_KW': 55, 'CALL_KW': 55,
@ -301,41 +297,38 @@ opmap = {
'LOAD_FROM_DICT_OR_DEREF': 87, 'LOAD_FROM_DICT_OR_DEREF': 87,
'LOAD_FROM_DICT_OR_GLOBALS': 88, 'LOAD_FROM_DICT_OR_GLOBALS': 88,
'LOAD_GLOBAL': 89, 'LOAD_GLOBAL': 89,
'LOAD_METHOD': 90, 'LOAD_NAME': 90,
'LOAD_NAME': 91, 'LOAD_SMALL_INT': 91,
'LOAD_SMALL_INT': 92, 'LOAD_SPECIAL': 92,
'LOAD_SPECIAL': 93, 'LOAD_SUPER_ATTR': 93,
'LOAD_SUPER_ATTR': 94, 'MAKE_CELL': 94,
'LOAD_SUPER_METHOD': 95, 'MAP_ADD': 95,
'MAKE_CELL': 96, 'MATCH_CLASS': 96,
'MAP_ADD': 97, 'POP_JUMP_IF_FALSE': 97,
'MATCH_CLASS': 98, 'POP_JUMP_IF_NONE': 98,
'POP_JUMP_IF_FALSE': 99, 'POP_JUMP_IF_NOT_NONE': 99,
'POP_JUMP_IF_NONE': 100, 'POP_JUMP_IF_TRUE': 100,
'POP_JUMP_IF_NOT_NONE': 101, 'RAISE_VARARGS': 101,
'POP_JUMP_IF_TRUE': 102, 'RERAISE': 102,
'RAISE_VARARGS': 103, 'SEND': 103,
'RERAISE': 104, 'SET_ADD': 104,
'SEND': 105, 'SET_FUNCTION_ATTRIBUTE': 105,
'SET_ADD': 106, 'SET_UPDATE': 106,
'SET_FUNCTION_ATTRIBUTE': 107, 'STORE_ATTR': 107,
'SET_UPDATE': 108, 'STORE_DEREF': 108,
'STORE_ATTR': 109, 'STORE_FAST': 109,
'STORE_DEREF': 110, 'STORE_FAST_LOAD_FAST': 110,
'STORE_FAST': 111, 'STORE_FAST_STORE_FAST': 111,
'STORE_FAST_LOAD_FAST': 112, 'STORE_GLOBAL': 112,
'STORE_FAST_STORE_FAST': 113, 'STORE_NAME': 113,
'STORE_GLOBAL': 114, 'SWAP': 114,
'STORE_NAME': 115, 'UNPACK_EX': 115,
'SWAP': 116, 'UNPACK_SEQUENCE': 116,
'UNPACK_EX': 117, 'YIELD_VALUE': 117,
'UNPACK_SEQUENCE': 118, 'INSTRUMENTED_END_FOR': 235,
'YIELD_VALUE': 119, 'INSTRUMENTED_POP_ITER': 236,
'INSTRUMENTED_END_FOR': 234, 'INSTRUMENTED_END_SEND': 237,
'INSTRUMENTED_POP_ITER': 235, 'INSTRUMENTED_LOAD_SUPER_ATTR': 238,
'INSTRUMENTED_END_SEND': 236,
'INSTRUMENTED_LOAD_SUPER_ATTR': 237,
'INSTRUMENTED_LOAD_SUPER_METHOD': 238,
'INSTRUMENTED_FOR_ITER': 239, 'INSTRUMENTED_FOR_ITER': 239,
'INSTRUMENTED_CALL_KW': 240, 'INSTRUMENTED_CALL_KW': 240,
'INSTRUMENTED_CALL_FUNCTION_EX': 241, 'INSTRUMENTED_CALL_FUNCTION_EX': 241,
@ -363,5 +356,5 @@ opmap = {
'STORE_FAST_MAYBE_NULL': 265, 'STORE_FAST_MAYBE_NULL': 265,
} }
HAVE_ARGUMENT = 44 HAVE_ARGUMENT = 43
MIN_INSTRUMENTED_OPCODE = 234 MIN_INSTRUMENTED_OPCODE = 235

View File

@ -42,9 +42,7 @@
FOR_ITER = opmap['FOR_ITER'] FOR_ITER = opmap['FOR_ITER']
SEND = opmap['SEND'] SEND = opmap['SEND']
LOAD_ATTR = opmap['LOAD_ATTR'] LOAD_ATTR = opmap['LOAD_ATTR']
LOAD_METHOD = opmap['LOAD_METHOD']
LOAD_SUPER_ATTR = opmap['LOAD_SUPER_ATTR'] LOAD_SUPER_ATTR = opmap['LOAD_SUPER_ATTR']
LOAD_SUPER_METHOD = opmap['LOAD_SUPER_METHOD']
CALL_INTRINSIC_1 = opmap['CALL_INTRINSIC_1'] CALL_INTRINSIC_1 = opmap['CALL_INTRINSIC_1']
CALL_INTRINSIC_2 = opmap['CALL_INTRINSIC_2'] CALL_INTRINSIC_2 = opmap['CALL_INTRINSIC_2']
LOAD_COMMON_CONSTANT = opmap['LOAD_COMMON_CONSTANT'] LOAD_COMMON_CONSTANT = opmap['LOAD_COMMON_CONSTANT']
@ -582,14 +580,16 @@ def get_argval_argrepr(self, op, arg, offset):
argval, argrepr = _get_const_info(deop, arg, self.co_consts) argval, argrepr = _get_const_info(deop, arg, self.co_consts)
elif deop in hasname: elif deop in hasname:
if deop == LOAD_GLOBAL: if deop == LOAD_GLOBAL:
argval, argrepr = _get_name_info(arg, get_name) argval, argrepr = _get_name_info(arg//2, get_name)
elif deop == LOAD_ATTR or deop == LOAD_METHOD: if (arg & 1) and argrepr:
argval, argrepr = _get_name_info(arg, get_name) argrepr = f"{argrepr} + NULL"
if deop == LOAD_METHOD and argrepr: elif deop == LOAD_ATTR:
argval, argrepr = _get_name_info(arg//2, get_name)
if (arg & 1) and argrepr:
argrepr = f"{argrepr} + NULL|self" argrepr = f"{argrepr} + NULL|self"
elif deop == LOAD_SUPER_ATTR or deop == LOAD_SUPER_METHOD: elif deop == LOAD_SUPER_ATTR:
argval, argrepr = _get_name_info(arg//4, get_name) argval, argrepr = _get_name_info(arg//4, get_name)
if deop == LOAD_SUPER_METHOD and argrepr: if (arg & 1) and argrepr:
argrepr = f"{argrepr} + NULL|self" argrepr = f"{argrepr} + NULL|self"
else: else:
argval, argrepr = _get_name_info(arg, get_name) argval, argrepr = _get_name_info(arg, get_name)

View File

@ -1511,7 +1511,7 @@ def getclosurevars(func):
for instruction in dis.get_instructions(code): for instruction in dis.get_instructions(code):
opname = instruction.opname opname = instruction.opname
name = instruction.argval name = instruction.argval
if opname == "LOAD_ATTR" or opname == "LOAD_METHOD": if opname == "LOAD_ATTR":
unbound_names.add(name) unbound_names.add(name)
elif opname == "LOAD_GLOBAL": elif opname == "LOAD_GLOBAL":
global_names.add(name) global_names.add(name)

View File

@ -72,21 +72,12 @@
"LOAD_SUPER_ATTR": { "LOAD_SUPER_ATTR": {
"counter": 1, "counter": 1,
}, },
"LOAD_SUPER_METHOD": {
"counter": 1,
},
"LOAD_ATTR": { "LOAD_ATTR": {
"counter": 1, "counter": 1,
"version": 2, "version": 2,
"keys_version": 2, "keys_version": 2,
"descr": 4, "descr": 4,
}, },
"LOAD_METHOD": {
"counter": 1,
"version": 2,
"keys_version": 2,
"descr": 4,
},
"STORE_ATTR": { "STORE_ATTR": {
"counter": 1, "counter": 1,
"version": 2, "version": 2,

View File

@ -65,7 +65,8 @@ def check_function(self, func, expected):
class StackEffectTests(unittest.TestCase): class StackEffectTests(unittest.TestCase):
def test_stack_effect(self): def test_stack_effect(self):
self.assertEqual(stack_effect(dis.opmap['POP_TOP']), -1) self.assertEqual(stack_effect(dis.opmap['POP_TOP']), -1)
self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 2), -1) self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 0), -1)
self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 1), -1)
self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 3), -2) self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 3), -2)
self.assertRaises(ValueError, stack_effect, 30000) self.assertRaises(ValueError, stack_effect, 30000)
# All defined opcodes # All defined opcodes

View File

@ -711,7 +711,7 @@ def testfunc(n):
assert ex is not None assert ex is not None
uops = get_opnames(ex) uops = get_opnames(ex)
assert "_LOAD_GLOBAL_BUILTINS" not in uops assert "_LOAD_GLOBAL_BUILTINS" not in uops
assert "_LOAD_CONST_INLINE_BORROW" in uops assert "_LOAD_CONST_INLINE_BORROW_WITH_NULL" in uops
""")) """))
self.assertEqual(result[0].rc, 0, result) self.assertEqual(result[0].rc, 0, result)

View File

@ -2157,7 +2157,7 @@ def test_method_call(self):
source = "(\n lhs \n . \n rhs \n )()" source = "(\n lhs \n . \n rhs \n )()"
code = compile(source, "<test>", "exec") code = compile(source, "<test>", "exec")
self.assertOpcodeSourcePositionIs( self.assertOpcodeSourcePositionIs(
code, "LOAD_METHOD", line=4, end_line=4, column=5, end_column=8 code, "LOAD_ATTR", line=4, end_line=4, column=5, end_column=8
) )
self.assertOpcodeSourcePositionIs( self.assertOpcodeSourcePositionIs(
code, "CALL", line=4, end_line=5, column=5, end_column=10 code, "CALL", line=4, end_line=5, column=5, end_column=10

View File

@ -113,8 +113,7 @@ def _f(a):
dis_f = """\ dis_f = """\
%3d RESUME 0 %3d RESUME 0
%3d LOAD_GLOBAL 0 (print) %3d LOAD_GLOBAL 1 (print + NULL)
PUSH_NULL
LOAD_FAST 0 (a) LOAD_FAST 0 (a)
CALL 1 CALL 1
POP_TOP POP_TOP
@ -128,14 +127,13 @@ def _f(a):
dis_f_with_offsets = """\ dis_f_with_offsets = """\
%3d 0 RESUME 0 %3d 0 RESUME 0
%3d 2 LOAD_GLOBAL 0 (print) %3d 2 LOAD_GLOBAL 1 (print + NULL)
12 PUSH_NULL 12 LOAD_FAST 0 (a)
14 LOAD_FAST 0 (a) 14 CALL 1
16 CALL 1 22 POP_TOP
24 POP_TOP
%3d 26 LOAD_SMALL_INT 1 %3d 24 LOAD_SMALL_INT 1
28 RETURN_VALUE 26 RETURN_VALUE
""" % (_f.__code__.co_firstlineno, """ % (_f.__code__.co_firstlineno,
_f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 1,
_f.__code__.co_firstlineno + 2) _f.__code__.co_firstlineno + 2)
@ -143,8 +141,7 @@ def _f(a):
dis_f_with_positions_format = f"""\ dis_f_with_positions_format = f"""\
%-14s RESUME 0 %-14s RESUME 0
%-14s LOAD_GLOBAL 0 (print) %-14s LOAD_GLOBAL 1 (print + NULL)
%-14s PUSH_NULL
%-14s LOAD_FAST 0 (a) %-14s LOAD_FAST 0 (a)
%-14s CALL 1 %-14s CALL 1
%-14s POP_TOP %-14s POP_TOP
@ -155,8 +152,7 @@ def _f(a):
dis_f_co_code = """\ dis_f_co_code = """\
RESUME 0 RESUME 0
LOAD_GLOBAL 0 LOAD_GLOBAL 1
PUSH_NULL
LOAD_FAST 0 LOAD_FAST 0
CALL 1 CALL 1
POP_TOP POP_TOP
@ -172,8 +168,7 @@ def bug708901():
dis_bug708901 = """\ dis_bug708901 = """\
%3d RESUME 0 %3d RESUME 0
%3d LOAD_GLOBAL 0 (range) %3d LOAD_GLOBAL 1 (range + NULL)
PUSH_NULL
LOAD_SMALL_INT 1 LOAD_SMALL_INT 1
%3d LOAD_SMALL_INT 10 %3d LOAD_SMALL_INT 10
@ -281,8 +276,7 @@ def wrap_func_w_kwargs():
dis_kw_names = """\ dis_kw_names = """\
%3d RESUME 0 %3d RESUME 0
%3d LOAD_GLOBAL 0 (func_w_kwargs) %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL)
PUSH_NULL
LOAD_SMALL_INT 1 LOAD_SMALL_INT 1
LOAD_SMALL_INT 2 LOAD_SMALL_INT 2
LOAD_SMALL_INT 5 LOAD_SMALL_INT 5
@ -469,7 +463,7 @@ def foo(a: int, b: str) -> str:
STORE_FAST 0 (e) STORE_FAST 0 (e)
%4d L4: LOAD_FAST 0 (e) %4d L4: LOAD_FAST 0 (e)
LOAD_ATTR 1 (__traceback__) LOAD_ATTR 2 (__traceback__)
STORE_FAST 1 (tb) STORE_FAST 1 (tb)
L5: POP_EXCEPT L5: POP_EXCEPT
LOAD_CONST 0 (None) LOAD_CONST 0 (None)
@ -820,8 +814,7 @@ def foo(x):
%4d RESUME 0 %4d RESUME 0
%4d LOAD_GLOBAL 0 (list) %4d LOAD_GLOBAL 1 (list + NULL)
PUSH_NULL
LOAD_FAST 0 (x) LOAD_FAST 0 (x)
BUILD_TUPLE 1 BUILD_TUPLE 1
LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>) LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>)
@ -904,15 +897,14 @@ def loop_test():
LOAD_SMALL_INT 3 LOAD_SMALL_INT 3
BINARY_OP 5 (*) BINARY_OP 5 (*)
GET_ITER GET_ITER
L1: FOR_ITER_LIST 15 (to L2) L1: FOR_ITER_LIST 14 (to L2)
STORE_FAST 0 (i) STORE_FAST 0 (i)
%3d LOAD_GLOBAL_MODULE 0 (load_test) %3d LOAD_GLOBAL_MODULE 1 (load_test + NULL)
PUSH_NULL
LOAD_FAST 0 (i) LOAD_FAST 0 (i)
CALL_PY_GENERAL 1 CALL_PY_GENERAL 1
POP_TOP POP_TOP
JUMP_BACKWARD 17 (to L1) JUMP_BACKWARD 16 (to L1)
%3d L2: END_FOR %3d L2: END_FOR
POP_ITER POP_ITER
@ -1713,215 +1705,203 @@ def _prepare_test_cases():
Instruction = dis.Instruction Instruction = dis.Instruction
expected_opinfo_outer = [ expected_opinfo_outer = [
Instruction(opname='MAKE_CELL', opcode=96, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='MAKE_CELL', opcode=96, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='BUILD_TUPLE', opcode=51, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='BUILD_TUPLE', opcode=50, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='STORE_FAST', opcode=111, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=109, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='print', argrepr='print', offset=24, start_offset=24, starts_line=True, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='a', argrepr='a', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='b', argrepr='b', offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='', argrepr="''", offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='BUILD_LIST', opcode=45, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='BUILD_LIST', opcode=46, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='BUILD_MAP', opcode=46, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='BUILD_MAP', opcode=47, arg=0, argval=0, argrepr='', offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CALL', opcode=52, arg=7, argval=7, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='f', argrepr='f', offset=60, start_offset=60, starts_line=True, line_number=8, label=None, positions=None, cache_info=None), Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=62, start_offset=62, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
] ]
expected_opinfo_f = [ expected_opinfo_f = [
Instruction(opname='COPY_FREE_VARS', opcode=60, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='COPY_FREE_VARS', opcode=60, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='MAKE_CELL', opcode=96, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='MAKE_CELL', opcode=96, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='BUILD_TUPLE', opcode=51, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='BUILD_TUPLE', opcode=50, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=107, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='STORE_FAST', opcode=111, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=109, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='print', argrepr='print', offset=30, start_offset=30, starts_line=True, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='a', argrepr='a', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='b', argrepr='b', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='c', argrepr='c', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='d', argrepr='d', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CALL', opcode=52, arg=4, argval=4, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='inner', argrepr='inner', offset=60, start_offset=60, starts_line=True, line_number=6, label=None, positions=None, cache_info=None), Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None),
Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=62, start_offset=62, starts_line=False, line_number=6, label=None, positions=None, cache_info=None),
] ]
expected_opinfo_inner = [ expected_opinfo_inner = [
Instruction(opname='COPY_FREE_VARS', opcode=60, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='COPY_FREE_VARS', opcode=60, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='print', argrepr='print', offset=4, start_offset=4, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=2, argval='a', argrepr='a', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='b', argrepr='b', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='c', argrepr='c', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=82, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_DEREF', opcode=82, arg=5, argval='d', argrepr='d', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=86, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=86, arg=1, argval=('e', 'f'), argrepr='e, f', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CALL', opcode=52, arg=6, argval=6, argrepr='', offset=26, start_offset=26, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=38, start_offset=38, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
] ]
expected_opinfo_jumpy = [ expected_opinfo_jumpy = [
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=0, argval='range', argrepr='range', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=10, argval=10, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=10, argval=10, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='GET_ITER', opcode=16, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='GET_ITER', opcode=18, arg=None, argval=None, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='FOR_ITER', opcode=69, arg=32, argval=92, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='FOR_ITER', opcode=69, arg=33, argval=96, argrepr='to L4', offset=26, start_offset=26, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='STORE_FAST', opcode=111, arg=0, argval='i', argrepr='i', offset=30, start_offset=30, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=32, start_offset=32, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=44, start_offset=44, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=46, start_offset=46, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=54, start_offset=54, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=56, start_offset=56, starts_line=True, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=4, argval=4, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=70, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=64, start_offset=64, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=3, argval=74, argrepr='to L2', offset=64, start_offset=64, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_BACKWARD', opcode=74, arg=23, argval=24, argrepr='to L1', offset=66, start_offset=66, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=68, start_offset=68, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=70, start_offset=70, starts_line=True, line_number=7, label=2, positions=None, cache_info=None),
Instruction(opname='JUMP_BACKWARD', opcode=74, arg=24, argval=26, argrepr='to L1', offset=70, start_offset=70, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=74, start_offset=74, starts_line=True, line_number=7, label=2, positions=None, cache_info=None), Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=74, start_offset=74, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=6, argval=6, argrepr='', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=88, argrepr='to L3', offset=78, start_offset=78, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=78, start_offset=78, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=82, start_offset=82, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='POP_JUMP_IF_TRUE', opcode=102, arg=3, argval=92, argrepr='to L3', offset=82, start_offset=82, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_BACKWARD', opcode=74, arg=32, argval=24, argrepr='to L1', offset=84, start_offset=84, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=86, start_offset=86, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=8, label=3, positions=None, cache_info=None),
Instruction(opname='JUMP_BACKWARD', opcode=74, arg=33, argval=26, argrepr='to L1', offset=88, start_offset=88, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_FORWARD', opcode=76, arg=13, argval=118, argrepr='to L5', offset=90, start_offset=90, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=8, label=3, positions=None, cache_info=None), Instruction(opname='END_FOR', opcode=9, arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
Instruction(opname='JUMP_FORWARD', opcode=76, arg=14, argval=124, argrepr='to L5', offset=94, start_offset=94, starts_line=False, line_number=8, label=None, positions=None, cache_info=None), Instruction(opname='POP_ITER', opcode=30, arg=None, argval=None, argrepr='', offset=94, start_offset=94, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='END_FOR', opcode=10, arg=None, argval=None, argrepr='', offset=96, start_offset=96, starts_line=True, line_number=3, label=4, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=96, start_offset=96, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='POP_ITER', opcode=31, arg=None, argval=None, argrepr='', offset=98, start_offset=98, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=106, start_offset=106, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=100, start_offset=100, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=108, start_offset=108, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=116, start_offset=116, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=112, start_offset=112, starts_line=False, line_number=10, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST_CHECK', opcode=85, arg=0, argval='i', argrepr='i', offset=118, start_offset=118, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=120, start_offset=120, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=122, start_offset=122, starts_line=False, line_number=10, label=None, positions=None, cache_info=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=212, argrepr='to L8', offset=128, start_offset=128, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='LOAD_FAST_CHECK', opcode=85, arg=0, argval='i', argrepr='i', offset=124, start_offset=124, starts_line=True, line_number=11, label=5, positions=None, cache_info=None), Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=132, start_offset=132, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=126, start_offset=126, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=134, start_offset=134, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=41, argval=220, argrepr='to L8', offset=134, start_offset=134, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=144, start_offset=144, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=11, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=140, start_offset=140, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=154, start_offset=154, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=150, start_offset=150, starts_line=False, line_number=12, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=152, start_offset=152, starts_line=False, line_number=12, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=158, start_offset=158, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=154, start_offset=154, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='BINARY_OP', opcode=44, arg=23, argval=23, argrepr='-=', offset=160, start_offset=160, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=162, start_offset=162, starts_line=False, line_number=12, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=172, start_offset=172, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=164, start_offset=164, starts_line=True, line_number=13, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=1, argval=1, argrepr='', offset=166, start_offset=166, starts_line=False, line_number=13, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=176, start_offset=176, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
Instruction(opname='BINARY_OP', opcode=45, arg=23, argval=23, argrepr='-=', offset=168, start_offset=168, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]), Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=178, start_offset=178, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='STORE_FAST', opcode=111, arg=0, argval='i', argrepr='i', offset=180, start_offset=180, starts_line=False, line_number=13, label=None, positions=None, cache_info=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=192, argrepr='to L6', offset=182, start_offset=182, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=182, start_offset=182, starts_line=True, line_number=14, label=None, positions=None, cache_info=None), Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=186, start_offset=186, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=6, argval=6, argrepr='', offset=184, start_offset=184, starts_line=False, line_number=14, label=None, positions=None, cache_info=None), Instruction(opname='JUMP_BACKWARD', opcode=74, arg=37, argval=118, argrepr='to L5', offset=188, start_offset=188, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=186, start_offset=186, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=192, start_offset=192, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=3, argval=200, argrepr='to L6', offset=190, start_offset=190, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=194, start_offset=194, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=194, start_offset=194, starts_line=False, line_number=14, label=None, positions=None, cache_info=None), Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=196, start_offset=196, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='JUMP_BACKWARD', opcode=74, arg=38, argval=124, argrepr='to L5', offset=196, start_offset=196, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=210, argrepr='to L7', offset=200, start_offset=200, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=200, start_offset=200, starts_line=True, line_number=16, label=6, positions=None, cache_info=None), Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=204, start_offset=204, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=4, argval=4, argrepr='', offset=202, start_offset=202, starts_line=False, line_number=16, label=None, positions=None, cache_info=None), Instruction(opname='JUMP_BACKWARD', opcode=74, arg=46, argval=118, argrepr='to L5', offset=206, start_offset=206, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=204, start_offset=204, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_FORWARD', opcode=76, arg=11, argval=234, argrepr='to L9', offset=210, start_offset=210, starts_line=True, line_number=17, label=7, positions=None, cache_info=None),
Instruction(opname='POP_JUMP_IF_TRUE', opcode=102, arg=3, argval=218, argrepr='to L7', offset=208, start_offset=208, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=212, start_offset=212, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=212, start_offset=212, starts_line=False, line_number=16, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=222, start_offset=222, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
Instruction(opname='JUMP_BACKWARD', opcode=74, arg=47, argval=124, argrepr='to L5', offset=214, start_offset=214, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=224, start_offset=224, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='JUMP_FORWARD', opcode=76, arg=12, argval=244, argrepr='to L9', offset=218, start_offset=218, starts_line=True, line_number=17, label=7, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=232, start_offset=232, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=220, start_offset=220, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=234, start_offset=234, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=230, start_offset=230, starts_line=False, line_number=19, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=236, start_offset=236, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=232, start_offset=232, starts_line=False, line_number=19, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=0, argval=0, argrepr='', offset=238, start_offset=238, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=234, start_offset=234, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='BINARY_OP', opcode=44, arg=11, argval=11, argrepr='/', offset=240, start_offset=240, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=19, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=252, start_offset=252, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
Instruction(opname='NOP', opcode=28, arg=None, argval=None, argrepr='', offset=244, start_offset=244, starts_line=True, line_number=20, label=9, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=254, start_offset=254, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=1, argval=1, argrepr='', offset=246, start_offset=246, starts_line=True, line_number=21, label=None, positions=None, cache_info=None), Instruction(opname='COPY', opcode=59, arg=1, argval=1, argrepr='', offset=256, start_offset=256, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SMALL_INT', opcode=92, arg=0, argval=0, argrepr='', offset=248, start_offset=248, starts_line=False, line_number=21, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SPECIAL', opcode=92, arg=1, argval=1, argrepr='__exit__', offset=258, start_offset=258, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='BINARY_OP', opcode=45, arg=11, argval=11, argrepr='/', offset=250, start_offset=250, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]), Instruction(opname='SWAP', opcode=114, arg=2, argval=2, argrepr='', offset=260, start_offset=260, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=262, start_offset=262, starts_line=False, line_number=21, label=None, positions=None, cache_info=None), Instruction(opname='SWAP', opcode=114, arg=3, argval=3, argrepr='', offset=262, start_offset=262, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=264, start_offset=264, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_SPECIAL', opcode=92, arg=0, argval=0, argrepr='__enter__', offset=264, start_offset=264, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='COPY', opcode=59, arg=1, argval=1, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=0, argval=0, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='LOAD_SPECIAL', opcode=93, arg=1, argval=1, argrepr='__exit__', offset=268, start_offset=268, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=109, arg=1, argval='dodgy', argrepr='dodgy', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='SWAP', opcode=116, arg=2, argval=2, argrepr='', offset=270, start_offset=270, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=276, start_offset=276, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='SWAP', opcode=116, arg=3, argval=3, argrepr='', offset=272, start_offset=272, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=286, start_offset=286, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_SPECIAL', opcode=93, arg=0, argval=0, argrepr='__enter__', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=288, start_offset=288, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=276, start_offset=276, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
Instruction(opname='STORE_FAST', opcode=111, arg=1, argval='dodgy', argrepr='dodgy', offset=284, start_offset=284, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=298, start_offset=298, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=286, start_offset=286, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=300, start_offset=300, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=26, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=302, start_offset=302, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=298, start_offset=298, starts_line=False, line_number=26, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=3, argval=3, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=300, start_offset=300, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=False, line_number=26, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=314, start_offset=314, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=310, start_offset=310, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=324, start_offset=324, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=314, start_offset=314, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=334, start_offset=334, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=52, arg=3, argval=3, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=336, start_offset=336, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=338, start_offset=338, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=326, start_offset=326, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=336, start_offset=336, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), Instruction(opname='WITH_EXCEPT_START', opcode=43, arg=None, argval=None, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=338, start_offset=338, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=360, argrepr='to L11', offset=352, start_offset=352, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=350, start_offset=350, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=352, start_offset=352, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=360, start_offset=360, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=354, start_offset=354, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='WITH_EXCEPT_START', opcode=44, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=364, start_offset=364, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='POP_JUMP_IF_TRUE', opcode=102, arg=2, argval=374, argrepr='to L11', offset=366, start_offset=366, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=370, start_offset=370, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=29, argval=314, argrepr='to L10', offset=370, start_offset=370, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='RERAISE', opcode=104, arg=2, argval=2, argrepr='', offset=372, start_offset=372, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=372, start_offset=372, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=374, start_offset=374, starts_line=False, line_number=25, label=11, positions=None, cache_info=None), Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=374, start_offset=374, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=380, start_offset=380, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=382, start_offset=382, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=390, start_offset=390, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=30, argval=326, argrepr='to L10', offset=384, start_offset=384, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=426, argrepr='to L12', offset=392, start_offset=392, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=386, start_offset=386, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=388, start_offset=388, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
Instruction(opname='RERAISE', opcode=104, arg=1, argval=1, argrepr='', offset=390, start_offset=390, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=400, start_offset=400, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=392, start_offset=392, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=410, start_offset=410, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=394, start_offset=394, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=412, start_offset=412, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='CHECK_EXC_MATCH', opcode=6, arg=None, argval=None, argrepr='', offset=404, start_offset=404, starts_line=False, line_number=22, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=420, start_offset=420, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=99, arg=16, argval=442, argrepr='to L12', offset=406, start_offset=406, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
Instruction(opname='NOT_TAKEN', opcode=29, arg=None, argval=None, argrepr='', offset=410, start_offset=410, starts_line=False, line_number=22, label=None, positions=None, cache_info=None), Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=56, argval=314, argrepr='to L10', offset=424, start_offset=424, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=412, start_offset=412, starts_line=False, line_number=22, label=None, positions=None, cache_info=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=426, start_offset=426, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=414, start_offset=414, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=428, start_offset=428, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=426, start_offset=426, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=434, start_offset=434, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=436, start_offset=436, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=436, start_offset=436, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=438, start_offset=438, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=446, start_offset=446, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=58, argval=326, argrepr='to L10', offset=440, start_offset=440, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='RERAISE', opcode=104, arg=0, argval=0, argrepr='', offset=442, start_offset=442, starts_line=True, line_number=22, label=12, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=456, start_offset=456, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=444, start_offset=444, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=458, start_offset=458, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=446, start_offset=446, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=460, start_offset=460, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RERAISE', opcode=104, arg=1, argval=1, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=462, start_offset=462, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=450, start_offset=450, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=464, start_offset=464, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print', offset=452, start_offset=452, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='PUSH_NULL', opcode=34, arg=None, argval=None, argrepr='', offset=462, start_offset=462, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=464, start_offset=464, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=52, arg=1, argval=1, argrepr='', offset=466, start_offset=466, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=474, start_offset=474, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='RERAISE', opcode=104, arg=0, argval=0, argrepr='', offset=476, start_offset=476, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=478, start_offset=478, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='POP_EXCEPT', opcode=30, arg=None, argval=None, argrepr='', offset=480, start_offset=480, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RERAISE', opcode=104, arg=1, argval=1, argrepr='', offset=482, start_offset=482, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
] ]
# One last piece of inspect fodder to check the default line number handling # One last piece of inspect fodder to check the default line number handling
@ -1929,7 +1909,7 @@ def simple(): pass
expected_opinfo_simple = [ expected_opinfo_simple = [
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, label=None, positions=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, label=None, positions=None),
Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None), Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None), Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
] ]
@ -2153,7 +2133,7 @@ def f(opcode, oparg, offset, *init_args):
args = (offset, co_consts, names, varname_from_oparg, labels_map) args = (offset, co_consts, names, varname_from_oparg, labels_map)
self.assertEqual(f(opcode.opmap["POP_TOP"], None, *args), (None, '')) self.assertEqual(f(opcode.opmap["POP_TOP"], None, *args), (None, ''))
self.assertEqual(f(opcode.opmap["LOAD_CONST"], 1, *args), (1, '1')) self.assertEqual(f(opcode.opmap["LOAD_CONST"], 1, *args), (1, '1'))
self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 1, *args), ('a', 'a')) self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 2, *args), ('a', 'a'))
self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to L1')) self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to L1'))
self.assertEqual(f(opcode.opmap["COMPARE_OP"], 3, *args), ('<', '<')) self.assertEqual(f(opcode.opmap["COMPARE_OP"], 3, *args), ('<', '<'))
self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults')) self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults'))

View File

@ -59,14 +59,14 @@ class TestEffects(unittest.TestCase):
def test_effect_sizes(self): def test_effect_sizes(self):
stack = Stack() stack = Stack()
inputs = [ inputs = [
x := StackItem("x", None, "1"), x := StackItem("x", None, "", "1"),
y := StackItem("y", None, "oparg"), y := StackItem("y", None, "", "oparg"),
z := StackItem("z", None, "oparg*2"), z := StackItem("z", None, "", "oparg*2"),
] ]
outputs = [ outputs = [
StackItem("x", None, "1"), StackItem("x", None, "", "1"),
StackItem("b", None, "oparg*4"), StackItem("b", None, "", "oparg*4"),
StackItem("c", None, "1"), StackItem("c", None, "", "1"),
] ]
stack.pop(z) stack.pop(z)
stack.pop(y) stack.pop(y)
@ -104,6 +104,20 @@ def test_push_one(self):
""" """
self.check(input, output) self.check(input, output)
def test_cond_push(self):
input = """
inst(OP, (a -- b, c if (oparg))) {
SPAM();
}
"""
output = """
case OP: {
*effect = ((oparg) ? 1 : 0);
return 0;
}
"""
self.check(input, output)
def test_ops_pass_two(self): def test_ops_pass_two(self):
input = """ input = """
op(A, (-- val1)) { op(A, (-- val1)) {
@ -124,6 +138,25 @@ def test_ops_pass_two(self):
""" """
self.check(input, output) self.check(input, output)
def test_ops_pass_two_cond_push(self):
input = """
op(A, (-- val1, val2)) {
val1 = 0;
val2 = 1;
}
op(B, (val1, val2 -- val1, val2, val3 if (oparg))) {
val3 = SPAM();
}
macro(OP) = A + B;
"""
output = """
case OP: {
*effect = Py_MAX(2, 2 + ((oparg) ? 1 : 0));
return 0;
}
"""
self.check(input, output)
def test_pop_push_array(self): def test_pop_push_array(self):
input = """ input = """
inst(OP, (values[oparg] -- values[oparg], above)) { inst(OP, (values[oparg] -- values[oparg], above)) {
@ -905,6 +938,90 @@ def test_array_error_if(self):
""" """
self.run_cases_test(input, output) self.run_cases_test(input, output)
def test_cond_effect(self):
input = """
inst(OP, (aa, input if ((oparg & 1) == 1), cc -- xx, output if (oparg & 2), zz)) {
output = SPAM(oparg, aa, cc, input);
INPUTS_DEAD();
xx = 0;
zz = 0;
}
"""
output = """
TARGET(OP) {
frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(OP);
_PyStackRef aa;
_PyStackRef input = PyStackRef_NULL;
_PyStackRef cc;
_PyStackRef xx;
_PyStackRef output = PyStackRef_NULL;
_PyStackRef zz;
cc = stack_pointer[-1];
if ((oparg & 1) == 1) { input = stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)]; }
aa = stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)];
output = SPAM(oparg, aa, cc, input);
xx = 0;
zz = 0;
stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)] = xx;
if (oparg & 2) stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)] = output;
stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0)] = zz;
stack_pointer += -(((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0);
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
"""
self.run_cases_test(input, output)
def test_macro_cond_effect(self):
input = """
op(A, (left, middle, right --)) {
USE(left, middle, right);
INPUTS_DEAD();
}
op(B, (-- deep, extra if (oparg), res)) {
deep = -1;
res = 0;
extra = 1;
INPUTS_DEAD();
}
macro(M) = A + B;
"""
output = """
TARGET(M) {
frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(M);
_PyStackRef left;
_PyStackRef middle;
_PyStackRef right;
_PyStackRef deep;
_PyStackRef extra = PyStackRef_NULL;
_PyStackRef res;
// A
{
right = stack_pointer[-1];
middle = stack_pointer[-2];
left = stack_pointer[-3];
USE(left, middle, right);
}
// B
{
deep = -1;
res = 0;
extra = 1;
}
stack_pointer[-3] = deep;
if (oparg) stack_pointer[-2] = extra;
stack_pointer[-2 + ((oparg) ? 1 : 0)] = res;
stack_pointer += -1 + ((oparg) ? 1 : 0);
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
"""
self.run_cases_test(input, output)
def test_macro_push_push(self): def test_macro_push_push(self):
input = """ input = """
op(A, (-- val1)) { op(A, (-- val1)) {

View File

@ -1588,11 +1588,11 @@ def whilefunc(n=0):
('branch right', 'whilefunc', 1, 3)]) ('branch right', 'whilefunc', 1, 3)])
self.check_events(func, recorders = BRANCH_OFFSET_RECORDERS, expected = [ self.check_events(func, recorders = BRANCH_OFFSET_RECORDERS, expected = [
('branch left', 'func', 30, 34), ('branch left', 'func', 28, 32),
('branch right', 'func', 46, 60), ('branch right', 'func', 44, 58),
('branch left', 'func', 30, 34), ('branch left', 'func', 28, 32),
('branch left', 'func', 46, 52), ('branch left', 'func', 44, 50),
('branch right', 'func', 30, 72)]) ('branch right', 'func', 28, 70)])
def test_except_star(self): def test_except_star(self):
@ -1762,8 +1762,7 @@ def _exec_super(self, codestr, optimized=False):
return self._exec(co) return self._exec(co)
def _has_load_super_attr(self, co): def _has_load_super_attr(self, co):
has = any(instr.opname in ("LOAD_SUPER_ATTR", "LOAD_SUPER_METHOD") has = any(instr.opname == "LOAD_SUPER_ATTR" for instr in dis.get_instructions(co))
for instr in dis.get_instructions(co))
if not has: if not has:
has = any( has = any(
isinstance(c, types.CodeType) and self._has_load_super_attr(c) isinstance(c, types.CodeType) and self._has_load_super_attr(c)

View File

@ -868,7 +868,7 @@ def write(items):
pass pass
type(item).m = lambda self: None type(item).m = lambda self: None
opname = "LOAD_METHOD_LAZY_DICT" opname = "LOAD_ATTR_METHOD_LAZY_DICT"
self.assert_races_do_not_crash(opname, get_items, read, write) self.assert_races_do_not_crash(opname, get_items, read, write)
@requires_specialization_ft @requires_specialization_ft
@ -899,7 +899,7 @@ def write(items):
pass pass
type(item).m = lambda self: None type(item).m = lambda self: None
opname = "LOAD_METHOD_NO_DICT" opname = "LOAD_ATTR_METHOD_NO_DICT"
self.assert_races_do_not_crash(opname, get_items, read, write) self.assert_races_do_not_crash(opname, get_items, read, write)
@requires_specialization_ft @requires_specialization_ft
@ -929,7 +929,7 @@ def write(items):
pass pass
type(item).m = lambda self: None type(item).m = lambda self: None
opname = "LOAD_METHOD_WITH_VALUES" opname = "LOAD_ATTR_METHOD_WITH_VALUES"
self.assert_races_do_not_crash(opname, get_items, read, write) self.assert_races_do_not_crash(opname, get_items, read, write)
@requires_specialization_ft @requires_specialization_ft
@ -1424,9 +1424,8 @@ def __init__(self):
A() A()
self.assert_specialized(A.__init__, "LOAD_SUPER_ATTR_ATTR") self.assert_specialized(A.__init__, "LOAD_SUPER_ATTR_ATTR")
self.assert_specialized(A.__init__, "LOAD_SUPER_METHOD_METHOD") self.assert_specialized(A.__init__, "LOAD_SUPER_ATTR_METHOD")
self.assert_no_opcode(A.__init__, "LOAD_SUPER_ATTR") self.assert_no_opcode(A.__init__, "LOAD_SUPER_ATTR")
self.assert_no_opcode(A.__init__, "LOAD_SUPER_METHOD")
# Temporarily replace super() with something else. # Temporarily replace super() with something else.
real_super = super real_super = super

View File

@ -1,3 +0,0 @@
:opcode:`LOAD_ATTR` no longer pushes an extra ``NULL`` to the stack.
:opcode:`LOAD_METHOD` has been added. ``LOAD_METHOD`` is equivalent to
``LOAD_ATTR; PUSH_NULL`` but is optimized for use in method calls.

View File

@ -1261,18 +1261,27 @@ mark_stacks(PyCodeObject *code_obj, int len)
stacks[next_i] = next_stack; stacks[next_i] = next_stack;
break; break;
case LOAD_GLOBAL: case LOAD_GLOBAL:
{
int j = oparg;
next_stack = push_value(next_stack, Object); next_stack = push_value(next_stack, Object);
if (j & 1) {
next_stack = push_value(next_stack, Null);
}
stacks[next_i] = next_stack; stacks[next_i] = next_stack;
break; break;
}
case LOAD_ATTR: case LOAD_ATTR:
{
assert(top_of_stack(next_stack) == Object); assert(top_of_stack(next_stack) == Object);
int j = oparg;
if (j & 1) {
next_stack = pop_value(next_stack);
next_stack = push_value(next_stack, Object);
next_stack = push_value(next_stack, Null);
}
stacks[next_i] = next_stack; stacks[next_i] = next_stack;
break; break;
case LOAD_METHOD: }
assert(top_of_stack(next_stack) == Object);
next_stack = push_value(next_stack, Null);
stacks[next_i] = next_stack;
break;
case SWAP: case SWAP:
{ {
int n = oparg; int n = oparg;

View File

@ -1551,7 +1551,7 @@ _PyObject_NextNotImplemented(PyObject *self)
/* Specialized version of _PyObject_GenericGetAttrWithDict /* Specialized version of _PyObject_GenericGetAttrWithDict
specifically for the loading methods specifically for the LOAD_METHOD opcode.
Return 1 if a method is found, 0 if it's a regular attribute Return 1 if a method is found, 0 if it's a regular attribute
from __dict__ or something returned by using a descriptor from __dict__ or something returned by using a descriptor

View File

@ -1,18 +1,18 @@
// Auto-generated by Programs/freeze_test_frozenmain.py // Auto-generated by Programs/freeze_test_frozenmain.py
unsigned char M_test_frozenmain[] = { unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0, 227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,
0,0,0,0,0,243,168,0,0,0,149,0,92,0,81,0, 0,0,0,0,0,243,168,0,0,0,149,0,91,0,81,0,
72,0,115,0,92,0,81,0,72,1,115,1,91,2,34,0, 72,0,113,0,91,0,81,0,72,1,113,1,90,2,33,0,
81,1,52,1,0,0,0,0,0,0,32,0,91,2,34,0, 81,1,51,1,0,0,0,0,0,0,31,0,90,2,33,0,
81,2,91,0,79,3,0,0,0,0,0,0,0,0,0,0, 81,2,90,0,79,6,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,52,2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,51,2,0,0,0,0,0,0,
32,0,91,1,79,4,0,0,0,0,0,0,0,0,0,0, 31,0,90,1,79,8,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,34,0,52,0,0,0,0,0, 0,0,0,0,0,0,0,0,33,0,51,0,0,0,0,0,
0,0,81,3,2,0,0,0,115,5,81,4,18,0,69,20, 0,0,81,3,2,0,0,0,113,5,81,4,16,0,69,20,
0,0,115,6,91,2,34,0,81,5,91,6,13,0,81,6, 0,0,113,6,90,2,33,0,81,5,90,6,12,0,81,6,
91,5,91,6,2,0,0,0,13,0,50,4,52,1,0,0, 90,5,90,6,2,0,0,0,12,0,49,4,51,1,0,0,
0,0,0,0,32,0,74,22,0,0,10,0,31,0,81,0, 0,0,0,0,31,0,74,22,0,0,9,0,30,0,81,0,
36,0,41,7,78,122,18,70,114,111,122,101,110,32,72,101, 35,0,41,7,78,122,18,70,114,111,122,101,110,32,72,101,
108,108,111,32,87,111,114,108,100,122,8,115,121,115,46,97, 108,108,111,32,87,111,114,108,100,122,8,115,121,115,46,97,
114,103,118,218,6,99,111,110,102,105,103,41,5,218,12,112, 114,103,118,218,6,99,111,110,102,105,103,41,5,218,12,112,
114,111,103,114,97,109,95,110,97,109,101,218,10,101,120,101, 114,111,103,114,97,109,95,110,97,109,101,218,10,101,120,101,

View File

@ -348,8 +348,8 @@ dummy_func(
DECREF_INPUTS(); DECREF_INPUTS();
} }
pure inst(PUSH_NULL, (-- null)) { pure inst(PUSH_NULL, (-- res)) {
null = PyStackRef_NULL; res = PyStackRef_NULL;
} }
no_save_ip inst(END_FOR, (value -- )) { no_save_ip inst(END_FOR, (value -- )) {
@ -1654,7 +1654,7 @@ dummy_func(
specializing op(_SPECIALIZE_LOAD_GLOBAL, (counter/1 -- )) { specializing op(_SPECIALIZE_LOAD_GLOBAL, (counter/1 -- )) {
#if ENABLE_SPECIALIZATION_FT #if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
next_instr = this_instr; next_instr = this_instr;
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
DISPATCH_SAME_OPARG(); DISPATCH_SAME_OPARG();
@ -1665,10 +1665,11 @@ dummy_func(
} }
// res[1] because we need a pointer to res to pass it to _PyEval_LoadGlobalStackRef // res[1] because we need a pointer to res to pass it to _PyEval_LoadGlobalStackRef
op(_LOAD_GLOBAL, ( -- res[1])) { op(_LOAD_GLOBAL, ( -- res[1], null if (oparg & 1))) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
ERROR_IF(PyStackRef_IsNull(*res), error); ERROR_IF(PyStackRef_IsNull(*res), error);
null = PyStackRef_NULL;
} }
macro(LOAD_GLOBAL) = macro(LOAD_GLOBAL) =
@ -1706,7 +1707,7 @@ dummy_func(
assert(DK_IS_UNICODE(builtins_keys)); assert(DK_IS_UNICODE(builtins_keys));
} }
op(_LOAD_GLOBAL_MODULE_FROM_KEYS, (index/1, globals_keys: PyDictKeysObject* -- res)) { op(_LOAD_GLOBAL_MODULE_FROM_KEYS, (index/1, globals_keys: PyDictKeysObject* -- res, null if (oparg & 1))) {
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value); PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
DEAD(globals_keys); DEAD(globals_keys);
@ -1720,9 +1721,10 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
#endif #endif
STAT_INC(LOAD_GLOBAL, hit); STAT_INC(LOAD_GLOBAL, hit);
null = PyStackRef_NULL;
} }
op(_LOAD_GLOBAL_BUILTINS_FROM_KEYS, (index/1, builtins_keys: PyDictKeysObject* -- res)) { op(_LOAD_GLOBAL_BUILTINS_FROM_KEYS, (index/1, builtins_keys: PyDictKeysObject* -- res, null if (oparg & 1))) {
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value); PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
DEAD(builtins_keys); DEAD(builtins_keys);
@ -1736,6 +1738,7 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
#endif #endif
STAT_INC(LOAD_GLOBAL, hit); STAT_INC(LOAD_GLOBAL, hit);
null = PyStackRef_NULL;
} }
macro(LOAD_GLOBAL_MODULE) = macro(LOAD_GLOBAL_MODULE) =
@ -2009,27 +2012,17 @@ dummy_func(
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
} }
inst(INSTRUMENTED_LOAD_SUPER_METHOD, (unused/1 -- )) {
// cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
// don't want to specialize instrumented instructions
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
GO_TO_INSTRUCTION(LOAD_SUPER_METHOD);
}
family(LOAD_SUPER_ATTR, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = { family(LOAD_SUPER_ATTR, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_ATTR_ATTR, LOAD_SUPER_ATTR_ATTR,
}; LOAD_SUPER_ATTR_METHOD,
family(LOAD_SUPER_METHOD, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_METHOD_METHOD,
}; };
specializing op(_SPECIALIZE_LOAD_SUPER_ATTR, (counter/1, global_super_st, class_st, unused -- global_super_st, class_st, unused)) { specializing op(_SPECIALIZE_LOAD_SUPER_ATTR, (counter/1, global_super_st, class_st, unused -- global_super_st, class_st, unused)) {
#if ENABLE_SPECIALIZATION_FT #if ENABLE_SPECIALIZATION_FT
int load_method = oparg & 1;
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr; next_instr = this_instr;
_Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 0); _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, load_method);
DISPATCH_SAME_OPARG(); DISPATCH_SAME_OPARG();
} }
OPCODE_DEFERRED_INC(LOAD_SUPER_ATTR); OPCODE_DEFERRED_INC(LOAD_SUPER_ATTR);
@ -2037,24 +2030,12 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION_FT */ #endif /* ENABLE_SPECIALIZATION_FT */
} }
specializing op(_SPECIALIZE_LOAD_SUPER_METHOD, (counter/1, global_super_st, class_st, unused -- global_super_st, class_st, unused)) { tier1 op(_LOAD_SUPER_ATTR, (global_super_st, class_st, self_st -- attr, null if (oparg & 1))) {
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
_Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 1);
DISPATCH_SAME_OPARG();
}
OPCODE_DEFERRED_INC(LOAD_SUPER_METHOD);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
#endif /* ENABLE_SPECIALIZATION_FT */
}
tier1 op(_LOAD_SUPER_ATTR, (global_super_st, class_st, self_st -- attr)) {
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st); PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st); PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st); PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
if (opcode >= MIN_INSTRUMENTED_OPCODE) { if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
int err = _Py_call_instrumentation_2args( int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL, tstate, PY_MONITORING_EVENT_CALL,
@ -2068,7 +2049,7 @@ dummy_func(
// handle any case whose performance we care about // handle any case whose performance we care about
PyObject *stack[] = {class, self}; PyObject *stack[] = {class, self};
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
if (opcode >= MIN_INSTRUMENTED_OPCODE) { if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) { if (super == NULL) {
_Py_call_instrumentation_exc2( _Py_call_instrumentation_exc2(
@ -2091,13 +2072,12 @@ dummy_func(
Py_DECREF(super); Py_DECREF(super);
ERROR_IF(attr_o == NULL, error); ERROR_IF(attr_o == NULL, error);
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
null = PyStackRef_NULL;
} }
macro(LOAD_SUPER_ATTR) = _SPECIALIZE_LOAD_SUPER_ATTR + _LOAD_SUPER_ATTR; macro(LOAD_SUPER_ATTR) = _SPECIALIZE_LOAD_SUPER_ATTR + _LOAD_SUPER_ATTR;
macro(LOAD_SUPER_METHOD) = _SPECIALIZE_LOAD_SUPER_METHOD + _LOAD_SUPER_ATTR + PUSH_NULL;
inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st, unused if (0))) {
inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st)) {
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st); PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st); PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st); PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
@ -2113,7 +2093,7 @@ dummy_func(
attr_st = PyStackRef_FromPyObjectSteal(attr); attr_st = PyStackRef_FromPyObjectSteal(attr);
} }
inst(LOAD_SUPER_METHOD_METHOD, (unused/1, global_super_st, class_st, self_st -- attr, self_or_null)) { inst(LOAD_SUPER_ATTR_METHOD, (unused/1, global_super_st, class_st, self_st -- attr, self_or_null)) {
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st); PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st); PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st); PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
@ -2152,20 +2132,17 @@ dummy_func(
LOAD_ATTR_CLASS_WITH_METACLASS_CHECK, LOAD_ATTR_CLASS_WITH_METACLASS_CHECK,
LOAD_ATTR_PROPERTY, LOAD_ATTR_PROPERTY,
LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
LOAD_ATTR_METHOD_WITH_VALUES,
LOAD_ATTR_METHOD_NO_DICT,
LOAD_ATTR_METHOD_LAZY_DICT,
LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES,
LOAD_ATTR_NONDESCRIPTOR_NO_DICT, LOAD_ATTR_NONDESCRIPTOR_NO_DICT,
}; };
family(LOAD_METHOD, INLINE_CACHE_ENTRIES_LOAD_ATTR) = {
LOAD_METHOD_WITH_VALUES,
LOAD_METHOD_NO_DICT,
LOAD_METHOD_LAZY_DICT,
};
specializing op(_SPECIALIZE_LOAD_ATTR, (counter/1, owner -- owner)) { specializing op(_SPECIALIZE_LOAD_ATTR, (counter/1, owner -- owner)) {
#if ENABLE_SPECIALIZATION_FT #if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
next_instr = this_instr; next_instr = this_instr;
_Py_Specialize_LoadAttr(owner, next_instr, name); _Py_Specialize_LoadAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG(); DISPATCH_SAME_OPARG();
@ -2175,67 +2152,50 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION_FT */ #endif /* ENABLE_SPECIALIZATION_FT */
} }
specializing op(_SPECIALIZE_LOAD_METHOD, (counter/1, owner -- owner)) { op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
#if ENABLE_SPECIALIZATION_FT PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
next_instr = this_instr;
_Py_Specialize_LoadMethod(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
OPCODE_DEFERRED_INC(LOAD_METHOD);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
#endif /* ENABLE_SPECIALIZATION_FT */
}
op(_LOAD_METHOD, (owner -- attr, self_or_null)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *attr_o; PyObject *attr_o;
/* Designed to work in tandem with CALL, pushes two values. */ if (oparg & 1) {
attr_o = NULL; /* Designed to work in tandem with CALL, pushes two values. */
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o); attr_o = NULL;
if (is_meth) { int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
/* We can bypass temporary bound method object. if (is_meth) {
meth is unbound method and obj is self. /* We can bypass temporary bound method object.
meth | self | arg1 | ... | argN meth is unbound method and obj is self.
meth | self | arg1 | ... | argN
*/
assert(attr_o != NULL); // No errors on this branch
self_or_null = owner; // Transfer ownership
DEAD(owner);
}
else {
/* meth is not an unbound method (but a regular attr, or
something was returned by a descriptor protocol). Set
the second element of the stack to NULL, to signal
CALL that it's not a method call.
meth | NULL | arg1 | ... | argN
*/ */
assert(attr_o != NULL); // No errors on this branch DECREF_INPUTS();
self_or_null = owner; // Transfer ownership ERROR_IF(attr_o == NULL, error);
DEAD(owner); self_or_null = PyStackRef_NULL;
}
} }
else { else {
/* meth is not an unbound method (but a regular attr, or /* Classic, pushes one value. */
something was returned by a descriptor protocol). Set attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
the second element of the stack to NULL, to signal
CALL that it's not a method call.
meth | NULL | arg1 | ... | argN
*/
DECREF_INPUTS(); DECREF_INPUTS();
ERROR_IF(attr_o == NULL, error); ERROR_IF(attr_o == NULL, error);
/* We need to define self_or_null on all paths */
self_or_null = PyStackRef_NULL; self_or_null = PyStackRef_NULL;
} }
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
} }
op(_LOAD_ATTR, (owner -- attr)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
DECREF_INPUTS();
ERROR_IF(attr_o == NULL, error);
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
macro(LOAD_ATTR) = macro(LOAD_ATTR) =
_SPECIALIZE_LOAD_ATTR + _SPECIALIZE_LOAD_ATTR +
unused/8 + unused/8 +
_LOAD_ATTR; _LOAD_ATTR;
macro(LOAD_METHOD) =
_SPECIALIZE_LOAD_METHOD +
unused/8 +
_LOAD_METHOD;
op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) { op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner)); PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0); assert(type_version != 0);
@ -2260,7 +2220,7 @@ dummy_func(
DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)); DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid));
} }
op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) { split op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr, null if (oparg & 1))) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset); PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr); PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
@ -2273,6 +2233,7 @@ dummy_func(
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
DECREF_INPUTS(); DECREF_INPUTS();
} }
@ -2293,7 +2254,7 @@ dummy_func(
mod_keys = keys; mod_keys = keys;
} }
op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys: PyDictKeysObject * -- attr)) { op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys: PyDictKeysObject * -- attr, null if (oparg & 1))) {
assert(mod_keys->dk_kind == DICT_KEYS_UNICODE); assert(mod_keys->dk_kind == DICT_KEYS_UNICODE);
assert(index < FT_ATOMIC_LOAD_SSIZE_RELAXED(mod_keys->dk_nentries)); assert(index < FT_ATOMIC_LOAD_SSIZE_RELAXED(mod_keys->dk_nentries));
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mod_keys) + index; PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mod_keys) + index;
@ -2311,6 +2272,7 @@ dummy_func(
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
} }
@ -2330,7 +2292,7 @@ dummy_func(
dict = dict_o; dict = dict_o;
} }
op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict: PyDictObject * -- attr)) { op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict: PyDictObject * -- attr, null if (oparg & 1))) {
PyObject *attr_o; PyObject *attr_o;
if (!LOCK_OBJECT(dict)) { if (!LOCK_OBJECT(dict)) {
POP_INPUT(dict); POP_INPUT(dict);
@ -2342,7 +2304,7 @@ dummy_func(
POP_INPUT(dict); POP_INPUT(dict);
DEOPT_IF(true); DEOPT_IF(true);
} }
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) { if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
UNLOCK_OBJECT(dict); UNLOCK_OBJECT(dict);
POP_INPUT(dict); POP_INPUT(dict);
@ -2364,6 +2326,7 @@ dummy_func(
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
UNLOCK_OBJECT(dict); UNLOCK_OBJECT(dict);
DEAD(dict); DEAD(dict);
null = PyStackRef_NULL;
DECREF_INPUTS(); DECREF_INPUTS();
} }
@ -2374,7 +2337,7 @@ dummy_func(
_LOAD_ATTR_WITH_HINT + _LOAD_ATTR_WITH_HINT +
unused/5; unused/5;
op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) { split op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **addr = (PyObject **)((char *)owner_o + index); PyObject **addr = (PyObject **)((char *)owner_o + index);
@ -2387,6 +2350,7 @@ dummy_func(
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
DECREF_INPUTS(); DECREF_INPUTS();
} }
@ -2404,10 +2368,11 @@ dummy_func(
EXIT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(((PyTypeObject *)owner_o)->tp_version_tag) != type_version); EXIT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(((PyTypeObject *)owner_o)->tp_version_tag) != type_version);
} }
op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) { split op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) {
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr); attr = PyStackRef_FromPyObjectNew(descr);
null = PyStackRef_NULL;
DECREF_INPUTS(); DECREF_INPUTS();
} }
@ -2424,6 +2389,7 @@ dummy_func(
_LOAD_ATTR_CLASS; _LOAD_ATTR_CLASS;
op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _PyInterpreterFrame *)) { op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _PyInterpreterFrame *)) {
assert((oparg & 1) == 0);
assert(Py_IS_TYPE(fget, &PyFunction_Type)); assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget; PyFunctionObject *f = (PyFunctionObject *)fget;
PyCodeObject *code = (PyCodeObject *)f->func_code; PyCodeObject *code = (PyCodeObject *)f->func_code;
@ -2446,8 +2412,10 @@ dummy_func(
_SAVE_RETURN_OFFSET + _SAVE_RETURN_OFFSET +
_PUSH_FRAME; _PUSH_FRAME;
inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused)) { inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused, unused if (0))) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
assert((oparg & 1) == 0);
DEOPT_IF(tstate->interp->eval_frame); DEOPT_IF(tstate->interp->eval_frame);
PyTypeObject *cls = Py_TYPE(owner_o); PyTypeObject *cls = Py_TYPE(owner_o);
assert(type_version != 0); assert(type_version != 0);
@ -2461,7 +2429,7 @@ dummy_func(
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize));
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked( _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(
tstate, PyStackRef_FromPyObjectNew(f), 2, frame); tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
// Manipulate stack directly because we exit with DISPATCH_INLINED(). // Manipulate stack directly because we exit with DISPATCH_INLINED().
@ -3380,7 +3348,8 @@ dummy_func(
DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version); DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version);
} }
op(_LOAD_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) { split op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) {
assert(oparg & 1);
/* Cached method object */ /* Cached method object */
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -3390,14 +3359,15 @@ dummy_func(
DEAD(owner); DEAD(owner);
} }
macro(LOAD_METHOD_WITH_VALUES) = macro(LOAD_ATTR_METHOD_WITH_VALUES) =
unused/1 + unused/1 +
_GUARD_TYPE_VERSION + _GUARD_TYPE_VERSION +
_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT + _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT +
_GUARD_KEYS_VERSION + _GUARD_KEYS_VERSION +
_LOAD_METHOD_WITH_VALUES; _LOAD_ATTR_METHOD_WITH_VALUES;
op(_LOAD_METHOD_NO_DICT, (descr/4, owner -- attr, self)) { op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) {
assert(oparg & 1);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -3407,13 +3377,14 @@ dummy_func(
DEAD(owner); DEAD(owner);
} }
macro(LOAD_METHOD_NO_DICT) = macro(LOAD_ATTR_METHOD_NO_DICT) =
unused/1 + unused/1 +
_GUARD_TYPE_VERSION + _GUARD_TYPE_VERSION +
unused/2 + unused/2 +
_LOAD_METHOD_NO_DICT; _LOAD_ATTR_METHOD_NO_DICT;
op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr)) { op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr, unused if (0))) {
assert((oparg & 1) == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
DECREF_INPUTS(); DECREF_INPUTS();
@ -3427,7 +3398,8 @@ dummy_func(
_GUARD_KEYS_VERSION + _GUARD_KEYS_VERSION +
_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES; _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES;
op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr)) { op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr, unused if (0))) {
assert((oparg & 1) == 0);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -3448,7 +3420,8 @@ dummy_func(
DEOPT_IF(dict != NULL); DEOPT_IF(dict != NULL);
} }
op(_LOAD_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) { op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) {
assert(oparg & 1);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
@ -3457,12 +3430,12 @@ dummy_func(
DEAD(owner); DEAD(owner);
} }
macro(LOAD_METHOD_LAZY_DICT) = macro(LOAD_ATTR_METHOD_LAZY_DICT) =
unused/1 + unused/1 +
_GUARD_TYPE_VERSION + _GUARD_TYPE_VERSION +
_CHECK_ATTR_METHOD_LAZY_DICT + _CHECK_ATTR_METHOD_LAZY_DICT +
unused/1 + unused/1 +
_LOAD_METHOD_LAZY_DICT; _LOAD_ATTR_METHOD_LAZY_DICT;
// Cache layout: counter/1, func_version/2 // Cache layout: counter/1, func_version/2
// CALL_INTRINSIC_1/2, CALL_KW, and CALL_FUNCTION_EX aren't members! // CALL_INTRINSIC_1/2, CALL_KW, and CALL_FUNCTION_EX aren't members!
@ -4564,7 +4537,7 @@ dummy_func(
GO_TO_INSTRUCTION(CALL_FUNCTION_EX); GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
} }
op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in -- func, unused, tuple, kwargs_out)) { op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in if (oparg & 1) -- func, unused, tuple, kwargs_out if (oparg & 1))) {
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs); PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
if (PyTuple_CheckExact(callargs_o)) { if (PyTuple_CheckExact(callargs_o)) {
tuple = callargs; tuple = callargs;
@ -4588,7 +4561,7 @@ dummy_func(
} }
} }
op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st -- result)) { op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) {
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st); PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
// DICT_MERGE is called before this opcode if there are kwargs. // DICT_MERGE is called before this opcode if there are kwargs.
@ -4722,16 +4695,11 @@ dummy_func(
LLTRACE_RESUME_FRAME(); LLTRACE_RESUME_FRAME();
} }
inst(BUILD_SLICE, (args[oparg] -- slice)) { inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) {
assert(oparg == 2 || oparg == 3);
_PyStackRef start = args[0];
_PyStackRef stop = args[1];
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
PyObject * step_o = NULL; PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
if (oparg == 3) {
step_o = PyStackRef_AsPyObjectBorrow(args[2]);
}
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o); PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
DECREF_INPUTS(); DECREF_INPUTS();
ERROR_IF(slice_o == NULL, error); ERROR_IF(slice_o == NULL, error);
@ -5074,25 +5042,27 @@ dummy_func(
DEOPT_IF(func->func_version != func_version); DEOPT_IF(func->func_version != func_version);
} }
tier2 op(_LOAD_GLOBAL_MODULE, (index/1 -- res)) { tier2 op(_LOAD_GLOBAL_MODULE, (index/1 -- res, null if (oparg & 1))) {
PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictObject *dict = (PyDictObject *)GLOBALS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
PyObject *res_o = entries[index].me_value; PyObject *res_o = entries[index].me_value;
DEOPT_IF(res_o == NULL); DEOPT_IF(res_o == NULL);
Py_INCREF(res_o); Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
null = PyStackRef_NULL;
} }
tier2 op(_LOAD_GLOBAL_BUILTINS, (index/1 -- res)) { tier2 op(_LOAD_GLOBAL_BUILTINS, (index/1 -- res, null if (oparg & 1))) {
PyDictObject *dict = (PyDictObject *)BUILTINS(); PyDictObject *dict = (PyDictObject *)BUILTINS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
PyObject *res_o = entries[index].me_value; PyObject *res_o = entries[index].me_value;
DEOPT_IF(res_o == NULL); DEOPT_IF(res_o == NULL);
Py_INCREF(res_o); Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
null = PyStackRef_NULL;
} }
tier2 op(_LOAD_ATTR_MODULE, (index/1, owner -- attr)) { tier2 op(_LOAD_ATTR_MODULE, (index/1, owner -- attr, null if (oparg & 1))) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict; PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict;
assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
@ -5103,6 +5073,7 @@ dummy_func(
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
Py_INCREF(attr_o); Py_INCREF(attr_o);
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
null = PyStackRef_NULL;
DECREF_INPUTS(); DECREF_INPUTS();
} }

View File

@ -348,6 +348,8 @@ codegen_addop_o(compiler *c, location loc,
RETURN_IF_ERROR_IN_SCOPE((C), ret); \ RETURN_IF_ERROR_IN_SCOPE((C), ret); \
} while (0) } while (0)
#define LOAD_METHOD -1
#define LOAD_SUPER_METHOD -2
#define LOAD_ZERO_SUPER_ATTR -3 #define LOAD_ZERO_SUPER_ATTR -3
#define LOAD_ZERO_SUPER_METHOD -4 #define LOAD_ZERO_SUPER_METHOD -4
@ -364,11 +366,20 @@ codegen_addop_name(compiler *c, location loc,
if (arg < 0) { if (arg < 0) {
return ERROR; return ERROR;
} }
if (opcode == LOAD_ATTR) {
arg <<= 1;
}
if (opcode == LOAD_METHOD) {
opcode = LOAD_ATTR;
arg <<= 1;
arg |= 1;
}
if (opcode == LOAD_SUPER_ATTR) { if (opcode == LOAD_SUPER_ATTR) {
arg <<= 2; arg <<= 2;
arg |= 2; arg |= 2;
} }
if (opcode == LOAD_SUPER_METHOD) { if (opcode == LOAD_SUPER_METHOD) {
opcode = LOAD_SUPER_ATTR;
arg <<= 2; arg <<= 2;
arg |= 3; arg |= 3;
} }
@ -377,7 +388,7 @@ codegen_addop_name(compiler *c, location loc,
arg <<= 2; arg <<= 2;
} }
if (opcode == LOAD_ZERO_SUPER_METHOD) { if (opcode == LOAD_ZERO_SUPER_METHOD) {
opcode = LOAD_SUPER_METHOD; opcode = LOAD_SUPER_ATTR;
arg <<= 2; arg <<= 2;
arg |= 1; arg |= 1;
} }
@ -3154,6 +3165,9 @@ codegen_nameop(compiler *c, location loc,
assert(op); assert(op);
Py_DECREF(mangled); Py_DECREF(mangled);
if (op == LOAD_GLOBAL) {
arg <<= 1;
}
ADDOP_I(c, loc, op, arg); ADDOP_I(c, loc, op, arg);
return SUCCESS; return SUCCESS;
@ -4094,10 +4108,7 @@ codegen_call_helper_impl(compiler *c, location loc,
} }
assert(have_dict); assert(have_dict);
} }
if (nkwelts == 0) { ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0);
ADDOP(c, loc, PUSH_NULL);
}
ADDOP(c, loc, CALL_FUNCTION_EX);
return SUCCESS; return SUCCESS;
} }
@ -4830,10 +4841,8 @@ codegen_async_with(compiler *c, stmt_ty s, int pos)
SETUP_WITH E SETUP_WITH E
<code to store to VAR> or POP_TOP <code to store to VAR> or POP_TOP
<code for BLOCK> <code for BLOCK>
LOAD_CONST None LOAD_CONST (None, None, None)
LOAD_CONST None CALL_FUNCTION_EX 0
LOAD_CONST None
CALL 3
JUMP EXIT JUMP EXIT
E: WITH_EXCEPT_START (calls EXPR.__exit__) E: WITH_EXCEPT_START (calls EXPR.__exit__)
POP_JUMP_IF_TRUE T: POP_JUMP_IF_TRUE T:

View File

@ -406,9 +406,9 @@
} }
case _PUSH_NULL: { case _PUSH_NULL: {
_PyStackRef null; _PyStackRef res;
null = PyStackRef_NULL; res = PyStackRef_NULL;
stack_pointer[0] = null; stack_pointer[0] = res;
stack_pointer += 1; stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
@ -1953,14 +1953,17 @@
case _LOAD_GLOBAL: { case _LOAD_GLOBAL: {
_PyStackRef *res; _PyStackRef *res;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
res = &stack_pointer[0]; res = &stack_pointer[0];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
if (PyStackRef_IsNull(*res)) JUMP_TO_ERROR(); if (PyStackRef_IsNull(*res)) JUMP_TO_ERROR();
stack_pointer += 1; null = PyStackRef_NULL;
if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -2026,6 +2029,8 @@
case _LOAD_GLOBAL_MODULE_FROM_KEYS: { case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
PyDictKeysObject *globals_keys; PyDictKeysObject *globals_keys;
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits; globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
uint16_t index = (uint16_t)CURRENT_OPERAND0(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
@ -2047,8 +2052,10 @@
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
#endif #endif
STAT_INC(LOAD_GLOBAL, hit); STAT_INC(LOAD_GLOBAL, hit);
null = PyStackRef_NULL;
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -2056,6 +2063,8 @@
case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: { case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
PyDictKeysObject *builtins_keys; PyDictKeysObject *builtins_keys;
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits; builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
uint16_t index = (uint16_t)CURRENT_OPERAND0(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
@ -2077,8 +2086,10 @@
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
#endif #endif
STAT_INC(LOAD_GLOBAL, hit); STAT_INC(LOAD_GLOBAL, hit);
null = PyStackRef_NULL;
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -2508,8 +2519,6 @@
/* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 because it is instrumented */ /* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 because it is instrumented */
/* _INSTRUMENTED_LOAD_SUPER_METHOD is not a viable micro-op for tier 2 because it is instrumented */
case _LOAD_SUPER_ATTR_ATTR: { case _LOAD_SUPER_ATTR_ATTR: {
_PyStackRef self_st; _PyStackRef self_st;
_PyStackRef class_st; _PyStackRef class_st;
@ -2547,7 +2556,7 @@
break; break;
} }
case _LOAD_SUPER_METHOD_METHOD: { case _LOAD_SUPER_ATTR_METHOD: {
_PyStackRef self_st; _PyStackRef self_st;
_PyStackRef class_st; _PyStackRef class_st;
_PyStackRef global_super_st; _PyStackRef global_super_st;
@ -2596,62 +2605,58 @@
break; break;
} }
case _LOAD_METHOD: { case _LOAD_ATTR: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef self_or_null; _PyStackRef self_or_null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
PyObject *attr_o; PyObject *attr_o;
/* Designed to work in tandem with CALL, pushes two values. */ if (oparg & 1) {
attr_o = NULL; /* Designed to work in tandem with CALL, pushes two values. */
_PyFrame_SetStackPointer(frame, stack_pointer); attr_o = NULL;
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o); _PyFrame_SetStackPointer(frame, stack_pointer);
stack_pointer = _PyFrame_GetStackPointer(frame); int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
if (is_meth) { stack_pointer = _PyFrame_GetStackPointer(frame);
/* We can bypass temporary bound method object. if (is_meth) {
meth is unbound method and obj is self. /* We can bypass temporary bound method object.
meth | self | arg1 | ... | argN meth is unbound method and obj is self.
*/ meth | self | arg1 | ... | argN
assert(attr_o != NULL); // No errors on this branch */
self_or_null = owner; // Transfer ownership assert(attr_o != NULL); // No errors on this branch
self_or_null = owner; // Transfer ownership
}
else {
/* meth is not an unbound method (but a regular attr, or
something was returned by a descriptor protocol). Set
the second element of the stack to NULL, to signal
CALL that it's not a method call.
meth | NULL | arg1 | ... | argN
*/
PyStackRef_CLOSE(owner);
if (attr_o == NULL) JUMP_TO_ERROR();
self_or_null = PyStackRef_NULL;
}
} }
else { else {
/* meth is not an unbound method (but a regular attr, or /* Classic, pushes one value. */
something was returned by a descriptor protocol). Set _PyFrame_SetStackPointer(frame, stack_pointer);
the second element of the stack to NULL, to signal attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
CALL that it's not a method call. stack_pointer = _PyFrame_GetStackPointer(frame);
meth | NULL | arg1 | ... | argN
*/
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
if (attr_o == NULL) JUMP_TO_ERROR(); if (attr_o == NULL) JUMP_TO_ERROR();
/* We need to define self_or_null on all paths */
self_or_null = PyStackRef_NULL; self_or_null = PyStackRef_NULL;
} }
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
stack_pointer[0] = self_or_null; if (oparg & 1) stack_pointer[0] = self_or_null;
stack_pointer += 1; stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
case _LOAD_ATTR: {
_PyStackRef owner;
_PyStackRef attr;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
stack_pointer = _PyFrame_GetStackPointer(frame);
PyStackRef_CLOSE(owner);
if (attr_o == NULL) JUMP_TO_ERROR();
attr = PyStackRef_FromPyObjectSteal(attr_o);
stack_pointer[-1] = attr;
break;
}
case _GUARD_TYPE_VERSION: { case _GUARD_TYPE_VERSION: {
_PyStackRef owner; _PyStackRef owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
@ -2699,9 +2704,11 @@
break; break;
} }
case _LOAD_ATTR_INSTANCE_VALUE: { case _LOAD_ATTR_INSTANCE_VALUE_0: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
(void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t offset = (uint16_t)CURRENT_OPERAND0(); uint16_t offset = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
@ -2722,11 +2729,48 @@
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
break; break;
} }
case _LOAD_ATTR_INSTANCE_VALUE_1: {
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
(void)null;
owner = stack_pointer[-1];
uint16_t offset = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
if (attr_o == NULL) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
#ifdef Py_GIL_DISABLED
if (!_Py_TryIncrefCompareStackRef(value_ptr, attr_o, &attr)) {
if (true) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
}
#else
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
stack_pointer[0] = null;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
/* _LOAD_ATTR_INSTANCE_VALUE is split on (oparg & 1) */
case _CHECK_ATTR_MODULE_PUSH_KEYS: { case _CHECK_ATTR_MODULE_PUSH_KEYS: {
_PyStackRef owner; _PyStackRef owner;
PyDictKeysObject *mod_keys; PyDictKeysObject *mod_keys;
@ -2755,6 +2799,8 @@
PyDictKeysObject *mod_keys; PyDictKeysObject *mod_keys;
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
mod_keys = (PyDictKeysObject *)stack_pointer[-1].bits; mod_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
owner = stack_pointer[-2]; owner = stack_pointer[-2];
uint16_t index = (uint16_t)CURRENT_OPERAND0(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
@ -2782,8 +2828,12 @@
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -2810,6 +2860,7 @@
PyDictObject *dict; PyDictObject *dict;
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
dict = (PyDictObject *)stack_pointer[-1].bits; dict = (PyDictObject *)stack_pointer[-1].bits;
owner = stack_pointer[-2]; owner = stack_pointer[-2];
@ -2832,7 +2883,7 @@
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
} }
} }
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) { if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
UNLOCK_OBJECT(dict); UNLOCK_OBJECT(dict);
stack_pointer += -1; stack_pointer += -1;
@ -2865,16 +2916,20 @@
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
UNLOCK_OBJECT(dict); UNLOCK_OBJECT(dict);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
stack_pointer[-2] = attr; stack_pointer[-2] = attr;
stack_pointer += -1; if (oparg & 1) stack_pointer[-1] = null;
stack_pointer += -1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
case _LOAD_ATTR_SLOT: { case _LOAD_ATTR_SLOT_0: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
(void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND0(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
@ -2894,11 +2949,47 @@
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
break; break;
} }
case _LOAD_ATTR_SLOT_1: {
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
(void)null;
owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **addr = (PyObject **)((char *)owner_o + index);
PyObject *attr_o = FT_ATOMIC_LOAD_PTR(*addr);
if (attr_o == NULL) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
#ifdef Py_GIL_DISABLED
int increfed = _Py_TryIncrefCompareStackRef(addr, attr_o, &attr);
if (!increfed) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
#else
attr = PyStackRef_FromPyObjectNew(attr_o);
#endif
STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
stack_pointer[0] = null;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
/* _LOAD_ATTR_SLOT is split on (oparg & 1) */
case _CHECK_ATTR_CLASS: { case _CHECK_ATTR_CLASS: {
_PyStackRef owner; _PyStackRef owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
@ -2916,24 +3007,50 @@
break; break;
} }
case _LOAD_ATTR_CLASS: { case _LOAD_ATTR_CLASS_0: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
(void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr); attr = PyStackRef_FromPyObjectNew(descr);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
break; break;
} }
case _LOAD_ATTR_CLASS_1: {
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
(void)null;
owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr;
stack_pointer[0] = null;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
break;
}
/* _LOAD_ATTR_CLASS is split on (oparg & 1) */
case _LOAD_ATTR_PROPERTY_FRAME: { case _LOAD_ATTR_PROPERTY_FRAME: {
_PyStackRef owner; _PyStackRef owner;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *fget = (PyObject *)CURRENT_OPERAND0(); PyObject *fget = (PyObject *)CURRENT_OPERAND0();
assert((oparg & 1) == 0);
assert(Py_IS_TYPE(fget, &PyFunction_Type)); assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget; PyFunctionObject *f = (PyFunctionObject *)fget;
PyCodeObject *code = (PyCodeObject *)f->func_code; PyCodeObject *code = (PyCodeObject *)f->func_code;
@ -3939,12 +4056,14 @@
break; break;
} }
case _LOAD_METHOD_WITH_VALUES: { case _LOAD_ATTR_METHOD_WITH_VALUES: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef self; _PyStackRef self = PyStackRef_NULL;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert(oparg & 1);
/* Cached method object */ /* Cached method object */
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -3958,12 +4077,14 @@
break; break;
} }
case _LOAD_METHOD_NO_DICT: { case _LOAD_ATTR_METHOD_NO_DICT: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef self; _PyStackRef self = PyStackRef_NULL;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert(oparg & 1);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -3980,8 +4101,10 @@
case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: { case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert((oparg & 1) == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
@ -3993,8 +4116,10 @@
case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: { case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert((oparg & 1) == 0);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -4018,12 +4143,14 @@
break; break;
} }
case _LOAD_METHOD_LAZY_DICT: { case _LOAD_ATTR_METHOD_LAZY_DICT: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef self; _PyStackRef self = PyStackRef_NULL;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND0(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert(oparg & 1);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
@ -5517,14 +5644,15 @@
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */ /* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */
case _MAKE_CALLARGS_A_TUPLE: { case _MAKE_CALLARGS_A_TUPLE: {
_PyStackRef kwargs_in; _PyStackRef kwargs_in = PyStackRef_NULL;
_PyStackRef callargs; _PyStackRef callargs;
_PyStackRef func; _PyStackRef func;
_PyStackRef tuple; _PyStackRef tuple;
_PyStackRef kwargs_out; _PyStackRef kwargs_out = PyStackRef_NULL;
kwargs_in = stack_pointer[-1]; oparg = CURRENT_OPARG();
callargs = stack_pointer[-2]; if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
func = stack_pointer[-4]; callargs = stack_pointer[-1 - (oparg & 1)];
func = stack_pointer[-3 - (oparg & 1)];
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs); PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
if (PyTuple_CheckExact(callargs_o)) { if (PyTuple_CheckExact(callargs_o)) {
tuple = callargs; tuple = callargs;
@ -5547,8 +5675,8 @@
PyStackRef_CLOSE(callargs); PyStackRef_CLOSE(callargs);
tuple = PyStackRef_FromPyObjectSteal(tuple_o); tuple = PyStackRef_FromPyObjectSteal(tuple_o);
} }
stack_pointer[-2] = tuple; stack_pointer[-1 - (oparg & 1)] = tuple;
stack_pointer[-1] = kwargs_out; if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
break; break;
} }
@ -5625,27 +5753,25 @@
} }
case _BUILD_SLICE: { case _BUILD_SLICE: {
_PyStackRef *args; _PyStackRef step = PyStackRef_NULL;
_PyStackRef stop;
_PyStackRef start;
_PyStackRef slice; _PyStackRef slice;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
assert(oparg == 2 || oparg == 3); stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
_PyStackRef start = args[0]; start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
_PyStackRef stop = args[1];
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
PyObject * step_o = NULL; PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
if (oparg == 3) {
step_o = PyStackRef_AsPyObjectBorrow(args[2]);
}
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o); PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(start);
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(stop);
} PyStackRef_XCLOSE(step);
if (slice_o == NULL) JUMP_TO_ERROR(); if (slice_o == NULL) JUMP_TO_ERROR();
slice = PyStackRef_FromPyObjectSteal(slice_o); slice = PyStackRef_FromPyObjectSteal(slice_o);
stack_pointer[-oparg] = slice; stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
stack_pointer += 1 - oparg; stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -6012,6 +6138,8 @@
case _LOAD_GLOBAL_MODULE: { case _LOAD_GLOBAL_MODULE: {
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
uint16_t index = (uint16_t)CURRENT_OPERAND0(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictObject *dict = (PyDictObject *)GLOBALS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
@ -6022,14 +6150,18 @@
} }
Py_INCREF(res_o); Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
null = PyStackRef_NULL;
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
case _LOAD_GLOBAL_BUILTINS: { case _LOAD_GLOBAL_BUILTINS: {
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
uint16_t index = (uint16_t)CURRENT_OPERAND0(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)BUILTINS(); PyDictObject *dict = (PyDictObject *)BUILTINS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
@ -6040,8 +6172,10 @@
} }
Py_INCREF(res_o); Py_INCREF(res_o);
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
null = PyStackRef_NULL;
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -6049,6 +6183,8 @@
case _LOAD_ATTR_MODULE: { case _LOAD_ATTR_MODULE: {
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND0(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
@ -6064,8 +6200,12 @@
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
Py_INCREF(attr_o); Py_INCREF(attr_o);
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }

View File

@ -1836,6 +1836,12 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
INSTR_SET_OP0(inst, NOP); INSTR_SET_OP0(inst, NOP);
} }
break; break;
case LOAD_GLOBAL:
if (nextop == PUSH_NULL && (oparg & 1) == 0) {
INSTR_SET_OP1(inst, LOAD_GLOBAL, oparg | 1);
INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
}
break;
case COMPARE_OP: case COMPARE_OP:
if (nextop == TO_BOOL) { if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP); INSTR_SET_OP0(inst, NOP);

View File

@ -833,30 +833,28 @@
frame->instr_ptr = next_instr; frame->instr_ptr = next_instr;
next_instr += 1; next_instr += 1;
INSTRUCTION_STATS(BUILD_SLICE); INSTRUCTION_STATS(BUILD_SLICE);
_PyStackRef *args; _PyStackRef start;
_PyStackRef stop;
_PyStackRef step = PyStackRef_NULL;
_PyStackRef slice; _PyStackRef slice;
args = &stack_pointer[-oparg]; if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
assert(oparg == 2 || oparg == 3); stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
_PyStackRef start = args[0]; start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
_PyStackRef stop = args[1];
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
PyObject * step_o = NULL; PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
if (oparg == 3) {
step_o = PyStackRef_AsPyObjectBorrow(args[2]);
}
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o); PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(start);
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(stop);
} PyStackRef_XCLOSE(step);
if (slice_o == NULL) { if (slice_o == NULL) {
stack_pointer += -oparg; stack_pointer += -2 - ((oparg == 3) ? 1 : 0);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
goto error; goto error;
} }
slice = PyStackRef_FromPyObjectSteal(slice_o); slice = PyStackRef_FromPyObjectSteal(slice_o);
stack_pointer[-oparg] = slice; stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
stack_pointer += 1 - oparg; stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -1708,18 +1706,18 @@
(void)this_instr; (void)this_instr;
_PyStackRef func; _PyStackRef func;
_PyStackRef callargs; _PyStackRef callargs;
_PyStackRef kwargs_in; _PyStackRef kwargs_in = PyStackRef_NULL;
_PyStackRef tuple; _PyStackRef tuple;
_PyStackRef kwargs_out; _PyStackRef kwargs_out = PyStackRef_NULL;
_PyStackRef func_st; _PyStackRef func_st;
_PyStackRef callargs_st; _PyStackRef callargs_st;
_PyStackRef kwargs_st; _PyStackRef kwargs_st = PyStackRef_NULL;
_PyStackRef result; _PyStackRef result;
// _MAKE_CALLARGS_A_TUPLE // _MAKE_CALLARGS_A_TUPLE
{ {
kwargs_in = stack_pointer[-1]; if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
callargs = stack_pointer[-2]; callargs = stack_pointer[-1 - (oparg & 1)];
func = stack_pointer[-4]; func = stack_pointer[-3 - (oparg & 1)];
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs); PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
if (PyTuple_CheckExact(callargs_o)) { if (PyTuple_CheckExact(callargs_o)) {
tuple = callargs; tuple = callargs;
@ -1761,8 +1759,8 @@
assert(PyTuple_CheckExact(callargs)); assert(PyTuple_CheckExact(callargs));
PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ? PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING; PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
stack_pointer[-2] = callargs_st; stack_pointer[-1 - (oparg & 1)] = callargs_st;
stack_pointer[-1] = kwargs_st; if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation_2args( int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL, tstate, PY_MONITORING_EVENT_CALL,
@ -1805,7 +1803,7 @@
Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags; int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func)); PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
stack_pointer += -3; stack_pointer += -2 - (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex( _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(
@ -1826,8 +1824,8 @@
assert(PyTuple_CheckExact(callargs)); assert(PyTuple_CheckExact(callargs));
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st); PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
assert(kwargs == NULL || PyDict_CheckExact(kwargs)); assert(kwargs == NULL || PyDict_CheckExact(kwargs));
stack_pointer[-2] = callargs_st; stack_pointer[-1 - (oparg & 1)] = callargs_st;
stack_pointer[-1] = kwargs_st; if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
result_o = PyObject_Call(func, callargs, kwargs); result_o = PyObject_Call(func, callargs, kwargs);
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
@ -1837,7 +1835,11 @@
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
PyStackRef_CLOSE(callargs_st); PyStackRef_CLOSE(callargs_st);
PyStackRef_CLOSE(func_st); PyStackRef_CLOSE(func_st);
if (result_o == NULL) goto pop_4_error; if (result_o == NULL) {
stack_pointer += -3 - (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
goto error;
}
result = PyStackRef_FromPyObjectSteal(result_o); result = PyStackRef_FromPyObjectSteal(result_o);
} }
// _CHECK_PERIODIC // _CHECK_PERIODIC
@ -1845,19 +1847,19 @@
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
QSBR_QUIESCENT_STATE(tstate); QSBR_QUIESCENT_STATE(tstate);
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
stack_pointer[-4] = result; stack_pointer[-3 - (oparg & 1)] = result;
stack_pointer += -3; stack_pointer += -2 - (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_HandlePending(tstate); int err = _Py_HandlePending(tstate);
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
if (err != 0) goto error; if (err != 0) goto error;
stack_pointer += 3; stack_pointer += 2 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
} }
} }
stack_pointer[-4] = result; stack_pointer[-3 - (oparg & 1)] = result;
stack_pointer += -3; stack_pointer += -2 - (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -4846,18 +4848,6 @@
goto PREDICTED_LOAD_SUPER_ATTR; goto PREDICTED_LOAD_SUPER_ATTR;
} }
TARGET(INSTRUMENTED_LOAD_SUPER_METHOD) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
(void)this_instr;
next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_LOAD_SUPER_METHOD);
/* Skip 1 cache entry */
// cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
// don't want to specialize instrumented instructions
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
goto PREDICTED_LOAD_SUPER_METHOD;
}
TARGET(INSTRUMENTED_NOT_TAKEN) { TARGET(INSTRUMENTED_NOT_TAKEN) {
_Py_CODEUNIT* const prev_instr = frame->instr_ptr; _Py_CODEUNIT* const prev_instr = frame->instr_ptr;
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr; _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
@ -5311,6 +5301,7 @@
(void)this_instr; (void)this_instr;
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef self_or_null = PyStackRef_NULL;
// _SPECIALIZE_LOAD_ATTR // _SPECIALIZE_LOAD_ATTR
{ {
owner = stack_pointer[-1]; owner = stack_pointer[-1];
@ -5318,7 +5309,7 @@
(void)counter; (void)counter;
#if ENABLE_SPECIALIZATION_FT #if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
next_instr = this_instr; next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadAttr(owner, next_instr, name); _Py_Specialize_LoadAttr(owner, next_instr, name);
@ -5332,15 +5323,50 @@
/* Skip 8 cache entries */ /* Skip 8 cache entries */
// _LOAD_ATTR // _LOAD_ATTR
{ {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
_PyFrame_SetStackPointer(frame, stack_pointer); PyObject *attr_o;
PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); if (oparg & 1) {
stack_pointer = _PyFrame_GetStackPointer(frame); /* Designed to work in tandem with CALL, pushes two values. */
PyStackRef_CLOSE(owner); attr_o = NULL;
if (attr_o == NULL) goto pop_1_error; _PyFrame_SetStackPointer(frame, stack_pointer);
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (is_meth) {
/* We can bypass temporary bound method object.
meth is unbound method and obj is self.
meth | self | arg1 | ... | argN
*/
assert(attr_o != NULL); // No errors on this branch
self_or_null = owner; // Transfer ownership
}
else {
/* meth is not an unbound method (but a regular attr, or
something was returned by a descriptor protocol). Set
the second element of the stack to NULL, to signal
CALL that it's not a method call.
meth | NULL | arg1 | ... | argN
*/
PyStackRef_CLOSE(owner);
if (attr_o == NULL) goto pop_1_error;
self_or_null = PyStackRef_NULL;
}
}
else {
/* Classic, pushes one value. */
_PyFrame_SetStackPointer(frame, stack_pointer);
attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
stack_pointer = _PyFrame_GetStackPointer(frame);
PyStackRef_CLOSE(owner);
if (attr_o == NULL) goto pop_1_error;
/* We need to define self_or_null on all paths */
self_or_null = PyStackRef_NULL;
}
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
} }
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = self_or_null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -5351,6 +5377,7 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _CHECK_ATTR_CLASS // _CHECK_ATTR_CLASS
{ {
@ -5368,9 +5395,13 @@
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr); attr = PyStackRef_FromPyObjectNew(descr);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
} }
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -5381,6 +5412,7 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _CHECK_ATTR_CLASS // _CHECK_ATTR_CLASS
{ {
@ -5404,9 +5436,13 @@
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr); attr = PyStackRef_FromPyObjectNew(descr);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
} }
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -5422,6 +5458,7 @@
uint32_t func_version = read_u32(&this_instr[4].cache); uint32_t func_version = read_u32(&this_instr[4].cache);
PyObject *getattribute = read_obj(&this_instr[6].cache); PyObject *getattribute = read_obj(&this_instr[6].cache);
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
assert((oparg & 1) == 0);
DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
PyTypeObject *cls = Py_TYPE(owner_o); PyTypeObject *cls = Py_TYPE(owner_o);
assert(type_version != 0); assert(type_version != 0);
@ -5434,7 +5471,7 @@
assert(code->co_argcount == 2); assert(code->co_argcount == 2);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked( _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(
tstate, PyStackRef_FromPyObjectNew(f), 2, frame); tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
// Manipulate stack directly because we exit with DISPATCH_INLINED(). // Manipulate stack directly because we exit with DISPATCH_INLINED().
@ -5452,6 +5489,7 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _GUARD_TYPE_VERSION // _GUARD_TYPE_VERSION
{ {
@ -5483,10 +5521,143 @@
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
} }
/* Skip 5 cache entries */ /* Skip 5 cache entries */
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_LAZY_DICT) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
next_instr += 10;
INSTRUCTION_STATS(LOAD_ATTR_METHOD_LAZY_DICT);
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef self = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
owner = stack_pointer[-1];
uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0);
DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_ATTR);
}
// _CHECK_ATTR_METHOD_LAZY_DICT
{
uint16_t dictoffset = read_u16(&this_instr[4].cache);
char *ptr = ((char *)PyStackRef_AsPyObjectBorrow(owner)) + MANAGED_DICT_OFFSET + dictoffset;
PyObject *dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*(PyObject **)ptr);
/* This object has a __dict__, just not yet created */
DEOPT_IF(dict != NULL, LOAD_ATTR);
}
/* Skip 1 cache entry */
// _LOAD_ATTR_METHOD_LAZY_DICT
{
PyObject *descr = read_obj(&this_instr[6].cache);
assert(oparg & 1);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
attr = PyStackRef_FromPyObjectNew(descr);
self = owner;
}
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_NO_DICT) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
next_instr += 10;
INSTRUCTION_STATS(LOAD_ATTR_METHOD_NO_DICT);
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef self = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
owner = stack_pointer[-1];
uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0);
DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_ATTR);
}
/* Skip 2 cache entries */
// _LOAD_ATTR_METHOD_NO_DICT
{
PyObject *descr = read_obj(&this_instr[6].cache);
assert(oparg & 1);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
attr = PyStackRef_FromPyObjectNew(descr);
self = owner;
}
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_WITH_VALUES) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
next_instr += 10;
INSTRUCTION_STATS(LOAD_ATTR_METHOD_WITH_VALUES);
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef self = PyStackRef_NULL;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
owner = stack_pointer[-1];
uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0);
DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_ATTR);
}
// _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT
{
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES);
PyDictValues *ivs = _PyObject_InlineValues(owner_o);
DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(ivs->valid), LOAD_ATTR);
}
// _GUARD_KEYS_VERSION
{
uint32_t keys_version = read_u32(&this_instr[4].cache);
PyTypeObject *owner_cls = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
PyDictKeysObject *keys = owner_heap_type->ht_cached_keys;
DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version, LOAD_ATTR);
}
// _LOAD_ATTR_METHOD_WITH_VALUES
{
PyObject *descr = read_obj(&this_instr[6].cache);
assert(oparg & 1);
/* Cached method object */
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
attr = PyStackRef_FromPyObjectNew(descr);
self = owner;
}
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -5498,6 +5669,7 @@
_PyStackRef owner; _PyStackRef owner;
PyDictKeysObject *mod_keys; PyDictKeysObject *mod_keys;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _CHECK_ATTR_MODULE_PUSH_KEYS // _CHECK_ATTR_MODULE_PUSH_KEYS
{ {
@ -5530,10 +5702,14 @@
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
} }
/* Skip 5 cache entries */ /* Skip 5 cache entries */
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -5557,6 +5733,7 @@
// _LOAD_ATTR_NONDESCRIPTOR_NO_DICT // _LOAD_ATTR_NONDESCRIPTOR_NO_DICT
{ {
PyObject *descr = read_obj(&this_instr[6].cache); PyObject *descr = read_obj(&this_instr[6].cache);
assert((oparg & 1) == 0);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -5601,6 +5778,7 @@
// _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES // _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES
{ {
PyObject *descr = read_obj(&this_instr[6].cache); PyObject *descr = read_obj(&this_instr[6].cache);
assert((oparg & 1) == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
@ -5634,6 +5812,7 @@
// _LOAD_ATTR_PROPERTY_FRAME // _LOAD_ATTR_PROPERTY_FRAME
{ {
PyObject *fget = read_obj(&this_instr[6].cache); PyObject *fget = read_obj(&this_instr[6].cache);
assert((oparg & 1) == 0);
assert(Py_IS_TYPE(fget, &PyFunction_Type)); assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget; PyFunctionObject *f = (PyFunctionObject *)fget;
PyCodeObject *code = (PyCodeObject *)f->func_code; PyCodeObject *code = (PyCodeObject *)f->func_code;
@ -5681,6 +5860,7 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner; _PyStackRef owner;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _GUARD_TYPE_VERSION // _GUARD_TYPE_VERSION
{ {
@ -5704,10 +5884,14 @@
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
#endif #endif
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
} }
/* Skip 5 cache entries */ /* Skip 5 cache entries */
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -5719,6 +5903,7 @@
_PyStackRef owner; _PyStackRef owner;
PyDictObject *dict; PyDictObject *dict;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _GUARD_TYPE_VERSION // _GUARD_TYPE_VERSION
{ {
@ -5748,7 +5933,7 @@
UNLOCK_OBJECT(dict); UNLOCK_OBJECT(dict);
DEOPT_IF(true, LOAD_ATTR); DEOPT_IF(true, LOAD_ATTR);
} }
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) { if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
UNLOCK_OBJECT(dict); UNLOCK_OBJECT(dict);
DEOPT_IF(true, LOAD_ATTR); DEOPT_IF(true, LOAD_ATTR);
@ -5766,10 +5951,14 @@
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
attr = PyStackRef_FromPyObjectNew(attr_o); attr = PyStackRef_FromPyObjectNew(attr_o);
UNLOCK_OBJECT(dict); UNLOCK_OBJECT(dict);
null = PyStackRef_NULL;
PyStackRef_CLOSE(owner); PyStackRef_CLOSE(owner);
} }
/* Skip 5 cache entries */ /* Skip 5 cache entries */
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -6070,13 +6259,14 @@
_Py_CODEUNIT* const this_instr = next_instr - 5; _Py_CODEUNIT* const this_instr = next_instr - 5;
(void)this_instr; (void)this_instr;
_PyStackRef *res; _PyStackRef *res;
_PyStackRef null = PyStackRef_NULL;
// _SPECIALIZE_LOAD_GLOBAL // _SPECIALIZE_LOAD_GLOBAL
{ {
uint16_t counter = read_u16(&this_instr[1].cache); uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter; (void)counter;
#if ENABLE_SPECIALIZATION_FT #if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
next_instr = this_instr; next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
@ -6093,13 +6283,15 @@
// _LOAD_GLOBAL // _LOAD_GLOBAL
{ {
res = &stack_pointer[0]; res = &stack_pointer[0];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
if (PyStackRef_IsNull(*res)) goto error; if (PyStackRef_IsNull(*res)) goto error;
null = PyStackRef_NULL;
} }
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -6111,6 +6303,7 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
PyDictKeysObject *builtins_keys; PyDictKeysObject *builtins_keys;
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _GUARD_GLOBALS_VERSION // _GUARD_GLOBALS_VERSION
{ {
@ -6145,9 +6338,11 @@
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
#endif #endif
STAT_INC(LOAD_GLOBAL, hit); STAT_INC(LOAD_GLOBAL, hit);
null = PyStackRef_NULL;
} }
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -6159,6 +6354,7 @@
static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
PyDictKeysObject *globals_keys; PyDictKeysObject *globals_keys;
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
// _GUARD_GLOBALS_VERSION_PUSH_KEYS // _GUARD_GLOBALS_VERSION_PUSH_KEYS
{ {
@ -6185,9 +6381,11 @@
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
#endif #endif
STAT_INC(LOAD_GLOBAL, hit); STAT_INC(LOAD_GLOBAL, hit);
null = PyStackRef_NULL;
} }
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -6212,198 +6410,6 @@
DISPATCH(); DISPATCH();
} }
TARGET(LOAD_METHOD) {
frame->instr_ptr = next_instr;
next_instr += 10;
INSTRUCTION_STATS(LOAD_METHOD);
PREDICTED_LOAD_METHOD:;
_Py_CODEUNIT* const this_instr = next_instr - 10;
(void)this_instr;
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef self_or_null;
// _SPECIALIZE_LOAD_METHOD
{
owner = stack_pointer[-1];
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadMethod(owner, next_instr, name);
stack_pointer = _PyFrame_GetStackPointer(frame);
DISPATCH_SAME_OPARG();
}
OPCODE_DEFERRED_INC(LOAD_METHOD);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
#endif /* ENABLE_SPECIALIZATION_FT */
}
/* Skip 8 cache entries */
// _LOAD_METHOD
{
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *attr_o;
/* Designed to work in tandem with CALL, pushes two values. */
attr_o = NULL;
_PyFrame_SetStackPointer(frame, stack_pointer);
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (is_meth) {
/* We can bypass temporary bound method object.
meth is unbound method and obj is self.
meth | self | arg1 | ... | argN
*/
assert(attr_o != NULL); // No errors on this branch
self_or_null = owner; // Transfer ownership
}
else {
/* meth is not an unbound method (but a regular attr, or
something was returned by a descriptor protocol). Set
the second element of the stack to NULL, to signal
CALL that it's not a method call.
meth | NULL | arg1 | ... | argN
*/
PyStackRef_CLOSE(owner);
if (attr_o == NULL) goto pop_1_error;
self_or_null = PyStackRef_NULL;
}
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
stack_pointer[-1] = attr;
stack_pointer[0] = self_or_null;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_METHOD_LAZY_DICT) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
next_instr += 10;
INSTRUCTION_STATS(LOAD_METHOD_LAZY_DICT);
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef self;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
owner = stack_pointer[-1];
uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0);
DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_METHOD);
}
// _CHECK_ATTR_METHOD_LAZY_DICT
{
uint16_t dictoffset = read_u16(&this_instr[4].cache);
char *ptr = ((char *)PyStackRef_AsPyObjectBorrow(owner)) + MANAGED_DICT_OFFSET + dictoffset;
PyObject *dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*(PyObject **)ptr);
/* This object has a __dict__, just not yet created */
DEOPT_IF(dict != NULL, LOAD_METHOD);
}
/* Skip 1 cache entry */
// _LOAD_METHOD_LAZY_DICT
{
PyObject *descr = read_obj(&this_instr[6].cache);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
attr = PyStackRef_FromPyObjectNew(descr);
self = owner;
}
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_METHOD_NO_DICT) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
next_instr += 10;
INSTRUCTION_STATS(LOAD_METHOD_NO_DICT);
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef self;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
owner = stack_pointer[-1];
uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0);
DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_METHOD);
}
/* Skip 2 cache entries */
// _LOAD_METHOD_NO_DICT
{
PyObject *descr = read_obj(&this_instr[6].cache);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
attr = PyStackRef_FromPyObjectNew(descr);
self = owner;
}
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_METHOD_WITH_VALUES) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
next_instr += 10;
INSTRUCTION_STATS(LOAD_METHOD_WITH_VALUES);
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
_PyStackRef owner;
_PyStackRef attr;
_PyStackRef self;
/* Skip 1 cache entry */
// _GUARD_TYPE_VERSION
{
owner = stack_pointer[-1];
uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0);
DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version, LOAD_METHOD);
}
// _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT
{
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES);
PyDictValues *ivs = _PyObject_InlineValues(owner_o);
DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(ivs->valid), LOAD_METHOD);
}
// _GUARD_KEYS_VERSION
{
uint32_t keys_version = read_u32(&this_instr[4].cache);
PyTypeObject *owner_cls = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
PyDictKeysObject *keys = owner_heap_type->ht_cached_keys;
DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version, LOAD_METHOD);
}
// _LOAD_METHOD_WITH_VALUES
{
PyObject *descr = read_obj(&this_instr[6].cache);
/* Cached method object */
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
attr = PyStackRef_FromPyObjectNew(descr);
self = owner;
}
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_NAME) { TARGET(LOAD_NAME) {
frame->instr_ptr = next_instr; frame->instr_ptr = next_instr;
next_instr += 1; next_instr += 1;
@ -6483,6 +6489,7 @@
_PyStackRef class_st; _PyStackRef class_st;
_PyStackRef self_st; _PyStackRef self_st;
_PyStackRef attr; _PyStackRef attr;
_PyStackRef null = PyStackRef_NULL;
// _SPECIALIZE_LOAD_SUPER_ATTR // _SPECIALIZE_LOAD_SUPER_ATTR
{ {
class_st = stack_pointer[-2]; class_st = stack_pointer[-2];
@ -6490,10 +6497,11 @@
uint16_t counter = read_u16(&this_instr[1].cache); uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter; (void)counter;
#if ENABLE_SPECIALIZATION_FT #if ENABLE_SPECIALIZATION_FT
int load_method = oparg & 1;
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr; next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 0); _Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, load_method);
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
DISPATCH_SAME_OPARG(); DISPATCH_SAME_OPARG();
} }
@ -6507,7 +6515,7 @@
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st); PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st); PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st); PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
if (opcode >= MIN_INSTRUMENTED_OPCODE) { if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation_2args( int err = _Py_call_instrumentation_2args(
@ -6527,7 +6535,7 @@
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
if (opcode >= MIN_INSTRUMENTED_OPCODE) { if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) { if (super == NULL) {
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
@ -6560,9 +6568,11 @@
stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer = _PyFrame_GetStackPointer(frame);
if (attr_o == NULL) goto error; if (attr_o == NULL) goto error;
attr = PyStackRef_FromPyObjectSteal(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o);
null = PyStackRef_NULL;
} }
stack_pointer[0] = attr; stack_pointer[0] = attr;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();
} }
@ -6602,111 +6612,10 @@
DISPATCH(); DISPATCH();
} }
TARGET(LOAD_SUPER_METHOD) { TARGET(LOAD_SUPER_ATTR_METHOD) {
frame->instr_ptr = next_instr; frame->instr_ptr = next_instr;
next_instr += 2; next_instr += 2;
INSTRUCTION_STATS(LOAD_SUPER_METHOD); INSTRUCTION_STATS(LOAD_SUPER_ATTR_METHOD);
PREDICTED_LOAD_SUPER_METHOD:;
_Py_CODEUNIT* const this_instr = next_instr - 2;
(void)this_instr;
_PyStackRef global_super_st;
_PyStackRef class_st;
_PyStackRef self_st;
_PyStackRef attr;
_PyStackRef null;
// _SPECIALIZE_LOAD_SUPER_METHOD
{
class_st = stack_pointer[-2];
global_super_st = stack_pointer[-3];
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, 1);
stack_pointer = _PyFrame_GetStackPointer(frame);
DISPATCH_SAME_OPARG();
}
OPCODE_DEFERRED_INC(LOAD_SUPER_METHOD);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
#endif /* ENABLE_SPECIALIZATION_FT */
}
// _LOAD_SUPER_ATTR
{
self_st = stack_pointer[-1];
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
if (opcode >= MIN_INSTRUMENTED_OPCODE) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
frame, this_instr, global_super, arg);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err) {
PyStackRef_CLOSE(global_super_st);
PyStackRef_CLOSE(class_st);
PyStackRef_CLOSE(self_st);
goto pop_3_error;
}
}
// we make no attempt to optimize here; specializations should
// handle any case whose performance we care about
PyObject *stack[] = {class, self};
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (opcode >= MIN_INSTRUMENTED_OPCODE) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
if (super == NULL) {
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
frame, this_instr, global_super, arg);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
else {
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
frame, this_instr, global_super, arg);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
Py_CLEAR(super);
}
}
}
PyStackRef_CLOSE(global_super_st);
PyStackRef_CLOSE(class_st);
PyStackRef_CLOSE(self_st);
if (super == NULL) goto pop_3_error;
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
stack_pointer += -3;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *attr_o = PyObject_GetAttr(super, name);
Py_DECREF(super);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (attr_o == NULL) goto error;
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
// _PUSH_NULL
{
null = PyStackRef_NULL;
}
stack_pointer[0] = attr;
stack_pointer[1] = null;
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
TARGET(LOAD_SUPER_METHOD_METHOD) {
frame->instr_ptr = next_instr;
next_instr += 2;
INSTRUCTION_STATS(LOAD_SUPER_METHOD_METHOD);
static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size");
_PyStackRef global_super_st; _PyStackRef global_super_st;
_PyStackRef class_st; _PyStackRef class_st;
@ -6721,8 +6630,8 @@
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st); PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st); PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
assert(oparg & 1); assert(oparg & 1);
DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_METHOD); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
DEOPT_IF(!PyType_Check(class), LOAD_SUPER_METHOD); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
STAT_INC(LOAD_SUPER_ATTR, hit); STAT_INC(LOAD_SUPER_ATTR, hit);
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
PyTypeObject *cls = (PyTypeObject *)class; PyTypeObject *cls = (PyTypeObject *)class;
@ -7087,9 +6996,9 @@
frame->instr_ptr = next_instr; frame->instr_ptr = next_instr;
next_instr += 1; next_instr += 1;
INSTRUCTION_STATS(PUSH_NULL); INSTRUCTION_STATS(PUSH_NULL);
_PyStackRef null; _PyStackRef res;
null = PyStackRef_NULL; res = PyStackRef_NULL;
stack_pointer[0] = null; stack_pointer[0] = res;
stack_pointer += 1; stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
DISPATCH(); DISPATCH();

View File

@ -81,8 +81,6 @@ static const int8_t EVENT_FOR_OPCODE[256] = {
[INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL, [INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL,
[LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL, [LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL,
[INSTRUMENTED_LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL, [INSTRUMENTED_LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL,
[LOAD_SUPER_METHOD] = PY_MONITORING_EVENT_CALL,
[INSTRUMENTED_LOAD_SUPER_METHOD] = PY_MONITORING_EVENT_CALL,
[RESUME] = -1, [RESUME] = -1,
[YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD, [YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD,
[INSTRUMENTED_YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD, [INSTRUMENTED_YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD,
@ -128,7 +126,6 @@ static const uint8_t DE_INSTRUMENT[256] = {
[INSTRUMENTED_END_FOR] = END_FOR, [INSTRUMENTED_END_FOR] = END_FOR,
[INSTRUMENTED_END_SEND] = END_SEND, [INSTRUMENTED_END_SEND] = END_SEND,
[INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR, [INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
[INSTRUMENTED_LOAD_SUPER_METHOD] = LOAD_SUPER_METHOD,
[INSTRUMENTED_NOT_TAKEN] = NOT_TAKEN, [INSTRUMENTED_NOT_TAKEN] = NOT_TAKEN,
}; };
@ -167,8 +164,6 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
[INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER, [INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
[LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, [LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[LOAD_SUPER_METHOD] = INSTRUMENTED_LOAD_SUPER_METHOD,
[INSTRUMENTED_LOAD_SUPER_METHOD] = INSTRUMENTED_LOAD_SUPER_METHOD,
[NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN, [NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
[INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN, [INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,

View File

@ -3,7 +3,6 @@ static void *opcode_targets[256] = {
&&TARGET_BINARY_SLICE, &&TARGET_BINARY_SLICE,
&&TARGET_BINARY_SUBSCR, &&TARGET_BINARY_SUBSCR,
&&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE,
&&TARGET_CALL_FUNCTION_EX,
&&TARGET_CHECK_EG_MATCH, &&TARGET_CHECK_EG_MATCH,
&&TARGET_CHECK_EXC_MATCH, &&TARGET_CHECK_EXC_MATCH,
&&TARGET_CLEANUP_THROW, &&TARGET_CLEANUP_THROW,
@ -16,8 +15,8 @@ static void *opcode_targets[256] = {
&&TARGET_FORMAT_WITH_SPEC, &&TARGET_FORMAT_WITH_SPEC,
&&TARGET_GET_AITER, &&TARGET_GET_AITER,
&&TARGET_GET_ANEXT, &&TARGET_GET_ANEXT,
&&TARGET_RESERVED,
&&TARGET_GET_ITER, &&TARGET_GET_ITER,
&&TARGET_RESERVED,
&&TARGET_GET_LEN, &&TARGET_GET_LEN,
&&TARGET_GET_YIELD_FROM_ITER, &&TARGET_GET_YIELD_FROM_ITER,
&&TARGET_INTERPRETER_EXIT, &&TARGET_INTERPRETER_EXIT,
@ -52,6 +51,7 @@ static void *opcode_targets[256] = {
&&TARGET_BUILD_STRING, &&TARGET_BUILD_STRING,
&&TARGET_BUILD_TUPLE, &&TARGET_BUILD_TUPLE,
&&TARGET_CALL, &&TARGET_CALL,
&&TARGET_CALL_FUNCTION_EX,
&&TARGET_CALL_INTRINSIC_1, &&TARGET_CALL_INTRINSIC_1,
&&TARGET_CALL_INTRINSIC_2, &&TARGET_CALL_INTRINSIC_2,
&&TARGET_CALL_KW, &&TARGET_CALL_KW,
@ -89,12 +89,10 @@ static void *opcode_targets[256] = {
&&TARGET_LOAD_FROM_DICT_OR_DEREF, &&TARGET_LOAD_FROM_DICT_OR_DEREF,
&&TARGET_LOAD_FROM_DICT_OR_GLOBALS, &&TARGET_LOAD_FROM_DICT_OR_GLOBALS,
&&TARGET_LOAD_GLOBAL, &&TARGET_LOAD_GLOBAL,
&&TARGET_LOAD_METHOD,
&&TARGET_LOAD_NAME, &&TARGET_LOAD_NAME,
&&TARGET_LOAD_SMALL_INT, &&TARGET_LOAD_SMALL_INT,
&&TARGET_LOAD_SPECIAL, &&TARGET_LOAD_SPECIAL,
&&TARGET_LOAD_SUPER_ATTR, &&TARGET_LOAD_SUPER_ATTR,
&&TARGET_LOAD_SUPER_METHOD,
&&TARGET_MAKE_CELL, &&TARGET_MAKE_CELL,
&&TARGET_MAP_ADD, &&TARGET_MAP_ADD,
&&TARGET_MATCH_CLASS, &&TARGET_MATCH_CLASS,
@ -148,6 +146,8 @@ static void *opcode_targets[256] = {
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
&&TARGET_RESUME, &&TARGET_RESUME,
&&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_FLOAT,
&&TARGET_BINARY_OP_ADD_INT, &&TARGET_BINARY_OP_ADD_INT,
@ -198,6 +198,9 @@ static void *opcode_targets[256] = {
&&TARGET_LOAD_ATTR_CLASS_WITH_METACLASS_CHECK, &&TARGET_LOAD_ATTR_CLASS_WITH_METACLASS_CHECK,
&&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
&&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_INSTANCE_VALUE,
&&TARGET_LOAD_ATTR_METHOD_LAZY_DICT,
&&TARGET_LOAD_ATTR_METHOD_NO_DICT,
&&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
&&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_MODULE,
&&TARGET_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, &&TARGET_LOAD_ATTR_NONDESCRIPTOR_NO_DICT,
&&TARGET_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, &&TARGET_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES,
@ -208,11 +211,8 @@ static void *opcode_targets[256] = {
&&TARGET_LOAD_CONST_MORTAL, &&TARGET_LOAD_CONST_MORTAL,
&&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_GLOBAL_BUILTIN,
&&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_GLOBAL_MODULE,
&&TARGET_LOAD_METHOD_LAZY_DICT,
&&TARGET_LOAD_METHOD_NO_DICT,
&&TARGET_LOAD_METHOD_WITH_VALUES,
&&TARGET_LOAD_SUPER_ATTR_ATTR, &&TARGET_LOAD_SUPER_ATTR_ATTR,
&&TARGET_LOAD_SUPER_METHOD_METHOD, &&TARGET_LOAD_SUPER_ATTR_METHOD,
&&TARGET_RESUME_CHECK, &&TARGET_RESUME_CHECK,
&&TARGET_SEND_GEN, &&TARGET_SEND_GEN,
&&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_INSTANCE_VALUE,
@ -233,11 +233,11 @@ static void *opcode_targets[256] = {
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode,
&&TARGET_INSTRUMENTED_END_FOR, &&TARGET_INSTRUMENTED_END_FOR,
&&TARGET_INSTRUMENTED_POP_ITER, &&TARGET_INSTRUMENTED_POP_ITER,
&&TARGET_INSTRUMENTED_END_SEND, &&TARGET_INSTRUMENTED_END_SEND,
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR, &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
&&TARGET_INSTRUMENTED_LOAD_SUPER_METHOD,
&&TARGET_INSTRUMENTED_FOR_ITER, &&TARGET_INSTRUMENTED_FOR_ITER,
&&TARGET_INSTRUMENTED_CALL_KW, &&TARGET_INSTRUMENTED_CALL_KW,
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX, &&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,

View File

@ -1274,7 +1274,10 @@ uop_optimize(
for (int pc = 0; pc < length; pc++) { for (int pc = 0; pc < length; pc++) {
int opcode = buffer[pc].opcode; int opcode = buffer[pc].opcode;
int oparg = buffer[pc].oparg; int oparg = buffer[pc].oparg;
if (oparg < _PyUop_Replication[opcode]) { if (_PyUop_Flags[opcode] & HAS_OPARG_AND_1_FLAG) {
buffer[pc].opcode = opcode + 1 + (oparg & 1);
}
else if (oparg < _PyUop_Replication[opcode]) {
buffer[pc].opcode = opcode + oparg + 1; buffer[pc].opcode = opcode + oparg + 1;
} }
else if (is_terminator(&buffer[pc])) { else if (is_terminator(&buffer[pc])) {

View File

@ -109,10 +109,10 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj)
return NULL; return NULL;
} }
if (_Py_IsImmortal(res)) { if (_Py_IsImmortal(res)) {
inst->opcode = _LOAD_CONST_INLINE_BORROW; inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_BORROW_WITH_NULL : _LOAD_CONST_INLINE_BORROW;
} }
else { else {
inst->opcode = _LOAD_CONST_INLINE; inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_WITH_NULL : _LOAD_CONST_INLINE;
} }
inst->operand0 = (uint64_t)res; inst->operand0 = (uint64_t)res;
return res; return res;

View File

@ -528,8 +528,9 @@ dummy_func(void) {
top_out = top_in; top_out = top_in;
} }
op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) { op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr, null if (oparg & 1))) {
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)offset; (void)offset;
(void)owner; (void)owner;
} }
@ -552,19 +553,15 @@ dummy_func(void) {
} }
} }
op(_LOAD_ATTR, (owner -- attr)) { op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
(void)owner;
attr = sym_new_not_null(ctx);
}
op(_LOAD_METHOD, (owner -- attr, self_or_null)) {
(void)owner; (void)owner;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self_or_null = sym_new_unknown(ctx); self_or_null = sym_new_unknown(ctx);
} }
op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys -- attr)) { op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys -- attr, null if (oparg & 1))) {
(void)index; (void)index;
null = sym_new_null(ctx);
attr = NULL; attr = NULL;
if (this_instr[-1].opcode == _NOP) { if (this_instr[-1].opcode == _NOP) {
// Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched. // Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
@ -592,38 +589,41 @@ dummy_func(void) {
(void)owner; (void)owner;
} }
op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict -- attr)) { op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict -- attr, null if (oparg & 1))) {
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)hint; (void)hint;
(void)owner; (void)owner;
(void)dict; (void)dict;
} }
op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) { op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) {
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)index; (void)index;
(void)owner; (void)owner;
} }
op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) { op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) {
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)descr; (void)descr;
(void)owner; (void)owner;
} }
op(_LOAD_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) { op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) {
(void)descr; (void)descr;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self = owner; self = owner;
} }
op(_LOAD_METHOD_NO_DICT, (descr/4, owner -- attr, self)) { op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) {
(void)descr; (void)descr;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self = owner; self = owner;
} }
op(_LOAD_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) { op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) {
(void)descr; (void)descr;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self = owner; self = owner;
@ -819,7 +819,7 @@ dummy_func(void) {
Py_UNREACHABLE(); Py_UNREACHABLE();
} }
op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- )) { op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- unused if (0))) {
SYNC_SP(); SYNC_SP();
ctx->frame->stack_pointer = stack_pointer; ctx->frame->stack_pointer = stack_pointer;
ctx->frame = new_frame; ctx->frame = new_frame;

View File

@ -928,9 +928,12 @@
case _LOAD_GLOBAL: { case _LOAD_GLOBAL: {
JitOptSymbol **res; JitOptSymbol **res;
JitOptSymbol *null = NULL;
res = &stack_pointer[0]; res = &stack_pointer[0];
res[0] = sym_new_not_null(ctx); res[0] = sym_new_not_null(ctx);
stack_pointer += 1; null = sym_new_null(ctx);
if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -963,15 +966,25 @@
case _LOAD_GLOBAL_MODULE_FROM_KEYS: { case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
JitOptSymbol *res; JitOptSymbol *res;
JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx); res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[-1] = res; stack_pointer[-1] = res;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }
case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: { case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
JitOptSymbol *res; JitOptSymbol *res;
JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx); res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[-1] = res; stack_pointer[-1] = res;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -1096,8 +1109,6 @@
/* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 */ /* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 */
/* _INSTRUMENTED_LOAD_SUPER_METHOD is not a viable micro-op for tier 2 */
case _LOAD_SUPER_ATTR_ATTR: { case _LOAD_SUPER_ATTR_ATTR: {
JitOptSymbol *attr_st; JitOptSymbol *attr_st;
attr_st = sym_new_not_null(ctx); attr_st = sym_new_not_null(ctx);
@ -1107,7 +1118,7 @@
break; break;
} }
case _LOAD_SUPER_METHOD_METHOD: { case _LOAD_SUPER_ATTR_METHOD: {
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *self_or_null; JitOptSymbol *self_or_null;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
@ -1119,31 +1130,21 @@
break; break;
} }
case _LOAD_METHOD: { case _LOAD_ATTR: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *self_or_null; JitOptSymbol *self_or_null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
(void)owner; (void)owner;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self_or_null = sym_new_unknown(ctx); self_or_null = sym_new_unknown(ctx);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
stack_pointer[0] = self_or_null; if (oparg & 1) stack_pointer[0] = self_or_null;
stack_pointer += 1; stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
case _LOAD_ATTR: {
JitOptSymbol *owner;
JitOptSymbol *attr;
owner = stack_pointer[-1];
(void)owner;
attr = sym_new_not_null(ctx);
stack_pointer[-1] = attr;
break;
}
case _GUARD_TYPE_VERSION: { case _GUARD_TYPE_VERSION: {
JitOptSymbol *owner; JitOptSymbol *owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
@ -1181,12 +1182,17 @@
case _LOAD_ATTR_INSTANCE_VALUE: { case _LOAD_ATTR_INSTANCE_VALUE: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t offset = (uint16_t)this_instr->operand0; uint16_t offset = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)offset; (void)offset;
(void)owner; (void)owner;
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -1224,9 +1230,11 @@
case _LOAD_ATTR_MODULE_FROM_KEYS: { case _LOAD_ATTR_MODULE_FROM_KEYS: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *null = NULL;
owner = stack_pointer[-2]; owner = stack_pointer[-2];
uint16_t index = (uint16_t)this_instr->operand0; uint16_t index = (uint16_t)this_instr->operand0;
(void)index; (void)index;
null = sym_new_null(ctx);
attr = NULL; attr = NULL;
if (this_instr[-1].opcode == _NOP) { if (this_instr[-1].opcode == _NOP) {
// Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched. // Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
@ -1235,7 +1243,8 @@
assert(PyModule_CheckExact(mod)); assert(PyModule_CheckExact(mod));
PyObject *dict = mod->md_dict; PyObject *dict = mod->md_dict;
stack_pointer[-2] = attr; stack_pointer[-2] = attr;
stack_pointer += -1; if (oparg & 1) stack_pointer[-1] = null;
stack_pointer += -1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
PyObject *res = convert_global_to_const(this_instr, dict); PyObject *res = convert_global_to_const(this_instr, dict);
if (res != NULL) { if (res != NULL) {
@ -1245,7 +1254,7 @@
else { else {
this_instr->opcode = _LOAD_ATTR_MODULE; this_instr->opcode = _LOAD_ATTR_MODULE;
} }
stack_pointer += 1; stack_pointer += 1 - (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
} }
if (attr == NULL) { if (attr == NULL) {
@ -1253,7 +1262,8 @@
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
} }
stack_pointer[-2] = attr; stack_pointer[-2] = attr;
stack_pointer += -1; if (oparg & 1) stack_pointer[-1] = null;
stack_pointer += -1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -1274,15 +1284,18 @@
JitOptSymbol *dict; JitOptSymbol *dict;
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *null = NULL;
dict = stack_pointer[-1]; dict = stack_pointer[-1];
owner = stack_pointer[-2]; owner = stack_pointer[-2];
uint16_t hint = (uint16_t)this_instr->operand0; uint16_t hint = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)hint; (void)hint;
(void)owner; (void)owner;
(void)dict; (void)dict;
stack_pointer[-2] = attr; stack_pointer[-2] = attr;
stack_pointer += -1; if (oparg & 1) stack_pointer[-1] = null;
stack_pointer += -1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -1290,12 +1303,17 @@
case _LOAD_ATTR_SLOT: { case _LOAD_ATTR_SLOT: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)this_instr->operand0; uint16_t index = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)index; (void)index;
(void)owner; (void)owner;
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -1306,12 +1324,17 @@
case _LOAD_ATTR_CLASS: { case _LOAD_ATTR_CLASS: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0; PyObject *descr = (PyObject *)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
(void)descr; (void)descr;
(void)owner; (void)owner;
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -1697,10 +1720,10 @@
break; break;
} }
case _LOAD_METHOD_WITH_VALUES: { case _LOAD_ATTR_METHOD_WITH_VALUES: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *self; JitOptSymbol *self = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0; PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr; (void)descr;
@ -1713,10 +1736,10 @@
break; break;
} }
case _LOAD_METHOD_NO_DICT: { case _LOAD_ATTR_METHOD_NO_DICT: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *self; JitOptSymbol *self = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0; PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr; (void)descr;
@ -1747,10 +1770,10 @@
break; break;
} }
case _LOAD_METHOD_LAZY_DICT: { case _LOAD_ATTR_METHOD_LAZY_DICT: {
JitOptSymbol *owner; JitOptSymbol *owner;
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *self; JitOptSymbol *self = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand0; PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr; (void)descr;
@ -2239,11 +2262,11 @@
case _MAKE_CALLARGS_A_TUPLE: { case _MAKE_CALLARGS_A_TUPLE: {
JitOptSymbol *tuple; JitOptSymbol *tuple;
JitOptSymbol *kwargs_out; JitOptSymbol *kwargs_out = NULL;
tuple = sym_new_not_null(ctx); tuple = sym_new_not_null(ctx);
kwargs_out = sym_new_not_null(ctx); kwargs_out = sym_new_not_null(ctx);
stack_pointer[-2] = tuple; stack_pointer[-1 - (oparg & 1)] = tuple;
stack_pointer[-1] = kwargs_out; if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
break; break;
} }
@ -2292,8 +2315,8 @@
case _BUILD_SLICE: { case _BUILD_SLICE: {
JitOptSymbol *slice; JitOptSymbol *slice;
slice = sym_new_not_null(ctx); slice = sym_new_not_null(ctx);
stack_pointer[-oparg] = slice; stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
stack_pointer += 1 - oparg; stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
@ -2616,26 +2639,37 @@
case _LOAD_GLOBAL_MODULE: { case _LOAD_GLOBAL_MODULE: {
JitOptSymbol *res; JitOptSymbol *res;
JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx); res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
case _LOAD_GLOBAL_BUILTINS: { case _LOAD_GLOBAL_BUILTINS: {
JitOptSymbol *res; JitOptSymbol *res;
JitOptSymbol *null = NULL;
res = sym_new_not_null(ctx); res = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[0] = res; stack_pointer[0] = res;
stack_pointer += 1; if (oparg & 1) stack_pointer[1] = null;
stack_pointer += 1 + (oparg & 1);
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
} }
case _LOAD_ATTR_MODULE: { case _LOAD_ATTR_MODULE: {
JitOptSymbol *attr; JitOptSymbol *attr;
JitOptSymbol *null = NULL;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx);
stack_pointer[-1] = attr; stack_pointer[-1] = attr;
if (oparg & 1) stack_pointer[0] = null;
stack_pointer += (oparg & 1);
assert(WITHIN_STACK_BOUNDS());
break; break;
} }

View File

@ -804,7 +804,7 @@ _Py_Specialize_LoadSuperAttr(_PyStackRef global_super_st, _PyStackRef cls_st, _P
SPECIALIZATION_FAIL(LOAD_SUPER_ATTR, SPEC_FAIL_SUPER_BAD_CLASS); SPECIALIZATION_FAIL(LOAD_SUPER_ATTR, SPEC_FAIL_SUPER_BAD_CLASS);
goto fail; goto fail;
} }
uint8_t load_code = load_method ? LOAD_SUPER_METHOD_METHOD : LOAD_SUPER_ATTR_ATTR; uint8_t load_code = load_method ? LOAD_SUPER_ATTR_METHOD : LOAD_SUPER_ATTR_ATTR;
specialize(instr, load_code); specialize(instr, load_code);
return; return;
fail: fail:
@ -1109,7 +1109,7 @@ instance_has_key(PyObject *obj, PyObject *name, uint32_t *shared_keys_version)
static int static int
do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name, do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name,
bool shadow, uint32_t shared_keys_version, bool shadow, uint32_t shared_keys_version,
DescriptorClassification kind, PyObject *descr, unsigned int tp_version, bool load_method) DescriptorClassification kind, PyObject *descr, unsigned int tp_version)
{ {
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1); _PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
PyTypeObject *type = Py_TYPE(owner); PyTypeObject *type = Py_TYPE(owner);
@ -1117,16 +1117,17 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
return -1; return -1;
} }
uint8_t oparg = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.arg);
switch(kind) { switch(kind) {
case OVERRIDING: case OVERRIDING:
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
return -1; return -1;
case METHOD: case METHOD:
{ {
if (shadow) { if (shadow) {
goto try_instance; goto try_instance;
} }
if (load_method) { if (oparg & 1) {
if (specialize_attr_loadclassattr(owner, instr, name, descr, if (specialize_attr_loadclassattr(owner, instr, name, descr,
tp_version, kind, true, tp_version, kind, true,
shared_keys_version)) { shared_keys_version)) {
@ -1136,7 +1137,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
return -1; return -1;
} }
} }
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
return -1; return -1;
} }
case PROPERTY: case PROPERTY:
@ -1145,28 +1146,28 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
assert(Py_TYPE(descr) == &PyProperty_Type); assert(Py_TYPE(descr) == &PyProperty_Type);
PyObject *fget = ((_PyPropertyObject *)descr)->prop_get; PyObject *fget = ((_PyPropertyObject *)descr)->prop_get;
if (fget == NULL) { if (fget == NULL) {
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
return -1; return -1;
} }
if (!Py_IS_TYPE(fget, &PyFunction_Type)) { if (!Py_IS_TYPE(fget, &PyFunction_Type)) {
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION);
return -1;
}
if (load_method) {
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_ATTR_METHOD);
return -1; return -1;
} }
if (!function_check_args(fget, 1, LOAD_ATTR)) { if (!function_check_args(fget, 1, LOAD_ATTR)) {
return -1; return -1;
} }
if (oparg & 1) {
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
return -1;
}
/* Don't specialize if PEP 523 is active */ /* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) { if (_PyInterpreterState_GET()->eval_frame) {
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OTHER); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
return -1; return -1;
} }
#ifdef Py_GIL_DISABLED #ifdef Py_GIL_DISABLED
if (!_PyObject_HasDeferredRefcount(fget)) { if (!_PyObject_HasDeferredRefcount(fget)) {
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
return -1; return -1;
} }
#endif #endif
@ -1179,10 +1180,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
} }
case OBJECT_SLOT: case OBJECT_SLOT:
{ {
if (load_method) {
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
return -1;
}
PyMemberDescrObject *member = (PyMemberDescrObject *)descr; PyMemberDescrObject *member = (PyMemberDescrObject *)descr;
struct PyMemberDef *dmem = member->d_member; struct PyMemberDef *dmem = member->d_member;
Py_ssize_t offset = dmem->offset; Py_ssize_t offset = dmem->offset;
@ -1207,10 +1204,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
} }
case DUNDER_CLASS: case DUNDER_CLASS:
{ {
if (load_method) {
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
return -1;
}
Py_ssize_t offset = offsetof(PyObject, ob_type); Py_ssize_t offset = offsetof(PyObject, ob_type);
assert(offset == (uint16_t)offset); assert(offset == (uint16_t)offset);
cache->index = (uint16_t)offset; cache->index = (uint16_t)offset;
@ -1219,20 +1212,16 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
return 0; return 0;
} }
case OTHER_SLOT: case OTHER_SLOT:
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT);
return -1; return -1;
case MUTABLE: case MUTABLE:
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS);
return -1; return -1;
case GETSET_OVERRIDDEN: case GETSET_OVERRIDDEN:
SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OVERRIDDEN); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN);
return -1; return -1;
case GETATTRIBUTE_IS_PYTHON_FUNCTION: case GETATTRIBUTE_IS_PYTHON_FUNCTION:
{ {
if (load_method) {
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
return -1;
}
#ifndef Py_GIL_DISABLED #ifndef Py_GIL_DISABLED
// In free-threaded builds it's possible for tp_getattro to change // In free-threaded builds it's possible for tp_getattro to change
// after the call to analyze_descriptor. That is fine: the version // after the call to analyze_descriptor. That is fine: the version
@ -1244,6 +1233,10 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
if (!function_check_args(descr, 2, LOAD_ATTR)) { if (!function_check_args(descr, 2, LOAD_ATTR)) {
return -1; return -1;
} }
if (oparg & 1) {
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
return -1;
}
uint32_t version = function_get_version(descr, LOAD_ATTR); uint32_t version = function_get_version(descr, LOAD_ATTR);
if (version == 0) { if (version == 0) {
return -1; return -1;
@ -1277,7 +1270,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
if (shadow) { if (shadow) {
goto try_instance; goto try_instance;
} }
if (!load_method) { if ((oparg & 1) == 0) {
if (specialize_attr_loadclassattr(owner, instr, name, descr, if (specialize_attr_loadclassattr(owner, instr, name, descr,
tp_version, kind, false, tp_version, kind, false,
shared_keys_version)) { shared_keys_version)) {
@ -1294,10 +1287,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
} }
Py_UNREACHABLE(); Py_UNREACHABLE();
try_instance: try_instance:
if (load_method) {
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
return -1;
}
if (specialize_dict_access(owner, instr, type, kind, name, tp_version, if (specialize_dict_access(owner, instr, type, kind, name, tp_version,
LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT)) LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT))
{ {
@ -1307,7 +1296,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
} }
static int static int
specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name, bool load_method) specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name)
{ {
// 0 is not a valid version // 0 is not a valid version
uint32_t shared_keys_version = 0; uint32_t shared_keys_version = 0;
@ -1316,7 +1305,7 @@ specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* na
unsigned int tp_version = 0; unsigned int tp_version = 0;
PyTypeObject *type = Py_TYPE(owner); PyTypeObject *type = Py_TYPE(owner);
DescriptorClassification kind = analyze_descriptor_load(type, name, &descr, &tp_version); DescriptorClassification kind = analyze_descriptor_load(type, name, &descr, &tp_version);
int result = do_specialize_instance_load_attr(owner, instr, name, shadow, shared_keys_version, kind, descr, tp_version, load_method); int result = do_specialize_instance_load_attr(owner, instr, name, shadow, shared_keys_version, kind, descr, tp_version);
Py_XDECREF(descr); Py_XDECREF(descr);
return result; return result;
} }
@ -1344,40 +1333,7 @@ _Py_Specialize_LoadAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *nam
fail = specialize_class_load_attr(owner, instr, name); fail = specialize_class_load_attr(owner, instr, name);
} }
else { else {
fail = specialize_instance_load_attr(owner, instr, name, false); fail = specialize_instance_load_attr(owner, instr, name);
}
if (fail) {
unspecialize(instr);
}
}
void
_Py_Specialize_LoadMethod(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *name)
{
PyObject *owner = PyStackRef_AsPyObjectBorrow(owner_st);
assert(ENABLE_SPECIALIZATION_FT);
assert(_PyOpcode_Caches[LOAD_ATTR] == INLINE_CACHE_ENTRIES_LOAD_ATTR);
PyTypeObject *type = Py_TYPE(owner);
bool fail;
if (!_PyType_IsReady(type)) {
// We *might* not really need this check, but we inherited it from
// PyObject_GenericGetAttr and friends... and this way we still do the
// right thing if someone forgets to call PyType_Ready(type):
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
fail = true;
}
else if (Py_TYPE(owner)->tp_getattro == PyModule_Type.tp_getattro) {
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
fail = true;
}
else if (PyType_Check(owner)) {
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
fail = true;
}
else {
fail = specialize_instance_load_attr(owner, instr, name, true);
} }
if (fail) { if (fail) {
@ -1619,7 +1575,7 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
#ifdef Py_GIL_DISABLED #ifdef Py_GIL_DISABLED
if (!_PyObject_HasDeferredRefcount(descr)) { if (!_PyObject_HasDeferredRefcount(descr)) {
SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
return 0; return 0;
} }
#endif #endif
@ -1631,11 +1587,11 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
((PyHeapTypeObject *)owner_cls)->ht_cached_keys, name) < 0); ((PyHeapTypeObject *)owner_cls)->ht_cached_keys, name) < 0);
#endif #endif
if (shared_keys_version == 0) { if (shared_keys_version == 0) {
SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
return 0; return 0;
} }
write_u32(cache->keys_version, shared_keys_version); write_u32(cache->keys_version, shared_keys_version);
specialize(instr, is_method ? LOAD_METHOD_WITH_VALUES : LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES); specialize(instr, is_method ? LOAD_ATTR_METHOD_WITH_VALUES : LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES);
} }
else { else {
Py_ssize_t dictoffset; Py_ssize_t dictoffset;
@ -1645,17 +1601,17 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
else { else {
dictoffset = owner_cls->tp_dictoffset; dictoffset = owner_cls->tp_dictoffset;
if (dictoffset < 0 || dictoffset > INT16_MAX + MANAGED_DICT_OFFSET) { if (dictoffset < 0 || dictoffset > INT16_MAX + MANAGED_DICT_OFFSET) {
SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE);
return 0; return 0;
} }
} }
if (dictoffset == 0) { if (dictoffset == 0) {
specialize(instr, is_method ? LOAD_METHOD_NO_DICT : LOAD_ATTR_NONDESCRIPTOR_NO_DICT); specialize(instr, is_method ? LOAD_ATTR_METHOD_NO_DICT : LOAD_ATTR_NONDESCRIPTOR_NO_DICT);
} }
else if (is_method) { else if (is_method) {
PyObject *dict = *(PyObject **) ((char *)owner + dictoffset); PyObject *dict = *(PyObject **) ((char *)owner + dictoffset);
if (dict) { if (dict) {
SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
return 0; return 0;
} }
/* Cache entries must be unsigned values, so we offset the /* Cache entries must be unsigned values, so we offset the
@ -1664,10 +1620,10 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
dictoffset -= MANAGED_DICT_OFFSET; dictoffset -= MANAGED_DICT_OFFSET;
assert(((uint16_t)dictoffset) == dictoffset); assert(((uint16_t)dictoffset) == dictoffset);
cache->dict_offset = (uint16_t)dictoffset; cache->dict_offset = (uint16_t)dictoffset;
specialize(instr, LOAD_METHOD_LAZY_DICT); specialize(instr, LOAD_ATTR_METHOD_LAZY_DICT);
} }
else { else {
SPECIALIZATION_FAIL(is_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE); SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE);
return 0; return 0;
} }
} }

View File

@ -25,6 +25,7 @@ class Properties:
side_exit: bool side_exit: bool
pure: bool pure: bool
tier: int | None = None tier: int | None = None
oparg_and_1: bool = False
const_oparg: int = -1 const_oparg: int = -1
needs_prev: bool = False needs_prev: bool = False
no_save_ip: bool = False no_save_ip: bool = False
@ -123,14 +124,16 @@ def size(self) -> int:
class StackItem: class StackItem:
name: str name: str
type: str | None type: str | None
condition: str | None
size: str size: str
peek: bool = False peek: bool = False
used: bool = False used: bool = False
def __str__(self) -> str: def __str__(self) -> str:
cond = f" if ({self.condition})" if self.condition else ""
size = f"[{self.size}]" if self.size else "" size = f"[{self.size}]" if self.size else ""
type = "" if self.type is None else f"{self.type} " type = "" if self.type is None else f"{self.type} "
return f"{type}{self.name}{size} {self.peek}" return f"{type}{self.name}{size}{cond} {self.peek}"
def is_array(self) -> bool: def is_array(self) -> bool:
return self.size != "" return self.size != ""
@ -312,19 +315,25 @@ def override_error(
) )
def convert_stack_item(item: parser.StackEffect) -> StackItem: def convert_stack_item(
return StackItem(item.name, item.type, item.size) item: parser.StackEffect, replace_op_arg_1: str | None
) -> StackItem:
cond = item.cond
if replace_op_arg_1 and OPARG_AND_1.match(item.cond):
cond = replace_op_arg_1
return StackItem(item.name, item.type, cond, item.size)
def analyze_stack( def analyze_stack(
op: parser.InstDef | parser.Pseudo) -> StackEffect: op: parser.InstDef | parser.Pseudo, replace_op_arg_1: str | None = None
) -> StackEffect:
inputs: list[StackItem] = [ inputs: list[StackItem] = [
convert_stack_item(i) convert_stack_item(i, replace_op_arg_1)
for i in op.inputs for i in op.inputs
if isinstance(i, parser.StackEffect) if isinstance(i, parser.StackEffect)
] ]
outputs: list[StackItem] = [ outputs: list[StackItem] = [
convert_stack_item(i) for i in op.outputs convert_stack_item(i, replace_op_arg_1) for i in op.outputs
] ]
# Mark variables with matching names at the base of the stack as "peek" # Mark variables with matching names at the base of the stack as "peek"
modified = False modified = False
@ -746,6 +755,40 @@ def always_exits(op: parser.InstDef) -> bool:
return True return True
return False return False
def stack_effect_only_peeks(instr: parser.InstDef) -> bool:
stack_inputs = [s for s in instr.inputs if not isinstance(s, parser.CacheEffect)]
if len(stack_inputs) != len(instr.outputs):
return False
if len(stack_inputs) == 0:
return False
if any(s.cond for s in stack_inputs) or any(s.cond for s in instr.outputs):
return False
return all(
(s.name == other.name and s.type == other.type and s.size == other.size)
for s, other in zip(stack_inputs, instr.outputs)
)
OPARG_AND_1 = re.compile("\\(*oparg *& *1")
def effect_depends_on_oparg_1(op: parser.InstDef) -> bool:
for effect in op.inputs:
if isinstance(effect, parser.CacheEffect):
continue
if not effect.cond:
continue
if OPARG_AND_1.match(effect.cond):
return True
for effect in op.outputs:
if not effect.cond:
continue
if OPARG_AND_1.match(effect.cond):
return True
return False
def compute_properties(op: parser.InstDef) -> Properties: def compute_properties(op: parser.InstDef) -> Properties:
escaping_calls = find_escaping_api_calls(op) escaping_calls = find_escaping_api_calls(op)
has_free = ( has_free = (
@ -819,6 +862,29 @@ def make_uop(
body=op.block.tokens, body=op.block.tokens,
properties=compute_properties(op), properties=compute_properties(op),
) )
if effect_depends_on_oparg_1(op) and "split" in op.annotations:
result.properties.oparg_and_1 = True
for bit in ("0", "1"):
name_x = name + "_" + bit
properties = compute_properties(op)
if properties.oparg:
# May not need oparg anymore
properties.oparg = any(
token.text == "oparg" for token in op.block.tokens
)
rep = Uop(
name=name_x,
context=op.context,
annotations=op.annotations,
stack=analyze_stack(op, bit),
caches=analyze_caches(inputs),
deferred_refs=analyze_deferred_refs(op),
output_stores=find_stores_outputs(op),
body=op.block.tokens,
properties=properties,
)
rep.replicates = result
uops[name_x] = rep
for anno in op.annotations: for anno in op.annotations:
if anno.startswith("replicate"): if anno.startswith("replicate"):
result.replicated = int(anno[10:-1]) result.replicated = int(anno[10:-1])

View File

@ -247,7 +247,7 @@ def decref_inputs(
if var.name == "null": if var.name == "null":
continue continue
close = "PyStackRef_CLOSE" close = "PyStackRef_CLOSE"
if "null" in var.name: if "null" in var.name or var.condition and var.condition != "1":
close = "PyStackRef_XCLOSE" close = "PyStackRef_XCLOSE"
if var.size: if var.size:
if var.size == "1": if var.size == "1":
@ -256,6 +256,9 @@ def decref_inputs(
self.out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n") self.out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n")
self.out.emit(f"{close}({var.name}[_i]);\n") self.out.emit(f"{close}({var.name}[_i]);\n")
self.out.emit("}\n") self.out.emit("}\n")
elif var.condition:
if var.condition != "0":
self.out.emit(f"{close}({var.name});\n")
else: else:
self.out.emit(f"{close}({var.name});\n") self.out.emit(f"{close}({var.name});\n")
for input in storage.inputs: for input in storage.inputs:
@ -683,6 +686,8 @@ def cflags(p: Properties) -> str:
flags.append("HAS_PURE_FLAG") flags.append("HAS_PURE_FLAG")
if p.no_save_ip: if p.no_save_ip:
flags.append("HAS_NO_SAVE_IP_FLAG") flags.append("HAS_NO_SAVE_IP_FLAG")
if p.oparg_and_1:
flags.append("HAS_OPARG_AND_1_FLAG")
if flags: if flags:
return " | ".join(flags) return " | ".join(flags)
else: else:

View File

@ -222,6 +222,7 @@ def choice(*opts: str) -> str:
"register", "register",
"replaced", "replaced",
"pure", "pure",
"split",
"replicate", "replicate",
"tier1", "tier1",
"tier2", "tier2",

View File

@ -51,6 +51,7 @@
"EXIT", "EXIT",
"PURE", "PURE",
"PASSTHROUGH", "PASSTHROUGH",
"OPARG_AND_1",
"ERROR_NO_POP", "ERROR_NO_POP",
"NO_SAVE_IP", "NO_SAVE_IP",
] ]

View File

@ -48,13 +48,19 @@ def declare_variables(uop: Uop, out: CWriter, skip_inputs: bool) -> None:
for var in reversed(uop.stack.inputs): for var in reversed(uop.stack.inputs):
if var.used and var.name not in variables: if var.used and var.name not in variables:
variables.add(var.name) variables.add(var.name)
out.emit(f"{type_name(var)}{var.name};\n") if var.condition:
out.emit(f"{type_name(var)}{var.name} = NULL;\n")
else:
out.emit(f"{type_name(var)}{var.name};\n")
for var in uop.stack.outputs: for var in uop.stack.outputs:
if var.peek: if var.peek:
continue continue
if var.name not in variables: if var.name not in variables:
variables.add(var.name) variables.add(var.name)
out.emit(f"{type_name(var)}{var.name};\n") if var.condition:
out.emit(f"{type_name(var)}{var.name} = NULL;\n")
else:
out.emit(f"{type_name(var)}{var.name};\n")
def decref_inputs( def decref_inputs(

View File

@ -77,11 +77,12 @@ class Block(Node):
class StackEffect(Node): class StackEffect(Node):
name: str = field(compare=False) # __eq__ only uses type, cond, size name: str = field(compare=False) # __eq__ only uses type, cond, size
type: str = "" # Optional `:type` type: str = "" # Optional `:type`
cond: str = "" # Optional `if (cond)`
size: str = "" # Optional `[size]` size: str = "" # Optional `[size]`
# Note: size cannot be combined with type or cond # Note: size cannot be combined with type or cond
def __repr__(self) -> str: def __repr__(self) -> str:
items = [self.name, self.type, self.size] items = [self.name, self.type, self.cond, self.size]
while items and items[-1] == "": while items and items[-1] == "":
del items[-1] del items[-1]
return f"StackEffect({', '.join(repr(item) for item in items)})" return f"StackEffect({', '.join(repr(item) for item in items)})"
@ -277,15 +278,22 @@ def stack_effect(self) -> StackEffect | None:
type_text = self.require(lx.IDENTIFIER).text.strip() type_text = self.require(lx.IDENTIFIER).text.strip()
if self.expect(lx.TIMES): if self.expect(lx.TIMES):
type_text += " *" type_text += " *"
cond_text = ""
if self.expect(lx.IF):
self.require(lx.LPAREN)
if not (cond := self.expression()):
raise self.make_syntax_error("Expected condition")
self.require(lx.RPAREN)
cond_text = cond.text.strip()
size_text = "" size_text = ""
if self.expect(lx.LBRACKET): if self.expect(lx.LBRACKET):
if type_text: if type_text or cond_text:
raise self.make_syntax_error("Unexpected [") raise self.make_syntax_error("Unexpected [")
if not (size := self.expression()): if not (size := self.expression()):
raise self.make_syntax_error("Expected expression") raise self.make_syntax_error("Expected expression")
self.require(lx.RBRACKET) self.require(lx.RBRACKET)
size_text = size.text.strip() size_text = size.text.strip()
return StackEffect(tkn.text, type_text, size_text) return StackEffect(tkn.text, type_text, cond_text, size_text)
return None return None
@contextual @contextual

View File

@ -24,7 +24,17 @@ def maybe_parenthesize(sym: str) -> str:
def var_size(var: StackItem) -> str: def var_size(var: StackItem) -> str:
if var.size: if var.condition:
# Special case simplifications
if var.condition == "0":
return "0"
elif var.condition == "1":
return var.get_size()
elif var.condition == "oparg & 1" and not var.size:
return f"({var.condition})"
else:
return f"(({var.condition}) ? {var.get_size()} : 0)"
elif var.size:
return var.size return var.size
else: else:
return "1" return "1"
@ -80,6 +90,10 @@ def size(self) -> str:
def name(self) -> str: def name(self) -> str:
return self.item.name return self.item.name
@property
def condition(self) -> str | None:
return self.item.condition
def is_array(self) -> bool: def is_array(self) -> bool:
return self.item.is_array() return self.item.is_array()
@ -260,7 +274,16 @@ def pop(self, var: StackItem) -> tuple[str, Local]:
self.defined.add(var.name) self.defined.add(var.name)
cast = f"({var.type})" if (not indirect and var.type) else "" cast = f"({var.type})" if (not indirect and var.type) else ""
bits = ".bits" if cast and self.extract_bits else "" bits = ".bits" if cast and self.extract_bits else ""
assign = f"{var.name} = {cast}{indirect}stack_pointer[{self.base_offset.to_c()}]{bits};\n" assign = f"{var.name} = {cast}{indirect}stack_pointer[{self.base_offset.to_c()}]{bits};"
if var.condition:
if var.condition == "1":
assign = f"{assign}\n"
elif var.condition == "0":
return "", Local.unused(var)
else:
assign = f"if ({var.condition}) {{ {assign} }}\n"
else:
assign = f"{assign}\n"
return assign, Local.from_memory(var) return assign, Local.from_memory(var)
def push(self, var: Local) -> None: def push(self, var: Local) -> None:
@ -280,6 +303,10 @@ def _do_emit(
) -> None: ) -> None:
cast = f"({cast_type})" if var.type else "" cast = f"({cast_type})" if var.type else ""
bits = ".bits" if cast and extract_bits else "" bits = ".bits" if cast and extract_bits else ""
if var.condition == "0":
return
if var.condition and var.condition != "1":
out.emit(f"if ({var.condition}) ")
out.emit(f"stack_pointer[{base_offset.to_c()}]{bits} = {cast}{var.name};\n") out.emit(f"stack_pointer[{base_offset.to_c()}]{bits} = {cast}{var.name};\n")
def _adjust_stack_pointer(self, out: CWriter, number: str) -> None: def _adjust_stack_pointer(self, out: CWriter, number: str) -> None:

View File

@ -37,7 +37,10 @@
def declare_variable(var: StackItem, out: CWriter) -> None: def declare_variable(var: StackItem, out: CWriter) -> None:
type, null = type_and_null(var) type, null = type_and_null(var)
space = " " if type[-1].isalnum() else "" space = " " if type[-1].isalnum() else ""
out.emit(f"{type}{space}{var.name};\n") if var.condition:
out.emit(f"{type}{space}{var.name} = {null};\n")
else:
out.emit(f"{type}{space}{var.name};\n")
def declare_variables(inst: Instruction, out: CWriter) -> None: def declare_variables(inst: Instruction, out: CWriter) -> None:

View File

@ -39,7 +39,14 @@ def declare_variable(
required.remove(var.name) required.remove(var.name)
type, null = type_and_null(var) type, null = type_and_null(var)
space = " " if type[-1].isalnum() else "" space = " " if type[-1].isalnum() else ""
out.emit(f"{type}{space}{var.name};\n") if var.condition:
out.emit(f"{type}{space}{var.name} = {null};\n")
if uop.replicates:
# Replicas may not use all their conditional variables
# So avoid a compiler warning with a fake use
out.emit(f"(void){var.name};\n")
else:
out.emit(f"{type}{space}{var.name};\n")
def declare_variables(uop: Uop, out: CWriter) -> None: def declare_variables(uop: Uop, out: CWriter) -> None:
@ -208,6 +215,9 @@ def generate_tier2(
for name, uop in analysis.uops.items(): for name, uop in analysis.uops.items():
if uop.properties.tier == 1: if uop.properties.tier == 1:
continue continue
if uop.properties.oparg_and_1:
out.emit(f"/* {uop.name} is split on (oparg & 1) */\n\n")
continue
if uop.is_super(): if uop.is_super():
continue continue
why_not_viable = uop.why_not_viable() why_not_viable = uop.why_not_viable()

View File

@ -284,7 +284,7 @@ def get_specialization_failure_kinds(self, opcode: str) -> dict[str, int]:
def kind_to_text(kind: int, opcode: str): def kind_to_text(kind: int, opcode: str):
if kind <= 8: if kind <= 8:
return pretty(self._defines[kind][0]) return pretty(self._defines[kind][0])
if opcode == "LOAD_SUPER_ATTR" or opcode == "LOAD_SUPER_METHOD": if opcode == "LOAD_SUPER_ATTR":
opcode = "SUPER" opcode = "SUPER"
elif opcode.endswith("ATTR"): elif opcode.endswith("ATTR"):
opcode = "ATTR" opcode = "ATTR"