summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-12-19 16:59:51 (GMT)
committerGitHub <noreply@github.com>2024-12-19 16:59:51 (GMT)
commitd2f1d917e8b3d2dd8f35495c7632a32688883332 (patch)
tree334558f483e0f41d80924973d16b68354bf95b82
parent7b811d0562a0bf7433165785f1549ac199610f8b (diff)
downloadcpython-d2f1d917e8b3d2dd8f35495c7632a32688883332.zip
cpython-d2f1d917e8b3d2dd8f35495c7632a32688883332.tar.gz
cpython-d2f1d917e8b3d2dd8f35495c7632a32688883332.tar.bz2
GH-122548: Implement branch taken and not taken events for sys.monitoring (GH-122564)
-rw-r--r--Doc/c-api/monitoring.rst12
-rw-r--r--Doc/library/sys.monitoring.rst29
-rw-r--r--Doc/whatsnew/3.13.rst2
-rw-r--r--Doc/whatsnew/3.14.rst14
-rw-r--r--Include/cpython/code.h6
-rw-r--r--Include/cpython/monitoring.h43
-rw-r--r--Include/internal/pycore_code.h2
-rw-r--r--Include/internal/pycore_magic_number.h3
-rw-r--r--Include/internal/pycore_opcode_metadata.h25
-rw-r--r--Include/internal/pycore_opcode_utils.h6
-rw-r--r--Include/internal/pycore_uop_ids.h1
-rw-r--r--Include/opcode_ids.h198
-rw-r--r--Lib/_opcode_metadata.py198
-rw-r--r--Lib/test/test_compiler_codegen.py2
-rw-r--r--Lib/test/test_dis.py391
-rw-r--r--Lib/test/test_monitoring.py67
-rw-r--r--Misc/NEWS.d/next/Library/2024-12-13-14-21-04.gh-issue-122548.hq3Vud.rst4
-rw-r--r--Modules/_testcapi/monitoring.c25
-rw-r--r--Objects/codeobject.c7
-rw-r--r--Programs/test_frozenmain.h66
-rw-r--r--Python/bytecodes.c60
-rw-r--r--Python/codegen.c9
-rw-r--r--Python/executor_cases.c.h2
-rw-r--r--Python/flowgraph.c6
-rw-r--r--Python/generated_cases.c.h74
-rw-r--r--Python/instrumentation.c321
-rw-r--r--Python/opcode_targets.h4
-rw-r--r--Python/optimizer_cases.c.h2
-rw-r--r--Tools/c-analyzer/cpython/globals-to-fix.tsv2
29 files changed, 998 insertions, 583 deletions
diff --git a/Doc/c-api/monitoring.rst b/Doc/c-api/monitoring.rst
index 51d866c..bda6cd2 100644
--- a/Doc/c-api/monitoring.rst
+++ b/Doc/c-api/monitoring.rst
@@ -75,9 +75,14 @@ See :mod:`sys.monitoring` for descriptions of the events.
Fire a ``JUMP`` event.
-.. c:function:: int PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)
+.. c:function:: int PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)
- Fire a ``BRANCH`` event.
+ Fire a ``BRANCH_LEFT`` event.
+
+
+.. c:function:: int PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)
+
+ Fire a ``BRANCH_RIGHT`` event.
.. c:function:: int PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)
@@ -168,7 +173,8 @@ would typically correspond to a python function.
================================================== =====================================
Macro Event
================================================== =====================================
- .. c:macro:: PY_MONITORING_EVENT_BRANCH :monitoring-event:`BRANCH`
+ .. c:macro:: PY_MONITORING_EVENT_BRANCH_LEFT :monitoring-event:`BRANCH_LEFT`
+ .. c:macro:: PY_MONITORING_EVENT_BRANCH_RIGHT :monitoring-event:`BRANCH_RIGHT`
.. c:macro:: PY_MONITORING_EVENT_CALL :monitoring-event:`CALL`
.. c:macro:: PY_MONITORING_EVENT_C_RAISE :monitoring-event:`C_RAISE`
.. c:macro:: PY_MONITORING_EVENT_C_RETURN :monitoring-event:`C_RETURN`
diff --git a/Doc/library/sys.monitoring.rst b/Doc/library/sys.monitoring.rst
index f7140af..cfdcdf2 100644
--- a/Doc/library/sys.monitoring.rst
+++ b/Doc/library/sys.monitoring.rst
@@ -79,9 +79,17 @@ Events
The following events are supported:
-.. monitoring-event:: BRANCH
+.. monitoring-event:: BRANCH_LEFT
- A conditional branch is taken (or not).
+ A conditional branch goes left.
+
+ It is up to the tool to determine how to present "left" and "right" branches.
+ There is no guarantee which branch is "left" and which is "right", except
+ that it will be consistent for the duration of the program.
+
+.. monitoring-event:: BRANCH_RIGHT
+
+ A conditional branch goes right.
.. monitoring-event:: CALL
@@ -180,9 +188,20 @@ The local events are:
* :monitoring-event:`LINE`
* :monitoring-event:`INSTRUCTION`
* :monitoring-event:`JUMP`
-* :monitoring-event:`BRANCH`
+* :monitoring-event:`BRANCH_LEFT`
+* :monitoring-event:`BRANCH_RIGHT`
* :monitoring-event:`STOP_ITERATION`
+Deprecated event
+''''''''''''''''
+
+* ``BRANCH``
+
+The ``BRANCH`` event is deprecated in 3.14.
+Using :monitoring-event:`BRANCH_LEFT` and :monitoring-event:`BRANCH_RIGHT`
+events will give much better performance as they can be disabled
+independently.
+
Ancillary events
''''''''''''''''
@@ -357,13 +376,11 @@ Different events will provide the callback function with different arguments, as
func(code: CodeType, line_number: int) -> DISABLE | Any
-* :monitoring-event:`BRANCH` and :monitoring-event:`JUMP`::
+* :monitoring-event:`BRANCH_LEFT`, :monitoring-event:`BRANCH_RIGHT` and :monitoring-event:`JUMP`::
func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any
Note that the *destination_offset* is where the code will next execute.
- For an untaken branch this will be the offset of the instruction following
- the branch.
* :monitoring-event:`INSTRUCTION`::
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 9f6d98b..45cc1b5 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -1971,7 +1971,7 @@ New Features
* :c:func:`PyMonitoring_FireCallEvent`
* :c:func:`PyMonitoring_FireLineEvent`
* :c:func:`PyMonitoring_FireJumpEvent`
- * :c:func:`PyMonitoring_FireBranchEvent`
+ * ``PyMonitoring_FireBranchEvent``
* :c:func:`PyMonitoring_FireCReturnEvent`
* :c:func:`PyMonitoring_FirePyThrowEvent`
* :c:func:`PyMonitoring_FireRaiseEvent`
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 2e43dce..97a37a8 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -603,6 +603,11 @@ sys
which only exists in specialized builds of Python, may now return objects
from other interpreters than the one it's called in.
+sys.monitoring
+--------------
+
+Two new events are added: :monitoring-event:`BRANCH_LEFT` and
+:monitoring-event:`BRANCH_RIGHT`. The ``BRANCH`` event is deprecated.
tkinter
-------
@@ -1144,6 +1149,11 @@ New features
a :exc:`UnicodeError` object.
(Contributed by Bénédikt Tran in :gh:`127691`.)
+* Add :c:func:`PyMonitoring_FireBranchLeftEvent` and
+ :c:func:`PyMonitoring_FireBranchRightEvent` for generating
+ :monitoring-event:`BRANCH_LEFT` and :monitoring-event:`BRANCH_RIGHT`
+ events, respectively.
+
Porting to Python 3.14
----------------------
@@ -1177,6 +1187,10 @@ Deprecated
.. include:: ../deprecations/c-api-pending-removal-in-future.rst
+* The ``PyMonitoring_FireBranchEvent`` function is deprecated and should
+ be replaced with calls to :c:func:`PyMonitoring_FireBranchLeftEvent`
+ and :c:func:`PyMonitoring_FireBranchRightEvent`.
+
Removed
-------
diff --git a/Include/cpython/code.h b/Include/cpython/code.h
index 3899d42..c3c0165 100644
--- a/Include/cpython/code.h
+++ b/Include/cpython/code.h
@@ -11,11 +11,11 @@ extern "C" {
/* Total tool ids available */
#define _PY_MONITORING_TOOL_IDS 8
/* Count of all local monitoring events */
-#define _PY_MONITORING_LOCAL_EVENTS 10
+#define _PY_MONITORING_LOCAL_EVENTS 11
/* Count of all "real" monitoring events (not derived from other events) */
-#define _PY_MONITORING_UNGROUPED_EVENTS 15
+#define _PY_MONITORING_UNGROUPED_EVENTS 16
/* Count of all monitoring events */
-#define _PY_MONITORING_EVENTS 17
+#define _PY_MONITORING_EVENTS 19
/* Tables of which tools are active for each monitored event. */
typedef struct _Py_LocalMonitors {
diff --git a/Include/cpython/monitoring.h b/Include/cpython/monitoring.h
index 797ba51..ce92942 100644
--- a/Include/cpython/monitoring.h
+++ b/Include/cpython/monitoring.h
@@ -13,25 +13,27 @@
#define PY_MONITORING_EVENT_LINE 5
#define PY_MONITORING_EVENT_INSTRUCTION 6
#define PY_MONITORING_EVENT_JUMP 7
-#define PY_MONITORING_EVENT_BRANCH 8
-#define PY_MONITORING_EVENT_STOP_ITERATION 9
+#define PY_MONITORING_EVENT_BRANCH_LEFT 8
+#define PY_MONITORING_EVENT_BRANCH_RIGHT 9
+#define PY_MONITORING_EVENT_STOP_ITERATION 10
#define PY_MONITORING_IS_INSTRUMENTED_EVENT(ev) \
((ev) < _PY_MONITORING_LOCAL_EVENTS)
/* Other events, mainly exceptions */
-#define PY_MONITORING_EVENT_RAISE 10
-#define PY_MONITORING_EVENT_EXCEPTION_HANDLED 11
-#define PY_MONITORING_EVENT_PY_UNWIND 12
-#define PY_MONITORING_EVENT_PY_THROW 13
-#define PY_MONITORING_EVENT_RERAISE 14
+#define PY_MONITORING_EVENT_RAISE 11
+#define PY_MONITORING_EVENT_EXCEPTION_HANDLED 12
+#define PY_MONITORING_EVENT_PY_UNWIND 13
+#define PY_MONITORING_EVENT_PY_THROW 14
+#define PY_MONITORING_EVENT_RERAISE 15
/* Ancillary events */
-#define PY_MONITORING_EVENT_C_RETURN 15
-#define PY_MONITORING_EVENT_C_RAISE 16
+#define PY_MONITORING_EVENT_C_RETURN 16
+#define PY_MONITORING_EVENT_C_RAISE 17
+#define PY_MONITORING_EVENT_BRANCH 18
typedef struct _PyMonitoringState {
@@ -74,11 +76,19 @@ PyAPI_FUNC(int)
_PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset);
-PyAPI_FUNC(int)
+Py_DEPRECATED(3.14) PyAPI_FUNC(int)
_PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset);
PyAPI_FUNC(int)
+_PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
+ PyObject *target_offset);
+
+PyAPI_FUNC(int)
+_PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
+ PyObject *target_offset);
+
+PyAPI_FUNC(int)
_PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *retval);
@@ -174,12 +184,21 @@ PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t
}
static inline int
-PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
+PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
+ PyObject *target_offset)
+{
+ _PYMONITORING_IF_ACTIVE(
+ state,
+ _PyMonitoring_FireBranchRightEvent(state, codelike, offset, target_offset));
+}
+
+static inline int
+PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset)
{
_PYMONITORING_IF_ACTIVE(
state,
- _PyMonitoring_FireBranchEvent(state, codelike, offset, target_offset));
+ _PyMonitoring_FireBranchLeftEvent(state, codelike, offset, target_offset));
}
static inline int
diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h
index d607a54..d97fe81 100644
--- a/Include/internal/pycore_code.h
+++ b/Include/internal/pycore_code.h
@@ -603,6 +603,8 @@ extern _Py_CODEUNIT _Py_GetBaseCodeUnit(PyCodeObject *code, int offset);
extern int _PyInstruction_GetLength(PyCodeObject *code, int offset);
+extern PyObject *_PyInstrumentation_BranchesIterator(PyCodeObject *code);
+
struct _PyCode8 _PyCode_DEF(8);
PyAPI_DATA(const struct _PyCode8) _Py_InitCleanup;
diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h
index 14e2957..079a9be 100644
--- a/Include/internal/pycore_magic_number.h
+++ b/Include/internal/pycore_magic_number.h
@@ -262,6 +262,7 @@ Known values:
Python 3.14a1 3607 (Add pseudo instructions JUMP_IF_TRUE/FALSE)
Python 3.14a1 3608 (Add support for slices)
Python 3.14a2 3609 (Add LOAD_SMALL_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST)
+ Python 3.14a3 3610 (Add NOT_TAKEN instruction)
Python 3.15 will start with 3650
@@ -274,7 +275,7 @@ PC/launcher.c must also be updated.
*/
-#define PYC_MAGIC_NUMBER 3609
+#define PYC_MAGIC_NUMBER 3611
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index d2ae892..e09fff0 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -243,6 +243,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 0;
case INSTRUMENTED_LOAD_SUPER_ATTR:
return 0;
+ case INSTRUMENTED_NOT_TAKEN:
+ return 0;
case INSTRUMENTED_POP_JUMP_IF_FALSE:
return 0;
case INSTRUMENTED_POP_JUMP_IF_NONE:
@@ -367,6 +369,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 1;
case NOP:
return 0;
+ case NOT_TAKEN:
+ return 0;
case POP_BLOCK:
return 0;
case POP_EXCEPT:
@@ -702,6 +706,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 0;
case INSTRUMENTED_LOAD_SUPER_ATTR:
return 0;
+ case INSTRUMENTED_NOT_TAKEN:
+ return 0;
case INSTRUMENTED_POP_JUMP_IF_FALSE:
return 0;
case INSTRUMENTED_POP_JUMP_IF_NONE:
@@ -826,6 +832,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 2;
case NOP:
return 0;
+ case NOT_TAKEN:
+ return 0;
case POP_BLOCK:
return 0;
case POP_EXCEPT:
@@ -1387,6 +1395,10 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
*effect = 0;
return 0;
}
+ case INSTRUMENTED_NOT_TAKEN: {
+ *effect = 0;
+ return 0;
+ }
case INSTRUMENTED_POP_JUMP_IF_FALSE: {
*effect = 0;
return 0;
@@ -1635,6 +1647,10 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
*effect = 0;
return 0;
}
+ case NOT_TAKEN: {
+ *effect = 0;
+ return 0;
+ }
case POP_BLOCK: {
*effect = 0;
return 0;
@@ -2043,6 +2059,7 @@ 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_NOT_TAKEN] = { true, INSTR_FMT_IX, 0 },
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
@@ -2100,6 +2117,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 },
[MATCH_SEQUENCE] = { true, INSTR_FMT_IX, 0 },
[NOP] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [NOT_TAKEN] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
[POP_EXCEPT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
@@ -2304,6 +2322,7 @@ _PyOpcode_macro_expansion[256] = {
[MATCH_MAPPING] = { .nuops = 1, .uops = { { _MATCH_MAPPING, 0, 0 } } },
[MATCH_SEQUENCE] = { .nuops = 1, .uops = { { _MATCH_SEQUENCE, 0, 0 } } },
[NOP] = { .nuops = 1, .uops = { { _NOP, 0, 0 } } },
+ [NOT_TAKEN] = { .nuops = 1, .uops = { { _NOP, 0, 0 } } },
[POP_EXCEPT] = { .nuops = 1, .uops = { { _POP_EXCEPT, 0, 0 } } },
[POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 9, 1 } } },
[POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 9, 1 } } },
@@ -2462,6 +2481,7 @@ const char *_PyOpcode_OpName[266] = {
[INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD",
[INSTRUMENTED_LINE] = "INSTRUMENTED_LINE",
[INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
+ [INSTRUMENTED_NOT_TAKEN] = "INSTRUMENTED_NOT_TAKEN",
[INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE",
[INSTRUMENTED_POP_JUMP_IF_NONE] = "INSTRUMENTED_POP_JUMP_IF_NONE",
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE",
@@ -2524,6 +2544,7 @@ const char *_PyOpcode_OpName[266] = {
[MATCH_MAPPING] = "MATCH_MAPPING",
[MATCH_SEQUENCE] = "MATCH_SEQUENCE",
[NOP] = "NOP",
+ [NOT_TAKEN] = "NOT_TAKEN",
[POP_BLOCK] = "POP_BLOCK",
[POP_EXCEPT] = "POP_EXCEPT",
[POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
@@ -2718,6 +2739,7 @@ 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_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
[INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
[INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
@@ -2775,6 +2797,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[MATCH_MAPPING] = MATCH_MAPPING,
[MATCH_SEQUENCE] = MATCH_SEQUENCE,
[NOP] = NOP,
+ [NOT_TAKEN] = NOT_TAKEN,
[POP_EXCEPT] = POP_EXCEPT,
[POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
[POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
@@ -2833,7 +2856,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
#endif // NEED_OPCODE_METADATA
#define EXTRA_CASES \
- case 116: \
case 117: \
case 118: \
case 119: \
@@ -2874,7 +2896,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 233: \
case 234: \
case 235: \
- case 236: \
;
struct pseudo_targets {
uint8_t as_sequence;
diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h
index c6ce7e6..0872231 100644
--- a/Include/internal/pycore_opcode_utils.h
+++ b/Include/internal/pycore_opcode_utils.h
@@ -45,6 +45,12 @@ extern "C" {
(opcode) == JUMP_BACKWARD || \
(opcode) == JUMP_BACKWARD_NO_INTERRUPT)
+#define IS_CONDITIONAL_JUMP_OPCODE(opcode) \
+ ((opcode) == POP_JUMP_IF_FALSE || \
+ (opcode) == POP_JUMP_IF_TRUE || \
+ (opcode) == POP_JUMP_IF_NONE || \
+ (opcode) == POP_JUMP_IF_NOT_NONE)
+
#define IS_SCOPE_EXIT_OPCODE(opcode) \
((opcode) == RETURN_VALUE || \
(opcode) == RAISE_VARARGS || \
diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h
index 4556358..5fc57e4 100644
--- a/Include/internal/pycore_uop_ids.h
+++ b/Include/internal/pycore_uop_ids.h
@@ -155,6 +155,7 @@ 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_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
#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h
index ce3d23e..3cd189b 100644
--- a/Include/opcode_ids.h
+++ b/Include/opcode_ids.h
@@ -38,94 +38,95 @@ extern "C" {
#define MATCH_MAPPING 25
#define MATCH_SEQUENCE 26
#define NOP 27
-#define POP_EXCEPT 28
-#define POP_TOP 29
-#define PUSH_EXC_INFO 30
-#define PUSH_NULL 31
-#define RETURN_GENERATOR 32
-#define RETURN_VALUE 33
-#define SETUP_ANNOTATIONS 34
-#define STORE_SLICE 35
-#define STORE_SUBSCR 36
-#define TO_BOOL 37
-#define UNARY_INVERT 38
-#define UNARY_NEGATIVE 39
-#define UNARY_NOT 40
-#define WITH_EXCEPT_START 41
-#define BINARY_OP 42
-#define BUILD_LIST 43
-#define BUILD_MAP 44
-#define BUILD_SET 45
-#define BUILD_SLICE 46
-#define BUILD_STRING 47
-#define BUILD_TUPLE 48
-#define CALL 49
-#define CALL_FUNCTION_EX 50
-#define CALL_INTRINSIC_1 51
-#define CALL_INTRINSIC_2 52
-#define CALL_KW 53
-#define COMPARE_OP 54
-#define CONTAINS_OP 55
-#define CONVERT_VALUE 56
-#define COPY 57
-#define COPY_FREE_VARS 58
-#define DELETE_ATTR 59
-#define DELETE_DEREF 60
-#define DELETE_FAST 61
-#define DELETE_GLOBAL 62
-#define DELETE_NAME 63
-#define DICT_MERGE 64
-#define DICT_UPDATE 65
-#define EXTENDED_ARG 66
-#define FOR_ITER 67
-#define GET_AWAITABLE 68
-#define IMPORT_FROM 69
-#define IMPORT_NAME 70
-#define IS_OP 71
-#define JUMP_BACKWARD 72
-#define JUMP_BACKWARD_NO_INTERRUPT 73
-#define JUMP_FORWARD 74
-#define LIST_APPEND 75
-#define LIST_EXTEND 76
-#define LOAD_ATTR 77
-#define LOAD_COMMON_CONSTANT 78
-#define LOAD_CONST 79
-#define LOAD_DEREF 80
-#define LOAD_FAST 81
-#define LOAD_FAST_AND_CLEAR 82
-#define LOAD_FAST_CHECK 83
-#define LOAD_FAST_LOAD_FAST 84
-#define LOAD_FROM_DICT_OR_DEREF 85
-#define LOAD_FROM_DICT_OR_GLOBALS 86
-#define LOAD_GLOBAL 87
-#define LOAD_NAME 88
-#define LOAD_SMALL_INT 89
-#define LOAD_SPECIAL 90
-#define LOAD_SUPER_ATTR 91
-#define MAKE_CELL 92
-#define MAP_ADD 93
-#define MATCH_CLASS 94
-#define POP_JUMP_IF_FALSE 95
-#define POP_JUMP_IF_NONE 96
-#define POP_JUMP_IF_NOT_NONE 97
-#define POP_JUMP_IF_TRUE 98
-#define RAISE_VARARGS 99
-#define RERAISE 100
-#define SEND 101
-#define SET_ADD 102
-#define SET_FUNCTION_ATTRIBUTE 103
-#define SET_UPDATE 104
-#define STORE_ATTR 105
-#define STORE_DEREF 106
-#define STORE_FAST 107
-#define STORE_FAST_LOAD_FAST 108
-#define STORE_FAST_STORE_FAST 109
-#define STORE_GLOBAL 110
-#define STORE_NAME 111
-#define SWAP 112
-#define UNPACK_EX 113
-#define UNPACK_SEQUENCE 114
-#define YIELD_VALUE 115
+#define NOT_TAKEN 28
+#define POP_EXCEPT 29
+#define POP_TOP 30
+#define PUSH_EXC_INFO 31
+#define PUSH_NULL 32
+#define RETURN_GENERATOR 33
+#define RETURN_VALUE 34
+#define SETUP_ANNOTATIONS 35
+#define STORE_SLICE 36
+#define STORE_SUBSCR 37
+#define TO_BOOL 38
+#define UNARY_INVERT 39
+#define UNARY_NEGATIVE 40
+#define UNARY_NOT 41
+#define WITH_EXCEPT_START 42
+#define BINARY_OP 43
+#define BUILD_LIST 44
+#define BUILD_MAP 45
+#define BUILD_SET 46
+#define BUILD_SLICE 47
+#define BUILD_STRING 48
+#define BUILD_TUPLE 49
+#define CALL 50
+#define CALL_FUNCTION_EX 51
+#define CALL_INTRINSIC_1 52
+#define CALL_INTRINSIC_2 53
+#define CALL_KW 54
+#define COMPARE_OP 55
+#define CONTAINS_OP 56
+#define CONVERT_VALUE 57
+#define COPY 58
+#define COPY_FREE_VARS 59
+#define DELETE_ATTR 60
+#define DELETE_DEREF 61
+#define DELETE_FAST 62
+#define DELETE_GLOBAL 63
+#define DELETE_NAME 64
+#define DICT_MERGE 65
+#define DICT_UPDATE 66
+#define EXTENDED_ARG 67
+#define FOR_ITER 68
+#define GET_AWAITABLE 69
+#define IMPORT_FROM 70
+#define IMPORT_NAME 71
+#define IS_OP 72
+#define JUMP_BACKWARD 73
+#define JUMP_BACKWARD_NO_INTERRUPT 74
+#define JUMP_FORWARD 75
+#define LIST_APPEND 76
+#define LIST_EXTEND 77
+#define LOAD_ATTR 78
+#define LOAD_COMMON_CONSTANT 79
+#define LOAD_CONST 80
+#define LOAD_DEREF 81
+#define LOAD_FAST 82
+#define LOAD_FAST_AND_CLEAR 83
+#define LOAD_FAST_CHECK 84
+#define LOAD_FAST_LOAD_FAST 85
+#define LOAD_FROM_DICT_OR_DEREF 86
+#define LOAD_FROM_DICT_OR_GLOBALS 87
+#define LOAD_GLOBAL 88
+#define LOAD_NAME 89
+#define LOAD_SMALL_INT 90
+#define LOAD_SPECIAL 91
+#define LOAD_SUPER_ATTR 92
+#define MAKE_CELL 93
+#define MAP_ADD 94
+#define MATCH_CLASS 95
+#define POP_JUMP_IF_FALSE 96
+#define POP_JUMP_IF_NONE 97
+#define POP_JUMP_IF_NOT_NONE 98
+#define POP_JUMP_IF_TRUE 99
+#define RAISE_VARARGS 100
+#define RERAISE 101
+#define SEND 102
+#define SET_ADD 103
+#define SET_FUNCTION_ATTRIBUTE 104
+#define SET_UPDATE 105
+#define STORE_ATTR 106
+#define STORE_DEREF 107
+#define STORE_FAST 108
+#define STORE_FAST_LOAD_FAST 109
+#define STORE_FAST_STORE_FAST 110
+#define STORE_GLOBAL 111
+#define STORE_NAME 112
+#define SWAP 113
+#define UNPACK_EX 114
+#define UNPACK_SEQUENCE 115
+#define YIELD_VALUE 116
#define RESUME 149
#define BINARY_OP_ADD_FLOAT 150
#define BINARY_OP_ADD_INT 151
@@ -205,14 +206,15 @@ extern "C" {
#define UNPACK_SEQUENCE_LIST 225
#define UNPACK_SEQUENCE_TUPLE 226
#define UNPACK_SEQUENCE_TWO_TUPLE 227
-#define INSTRUMENTED_END_FOR 237
-#define INSTRUMENTED_END_SEND 238
-#define INSTRUMENTED_LOAD_SUPER_ATTR 239
-#define INSTRUMENTED_FOR_ITER 240
-#define INSTRUMENTED_CALL_KW 241
-#define INSTRUMENTED_CALL_FUNCTION_EX 242
-#define INSTRUMENTED_INSTRUCTION 243
-#define INSTRUMENTED_JUMP_FORWARD 244
+#define INSTRUMENTED_END_FOR 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
+#define INSTRUMENTED_INSTRUCTION 242
+#define INSTRUMENTED_JUMP_FORWARD 243
+#define INSTRUMENTED_NOT_TAKEN 244
#define INSTRUMENTED_POP_JUMP_IF_TRUE 245
#define INSTRUMENTED_POP_JUMP_IF_FALSE 246
#define INSTRUMENTED_POP_JUMP_IF_NONE 247
@@ -235,9 +237,9 @@ extern "C" {
#define SETUP_WITH 264
#define STORE_FAST_MAYBE_NULL 265
-#define HAVE_ARGUMENT 41
+#define HAVE_ARGUMENT 42
#define MIN_SPECIALIZED_OPCODE 150
-#define MIN_INSTRUMENTED_OPCODE 237
+#define MIN_INSTRUMENTED_OPCODE 236
#ifdef __cplusplus
}
diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py
index cda3c34..dada2cb 100644
--- a/Lib/_opcode_metadata.py
+++ b/Lib/_opcode_metadata.py
@@ -231,102 +231,104 @@ opmap = {
'MATCH_MAPPING': 25,
'MATCH_SEQUENCE': 26,
'NOP': 27,
- 'POP_EXCEPT': 28,
- 'POP_TOP': 29,
- 'PUSH_EXC_INFO': 30,
- 'PUSH_NULL': 31,
- 'RETURN_GENERATOR': 32,
- 'RETURN_VALUE': 33,
- 'SETUP_ANNOTATIONS': 34,
- 'STORE_SLICE': 35,
- 'STORE_SUBSCR': 36,
- 'TO_BOOL': 37,
- 'UNARY_INVERT': 38,
- 'UNARY_NEGATIVE': 39,
- 'UNARY_NOT': 40,
- 'WITH_EXCEPT_START': 41,
- 'BINARY_OP': 42,
- 'BUILD_LIST': 43,
- 'BUILD_MAP': 44,
- 'BUILD_SET': 45,
- 'BUILD_SLICE': 46,
- 'BUILD_STRING': 47,
- 'BUILD_TUPLE': 48,
- 'CALL': 49,
- 'CALL_FUNCTION_EX': 50,
- 'CALL_INTRINSIC_1': 51,
- 'CALL_INTRINSIC_2': 52,
- 'CALL_KW': 53,
- 'COMPARE_OP': 54,
- 'CONTAINS_OP': 55,
- 'CONVERT_VALUE': 56,
- 'COPY': 57,
- 'COPY_FREE_VARS': 58,
- 'DELETE_ATTR': 59,
- 'DELETE_DEREF': 60,
- 'DELETE_FAST': 61,
- 'DELETE_GLOBAL': 62,
- 'DELETE_NAME': 63,
- 'DICT_MERGE': 64,
- 'DICT_UPDATE': 65,
- 'EXTENDED_ARG': 66,
- 'FOR_ITER': 67,
- 'GET_AWAITABLE': 68,
- 'IMPORT_FROM': 69,
- 'IMPORT_NAME': 70,
- 'IS_OP': 71,
- 'JUMP_BACKWARD': 72,
- 'JUMP_BACKWARD_NO_INTERRUPT': 73,
- 'JUMP_FORWARD': 74,
- 'LIST_APPEND': 75,
- 'LIST_EXTEND': 76,
- 'LOAD_ATTR': 77,
- 'LOAD_COMMON_CONSTANT': 78,
- 'LOAD_CONST': 79,
- 'LOAD_DEREF': 80,
- 'LOAD_FAST': 81,
- 'LOAD_FAST_AND_CLEAR': 82,
- 'LOAD_FAST_CHECK': 83,
- 'LOAD_FAST_LOAD_FAST': 84,
- 'LOAD_FROM_DICT_OR_DEREF': 85,
- 'LOAD_FROM_DICT_OR_GLOBALS': 86,
- 'LOAD_GLOBAL': 87,
- 'LOAD_NAME': 88,
- 'LOAD_SMALL_INT': 89,
- 'LOAD_SPECIAL': 90,
- 'LOAD_SUPER_ATTR': 91,
- 'MAKE_CELL': 92,
- 'MAP_ADD': 93,
- 'MATCH_CLASS': 94,
- 'POP_JUMP_IF_FALSE': 95,
- 'POP_JUMP_IF_NONE': 96,
- 'POP_JUMP_IF_NOT_NONE': 97,
- 'POP_JUMP_IF_TRUE': 98,
- 'RAISE_VARARGS': 99,
- 'RERAISE': 100,
- 'SEND': 101,
- 'SET_ADD': 102,
- 'SET_FUNCTION_ATTRIBUTE': 103,
- 'SET_UPDATE': 104,
- 'STORE_ATTR': 105,
- 'STORE_DEREF': 106,
- 'STORE_FAST': 107,
- 'STORE_FAST_LOAD_FAST': 108,
- 'STORE_FAST_STORE_FAST': 109,
- 'STORE_GLOBAL': 110,
- 'STORE_NAME': 111,
- 'SWAP': 112,
- 'UNPACK_EX': 113,
- 'UNPACK_SEQUENCE': 114,
- 'YIELD_VALUE': 115,
- 'INSTRUMENTED_END_FOR': 237,
- 'INSTRUMENTED_END_SEND': 238,
- 'INSTRUMENTED_LOAD_SUPER_ATTR': 239,
- 'INSTRUMENTED_FOR_ITER': 240,
- 'INSTRUMENTED_CALL_KW': 241,
- 'INSTRUMENTED_CALL_FUNCTION_EX': 242,
- 'INSTRUMENTED_INSTRUCTION': 243,
- 'INSTRUMENTED_JUMP_FORWARD': 244,
+ 'NOT_TAKEN': 28,
+ 'POP_EXCEPT': 29,
+ 'POP_TOP': 30,
+ 'PUSH_EXC_INFO': 31,
+ 'PUSH_NULL': 32,
+ 'RETURN_GENERATOR': 33,
+ 'RETURN_VALUE': 34,
+ 'SETUP_ANNOTATIONS': 35,
+ 'STORE_SLICE': 36,
+ 'STORE_SUBSCR': 37,
+ 'TO_BOOL': 38,
+ 'UNARY_INVERT': 39,
+ 'UNARY_NEGATIVE': 40,
+ 'UNARY_NOT': 41,
+ 'WITH_EXCEPT_START': 42,
+ 'BINARY_OP': 43,
+ 'BUILD_LIST': 44,
+ 'BUILD_MAP': 45,
+ 'BUILD_SET': 46,
+ 'BUILD_SLICE': 47,
+ 'BUILD_STRING': 48,
+ 'BUILD_TUPLE': 49,
+ 'CALL': 50,
+ 'CALL_FUNCTION_EX': 51,
+ 'CALL_INTRINSIC_1': 52,
+ 'CALL_INTRINSIC_2': 53,
+ 'CALL_KW': 54,
+ 'COMPARE_OP': 55,
+ 'CONTAINS_OP': 56,
+ 'CONVERT_VALUE': 57,
+ 'COPY': 58,
+ 'COPY_FREE_VARS': 59,
+ 'DELETE_ATTR': 60,
+ 'DELETE_DEREF': 61,
+ 'DELETE_FAST': 62,
+ 'DELETE_GLOBAL': 63,
+ 'DELETE_NAME': 64,
+ 'DICT_MERGE': 65,
+ 'DICT_UPDATE': 66,
+ 'EXTENDED_ARG': 67,
+ 'FOR_ITER': 68,
+ 'GET_AWAITABLE': 69,
+ 'IMPORT_FROM': 70,
+ 'IMPORT_NAME': 71,
+ 'IS_OP': 72,
+ 'JUMP_BACKWARD': 73,
+ 'JUMP_BACKWARD_NO_INTERRUPT': 74,
+ 'JUMP_FORWARD': 75,
+ 'LIST_APPEND': 76,
+ 'LIST_EXTEND': 77,
+ 'LOAD_ATTR': 78,
+ 'LOAD_COMMON_CONSTANT': 79,
+ 'LOAD_CONST': 80,
+ 'LOAD_DEREF': 81,
+ 'LOAD_FAST': 82,
+ 'LOAD_FAST_AND_CLEAR': 83,
+ 'LOAD_FAST_CHECK': 84,
+ 'LOAD_FAST_LOAD_FAST': 85,
+ 'LOAD_FROM_DICT_OR_DEREF': 86,
+ 'LOAD_FROM_DICT_OR_GLOBALS': 87,
+ 'LOAD_GLOBAL': 88,
+ 'LOAD_NAME': 89,
+ 'LOAD_SMALL_INT': 90,
+ 'LOAD_SPECIAL': 91,
+ 'LOAD_SUPER_ATTR': 92,
+ 'MAKE_CELL': 93,
+ 'MAP_ADD': 94,
+ 'MATCH_CLASS': 95,
+ 'POP_JUMP_IF_FALSE': 96,
+ 'POP_JUMP_IF_NONE': 97,
+ 'POP_JUMP_IF_NOT_NONE': 98,
+ 'POP_JUMP_IF_TRUE': 99,
+ 'RAISE_VARARGS': 100,
+ 'RERAISE': 101,
+ 'SEND': 102,
+ 'SET_ADD': 103,
+ 'SET_FUNCTION_ATTRIBUTE': 104,
+ 'SET_UPDATE': 105,
+ 'STORE_ATTR': 106,
+ 'STORE_DEREF': 107,
+ 'STORE_FAST': 108,
+ 'STORE_FAST_LOAD_FAST': 109,
+ 'STORE_FAST_STORE_FAST': 110,
+ 'STORE_GLOBAL': 111,
+ 'STORE_NAME': 112,
+ 'SWAP': 113,
+ 'UNPACK_EX': 114,
+ 'UNPACK_SEQUENCE': 115,
+ 'YIELD_VALUE': 116,
+ 'INSTRUMENTED_END_FOR': 236,
+ 'INSTRUMENTED_END_SEND': 237,
+ 'INSTRUMENTED_LOAD_SUPER_ATTR': 238,
+ 'INSTRUMENTED_FOR_ITER': 239,
+ 'INSTRUMENTED_CALL_KW': 240,
+ 'INSTRUMENTED_CALL_FUNCTION_EX': 241,
+ 'INSTRUMENTED_INSTRUCTION': 242,
+ 'INSTRUMENTED_JUMP_FORWARD': 243,
+ 'INSTRUMENTED_NOT_TAKEN': 244,
'INSTRUMENTED_POP_JUMP_IF_TRUE': 245,
'INSTRUMENTED_POP_JUMP_IF_FALSE': 246,
'INSTRUMENTED_POP_JUMP_IF_NONE': 247,
@@ -348,5 +350,5 @@ opmap = {
'STORE_FAST_MAYBE_NULL': 265,
}
-HAVE_ARGUMENT = 41
-MIN_INSTRUMENTED_OPCODE = 237
+HAVE_ARGUMENT = 42
+MIN_INSTRUMENTED_OPCODE = 236
diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py
index 2dd7cf6..f8c4fc1 100644
--- a/Lib/test/test_compiler_codegen.py
+++ b/Lib/test/test_compiler_codegen.py
@@ -29,6 +29,7 @@ class IsolatedCodeGenTests(CodegenTestCase):
('LOAD_CONST', 0, 1),
('TO_BOOL', 0, 1),
('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1),
+ ('NOT_TAKEN', None, 1),
('LOAD_SMALL_INT', 42, 1),
('JUMP_NO_INTERRUPT', exit_lbl := self.Label()),
false_lbl,
@@ -49,6 +50,7 @@ class IsolatedCodeGenTests(CodegenTestCase):
('GET_ITER', None, 1),
loop_lbl := self.Label(),
('FOR_ITER', exit_lbl := self.Label(), 1),
+ ('NOT_TAKEN', None, 1),
('NOP', None, 1, 1),
('STORE_NAME', 1, 1),
('LOAD_NAME', 2, 2),
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index c719f57..955a3e4 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -175,10 +175,11 @@ dis_bug708901 = """\
%3d CALL 2
GET_ITER
- L1: FOR_ITER 3 (to L2)
+ L1: FOR_ITER 4 (to L2)
+ NOT_TAKEN
STORE_FAST 0 (res)
-%3d JUMP_BACKWARD 5 (to L1)
+%3d JUMP_BACKWARD 6 (to L1)
%3d L2: END_FOR
POP_TOP
@@ -200,7 +201,8 @@ def bug1333982(x=[]):
dis_bug1333982 = """\
%3d RESUME 0
-%3d LOAD_COMMON_CONSTANT 0 (AssertionError)
+%3d NOT_TAKEN
+ LOAD_COMMON_CONSTANT 0 (AssertionError)
LOAD_CONST 0 (<code object <genexpr> at 0x..., file "%s", line %d>)
MAKE_FUNCTION
LOAD_FAST 0 (x)
@@ -432,7 +434,7 @@ dis_compound_stmt_str = """\
1 LOAD_SMALL_INT 0
STORE_NAME 0 (x)
- 2 L1: NOP
+ 2 L1: NOT_TAKEN
3 LOAD_NAME 0 (x)
LOAD_SMALL_INT 1
@@ -458,7 +460,8 @@ dis_traceback = """\
%4d LOAD_GLOBAL 0 (Exception)
CHECK_EXC_MATCH
- POP_JUMP_IF_FALSE 23 (to L7)
+ POP_JUMP_IF_FALSE 24 (to L7)
+ NOT_TAKEN
STORE_FAST 0 (e)
%4d L4: LOAD_FAST 0 (e)
@@ -555,7 +558,8 @@ dis_with = """\
%4d L3: PUSH_EXC_INFO
WITH_EXCEPT_START
TO_BOOL
- POP_JUMP_IF_TRUE 1 (to L4)
+ POP_JUMP_IF_TRUE 2 (to L4)
+ NOT_TAKEN
RERAISE 2
L4: POP_TOP
L5: POP_EXCEPT
@@ -645,7 +649,8 @@ dis_asyncwith = """\
L20: CLEANUP_THROW
L21: END_SEND
TO_BOOL
- POP_JUMP_IF_TRUE 1 (to L22)
+ POP_JUMP_IF_TRUE 2 (to L22)
+ NOT_TAKEN
RERAISE 2
L22: POP_TOP
L23: POP_EXCEPT
@@ -839,7 +844,8 @@ Disassembly of <code object <genexpr> at 0x..., file "%s", line %d>:
L1: RESUME 0
LOAD_FAST 0 (.0)
GET_ITER
- L2: FOR_ITER 10 (to L3)
+ L2: FOR_ITER 11 (to L3)
+ NOT_TAKEN
STORE_FAST 1 (z)
LOAD_DEREF 2 (x)
LOAD_FAST 1 (z)
@@ -847,7 +853,7 @@ Disassembly of <code object <genexpr> at 0x..., file "%s", line %d>:
YIELD_VALUE 0
RESUME 5
POP_TOP
- JUMP_BACKWARD 12 (to L2)
+ JUMP_BACKWARD 13 (to L2)
L3: END_FOR
POP_TOP
LOAD_CONST 0 (None)
@@ -893,14 +899,15 @@ dis_loop_test_quickened_code = """\
LOAD_SMALL_INT 3
BINARY_OP 5 (*)
GET_ITER
- L1: FOR_ITER_LIST 14 (to L2)
+ L1: FOR_ITER_LIST 15 (to L2)
+ NOT_TAKEN
STORE_FAST 0 (i)
%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL)
LOAD_FAST 0 (i)
CALL_PY_GENERAL 1
POP_TOP
- JUMP_BACKWARD 16 (to L1)
+ JUMP_BACKWARD 17 (to L1)
%3d L2: END_FOR
POP_TOP
@@ -1699,204 +1706,214 @@ def _prepare_test_cases():
Instruction = dis.Instruction
expected_opinfo_outer = [
- Instruction(opname='MAKE_CELL', opcode=92, 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=92, 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=93, 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=93, 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=79, 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=81, 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=81, 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=48, 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=79, arg=0, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=80, 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=82, 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=82, 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=49, 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=80, 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=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=103, 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=103, 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=107, 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=87, 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=80, 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=80, 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=79, 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=89, 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=43, 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=44, 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=79, 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=49, 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=29, 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=81, 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=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=104, 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=104, 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=108, 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=88, 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=81, 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=81, 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=80, 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=90, 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=44, 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=45, 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=80, 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=50, 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=30, 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=82, 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=34, 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=58, 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=92, 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=92, 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='COPY_FREE_VARS', opcode=59, 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=93, 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=93, 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=79, 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=81, 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=81, 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=81, 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=81, 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=48, 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=79, arg=0, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=80, 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=82, 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=82, 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=82, 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=82, 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=49, 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=80, 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=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=103, 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=103, 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=107, 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=87, 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=80, 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=80, 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=80, 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=80, 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=49, 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=29, 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=81, 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=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=104, 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=104, 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=108, 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=88, 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=81, 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=81, 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=81, 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=81, 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=50, 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=30, 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=82, 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=34, 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=58, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY_FREE_VARS', opcode=59, 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=87, 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=80, 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=80, 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=80, 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=80, 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=84, 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=49, 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=29, 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=79, 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=33, arg=None, argval=None, argrepr='', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, 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=81, 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=81, 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=81, 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=81, 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=85, 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=50, 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=30, 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=80, 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=34, 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=87, 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=89, 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=49, 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='LOAD_GLOBAL', opcode=88, 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=90, 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=50, 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=67, arg=30, argval=88, 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=107, 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=87, 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=81, 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=49, 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=29, 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=81, 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=89, 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=54, 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=95, arg=2, argval=68, 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='JUMP_BACKWARD', opcode=72, arg=22, argval=24, argrepr='to L1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, label=2, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=6, argval=6, argrepr='', offset=70, start_offset=70, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=54, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=98, arg=2, argval=84, argrepr='to L3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='JUMP_BACKWARD', opcode=72, arg=30, argval=24, argrepr='to L1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, label=3, positions=None, cache_info=None),
- Instruction(opname='JUMP_FORWARD', opcode=74, arg=13, argval=114, argrepr='to L5', offset=86, start_offset=86, 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=88, start_offset=88, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=92, start_offset=92, 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=79, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=102, start_offset=102, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=104, start_offset=104, 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=29, arg=None, argval=None, argrepr='', offset=112, start_offset=112, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST_CHECK', opcode=83, arg=0, argval='i', argrepr='i', offset=114, start_offset=114, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=37, arg=None, argval=None, argrepr='', offset=116, start_offset=116, 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=95, arg=33, argval=194, argrepr='to L8', offset=124, start_offset=124, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=128, start_offset=128, 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=81, arg=0, argval='i', argrepr='i', offset=138, start_offset=138, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=140, start_offset=140, 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=29, arg=None, argval=None, argrepr='', offset=148, start_offset=148, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=150, start_offset=150, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=1, argval=1, argrepr='', offset=152, start_offset=152, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=42, arg=23, argval=23, argrepr='-=', offset=154, start_offset=154, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=107, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=160, start_offset=160, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=6, argval=6, argrepr='', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=54, arg=148, argval='>', argrepr='bool(>)', offset=164, start_offset=164, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=95, arg=2, argval=176, argrepr='to L6', offset=168, start_offset=168, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='JUMP_BACKWARD', opcode=72, arg=31, argval=114, argrepr='to L5', offset=172, start_offset=172, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=176, start_offset=176, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=4, argval=4, argrepr='', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=54, arg=18, argval='<', argrepr='bool(<)', offset=180, start_offset=180, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=98, arg=2, argval=192, argrepr='to L7', offset=184, start_offset=184, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='JUMP_BACKWARD', opcode=72, arg=39, argval=114, argrepr='to L5', offset=188, start_offset=188, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='JUMP_FORWARD', opcode=74, arg=11, argval=216, argrepr='to L9', offset=192, start_offset=192, starts_line=True, line_number=17, label=7, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=194, start_offset=194, 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=79, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=204, start_offset=204, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=206, start_offset=206, 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=29, arg=None, argval=None, argrepr='', offset=214, start_offset=214, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=216, start_offset=216, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=0, argval=0, argrepr='', offset=220, start_offset=220, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=42, arg=11, argval=11, argrepr='/', offset=222, start_offset=222, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=228, start_offset=228, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=57, arg=1, argval=1, argrepr='', offset=230, start_offset=230, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=90, arg=1, argval=1, argrepr='__exit__', offset=232, start_offset=232, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=112, arg=2, argval=2, argrepr='', offset=234, start_offset=234, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=112, arg=3, argval=3, argrepr='', offset=236, start_offset=236, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=90, arg=0, argval=0, argrepr='__enter__', offset=238, start_offset=238, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=0, argval=0, argrepr='', offset=240, start_offset=240, 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=107, arg=1, argval='dodgy', argrepr='dodgy', offset=248, start_offset=248, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=250, start_offset=250, 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=79, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=260, start_offset=260, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=262, start_offset=262, 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=29, arg=None, argval=None, argrepr='', offset=270, start_offset=270, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval=None, argrepr='None', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval=None, argrepr='None', offset=276, start_offset=276, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=3, argval=3, argrepr='', offset=278, start_offset=278, 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=29, arg=None, argval=None, argrepr='', offset=286, start_offset=286, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=288, start_offset=288, 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=79, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=298, start_offset=298, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=300, start_offset=300, 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=29, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval=None, argrepr='None', offset=310, start_offset=310, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=314, start_offset=314, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='WITH_EXCEPT_START', opcode=41, arg=None, argval=None, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=37, arg=None, argval=None, argrepr='', offset=318, start_offset=318, 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=98, arg=1, argval=332, argrepr='to L11', offset=326, start_offset=326, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='RERAISE', opcode=100, arg=2, argval=2, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=336, start_offset=336, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=338, start_offset=338, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=73, arg=28, argval=288, argrepr='to L10', offset=342, start_offset=342, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=344, start_offset=344, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=100, arg=1, argval=1, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=350, start_offset=350, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=352, start_offset=352, 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=362, start_offset=362, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=95, arg=14, argval=396, argrepr='to L12', offset=364, start_offset=364, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=370, start_offset=370, 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=79, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=380, start_offset=380, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=382, start_offset=382, 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=29, arg=None, argval=None, argrepr='', offset=390, start_offset=390, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=392, start_offset=392, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=73, arg=54, argval=288, argrepr='to L10', offset=394, start_offset=394, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=100, arg=0, argval=0, argrepr='', offset=396, start_offset=396, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=398, start_offset=398, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=100, arg=1, argval=1, argrepr='', offset=402, start_offset=402, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=404, start_offset=404, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=406, start_offset=406, 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=79, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=416, start_offset=416, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=418, start_offset=418, 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=29, arg=None, argval=None, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=100, arg=0, argval=0, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=430, start_offset=430, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=100, arg=1, argval=1, argrepr='', offset=434, start_offset=434, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='FOR_ITER', opcode=68, arg=34, argval=96, 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='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='STORE_FAST', opcode=108, 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=88, arg=3, argval='print', argrepr='print + NULL', offset=32, start_offset=32, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=44, start_offset=44, 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=30, arg=None, argval=None, argrepr='', offset=52, start_offset=52, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=54, start_offset=54, starts_line=True, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=4, argval=4, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=55, arg=18, argval='<', argrepr='bool(<)', offset=58, start_offset=58, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=96, arg=3, argval=72, argrepr='to L2', offset=62, start_offset=62, 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=66, start_offset=66, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=73, arg=24, argval=24, argrepr='to L1', offset=68, start_offset=68, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=72, start_offset=72, starts_line=True, line_number=7, label=2, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=6, argval=6, argrepr='', offset=74, start_offset=74, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=55, arg=148, argval='>', argrepr='bool(>)', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=99, arg=3, argval=90, argrepr='to L3', offset=80, start_offset=80, 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=84, start_offset=84, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=73, arg=33, argval=24, argrepr='to L1', offset=86, start_offset=86, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=True, line_number=None, label=3, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_FORWARD', opcode=75, arg=13, argval=122, 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=9, 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_TOP', opcode=30, 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=88, arg=3, argval='print', argrepr='print + NULL', 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='LOAD_CONST', opcode=80, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=112, start_offset=112, 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=30, arg=None, argval=None, argrepr='', offset=120, start_offset=120, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST_CHECK', opcode=84, arg=0, argval='i', argrepr='i', offset=122, start_offset=122, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=38, arg=None, argval=None, argrepr='', offset=124, start_offset=124, 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=96, arg=37, argval=210, argrepr='to L8', offset=132, start_offset=132, 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=136, start_offset=136, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=138, start_offset=138, 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=82, arg=0, argval='i', argrepr='i', offset=148, start_offset=148, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=150, start_offset=150, 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=30, arg=None, argval=None, argrepr='', offset=158, start_offset=158, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=160, start_offset=160, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=1, argval=1, argrepr='', offset=162, start_offset=162, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=43, arg=23, argval=23, argrepr='-=', offset=164, start_offset=164, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=108, arg=0, argval='i', argrepr='i', offset=168, start_offset=168, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=170, start_offset=170, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=6, argval=6, argrepr='', offset=172, start_offset=172, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=55, arg=148, argval='>', argrepr='bool(>)', offset=174, start_offset=174, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=96, arg=3, argval=188, argrepr='to L6', offset=178, start_offset=178, 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=182, start_offset=182, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=73, arg=33, argval=122, argrepr='to L5', offset=184, start_offset=184, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=4, argval=4, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=55, arg=18, argval='<', argrepr='bool(<)', offset=192, start_offset=192, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=99, arg=3, argval=206, argrepr='to L7', offset=196, start_offset=196, 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=200, start_offset=200, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=73, arg=42, argval=122, argrepr='to L5', offset=202, start_offset=202, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=206, start_offset=206, starts_line=True, line_number=None, label=7, positions=None, cache_info=None),
+ Instruction(opname='JUMP_FORWARD', opcode=75, arg=11, argval=232, argrepr='to L9', offset=208, start_offset=208, starts_line=True, line_number=17, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=210, start_offset=210, 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=80, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=220, start_offset=220, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=222, start_offset=222, 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=30, 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='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=232, start_offset=232, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=1, argval=1, argrepr='', offset=234, start_offset=234, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=0, argval=0, argrepr='', offset=236, start_offset=236, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=43, arg=11, argval=11, argrepr='/', offset=238, start_offset=238, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=244, start_offset=244, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=58, arg=1, argval=1, argrepr='', offset=246, start_offset=246, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=91, arg=1, argval=1, argrepr='__exit__', offset=248, start_offset=248, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=113, arg=2, argval=2, argrepr='', offset=250, start_offset=250, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=113, arg=3, argval=3, argrepr='', offset=252, start_offset=252, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=91, arg=0, argval=0, argrepr='__enter__', offset=254, start_offset=254, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=0, argval=0, argrepr='', offset=256, start_offset=256, 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=108, arg=1, argval='dodgy', argrepr='dodgy', offset=264, start_offset=264, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=266, start_offset=266, 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=80, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=276, start_offset=276, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=278, start_offset=278, 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=30, arg=None, argval=None, argrepr='', offset=286, start_offset=286, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=288, start_offset=288, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=290, start_offset=290, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=292, start_offset=292, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=3, argval=3, argrepr='', offset=294, start_offset=294, 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=30, arg=None, argval=None, argrepr='', offset=302, start_offset=302, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=304, start_offset=304, 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=80, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=314, start_offset=314, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=316, start_offset=316, 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=30, arg=None, argval=None, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=326, start_offset=326, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=34, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=31, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='WITH_EXCEPT_START', opcode=42, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=38, arg=None, argval=None, argrepr='', offset=334, start_offset=334, 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=99, arg=2, argval=350, argrepr='to L11', offset=342, start_offset=342, 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=346, start_offset=346, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=101, arg=2, argval=2, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=350, start_offset=350, 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=352, start_offset=352, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=354, start_offset=354, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=74, arg=29, argval=304, argrepr='to L10', offset=360, start_offset=360, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=58, arg=3, argval=3, argrepr='', offset=362, start_offset=362, 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=364, start_offset=364, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=101, arg=1, argval=1, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=31, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=370, start_offset=370, 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=380, start_offset=380, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=96, arg=15, argval=416, argrepr='to L12', offset=382, start_offset=382, 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=386, start_offset=386, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=388, start_offset=388, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=390, start_offset=390, 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=80, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=400, start_offset=400, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=402, start_offset=402, 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=30, arg=None, argval=None, argrepr='', offset=410, start_offset=410, 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=412, start_offset=412, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=74, arg=56, argval=304, argrepr='to L10', offset=414, start_offset=414, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=101, arg=0, argval=0, argrepr='', offset=416, start_offset=416, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=58, arg=3, argval=3, argrepr='', offset=418, start_offset=418, 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=420, start_offset=420, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=101, arg=1, argval=1, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=31, arg=None, argval=None, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=426, start_offset=426, 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=80, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=436, start_offset=436, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=438, start_offset=438, 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=30, arg=None, argval=None, argrepr='', offset=446, start_offset=446, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=101, arg=0, argval=0, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=58, arg=3, argval=3, argrepr='', offset=450, start_offset=450, 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=452, start_offset=452, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=101, arg=1, argval=1, argrepr='', offset=454, start_offset=454, 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
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=79, 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=33, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
+ Instruction(opname='LOAD_CONST', opcode=80, 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=34, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
]
diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py
index 5a4bceb..087ac8d 100644
--- a/Lib/test/test_monitoring.py
+++ b/Lib/test/test_monitoring.py
@@ -1491,7 +1491,15 @@ class BranchRecorder(JumpRecorder):
event_type = E.BRANCH
name = "branch"
+class BranchRightRecorder(JumpRecorder):
+ event_type = E.BRANCH_RIGHT
+ name = "branch right"
+
+class BranchLeftRecorder(JumpRecorder):
+
+ event_type = E.BRANCH_LEFT
+ name = "branch left"
class JumpOffsetRecorder:
@@ -1504,16 +1512,23 @@ class JumpOffsetRecorder:
def __call__(self, code, from_, to):
self.events.append((self.name, code.co_name, from_, to))
-class BranchOffsetRecorder(JumpOffsetRecorder):
+class BranchLeftOffsetRecorder(JumpOffsetRecorder):
- event_type = E.BRANCH
- name = "branch"
+ event_type = E.BRANCH_LEFT
+ name = "branch left"
+
+class BranchRightOffsetRecorder(JumpOffsetRecorder):
+
+ event_type = E.BRANCH_RIGHT
+ name = "branch right"
JUMP_AND_BRANCH_RECORDERS = JumpRecorder, BranchRecorder
JUMP_BRANCH_AND_LINE_RECORDERS = JumpRecorder, BranchRecorder, LineRecorder
FLOW_AND_LINE_RECORDERS = JumpRecorder, BranchRecorder, LineRecorder, ExceptionRecorder, ReturnRecorder
-BRANCH_OFFSET_RECORDERS = BranchOffsetRecorder,
+
+BRANCHES_RECORDERS = BranchLeftRecorder, BranchRightRecorder
+BRANCH_OFFSET_RECORDERS = BranchLeftOffsetRecorder, BranchRightOffsetRecorder
class TestBranchAndJumpEvents(CheckEvents):
maxDiff = None
@@ -1529,6 +1544,11 @@ class TestBranchAndJumpEvents(CheckEvents):
x = 6
7
+ def whilefunc(n=0):
+ while n < 3:
+ n += 1 # line 2
+ 3
+
self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [
('branch', 'func', 2, 2),
('branch', 'func', 3, 6),
@@ -1558,6 +1578,26 @@ class TestBranchAndJumpEvents(CheckEvents):
('line', 'func', 7),
('line', 'get_events', 11)])
+ self.check_events(func, recorders = BRANCHES_RECORDERS, expected = [
+ ('branch left', 'func', 2, 2),
+ ('branch right', 'func', 3, 6),
+ ('branch left', 'func', 2, 2),
+ ('branch left', 'func', 3, 4),
+ ('branch right', 'func', 2, 7)])
+
+ self.check_events(whilefunc, recorders = BRANCHES_RECORDERS, expected = [
+ ('branch left', 'whilefunc', 1, 2),
+ ('branch left', 'whilefunc', 1, 2),
+ ('branch left', 'whilefunc', 1, 2),
+ ('branch right', 'whilefunc', 1, 3)])
+
+ self.check_events(func, recorders = BRANCH_OFFSET_RECORDERS, expected = [
+ ('branch left', 'func', 28, 34),
+ ('branch right', 'func', 46, 60),
+ ('branch left', 'func', 28, 34),
+ ('branch left', 'func', 46, 52),
+ ('branch right', 'func', 28, 72)])
+
def test_except_star(self):
class Foo:
@@ -1583,8 +1623,8 @@ class TestBranchAndJumpEvents(CheckEvents):
('branch', 'func', 4, 4),
('line', 'func', 5),
('line', 'meth', 1),
- ('jump', 'func', 5, '[offset=118]'),
- ('branch', 'func', '[offset=122]', '[offset=126]'),
+ ('jump', 'func', 5, '[offset=120]'),
+ ('branch', 'func', '[offset=124]', '[offset=130]'),
('line', 'get_events', 11)])
self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [
@@ -1598,8 +1638,8 @@ class TestBranchAndJumpEvents(CheckEvents):
('line', 'func', 5),
('line', 'meth', 1),
('return', 'meth', None),
- ('jump', 'func', 5, '[offset=118]'),
- ('branch', 'func', '[offset=122]', '[offset=126]'),
+ ('jump', 'func', 5, '[offset=120]'),
+ ('branch', 'func', '[offset=124]', '[offset=130]'),
('return', 'func', None),
('line', 'get_events', 11)])
@@ -1611,8 +1651,8 @@ class TestBranchAndJumpEvents(CheckEvents):
n += 1
return None
- in_loop = ('branch', 'foo', 10, 14)
- exit_loop = ('branch', 'foo', 10, 30)
+ in_loop = ('branch left', 'foo', 10, 16)
+ exit_loop = ('branch right', 'foo', 10, 32)
self.check_events(foo, recorders = BRANCH_OFFSET_RECORDERS, expected = [
in_loop,
in_loop,
@@ -1852,6 +1892,10 @@ class TestSetGetEvents(MonitoringTestBase, unittest.TestCase):
code = f1.__code__
sys.monitoring.set_local_events(TEST_TOOL, code, E.PY_START)
self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), E.PY_START)
+ sys.monitoring.set_local_events(TEST_TOOL, code, 0)
+ sys.monitoring.set_local_events(TEST_TOOL, code, E.BRANCH)
+ self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), E.BRANCH_LEFT | E.BRANCH_RIGHT)
+ sys.monitoring.set_local_events(TEST_TOOL, code, 0)
sys.monitoring.set_local_events(TEST_TOOL2, code, E.PY_START)
self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL2, code), E.PY_START)
sys.monitoring.set_local_events(TEST_TOOL, code, 0)
@@ -2053,7 +2097,8 @@ class TestCApiEventGeneration(MonitoringTestBase, unittest.TestCase):
( 1, E.PY_RETURN, capi.fire_event_py_return, 20),
( 2, E.CALL, capi.fire_event_call, callable, 40),
( 1, E.JUMP, capi.fire_event_jump, 60),
- ( 1, E.BRANCH, capi.fire_event_branch, 70),
+ ( 1, E.BRANCH_RIGHT, capi.fire_event_branch_right, 70),
+ ( 1, E.BRANCH_LEFT, capi.fire_event_branch_left, 80),
( 1, E.PY_THROW, capi.fire_event_py_throw, ValueError(1)),
( 1, E.RAISE, capi.fire_event_raise, ValueError(2)),
( 1, E.EXCEPTION_HANDLED, capi.fire_event_exception_handled, ValueError(5)),
diff --git a/Misc/NEWS.d/next/Library/2024-12-13-14-21-04.gh-issue-122548.hq3Vud.rst b/Misc/NEWS.d/next/Library/2024-12-13-14-21-04.gh-issue-122548.hq3Vud.rst
new file mode 100644
index 0000000..6cd1357
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-13-14-21-04.gh-issue-122548.hq3Vud.rst
@@ -0,0 +1,4 @@
+Adds two new local events to sys.monitoring, ``BRANCH_LEFT`` and
+``BRANCH_RIGHT``. This allows the two arms of the branch to be disabled
+independently, which should hugely improve performance of branch-level
+coverage tools. The old branch event, ``BRANCH`` is now deprecated.
diff --git a/Modules/_testcapi/monitoring.c b/Modules/_testcapi/monitoring.c
index 6fd4a40..e475e3b 100644
--- a/Modules/_testcapi/monitoring.c
+++ b/Modules/_testcapi/monitoring.c
@@ -286,7 +286,7 @@ fire_event_jump(PyObject *self, PyObject *args)
}
static PyObject *
-fire_event_branch(PyObject *self, PyObject *args)
+fire_event_branch_right(PyObject *self, PyObject *args)
{
PyObject *codelike;
int offset;
@@ -299,7 +299,25 @@ fire_event_branch(PyObject *self, PyObject *args)
if (state == NULL) {
return NULL;
}
- int res = PyMonitoring_FireBranchEvent(state, codelike, offset, target_offset);
+ int res = PyMonitoring_FireBranchRightEvent(state, codelike, offset, target_offset);
+ RETURN_INT(teardown_fire(res, state, exception));
+}
+
+static PyObject *
+fire_event_branch_left(PyObject *self, PyObject *args)
+{
+ PyObject *codelike;
+ int offset;
+ PyObject *target_offset;
+ if (!PyArg_ParseTuple(args, "OiO", &codelike, &offset, &target_offset)) {
+ return NULL;
+ }
+ PyObject *exception = NULL;
+ PyMonitoringState *state = setup_fire(codelike, offset, exception);
+ if (state == NULL) {
+ return NULL;
+ }
+ int res = PyMonitoring_FireBranchLeftEvent(state, codelike, offset, target_offset);
RETURN_INT(teardown_fire(res, state, exception));
}
@@ -478,7 +496,8 @@ static PyMethodDef TestMethods[] = {
{"fire_event_call", fire_event_call, METH_VARARGS},
{"fire_event_line", fire_event_line, METH_VARARGS},
{"fire_event_jump", fire_event_jump, METH_VARARGS},
- {"fire_event_branch", fire_event_branch, METH_VARARGS},
+ {"fire_event_branch_left", fire_event_branch_left, METH_VARARGS},
+ {"fire_event_branch_right", fire_event_branch_right, METH_VARARGS},
{"fire_event_py_throw", fire_event_py_throw, METH_VARARGS},
{"fire_event_raise", fire_event_raise, METH_VARARGS},
{"fire_event_c_raise", fire_event_c_raise, METH_VARARGS},
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index eb8de13..ae232ca 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -2197,6 +2197,12 @@ code_linesiterator(PyObject *self, PyObject *Py_UNUSED(args))
return (PyObject *)new_linesiterator(code);
}
+static PyObject *
+code_branchesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
+{
+ return _PyInstrumentation_BranchesIterator(code);
+}
+
/*[clinic input]
@text_signature "($self, /, **changes)"
code.replace
@@ -2337,6 +2343,7 @@ code__varname_from_oparg_impl(PyCodeObject *self, int oparg)
static struct PyMethodDef code_methods[] = {
{"__sizeof__", code_sizeof, METH_NOARGS},
{"co_lines", code_linesiterator, METH_NOARGS},
+ {"co_branches", (PyCFunction)code_branchesiterator, METH_NOARGS},
{"co_positions", code_positionsiterator, METH_NOARGS},
CODE_REPLACE_METHODDEF
CODE__VARNAME_FROM_OPARG_METHODDEF
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index 99b0fa4..a000783 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -1,37 +1,37 @@
// 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,89,0,79,0,
- 70,0,111,0,89,0,79,0,70,1,111,1,88,2,31,0,
- 79,1,49,1,0,0,0,0,0,0,29,0,88,2,31,0,
- 79,2,88,0,77,6,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,49,2,0,0,0,0,0,0,
- 29,0,88,1,77,8,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,31,0,49,0,0,0,0,0,
- 0,0,79,3,2,0,0,0,111,5,79,4,16,0,67,20,
- 0,0,111,6,88,2,31,0,79,5,88,6,12,0,79,6,
- 88,5,88,6,2,0,0,0,12,0,47,4,49,1,0,0,
- 0,0,0,0,29,0,72,22,0,0,9,0,29,0,79,0,
- 33,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,
- 99,117,116,97,98,108,101,218,15,117,115,101,95,101,110,118,
- 105,114,111,110,109,101,110,116,218,17,99,111,110,102,105,103,
- 117,114,101,95,99,95,115,116,100,105,111,218,14,98,117,102,
- 102,101,114,101,100,95,115,116,100,105,111,122,7,99,111,110,
- 102,105,103,32,122,2,58,32,41,7,218,3,115,121,115,218,
- 17,95,116,101,115,116,105,110,116,101,114,110,97,108,99,97,
- 112,105,218,5,112,114,105,110,116,218,4,97,114,103,118,218,
- 11,103,101,116,95,99,111,110,102,105,103,115,114,2,0,0,
- 0,218,3,107,101,121,169,0,243,0,0,0,0,218,18,116,
- 101,115,116,95,102,114,111,122,101,110,109,97,105,110,46,112,
- 121,218,8,60,109,111,100,117,108,101,62,114,17,0,0,0,
- 1,0,0,0,115,94,0,0,0,240,3,1,1,1,243,8,
- 0,1,11,219,0,24,225,0,5,208,6,26,212,0,27,217,
- 0,5,128,106,144,35,151,40,145,40,212,0,27,216,9,26,
- 215,9,38,210,9,38,211,9,40,168,24,209,9,50,128,6,
- 243,2,6,12,2,128,67,241,14,0,5,10,136,71,144,67,
- 144,53,152,2,152,54,160,35,153,59,152,45,208,10,40,214,
- 4,41,243,15,6,12,2,114,15,0,0,0,
+ 0,0,0,0,0,243,170,0,0,0,149,0,90,0,80,0,
+ 71,0,112,0,90,0,80,0,71,1,112,1,89,2,32,0,
+ 80,1,50,1,0,0,0,0,0,0,30,0,89,2,32,0,
+ 80,2,89,0,78,6,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,50,2,0,0,0,0,0,0,
+ 30,0,89,1,78,8,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,32,0,50,0,0,0,0,0,
+ 0,0,80,3,2,0,0,0,112,5,80,4,16,0,68,21,
+ 0,0,28,0,112,6,89,2,32,0,80,5,89,6,12,0,
+ 80,6,89,5,89,6,2,0,0,0,12,0,48,4,50,1,
+ 0,0,0,0,0,0,30,0,73,23,0,0,9,0,30,0,
+ 80,0,34,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,99,117,116,97,98,108,101,218,15,117,115,101,95,101,
+ 110,118,105,114,111,110,109,101,110,116,218,17,99,111,110,102,
+ 105,103,117,114,101,95,99,95,115,116,100,105,111,218,14,98,
+ 117,102,102,101,114,101,100,95,115,116,100,105,111,122,7,99,
+ 111,110,102,105,103,32,122,2,58,32,41,7,218,3,115,121,
+ 115,218,17,95,116,101,115,116,105,110,116,101,114,110,97,108,
+ 99,97,112,105,218,5,112,114,105,110,116,218,4,97,114,103,
+ 118,218,11,103,101,116,95,99,111,110,102,105,103,115,114,2,
+ 0,0,0,218,3,107,101,121,169,0,243,0,0,0,0,218,
+ 18,116,101,115,116,95,102,114,111,122,101,110,109,97,105,110,
+ 46,112,121,218,8,60,109,111,100,117,108,101,62,114,17,0,
+ 0,0,1,0,0,0,115,94,0,0,0,240,3,1,1,1,
+ 243,8,0,1,11,219,0,24,225,0,5,208,6,26,212,0,
+ 27,217,0,5,128,106,144,35,151,40,145,40,212,0,27,216,
+ 9,26,215,9,38,210,9,38,211,9,40,168,24,209,9,50,
+ 128,6,244,2,6,12,2,128,67,241,14,0,5,10,136,71,
+ 144,67,144,53,152,2,152,54,160,35,153,59,152,45,208,10,
+ 40,214,4,41,243,15,6,12,2,114,15,0,0,0,
};
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index b67264f..cf089c3 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -148,6 +148,8 @@ dummy_func(
RESUME_CHECK,
};
+ macro(NOT_TAKEN) = NOP;
+
op(_CHECK_PERIODIC, (--)) {
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
QSBR_QUIESCENT_STATE(tstate);
@@ -2723,7 +2725,7 @@ dummy_func(
int flag = PyStackRef_IsFalse(cond);
DEAD(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- JUMPBY(oparg * flag);
+ JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN);
}
replaced op(_POP_JUMP_IF_TRUE, (cond -- )) {
@@ -2731,7 +2733,7 @@ dummy_func(
int flag = PyStackRef_IsTrue(cond);
DEAD(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- JUMPBY(oparg * flag);
+ JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN);
}
op(_IS_NONE, (value -- b)) {
@@ -2923,13 +2925,11 @@ dummy_func(
macro(FOR_ITER) = _SPECIALIZE_FOR_ITER + _FOR_ITER;
inst(INSTRUMENTED_FOR_ITER, (unused/1 -- )) {
- _Py_CODEUNIT *target;
_PyStackRef iter_stackref = TOP();
PyObject *iter = PyStackRef_AsPyObjectBorrow(iter_stackref);
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
if (next != NULL) {
PUSH(PyStackRef_FromPyObjectSteal(next));
- target = next_instr;
}
else {
if (_PyErr_Occurred(tstate)) {
@@ -2946,9 +2946,9 @@ dummy_func(
STACK_SHRINK(1);
PyStackRef_CLOSE(iter_stackref);
/* Skip END_FOR and POP_TOP */
- target = next_instr + oparg + 2;
+ _Py_CODEUNIT *target = next_instr + oparg + 2;
+ INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
- INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH);
}
op(_ITER_CHECK_LIST, (iter -- iter)) {
@@ -4736,6 +4736,10 @@ dummy_func(
INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP);
}
+ inst(INSTRUMENTED_NOT_TAKEN, ( -- )) {
+ INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
+ }
+
macro(INSTRUMENTED_JUMP_BACKWARD) =
unused/1 +
_CHECK_PERIODIC +
@@ -4744,51 +4748,43 @@ dummy_func(
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
_PyStackRef cond = POP();
assert(PyStackRef_BoolCheck(cond));
- int flag = PyStackRef_IsTrue(cond);
- int offset = flag * oparg;
- RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ int jump = PyStackRef_IsTrue(cond);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ }
}
inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) {
_PyStackRef cond = POP();
assert(PyStackRef_BoolCheck(cond));
- int flag = PyStackRef_IsFalse(cond);
- int offset = flag * oparg;
- RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ int jump = PyStackRef_IsFalse(cond);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ }
}
inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1 -- )) {
_PyStackRef value_stackref = POP();
- int flag = PyStackRef_IsNone(value_stackref);
- int offset;
- if (flag) {
- offset = oparg;
+ int jump = PyStackRef_IsNone(value_stackref);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
else {
PyStackRef_CLOSE(value_stackref);
- offset = 0;
}
- RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1 -- )) {
_PyStackRef value_stackref = POP();
- int offset;
- int nflag = PyStackRef_IsNone(value_stackref);
- if (nflag) {
- offset = 0;
- }
- else {
+ int jump = !PyStackRef_IsNone(value_stackref);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
PyStackRef_CLOSE(value_stackref);
- offset = oparg;
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
- #if ENABLE_SPECIALIZATION
- this_instr[1].cache = (this_instr[1].cache << 1) | !nflag;
- #endif
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
tier1 inst(EXTENDED_ARG, ( -- )) {
diff --git a/Python/codegen.c b/Python/codegen.c
index a5e550c..6d3272e 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -406,7 +406,13 @@ codegen_addop_j(instr_sequence *seq, location loc,
assert(IS_JUMP_TARGET_LABEL(target));
assert(OPCODE_HAS_JUMP(opcode) || IS_BLOCK_PUSH_OPCODE(opcode));
assert(!IS_ASSEMBLER_OPCODE(opcode));
- return _PyInstructionSequence_Addop(seq, opcode, target.id, loc);
+ if (_PyInstructionSequence_Addop(seq, opcode, target.id, loc) != SUCCESS) {
+ return ERROR;
+ }
+ if (IS_CONDITIONAL_JUMP_OPCODE(opcode) || opcode == FOR_ITER) {
+ return _PyInstructionSequence_Addop(seq, NOT_TAKEN, 0, NO_LOCATION);
+ }
+ return SUCCESS;
}
#define ADDOP_JUMP(C, LOC, OP, O) \
@@ -682,7 +688,6 @@ codegen_setup_annotations_scope(compiler *c, location loc,
ADDOP_I(c, loc, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]);
NEW_JUMP_TARGET_LABEL(c, body);
ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body);
-
ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
ADDOP_I(c, loc, RAISE_VARARGS, 1);
USE_LABEL(c, body);
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index de61a64..9bfc3e7 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -5668,6 +5668,8 @@
/* _MONITOR_JUMP_BACKWARD is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
+ /* _INSTRUMENTED_NOT_TAKEN is not a viable micro-op for tier 2 because it is instrumented */
+
/* _INSTRUMENTED_POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 because it is instrumented */
/* _INSTRUMENTED_POP_JUMP_IF_FALSE is not a viable micro-op for tier 2 because it is instrumented */
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index b1097b6..64df629 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -557,6 +557,12 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
if (backwards_jump == NULL) {
return ERROR;
}
+ assert(b->b_next->b_iused > 0);
+ assert(b->b_next->b_instr[0].i_opcode == NOT_TAKEN);
+ b->b_next->b_instr[0].i_opcode = NOP;
+ b->b_next->b_instr[0].i_loc = NO_LOCATION;
+ RETURN_IF_ERROR(
+ basicblock_addop(backwards_jump, NOT_TAKEN, 0, last->i_loc));
RETURN_IF_ERROR(
basicblock_add_jump(backwards_jump, JUMP, target, last->i_loc));
last->i_opcode = reversed_opcode;
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 8a89ba8..ac89891 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -4618,7 +4618,6 @@
next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_FOR_ITER);
/* Skip 1 cache entry */
- _Py_CODEUNIT *target;
_PyStackRef iter_stackref = TOP();
PyObject *iter = PyStackRef_AsPyObjectBorrow(iter_stackref);
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -4626,7 +4625,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
if (next != NULL) {
PUSH(PyStackRef_FromPyObjectSteal(next));
- target = next_instr;
}
else {
if (_PyErr_Occurred(tstate)) {
@@ -4647,9 +4645,9 @@
STACK_SHRINK(1);
PyStackRef_CLOSE(iter_stackref);
/* Skip END_FOR and POP_TOP */
- target = next_instr + oparg + 2;
+ _Py_CODEUNIT *target = next_instr + oparg + 2;
+ INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
- INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
@@ -4754,6 +4752,15 @@
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
}
+ TARGET(INSTRUMENTED_NOT_TAKEN) {
+ _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
+ (void)this_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_NOT_TAKEN);
+ INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
+ DISPATCH();
+ }
+
TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
(void)this_instr;
@@ -4762,10 +4769,11 @@
/* Skip 1 cache entry */
_PyStackRef cond = POP();
assert(PyStackRef_BoolCheck(cond));
- int flag = PyStackRef_IsFalse(cond);
- int offset = flag * oparg;
- RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ int jump = PyStackRef_IsFalse(cond);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ }
DISPATCH();
}
@@ -4776,17 +4784,14 @@
INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NONE);
/* Skip 1 cache entry */
_PyStackRef value_stackref = POP();
- int flag = PyStackRef_IsNone(value_stackref);
- int offset;
- if (flag) {
- offset = oparg;
+ int jump = PyStackRef_IsNone(value_stackref);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
else {
PyStackRef_CLOSE(value_stackref);
- offset = 0;
}
- RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
@@ -4797,19 +4802,12 @@
INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NOT_NONE);
/* Skip 1 cache entry */
_PyStackRef value_stackref = POP();
- int offset;
- int nflag = PyStackRef_IsNone(value_stackref);
- if (nflag) {
- offset = 0;
- }
- else {
+ int jump = !PyStackRef_IsNone(value_stackref);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
PyStackRef_CLOSE(value_stackref);
- offset = oparg;
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
- #if ENABLE_SPECIALIZATION
- this_instr[1].cache = (this_instr[1].cache << 1) | !nflag;
- #endif
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
@@ -4821,10 +4819,11 @@
/* Skip 1 cache entry */
_PyStackRef cond = POP();
assert(PyStackRef_BoolCheck(cond));
- int flag = PyStackRef_IsTrue(cond);
- int offset = flag * oparg;
- RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ int jump = PyStackRef_IsTrue(cond);
+ RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
+ if (jump) {
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ }
DISPATCH();
}
@@ -6659,6 +6658,13 @@
DISPATCH();
}
+ TARGET(NOT_TAKEN) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(NOT_TAKEN);
+ DISPATCH();
+ }
+
TARGET(POP_EXCEPT) {
frame->instr_ptr = next_instr;
next_instr += 1;
@@ -6687,7 +6693,7 @@
assert(PyStackRef_BoolCheck(cond));
int flag = PyStackRef_IsFalse(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- JUMPBY(oparg * flag);
+ JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
@@ -6719,7 +6725,7 @@
assert(PyStackRef_BoolCheck(cond));
int flag = PyStackRef_IsTrue(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- JUMPBY(oparg * flag);
+ JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@@ -6752,7 +6758,7 @@
assert(PyStackRef_BoolCheck(cond));
int flag = PyStackRef_IsFalse(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- JUMPBY(oparg * flag);
+ JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@@ -6770,7 +6776,7 @@
assert(PyStackRef_BoolCheck(cond));
int flag = PyStackRef_IsTrue(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, flag);
- JUMPBY(oparg * flag);
+ JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 3503809..e4255bf 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -85,22 +85,24 @@ static const int8_t EVENT_FOR_OPCODE[256] = {
[INSTRUMENTED_YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD,
[JUMP_FORWARD] = PY_MONITORING_EVENT_JUMP,
[JUMP_BACKWARD] = PY_MONITORING_EVENT_JUMP,
- [POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH,
- [POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH,
- [POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH,
- [POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH,
+ [POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
[INSTRUMENTED_JUMP_FORWARD] = PY_MONITORING_EVENT_JUMP,
[INSTRUMENTED_JUMP_BACKWARD] = PY_MONITORING_EVENT_JUMP,
- [INSTRUMENTED_POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH,
- [INSTRUMENTED_POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH,
- [INSTRUMENTED_POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH,
- [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH,
- [FOR_ITER] = PY_MONITORING_EVENT_BRANCH,
- [INSTRUMENTED_FOR_ITER] = PY_MONITORING_EVENT_BRANCH,
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [FOR_ITER] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [INSTRUMENTED_FOR_ITER] = PY_MONITORING_EVENT_BRANCH_RIGHT,
[END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION,
[INSTRUMENTED_END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION,
[END_SEND] = PY_MONITORING_EVENT_STOP_ITERATION,
[INSTRUMENTED_END_SEND] = PY_MONITORING_EVENT_STOP_ITERATION,
+ [NOT_TAKEN] = PY_MONITORING_EVENT_BRANCH_LEFT,
+ [INSTRUMENTED_NOT_TAKEN] = PY_MONITORING_EVENT_BRANCH_LEFT,
};
static const uint8_t DE_INSTRUMENT[256] = {
@@ -120,6 +122,7 @@ 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_NOT_TAKEN] = NOT_TAKEN,
};
static const uint8_t INSTRUMENTED_OPCODES[256] = {
@@ -155,6 +158,8 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
[INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
[LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
+ [NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
+ [INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
[INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
[INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
@@ -323,33 +328,8 @@ _PyInstruction_GetLength(PyCodeObject *code, int offset)
{
ASSERT_WORLD_STOPPED_OR_LOCKED(code);
- int opcode =
- FT_ATOMIC_LOAD_UINT8_RELAXED(_PyCode_CODE(code)[offset].op.code);
- assert(opcode != 0);
- assert(opcode != RESERVED);
- if (opcode == INSTRUMENTED_LINE) {
- opcode = code->_co_monitoring->lines[offset].original_opcode;
- }
- if (opcode == INSTRUMENTED_INSTRUCTION) {
- opcode = code->_co_monitoring->per_instruction_opcodes[offset];
- }
- int deinstrumented = DE_INSTRUMENT[opcode];
- if (deinstrumented) {
- opcode = deinstrumented;
- }
- else {
- opcode = _PyOpcode_Deopt[opcode];
- }
- assert(opcode != 0);
- if (opcode == ENTER_EXECUTOR) {
- int exec_index = _PyCode_CODE(code)[offset].op.arg;
- _PyExecutorObject *exec = code->co_executors->executors[exec_index];
- opcode = _PyOpcode_Deopt[exec->vm_data.opcode];
- }
- assert(!is_instrumented(opcode));
- assert(opcode != ENTER_EXECUTOR);
- assert(opcode == _PyOpcode_Deopt[opcode]);
- return 1 + _PyOpcode_Caches[opcode];
+ _Py_CODEUNIT inst = _Py_GetBaseCodeUnit(code, offset);
+ return 1 + _PyOpcode_Caches[inst.op.code];
}
#ifdef INSTRUMENT_DEBUG
@@ -599,16 +579,15 @@ _Py_GetBaseCodeUnit(PyCodeObject *code, int i)
int opcode = inst.op.code;
if (opcode < MIN_INSTRUMENTED_OPCODE) {
inst.op.code = _PyOpcode_Deopt[opcode];
- assert(inst.op.code <= RESUME);
+ assert(inst.op.code < MIN_SPECIALIZED_OPCODE);
return inst;
}
if (opcode == ENTER_EXECUTOR) {
_PyExecutorObject *exec = code->co_executors->executors[inst.op.arg];
opcode = _PyOpcode_Deopt[exec->vm_data.opcode];
inst.op.code = opcode;
- assert(opcode <= RESUME);
inst.op.arg = exec->vm_data.oparg;
- assert(inst.op.code <= RESUME);
+ assert(inst.op.code < MIN_SPECIALIZED_OPCODE);
return inst;
}
if (opcode == INSTRUMENTED_LINE) {
@@ -1084,6 +1063,8 @@ static const char *const event_names [] = {
[PY_MONITORING_EVENT_INSTRUCTION] = "INSTRUCTION",
[PY_MONITORING_EVENT_JUMP] = "JUMP",
[PY_MONITORING_EVENT_BRANCH] = "BRANCH",
+ [PY_MONITORING_EVENT_BRANCH_LEFT] = "BRANCH_LEFT",
+ [PY_MONITORING_EVENT_BRANCH_RIGHT] = "BRANCH_RIGHT",
[PY_MONITORING_EVENT_C_RETURN] = "C_RETURN",
[PY_MONITORING_EVENT_PY_THROW] = "PY_THROW",
[PY_MONITORING_EVENT_RAISE] = "RAISE",
@@ -1111,6 +1092,10 @@ call_instrumentation_vector(
/* Offset visible to user should be the offset in bytes, as that is the
* convention for APIs involving code offsets. */
int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT);
+ if (event == PY_MONITORING_EVENT_BRANCH_LEFT) {
+ assert(EVENT_FOR_OPCODE[_Py_GetBaseCodeUnit(code, offset-2).op.code] == PY_MONITORING_EVENT_BRANCH_RIGHT);
+ bytes_offset -= 4;
+ }
PyObject *offset_obj = PyLong_FromLong(bytes_offset);
if (offset_obj == NULL) {
return -1;
@@ -1191,7 +1176,8 @@ _Py_call_instrumentation_jump(
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *target)
{
assert(event == PY_MONITORING_EVENT_JUMP ||
- event == PY_MONITORING_EVENT_BRANCH);
+ event == PY_MONITORING_EVENT_BRANCH_RIGHT ||
+ event == PY_MONITORING_EVENT_BRANCH_LEFT);
assert(frame->instr_ptr == instr);
int to = (int)(target - _PyFrame_GetBytecode(frame));
PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT));
@@ -1427,19 +1413,6 @@ _Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame*
return next_opcode;
}
-
-PyObject *
-_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
-{
- PyInterpreterState *is = _PyInterpreterState_GET();
- assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
- assert(0 <= event_id && event_id < _PY_MONITORING_EVENTS);
- PyObject *callback = _Py_atomic_exchange_ptr(&is->monitoring_callables[tool_id][event_id],
- Py_XNewRef(obj));
-
- return callback;
-}
-
static void
initialize_tools(PyCodeObject *code)
{
@@ -2312,6 +2285,10 @@ monitoring_set_events_impl(PyObject *module, int tool_id, int event_set)
return NULL;
}
event_set &= ~C_RETURN_EVENTS;
+ if (event_set & (1 << PY_MONITORING_EVENT_BRANCH)) {
+ event_set &= ~(1 << PY_MONITORING_EVENT_BRANCH);
+ event_set |= (1 << PY_MONITORING_EVENT_BRANCH_RIGHT) | (1 << PY_MONITORING_EVENT_BRANCH_LEFT);
+ }
if (_PyMonitoring_SetEvents(tool_id, event_set)) {
return NULL;
}
@@ -2384,6 +2361,10 @@ monitoring_set_local_events_impl(PyObject *module, int tool_id,
return NULL;
}
event_set &= ~C_RETURN_EVENTS;
+ if (event_set & (1 << PY_MONITORING_EVENT_BRANCH)) {
+ event_set &= ~(1 << PY_MONITORING_EVENT_BRANCH);
+ event_set |= (1 << PY_MONITORING_EVENT_BRANCH_RIGHT) | (1 << PY_MONITORING_EVENT_BRANCH_LEFT);
+ }
if (event_set < 0 || event_set >= (1 << _PY_MONITORING_LOCAL_EVENTS)) {
PyErr_Format(PyExc_ValueError, "invalid local event set 0x%x", event_set);
return NULL;
@@ -2711,7 +2692,27 @@ _PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int3
assert(state->active);
PyObject *args[4] = { NULL, NULL, NULL, target_offset };
return capi_call_instrumentation(state, codelike, offset, args, 3,
- PY_MONITORING_EVENT_BRANCH);
+ PY_MONITORING_EVENT_BRANCH_RIGHT);
+}
+
+int
+_PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
+ PyObject *target_offset)
+{
+ assert(state->active);
+ PyObject *args[4] = { NULL, NULL, NULL, target_offset };
+ return capi_call_instrumentation(state, codelike, offset, args, 3,
+ PY_MONITORING_EVENT_BRANCH_RIGHT);
+}
+
+int
+_PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
+ PyObject *target_offset)
+{
+ assert(state->active);
+ PyObject *args[4] = { NULL, NULL, NULL, target_offset };
+ return capi_call_instrumentation(state, codelike, offset, args, 3,
+ PY_MONITORING_EVENT_BRANCH_LEFT);
}
int
@@ -2849,3 +2850,213 @@ _PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelik
Py_DECREF(exc);
return exception_event_teardown(err, NULL);
}
+
+
+
+/* Handle legacy BRANCH event */
+
+typedef struct _PyLegacyBranchEventHandler {
+ PyObject_HEAD
+ vectorcallfunc vectorcall;
+ PyObject *handler;
+ bool right;
+ int tool_id;
+} _PyLegacyBranchEventHandler;
+
+static void
+dealloc_branch_handler(_PyLegacyBranchEventHandler *self)
+{
+ Py_CLEAR(self->handler);
+ PyObject_Free((PyObject *)self);
+}
+
+static PyTypeObject _PyLegacyBranchEventHandler_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "sys.monitoring.branch_event_handler",
+ sizeof(_PyLegacyBranchEventHandler),
+ .tp_dealloc = (destructor)dealloc_branch_handler,
+ .tp_vectorcall_offset = offsetof(_PyLegacyBranchEventHandler, vectorcall),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_DISALLOW_INSTANTIATION,
+ .tp_call = PyVectorcall_Call,
+};
+
+
+static PyObject *
+branch_handler(
+ _PyLegacyBranchEventHandler *self, PyObject *const *args,
+ size_t nargsf, PyObject *kwnames
+) {
+ PyObject *res = PyObject_Vectorcall(self->handler, args, nargsf, kwnames);
+ if (res == &_PyInstrumentation_DISABLE) {
+ // Find the other instrumented instruction and remove tool
+ assert(PyVectorcall_NARGS(nargsf) >= 2);
+ PyObject *offset_obj = args[1];
+ int bytes_offset = PyLong_AsLong(offset_obj);
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ PyCodeObject *code = (PyCodeObject *)args[0];
+ if (!PyCode_Check(code) || (bytes_offset & 1)) {
+ return res;
+ }
+ int offset = bytes_offset / 2;
+ /* We need FOR_ITER and POP_JUMP_ to be the same size */
+ assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1);
+ if (self->right) {
+ offset += 2;
+ }
+ if (offset >= Py_SIZE(code)) {
+ return res;
+ }
+ int other_event = self->right ?
+ PY_MONITORING_EVENT_BRANCH_LEFT : PY_MONITORING_EVENT_BRANCH_RIGHT;
+ LOCK_CODE(code);
+ remove_tools(code, offset, other_event, 1 << self->tool_id);
+ UNLOCK_CODE();
+ }
+ return res;
+}
+
+static PyObject *make_branch_handler(int tool_id, PyObject *handler, bool right)
+{
+ _PyLegacyBranchEventHandler *callback =
+ PyObject_NEW(_PyLegacyBranchEventHandler, &_PyLegacyBranchEventHandler_Type);
+ if (callback == NULL) {
+ return NULL;
+ }
+ callback->vectorcall = (vectorcallfunc)branch_handler;
+ callback->handler = Py_NewRef(handler);
+ callback->right = right;
+ callback->tool_id = tool_id;
+ return (PyObject *)callback;
+}
+
+/* Consumes a reference to obj */
+static PyObject *exchange_callables(int tool_id, int event_id, PyObject *obj)
+{
+ PyInterpreterState *is = _PyInterpreterState_GET();
+ return _Py_atomic_exchange_ptr(&is->monitoring_callables[tool_id][event_id], obj);
+}
+
+PyObject *
+_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
+{
+ assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
+ assert(0 <= event_id && event_id < _PY_MONITORING_EVENTS);
+ PyObject *res;
+ if (event_id == PY_MONITORING_EVENT_BRANCH) {
+ PyObject *left, *right;
+ if (obj == NULL) {
+ left = NULL;
+ right = NULL;
+ }
+ else {
+ right = make_branch_handler(tool_id, obj, true);
+ if (right == NULL) {
+ return NULL;
+ }
+ left = make_branch_handler(tool_id, obj, false);
+ if (left == NULL) {
+ Py_DECREF(right);
+ return NULL;
+ }
+ }
+ Py_XDECREF(exchange_callables(tool_id, PY_MONITORING_EVENT_BRANCH_RIGHT, right));
+ res = exchange_callables(tool_id, PY_MONITORING_EVENT_BRANCH_LEFT, left);
+ }
+ else {
+ res = exchange_callables(tool_id, event_id, Py_XNewRef(obj));
+ }
+ if (res != NULL && Py_TYPE(res) == &_PyLegacyBranchEventHandler_Type) {
+ _PyLegacyBranchEventHandler *wrapper = (_PyLegacyBranchEventHandler *)res;
+ res = Py_NewRef(wrapper->handler);
+ Py_DECREF(wrapper);
+ }
+ return res;
+}
+
+/* Branch Iterator */
+
+typedef struct {
+ PyObject_HEAD
+ PyCodeObject *bi_code;
+ int bi_offset;
+} branchesiterator;
+
+static PyObject *
+int_triple(int a, int b, int c) {
+ PyObject *obja = PyLong_FromLong(a);
+ PyObject *objb = NULL;
+ PyObject *objc = NULL;
+ if (obja == NULL) {
+ goto error;
+ }
+ objb = PyLong_FromLong(b);
+ if (objb == NULL) {
+ goto error;
+ }
+ objc = PyLong_FromLong(c);
+ if (objc == NULL) {
+ goto error;
+ }
+ PyObject *array[3] = { obja, objb, objc };
+ return _PyTuple_FromArraySteal(array, 3);
+error:
+ Py_XDECREF(obja);
+ Py_XDECREF(objb);
+ Py_XDECREF(objc);
+ return NULL;
+}
+
+static PyObject *
+branchesiter_next(branchesiterator *bi)
+{
+ int offset = bi->bi_offset;
+ while (offset < Py_SIZE(bi->bi_code)) {
+ _Py_CODEUNIT inst = _Py_GetBaseCodeUnit(bi->bi_code, offset);
+ int next_offset = offset + _PyInstruction_GetLength(bi->bi_code, offset);
+ int event = EVENT_FOR_OPCODE[inst.op.code];
+ if (event == PY_MONITORING_EVENT_BRANCH_RIGHT) {
+ /* Skip NOT_TAKEN */
+ int not_taken = next_offset + 1;
+ bi->bi_offset = not_taken;
+ return int_triple(offset*2, not_taken*2, (next_offset + inst.op.arg)*2);
+ }
+ offset = next_offset;
+ }
+ return NULL;
+}
+
+static void
+branchesiter_dealloc(branchesiterator *bi)
+{
+ Py_DECREF(bi->bi_code);
+ PyObject_Free(bi);
+}
+
+static PyTypeObject _PyBranchesIterator = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "line_iterator", /* tp_name */
+ sizeof(branchesiterator), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ .tp_dealloc = (destructor)branchesiter_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_iter = PyObject_SelfIter,
+ .tp_iternext = (iternextfunc)branchesiter_next,
+ .tp_free = PyObject_Del,
+};
+
+PyObject *
+_PyInstrumentation_BranchesIterator(PyCodeObject *code)
+{
+
+ branchesiterator *bi = (branchesiterator *)PyType_GenericAlloc(&_PyBranchesIterator, 0);
+ if (bi == NULL) {
+ return NULL;
+ }
+ bi->bi_code = (PyCodeObject*)Py_NewRef(code);
+ bi->bi_offset = 0;
+ return (PyObject *)bi;
+}
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index c93941d..7f3fb9c 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -27,6 +27,7 @@ static void *opcode_targets[256] = {
&&TARGET_MATCH_MAPPING,
&&TARGET_MATCH_SEQUENCE,
&&TARGET_NOP,
+ &&TARGET_NOT_TAKEN,
&&TARGET_POP_EXCEPT,
&&TARGET_POP_TOP,
&&TARGET_PUSH_EXC_INFO,
@@ -147,7 +148,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_RESUME,
&&TARGET_BINARY_OP_ADD_FLOAT,
&&TARGET_BINARY_OP_ADD_INT,
@@ -235,7 +235,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_INSTRUMENTED_END_FOR,
&&TARGET_INSTRUMENTED_END_SEND,
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
@@ -244,6 +243,7 @@ static void *opcode_targets[256] = {
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
&&TARGET_INSTRUMENTED_INSTRUCTION,
&&TARGET_INSTRUMENTED_JUMP_FORWARD,
+ &&TARGET_INSTRUMENTED_NOT_TAKEN,
&&TARGET_INSTRUMENTED_POP_JUMP_IF_TRUE,
&&TARGET_INSTRUMENTED_POP_JUMP_IF_FALSE,
&&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE,
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 33b34d6..2c3133d 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -2343,6 +2343,8 @@
/* _MONITOR_JUMP_BACKWARD is not a viable micro-op for tier 2 */
+ /* _INSTRUMENTED_NOT_TAKEN is not a viable micro-op for tier 2 */
+
/* _INSTRUMENTED_POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */
/* _INSTRUMENTED_POP_JUMP_IF_FALSE is not a viable micro-op for tier 2 */
diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv
index badd7b7..a1ec192 100644
--- a/Tools/c-analyzer/cpython/globals-to-fix.tsv
+++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv
@@ -106,6 +106,8 @@ Python/context.c - PyContextToken_Type -
Python/context.c - PyContextVar_Type -
Python/context.c - PyContext_Type -
Python/instruction_sequence.c - _PyInstructionSequence_Type -
+Python/instrumentation.c - _PyLegacyBranchEventHandler_Type -
+Python/instrumentation.c - _PyBranchesIterator -
Python/traceback.c - PyTraceBack_Type -
##-----------------------