@@ -962,7 +962,7 @@ call_instrumentation_vector(
962962 /* Offset visible to user should be the offset in bytes, as that is the
963963 * convention for APIs involving code offsets. */
964964 int bytes_offset = offset * (int )sizeof (_Py_CODEUNIT );
965- PyObject * offset_obj = PyLong_FromSsize_t (bytes_offset );
965+ PyObject * offset_obj = PyLong_FromLong (bytes_offset );
966966 if (offset_obj == NULL ) {
967967 return -1 ;
968968 }
@@ -1141,14 +1141,46 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
11411141 (interp -> monitors .tools [PY_MONITORING_EVENT_LINE ] |
11421142 code -> _co_monitoring -> local_monitors .tools [PY_MONITORING_EVENT_LINE ]
11431143 );
1144- PyObject * line_obj = PyLong_FromSsize_t (line );
1144+ /* Special case sys.settrace to avoid boxing the line number,
1145+ * only to immediately unbox it. */
1146+ if (tools & (1 << PY_MONITORING_SYS_TRACE_ID )) {
1147+ if (tstate -> c_tracefunc != NULL && line >= 0 ) {
1148+ PyFrameObject * frame_obj = _PyFrame_GetFrameObject (frame );
1149+ if (frame_obj == NULL ) {
1150+ return -1 ;
1151+ }
1152+ if (frame_obj -> f_trace_lines ) {
1153+ /* Need to set tracing and what_event as if using
1154+ * the instrumentation call. */
1155+ int old_what = tstate -> what_event ;
1156+ tstate -> what_event = PY_MONITORING_EVENT_LINE ;
1157+ tstate -> tracing ++ ;
1158+ /* Call c_tracefunc directly, having set the line number. */
1159+ Py_INCREF (frame_obj );
1160+ frame_obj -> f_lineno = line ;
1161+ int err = tstate -> c_tracefunc (tstate -> c_traceobj , frame_obj , PyTrace_LINE , Py_None );
1162+ frame_obj -> f_lineno = 0 ;
1163+ tstate -> tracing -- ;
1164+ tstate -> what_event = old_what ;
1165+ Py_DECREF (frame_obj );
1166+ if (err ) {
1167+ return -1 ;
1168+ }
1169+ }
1170+ }
1171+ tools &= (255 - (1 << PY_MONITORING_SYS_TRACE_ID ));
1172+ }
1173+ if (tools == 0 ) {
1174+ goto done ;
1175+ }
1176+ PyObject * line_obj = PyLong_FromLong (line );
11451177 if (line_obj == NULL ) {
11461178 return -1 ;
11471179 }
11481180 PyObject * args [3 ] = { NULL , (PyObject * )code , line_obj };
1149- while ( tools ) {
1181+ do {
11501182 int tool = most_significant_bit (tools );
1151- assert (tool >= 0 && tool < 8 );
1183+ assert (tool >= 0 && tool < PY_MONITORING_SYS_PROFILE_ID );
11521184 assert (tools & (1 << tool ));
11531185 tools &= ~(1 << tool );
11541186 int res = call_one_instrument (interp , tstate , & args [1 ],
@@ -1166,7 +1198,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
11661198 /* DISABLE */
11671199 remove_line_tools (code , i , 1 << tool );
11681200 }
1169- }
1201+ } while ( tools );
11701202 Py_DECREF (line_obj );
11711203 uint8_t original_opcode ;
11721204done :
@@ -1197,7 +1229,7 @@ _Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame*
11971229 code -> _co_monitoring -> local_monitors .tools [PY_MONITORING_EVENT_INSTRUCTION ]
11981230 );
11991231 int bytes_offset = offset * (int )sizeof (_Py_CODEUNIT );
1200- PyObject * offset_obj = PyLong_FromSsize_t (bytes_offset );
1232+ PyObject * offset_obj = PyLong_FromLong (bytes_offset );
12011233 if (offset_obj == NULL ) {
12021234 return -1 ;
12031235 }
0 commit comments