]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Revert "GH-128914: Remove conditional stack effects from `bytecodes.c` and the code...
authorSam Gross <colesbury@gmail.com>
Thu, 23 Jan 2025 09:26:25 +0000 (04:26 -0500)
committerGitHub <noreply@github.com>
Thu, 23 Jan 2025 09:26:25 +0000 (09:26 +0000)
The commit introduced a ~2.5-3% regression in the free threading build.

This reverts commit ab61d3f4303d14a413bc9ae6557c730ffdf7579e.

44 files changed:
Doc/library/dis.rst
Include/internal/pycore_code.h
Include/internal/pycore_magic_number.h
Include/internal/pycore_opcode_metadata.h
Include/internal/pycore_uop_ids.h
Include/internal/pycore_uop_metadata.h
Include/opcode_ids.h
Lib/_opcode_metadata.py
Lib/dis.py
Lib/inspect.py
Lib/opcode.py
Lib/test/test__opcode.py
Lib/test/test_capi/test_opt.py
Lib/test/test_compile.py
Lib/test/test_dis.py
Lib/test/test_generated_cases.py
Lib/test/test_monitoring.py
Lib/test/test_opcache.py
Misc/NEWS.d/next/Core_and_Builtins/2025-01-17-10-17-01.gh-issue-128914.dn6RaW.rst [deleted file]
Objects/frameobject.c
Objects/object.c
Programs/test_frozenmain.h
Python/bytecodes.c
Python/codegen.c
Python/executor_cases.c.h
Python/flowgraph.c
Python/generated_cases.c.h
Python/instrumentation.c
Python/opcode_targets.h
Python/optimizer.c
Python/optimizer_analysis.c
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h
Python/specialize.c
Tools/cases_generator/analyzer.py
Tools/cases_generator/generators_common.py
Tools/cases_generator/lexer.py
Tools/cases_generator/opcode_metadata_generator.py
Tools/cases_generator/optimizer_generator.py
Tools/cases_generator/parsing.py
Tools/cases_generator/stack.py
Tools/cases_generator/tier1_generator.py
Tools/cases_generator/tier2_generator.py
Tools/scripts/summarize_stats.py

index 225ef321aed3b89b22668cff5219001e147541fe..f8f4188d27b472fad4e5e308c27f355cd3ed80d9 100644 (file)
@@ -75,8 +75,7 @@ the following command can be used to display the disassembly of
    >>> dis.dis(myfunc)
      2           RESUME                   0
    <BLANKLINE>
-     3           LOAD_GLOBAL              0 (len)
-                 PUSH_NULL
+     3           LOAD_GLOBAL              1 (len + NULL)
                  LOAD_FAST                0 (alist)
                  CALL                     1
                  RETURN_VALUE
@@ -208,7 +207,6 @@ Example:
     ...
     RESUME
     LOAD_GLOBAL
-    PUSH_NULL
     LOAD_FAST
     CALL
     RETURN_VALUE
@@ -1217,20 +1215,11 @@ iterations of the loop.
 
 .. 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, then a ``NULL`` or ``self`` is
-      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.
+   If the low bit of ``namei`` is set, this will 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
    correct name, the bytecode pushes the unbound method and ``STACK[-1]``.
    ``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
    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)
@@ -1935,6 +1926,12 @@ but are replaced by real opcodes or removed before bytecode is generated.
       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
index f5eddab6e90e41f7ccdab4b8e31602807cda1a2c..01d41446fdb0cf2bfe0f253ffd91c3b55040f5ca 100644 (file)
@@ -334,8 +334,6 @@ extern void _Py_Specialize_LoadSuperAttr(_PyStackRef global_super, _PyStackRef c
                                          _Py_CODEUNIT *instr, int load_method);
 extern void _Py_Specialize_LoadAttr(_PyStackRef owner, _Py_CODEUNIT *instr,
                                     PyObject *name);
-extern void _Py_Specialize_LoadMethod(_PyStackRef owner, _Py_CODEUNIT *instr,
-                                      PyObject *name);
 extern void _Py_Specialize_StoreAttr(_PyStackRef owner, _Py_CODEUNIT *instr,
                                      PyObject *name);
 extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins,
index 0d94b6d81d29365249ee5d837e0323a651e5fa85..1dd155abf3babfc262313c30ddfbe55aaf973372 100644 (file)
@@ -267,7 +267,6 @@ Known values:
     Python 3.14a4 3612 (Add POP_ITER and INSTRUMENTED_POP_ITER)
     Python 3.14a4 3613 (Add LOAD_CONST_MORTAL instruction)
     Python 3.14a5 3614 (Add BINARY_OP_EXTEND)
-    Python 3.14a5 3615 (Remove conditional stack effects)
 
     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
    (little-endian) and then appending b'\r\n'. */
 #define PYC_MAGIC_NUMBER_TOKEN \
index 22ed269c5f1686b54021b766c2f99f5356b24248..10061c988d5f4bc0c76e9597faf18bc497857627 100644 (file)
@@ -76,7 +76,7 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
         case BUILD_SET:
             return oparg;
         case BUILD_SLICE:
-            return oparg;
+            return 2 + ((oparg == 3) ? 1 : 0);
         case BUILD_STRING:
             return oparg;
         case BUILD_TUPLE:
@@ -100,7 +100,7 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
         case CALL_BUILTIN_O:
             return 2 + oparg;
         case CALL_FUNCTION_EX:
-            return 4;
+            return 3 + (oparg & 1);
         case CALL_INTRINSIC_1:
             return 1;
         case CALL_INTRINSIC_2:
@@ -245,8 +245,6 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
             return 0;
         case INSTRUMENTED_LOAD_SUPER_ATTR:
             return 0;
-        case INSTRUMENTED_LOAD_SUPER_METHOD:
-            return 0;
         case INSTRUMENTED_NOT_TAKEN:
             return 0;
         case INSTRUMENTED_POP_ITER:
@@ -297,6 +295,12 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
             return 1;
         case LOAD_ATTR_INSTANCE_VALUE:
             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:
             return 1;
         case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
@@ -343,14 +347,6 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
             return 0;
         case LOAD_LOCALS:
             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:
             return 0;
         case LOAD_SMALL_INT:
@@ -361,9 +357,7 @@ int _PyOpcode_num_popped(int opcode, int oparg)  {
             return 3;
         case LOAD_SUPER_ATTR_ATTR:
             return 3;
-        case LOAD_SUPER_METHOD:
-            return 3;
-        case LOAD_SUPER_METHOD_METHOD:
+        case LOAD_SUPER_ATTR_METHOD:
             return 3;
         case MAKE_CELL:
             return 0;
@@ -722,8 +716,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
             return 0;
         case INSTRUMENTED_LOAD_SUPER_ATTR:
             return 0;
-        case INSTRUMENTED_LOAD_SUPER_METHOD:
-            return 0;
         case INSTRUMENTED_NOT_TAKEN:
             return 0;
         case INSTRUMENTED_POP_ITER:
@@ -765,17 +757,23 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
         case LIST_EXTEND:
             return 1 + (oparg-1);
         case LOAD_ATTR:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_ATTR_CLASS:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
             return 1;
         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:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
             return 1;
         case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
@@ -783,9 +781,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
         case LOAD_ATTR_PROPERTY:
             return 0;
         case LOAD_ATTR_SLOT:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_ATTR_WITH_HINT:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_BUILD_CLASS:
             return 1;
         case LOAD_CLOSURE:
@@ -813,21 +811,13 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
         case LOAD_FROM_DICT_OR_GLOBALS:
             return 1;
         case LOAD_GLOBAL:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_GLOBAL_BUILTIN:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_GLOBAL_MODULE:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_LOCALS:
             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:
             return 1;
         case LOAD_SMALL_INT:
@@ -835,12 +825,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg)  {
         case LOAD_SPECIAL:
             return 2;
         case LOAD_SUPER_ATTR:
-            return 1;
+            return 1 + (oparg & 1);
         case LOAD_SUPER_ATTR_ATTR:
             return 1;
-        case LOAD_SUPER_METHOD:
-            return 2;
-        case LOAD_SUPER_METHOD_METHOD:
+        case LOAD_SUPER_ATTR_METHOD:
             return 2;
         case MAKE_CELL:
             return 0;
@@ -1070,7 +1058,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             return 0;
         }
         case BUILD_SLICE: {
-            *effect = 1 - oparg;
+            *effect = -1 - ((oparg == 3) ? 1 : 0);
             return 0;
         }
         case BUILD_STRING: {
@@ -1126,7 +1114,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             return 0;
         }
         case CALL_FUNCTION_EX: {
-            *effect = 0;
+            *effect = Py_MAX(0, -2 - (oparg & 1));
             return 0;
         }
         case CALL_INTRINSIC_1: {
@@ -1427,10 +1415,6 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             *effect = 0;
             return 0;
         }
-        case INSTRUMENTED_LOAD_SUPER_METHOD: {
-            *effect = 0;
-            return 0;
-        }
         case INSTRUMENTED_NOT_TAKEN: {
             *effect = 0;
             return 0;
@@ -1512,15 +1496,15 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             return 0;
         }
         case LOAD_ATTR: {
-            *effect = 1;
+            *effect = Py_MAX(1, (oparg & 1));
             return 0;
         }
         case LOAD_ATTR_CLASS: {
-            *effect = 0;
+            *effect = Py_MAX(0, (oparg & 1));
             return 0;
         }
         case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK: {
-            *effect = 0;
+            *effect = Py_MAX(0, (oparg & 1));
             return 0;
         }
         case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: {
@@ -1528,13 +1512,25 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             return 0;
         }
         case LOAD_ATTR_INSTANCE_VALUE: {
-            *effect = 0;
+            *effect = Py_MAX(0, (oparg & 1));
             return 0;
         }
-        case LOAD_ATTR_MODULE: {
+        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;
         }
+        case LOAD_ATTR_MODULE: {
+            *effect = Py_MAX(1, (oparg & 1));
+            return 0;
+        }
         case LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
             *effect = 0;
             return 0;
