summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-09-19 15:44:21 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-09-19 15:44:21 (GMT)
commit77946f661583330fa93c84272c3cb2d06ee1ec9d (patch)
treef80120585e4a1dac922ed236f9febbe1519a0482
parent68feed9f4e09c3677ca335a790e197df2bdc5cf5 (diff)
downloadtcl-77946f661583330fa93c84272c3cb2d06ee1ec9d.zip
tcl-77946f661583330fa93c84272c3cb2d06ee1ec9d.tar.gz
tcl-77946f661583330fa93c84272c3cb2d06ee1ec9d.tar.bz2
Line numbers wrong in compiled [upvar].
-rw-r--r--generic/tclCompCmds.c16
-rw-r--r--tests/upvar.test11
2 files changed, 19 insertions, 8 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 51a566e..6189b29 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -5781,16 +5781,14 @@ TclCompileUpvarCmd(
Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
int simpleVarName, isScalar, localIndex, numWords, i;
DefineLineInformation; /* TIP #280 */
- Tcl_Obj *objPtr = Tcl_NewObj();
+ Tcl_Obj *objPtr;
if (envPtr->procPtr == NULL) {
- Tcl_DecrRefCount(objPtr);
return TCL_ERROR;
}
numWords = parsePtr->numWords;
if (numWords < 3) {
- Tcl_DecrRefCount(objPtr);
return TCL_ERROR;
}
@@ -5798,6 +5796,7 @@ TclCompileUpvarCmd(
* Push the frame index if it is known at compile time
*/
+ objPtr = Tcl_NewObj();
tokenPtr = TokenAfter(parsePtr->tokenPtr);
if(TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
CallFrame *framePtr;
@@ -5816,16 +5815,17 @@ TclCompileUpvarCmd(
if(numWords%2) {
return TCL_ERROR;
}
+ /* TODO: Push the known value instead? */
CompileWord(envPtr, tokenPtr, interp, 1);
otherTokenPtr = TokenAfter(tokenPtr);
- i = 4;
+ i = 2;
} else {
if(!(numWords%2)) {
return TCL_ERROR;
}
PushLiteral(envPtr, "1", 1);
otherTokenPtr = tokenPtr;
- i = 3;
+ i = 1;
}
} else {
Tcl_DecrRefCount(objPtr);
@@ -5838,12 +5838,12 @@ TclCompileUpvarCmd(
* be called at runtime.
*/
- for(; i<=numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) {
+ for(; i<numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) {
localTokenPtr = TokenAfter(otherTokenPtr);
- CompileWord(envPtr, otherTokenPtr, interp, 1);
+ CompileWord(envPtr, otherTokenPtr, interp, i);
PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR,
- &localIndex, &simpleVarName, &isScalar, 1);
+ &localIndex, &simpleVarName, &isScalar, i+1);
if((localIndex < 0) || !isScalar) {
return TCL_ERROR;
diff --git a/tests/upvar.test b/tests/upvar.test
index 457c9f8..d88d2c9 100644
--- a/tests/upvar.test
+++ b/tests/upvar.test
@@ -405,6 +405,17 @@ test upvar-9.7 {Tcl_UpVar procedure} testupvar {
} {1234}
catch {unset a}
+test upvar-10.1 {CompileWord OBOE} -setup {
+ proc linenumber {} {dict get [info frame -1] line}
+} -body {
+ apply {n {
+ upvar 1 {*}{
+ } [return [incr n -[linenumber]]] x
+ }} [linenumber]
+} -cleanup {
+ rename linenumber {}
+} -result 1
+
#
# Tests for 'namespace upvar'. As the implementation is essentially the same as