Tcl Source Code

Artifact [7b933d7422]
Login

Artifact 7b933d7422bd4956b55a108e2e90c9205015522a:

Attachment "2910748-2.patch" to ticket [2910748fff] added by dgp 2010-01-21 23:52:37.
Index: generic/tclCompile.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompile.h,v
retrieving revision 1.120
diff -u -r1.120 tclCompile.h
--- generic/tclCompile.h	3 Jan 2010 20:29:11 -0000	1.120
+++ generic/tclCompile.h	21 Jan 2010 16:41:57 -0000
@@ -343,6 +343,8 @@
 
 #define TCL_BYTECODE_RESOLVE_VARS		0x0002
 
+#define TCL_BYTECODE_RECOMPILE			0x0004
+
 typedef struct ByteCode {
     TclHandle interpHandle;	/* Handle for interpreter containing the
 				 * compiled code. Commands and their compile
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.468
diff -u -r1.468 tclExecute.c
--- generic/tclExecute.c	13 Dec 2009 17:11:47 -0000	1.468
+++ generic/tclExecute.c	21 Jan 2010 16:41:58 -0000
@@ -2353,32 +2353,25 @@
 	} else {
 	    const char *bytes;
 	    int length = 0, opnd;
-	    Tcl_Obj *newObjResultPtr;
-
-	    bytes = GetSrcInfoForPc(pc, codePtr, &length);
-	    DECACHE_STACK_INFO();
-	    TRESULT = Tcl_EvalEx(interp, bytes, length, 0);
-	    CACHE_STACK_INFO();
-	    if (TRESULT != TCL_OK) {
-		cleanup = 0;
-		if (TRESULT == TCL_ERROR) {
-		    /*
-		     * Tcl_EvalEx already did the task of logging the error to
-		     * the stack trace for us, so set a flag to prevent the
-		     * TEBC exception handling machinery from trying to do it
-		     * again. See test execute-8.4. [Bug 2037338]
-		     */
+	    
+	    /*
+	     * We used to switch to direct eval; for NRE-awareness we now
+	     * compile and eval the command so that this evaluation does not
+	     * add a new TEBC instance [Bug 2910748]
+	     */
+		
 
-		    iPtr->flags |= ERR_ALREADY_LOGGED;
-		}
-		goto processExceptionReturn;
+	    if (TclInterpReady(interp) == TCL_ERROR) {
+		TRESULT = TCL_ERROR;
+		goto checkForCatch;
 	    }
+	    
+	    codePtr->flags |= TCL_BYTECODE_RECOMPILE;
+	    bytes = GetSrcInfoForPc(pc, codePtr, &length);
 	    opnd = TclGetUInt4AtPtr(pc+1);
-	    objResultPtr = Tcl_GetObjResult(interp);
-	    TclNewObj(newObjResultPtr);
-	    Tcl_IncrRefCount(newObjResultPtr);
-	    iPtr->objResultPtr = newObjResultPtr;
-	    NEXT_INST_F(opnd, 0, -1);
+	    pc += (opnd-1);
+	    PUSH_OBJECT(Tcl_NewStringObj(bytes, length));
+	    goto instEvalStk;
 	}
 
     case INST_NOP:
@@ -2675,6 +2668,7 @@
 	int objc, pcAdjustment;
 	Tcl_Obj **objv;
 
+	instEvalStk:
 	case INST_EVAL_STK: {
 	    /*
 	     * Moved here to support transforming the eval of objects to a
@@ -2915,6 +2909,10 @@
 
 	nonRecursiveCallReturn:
 
+	    if (codePtr->flags & TCL_BYTECODE_RECOMPILE) {
+		iPtr->flags |= ERR_ALREADY_LOGGED;
+		codePtr->flags &= ~TCL_BYTECODE_RECOMPILE;
+	    }
 	    NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr);
 	    iPtr->cmdFramePtr = bcFramePtr->nextPtr;
 	    TclArgumentBCRelease((Tcl_Interp *) iPtr, bcFramePtr);
Index: tests/nre.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/nre.test,v
retrieving revision 1.11
diff -u -r1.11 nre.test
--- tests/nre.test	25 Jun 2009 19:24:16 -0000	1.11
+++ tests/nre.test	21 Jan 2010 16:41:58 -0000
@@ -280,6 +280,28 @@
     testnrelevels
 } -result {{0 2 2 1} 0}
 
+test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup {
+    proc foo args {}
+    foo
+    coroutine bar apply {{} {
+	yield
+	proc foo args {return ok}
+	while 1 {
+	    yield [incr i]
+	    foo
+	}
+    }}
+} -body {
+    # if switching to plain eval is not nre aware, this will cause a "cannot
+    # yield" error
+
+    list [bar] [bar] [bar]
+} -cleanup {
+    rename bar {}
+    rename foo {}
+} -result {1 2 3}
+
+
 test nre-8.1 {nre and {*}} -body {
     # force an expansion that grows the evaluation stack, check that nre
     # adapts the bottomPtr. This crashes on failure.