@@ -1548,11 +1544,11 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             return 0;
         }
         case LOAD_ATTR_SLOT: {
-            *effect = 0;
+            *effect = Py_MAX(0, (oparg & 1));
             return 0;
         }
         case LOAD_ATTR_WITH_HINT: {
-            *effect = 1;
+            *effect = Py_MAX(1, (oparg & 1));
             return 0;
         }
         case LOAD_BUILD_CLASS: {
@@ -1608,37 +1604,21 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             return 0;
         }
         case LOAD_GLOBAL: {
-            *effect = 1;
+            *effect = Py_MAX(1, 1 + (oparg & 1));
             return 0;
         }
         case LOAD_GLOBAL_BUILTIN: {
-            *effect = 1;
+            *effect = Py_MAX(1, 1 + (oparg & 1));
             return 0;
         }
         case LOAD_GLOBAL_MODULE: {
-            *effect = 1;
+            *effect = Py_MAX(1, 1 + (oparg & 1));
             return 0;
         }
         case LOAD_LOCALS: {
             *effect = 1;
             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: {
             *effect = 1;
             return 0;
@@ -1652,18 +1632,14 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect)  {
             return 0;
         }
         case LOAD_SUPER_ATTR: {
-            *effect = 0;
+            *effect = Py_MAX(0, -2 + (oparg & 1));
             return 0;
         }
         case LOAD_SUPER_ATTR_ATTR: {
             *effect = -2;
             return 0;
         }
-        case LOAD_SUPER_METHOD: {
-            *effect = 0;
-            return 0;
-        }
-        case LOAD_SUPER_METHOD_METHOD: {
+        case LOAD_SUPER_ATTR_METHOD: {
             *effect = -1;
             return 0;
         }
@@ -1958,7 +1934,6 @@ enum InstructionFormat {
     INSTR_FMT_IXC00 = 9,
     INSTR_FMT_IXC000 = 10,
     INSTR_FMT_IXC0000 = 11,
-    INSTR_FMT_IXC00000000 = 12,
 };
 
 #define IS_VALID_OPCODE(OP) \
@@ -1978,8 +1953,9 @@ enum InstructionFormat {
 #define HAS_EXIT_FLAG (1024)
 #define HAS_PURE_FLAG (2048)
 #define HAS_PASSTHROUGH_FLAG (4096)
-#define HAS_ERROR_NO_POP_FLAG (8192)
-#define HAS_NO_SAVE_IP_FLAG (16384)
+#define HAS_OPARG_AND_1_FLAG (8192)
+#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_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_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_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_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_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_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_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_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 },
@@ -2119,7 +2096,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
     [INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
     [INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
     [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_POP_ITER] = { true, INSTR_FMT_IX, HAS_ESCAPES_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_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_CLASS] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG },
-    [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { 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_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_INSTANCE_VALUE] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
-    [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IXC00000000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
-    [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IXC00000000, HAS_EXIT_FLAG },
-    [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { 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_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+    [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_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_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_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_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_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_BUILTIN] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG },
-    [LOAD_GLOBAL_MODULE] = { 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_IBC000, HAS_ARG_FLAG | HAS_DEOPT_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_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_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_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_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 },
+    [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 },
     [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 },
     [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_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_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_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 } } },
@@ -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_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_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_SMALL_INT] = { .nuops = 1, .uops = { { _LOAD_SMALL_INT, 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_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_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, 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_LINE] = "INSTRUMENTED_LINE",
     [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
-    [INSTRUMENTED_LOAD_SUPER_METHOD] = "INSTRUMENTED_LOAD_SUPER_METHOD",
     [INSTRUMENTED_NOT_TAKEN] = "INSTRUMENTED_NOT_TAKEN",
     [INSTRUMENTED_POP_ITER] = "INSTRUMENTED_POP_ITER",
     [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_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
     [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_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
     [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_MODULE] = "LOAD_GLOBAL_MODULE",
     [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_SMALL_INT] = "LOAD_SMALL_INT",
     [LOAD_SPECIAL] = "LOAD_SPECIAL",
     [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR",
     [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR",
-    [LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD",
-    [LOAD_SUPER_METHOD_METHOD] = "LOAD_SUPER_METHOD_METHOD",
+    [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
     [MAKE_CELL] = "MAKE_CELL",
     [MAKE_FUNCTION] = "MAKE_FUNCTION",
     [MAP_ADD] = "MAP_ADD",
@@ -2693,9 +2663,7 @@ const uint8_t _PyOpcode_Caches[256] = {
     [STORE_ATTR] = 4,
     [LOAD_GLOBAL] = 4,
     [LOAD_SUPER_ATTR] = 1,
-    [LOAD_SUPER_METHOD] = 1,
     [LOAD_ATTR] = 9,
-    [LOAD_METHOD] = 9,
     [COMPARE_OP] = 1,
     [CONTAINS_OP] = 1,
     [JUMP_BACKWARD] = 1,
@@ -2818,7 +2786,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
     [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
     [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
-    [INSTRUMENTED_LOAD_SUPER_METHOD] = INSTRUMENTED_LOAD_SUPER_METHOD,
     [INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
     [INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
     [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_GETATTRIBUTE_OVERRIDDEN] = 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_NONDESCRIPTOR_NO_DICT] = 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_MODULE] = LOAD_GLOBAL,
     [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_SMALL_INT] = LOAD_SMALL_INT,
     [LOAD_SPECIAL] = LOAD_SPECIAL,
     [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
     [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
-    [LOAD_SUPER_METHOD] = LOAD_SUPER_METHOD,
-    [LOAD_SUPER_METHOD_METHOD] = LOAD_SUPER_METHOD,
+    [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
     [MAKE_CELL] = MAKE_CELL,
     [MAKE_FUNCTION] = MAKE_FUNCTION,
     [MAP_ADD] = MAP_ADD,
@@ -2941,6 +2906,8 @@ const uint8_t _PyOpcode_Deopt[256] = {
 #endif // NEED_OPCODE_METADATA
 
 #define EXTRA_CASES \
+    case 118: \
+    case 119: \
     case 120: \
     case 121: \
     case 122: \
@@ -2974,6 +2941,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
     case 231: \
     case 232: \
     case 233: \
+    case 234: \
         ;
 struct pseudo_targets {
     uint8_t as_sequence;
index 2bf8542bdb67a94946232ff2f023c7f052f6661a..066165a2c810d5f618550f5944ab3c95a5707b30 100644 (file)
@@ -159,7 +159,6 @@ extern "C" {
 #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
 #define _INSTRUMENTED_LINE INSTRUMENTED_LINE
 #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_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
 #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
@@ -181,122 +180,127 @@ extern "C" {
 #define _LIST_EXTEND LIST_EXTEND
 #define _LOAD_ATTR 410
 #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_INSTANCE_VALUE 412
-#define _LOAD_ATTR_MODULE 413
-#define _LOAD_ATTR_MODULE_FROM_KEYS 414
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 415
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 416
-#define _LOAD_ATTR_PROPERTY_FRAME 417
-#define _LOAD_ATTR_SLOT 418
-#define _LOAD_ATTR_WITH_HINT 419
+#define _LOAD_ATTR_INSTANCE_VALUE 414
+#define _LOAD_ATTR_INSTANCE_VALUE_0 415
+#define _LOAD_ATTR_INSTANCE_VALUE_1 416
+#define _LOAD_ATTR_METHOD_LAZY_DICT 417
+#define _LOAD_ATTR_METHOD_NO_DICT 418
+#define _LOAD_ATTR_METHOD_WITH_VALUES 419
+#define _LOAD_ATTR_MODULE 420
+#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_BYTECODE 420
+#define _LOAD_BYTECODE 429
 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
 #define _LOAD_CONST LOAD_CONST
 #define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL
-#define _LOAD_CONST_INLINE 421
-#define _LOAD_CONST_INLINE_BORROW 422
-#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 423
-#define _LOAD_CONST_INLINE_WITH_NULL 424
+#define _LOAD_CONST_INLINE 430
+#define _LOAD_CONST_INLINE_BORROW 431
+#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 432
+#define _LOAD_CONST_INLINE_WITH_NULL 433
 #define _LOAD_CONST_MORTAL LOAD_CONST_MORTAL
 #define _LOAD_DEREF LOAD_DEREF
-#define _LOAD_FAST 425
-#define _LOAD_FAST_0 426
-#define _LOAD_FAST_1 427
-#define _LOAD_FAST_2 428
-#define _LOAD_FAST_3 429
-#define _LOAD_FAST_4 430
-#define _LOAD_FAST_5 431
-#define _LOAD_FAST_6 432
-#define _LOAD_FAST_7 433
+#define _LOAD_FAST 434
+#define _LOAD_FAST_0 435
+#define _LOAD_FAST_1 436
+#define _LOAD_FAST_2 437
+#define _LOAD_FAST_3 438
+#define _LOAD_FAST_4 439
+#define _LOAD_FAST_5 440
+#define _LOAD_FAST_6 441
+#define _LOAD_FAST_7 442
 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK
 #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_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
-#define _LOAD_GLOBAL 434
-#define _LOAD_GLOBAL_BUILTINS 435
-#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 436
-#define _LOAD_GLOBAL_MODULE 437
-#define _LOAD_GLOBAL_MODULE_FROM_KEYS 438
+#define _LOAD_GLOBAL 443
+#define _LOAD_GLOBAL_BUILTINS 444
+#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 445
+#define _LOAD_GLOBAL_MODULE 446
+#define _LOAD_GLOBAL_MODULE_FROM_KEYS 447
 #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_SMALL_INT 443
-#define _LOAD_SMALL_INT_0 444
-#define _LOAD_SMALL_INT_1 445
-#define _LOAD_SMALL_INT_2 446
-#define _LOAD_SMALL_INT_3 447
+#define _LOAD_SMALL_INT 448
+#define _LOAD_SMALL_INT_0 449
+#define _LOAD_SMALL_INT_1 450
+#define _LOAD_SMALL_INT_2 451
+#define _LOAD_SMALL_INT_3 452
 #define _LOAD_SPECIAL LOAD_SPECIAL
 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
-#define _LOAD_SUPER_METHOD_METHOD LOAD_SUPER_METHOD_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 448
+#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
+#define _MAKE_CALLARGS_A_TUPLE 453
 #define _MAKE_CELL MAKE_CELL
 #define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 449
+#define _MAKE_WARM 454
 #define _MAP_ADD MAP_ADD
 #define _MATCH_CLASS MATCH_CLASS
 #define _MATCH_KEYS MATCH_KEYS
 #define _MATCH_MAPPING MATCH_MAPPING
 #define _MATCH_SEQUENCE MATCH_SEQUENCE
-#define _MAYBE_EXPAND_METHOD 450
-#define _MAYBE_EXPAND_METHOD_KW 451
-#define _MONITOR_CALL 452
-#define _MONITOR_JUMP_BACKWARD 453
-#define _MONITOR_RESUME 454
+#define _MAYBE_EXPAND_METHOD 455
+#define _MAYBE_EXPAND_METHOD_KW 456
+#define _MONITOR_CALL 457
+#define _MONITOR_JUMP_BACKWARD 458
+#define _MONITOR_RESUME 459
 #define _NOP NOP
 #define _POP_EXCEPT POP_EXCEPT
-#define _POP_JUMP_IF_FALSE 455
-#define _POP_JUMP_IF_TRUE 456
+#define _POP_JUMP_IF_FALSE 460
+#define _POP_JUMP_IF_TRUE 461
 #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_FRAME 458
+#define _PUSH_FRAME 463
 #define _PUSH_NULL PUSH_NULL
-#define _PY_FRAME_GENERAL 459
-#define _PY_FRAME_KW 460
-#define _QUICKEN_RESUME 461
-#define _REPLACE_WITH_TRUE 462
+#define _PY_FRAME_GENERAL 464
+#define _PY_FRAME_KW 465
+#define _QUICKEN_RESUME 466
+#define _REPLACE_WITH_TRUE 467
 #define _RESUME_CHECK RESUME_CHECK
 #define _RETURN_GENERATOR RETURN_GENERATOR
 #define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 463
-#define _SEND 464
-#define _SEND_GEN_FRAME 465
+#define _SAVE_RETURN_OFFSET 468
+#define _SEND 469
+#define _SEND_GEN_FRAME 470
 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
 #define _SET_ADD SET_ADD
 #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
 #define _SET_UPDATE SET_UPDATE
-#define _START_EXECUTOR 466
-#define _STORE_ATTR 467
-#define _STORE_ATTR_INSTANCE_VALUE 468
-#define _STORE_ATTR_SLOT 469
-#define _STORE_ATTR_WITH_HINT 470
+#define _START_EXECUTOR 471
+#define _STORE_ATTR 472
+#define _STORE_ATTR_INSTANCE_VALUE 473
+#define _STORE_ATTR_SLOT 474
+#define _STORE_ATTR_WITH_HINT 475
 #define _STORE_DEREF STORE_DEREF
-#define _STORE_FAST 471
-#define _STORE_FAST_0 472
-#define _STORE_FAST_1 473
-#define _STORE_FAST_2 474
-#define _STORE_FAST_3 475
-#define _STORE_FAST_4 476
-#define _STORE_FAST_5 477
-#define _STORE_FAST_6 478
-#define _STORE_FAST_7 479
+#define _STORE_FAST 476
+#define _STORE_FAST_0 477
+#define _STORE_FAST_1 478
+#define _STORE_FAST_2 479
+#define _STORE_FAST_3 480
+#define _STORE_FAST_4 481
+#define _STORE_FAST_5 482
+#define _STORE_FAST_6 483
+#define _STORE_FAST_7 484
 #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
 #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
 #define _STORE_GLOBAL STORE_GLOBAL
 #define _STORE_NAME STORE_NAME
-#define _STORE_SLICE 480
-#define _STORE_SUBSCR 481
+#define _STORE_SLICE 485
+#define _STORE_SUBSCR 486
 #define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
 #define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
 #define _SWAP SWAP
-#define _TIER2_RESUME_CHECK 482
-#define _TO_BOOL 483
+#define _TIER2_RESUME_CHECK 487
+#define _TO_BOOL 488
 #define _TO_BOOL_BOOL TO_BOOL_BOOL
 #define _TO_BOOL_INT TO_BOOL_INT
 #define _TO_BOOL_LIST TO_BOOL_LIST
@@ -306,13 +310,13 @@ extern "C" {
 #define _UNARY_NEGATIVE UNARY_NEGATIVE
 #define _UNARY_NOT UNARY_NOT
 #define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 484
+#define _UNPACK_SEQUENCE 489
 #define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
 #define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
 #define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
 #define _WITH_EXCEPT_START WITH_EXCEPT_START
 #define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 484
+#define MAX_UOP_ID 489
 
 #ifdef __cplusplus
 }
index 4d97a26ec6478a8db4005aeb056c9376cab8ddcc..c9bef792e5b3e35bbccc3f7431782ed324b7a05d 100644 (file)
@@ -127,8 +127,8 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
     [_GUARD_GLOBALS_VERSION] = HAS_DEOPT_FLAG,
     [_GUARD_GLOBALS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG,
     [_GUARD_BUILTINS_VERSION_PUSH_KEYS] = HAS_DEOPT_FLAG,
-    [_LOAD_GLOBAL_MODULE_FROM_KEYS] = HAS_DEOPT_FLAG,
-    [_LOAD_GLOBAL_BUILTINS_FROM_KEYS] = HAS_DEOPT_FLAG,
+    [_LOAD_GLOBAL_MODULE_FROM_KEYS] = HAS_ARG_FLAG | 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,
     [_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,
@@ -148,21 +148,26 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
     [_DICT_MERGE] = 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_METHOD_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_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_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_AND_LOCK] = HAS_EXIT_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,
-    [_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,
     [_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,
-    [_LOAD_ATTR_CLASS] = 0,
-    [_LOAD_ATTR_PROPERTY_FRAME] = HAS_DEOPT_FLAG,
+    [_LOAD_ATTR_CLASS_0] = 0,
+    [_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,
     [_STORE_ATTR_INSTANCE_VALUE] = 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,
     [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG,
     [_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG,
-    [_LOAD_METHOD_WITH_VALUES] = 0,
-    [_LOAD_METHOD_NO_DICT] = 0,
-    [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = 0,
-    [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = 0,
+    [_LOAD_ATTR_METHOD_WITH_VALUES] = HAS_ARG_FLAG,
+    [_LOAD_ATTR_METHOD_NO_DICT] = HAS_ARG_FLAG,
+    [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = HAS_ARG_FLAG,
+    [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = HAS_ARG_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,
     [_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,
@@ -253,7 +258,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
     [_EXPAND_METHOD_KW] = HAS_ARG_FLAG | HAS_ESCAPES_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,
-    [_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,
     [_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_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_BORROW_WITH_NULL] = HAS_PURE_FLAG,
     [_CHECK_FUNCTION] = HAS_DEOPT_FLAG,
-    [_LOAD_GLOBAL_MODULE] = HAS_DEOPT_FLAG,
-    [_LOAD_GLOBAL_BUILTINS] = HAS_DEOPT_FLAG,
-    [_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG,
+    [_LOAD_GLOBAL_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_LOAD_GLOBAL_BUILTINS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
     [_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG,
     [_START_EXECUTOR] = HAS_ESCAPES_FLAG,
     [_MAKE_WARM] = 0,
@@ -452,13 +457,22 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
     [_LIST_EXTEND] = "_LIST_EXTEND",
     [_LOAD_ATTR] = "_LOAD_ATTR",
     [_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_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_FROM_KEYS] = "_LOAD_ATTR_MODULE_FROM_KEYS",
     [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
     [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
     [_LOAD_ATTR_PROPERTY_FRAME] = "_LOAD_ATTR_PROPERTY_FRAME",
     [_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_BUILD_CLASS] = "_LOAD_BUILD_CLASS",
     [_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_FROM_KEYS] = "_LOAD_GLOBAL_MODULE_FROM_KEYS",
     [_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_SMALL_INT] = "_LOAD_SMALL_INT",
     [_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_SPECIAL] = "_LOAD_SPECIAL",
     [_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_CELL] = "_MAKE_CELL",
     [_MAKE_FUNCTION] = "_MAKE_FUNCTION",
@@ -835,10 +845,8 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 2;
         case _LOAD_SUPER_ATTR_ATTR:
             return 3;
-        case _LOAD_SUPER_METHOD_METHOD:
+        case _LOAD_SUPER_ATTR_METHOD:
             return 3;
-        case _LOAD_METHOD:
-            return 1;
         case _LOAD_ATTR:
             return 1;
         case _GUARD_TYPE_VERSION:
@@ -847,6 +855,10 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 0;
         case _CHECK_MANAGED_OBJECT_HAS_VALUES:
             return 0;
+        case _LOAD_ATTR_INSTANCE_VALUE_0:
+            return 1;
+        case _LOAD_ATTR_INSTANCE_VALUE_1:
+            return 1;
         case _LOAD_ATTR_INSTANCE_VALUE:
             return 1;
         case _CHECK_ATTR_MODULE_PUSH_KEYS:
@@ -857,10 +869,18 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 0;
         case _LOAD_ATTR_WITH_HINT:
             return 2;
+        case _LOAD_ATTR_SLOT_0:
+            return 1;
+        case _LOAD_ATTR_SLOT_1:
+            return 1;
         case _LOAD_ATTR_SLOT:
             return 1;
         case _CHECK_ATTR_CLASS:
             return 0;
+        case _LOAD_ATTR_CLASS_0:
+            return 1;
+        case _LOAD_ATTR_CLASS_1:
+            return 1;
         case _LOAD_ATTR_CLASS:
             return 1;
         case _LOAD_ATTR_PROPERTY_FRAME:
@@ -945,9 +965,9 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 0;
         case _GUARD_KEYS_VERSION:
             return 0;
-        case _LOAD_METHOD_WITH_VALUES:
+        case _LOAD_ATTR_METHOD_WITH_VALUES:
             return 1;
-        case _LOAD_METHOD_NO_DICT:
+        case _LOAD_ATTR_METHOD_NO_DICT:
             return 1;
         case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
             return 1;
@@ -955,7 +975,7 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 1;
         case _CHECK_ATTR_METHOD_LAZY_DICT:
             return 0;
-        case _LOAD_METHOD_LAZY_DICT:
+        case _LOAD_ATTR_METHOD_LAZY_DICT:
             return 1;
         case _MAYBE_EXPAND_METHOD:
             return 2 + oparg;
@@ -1046,7 +1066,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _CALL_KW_NON_PY:
             return 3 + oparg;
         case _MAKE_CALLARGS_A_TUPLE:
-            return 2;
+            return 1 + (oparg & 1);
         case _MAKE_FUNCTION:
             return 1;
         case _SET_FUNCTION_ATTRIBUTE:
@@ -1054,7 +1074,7 @@ int _PyUop_num_popped(int opcode, int oparg)
         case _RETURN_GENERATOR:
             return 0;
         case _BUILD_SLICE:
-            return oparg;
+            return 2 + ((oparg == 3) ? 1 : 0);
         case _CONVERT_VALUE:
             return 1;
         case _FORMAT_SIMPLE:
index e931e76bdb193a38a6da941244ebfd63b933054c..06b207b347e50427e3c1fda5536b3b0114829ab5 100644 (file)
@@ -14,55 +14,55 @@ extern "C" {
 #define BINARY_SLICE                             1
 #define BINARY_SUBSCR                            2
 #define BINARY_OP_INPLACE_ADD_UNICODE            3
-#define CALL_FUNCTION_EX                         4
-#define CHECK_EG_MATCH                           5
-#define CHECK_EXC_MATCH                          6
-#define CLEANUP_THROW                            7
-#define DELETE_SUBSCR                            8
-#define END_ASYNC_FOR                            9
-#define END_FOR                                 10
-#define END_SEND                                11
-#define EXIT_INIT_CHECK                         12
-#define FORMAT_SIMPLE                           13
-#define FORMAT_WITH_SPEC                        14
-#define GET_AITER                               15
-#define GET_ANEXT                               16
+#define CHECK_EG_MATCH                           4
+#define CHECK_EXC_MATCH                          5
+#define CLEANUP_THROW                            6
+#define DELETE_SUBSCR                            7
+#define END_ASYNC_FOR                            8
+#define END_FOR                                  9
+#define END_SEND                                10
+#define EXIT_INIT_CHECK                         11
+#define FORMAT_SIMPLE                           12
+#define FORMAT_WITH_SPEC                        13
+#define GET_AITER                               14
+#define GET_ANEXT                               15
+#define GET_ITER                                16
 #define RESERVED                                17
-#define GET_ITER                                18
-#define GET_LEN                                 19
-#define GET_YIELD_FROM_ITER                     20
-#define INTERPRETER_EXIT                        21
-#define LOAD_BUILD_CLASS                        22
-#define LOAD_LOCALS                             23
-#define MAKE_FUNCTION                           24
-#define MATCH_KEYS                              25
-#define MATCH_MAPPING                           26
-#define MATCH_SEQUENCE                          27
-#define NOP                                     28
-#define NOT_TAKEN                               29
-#define POP_EXCEPT                              30
-#define POP_ITER                                31
-#define POP_TOP                                 32
-#define PUSH_EXC_INFO                           33
-#define PUSH_NULL                               34
-#define RETURN_GENERATOR                        35
-#define RETURN_VALUE                            36
-#define SETUP_ANNOTATIONS                       37
-#define STORE_SLICE                             38
-#define STORE_SUBSCR                            39
-#define TO_BOOL                                 40
-#define UNARY_INVERT                            41
-#define UNARY_NEGATIVE                          42
-#define UNARY_NOT                               43
-#define WITH_EXCEPT_START                       44
-#define BINARY_OP                               45
-#define BUILD_LIST                              46
-#define BUILD_MAP                               47
-#define BUILD_SET                               48
-#define BUILD_SLICE                             49
-#define BUILD_STRING                            50
-#define BUILD_TUPLE                             51
-#define CALL                                    52
+#define GET_LEN                                 18
+#define GET_YIELD_FROM_ITER                     19
+#define INTERPRETER_EXIT                        20
+#define LOAD_BUILD_CLASS                        21
+#define LOAD_LOCALS                             22
+#define MAKE_FUNCTION                           23
+#define MATCH_KEYS                              24
+#define MATCH_MAPPING                           25
+#define MATCH_SEQUENCE                          26
+#define NOP                                     27
+#define NOT_TAKEN                               28
+#define POP_EXCEPT                              29
+#define POP_ITER                                30
+#define POP_TOP                                 31
+#define PUSH_EXC_INFO                           32
+#define PUSH_NULL                               33
+#define RETURN_GENERATOR                        34
+#define RETURN_VALUE                            35
+#define SETUP_ANNOTATIONS                       36
+#define STORE_SLICE                             37
+#define STORE_SUBSCR                            38
+#define TO_BOOL                                 39
+#define UNARY_INVERT                            40
+#define UNARY_NEGATIVE                          41
+#define UNARY_NOT                               42
+#define WITH_EXCEPT_START                       43
+#define BINARY_OP                               44
+#define BUILD_LIST                              45
+#define BUILD_MAP                               46
+#define BUILD_SET                               47
+#define BUILD_SLICE                             48
+#define BUILD_STRING                            49
+#define BUILD_TUPLE                             50
+#define CALL                                    51
+#define CALL_FUNCTION_EX                        52
 #define CALL_INTRINSIC_1                        53
 #define CALL_INTRINSIC_2                        54
 #define CALL_KW                                 55
@@ -100,36 +100,34 @@ extern "C" {
 #define LOAD_FROM_DICT_OR_DEREF                 87
 #define LOAD_FROM_DICT_OR_GLOBALS               88
 #define LOAD_GLOBAL                             89
-#define LOAD_METHOD                             90
-#define LOAD_NAME                               91
-#define LOAD_SMALL_INT                          92
-#define LOAD_SPECIAL                            93
-#define LOAD_SUPER_ATTR                         94
-#define LOAD_SUPER_METHOD                       95
-#define MAKE_CELL                               96
-#define MAP_ADD                                 97
-#define MATCH_CLASS                             98
-#define POP_JUMP_IF_FALSE                       99
-#define POP_JUMP_IF_NONE                       100
-#define POP_JUMP_IF_NOT_NONE                   101
-#define POP_JUMP_IF_TRUE                       102
-#define RAISE_VARARGS                          103
-#define RERAISE                                104
-#define SEND                                   105
-#define SET_ADD                                106
-#define SET_FUNCTION_ATTRIBUTE                 107
-#define SET_UPDATE                             108
-#define STORE_ATTR                             109
-#define STORE_DEREF                            110
-#define STORE_FAST                             111
-#define STORE_FAST_LOAD_FAST                   112
-#define STORE_FAST_STORE_FAST                  113
-#define STORE_GLOBAL                           114
-#define STORE_NAME                             115
-#define SWAP                                   116
-#define UNPACK_EX                              117
-#define UNPACK_SEQUENCE                        118
-#define YIELD_VALUE                            119
+#define LOAD_NAME                               90
+#define LOAD_SMALL_INT                          91
+#define LOAD_SPECIAL                            92
+#define LOAD_SUPER_ATTR                         93
+#define MAKE_CELL                               94
+#define MAP_ADD                                 95
+#define MATCH_CLASS                             96
+#define POP_JUMP_IF_FALSE                       97
+#define POP_JUMP_IF_NONE                        98
+#define POP_JUMP_IF_NOT_NONE                    99
+#define POP_JUMP_IF_TRUE                       100
+#define RAISE_VARARGS                          101
+#define RERAISE                                102
+#define SEND                                   103
+#define SET_ADD                                104
+#define SET_FUNCTION_ATTRIBUTE                 105
+#define SET_UPDATE                             106
+#define STORE_ATTR                             107
+#define STORE_DEREF                            108
+#define STORE_FAST                             109
+#define STORE_FAST_LOAD_FAST                   110
+#define STORE_FAST_STORE_FAST                  111
+#define STORE_GLOBAL                           112
+#define STORE_NAME                             113
+#define SWAP                                   114
+#define UNPACK_EX                              115
+#define UNPACK_SEQUENCE                        116
+#define YIELD_VALUE                            117
 #define RESUME                                 149
 #define BINARY_OP_ADD_FLOAT                    150
 #define BINARY_OP_ADD_INT                      151
@@ -180,21 +178,21 @@ extern "C" {
 #define LOAD_ATTR_CLASS_WITH_METACLASS_CHECK   196
 #define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN      197
 #define LOAD_ATTR_INSTANCE_VALUE               198
-#define LOAD_ATTR_MODULE                       199
-#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT        200
-#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES    201
-#define LOAD_ATTR_PROPERTY                     202
-#define LOAD_ATTR_SLOT                         203
-#define LOAD_ATTR_WITH_HINT                    204
-#define LOAD_CONST_IMMORTAL                    205
-#define LOAD_CONST_MORTAL                      206
-#define LOAD_GLOBAL_BUILTIN                    207
-#define LOAD_GLOBAL_MODULE                     208
-#define LOAD_METHOD_LAZY_DICT                  209
-#define LOAD_METHOD_NO_DICT                    210
-#define LOAD_METHOD_WITH_VALUES                211
+#define LOAD_ATTR_METHOD_LAZY_DICT             199
+#define LOAD_ATTR_METHOD_NO_DICT               200
+#define LOAD_ATTR_METHOD_WITH_VALUES           201
+#define LOAD_ATTR_MODULE                       202
+#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT        203
+#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES    204
+#define LOAD_ATTR_PROPERTY                     205
+#define LOAD_ATTR_SLOT                         206
+#define LOAD_ATTR_WITH_HINT                    207
+#define LOAD_CONST_IMMORTAL                    208
+#define LOAD_CONST_MORTAL                      209
+#define LOAD_GLOBAL_BUILTIN                    210
+#define LOAD_GLOBAL_MODULE                     211
 #define LOAD_SUPER_ATTR_ATTR                   212
-#define LOAD_SUPER_METHOD_METHOD               213
+#define LOAD_SUPER_ATTR_METHOD                 213
 #define RESUME_CHECK                           214
 #define SEND_GEN                               215
 #define STORE_ATTR_INSTANCE_VALUE              216
@@ -211,11 +209,10 @@ extern "C" {
 #define UNPACK_SEQUENCE_LIST                   227
 #define UNPACK_SEQUENCE_TUPLE                  228
 #define UNPACK_SEQUENCE_TWO_TUPLE              229
-#define INSTRUMENTED_END_FOR                   234
-#define INSTRUMENTED_POP_ITER                  235
-#define INSTRUMENTED_END_SEND                  236
-#define INSTRUMENTED_LOAD_SUPER_ATTR           237
-#define INSTRUMENTED_LOAD_SUPER_METHOD         238
+#define INSTRUMENTED_END_FOR                   235
+#define INSTRUMENTED_POP_ITER                  236
+#define INSTRUMENTED_END_SEND                  237
+#define INSTRUMENTED_LOAD_SUPER_ATTR           238
 #define INSTRUMENTED_FOR_ITER                  239
 #define INSTRUMENTED_CALL_KW                   240
 #define INSTRUMENTED_CALL_FUNCTION_EX          241
@@ -244,9 +241,9 @@ extern "C" {
 #define SETUP_WITH                             264
 #define STORE_FAST_MAYBE_NULL                  265
 
-#define HAVE_ARGUMENT                           44
+#define HAVE_ARGUMENT                           43
 #define MIN_SPECIALIZED_OPCODE                 150
-#define MIN_INSTRUMENTED_OPCODE                234
+#define MIN_INSTRUMENTED_OPCODE                235
 
 #ifdef __cplusplus
 }
index a32e6fe953b78233141b28bf4dcbda3aa904e2f6..7dd528ef74df3362b628b81a70ea891e9b8e7510 100644 (file)
@@ -59,9 +59,7 @@ _specializations = {
     ],
     "LOAD_SUPER_ATTR": [
         "LOAD_SUPER_ATTR_ATTR",
-    ],
-    "LOAD_SUPER_METHOD": [
-        "LOAD_SUPER_METHOD_METHOD",
+        "LOAD_SUPER_ATTR_METHOD",
     ],
     "LOAD_ATTR": [
         "LOAD_ATTR_INSTANCE_VALUE",
@@ -72,14 +70,12 @@ _specializations = {
         "LOAD_ATTR_CLASS_WITH_METACLASS_CHECK",
         "LOAD_ATTR_PROPERTY",
         "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_NO_DICT",
     ],
-    "LOAD_METHOD": [
-        "LOAD_METHOD_WITH_VALUES",
-        "LOAD_METHOD_NO_DICT",
-        "LOAD_METHOD_LAZY_DICT",
-    ],
     "COMPARE_OP": [
         "COMPARE_OP_FLOAT",
         "COMPARE_OP_INT",
@@ -175,21 +171,21 @@ _specialized_opmap = {
     'LOAD_ATTR_CLASS_WITH_METACLASS_CHECK': 196,
     'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 197,
     'LOAD_ATTR_INSTANCE_VALUE': 198,
-    'LOAD_ATTR_MODULE': 199,
-    'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 200,
-    'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 201,
-    'LOAD_ATTR_PROPERTY': 202,
-    'LOAD_ATTR_SLOT': 203,
-    'LOAD_ATTR_WITH_HINT': 204,
-    'LOAD_CONST_IMMORTAL': 205,
-    'LOAD_CONST_MORTAL': 206,
-    'LOAD_GLOBAL_BUILTIN': 207,
-    'LOAD_GLOBAL_MODULE': 208,
-    'LOAD_METHOD_LAZY_DICT': 209,
-    'LOAD_METHOD_NO_DICT': 210,
-    'LOAD_METHOD_WITH_VALUES': 211,
+    'LOAD_ATTR_METHOD_LAZY_DICT': 199,
+    'LOAD_ATTR_METHOD_NO_DICT': 200,
+    'LOAD_ATTR_METHOD_WITH_VALUES': 201,
+    'LOAD_ATTR_MODULE': 202,
+    'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 203,
+    'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 204,
+    'LOAD_ATTR_PROPERTY': 205,
+    'LOAD_ATTR_SLOT': 206,
+    'LOAD_ATTR_WITH_HINT': 207,
+    'LOAD_CONST_IMMORTAL': 208,
+    'LOAD_CONST_MORTAL': 209,
+    'LOAD_GLOBAL_BUILTIN': 210,
+    'LOAD_GLOBAL_MODULE': 211,
     'LOAD_SUPER_ATTR_ATTR': 212,
-    'LOAD_SUPER_METHOD_METHOD': 213,
+    'LOAD_SUPER_ATTR_METHOD': 213,
     'RESUME_CHECK': 214,
     'SEND_GEN': 215,
     'STORE_ATTR_INSTANCE_VALUE': 216,
@@ -216,54 +212,54 @@ opmap = {
     'ENTER_EXECUTOR': 255,
     'BINARY_SLICE': 1,
     'BINARY_SUBSCR': 2,
-    'CALL_FUNCTION_EX': 4,
-    'CHECK_EG_MATCH': 5,
-    'CHECK_EXC_MATCH': 6,
-    'CLEANUP_THROW': 7,
-    'DELETE_SUBSCR': 8,
-    'END_ASYNC_FOR': 9,
-    'END_FOR': 10,
-    'END_SEND': 11,
-    'EXIT_INIT_CHECK': 12,
-    'FORMAT_SIMPLE': 13,
-    'FORMAT_WITH_SPEC': 14,
-    'GET_AITER': 15,
-    'GET_ANEXT': 16,
-    'GET_ITER': 18,
-    'GET_LEN': 19,
-    'GET_YIELD_FROM_ITER': 20,
-    'INTERPRETER_EXIT': 21,
-    'LOAD_BUILD_CLASS': 22,
-    'LOAD_LOCALS': 23,
-    'MAKE_FUNCTION': 24,
-    'MATCH_KEYS': 25,
-    'MATCH_MAPPING': 26,
-    'MATCH_SEQUENCE': 27,
-    'NOP': 28,
-    'NOT_TAKEN': 29,
-    'POP_EXCEPT': 30,
-    'POP_ITER': 31,
-    'POP_TOP': 32,
-    'PUSH_EXC_INFO': 33,
-    'PUSH_NULL': 34,
-    'RETURN_GENERATOR': 35,
-    'RETURN_VALUE': 36,
-    'SETUP_ANNOTATIONS': 37,
-    'STORE_SLICE': 38,
-    'STORE_SUBSCR': 39,
-    'TO_BOOL': 40,
-    'UNARY_INVERT': 41,
-    'UNARY_NEGATIVE': 42,
-    'UNARY_NOT': 43,
-    'WITH_EXCEPT_START': 44,
-    'BINARY_OP': 45,
-    'BUILD_LIST': 46,
-    'BUILD_MAP': 47,
-    'BUILD_SET': 48,
-    'BUILD_SLICE': 49,
-    'BUILD_STRING': 50,
-    'BUILD_TUPLE': 51,
-    'CALL': 52,
+    'CHECK_EG_MATCH': 4,
+    'CHECK_EXC_MATCH': 5,
+    'CLEANUP_THROW': 6,
+    'DELETE_SUBSCR': 7,
+    'END_ASYNC_FOR': 8,
+    'END_FOR': 9,
+    'END_SEND': 10,
+    'EXIT_INIT_CHECK': 11,
+    'FORMAT_SIMPLE': 12,
+    'FORMAT_WITH_SPEC': 13,
+    'GET_AITER': 14,
+    'GET_ANEXT': 15,
+    'GET_ITER': 16,
+    'GET_LEN': 18,
+    'GET_YIELD_FROM_ITER': 19,
+    'INTERPRETER_EXIT': 20,
+    'LOAD_BUILD_CLASS': 21,
+    'LOAD_LOCALS': 22,
+    'MAKE_FUNCTION': 23,
+    'MATCH_KEYS': 24,
+    'MATCH_MAPPING': 25,
+    'MATCH_SEQUENCE': 26,
+    'NOP': 27,
+    'NOT_TAKEN': 28,
+    'POP_EXCEPT': 29,
+    'POP_ITER': 30,
+    'POP_TOP': 31,
+    'PUSH_EXC_INFO': 32,
+    'PUSH_NULL': 33,
+    'RETURN_GENERATOR': 34,
+    'RETURN_VALUE': 35,
+    'SETUP_ANNOTATIONS': 36,
+    'STORE_SLICE': 37,
+    'STORE_SUBSCR': 38,
+    'TO_BOOL': 39,
+    'UNARY_INVERT': 40,
+    'UNARY_NEGATIVE': 41,
+    'UNARY_NOT': 42,
+    'WITH_EXCEPT_START': 43,
+    'BINARY_OP': 44,
+    'BUILD_LIST': 45,
+    'BUILD_MAP': 46,
+    'BUILD_SET': 47,
+    'BUILD_SLICE': 48,
+    'BUILD_STRING': 49,
+    'BUILD_TUPLE': 50,
+    'CALL': 51,
+    'CALL_FUNCTION_EX': 52,
     'CALL_INTRINSIC_1': 53,
     'CALL_INTRINSIC_2': 54,
     'CALL_KW': 55,
@@ -301,41 +297,38 @@ opmap = {
     'LOAD_FROM_DICT_OR_DEREF': 87,
     'LOAD_FROM_DICT_OR_GLOBALS': 88,
     'LOAD_GLOBAL': 89,
-    'LOAD_METHOD': 90,
-    'LOAD_NAME': 91,
-    'LOAD_SMALL_INT': 92,
-    'LOAD_SPECIAL': 93,
-    'LOAD_SUPER_ATTR': 94,
-    'LOAD_SUPER_METHOD': 95,
-    'MAKE_CELL': 96,
-    'MAP_ADD': 97,
-    'MATCH_CLASS': 98,
-    'POP_JUMP_IF_FALSE': 99,
-    'POP_JUMP_IF_NONE': 100,
-    'POP_JUMP_IF_NOT_NONE': 101,
-    'POP_JUMP_IF_TRUE': 102,
-    'RAISE_VARARGS': 103,
-    'RERAISE': 104,
-    'SEND': 105,
-    'SET_ADD': 106,
-    'SET_FUNCTION_ATTRIBUTE': 107,
-    'SET_UPDATE': 108,
-    'STORE_ATTR': 109,
-    'STORE_DEREF': 110,
-    'STORE_FAST': 111,
-    'STORE_FAST_LOAD_FAST': 112,
-    'STORE_FAST_STORE_FAST': 113,
-    'STORE_GLOBAL': 114,
-    'STORE_NAME': 115,
-    'SWAP': 116,
-    'UNPACK_EX': 117,
-    'UNPACK_SEQUENCE': 118,
-    'YIELD_VALUE': 119,
-    'INSTRUMENTED_END_FOR': 234,
-    'INSTRUMENTED_POP_ITER': 235,
-    'INSTRUMENTED_END_SEND': 236,
-    'INSTRUMENTED_LOAD_SUPER_ATTR': 237,
-    'INSTRUMENTED_LOAD_SUPER_METHOD': 238,
+    'LOAD_NAME': 90,
+    'LOAD_SMALL_INT': 91,
+    'LOAD_SPECIAL': 92,
+    'LOAD_SUPER_ATTR': 93,
+    'MAKE_CELL': 94,
+    'MAP_ADD': 95,
+    'MATCH_CLASS': 96,
+    'POP_JUMP_IF_FALSE': 97,
+    'POP_JUMP_IF_NONE': 98,
+    'POP_JUMP_IF_NOT_NONE': 99,
+    'POP_JUMP_IF_TRUE': 100,
+    'RAISE_VARARGS': 101,
+    'RERAISE': 102,
+    'SEND': 103,
+    'SET_ADD': 104,
+    'SET_FUNCTION_ATTRIBUTE': 105,
+    'SET_UPDATE': 106,
+    'STORE_ATTR': 107,
+    'STORE_DEREF': 108,
+    'STORE_FAST': 109,
+    'STORE_FAST_LOAD_FAST': 110,
+    'STORE_FAST_STORE_FAST': 111,
+    'STORE_GLOBAL': 112,
+    'STORE_NAME': 113,
+    'SWAP': 114,
+    'UNPACK_EX': 115,
+    'UNPACK_SEQUENCE': 116,
+    'YIELD_VALUE': 117,
+    'INSTRUMENTED_END_FOR': 235,
+    'INSTRUMENTED_POP_ITER': 236,
+    'INSTRUMENTED_END_SEND': 237,
+    'INSTRUMENTED_LOAD_SUPER_ATTR': 238,
     'INSTRUMENTED_FOR_ITER': 239,
     'INSTRUMENTED_CALL_KW': 240,
     'INSTRUMENTED_CALL_FUNCTION_EX': 241,
@@ -363,5 +356,5 @@ opmap = {
     'STORE_FAST_MAYBE_NULL': 265,
 }
 
-HAVE_ARGUMENT = 44
-MIN_INSTRUMENTED_OPCODE = 234
+HAVE_ARGUMENT = 43
+MIN_INSTRUMENTED_OPCODE = 235
index 5a34e228079481476744388191b75431af9b2e45..109c986bbe3d7d944ad3cc7a3eff9a31fba72143 100644 (file)
@@ -42,9 +42,7 @@ JUMP_BACKWARD = opmap['JUMP_BACKWARD']
 FOR_ITER = opmap['FOR_ITER']
 SEND = opmap['SEND']
 LOAD_ATTR = opmap['LOAD_ATTR']
-LOAD_METHOD = opmap['LOAD_METHOD']
 LOAD_SUPER_ATTR = opmap['LOAD_SUPER_ATTR']
-LOAD_SUPER_METHOD = opmap['LOAD_SUPER_METHOD']
 CALL_INTRINSIC_1 = opmap['CALL_INTRINSIC_1']
 CALL_INTRINSIC_2 = opmap['CALL_INTRINSIC_2']
 LOAD_COMMON_CONSTANT = opmap['LOAD_COMMON_CONSTANT']
@@ -582,14 +580,16 @@ class ArgResolver:
                 argval, argrepr = _get_const_info(deop, arg, self.co_consts)
             elif deop in hasname:
                 if deop == LOAD_GLOBAL:
-                    argval, argrepr = _get_name_info(arg, get_name)
-                elif deop == LOAD_ATTR or deop == LOAD_METHOD:
-                    argval, argrepr = _get_name_info(arg, get_name)
-                    if deop == LOAD_METHOD and argrepr:
+                    argval, argrepr = _get_name_info(arg//2, get_name)
+                    if (arg & 1) and argrepr:
+                        argrepr = f"{argrepr} + NULL"
+                elif deop == LOAD_ATTR:
+                    argval, argrepr = _get_name_info(arg//2, get_name)
+                    if (arg & 1) and argrepr:
                         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)
-                    if deop == LOAD_SUPER_METHOD and argrepr:
+                    if (arg & 1) and argrepr:
                         argrepr = f"{argrepr} + NULL|self"
                 else:
                     argval, argrepr = _get_name_info(arg, get_name)
index 3d9ff07a3cfb7b4d403a9aebb899ddcdbf56ee11..facad478103668c4051065c620a968fb772d6e3f 100644 (file)
@@ -1511,7 +1511,7 @@ def getclosurevars(func):
     for instruction in dis.get_instructions(code):
         opname = instruction.opname
         name = instruction.argval
-        if opname == "LOAD_ATTR" or opname == "LOAD_METHOD":
+        if opname == "LOAD_ATTR":
             unbound_names.add(name)
         elif opname == "LOAD_GLOBAL":
             global_names.add(name)
index d87149e95b5a33d0e32f24520f5bb8503b8867b1..4ee0d64026bd0a19eea9268ddef2151986565217 100644 (file)
@@ -72,21 +72,12 @@ _cache_format = {
     "LOAD_SUPER_ATTR": {
         "counter": 1,
     },
-    "LOAD_SUPER_METHOD": {
-        "counter": 1,
-    },
     "LOAD_ATTR": {
         "counter": 1,
         "version": 2,
         "keys_version": 2,
         "descr": 4,
     },
-    "LOAD_METHOD": {
-        "counter": 1,
-        "version": 2,
-        "keys_version": 2,
-        "descr": 4,
-    },
     "STORE_ATTR": {
         "counter": 1,
         "version": 2,
index 4b11e83ae59a78fb2d1247c284d2a26c72fbcc83..95e09500df51d06339f636859b8241e5c096fc23 100644 (file)
@@ -65,7 +65,8 @@ class OpListTests(unittest.TestCase):
 class StackEffectTests(unittest.TestCase):
     def test_stack_effect(self):
         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.assertRaises(ValueError, stack_effect, 30000)
         # All defined opcodes
index 6a2f7726222f9b28720791430711c2a792f6b4ee..9cfc6c142da6cd5ff4b5822fdd7c04ba9482d4c7 100644 (file)
@@ -711,7 +711,7 @@ class TestUopsOptimization(unittest.TestCase):
         assert ex is not None
         uops = get_opnames(ex)
         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)
 
index f4123d2a85f52b00a5706bdca8cbdd946411b227..b5cf2ad18fe60beb3f47280cf39561feef9a444c 100644 (file)
@@ -2157,7 +2157,7 @@ class TestSourcePositions(unittest.TestCase):
         source = "(\n lhs  \n   .    \n     rhs      \n       )()"
         code = compile(source, "<test>", "exec")
         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(
             code, "CALL", line=4, end_line=5, column=5, end_column=10
index 6fdcdbb0d9a3ad1748e8f303d1b4cf5ead9961bb..da57aad2f84fbd238ee9ba78b08c6b0d3835562e 100644 (file)
@@ -113,8 +113,7 @@ def _f(a):
 dis_f = """\
 %3d           RESUME                   0
 
-%3d           LOAD_GLOBAL              0 (print)
-              PUSH_NULL
+%3d           LOAD_GLOBAL              1 (print + NULL)
               LOAD_FAST                0 (a)
               CALL                     1
               POP_TOP
@@ -128,14 +127,13 @@ dis_f = """\
 dis_f_with_offsets = """\
 %3d          0       RESUME                   0
 
-%3d          2       LOAD_GLOBAL              0 (print)
-            12       PUSH_NULL
-            14       LOAD_FAST                0 (a)
-            16       CALL                     1
-            24       POP_TOP
+%3d          2       LOAD_GLOBAL              1 (print + NULL)
+            12       LOAD_FAST                0 (a)
+            14       CALL                     1
+            22       POP_TOP
 
-%3d         26       LOAD_SMALL_INT           1
-            28       RETURN_VALUE
+%3d         24       LOAD_SMALL_INT           1
+            26       RETURN_VALUE
 """ % (_f.__code__.co_firstlineno,
        _f.__code__.co_firstlineno + 1,
        _f.__code__.co_firstlineno + 2)
@@ -143,8 +141,7 @@ dis_f_with_offsets = """\
 dis_f_with_positions_format = f"""\
 %-14s           RESUME                   0
 
-%-14s           LOAD_GLOBAL              0 (print)
-%-14s           PUSH_NULL
+%-14s           LOAD_GLOBAL              1 (print + NULL)
 %-14s           LOAD_FAST                0 (a)
 %-14s           CALL                     1
 %-14s           POP_TOP
@@ -155,8 +152,7 @@ dis_f_with_positions_format = f"""\
 
 dis_f_co_code = """\
           RESUME                   0
-          LOAD_GLOBAL              0
-          PUSH_NULL
+          LOAD_GLOBAL              1
           LOAD_FAST                0
           CALL                     1
           POP_TOP
@@ -172,8 +168,7 @@ def bug708901():
 dis_bug708901 = """\
 %3d           RESUME                   0
 
-%3d           LOAD_GLOBAL              0 (range)
-              PUSH_NULL
+%3d           LOAD_GLOBAL              1 (range + NULL)
               LOAD_SMALL_INT           1
 
 %3d           LOAD_SMALL_INT          10
@@ -281,8 +276,7 @@ def wrap_func_w_kwargs():
 dis_kw_names = """\
 %3d           RESUME                   0
 
-%3d           LOAD_GLOBAL              0 (func_w_kwargs)
-              PUSH_NULL
+%3d           LOAD_GLOBAL              1 (func_w_kwargs + NULL)
               LOAD_SMALL_INT           1
               LOAD_SMALL_INT           2
               LOAD_SMALL_INT           5
@@ -469,7 +463,7 @@ dis_traceback = """\
                STORE_FAST               0 (e)
 
 %4d   L4:     LOAD_FAST                0 (e)
-               LOAD_ATTR                1 (__traceback__)
+               LOAD_ATTR                2 (__traceback__)
                STORE_FAST               1 (tb)
        L5:     POP_EXCEPT
                LOAD_CONST               0 (None)
@@ -820,8 +814,7 @@ Disassembly of <code object foo at 0x..., file "%s", line %d>:
 
 %4d           RESUME                   0
 
-%4d           LOAD_GLOBAL              0 (list)
-               PUSH_NULL
+%4d           LOAD_GLOBAL              1 (list + NULL)
                LOAD_FAST                0 (x)
                BUILD_TUPLE              1
                LOAD_CONST               1 (<code object <genexpr> at 0x..., file "%s", line %d>)
@@ -904,15 +897,14 @@ dis_loop_test_quickened_code = """\
               LOAD_SMALL_INT           3
               BINARY_OP                5 (*)
               GET_ITER
-      L1:     FOR_ITER_LIST           15 (to L2)
+      L1:     FOR_ITER_LIST           14 (to L2)
               STORE_FAST               0 (i)
 
-%3d           LOAD_GLOBAL_MODULE       0 (load_test)
-              PUSH_NULL
+%3d           LOAD_GLOBAL_MODULE       1 (load_test + NULL)
               LOAD_FAST                0 (i)
               CALL_PY_GENERAL          1
               POP_TOP
-              JUMP_BACKWARD           17 (to L1)
+              JUMP_BACKWARD           16 (to L1)
 
 %3d   L2:     END_FOR
               POP_ITER
@@ -1713,215 +1705,203 @@ def _prepare_test_cases():
 Instruction = dis.Instruction
 
 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=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=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=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='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=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='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='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=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='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='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='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=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=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=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=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
-  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=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=60, start_offset=60, starts_line=True, 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),
+  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=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=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=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=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='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=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_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_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='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_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='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='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='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='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='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),
 ]
 
 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='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=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=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=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='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=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=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='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='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=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='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='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='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=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=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=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=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=60, start_offset=60, starts_line=True, 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),
+  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=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=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=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=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='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=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=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=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='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='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='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='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),
 ]
 
 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='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='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=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=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=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
-  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=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=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),
+  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='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=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=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=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_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='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='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='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='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),
 ]
 
 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='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='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=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=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=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=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=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=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='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='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='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='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_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='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='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='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='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='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_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='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='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='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='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='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='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='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='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='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_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='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='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='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='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='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='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='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='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='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='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=152, start_offset=152, starts_line=False, line_number=12, 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='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='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_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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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_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='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='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='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_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='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='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='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='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='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='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='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='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_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=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='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_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='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=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=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=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_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=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='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='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='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='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_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='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='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_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='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='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='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='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='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_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='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='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='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=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='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='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='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='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='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='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='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='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_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='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_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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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),
+  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='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='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='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='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='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='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_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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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_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='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='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='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='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='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='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_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='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_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='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='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='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='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='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='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_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='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='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=174, start_offset=174, starts_line=True, line_number=14, 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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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='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_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='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=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='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='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_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='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='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_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='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='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='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='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='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='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='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_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='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='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='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='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=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='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='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='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='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='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='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='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='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='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='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='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='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='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='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_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='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='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_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='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='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='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='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='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='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_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='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='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='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='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_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='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='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='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='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='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='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='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='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='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='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='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='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='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='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),
 ]
 
 # One last piece of inspect fodder to check the default line number handling
@@ -1929,7 +1909,7 @@ def simple(): pass
 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='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 @@ class InstructionTests(InstructionTestCase):
         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["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["COMPARE_OP"], 3, *args), ('<', '<'))
         self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults'))
index c93d6fc3d237a2b6613f7be0f9a5c3f53673b8cf..b5367a0f3ca367276d5095025dbdd6813bd0fbc5 100644 (file)
@@ -59,14 +59,14 @@ class TestEffects(unittest.TestCase):
     def test_effect_sizes(self):
         stack = Stack()
         inputs = [
-            x := StackItem("x", None, "1"),
-            y := StackItem("y", None, "oparg"),
-            z := StackItem("z", None, "oparg*2"),
+            x := StackItem("x", None, "", "1"),
+            y := StackItem("y", None, "", "oparg"),
+            z := StackItem("z", None, "", "oparg*2"),
         ]
         outputs = [
-            StackItem("x", None, "1"),
-            StackItem("b", None, "oparg*4"),
-            StackItem("c", None, "1"),
+            StackItem("x", None, "", "1"),
+            StackItem("b", None, "", "oparg*4"),
+            StackItem("c", None, "", "1"),
         ]
         stack.pop(z)
         stack.pop(y)
@@ -104,6 +104,20 @@ class TestGenerateMaxStackEffect(unittest.TestCase):
         """
         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):
         input = """
         op(A, (-- val1)) {
@@ -124,6 +138,25 @@ class TestGenerateMaxStackEffect(unittest.TestCase):
         """
         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):
         input = """
         inst(OP, (values[oparg] -- values[oparg], above)) {
@@ -905,6 +938,90 @@ class TestGeneratedCases(unittest.TestCase):
     """
         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):
         input = """
         op(A, (-- val1)) {
index 7ac2910cfb785445d56d7a92e10e84a8da46a394..364381e7dce00a414a21da76c2c982a23e8b0128 100644 (file)
@@ -1588,11 +1588,11 @@ class TestBranchAndJumpEvents(CheckEvents):
             ('branch right', 'whilefunc', 1, 3)])
 
         self.check_events(func, recorders = BRANCH_OFFSET_RECORDERS, expected = [
-            ('branch left', 'func', 30, 34),
-            ('branch right', 'func', 46, 60),
-            ('branch left', 'func', 30, 34),
-            ('branch left', 'func', 46, 52),
-            ('branch right', 'func', 30, 72)])
+            ('branch left', 'func', 28, 32),
+            ('branch right', 'func', 44, 58),
+            ('branch left', 'func', 28, 32),
+            ('branch left', 'func', 44, 50),
+            ('branch right', 'func', 28, 70)])
 
     def test_except_star(self):
 
@@ -1762,8 +1762,7 @@ class TestLoadSuperAttr(CheckEvents):
         return self._exec(co)
 
     def _has_load_super_attr(self, co):
-        has = any(instr.opname in ("LOAD_SUPER_ATTR", "LOAD_SUPER_METHOD")
-                  for instr in dis.get_instructions(co))
+        has = any(instr.opname == "LOAD_SUPER_ATTR" for instr in dis.get_instructions(co))
         if not has:
             has = any(
                 isinstance(c, types.CodeType) and self._has_load_super_attr(c)
index 1895a5001fd3186ff52c66e331bc28d56bd182bf..4d7304b1c9abb67fd5814eaba890b0e5013bf2a9 100644 (file)
@@ -868,7 +868,7 @@ class TestRacesDoNotCrash(TestBase):
                     pass
                 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)
 
     @requires_specialization_ft
@@ -899,7 +899,7 @@ class TestRacesDoNotCrash(TestBase):
                     pass
                 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)
 
     @requires_specialization_ft
@@ -929,7 +929,7 @@ class TestRacesDoNotCrash(TestBase):
                     pass
                 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)
 
     @requires_specialization_ft
@@ -1424,9 +1424,8 @@ class TestSpecializer(TestBase):
             A()
 
         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_METHOD")
 
         # Temporarily replace super() with something else.
         real_super = super
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-01-17-10-17-01.gh-issue-128914.dn6RaW.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-01-17-10-17-01.gh-issue-128914.dn6RaW.rst
deleted file mode 100644 (file)
index 63f7159..0000000
+++ /dev/null
@@ -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.
index 44b3a2a75626c959b24dae8b623bfcd30440f7fa..15ec4b78235992819fe3a86f3d17d78271808a6e 100644 (file)
@@ -1261,18 +1261,27 @@ mark_stacks(PyCodeObject *code_obj, int len)
                     stacks[next_i] = next_stack;
                     break;
                 case LOAD_GLOBAL:
+                {
+                    int j = oparg;
                     next_stack = push_value(next_stack, Object);
+                    if (j & 1) {
+                        next_stack = push_value(next_stack, Null);
+                    }
                     stacks[next_i] = next_stack;
                     break;
+                }
                 case LOAD_ATTR:
+                {
                     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;
                     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:
                 {
                     int n = oparg;
index 0a15c1e1de5499c98e563df8c9566231cb94f109..51b6016b9c191c85fcdef7b0b3514367674fca30 100644 (file)
@@ -1551,7 +1551,7 @@ _PyObject_NextNotImplemented(PyObject *self)
 
 
 /* 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
    from __dict__ or something returned by using a descriptor
index be05fae1a6d831ad9be00ce2f351fcf43ec91327..4f6933ac0ddcd60fc34c21acb8ce73cbd06a20bd 100644 (file)
@@ -1,18 +1,18 @@
 // Auto-generated by Programs/freeze_test_frozenmain.py
 unsigned char M_test_frozenmain[] = {
     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,
-    72,0,115,0,92,0,81,0,72,1,115,1,91,2,34,0,
-    81,1,52,1,0,0,0,0,0,0,32,0,91,2,34,0,
-    81,2,91,0,79,3,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,
-    32,0,91,1,79,4,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,81,3,2,0,0,0,115,5,81,4,18,0,69,20,
-    0,0,115,6,91,2,34,0,81,5,91,6,13,0,81,6,
-    91,5,91,6,2,0,0,0,13,0,50,4,52,1,0,0,
-    0,0,0,0,32,0,74,22,0,0,10,0,31,0,81,0,
-    36,0,41,7,78,122,18,70,114,111,122,101,110,32,72,101,
+    0,0,0,0,0,243,168,0,0,0,149,0,91,0,81,0,
+    72,0,113,0,91,0,81,0,72,1,113,1,90,2,33,0,
+    81,1,51,1,0,0,0,0,0,0,31,0,90,2,33,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,51,2,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,33,0,51,0,0,0,0,0,
+    0,0,81,3,2,0,0,0,113,5,81,4,16,0,69,20,
+    0,0,113,6,90,2,33,0,81,5,90,6,12,0,81,6,
+    90,5,90,6,2,0,0,0,12,0,49,4,51,1,0,0,
+    0,0,0,0,31,0,74,22,0,0,9,0,30,0,81,0,
+    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,
     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,
index c78d496adcd0863a45be3a4212528ad0d516880c..b70ed7f4d10b273a7e5acb91dd319634648280ab 100644 (file)
@@ -348,8 +348,8 @@ dummy_func(
             DECREF_INPUTS();
         }
 
-        pure inst(PUSH_NULL, (-- null)) {
-            null = PyStackRef_NULL;
+        pure inst(PUSH_NULL, (-- res)) {
+            res = PyStackRef_NULL;
         }
 
         no_save_ip inst(END_FOR, (value -- )) {
@@ -1654,7 +1654,7 @@ dummy_func(
         specializing op(_SPECIALIZE_LOAD_GLOBAL, (counter/1 -- )) {
             #if ENABLE_SPECIALIZATION_FT
             if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
-                PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+                PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
                 next_instr = this_instr;
                 _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
                 DISPATCH_SAME_OPARG();
@@ -1665,10 +1665,11 @@ dummy_func(
         }
 
         // res[1] because we need a pointer to res to pass it to _PyEval_LoadGlobalStackRef
-        op(_LOAD_GLOBAL, ( -- res[1])) {
-            PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+        op(_LOAD_GLOBAL, ( -- res[1], null if (oparg & 1))) {
+            PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
             _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
             ERROR_IF(PyStackRef_IsNull(*res), error);
+            null = PyStackRef_NULL;
         }
 
         macro(LOAD_GLOBAL) =
@@ -1706,7 +1707,7 @@ dummy_func(
             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);
             PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
             DEAD(globals_keys);
@@ -1720,9 +1721,10 @@ dummy_func(
             res = PyStackRef_FromPyObjectSteal(res_o);
             #endif
             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);
             PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
             DEAD(builtins_keys);
@@ -1736,6 +1738,7 @@ dummy_func(
             res = PyStackRef_FromPyObjectSteal(res_o);
             #endif
             STAT_INC(LOAD_GLOBAL, hit);
+            null = PyStackRef_NULL;
         }
 
         macro(LOAD_GLOBAL_MODULE) =
@@ -2009,27 +2012,17 @@ dummy_func(
             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) = {
             LOAD_SUPER_ATTR_ATTR,
-        };
-
-
-        family(LOAD_SUPER_METHOD, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
-            LOAD_SUPER_METHOD_METHOD,
+            LOAD_SUPER_ATTR_METHOD,
         };
 
         specializing op(_SPECIALIZE_LOAD_SUPER_ATTR, (counter/1, global_super_st, class_st, unused -- global_super_st, class_st, unused)) {
             #if ENABLE_SPECIALIZATION_FT
+            int load_method = oparg & 1;
             if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
                 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();
             }
             OPCODE_DEFERRED_INC(LOAD_SUPER_ATTR);
@@ -2037,24 +2030,12 @@ dummy_func(
             #endif  /* ENABLE_SPECIALIZATION_FT */
         }
 
-        specializing op(_SPECIALIZE_LOAD_SUPER_METHOD, (counter/1, global_super_st, class_st, unused -- global_super_st, class_st, unused)) {
-            #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)) {
+        tier1 op(_LOAD_SUPER_ATTR, (global_super_st, class_st, self_st -- attr, null if (oparg & 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) {
+            if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
                 PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
                 int err = _Py_call_instrumentation_2args(
                         tstate, PY_MONITORING_EVENT_CALL,
@@ -2068,7 +2049,7 @@ dummy_func(
             // handle any case whose performance we care about
             PyObject *stack[] = {class, self};
             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;
                 if (super == NULL) {
                     _Py_call_instrumentation_exc2(
@@ -2091,13 +2072,12 @@ dummy_func(
             Py_DECREF(super);
             ERROR_IF(attr_o == NULL, error);
             attr = PyStackRef_FromPyObjectSteal(attr_o);
+            null = PyStackRef_NULL;
         }
 
         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)) {
+        inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st, unused if (0))) {
             PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
             PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
             PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
@@ -2113,7 +2093,7 @@ dummy_func(
             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 *class = PyStackRef_AsPyObjectBorrow(class_st);
             PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
@@ -2152,20 +2132,17 @@ dummy_func(
             LOAD_ATTR_CLASS_WITH_METACLASS_CHECK,
             LOAD_ATTR_PROPERTY,
             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_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)) {
             #if ENABLE_SPECIALIZATION_FT
             if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
-                PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+                PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
                 next_instr = this_instr;
                 _Py_Specialize_LoadAttr(owner, next_instr, name);
                 DISPATCH_SAME_OPARG();
@@ -2175,67 +2152,50 @@ dummy_func(
             #endif  /* ENABLE_SPECIALIZATION_FT */
         }
 
-        specializing op(_SPECIALIZE_LOAD_METHOD, (counter/1, owner -- owner)) {
-            #if ENABLE_SPECIALIZATION_FT
-            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);
+        op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
+            PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
             PyObject *attr_o;
-            /* Designed to work in tandem with CALL, pushes two values. */
-            attr_o = NULL;
-            int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
-            if (is_meth) {
-                /* We can bypass temporary bound method object.
-                    meth is unbound method and obj is self.
-                    meth | self | arg1 | ... | argN
+            if (oparg & 1) {
+                /* Designed to work in tandem with CALL, pushes two values. */
+                attr_o = NULL;
+                int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
+                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
+                    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
-                self_or_null = owner;  // Transfer ownership
-                DEAD(owner);
+                    DECREF_INPUTS();
+                    ERROR_IF(attr_o == NULL, error);
+                    self_or_null = PyStackRef_NULL;
+                }
             }
             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
-                */
+                /* Classic, pushes one value. */
+                attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
                 DECREF_INPUTS();
                 ERROR_IF(attr_o == NULL, error);
+                /* We need to define self_or_null on all paths */
                 self_or_null = PyStackRef_NULL;
             }
             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) =
             _SPECIALIZE_LOAD_ATTR +
             unused/8 +
             _LOAD_ATTR;
 
-
-        macro(LOAD_METHOD) =
-            _SPECIALIZE_LOAD_METHOD +
-            unused/8 +
-            _LOAD_METHOD;
-
         op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
             PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
             assert(type_version != 0);
@@ -2260,7 +2220,7 @@ dummy_func(
             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 **value_ptr = (PyObject**)(((char *)owner_o) + offset);
             PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
@@ -2273,6 +2233,7 @@ dummy_func(
             attr = PyStackRef_FromPyObjectNew(attr_o);
             #endif
             STAT_INC(LOAD_ATTR, hit);
+            null = PyStackRef_NULL;
             DECREF_INPUTS();
         }
 
@@ -2293,7 +2254,7 @@ dummy_func(
             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(index < FT_ATOMIC_LOAD_SSIZE_RELAXED(mod_keys->dk_nentries));
             PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mod_keys) + index;
@@ -2311,6 +2272,7 @@ dummy_func(
             attr = PyStackRef_FromPyObjectSteal(attr_o);
             #endif
             STAT_INC(LOAD_ATTR, hit);
+            null = PyStackRef_NULL;
             PyStackRef_CLOSE(owner);
         }
 
@@ -2330,7 +2292,7 @@ dummy_func(
             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;
             if (!LOCK_OBJECT(dict)) {
                 POP_INPUT(dict);
@@ -2342,7 +2304,7 @@ dummy_func(
                 POP_INPUT(dict);
                 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) {
                 UNLOCK_OBJECT(dict);
                 POP_INPUT(dict);
@@ -2364,6 +2326,7 @@ dummy_func(
             attr = PyStackRef_FromPyObjectNew(attr_o);
             UNLOCK_OBJECT(dict);
             DEAD(dict);
+            null = PyStackRef_NULL;
             DECREF_INPUTS();
         }
 
@@ -2374,7 +2337,7 @@ dummy_func(
             _LOAD_ATTR_WITH_HINT +
             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 **addr = (PyObject **)((char *)owner_o + index);
@@ -2387,6 +2350,7 @@ dummy_func(
             attr = PyStackRef_FromPyObjectNew(attr_o);
             #endif
             STAT_INC(LOAD_ATTR, hit);
+            null = PyStackRef_NULL;
             DECREF_INPUTS();
         }
 
@@ -2404,10 +2368,11 @@ dummy_func(
             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);
             assert(descr != NULL);
             attr = PyStackRef_FromPyObjectNew(descr);
+            null = PyStackRef_NULL;
             DECREF_INPUTS();
         }
 
@@ -2424,6 +2389,7 @@ dummy_func(
             _LOAD_ATTR_CLASS;
 
         op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _PyInterpreterFrame *)) {
+            assert((oparg & 1) == 0);
             assert(Py_IS_TYPE(fget, &PyFunction_Type));
             PyFunctionObject *f = (PyFunctionObject *)fget;
             PyCodeObject *code = (PyCodeObject *)f->func_code;
@@ -2446,8 +2412,10 @@ dummy_func(
             _SAVE_RETURN_OFFSET +
             _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);
+
+            assert((oparg & 1) == 0);
             DEOPT_IF(tstate->interp->eval_frame);
             PyTypeObject *cls = Py_TYPE(owner_o);
             assert(type_version != 0);
@@ -2461,7 +2429,7 @@ dummy_func(
             DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize));
             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(
                 tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
             // 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);
         }
 
-        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 */
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
@@ -3390,14 +3359,15 @@ dummy_func(
             DEAD(owner);
         }
 
-        macro(LOAD_METHOD_WITH_VALUES) =
+        macro(LOAD_ATTR_METHOD_WITH_VALUES) =
             unused/1 +
             _GUARD_TYPE_VERSION +
             _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT +
             _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);
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
@@ -3407,13 +3377,14 @@ dummy_func(
             DEAD(owner);
         }
 
-        macro(LOAD_METHOD_NO_DICT) =
+        macro(LOAD_ATTR_METHOD_NO_DICT) =
             unused/1 +
             _GUARD_TYPE_VERSION +
             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);
             assert(descr != NULL);
             DECREF_INPUTS();
@@ -3427,7 +3398,8 @@ dummy_func(
             _GUARD_KEYS_VERSION +
             _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);
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
@@ -3448,7 +3420,8 @@ dummy_func(
             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);
             assert(descr != NULL);
             assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
@@ -3457,12 +3430,12 @@ dummy_func(
             DEAD(owner);
         }
 
-        macro(LOAD_METHOD_LAZY_DICT) =
+        macro(LOAD_ATTR_METHOD_LAZY_DICT) =
             unused/1 +
             _GUARD_TYPE_VERSION +
             _CHECK_ATTR_METHOD_LAZY_DICT +
             unused/1 +
-            _LOAD_METHOD_LAZY_DICT;
+            _LOAD_ATTR_METHOD_LAZY_DICT;
 
         // Cache layout: counter/1, func_version/2
         // 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);
         }
 
-        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);
             if (PyTuple_CheckExact(callargs_o)) {
                 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);
 
             // DICT_MERGE is called before this opcode if there are kwargs.
@@ -4722,16 +4695,11 @@ dummy_func(
             LLTRACE_RESUME_FRAME();
         }
 
-        inst(BUILD_SLICE, (args[oparg] -- slice)) {
-            assert(oparg == 2 || oparg == 3);
-            _PyStackRef start = args[0];
-            _PyStackRef stop = args[1];
+        inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) {
             PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
             PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
-            PyObject * step_o = NULL;
-            if (oparg == 3) {
-                step_o = PyStackRef_AsPyObjectBorrow(args[2]);
-            }
+            PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
+
             PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
             DECREF_INPUTS();
             ERROR_IF(slice_o == NULL, error);
@@ -5074,25 +5042,27 @@ dummy_func(
             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();
             PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
             PyObject *res_o = entries[index].me_value;
             DEOPT_IF(res_o == NULL);
             Py_INCREF(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();
             PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
             PyObject *res_o = entries[index].me_value;
             DEOPT_IF(res_o == NULL);
             Py_INCREF(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);
             PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict;
             assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
@@ -5103,6 +5073,7 @@ dummy_func(
             STAT_INC(LOAD_ATTR, hit);
             Py_INCREF(attr_o);
             attr = PyStackRef_FromPyObjectSteal(attr_o);
+            null = PyStackRef_NULL;
             DECREF_INPUTS();
         }
 
index b3f845569684de7cab93c8ce05ac03366c0c948c..61707ba677097cf132f578ce0a5a96755c5bca3e 100644 (file)
@@ -348,6 +348,8 @@ codegen_addop_o(compiler *c, location loc,
         RETURN_IF_ERROR_IN_SCOPE((C), ret);                             \
     } while (0)
 
+#define LOAD_METHOD -1
+#define LOAD_SUPER_METHOD -2
 #define LOAD_ZERO_SUPER_ATTR -3
 #define LOAD_ZERO_SUPER_METHOD -4
 
@@ -364,11 +366,20 @@ codegen_addop_name(compiler *c, location loc,
     if (arg < 0) {
         return ERROR;
     }
+    if (opcode == LOAD_ATTR) {
+        arg <<= 1;
+    }
+    if (opcode == LOAD_METHOD) {
+        opcode = LOAD_ATTR;
+        arg <<= 1;
+        arg |= 1;
+    }
     if (opcode == LOAD_SUPER_ATTR) {
         arg <<= 2;
         arg |= 2;
     }
     if (opcode == LOAD_SUPER_METHOD) {
+        opcode = LOAD_SUPER_ATTR;
         arg <<= 2;
         arg |= 3;
     }
@@ -377,7 +388,7 @@ codegen_addop_name(compiler *c, location loc,
         arg <<= 2;
     }
     if (opcode == LOAD_ZERO_SUPER_METHOD) {
-        opcode = LOAD_SUPER_METHOD;
+        opcode = LOAD_SUPER_ATTR;
         arg <<= 2;
         arg |= 1;
     }
@@ -3154,6 +3165,9 @@ codegen_nameop(compiler *c, location loc,
 
     assert(op);
     Py_DECREF(mangled);
+    if (op == LOAD_GLOBAL) {
+        arg <<= 1;
+    }
     ADDOP_I(c, loc, op, arg);
     return SUCCESS;
 
@@ -4094,10 +4108,7 @@ ex_call:
         }
         assert(have_dict);
     }
-    if (nkwelts == 0) {
-        ADDOP(c, loc, PUSH_NULL);
-    }
-    ADDOP(c, loc, CALL_FUNCTION_EX);
+    ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0);
     return SUCCESS;
 }
 
@@ -4830,10 +4841,8 @@ codegen_async_with(compiler *c, stmt_ty s, int pos)
         SETUP_WITH  E
         <code to store to VAR> or POP_TOP
         <code for BLOCK>
-        LOAD_CONST None
-        LOAD_CONST None
-        LOAD_CONST None
-        CALL 3
+        LOAD_CONST (None, None, None)
+        CALL_FUNCTION_EX 0
         JUMP  EXIT
     E:  WITH_EXCEPT_START (calls EXPR.__exit__)
         POP_JUMP_IF_TRUE T:
index d2da9a8acf9d97fc503e60305a6ef39141f5ad7d..d336f73c4a2de5089628affc5127c13f29945ade 100644 (file)
         }
 
         case _PUSH_NULL: {
-            _PyStackRef null;
-            null = PyStackRef_NULL;
-            stack_pointer[0] = null;
+            _PyStackRef res;
+            res = PyStackRef_NULL;
+            stack_pointer[0] = res;
             stack_pointer += 1;
             assert(WITHIN_STACK_BOUNDS());
             break;
 
         case _LOAD_GLOBAL: {
             _PyStackRef *res;
+            _PyStackRef null = PyStackRef_NULL;
             oparg = CURRENT_OPARG();
             res = &stack_pointer[0];
-            PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+            PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
             _PyFrame_SetStackPointer(frame, stack_pointer);
             _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
             stack_pointer = _PyFrame_GetStackPointer(frame);
             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());
             break;
         }
         case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
             PyDictKeysObject *globals_keys;
             _PyStackRef res;
+            _PyStackRef null = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
             uint16_t index = (uint16_t)CURRENT_OPERAND0();
             PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
             res = PyStackRef_FromPyObjectSteal(res_o);
             #endif
             STAT_INC(LOAD_GLOBAL, hit);
+            null = PyStackRef_NULL;
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
         case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
             PyDictKeysObject *builtins_keys;
             _PyStackRef res;
+            _PyStackRef null = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
             uint16_t index = (uint16_t)CURRENT_OPERAND0();
             PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
             res = PyStackRef_FromPyObjectSteal(res_o);
             #endif
             STAT_INC(LOAD_GLOBAL, hit);
+            null = PyStackRef_NULL;
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         /* _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: {
             _PyStackRef self_st;
             _PyStackRef class_st;
             break;
         }
 
-        case _LOAD_SUPER_METHOD_METHOD: {
+        case _LOAD_SUPER_ATTR_METHOD: {
             _PyStackRef self_st;
             _PyStackRef class_st;
             _PyStackRef global_super_st;
             break;
         }
 
-        case _LOAD_METHOD: {
+        case _LOAD_ATTR: {
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef self_or_null;
+            _PyStackRef self_or_null = PyStackRef_NULL;
             oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
-            PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+            PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
             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
+            if (oparg & 1) {
+                /* 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) JUMP_TO_ERROR();
+                    self_or_null = PyStackRef_NULL;
+                }
             }
             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
-                 */
+                /* 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) JUMP_TO_ERROR();
+                /* We need to define self_or_null on all paths */
                 self_or_null = PyStackRef_NULL;
             }
             attr = PyStackRef_FromPyObjectSteal(attr_o);
             stack_pointer[-1] = attr;
-            stack_pointer[0] = self_or_null;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[0] = self_or_null;
+            stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             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: {
             _PyStackRef owner;
             owner = stack_pointer[-1];
             break;
         }
 
-        case _LOAD_ATTR_INSTANCE_VALUE: {
+        case _LOAD_ATTR_INSTANCE_VALUE_0: {
+            _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;
+            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);
             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: {
             _PyStackRef owner;
             PyDictKeysObject *mod_keys;
             PyDictKeysObject *mod_keys;
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             mod_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
             owner = stack_pointer[-2];
             uint16_t index = (uint16_t)CURRENT_OPERAND0();
             attr = PyStackRef_FromPyObjectSteal(attr_o);
             #endif
             STAT_INC(LOAD_ATTR, hit);
+            null = PyStackRef_NULL;
             PyStackRef_CLOSE(owner);
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
             PyDictObject *dict;
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             oparg = CURRENT_OPARG();
             dict = (PyDictObject *)stack_pointer[-1].bits;
             owner = stack_pointer[-2];
                     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) {
                 UNLOCK_OBJECT(dict);
                 stack_pointer += -1;
             STAT_INC(LOAD_ATTR, hit);
             attr = PyStackRef_FromPyObjectNew(attr_o);
             UNLOCK_OBJECT(dict);
+            null = PyStackRef_NULL;
             PyStackRef_CLOSE(owner);
             stack_pointer[-2] = attr;
-            stack_pointer += -1;
+            if (oparg & 1) stack_pointer[-1] = null;
+            stack_pointer += -1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
-        case _LOAD_ATTR_SLOT: {
+        case _LOAD_ATTR_SLOT_0: {
             _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);
             attr = PyStackRef_FromPyObjectNew(attr_o);
             #endif
             STAT_INC(LOAD_ATTR, hit);
+            null = PyStackRef_NULL;
             PyStackRef_CLOSE(owner);
             stack_pointer[-1] = attr;
             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: {
             _PyStackRef owner;
             owner = stack_pointer[-1];
             break;
         }
 
-        case _LOAD_ATTR_CLASS: {
+        case _LOAD_ATTR_CLASS_0: {
             _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;
             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: {
             _PyStackRef owner;
             _PyInterpreterFrame *new_frame;
+            oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
             PyObject *fget = (PyObject *)CURRENT_OPERAND0();
+            assert((oparg & 1) == 0);
             assert(Py_IS_TYPE(fget, &PyFunction_Type));
             PyFunctionObject *f = (PyFunctionObject *)fget;
             PyCodeObject *code = (PyCodeObject *)f->func_code;
             break;
         }
 
-        case _LOAD_METHOD_WITH_VALUES: {
+        case _LOAD_ATTR_METHOD_WITH_VALUES: {
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef self;
+            _PyStackRef self = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)CURRENT_OPERAND0();
+            assert(oparg & 1);
             /* Cached method object */
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
             break;
         }
 
-        case _LOAD_METHOD_NO_DICT: {
+        case _LOAD_ATTR_METHOD_NO_DICT: {
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef self;
+            _PyStackRef self = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)CURRENT_OPERAND0();
+            assert(oparg & 1);
             assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
         case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: {
             _PyStackRef owner;
             _PyStackRef attr;
+            oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)CURRENT_OPERAND0();
+            assert((oparg & 1) == 0);
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
             PyStackRef_CLOSE(owner);
         case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: {
             _PyStackRef owner;
             _PyStackRef attr;
+            oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)CURRENT_OPERAND0();
+            assert((oparg & 1) == 0);
             assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
             break;
         }
 
-        case _LOAD_METHOD_LAZY_DICT: {
+        case _LOAD_ATTR_METHOD_LAZY_DICT: {
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef self;
+            _PyStackRef self = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)CURRENT_OPERAND0();
+            assert(oparg & 1);
             STAT_INC(LOAD_ATTR, hit);
             assert(descr != NULL);
             assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
         /* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */
 
         case _MAKE_CALLARGS_A_TUPLE: {
-            _PyStackRef kwargs_in;
+            _PyStackRef kwargs_in = PyStackRef_NULL;
             _PyStackRef callargs;
             _PyStackRef func;
             _PyStackRef tuple;
-            _PyStackRef kwargs_out;
-            kwargs_in = stack_pointer[-1];
-            callargs = stack_pointer[-2];
-            func = stack_pointer[-4];
+            _PyStackRef kwargs_out = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
+            if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
+            callargs = stack_pointer[-1 - (oparg & 1)];
+            func = stack_pointer[-3 - (oparg & 1)];
             PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
             if (PyTuple_CheckExact(callargs_o)) {
                 tuple = callargs;
                 PyStackRef_CLOSE(callargs);
                 tuple = PyStackRef_FromPyObjectSteal(tuple_o);
             }
-            stack_pointer[-2] = tuple;
-            stack_pointer[-1] = kwargs_out;
+            stack_pointer[-1 - (oparg & 1)] = tuple;
+            if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
             break;
         }
 
         }
 
         case _BUILD_SLICE: {
-            _PyStackRef *args;
+            _PyStackRef step = PyStackRef_NULL;
+            _PyStackRef stop;
+            _PyStackRef start;
             _PyStackRef slice;
             oparg = CURRENT_OPARG();
-            args = &stack_pointer[-oparg];
-            assert(oparg == 2 || oparg == 3);
-            _PyStackRef start = args[0];
-            _PyStackRef stop = args[1];
+            if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
+            stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
+            start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
             PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
             PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
-            PyObject * step_o = NULL;
-            if (oparg == 3) {
-                step_o = PyStackRef_AsPyObjectBorrow(args[2]);
-            }
+            PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
             PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
-            for (int _i = oparg; --_i >= 0;) {
-                PyStackRef_CLOSE(args[_i]);
-            }
+            PyStackRef_CLOSE(start);
+            PyStackRef_CLOSE(stop);
+            PyStackRef_XCLOSE(step);
             if (slice_o == NULL) JUMP_TO_ERROR();
             slice = PyStackRef_FromPyObjectSteal(slice_o);
-            stack_pointer[-oparg] = slice;
-            stack_pointer += 1 - oparg;
+            stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
+            stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_GLOBAL_MODULE: {
             _PyStackRef res;
+            _PyStackRef null = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             uint16_t index = (uint16_t)CURRENT_OPERAND0();
             PyDictObject *dict = (PyDictObject *)GLOBALS();
             PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
             }
             Py_INCREF(res_o);
             res = PyStackRef_FromPyObjectSteal(res_o);
+            null = PyStackRef_NULL;
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_GLOBAL_BUILTINS: {
             _PyStackRef res;
+            _PyStackRef null = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             uint16_t index = (uint16_t)CURRENT_OPERAND0();
             PyDictObject *dict = (PyDictObject *)BUILTINS();
             PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
             }
             Py_INCREF(res_o);
             res = PyStackRef_FromPyObjectSteal(res_o);
+            null = PyStackRef_NULL;
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
         case _LOAD_ATTR_MODULE: {
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
+            oparg = CURRENT_OPARG();
             owner = stack_pointer[-1];
             uint16_t index = (uint16_t)CURRENT_OPERAND0();
             PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
             STAT_INC(LOAD_ATTR, hit);
             Py_INCREF(attr_o);
             attr = PyStackRef_FromPyObjectSteal(attr_o);
+            null = PyStackRef_NULL;
             PyStackRef_CLOSE(owner);
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
index 3f8d9db166ff98d0ae13f04205380a135094b33b..24561c1ee04db9715858fdb1742a874f61f9ec77 100644 (file)
@@ -1836,6 +1836,12 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
                     INSTR_SET_OP0(inst, NOP);
                 }
                 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:
                 if (nextop == TO_BOOL) {
                     INSTR_SET_OP0(inst, NOP);
index 7b49f336383a7a806db69e0fa3f9a2a80c0bc782..4fb3ce6f6da9cd0f638d99694862bcfcfff9a312 100644 (file)
             frame->instr_ptr = next_instr;
             next_instr += 1;
             INSTRUCTION_STATS(BUILD_SLICE);
-            _PyStackRef *args;
+            _PyStackRef start;
+            _PyStackRef stop;
+            _PyStackRef step = PyStackRef_NULL;
             _PyStackRef slice;
-            args = &stack_pointer[-oparg];
-            assert(oparg == 2 || oparg == 3);
-            _PyStackRef start = args[0];
-            _PyStackRef stop = args[1];
+            if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
+            stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
+            start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
             PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
             PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
-            PyObject * step_o = NULL;
-            if (oparg == 3) {
-                step_o = PyStackRef_AsPyObjectBorrow(args[2]);
-            }
+            PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
             PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
-            for (int _i = oparg; --_i >= 0;) {
-                PyStackRef_CLOSE(args[_i]);
-            }
+            PyStackRef_CLOSE(start);
+            PyStackRef_CLOSE(stop);
+            PyStackRef_XCLOSE(step);
             if (slice_o == NULL) {
-                stack_pointer += -oparg;
+                stack_pointer += -2 - ((oparg == 3) ? 1 : 0);
                 assert(WITHIN_STACK_BOUNDS());
                 goto error;
             }
             slice = PyStackRef_FromPyObjectSteal(slice_o);
-            stack_pointer[-oparg] = slice;
-            stack_pointer += 1 - oparg;
+            stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
+            stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
             (void)this_instr;
             _PyStackRef func;
             _PyStackRef callargs;
-            _PyStackRef kwargs_in;
+            _PyStackRef kwargs_in = PyStackRef_NULL;
             _PyStackRef tuple;
-            _PyStackRef kwargs_out;
+            _PyStackRef kwargs_out = PyStackRef_NULL;
             _PyStackRef func_st;
             _PyStackRef callargs_st;
-            _PyStackRef kwargs_st;
+            _PyStackRef kwargs_st = PyStackRef_NULL;
             _PyStackRef result;
             // _MAKE_CALLARGS_A_TUPLE
             {
-                kwargs_in = stack_pointer[-1];
-                callargs = stack_pointer[-2];
-                func = stack_pointer[-4];
+                if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
+                callargs = stack_pointer[-1 - (oparg & 1)];
+                func = stack_pointer[-3 - (oparg & 1)];
                 PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
                 if (PyTuple_CheckExact(callargs_o)) {
                     tuple = callargs;
                     assert(PyTuple_CheckExact(callargs));
                     PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
                     PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
-                    stack_pointer[-2] = callargs_st;
-                    stack_pointer[-1] = kwargs_st;
+                    stack_pointer[-1 - (oparg & 1)] = callargs_st;
+                    if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
                     _PyFrame_SetStackPointer(frame, stack_pointer);
                     int err = _Py_call_instrumentation_2args(
                         tstate, PY_MONITORING_EVENT_CALL,
                         Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
                         int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
                         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());
                         _PyFrame_SetStackPointer(frame, stack_pointer);
                         _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(
                     assert(PyTuple_CheckExact(callargs));
                     PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
                     assert(kwargs == NULL || PyDict_CheckExact(kwargs));
-                    stack_pointer[-2] = callargs_st;
-                    stack_pointer[-1] = kwargs_st;
+                    stack_pointer[-1 - (oparg & 1)] = callargs_st;
+                    if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
                     _PyFrame_SetStackPointer(frame, stack_pointer);
                     result_o = PyObject_Call(func, callargs, kwargs);
                     stack_pointer = _PyFrame_GetStackPointer(frame);
                 stack_pointer = _PyFrame_GetStackPointer(frame);
                 PyStackRef_CLOSE(callargs_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);
             }
             // _CHECK_PERIODIC
                 _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
                 QSBR_QUIESCENT_STATE(tstate);
                 if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
-                    stack_pointer[-4] = result;
-                    stack_pointer += -3;
+                    stack_pointer[-3 - (oparg & 1)] = result;
+                    stack_pointer += -2 - (oparg & 1);
                     assert(WITHIN_STACK_BOUNDS());
                     _PyFrame_SetStackPointer(frame, stack_pointer);
                     int err = _Py_HandlePending(tstate);
                     stack_pointer = _PyFrame_GetStackPointer(frame);
                     if (err != 0) goto error;
-                    stack_pointer += 3;
+                    stack_pointer += 2 + (oparg & 1);
                     assert(WITHIN_STACK_BOUNDS());
                 }
             }
-            stack_pointer[-4] = result;
-            stack_pointer += -3;
+            stack_pointer[-3 - (oparg & 1)] = result;
+            stack_pointer += -2 - (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
             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) {
             _Py_CODEUNIT* const prev_instr = frame->instr_ptr;
             _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
             (void)this_instr;
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef self_or_null = PyStackRef_NULL;
             // _SPECIALIZE_LOAD_ATTR
             {
                 owner = stack_pointer[-1];
                 (void)counter;
                 #if ENABLE_SPECIALIZATION_FT
                 if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
-                    PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+                    PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
                     next_instr = this_instr;
                     _PyFrame_SetStackPointer(frame, stack_pointer);
                     _Py_Specialize_LoadAttr(owner, next_instr, name);
             /* Skip 8 cache entries */
             // _LOAD_ATTR
             {
-                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) goto pop_1_error;
+                PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
+                PyObject *attr_o;
+                if (oparg & 1) {
+                    /* 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;
+                    }
+                }
+                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);
             }
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = self_or_null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
 
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _CHECK_ATTR_CLASS
             {
                 STAT_INC(LOAD_ATTR, hit);
                 assert(descr != NULL);
                 attr = PyStackRef_FromPyObjectNew(descr);
+                null = PyStackRef_NULL;
                 PyStackRef_CLOSE(owner);
             }
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
 
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _CHECK_ATTR_CLASS
             {
                 STAT_INC(LOAD_ATTR, hit);
                 assert(descr != NULL);
                 attr = PyStackRef_FromPyObjectNew(descr);
+                null = PyStackRef_NULL;
                 PyStackRef_CLOSE(owner);
             }
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
 
             uint32_t func_version = read_u32(&this_instr[4].cache);
             PyObject *getattribute = read_obj(&this_instr[6].cache);
             PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
+            assert((oparg & 1) == 0);
             DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
             PyTypeObject *cls = Py_TYPE(owner_o);
             assert(type_version != 0);
             assert(code->co_argcount == 2);
             DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
             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(
                 tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
             // Manipulate stack directly because we exit with DISPATCH_INLINED().
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _GUARD_TYPE_VERSION
             {
                 attr = PyStackRef_FromPyObjectNew(attr_o);
                 #endif
                 STAT_INC(LOAD_ATTR, hit);
+                null = PyStackRef_NULL;
                 PyStackRef_CLOSE(owner);
             }
             /* Skip 5 cache entries */
             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();
         }
 
             _PyStackRef owner;
             PyDictKeysObject *mod_keys;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _CHECK_ATTR_MODULE_PUSH_KEYS
             {
                 attr = PyStackRef_FromPyObjectSteal(attr_o);
                 #endif
                 STAT_INC(LOAD_ATTR, hit);
+                null = PyStackRef_NULL;
                 PyStackRef_CLOSE(owner);
             }
             /* Skip 5 cache entries */
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
 
             // _LOAD_ATTR_NONDESCRIPTOR_NO_DICT
             {
                 PyObject *descr = read_obj(&this_instr[6].cache);
+                assert((oparg & 1) == 0);
                 assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
                 STAT_INC(LOAD_ATTR, hit);
                 assert(descr != NULL);
             // _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES
             {
                 PyObject *descr = read_obj(&this_instr[6].cache);
+                assert((oparg & 1) == 0);
                 STAT_INC(LOAD_ATTR, hit);
                 assert(descr != NULL);
                 PyStackRef_CLOSE(owner);
             // _LOAD_ATTR_PROPERTY_FRAME
             {
                 PyObject *fget = read_obj(&this_instr[6].cache);
+                assert((oparg & 1) == 0);
                 assert(Py_IS_TYPE(fget, &PyFunction_Type));
                 PyFunctionObject *f = (PyFunctionObject *)fget;
                 PyCodeObject *code = (PyCodeObject *)f->func_code;
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _GUARD_TYPE_VERSION
             {
                 attr = PyStackRef_FromPyObjectNew(attr_o);
                 #endif
                 STAT_INC(LOAD_ATTR, hit);
+                null = PyStackRef_NULL;
                 PyStackRef_CLOSE(owner);
             }
             /* Skip 5 cache entries */
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
 
             _PyStackRef owner;
             PyDictObject *dict;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _GUARD_TYPE_VERSION
             {
                     UNLOCK_OBJECT(dict);
                     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) {
                     UNLOCK_OBJECT(dict);
                     DEOPT_IF(true, LOAD_ATTR);
                 STAT_INC(LOAD_ATTR, hit);
                 attr = PyStackRef_FromPyObjectNew(attr_o);
                 UNLOCK_OBJECT(dict);
+                null = PyStackRef_NULL;
                 PyStackRef_CLOSE(owner);
             }
             /* Skip 5 cache entries */
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
 
             _Py_CODEUNIT* const this_instr = next_instr - 5;
             (void)this_instr;
             _PyStackRef *res;
+            _PyStackRef null = PyStackRef_NULL;
             // _SPECIALIZE_LOAD_GLOBAL
             {
                 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);
+                    PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
                     next_instr = this_instr;
                     _PyFrame_SetStackPointer(frame, stack_pointer);
                     _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
             // _LOAD_GLOBAL
             {
                 res = &stack_pointer[0];
-                PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
+                PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
                 _PyFrame_SetStackPointer(frame, stack_pointer);
                 _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
                 stack_pointer = _PyFrame_GetStackPointer(frame);
                 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());
             DISPATCH();
         }
             static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
             PyDictKeysObject *builtins_keys;
             _PyStackRef res;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _GUARD_GLOBALS_VERSION
             {
                 res = PyStackRef_FromPyObjectSteal(res_o);
                 #endif
                 STAT_INC(LOAD_GLOBAL, hit);
+                null = PyStackRef_NULL;
             }
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
             static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
             PyDictKeysObject *globals_keys;
             _PyStackRef res;
+            _PyStackRef null = PyStackRef_NULL;
             /* Skip 1 cache entry */
             // _GUARD_GLOBALS_VERSION_PUSH_KEYS
             {
                 res = PyStackRef_FromPyObjectSteal(res_o);
                 #endif
                 STAT_INC(LOAD_GLOBAL, hit);
+                null = PyStackRef_NULL;
             }
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             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) {
             frame->instr_ptr = next_instr;
             next_instr += 1;
             _PyStackRef class_st;
             _PyStackRef self_st;
             _PyStackRef attr;
+            _PyStackRef null = PyStackRef_NULL;
             // _SPECIALIZE_LOAD_SUPER_ATTR
             {
                 class_st = stack_pointer[-2];
                 uint16_t counter = read_u16(&this_instr[1].cache);
                 (void)counter;
                 #if ENABLE_SPECIALIZATION_FT
+                int load_method = oparg & 1;
                 if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
                     next_instr = this_instr;
                     _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);
                     DISPATCH_SAME_OPARG();
                 }
                 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) {
+                if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
                     PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
                     _PyFrame_SetStackPointer(frame, stack_pointer);
                     int err = _Py_call_instrumentation_2args(
                 _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) {
+                if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
                     PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
                     if (super == NULL) {
                         _PyFrame_SetStackPointer(frame, stack_pointer);
                 stack_pointer = _PyFrame_GetStackPointer(frame);
                 if (attr_o == NULL) goto error;
                 attr = PyStackRef_FromPyObjectSteal(attr_o);
+                null = PyStackRef_NULL;
             }
             stack_pointer[0] = attr;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
         }
             DISPATCH();
         }
 
-        TARGET(LOAD_SUPER_METHOD) {
+        TARGET(LOAD_SUPER_ATTR_METHOD) {
             frame->instr_ptr = next_instr;
             next_instr += 2;
-            INSTRUCTION_STATS(LOAD_SUPER_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);
+            INSTRUCTION_STATS(LOAD_SUPER_ATTR_METHOD);
             static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size");
             _PyStackRef global_super_st;
             _PyStackRef class_st;
             PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
             PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
             assert(oparg & 1);
-            DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_METHOD);
-            DEOPT_IF(!PyType_Check(class), LOAD_SUPER_METHOD);
+            DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
+            DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
             STAT_INC(LOAD_SUPER_ATTR, hit);
             PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
             PyTypeObject *cls = (PyTypeObject *)class;
             frame->instr_ptr = next_instr;
             next_instr += 1;
             INSTRUCTION_STATS(PUSH_NULL);
-            _PyStackRef null;
-            null = PyStackRef_NULL;
-            stack_pointer[0] = null;
+            _PyStackRef res;
+            res = PyStackRef_NULL;
+            stack_pointer[0] = res;
             stack_pointer += 1;
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
index d20195d426fc0065d0939b89e50af465e9c79bcb..0e7b48107264345af30b4b24549a3d3a5b392f95 100644 (file)
@@ -81,8 +81,6 @@ static const int8_t EVENT_FOR_OPCODE[256] = {
     [INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL,
     [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,
     [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_SEND] = END_SEND,
     [INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
-    [INSTRUMENTED_LOAD_SUPER_METHOD] = LOAD_SUPER_METHOD,
     [INSTRUMENTED_NOT_TAKEN] = NOT_TAKEN,
 };
 
@@ -167,8 +164,6 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
     [INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
     [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,
     [INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
 
index 2e35ae710b1430fd7ae0ff522fbcb865c31a10c1..cb6c33f01d35984eb9f37debc4961fd2ac9d3375 100644 (file)
@@ -3,7 +3,6 @@ static void *opcode_targets[256] = {
     &&TARGET_BINARY_SLICE,
     &&TARGET_BINARY_SUBSCR,
     &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE,
-    &&TARGET_CALL_FUNCTION_EX,
     &&TARGET_CHECK_EG_MATCH,
     &&TARGET_CHECK_EXC_MATCH,
     &&TARGET_CLEANUP_THROW,
@@ -16,8 +15,8 @@ static void *opcode_targets[256] = {
     &&TARGET_FORMAT_WITH_SPEC,
     &&TARGET_GET_AITER,
     &&TARGET_GET_ANEXT,
-    &&TARGET_RESERVED,
     &&TARGET_GET_ITER,
+    &&TARGET_RESERVED,
     &&TARGET_GET_LEN,
     &&TARGET_GET_YIELD_FROM_ITER,
     &&TARGET_INTERPRETER_EXIT,
@@ -52,6 +51,7 @@ static void *opcode_targets[256] = {
     &&TARGET_BUILD_STRING,
     &&TARGET_BUILD_TUPLE,
     &&TARGET_CALL,
+    &&TARGET_CALL_FUNCTION_EX,
     &&TARGET_CALL_INTRINSIC_1,
     &&TARGET_CALL_INTRINSIC_2,
     &&TARGET_CALL_KW,
@@ -89,12 +89,10 @@ static void *opcode_targets[256] = {
     &&TARGET_LOAD_FROM_DICT_OR_DEREF,
     &&TARGET_LOAD_FROM_DICT_OR_GLOBALS,
     &&TARGET_LOAD_GLOBAL,
-    &&TARGET_LOAD_METHOD,
     &&TARGET_LOAD_NAME,
     &&TARGET_LOAD_SMALL_INT,
     &&TARGET_LOAD_SPECIAL,
     &&TARGET_LOAD_SUPER_ATTR,
-    &&TARGET_LOAD_SUPER_METHOD,
     &&TARGET_MAKE_CELL,
     &&TARGET_MAP_ADD,
     &&TARGET_MATCH_CLASS,
@@ -148,6 +146,8 @@ static void *opcode_targets[256] = {
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
+    &&_unknown_opcode,
+    &&_unknown_opcode,
     &&TARGET_RESUME,
     &&TARGET_BINARY_OP_ADD_FLOAT,
     &&TARGET_BINARY_OP_ADD_INT,
@@ -198,6 +198,9 @@ static void *opcode_targets[256] = {
     &&TARGET_LOAD_ATTR_CLASS_WITH_METACLASS_CHECK,
     &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
     &&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_NONDESCRIPTOR_NO_DICT,
     &&TARGET_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES,
@@ -208,11 +211,8 @@ static void *opcode_targets[256] = {
     &&TARGET_LOAD_CONST_MORTAL,
     &&TARGET_LOAD_GLOBAL_BUILTIN,
     &&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_METHOD_METHOD,
+    &&TARGET_LOAD_SUPER_ATTR_METHOD,
     &&TARGET_RESUME_CHECK,
     &&TARGET_SEND_GEN,
     &&TARGET_STORE_ATTR_INSTANCE_VALUE,
@@ -233,11 +233,11 @@ static void *opcode_targets[256] = {
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
+    &&_unknown_opcode,
     &&TARGET_INSTRUMENTED_END_FOR,
     &&TARGET_INSTRUMENTED_POP_ITER,
     &&TARGET_INSTRUMENTED_END_SEND,
     &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
-    &&TARGET_INSTRUMENTED_LOAD_SUPER_METHOD,
     &&TARGET_INSTRUMENTED_FOR_ITER,
     &&TARGET_INSTRUMENTED_CALL_KW,
     &&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
index b91caf11ffa962c63c01598fa7414c09822d84e8..9beb47246eb3d6d51f821825c773dc00f3cc120c 100644 (file)
@@ -1274,7 +1274,10 @@ uop_optimize(
     for (int pc = 0; pc < length; pc++) {
         int opcode = buffer[pc].opcode;
         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;
         }
         else if (is_terminator(&buffer[pc])) {
index 05f9592e9a23fa806176e93b918cc36d5cb0d4f7..b9ac30ea04e4e824e98644484fcdc4c22bf330ce 100644 (file)
@@ -109,10 +109,10 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj)
         return NULL;
     }
     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 {
-        inst->opcode = _LOAD_CONST_INLINE;
+        inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_WITH_NULL : _LOAD_CONST_INLINE;
     }
     inst->operand0 = (uint64_t)res;
     return res;
index af834b6957be2244df62a59ff935884842bcfeb6..881a607ca2aa29a0f97bf124fb7641c86a7c3854 100644 (file)
@@ -528,8 +528,9 @@ dummy_func(void) {
         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);
+        null = sym_new_null(ctx);
         (void)offset;
         (void)owner;
     }
@@ -552,19 +553,15 @@ dummy_func(void) {
         }
     }
 
-    op(_LOAD_ATTR, (owner -- attr)) {
-        (void)owner;
-        attr = sym_new_not_null(ctx);
-    }
-
-    op(_LOAD_METHOD, (owner -- attr, self_or_null)) {
+    op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
         (void)owner;
         attr = sym_new_not_null(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;
+        null = sym_new_null(ctx);
         attr = NULL;
         if (this_instr[-1].opcode == _NOP) {
             // Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
@@ -592,38 +589,41 @@ dummy_func(void) {
         (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);
+        null = sym_new_null(ctx);
         (void)hint;
         (void)owner;
         (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);
+        null = sym_new_null(ctx);
         (void)index;
         (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);
+        null = sym_new_null(ctx);
         (void)descr;
         (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;
         attr = sym_new_not_null(ctx);
         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;
         attr = sym_new_not_null(ctx);
         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;
         attr = sym_new_not_null(ctx);
         self = owner;
@@ -819,7 +819,7 @@ dummy_func(void) {
         Py_UNREACHABLE();
     }
 
-    op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- )) {
+    op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- unused if (0))) {
         SYNC_SP();
         ctx->frame->stack_pointer = stack_pointer;
         ctx->frame = new_frame;
index cb4651a5d8093c2facabd321a6d1e1b4dec523ee..fa0b4ed4345320d878cefe8c05932b0b31f8a9e9 100644 (file)
 
         case _LOAD_GLOBAL: {
             JitOptSymbol **res;
+            JitOptSymbol *null = NULL;
             res = &stack_pointer[0];
             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());
             break;
         }
 
         case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
             JitOptSymbol *res;
+            JitOptSymbol *null = NULL;
             res = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             stack_pointer[-1] = res;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
             JitOptSymbol *res;
+            JitOptSymbol *null = NULL;
             res = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             stack_pointer[-1] = res;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
 
         /* _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: {
             JitOptSymbol *attr_st;
             attr_st = sym_new_not_null(ctx);
             break;
         }
 
-        case _LOAD_SUPER_METHOD_METHOD: {
+        case _LOAD_SUPER_ATTR_METHOD: {
             JitOptSymbol *attr;
             JitOptSymbol *self_or_null;
             attr = sym_new_not_null(ctx);
             break;
         }
 
-        case _LOAD_METHOD: {
+        case _LOAD_ATTR: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
-            JitOptSymbol *self_or_null;
+            JitOptSymbol *self_or_null = NULL;
             owner = stack_pointer[-1];
             (void)owner;
             attr = sym_new_not_null(ctx);
             self_or_null = sym_new_unknown(ctx);
             stack_pointer[-1] = attr;
-            stack_pointer[0] = self_or_null;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[0] = self_or_null;
+            stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             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: {
             JitOptSymbol *owner;
             owner = stack_pointer[-1];
         case _LOAD_ATTR_INSTANCE_VALUE: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
+            JitOptSymbol *null = NULL;
             owner = stack_pointer[-1];
             uint16_t offset = (uint16_t)this_instr->operand0;
             attr = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             (void)offset;
             (void)owner;
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_ATTR_MODULE_FROM_KEYS: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
+            JitOptSymbol *null = NULL;
             owner = stack_pointer[-2];
             uint16_t index = (uint16_t)this_instr->operand0;
             (void)index;
+            null = sym_new_null(ctx);
             attr = NULL;
             if (this_instr[-1].opcode == _NOP) {
                 // Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
                 assert(PyModule_CheckExact(mod));
                 PyObject *dict = mod->md_dict;
                 stack_pointer[-2] = attr;
-                stack_pointer += -1;
+                if (oparg & 1) stack_pointer[-1] = null;
+                stack_pointer += -1 + (oparg & 1);
                 assert(WITHIN_STACK_BOUNDS());
                 PyObject *res = convert_global_to_const(this_instr, dict);
                 if (res != NULL) {
                 else {
                     this_instr->opcode = _LOAD_ATTR_MODULE;
                 }
-                stack_pointer += 1;
+                stack_pointer += 1 - (oparg & 1);
                 assert(WITHIN_STACK_BOUNDS());
             }
             if (attr == NULL) {
                 attr = sym_new_not_null(ctx);
             }
             stack_pointer[-2] = attr;
-            stack_pointer += -1;
+            if (oparg & 1) stack_pointer[-1] = null;
+            stack_pointer += -1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
             JitOptSymbol *dict;
             JitOptSymbol *owner;
             JitOptSymbol *attr;
+            JitOptSymbol *null = NULL;
             dict = stack_pointer[-1];
             owner = stack_pointer[-2];
             uint16_t hint = (uint16_t)this_instr->operand0;
             attr = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             (void)hint;
             (void)owner;
             (void)dict;
             stack_pointer[-2] = attr;
-            stack_pointer += -1;
+            if (oparg & 1) stack_pointer[-1] = null;
+            stack_pointer += -1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
         case _LOAD_ATTR_SLOT: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
+            JitOptSymbol *null = NULL;
             owner = stack_pointer[-1];
             uint16_t index = (uint16_t)this_instr->operand0;
             attr = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             (void)index;
             (void)owner;
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_ATTR_CLASS: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
+            JitOptSymbol *null = NULL;
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)this_instr->operand0;
             attr = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             (void)descr;
             (void)owner;
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
             break;
         }
 
-        case _LOAD_METHOD_WITH_VALUES: {
+        case _LOAD_ATTR_METHOD_WITH_VALUES: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
-            JitOptSymbol *self;
+            JitOptSymbol *self = NULL;
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)this_instr->operand0;
             (void)descr;
             break;
         }
 
-        case _LOAD_METHOD_NO_DICT: {
+        case _LOAD_ATTR_METHOD_NO_DICT: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
-            JitOptSymbol *self;
+            JitOptSymbol *self = NULL;
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)this_instr->operand0;
             (void)descr;
             break;
         }
 
-        case _LOAD_METHOD_LAZY_DICT: {
+        case _LOAD_ATTR_METHOD_LAZY_DICT: {
             JitOptSymbol *owner;
             JitOptSymbol *attr;
-            JitOptSymbol *self;
+            JitOptSymbol *self = NULL;
             owner = stack_pointer[-1];
             PyObject *descr = (PyObject *)this_instr->operand0;
             (void)descr;
 
         case _MAKE_CALLARGS_A_TUPLE: {
             JitOptSymbol *tuple;
-            JitOptSymbol *kwargs_out;
+            JitOptSymbol *kwargs_out = NULL;
             tuple = sym_new_not_null(ctx);
             kwargs_out = sym_new_not_null(ctx);
-            stack_pointer[-2] = tuple;
-            stack_pointer[-1] = kwargs_out;
+            stack_pointer[-1 - (oparg & 1)] = tuple;
+            if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
             break;
         }
 
         case _BUILD_SLICE: {
             JitOptSymbol *slice;
             slice = sym_new_not_null(ctx);
-            stack_pointer[-oparg] = slice;
-            stack_pointer += 1 - oparg;
+            stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
+            stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_GLOBAL_MODULE: {
             JitOptSymbol *res;
+            JitOptSymbol *null = NULL;
             res = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_GLOBAL_BUILTINS: {
             JitOptSymbol *res;
+            JitOptSymbol *null = NULL;
             res = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             stack_pointer[0] = res;
-            stack_pointer += 1;
+            if (oparg & 1) stack_pointer[1] = null;
+            stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
         case _LOAD_ATTR_MODULE: {
             JitOptSymbol *attr;
+            JitOptSymbol *null = NULL;
             attr = sym_new_not_null(ctx);
+            null = sym_new_null(ctx);
             stack_pointer[-1] = attr;
+            if (oparg & 1) stack_pointer[0] = null;
+            stack_pointer += (oparg & 1);
+            assert(WITHIN_STACK_BOUNDS());
             break;
         }
 
index eb599028cefafabd2c12d509efa1f685ed90a3db..fa022346bdea6aa57b6b2e968a51c2e04e4da6c7 100644 (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);
         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);
     return;
 fail:
@@ -1109,7 +1109,7 @@ instance_has_key(PyObject *obj, PyObject *name, uint32_t *shared_keys_version)
 static int
 do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name,
                                  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);
     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);
         return -1;
     }
+    uint8_t oparg = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.arg);
     switch(kind) {
         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;
         case METHOD:
         {
             if (shadow) {
                 goto try_instance;
             }
-            if (load_method) {
+            if (oparg & 1) {
                 if (specialize_attr_loadclassattr(owner, instr, name, descr,
                                                   tp_version, kind, true,
                                                   shared_keys_version)) {
@@ -1136,7 +1137,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
                     return -1;
                 }
             }
-            SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
+            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
             return -1;
         }
         case PROPERTY:
@@ -1145,28 +1146,28 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
             assert(Py_TYPE(descr) == &PyProperty_Type);
             PyObject *fget = ((_PyPropertyObject *)descr)->prop_get;
             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;
             }
             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);
+            if (!function_check_args(fget, 1, LOAD_ATTR)) {
                 return -1;
             }
-            if (!function_check_args(fget, 1, LOAD_ATTR)) {
+            if (oparg & 1) {
+                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
                 return -1;
             }
             /* Don't specialize if PEP 523 is active */
             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;
             }
             #ifdef Py_GIL_DISABLED
             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;
             }
             #endif
@@ -1179,10 +1180,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
         }
         case OBJECT_SLOT:
         {
-            if (load_method) {
-                SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
-                return -1;
-            }
             PyMemberDescrObject *member = (PyMemberDescrObject *)descr;
             struct PyMemberDef *dmem = member->d_member;
             Py_ssize_t offset = dmem->offset;
@@ -1207,10 +1204,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
         }
         case DUNDER_CLASS:
         {
-            if (load_method) {
-                SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
-                return -1;
-            }
             Py_ssize_t offset = offsetof(PyObject, ob_type);
             assert(offset == (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;
         }
         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;
         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;
         case GETSET_OVERRIDDEN:
-            SPECIALIZATION_FAIL(load_method ? LOAD_METHOD : LOAD_ATTR, SPEC_FAIL_OVERRIDDEN);
+            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN);
             return -1;
         case GETATTRIBUTE_IS_PYTHON_FUNCTION:
         {
-            if (load_method) {
-                SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OTHER);
-                return -1;
-            }
             #ifndef Py_GIL_DISABLED
             // In free-threaded builds it's possible for tp_getattro to change
             // 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)) {
                 return -1;
             }
+            if (oparg & 1) {
+                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
+                return -1;
+            }
             uint32_t version = function_get_version(descr, LOAD_ATTR);
             if (version == 0) {
                 return -1;
@@ -1277,7 +1270,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
             if (shadow) {
                 goto try_instance;
             }
-            if (!load_method) {
+            if ((oparg & 1) == 0) {
                 if (specialize_attr_loadclassattr(owner, instr, name, descr,
                                                   tp_version, kind, false,
                                                   shared_keys_version)) {
@@ -1294,10 +1287,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
     }
     Py_UNREACHABLE();
 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,
                                LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT))
     {
@@ -1307,7 +1296,7 @@ try_instance:
 }
 
 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
     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;
     PyTypeObject *type = Py_TYPE(owner);
     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);
     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);
     }
     else {
-        fail = specialize_instance_load_attr(owner, instr, name, false);
-    }
-
-    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);
+        fail = specialize_instance_load_attr(owner, instr, name);
     }
 
     if (fail) {
@@ -1619,7 +1575,7 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
 
     #ifdef Py_GIL_DISABLED
     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;
     }
     #endif
@@ -1631,11 +1587,11 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
                    ((PyHeapTypeObject *)owner_cls)->ht_cached_keys, name) < 0);
         #endif
         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;
         }
         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 {
         Py_ssize_t dictoffset;
@@ -1645,17 +1601,17 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
         else {
             dictoffset = owner_cls->tp_dictoffset;
             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;
             }
         }
         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) {
             PyObject *dict = *(PyObject **) ((char *)owner + dictoffset);
             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;
             }
             /* 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;
             assert(((uint16_t)dictoffset) == dictoffset);
             cache->dict_offset = (uint16_t)dictoffset;
-            specialize(instr, LOAD_METHOD_LAZY_DICT);
+            specialize(instr, LOAD_ATTR_METHOD_LAZY_DICT);
         }
         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;
         }
     }
index e8ee314879893dd72332fb1d523c04ca2e2ec1d3..3daae46e61fcf2c38644e24bc4f44126a46004c8 100644 (file)
@@ -25,6 +25,7 @@ class Properties:
     side_exit: bool
     pure: bool
     tier: int | None = None
+    oparg_and_1: bool = False
     const_oparg: int = -1
     needs_prev: bool = False
     no_save_ip: bool = False
@@ -123,14 +124,16 @@ class Flush:
 class StackItem:
     name: str
     type: str | None
+    condition: str | None
     size: str
     peek: bool = False
     used: bool = False
 
     def __str__(self) -> str:
+        cond = f" if ({self.condition})" if self.condition else ""
         size = f"[{self.size}]" if self.size else ""
         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:
         return self.size != ""
@@ -312,19 +315,25 @@ def override_error(
     )
 
 
-def convert_stack_item(item: parser.StackEffect) -> StackItem:
-    return StackItem(item.name, item.type, item.size)
+def convert_stack_item(
+    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(
-    op: parser.InstDef | parser.Pseudo) -> StackEffect:
+    op: parser.InstDef | parser.Pseudo, replace_op_arg_1: str | None = None
+) -> StackEffect:
     inputs: list[StackItem] = [
-        convert_stack_item(i)
+        convert_stack_item(i, replace_op_arg_1)
         for i in op.inputs
         if isinstance(i, parser.StackEffect)
     ]
     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"
     modified = False
@@ -746,6 +755,40 @@ def always_exits(op: parser.InstDef) -> bool:
                     return True
     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:
     escaping_calls = find_escaping_api_calls(op)
     has_free = (
@@ -819,6 +862,29 @@ def make_uop(
         body=op.block.tokens,
         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:
         if anno.startswith("replicate"):
             result.replicated = int(anno[10:-1])
index 9edf3d4898eb4db70abf31055d17268100388675..f1f166ae104ba59a298afb7a4ce8c3729e7e47c9 100644 (file)
@@ -247,7 +247,7 @@ class Emitter:
             if var.name == "null":
                 continue
             close = "PyStackRef_CLOSE"
-            if "null" in var.name:
+            if "null" in var.name or var.condition and var.condition != "1":
                 close = "PyStackRef_XCLOSE"
             if var.size:
                 if var.size == "1":
@@ -256,6 +256,9 @@ class Emitter:
                     self.out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n")
                     self.out.emit(f"{close}({var.name}[_i]);\n")
                     self.out.emit("}\n")
+            elif var.condition:
+                if var.condition != "0":
+                    self.out.emit(f"{close}({var.name});\n")
             else:
                 self.out.emit(f"{close}({var.name});\n")
         for input in storage.inputs:
@@ -683,6 +686,8 @@ def cflags(p: Properties) -> str:
         flags.append("HAS_PURE_FLAG")
     if p.no_save_ip:
         flags.append("HAS_NO_SAVE_IP_FLAG")
+    if p.oparg_and_1:
+        flags.append("HAS_OPARG_AND_1_FLAG")
     if flags:
         return " | ".join(flags)
     else:
index 303a1c02705a3b3e1461023ec2ef21ad7697249a..bee2a185745f4dcbf903152f9f78c53adc5a362a 100644 (file)
@@ -222,6 +222,7 @@ annotations = {
     "register",
     "replaced",
     "pure",
+    "split",
     "replicate",
     "tier1",
     "tier2",
index 9ef49bdc41dc99e1cc793d0f6ff9b27a90a8489a..453db6905d68425fe3958fdabaea2037489cb4c5 100644 (file)
@@ -51,6 +51,7 @@ FLAGS = [
     "EXIT",
     "PURE",
     "PASSTHROUGH",
+    "OPARG_AND_1",
     "ERROR_NO_POP",
     "NO_SAVE_IP",
 ]
index 7ebeff716d290072a6870b85053e8467dfa14619..5cfec4bfecbf074bb4899a5992e13752762df0b5 100644 (file)
@@ -48,13 +48,19 @@ def declare_variables(uop: Uop, out: CWriter, skip_inputs: bool) -> None:
         for var in reversed(uop.stack.inputs):
             if var.used and var.name not in variables:
                 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:
         if var.peek:
             continue
         if var.name not in variables:
             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(
index b50bb627b6c41ced6c64433f799b08ebe0249883..41b36b6a546360fe1df37b15c24a04d78e05c3ba 100644 (file)
@@ -77,11 +77,12 @@ class Block(Node):
 class StackEffect(Node):
     name: str = field(compare=False)  # __eq__ only uses type, cond, size
     type: str = ""  # Optional `:type`
+    cond: str = ""  # Optional `if (cond)`
     size: str = ""  # Optional `[size]`
     # Note: size cannot be combined with type or cond
 
     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] == "":
             del items[-1]
         return f"StackEffect({', '.join(repr(item) for item in items)})"
@@ -277,15 +278,22 @@ class Parser(PLexer):
                 type_text = self.require(lx.IDENTIFIER).text.strip()
                 if self.expect(lx.TIMES):
                     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 = ""
             if self.expect(lx.LBRACKET):
-                if type_text:
+                if type_text or cond_text:
                     raise self.make_syntax_error("Unexpected [")
                 if not (size := self.expression()):
                     raise self.make_syntax_error("Expected expression")
                 self.require(lx.RBRACKET)
                 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
 
     @contextual
index 4e9a312ce34146051c4516221115c76a638b3734..5121837ed8334baddb5199162b194ff0ff3d912f 100644 (file)
@@ -24,7 +24,17 @@ def maybe_parenthesize(sym: str) -> 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
     else:
         return "1"
@@ -80,6 +90,10 @@ class Local:
     def name(self) -> str:
         return self.item.name
 
+    @property
+    def condition(self) -> str | None:
+        return self.item.condition
+
     def is_array(self) -> bool:
         return self.item.is_array()
 
@@ -260,7 +274,16 @@ class Stack:
         self.defined.add(var.name)
         cast = f"({var.type})" if (not indirect and var.type) 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)
 
     def push(self, var: Local) -> None:
@@ -280,6 +303,10 @@ class Stack:
     ) -> None:
         cast = f"({cast_type})" if var.type 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")
 
     def _adjust_stack_pointer(self, out: CWriter, number: str) -> None:
index f4409da3d83ccddf70a89b7923431855622a3340..441bb3f7af5bcbf68bae32709543ea5ca974c489 100644 (file)
@@ -37,7 +37,10 @@ FOOTER = "#undef TIER_ONE\n"
 def declare_variable(var: StackItem, out: CWriter) -> None:
     type, null = type_and_null(var)
     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:
index abd9b8d792429936ce2ca93ea5eb6dbf099a89f3..dd16a1a7eb28b56ce9a983702a50229306bdb5ae 100644 (file)
@@ -39,7 +39,14 @@ def declare_variable(
     required.remove(var.name)
     type, null = type_and_null(var)
     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:
@@ -208,6 +215,9 @@ def generate_tier2(
     for name, uop in analysis.uops.items():
         if uop.properties.tier == 1:
             continue
+        if uop.properties.oparg_and_1:
+            out.emit(f"/* {uop.name} is split on (oparg & 1) */\n\n")
+            continue
         if uop.is_super():
             continue
         why_not_viable = uop.why_not_viable()
index 17478933eb68e5c8e04732f16a8198b9cd67b915..bc7ccfe33e777da4c0fa9a9620e5e63594377eb1 100644 (file)
@@ -284,7 +284,7 @@ class OpcodeStats:
         def kind_to_text(kind: int, opcode: str):
             if kind <= 8:
                 return pretty(self._defines[kind][0])
-            if opcode == "LOAD_SUPER_ATTR" or opcode == "LOAD_SUPER_METHOD":
+            if opcode == "LOAD_SUPER_ATTR":
                 opcode = "SUPER"
             elif opcode.endswith("ATTR"):
                 opcode = "ATTR"