summaryrefslogtreecommitdiffstats
path: root/generic/tclProc.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclProc.c')
-rw-r--r--generic/tclProc.c89
1 files changed, 40 insertions, 49 deletions
diff --git a/generic/tclProc.c b/generic/tclProc.c
index 456e4c8..ce9f654 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -11,7 +11,7 @@
* 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.115.2.1 2007/06/05 18:12:42 dgp Exp $
+ * RCS: @(#) $Id: tclProc.c,v 1.115.2.2 2007/06/14 17:03:36 dgp Exp $
*/
#include "tclInt.h"
@@ -1249,13 +1249,15 @@ ObjInterpProcEx(
* When we've got bytecode, this is the check for validity. That is,
* the bytecode must be for the right interpreter (no cross-leaks!),
* the code must be from the current epoch (so subcommand compilation
- * is up-to-date), and the namespace must match (so variable handling
- * is right).
+ * is up-to-date), the namespace must match (so variable handling
+ * is right) and the resolverEpoch must match (so that new shadowed
+ * commands and/or resolver changes are considered).
*/
if (((Interp *) *codePtr->interpHandle != iPtr)
|| (codePtr->compileEpoch != iPtr->compileEpoch)
- || (codePtr->nsPtr != nsPtr)) {
+ || (codePtr->nsPtr != nsPtr)
+ || (codePtr->nsEpoch != nsPtr->resolverEpoch)) {
goto doCompilation;
}
} else {
@@ -1324,6 +1326,7 @@ TclObjInterpProcCore(
* results of the overall procedure. */
{
register Proc *procPtr = framePtr->procPtr;
+ ByteCode *codePtr = procPtr->bodyPtr->internalRep.otherValuePtr;
register Var *varPtr;
register CompiledLocal *localPtr;
int localCt, numArgs, argCt, i, imax, result;
@@ -1429,7 +1432,6 @@ TclObjInterpProcCore(
Tcl_IncrRefCount(objPtr); /* Local var is a reference. */
} else {
Tcl_Obj **desiredObjs;
- ByteCode *codePtr;
const char *final;
/*
@@ -1439,7 +1441,6 @@ TclObjInterpProcCore(
incorrectArgs:
final = NULL;
- codePtr = procPtr->bodyPtr->internalRep.otherValuePtr;
InitCompiledLocals(interp, codePtr, localPtr, varPtr, framePtr->nsPtr);
/*
@@ -1508,8 +1509,6 @@ TclObjInterpProcCore(
runProc:
if (localPtr) {
- ByteCode *codePtr = procPtr->bodyPtr->internalRep.otherValuePtr;
-
InitCompiledLocals(interp, codePtr, localPtr, varPtr, framePtr->nsPtr);
}
@@ -1534,13 +1533,20 @@ TclObjInterpProcCore(
*/
procPtr->refCount++;
+ ((Interp *)interp)->numLevels++;
- /*
- * TIP #280: No need to set the invoking context here. The body has
- * already been compiled, so the part of CompEvalObj using it is bypassed.
- */
-
- result = TclCompEvalObj(interp, procPtr->bodyPtr, NULL, 0);
+ if (TclInterpReady(interp) == TCL_ERROR) {
+ result = TCL_ERROR;
+ } else {
+ codePtr->refCount++;
+ result = TclExecuteByteCode(interp, codePtr);
+ codePtr->refCount--;
+ if (codePtr->refCount <= 0) {
+ TclCleanupByteCode(codePtr);
+ }
+ }
+
+ ((Interp *)interp)->numLevels--;
procPtr->refCount--;
if (procPtr->refCount <= 0) {
TclProcCleanupProc(procPtr);
@@ -1660,7 +1666,7 @@ ProcCompileProc(
* (Proc *) value may be written. */
{
Interp *iPtr = (Interp *) interp;
- int i, result;
+ int i;
Tcl_CallFrame *framePtr;
Proc *saveProcPtr;
ByteCode *codePtr = bodyPtr->internalRep.otherValuePtr;
@@ -1683,7 +1689,8 @@ ProcCompileProc(
if (bodyPtr->typePtr == &tclByteCodeType) {
if (((Interp *) *codePtr->interpHandle == iPtr)
&& (codePtr->compileEpoch == iPtr->compileEpoch)
- && (codePtr->nsPtr == nsPtr)) {
+ && (codePtr->nsPtr == nsPtr)
+ && (codePtr->nsEpoch == nsPtr->resolverEpoch)) {
return TCL_OK;
} else {
if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
@@ -1793,51 +1800,35 @@ ProcCompileProc(
}
iPtr->compiledProcPtr = procPtr;
- result = TclPushStackFrame(interp, &framePtr,
+ (void) TclPushStackFrame(interp, &framePtr,
(Tcl_Namespace *) nsPtr, /* isProcCallFrame */ 0);
- if (result == TCL_OK) {
- /*
- * TIP #280: We get the invoking context from the cmdFrame which
- * was saved by 'Tcl_ProcObjCmd' (using linePBodyPtr).
- */
-
- Tcl_HashEntry *hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr,
- (char *) procPtr);
+ /*
+ * TIP #280: We get the invoking context from the cmdFrame which
+ * was saved by 'Tcl_ProcObjCmd' (using linePBodyPtr).
+ */
- /*
- * Constructed saved frame has body as word 0. See Tcl_ProcObjCmd.
- */
+ Tcl_HashEntry *hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr,
+ (char *) procPtr);
- iPtr->invokeWord = 0;
- iPtr->invokeCmdFramePtr =
- (hePtr ? (CmdFrame *) Tcl_GetHashValue(hePtr) : NULL);
- result = tclByteCodeType.setFromAnyProc(interp, bodyPtr);
- iPtr->invokeCmdFramePtr = NULL;
- TclPopStackFrame(interp);
- }
+ /*
+ * Constructed saved frame has body as word 0. See Tcl_ProcObjCmd.
+ */
+ iPtr->invokeWord = 0;
+ iPtr->invokeCmdFramePtr =
+ (hePtr ? (CmdFrame *) Tcl_GetHashValue(hePtr) : NULL);
+ (void) tclByteCodeType.setFromAnyProc(interp, bodyPtr);
+ iPtr->invokeCmdFramePtr = NULL;
+ TclPopStackFrame(interp);
iPtr->compiledProcPtr = saveProcPtr;
-
- if (result != TCL_OK) {
- if (result == TCL_ERROR) {
- int length = strlen(procName);
- int limit = 50;
- int overflow = (length > limit);
-
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (compiling %s \"%.*s%s\", line %d)",
- description, (overflow ? limit : length), procName,
- (overflow ? "..." : ""), interp->errorLine));
- }
- return result;
- }
} else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {
/*
* The resolver epoch has changed, but we only need to invalidate the
* resolver cache.
*/
+ codePtr->nsEpoch = nsPtr->resolverEpoch;
codePtr->flags |= TCL_BYTECODE_RESOLVE_VARS;
}
return TCL_OK;