diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2004-03-30 16:22:11 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2004-03-30 16:22:11 (GMT) |
commit | d7342e95b8185e47c027ad6a573b4242e5ca67c9 (patch) | |
tree | 513ad8ee17cc642e66403897bbb9188df51ee60b /generic/tclExecute.c | |
parent | 18687b718a2c5a3bc06cd3aea1c081fa25827009 (diff) | |
download | tcl-d7342e95b8185e47c027ad6a573b4242e5ca67c9.zip tcl-d7342e95b8185e47c027ad6a573b4242e5ca67c9.tar.gz tcl-d7342e95b8185e47c027ad6a573b4242e5ca67c9.tar.bz2 |
* generic/tclCompile.c: New instruction code INST_START_CMD
* generic/tclCompile.h: that allows checking the bytecode's
* generic/tclExecute.c: validity [Bug 729692] and the interp's
* tests/interp.test (18.9): readyness [Bug 495830] before running
* tests/proc.test (7.1): the command. It also changes the
* tests/rename.test (6.1): mechanics of the async tests in TEBC,
doing it now at command start instead of every 16 instructions.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 2a313d2..3ff411d 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.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: tclExecute.c,v 1.121 2004/01/18 16:19:05 dkf Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.122 2004/03/30 16:22:21 msofer Exp $ */ #include "tclInt.h" @@ -61,15 +61,6 @@ int errno; # endif /* MAXDOUBLE */ #endif /* !DBL_MAX */ -/* - * A mask (should be 2**n-1) that is used to work out when the - * bytecode engine should call Tcl_AsyncReady() to see whether there - * is a signal that needs handling. - */ - -#ifndef ASYNC_CHECK_COUNT_MASK -# define ASYNC_CHECK_COUNT_MASK 15 -#endif /* !ASYNC_CHECK_COUNT_MASK */ /* * Boolean flag indicating whether the Tcl bytecode interpreter has been @@ -1098,9 +1089,11 @@ TclExecuteByteCode(interp, codePtr) int traceInstructions = (tclTraceExec == 3); char cmdNameBuf[21]; #endif - int instructionCount = 0; /* Counter that is used to work out - * when to call Tcl_AsyncReady() */ - + Namespace *namespacePtr; + int codeCompileEpoch = codePtr->compileEpoch; + int codeNsEpoch = codePtr->nsEpoch; + int codePrecompiled = (codePtr->flags & TCL_BYTECODE_PRECOMPILED); + /* * The execution uses a unified stack: first the catch stack, immediately * above it the execution stack. @@ -1134,6 +1127,11 @@ TclExecuteByteCode(interp, codePtr) iPtr->stats.numExecutions++; #endif + if (iPtr->varFramePtr != NULL) { + namespacePtr = iPtr->varFramePtr->nsPtr; + } else { + namespacePtr = iPtr->globalNsPtr; + } /* * Loop executing instructions until a "done" instruction, a @@ -1215,21 +1213,43 @@ TclExecuteByteCode(interp, codePtr) iPtr->stats.instructionCount[*pc]++; #endif - /* - * Check for asynchronous handlers [Bug 746722]; we - * do the check every 16th instruction. - */ + switch (*pc) { + case INST_START_CMD: + /* + * Check for asynchronous handlers [Bug 746722]. + */ - if (!(instructionCount++ & ASYNC_CHECK_COUNT_MASK) && Tcl_AsyncReady()) { - DECACHE_STACK_INFO(); - result = Tcl_AsyncInvoke(interp, result); - CACHE_STACK_INFO(); - if (result == TCL_ERROR) { - goto checkForCatch; + if (Tcl_AsyncReady()) { + DECACHE_STACK_INFO(); + result = Tcl_AsyncInvoke(interp, result); + CACHE_STACK_INFO(); + if (result == TCL_ERROR) { + goto checkForCatch; + } } - } - - switch (*pc) { + + if ((!(iPtr->flags & DELETED) + && (codeCompileEpoch == iPtr->compileEpoch) + && (codeNsEpoch == namespacePtr->resolverEpoch)) + || codePrecompiled) { + NEXT_INST_F(5, 0, 0); + } else { + bytes = GetSrcInfoForPc(pc, codePtr, &length); + result = Tcl_EvalEx(interp, bytes, length, 0); + if (result != TCL_OK) { + goto checkForCatch; + } + opnd = TclGetUInt4AtPtr(pc+1); + objResultPtr = Tcl_GetObjResult(interp); + { + Tcl_Obj *newObjResultPtr; + TclNewObj(newObjResultPtr); + Tcl_IncrRefCount(newObjResultPtr); + iPtr->objResultPtr = newObjResultPtr; + } + NEXT_INST_V(opnd, 0, -1); + } + case INST_RETURN: { int code = TclGetInt4AtPtr(pc+1); @@ -1532,14 +1552,6 @@ TclExecuteByteCode(interp, codePtr) ++*preservedStackRefCountPtr; /* - * Reset the instructionCount variable, since we're about - * to check for async stuff anyway while processing - * TclEvalObjvInternal. - */ - - instructionCount = 1; - - /* * Finally, let TclEvalObjvInternal handle the command. */ |