@@ -1025,6 +1025,7 @@ _Py_call_instrumentation_jump(
1025
1025
return NULL ;
1026
1026
}
1027
1027
if (frame -> prev_instr != target ) {
1028
+ /* The callback has caused a jump (by setting the line number) */
1028
1029
return frame -> prev_instr ;
1029
1030
}
1030
1031
/* Reset prev_instr for INSTRUMENTED_LINE */
@@ -1294,6 +1295,12 @@ initialize_lines(PyCodeObject *code)
1294
1295
line_data [i ].original_opcode = 0 ;
1295
1296
break ;
1296
1297
default :
1298
+ /* Set original_opcode to the opcode iff the instruction
1299
+ * starts a line, and thus should be instrumented.
1300
+ * This saves having to perform this check every time the
1301
+ * we turn instrumentation on or off, and serves as a sanity
1302
+ * check when debugging.
1303
+ */
1297
1304
if (line != current_line && line >= 0 ) {
1298
1305
line_data [i ].original_opcode = opcode ;
1299
1306
}
@@ -1322,6 +1329,8 @@ initialize_lines(PyCodeObject *code)
1322
1329
switch (opcode ) {
1323
1330
case POP_JUMP_IF_FALSE :
1324
1331
case POP_JUMP_IF_TRUE :
1332
+ case POP_JUMP_IF_NONE :
1333
+ case POP_JUMP_IF_NOT_NONE :
1325
1334
case JUMP_FORWARD :
1326
1335
{
1327
1336
target = i + oparg ;
@@ -1363,6 +1372,10 @@ initialize_lines(PyCodeObject *code)
1363
1372
int depth_and_lasti ;
1364
1373
scan = parse_varint (scan , & depth_and_lasti );
1365
1374
int original_opcode = _Py_GetBaseOpcode (code , handler );
1375
+ /* Skip if not the start of a line.
1376
+ * END_ASYNC_FOR is a bit special as it marks the end of
1377
+ * an `async for` loop, which should not generate its own
1378
+ * line event. */
1366
1379
if (line_data [handler ].line_delta != NO_LINE &&
1367
1380
original_opcode != END_ASYNC_FOR ) {
1368
1381
line_data [handler ].original_opcode = original_opcode ;
0 commit comments