1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/*
* tclProc.c --
*
* This file contains routines that implement Tcl procedures,
* including the "proc" and "uplevel" commands.
*
* Copyright (c) 1987-1993 The Regents of the University of California.
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclProc.c,v 1.73.2.6 2005/04/14 18:39:10 msofer Exp $
*/
#include "tclInt.h"
#include "tclCompile.h"
/*
* Prototypes for static functions in this file
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/*
* tclProc.c --
*
* This file contains routines that implement Tcl procedures,
* including the "proc" and "uplevel" commands.
*
* Copyright (c) 1987-1993 The Regents of the University of California.
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclProc.c,v 1.73.2.7 2005/06/13 01:46:15 msofer Exp $
*/
#include "tclInt.h"
#include "tclCompile.h"
/*
* Prototypes for static functions in this file
|
| ︙ | | | ︙ | |
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
* field, encoding the type of level reference in ptr1 and the actual
* parsed out offset in ptr2.
*
* Uses the default behaviour throughout, and never disposes of the
* string rep; it's just a cache type.
*/
Tcl_ObjType tclLevelReferenceType = {
"levelReference",
NULL, NULL, NULL, NULL
};
/*
*----------------------------------------------------------------------
*
|
|
|
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
* field, encoding the type of level reference in ptr1 and the actual
* parsed out offset in ptr2.
*
* Uses the default behaviour throughout, and never disposes of the
* string rep; it's just a cache type.
*/
static Tcl_ObjType levelReferenceType = {
"levelReference",
NULL, NULL, NULL, NULL
};
/*
*----------------------------------------------------------------------
*
|
| ︙ | | | ︙ | |
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
|
/*
* Parse object to figure out which level number to go to.
*/
result = 1;
curLevel = (iPtr->varFramePtr == NULL) ? 0 : iPtr->varFramePtr->level;
if (objPtr->typePtr == &tclLevelReferenceType) {
if ((int) objPtr->internalRep.twoPtrValue.ptr1) {
level = curLevel - (int) objPtr->internalRep.twoPtrValue.ptr2;
} else {
level = (int) objPtr->internalRep.twoPtrValue.ptr2;
}
if (level < 0) {
goto levelError;
|
|
|
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
|
/*
* Parse object to figure out which level number to go to.
*/
result = 1;
curLevel = (iPtr->varFramePtr == NULL) ? 0 : iPtr->varFramePtr->level;
if (objPtr->typePtr == &levelReferenceType) {
if ((int) objPtr->internalRep.twoPtrValue.ptr1) {
level = curLevel - (int) objPtr->internalRep.twoPtrValue.ptr2;
} else {
level = (int) objPtr->internalRep.twoPtrValue.ptr2;
}
if (level < 0) {
goto levelError;
|
| ︙ | | | ︙ | |
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
|
if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
goto levelError;
}
/*
* Cache for future reference.
*/
TclFreeIntRep(objPtr);
objPtr->typePtr = &tclLevelReferenceType;
objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) 0;
objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) level;
} else if (isdigit(UCHAR(*name))) { /* INTL: digit */
if (Tcl_GetInt(interp, name, &level) != TCL_OK) {
return -1;
}
/*
* Cache for future reference.
*/
TclFreeIntRep(objPtr);
objPtr->typePtr = &tclLevelReferenceType;
objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) 1;
objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) level;
level = curLevel - level;
} else {
/*
* Don't cache as the object *isn't* a level reference.
*/
|
|
|
|
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
|
if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
goto levelError;
}
/*
* Cache for future reference.
*/
TclFreeIntRep(objPtr);
objPtr->typePtr = &levelReferenceType;
objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) 0;
objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) level;
} else if (isdigit(UCHAR(*name))) { /* INTL: digit */
if (Tcl_GetInt(interp, name, &level) != TCL_OK) {
return -1;
}
/*
* Cache for future reference.
*/
TclFreeIntRep(objPtr);
objPtr->typePtr = &levelReferenceType;
objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) 1;
objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) level;
level = curLevel - level;
} else {
/*
* Don't cache as the object *isn't* a level reference.
*/
|
| ︙ | | | ︙ | |
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
|
iPtr->returnLevel--;
if (iPtr->returnLevel < 0) {
Tcl_Panic("TclUpdateReturnInfo: negative return level");
}
if (iPtr->returnLevel == 0) {
/* Now we've reached the level to return the requested -code */
return iPtr->returnCode;
}
return code;
}
/*
*----------------------------------------------------------------------
*
|
|
|
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
|
iPtr->returnLevel--;
if (iPtr->returnLevel < 0) {
Tcl_Panic("TclUpdateReturnInfo: negative return level");
}
if (iPtr->returnLevel == 0) {
/* Now we've reached the level to return the requested -code */
code = iPtr->returnCode;
}
return code;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | | | ︙ | |