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.23.6.1 2001/12/03 18:23:14 andreas_kupries 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.23.6.2 2001/12/05 18:22:26 andreas_kupries Exp $
*/
#include "tclInt.h"
#include "tclCompile.h"
/*
* Prototypes for static functions in this file
|
| ︙ | | | ︙ | |
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
|
|| (strcmp(localPtr->name, fieldValues[0]))
|| (localPtr->frameIndex != i)
|| (localPtr->flags != (VAR_SCALAR | VAR_ARGUMENT))
|| ((localPtr->defValuePtr == NULL)
&& (fieldCount == 2))
|| ((localPtr->defValuePtr != NULL)
&& (fieldCount != 2))) {
char buf[80 + TCL_INTEGER_SPACE];
sprintf(buf, "\": formal parameter %d is inconsistent with precompiled body",
i);
Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
"procedure \"", procName,
buf, (char *) NULL);
ckfree((char *) fieldValues);
goto procError;
}
/*
* compare the default value if any
*/
|
|
>
>
|
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
|
|| (strcmp(localPtr->name, fieldValues[0]))
|| (localPtr->frameIndex != i)
|| (localPtr->flags != (VAR_SCALAR | VAR_ARGUMENT))
|| ((localPtr->defValuePtr == NULL)
&& (fieldCount == 2))
|| ((localPtr->defValuePtr != NULL)
&& (fieldCount != 2))) {
STRING (80 + TCL_INTEGER_SPACE, buf);
NEWSTR (80 + TCL_INTEGER_SPACE, buf);
sprintf(buf, "\": formal parameter %d is inconsistent with precompiled body",
i);
Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
"procedure \"", procName,
buf, (char *) NULL);
RELTEMP (buf);
ckfree((char *) fieldValues);
goto procError;
}
/*
* compare the default value if any
*/
|
| ︙ | | | ︙ | |
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
|
* in the context of this procedure.) */
Namespace *nsPtr; /* Namespace containing procedure. */
CONST char *description; /* string describing this body of code. */
CONST char *procName; /* Name of this procedure. */
{
Interp *iPtr = (Interp*)interp;
int result;
Tcl_CallFrame frame;
Proc *saveProcPtr;
ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr;
/*
* If necessary, compile the procedure's body. The compiler will
* allocate frame slots for the procedure's non-argument local
* variables. If the ByteCode already exists, make sure it hasn't been
* invalidated by someone redefining a core command (this might make the
* compiled code wrong). Also, if the code was compiled in/for a
* different interpreter, we recompile it. Note that compiling the body
|
|
>
>
|
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
|
* in the context of this procedure.) */
Namespace *nsPtr; /* Namespace containing procedure. */
CONST char *description; /* string describing this body of code. */
CONST char *procName; /* Name of this procedure. */
{
Interp *iPtr = (Interp*)interp;
int result;
TEMP (Tcl_CallFrame) frame;
Proc *saveProcPtr;
ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr;
NEWTEMP (Tcl_CallFrame, frame);
/*
* If necessary, compile the procedure's body. The compiler will
* allocate frame slots for the procedure's non-argument local
* variables. If the ByteCode already exists, make sure it hasn't been
* invalidated by someone redefining a core command (this might make the
* compiled code wrong). Also, if the code was compiled in/for a
* different interpreter, we recompile it. Note that compiling the body
|
| ︙ | | | ︙ | |
858
859
860
861
862
863
864
865
866
867
868
869
870
871
|
if (((Interp *) *codePtr->interpHandle != iPtr)
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|| (codePtr->nsPtr != nsPtr)) {
if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
if ((Interp *) *codePtr->interpHandle != iPtr) {
Tcl_AppendResult(interp,
"a precompiled script jumped interps", NULL);
return TCL_ERROR;
}
codePtr->compileEpoch = iPtr->compileEpoch;
codePtr->nsPtr = nsPtr;
} else {
(*tclByteCodeType.freeIntRepProc)(bodyPtr);
bodyPtr->typePtr = (Tcl_ObjType *) NULL;
|
>
|
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
|
if (((Interp *) *codePtr->interpHandle != iPtr)
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|| (codePtr->nsPtr != nsPtr)) {
if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
if ((Interp *) *codePtr->interpHandle != iPtr) {
Tcl_AppendResult(interp,
"a precompiled script jumped interps", NULL);
RELTEMP (frame);
return TCL_ERROR;
}
codePtr->compileEpoch = iPtr->compileEpoch;
codePtr->nsPtr = nsPtr;
} else {
(*tclByteCodeType.freeIntRepProc)(bodyPtr);
bodyPtr->typePtr = (Tcl_ObjType *) NULL;
|
| ︙ | | | ︙ | |
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
|
* proper namespace context, so that the byte codes are
* compiled in the appropriate class context.
*/
saveProcPtr = iPtr->compiledProcPtr;
iPtr->compiledProcPtr = procPtr;
result = Tcl_PushCallFrame(interp, &frame,
(Tcl_Namespace*)nsPtr, /* isProcCallFrame */ 0);
if (result == TCL_OK) {
result = tclByteCodeType.setFromAnyProc(interp, bodyPtr);
Tcl_PopCallFrame(interp);
}
iPtr->compiledProcPtr = saveProcPtr;
if (result != TCL_OK) {
if (result == TCL_ERROR) {
char buf[100 + TCL_INTEGER_SPACE];
numChars = strlen(procName);
ellipsis = "";
if (numChars > 50) {
numChars = 50;
ellipsis = "...";
}
sprintf(buf, "\n (compiling %s \"%.*s%s\", line %d)",
description, numChars, procName, ellipsis,
interp->errorLine);
Tcl_AddObjErrorInfo(interp, buf, -1);
}
return result;
}
} else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {
register CompiledLocal *localPtr;
/*
* The resolver epoch has changed, but we only need to invalidate
|
|
|
>
>
>
|
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
|
* proper namespace context, so that the byte codes are
* compiled in the appropriate class context.
*/
saveProcPtr = iPtr->compiledProcPtr;
iPtr->compiledProcPtr = procPtr;
result = Tcl_PushCallFrame(interp, REF (frame),
(Tcl_Namespace*)nsPtr, /* isProcCallFrame */ 0);
if (result == TCL_OK) {
result = tclByteCodeType.setFromAnyProc(interp, bodyPtr);
Tcl_PopCallFrame(interp);
}
iPtr->compiledProcPtr = saveProcPtr;
if (result != TCL_OK) {
if (result == TCL_ERROR) {
STRING (100 + TCL_INTEGER_SPACE, buf);
NEWSTR (100 + TCL_INTEGER_SPACE, buf);
numChars = strlen(procName);
ellipsis = "";
if (numChars > 50) {
numChars = 50;
ellipsis = "...";
}
sprintf(buf, "\n (compiling %s \"%.*s%s\", line %d)",
description, numChars, procName, ellipsis,
interp->errorLine);
Tcl_AddObjErrorInfo(interp, buf, -1);
RELTEMP (buf);
}
RELTEMP (frame);
return result;
}
} else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {
register CompiledLocal *localPtr;
/*
* The resolver epoch has changed, but we only need to invalidate
|
| ︙ | | | ︙ | |
950
951
952
953
954
955
956
957
958
959
960
961
962
963
|
} else {
ckfree((char*)localPtr->resolveInfo);
}
localPtr->resolveInfo = NULL;
}
}
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclProcDeleteProc --
|
>
|
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
|
} else {
ckfree((char*)localPtr->resolveInfo);
}
localPtr->resolveInfo = NULL;
}
}
}
RELTEMP (frame);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclProcDeleteProc --
|
| ︙ | | | ︙ | |