[Python-checkins] python/dist/src/Python ceval.c,2.323,2.324 compile.c,2.257,2.258 frozen.c,1.12,1.13 import.c,2.208,2.209 traceback.c,2.38,2.39

mwh@users.sourceforge.net mwh@users.sourceforge.net
Thu, 15 Aug 2002 07:59:04 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv10908/Python

Modified Files:
	ceval.c compile.c frozen.c import.c traceback.c 
Log Message:
This is my patch

[ 587993 ] SET_LINENO killer

Remove SET_LINENO.  Tracing is now supported by inspecting co_lnotab.

Many sundry changes to document and adapt to this change.


Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.323
retrieving revision 2.324
diff -C2 -d -r2.323 -r2.324
*** ceval.c	9 Aug 2002 18:35:52 -0000	2.323
--- ceval.c	15 Aug 2002 14:59:02 -0000	2.324
***************
*** 52,55 ****
--- 52,58 ----
  				 PyFrameObject *, int);
  static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
+ static void maybe_call_line_trace(int, Py_tracefunc, PyObject *, 
+ 				  PyFrameObject *, int *, int *);
+ 
  static PyObject *apply_slice(PyObject *, PyObject *, PyObject *);
  static int assign_slice(PyObject *, PyObject *,
***************
*** 500,503 ****
--- 503,516 ----
  	PyThreadState *tstate = PyThreadState_GET();
  	PyCodeObject *co;
+ 
+ 	/* when tracing we set things up so that 
+ 
+                not (instr_lb <= current_bytecode_offset < instr_ub)
+ 
+ 	   is true when the line being executed has changed.  The 
+            initial values are such as to make this false the first
+            time it is tested. */
+ 	int instr_ub = -1, instr_lb = 0;
+ 
  	unsigned char *first_instr;
  	PyObject *names;
***************
*** 587,591 ****
  	freevars = f->f_localsplus + f->f_nlocals;
  	_PyCode_GETCODEPTR(co, &first_instr);
! 	next_instr = first_instr + f->f_lasti;
  	stack_pointer = f->f_stacktop;
  	assert(stack_pointer != NULL);
--- 600,609 ----
  	freevars = f->f_localsplus + f->f_nlocals;
  	_PyCode_GETCODEPTR(co, &first_instr);
! 	if (f->f_lasti < 0) {
! 		next_instr = first_instr;
! 	}
! 	else {
! 		next_instr = first_instr + f->f_lasti;
! 	}
  	stack_pointer = f->f_stacktop;
  	assert(stack_pointer != NULL);
***************
*** 638,643 ****
  
  	for (;;) {
! 		assert(stack_pointer >= f->f_valuestack);	/* else underflow */
! 		assert(STACK_LEVEL() <= f->f_stacksize);	/* else overflow */
  		/* Do periodic things.  Doing this every time through
  		   the loop would add too much overhead, so we do it
--- 656,662 ----
  
  	for (;;) {
! 		assert(stack_pointer >= f->f_valuestack); /* else underflow */
! 		assert(STACK_LEVEL() <= f->f_stacksize);  /* else overflow */
! 
  		/* Do periodic things.  Doing this every time through
  		   the loop would add too much overhead, so we do it
***************
*** 659,664 ****
  			/* If we have true signals, the signal handler
  			   will call Py_AddPendingCall() so we don't
! 			   have to call sigcheck().  On the Mac and
! 			   DOS, alas, we have to call it. */
  			if (PyErr_CheckSignals()) {
  				why = WHY_EXCEPTION;
--- 678,683 ----
  			/* If we have true signals, the signal handler
  			   will call Py_AddPendingCall() so we don't
! 			   have to call PyErr_CheckSignals().  On the 
! 			   Mac and DOS, alas, we have to call it. */
  			if (PyErr_CheckSignals()) {
  				why = WHY_EXCEPTION;
***************
*** 687,693 ****
  		/* Extract opcode and argument */
  
- #if defined(Py_DEBUG) || defined(LLTRACE)
  		f->f_lasti = INSTR_OFFSET();
- #endif
  
  		opcode = NEXTOP();
--- 706,710 ----
***************
*** 709,721 ****
  			if (HAS_ARG(opcode)) {
  				printf("%d: %d, %d\n",
! 					(int) (INSTR_OFFSET() - 3),
! 					opcode, oparg);
  			}
  			else {
  				printf("%d: %d\n",
! 					(int) (INSTR_OFFSET() - 1), opcode);
  			}
  		}
  #endif
  		/* Main switch on opcode */
  
--- 726,749 ----
  			if (HAS_ARG(opcode)) {
  				printf("%d: %d, %d\n",
! 				       f->f_lasti, opcode, oparg);
  			}
  			else {
  				printf("%d: %d\n",
! 				       f->f_lasti, opcode);
  			}
  		}
  #endif
+ 
+ 		/* line-by-line tracing support */
+ 
+ 		if (tstate->c_tracefunc != NULL && !tstate->tracing) {
+ 			/* see maybe_call_line_trace
+ 			   for expository comments */
+ 			maybe_call_line_trace(opcode, 
+ 					      tstate->c_tracefunc,
+ 					      tstate->c_traceobj,
+ 					      f, &instr_lb, &instr_ub);
+ 		}
+ 
  		/* Main switch on opcode */
  
***************
*** 729,752 ****
  		/* case STOP_CODE: this is an error! */
  
- 		case SET_LINENO:
- #ifdef LLTRACE
- 			if (lltrace)
- 				printf("--- %s:%d \n", filename, oparg);
- #endif
- 			f->f_lineno = oparg;
- 			if (tstate->c_tracefunc == NULL || tstate->tracing)
- 				goto fast_next_opcode;
- 			/* Trace each line of code reached */
- 			f->f_lasti = INSTR_OFFSET();
- 			/* Inline call_trace() for performance: */
- 			tstate->tracing++;
- 			tstate->use_tracing = 0;
- 			err = (tstate->c_tracefunc)(tstate->c_traceobj, f,
- 						    PyTrace_LINE, Py_None);
- 			tstate->use_tracing = (tstate->c_tracefunc
- 					       || tstate->c_profilefunc);
- 			tstate->tracing--;
- 			break;
- 
  		case LOAD_FAST:
  			x = GETLOCAL(oparg);
--- 757,760 ----
***************
*** 1505,1511 ****
--- 1513,1527 ----
  			break;
  
+ 		case RETURN_NONE:
+ 			retval = Py_None;
+ 			Py_INCREF(retval);
+ 			why = WHY_RETURN;
+ 			break;
+ 
  		case YIELD_VALUE:
  			retval = POP();
  			f->f_stacktop = stack_pointer;
+ 			/* abuse the lasti field: here it points to 
+ 			   the *next* instruction */
  			f->f_lasti = INSTR_OFFSET();
  			why = WHY_YIELD;
***************
*** 1955,1959 ****
  		    PyObject **pfunc = stack_pointer - n - 1;
  		    PyObject *func = *pfunc;
- 		    f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
  
  		    /* Always dispatch PyCFunction first, because
--- 1971,1974 ----
***************
*** 2023,2027 ****
  		    pfunc = stack_pointer - n - 1;
  		    func = *pfunc;
- 		    f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
  
  		    if (PyMethod_Check(func)
--- 2038,2041 ----
***************
*** 2135,2139 ****
  			fprintf(stderr,
  				"XXX lineno: %d, opcode: %d\n",
! 				f->f_lineno, opcode);
  			PyErr_SetString(PyExc_SystemError, "unknown opcode");
  			why = WHY_EXCEPTION;
--- 2149,2154 ----
  			fprintf(stderr,
  				"XXX lineno: %d, opcode: %d\n",
! 				PyCode_Addr2Line(f->f_code, f->f_lasti),
! 				opcode);
  			PyErr_SetString(PyExc_SystemError, "unknown opcode");
  			why = WHY_EXCEPTION;
***************
*** 2190,2196 ****
  
  		if (why == WHY_EXCEPTION) {
- 			f->f_lasti = INSTR_OFFSET() - 1;
- 			if (HAS_ARG(opcode))
- 				f->f_lasti -= 2;
  			PyTraceBack_Here(f);
  
--- 2205,2208 ----
***************
*** 2874,2877 ****
--- 2886,3008 ----
  	tstate->tracing--;
  	return result;
+ }
+ 
+ static void
+ maybe_call_line_trace(int opcode, Py_tracefunc func, PyObject *obj, 
+ 		      PyFrameObject *frame, int *instr_lb, int *instr_ub)
+ {
+ 	/* The theory of SET_LINENO-less tracing.
+ 	   
+ 	   In a nutshell, we use the co_lnotab field of the code object
+ 	   to tell when execution has moved onto a different line.
+ 
+ 	   As mentioned above, the basic idea is so set things up so
+ 	   that
+ 
+ 	         *instr_lb <= frame->f_lasti < *instr_ub
+ 
+ 	   is true so long as execution does not change lines.
+ 
+ 	   This is all fairly simple.  Digging the information out of
+ 	   co_lnotab takes some work, but is conceptually clear.
+ 
+ 	   Somewhat harder to explain is why we don't call the line
+ 	   trace function when executing a POP_TOP or RETURN_NONE
+ 	   opcodes.  An example probably serves best.
+ 
+ 	   Consider this code:
+ 
+ 	   1: def f(a):
+ 	   2:     if a:
+ 	   3:        print 1
+ 	   4:     else:
+ 	   5:        print 2
+ 
+ 	   which compiles to this:
+ 
+ 	   2           0 LOAD_FAST                0 (a)
+ 		       3 JUMP_IF_FALSE            9 (to 15)
+ 		       6 POP_TOP             
+ 
+ 	   3           7 LOAD_CONST               1 (1)
+ 		      10 PRINT_ITEM          
+ 		      11 PRINT_NEWLINE       
+ 		      12 JUMP_FORWARD             6 (to 21)
+ 		 >>   15 POP_TOP             
+ 
+ 	   5          16 LOAD_CONST               2 (2)
+ 		      19 PRINT_ITEM          
+ 		      20 PRINT_NEWLINE       
+ 		 >>   21 RETURN_NONE         
+ 
+ 	   If a is false, execution will jump to instruction at offset
+ 	   15 and the co_lnotab will claim that execution has moved to
+ 	   line 3.  This is at best misleading.  In this case we could
+ 	   associate the POP_TOP with line 4, but that doesn't make
+ 	   sense in all cases (I think).
+ 
+ 	   On the other hand, if a is true, execution will jump from
+ 	   instruction offset 12 to offset 21.  Then the co_lnotab would
+ 	   imply that execution has moved to line 5, which is again
+ 	   misleading.
+ 
+ 	   This is why it is important that RETURN_NONE is *only* used
+ 	   for the "falling off the end of the function" form of
+ 	   returning None -- using it for code like
+ 
+ 	   1: def f():
+ 	   2:     return
+ 
+ 	   would, once again, lead to misleading tracing behaviour.
+ 
+ 	   It is also worth mentioning that getting tracing behaviour
+ 	   right is the *entire* motivation for adding the RETURN_NONE
+ 	   opcode.
+ 	*/
+ 
+ 	if (opcode != POP_TOP && opcode != RETURN_NONE &&
+ 	    (frame->f_lasti < *instr_lb || frame->f_lasti > *instr_ub)) {
+ 		PyCodeObject* co = frame->f_code;
+ 		int size, addr;
+ 		unsigned char* p;
+ 
+ 		call_trace(func, obj, frame, PyTrace_LINE, Py_None);
+ 
+ 		size = PyString_Size(co->co_lnotab) / 2;
+ 		p = (unsigned char*)PyString_AsString(co->co_lnotab);
+ 
+ 		/* possible optimization: if f->f_lasti == instr_ub
+ 		   (likely to be a common case) then we already know
+ 		   instr_lb -- if we stored the matching value of p
+ 		   somwhere we could skip the first while loop. */
+ 
+ 		addr = 0;
+ 
+ 		/* see comments in compile.c for the description of
+ 		   co_lnotab.  A point to remember: increments to p
+ 		   should come in pairs -- although we don't care about
+ 		   the line increments here, treating them as byte
+ 		   increments gets confusing, to say the least. */
+ 
+ 		while (size >= 0) {
+ 			if (addr + *p > frame->f_lasti)
+ 				break;
+ 			addr += *p++;
+ 			p++;
+ 			--size;
+ 		}
+ 		*instr_lb = addr;
+ 		if (size > 0) {
+ 			while (--size >= 0) {
+ 				addr += *p++;
+ 				if (*p++)
+ 					break;
+ 			}
+ 			*instr_ub = addr;
+ 		}
+ 		else {
+ 			*instr_ub = INT_MAX;
+ 		}
+ 	}
  }
  

Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.257
retrieving revision 2.258
diff -C2 -d -r2.257 -r2.258
*** compile.c	14 Aug 2002 15:51:28 -0000	2.257
--- compile.c	15 Aug 2002 14:59:02 -0000	2.258
***************
*** 408,414 ****
  /* All about c_lnotab.
  
! c_lnotab is an array of unsigned bytes disguised as a Python string.  In -O
! mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped
! to source code line #s (when needed for tracebacks) via c_lnotab instead.
  The array is conceptually a list of
      (bytecode offset increment, line number increment)
--- 408,415 ----
  /* All about c_lnotab.
  
! c_lnotab is an array of unsigned bytes disguised as a Python string.  Since
! version 2.3, SET_LINENO opcodes are never generated and bytecode offsets are
! mapped to source code line #s via c_lnotab instead.
! 
  The array is conceptually a list of
      (bytecode offset increment, line number increment)
***************
*** 831,839 ****
  {
  	int extended_arg = arg >> 16;
- 	if (op == SET_LINENO) {
- 		com_set_lineno(c, arg);
- 		if (Py_OptimizeFlag)
- 			return;
- 	}
  	if (extended_arg){
  		com_addbyte(c, EXTENDED_ARG);
--- 832,835 ----
***************
*** 1739,1743 ****
  			if (ch->n_lineno != lineno) {
  				lineno = ch->n_lineno;
! 				com_addoparg(c, SET_LINENO, lineno);
  			}
  			com_argument(c, ch, &keywords);
--- 1735,1739 ----
  			if (ch->n_lineno != lineno) {
  				lineno = ch->n_lineno;
! 				com_set_lineno(c, lineno);
  			}
  			com_argument(c, ch, &keywords);
***************
*** 3169,3173 ****
  		}
  		if (i > 0)
! 			com_addoparg(c, SET_LINENO, ch->n_lineno);
  		com_node(c, ch);
  		com_addfwref(c, JUMP_IF_FALSE, &a);
--- 3165,3169 ----
  		}
  		if (i > 0)
! 			com_set_lineno(c, ch->n_lineno);
  		com_node(c, ch);
  		com_addfwref(c, JUMP_IF_FALSE, &a);
***************
*** 3196,3200 ****
  	block_push(c, SETUP_LOOP);
  	c->c_begin = c->c_nexti;
! 	com_addoparg(c, SET_LINENO, n->n_lineno);
  	com_node(c, CHILD(n, 1));
  	com_addfwref(c, JUMP_IF_FALSE, &anchor);
--- 3192,3196 ----
  	block_push(c, SETUP_LOOP);
  	c->c_begin = c->c_nexti;
! 	com_set_lineno(c, n->n_lineno);
  	com_node(c, CHILD(n, 1));
  	com_addfwref(c, JUMP_IF_FALSE, &anchor);
***************
*** 3229,3233 ****
  	com_addbyte(c, GET_ITER);
  	c->c_begin = c->c_nexti;
! 	com_addoparg(c, SET_LINENO, n->n_lineno);
  	com_addfwref(c, FOR_ITER, &anchor);
  	com_push(c, 1);
--- 3225,3229 ----
  	com_addbyte(c, GET_ITER);
  	c->c_begin = c->c_nexti;
! 	com_set_lineno(c, n->n_lineno);
  	com_addfwref(c, FOR_ITER, &anchor);
  	com_push(c, 1);
***************
*** 3340,3344 ****
  		except_anchor = 0;
  		com_push(c, 3); /* tb, val, exc pushed by exception */
! 		com_addoparg(c, SET_LINENO, ch->n_lineno);
  		if (NCH(ch) > 1) {
  			com_addbyte(c, DUP_TOP);
--- 3336,3340 ----
  		except_anchor = 0;
  		com_push(c, 3); /* tb, val, exc pushed by exception */
! 		com_set_lineno(c, ch->n_lineno);
  		if (NCH(ch) > 1) {
  			com_addbyte(c, DUP_TOP);
***************
*** 3402,3406 ****
  	com_backpatch(c, finally_anchor);
  	ch = CHILD(n, NCH(n)-1);
! 	com_addoparg(c, SET_LINENO, ch->n_lineno);
  	com_node(c, ch);
  	com_addbyte(c, END_FINALLY);
--- 3398,3402 ----
  	com_backpatch(c, finally_anchor);
  	ch = CHILD(n, NCH(n)-1);
! 	com_set_lineno(c, ch->n_lineno);
  	com_node(c, ch);
  	com_addbyte(c, END_FINALLY);
***************
*** 3728,3732 ****
  	case simple_stmt:
  		/* small_stmt (';' small_stmt)* [';'] NEWLINE */
! 		com_addoparg(c, SET_LINENO, n->n_lineno);
  		{
  			int i;
--- 3724,3728 ----
  	case simple_stmt:
  		/* small_stmt (';' small_stmt)* [';'] NEWLINE */
! 		com_set_lineno(c, n->n_lineno);
  		{
  			int i;
***************
*** 3737,3741 ****
  	
  	case compound_stmt:
! 		com_addoparg(c, SET_LINENO, n->n_lineno);
  		n = CHILD(n, 0);
  		goto loop;
--- 3733,3737 ----
  	
  	case compound_stmt:
! 		com_set_lineno(c, n->n_lineno);
  		n = CHILD(n, 0);
  		goto loop;
***************
*** 3991,3998 ****
  	com_node(c, CHILD(n, 4));
  	c->c_infunction = 0;
! 	com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
! 	com_push(c, 1);
! 	com_addbyte(c, RETURN_VALUE);
! 	com_pop(c, 1);
  }
  
--- 3987,3991 ----
  	com_node(c, CHILD(n, 4));
  	c->c_infunction = 0;
! 	com_addbyte(c, RETURN_NONE);
  }
  
***************
*** 4051,4055 ****
  compile_node(struct compiling *c, node *n)
  {
! 	com_addoparg(c, SET_LINENO, n->n_lineno);
  	
  	switch (TYPE(n)) {
--- 4044,4048 ----
  compile_node(struct compiling *c, node *n)
  {
! 	com_set_lineno(c, n->n_lineno);
  	
  	switch (TYPE(n)) {
***************
*** 4061,4068 ****
  		if (TYPE(n) != NEWLINE)
  			com_node(c, n);
! 		com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
! 		com_push(c, 1);
! 		com_addbyte(c, RETURN_VALUE);
! 		com_pop(c, 1);
  		c->c_interactive--;
  		break;
--- 4054,4058 ----
  		if (TYPE(n) != NEWLINE)
  			com_node(c, n);
! 		com_addbyte(c, RETURN_NONE);
  		c->c_interactive--;
  		break;
***************
*** 4070,4077 ****
  	case file_input: /* A whole file, or built-in function exec() */
  		com_file_input(c, n);
! 		com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
! 		com_push(c, 1);
! 		com_addbyte(c, RETURN_VALUE);
! 		com_pop(c, 1);
  		break;
  	
--- 4060,4064 ----
  	case file_input: /* A whole file, or built-in function exec() */
  		com_file_input(c, n);
! 		com_addbyte(c, RETURN_NONE);
  		break;
  	

Index: frozen.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/frozen.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** frozen.c	14 Jun 2002 01:11:57 -0000	1.12
--- frozen.c	15 Aug 2002 14:59:02 -0000	1.13
***************
*** 14,23 ****
  static unsigned char M___hello__[] = {
  	99,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
! 	0,115,15,0,0,0,127,0,0,127,1,0,100,0,0,71,
! 	72,100,1,0,83,40,2,0,0,0,115,14,0,0,0,72,
! 	101,108,108,111,32,119,111,114,108,100,46,46,46,78,40,0,
! 	0,0,0,40,0,0,0,0,40,0,0,0,0,40,0,0,
! 	0,0,115,8,0,0,0,104,101,108,108,111,46,112,121,115,
! 	1,0,0,0,63,1,0,0,0,115,0,0,0,0,
  };
  
--- 14,23 ----
  static unsigned char M___hello__[] = {
  	99,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
! 	0,115,9,0,0,0,100,0,0,71,72,100,1,0,83,40,
! 	2,0,0,0,115,14,0,0,0,72,101,108,108,111,32,119,
! 	111,114,108,100,46,46,46,78,40,0,0,0,0,40,0,0,
! 	0,0,40,0,0,0,0,40,0,0,0,0,115,8,0,0,
! 	0,104,101,108,108,111,46,112,121,115,1,0,0,0,63,1,
! 	0,0,0,115,0,0,0,0,
  };
  

Index: import.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/import.c,v
retrieving revision 2.208
retrieving revision 2.209
diff -C2 -d -r2.208 -r2.209
*** import.c	30 Jun 2002 15:26:10 -0000	2.208
--- import.c	15 Aug 2002 14:59:02 -0000	2.209
***************
*** 50,53 ****
--- 50,56 ----
         start counting in increments of 10 from now on ?!
  
+        MWH, 2002-08-03: Removed SET_LINENO.  Couldn't be bothered figuring
+        out the MAGIC schemes, so just incremented it by 10.
+ 
     Known values:
         Python 1.5:   20121
***************
*** 61,66 ****
         Python 2.2:   60717
         Python 2.3a0: 62011
  */
! #define MAGIC (62011 | ((long)'\r'<<16) | ((long)'\n'<<24))
  
  /* Magic word as global; note that _PyImport_Init() can change the
--- 64,70 ----
         Python 2.2:   60717
         Python 2.3a0: 62011
+        Python 2.3a0: 62021
  */
! #define MAGIC (62021 | ((long)'\r'<<16) | ((long)'\n'<<24))
  
  /* Magic word as global; note that _PyImport_Init() can change the

Index: traceback.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/traceback.c,v
retrieving revision 2.38
retrieving revision 2.39
diff -C2 -d -r2.38 -r2.39
*** traceback.c	14 Apr 2002 20:12:41 -0000	2.38
--- traceback.c	15 Aug 2002 14:59:02 -0000	2.39
***************
*** 104,109 ****
  
  static tracebackobject *
! newtracebackobject(tracebackobject *next, PyFrameObject *frame, int lasti,
! 		   int lineno)
  {
  	tracebackobject *tb;
--- 104,108 ----
  
  static tracebackobject *
! newtracebackobject(tracebackobject *next, PyFrameObject *frame)
  {
  	tracebackobject *tb;
***************
*** 119,124 ****
  		Py_XINCREF(frame);
  		tb->tb_frame = frame;
! 		tb->tb_lasti = lasti;
! 		tb->tb_lineno = lineno;
  		PyObject_GC_Track(tb);
  	}
--- 118,124 ----
  		Py_XINCREF(frame);
  		tb->tb_frame = frame;
! 		tb->tb_lasti = frame->f_lasti;
! 		tb->tb_lineno = PyCode_Addr2Line(frame->f_code, 
! 						 frame->f_lasti);
  		PyObject_GC_Track(tb);
  	}
***************
*** 131,136 ****
  	PyThreadState *tstate = frame->f_tstate;
  	tracebackobject *oldtb = (tracebackobject *) tstate->curexc_traceback;
! 	tracebackobject *tb = newtracebackobject(oldtb,
! 				frame, frame->f_lasti, frame->f_lineno);
  	if (tb == NULL)
  		return -1;
--- 131,135 ----
  	PyThreadState *tstate = frame->f_tstate;
  	tracebackobject *oldtb = (tracebackobject *) tstate->curexc_traceback;
! 	tracebackobject *tb = newtracebackobject(oldtb, frame);
  	if (tb == NULL)
  		return -1;