@@ -950,7 +950,7 @@ call_instrumentation_vector(
950950 /* Offset visible to user should be the offset in bytes, as that is the
951951 * convention for APIs involving code offsets. */
952952 int bytes_offset = offset * (int )sizeof (_Py_CODEUNIT );
953- PyObject * offset_obj = PyLong_FromSsize_t (bytes_offset );
953+ PyObject * offset_obj = PyLong_FromLong (bytes_offset );
954954 if (offset_obj == NULL ) {
955955 return -1 ;
956956 }
@@ -1140,14 +1140,46 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
11401140 (interp -> monitors .tools [PY_MONITORING_EVENT_LINE ] |
11411141 code -> _co_monitoring -> local_monitors .tools [PY_MONITORING_EVENT_LINE ]
11421142 );
1143- PyObject * line_obj = PyLong_FromSsize_t (line );
1143+ /* Special case sys.settrace to avoid boxing the line number,
1144+ * only to immediately unbox it. */
1145+ if (tools & (1 << PY_MONITORING_SYS_TRACE_ID )) {
1146+ if (tstate -> c_tracefunc != NULL && line >= 0 ) {
1147+ PyFrameObject * frame_obj = _PyFrame_GetFrameObject (frame );
1148+ if (frame_obj == NULL ) {
1149+ return -1 ;
1150+ }
1151+ if (frame_obj -> f_trace_lines ) {
1152+ /* Need to set tracing and what_event as if using
1153+ * the instrumentation call. */
1154+ int old_what = tstate -> what_event ;
1155+ tstate -> what_event = PY_MONITORING_EVENT_LINE ;
1156+ tstate -> tracing ++ ;
1157+ /* Call c_tracefunc directly, having set the line number. */
1158+ Py_INCREF (frame_obj );
1159+ frame_obj -> f_lineno = line ;
1160+ int err = tstate -> c_tracefunc (tstate -> c_traceobj , frame_obj , PyTrace_LINE , Py_None );
1161+ frame_obj -> f_lineno = 0 ;
1162+ tstate -> tracing -- ;
1163+ tstate -> what_event = old_what ;
1164+ Py_DECREF (frame_obj );
1165+ if (err ) {
1166+ return -1 ;
1167+ }
1168+ }
1169+ }
1170+ tools &= (255 - (1 << PY_MONITORING_SYS_TRACE_ID ));
1171+ }
1172+ if (tools == 0 ) {
1173+ goto done ;
1174+ }
1175+ PyObject * line_obj = PyLong_FromLong (line );
11441176 if (line_obj == NULL ) {
11451177 return -1 ;
11461178 }
11471179 PyObject * args [3 ] = { NULL , (PyObject * )code , line_obj };
1148- while ( tools ) {
1180+ do {
11491181 int tool = most_significant_bit (tools );
1150- assert (tool >= 0 && tool < 8 );
1182+ assert (tool >= 0 && tool < PY_MONITORING_SYS_PROFILE_ID );
11511183 assert (tools & (1 << tool ));
11521184 tools &= ~(1 << tool );
11531185 int res = call_one_instrument (interp , tstate , & args [1 ],
@@ -1165,7 +1197,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
11651197 /* DISABLE */
11661198 remove_line_tools (code , i , 1 << tool );
11671199 }
1168- }
1200+ } while ( tools );
11691201 Py_DECREF (line_obj );
11701202done :
11711203 assert (original_opcode != 0 );
@@ -1194,7 +1226,7 @@ _Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame*
11941226 code -> _co_monitoring -> local_monitors .tools [PY_MONITORING_EVENT_INSTRUCTION ]
11951227 );
11961228 int bytes_offset = offset * (int )sizeof (_Py_CODEUNIT );
1197- PyObject * offset_obj = PyLong_FromSsize_t (bytes_offset );
1229+ PyObject * offset_obj = PyLong_FromLong (bytes_offset );
11981230 if (offset_obj == NULL ) {
11991231 return -1 ;
12001232 }
0 commit comments