summaryrefslogtreecommitdiffstats
path: root/generic/tclInt.h
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2009-07-14 16:34:08 (GMT)
committerandreas_kupries <akupries@shaw.ca>2009-07-14 16:34:08 (GMT)
commit08604cad04da0d67c84406f99bda814f6a416386 (patch)
tree96331345b305a3ee61ad9c1dfa7f37983ab71540 /generic/tclInt.h
parent02457f7d6507f76fac8b308899e6592ab8214cb3 (diff)
downloadtcl-08604cad04da0d67c84406f99bda814f6a416386.zip
tcl-08604cad04da0d67c84406f99bda814f6a416386.tar.gz
tcl-08604cad04da0d67c84406f99bda814f6a416386.tar.bz2
* generic/tclCompile.c (TclInitCompileEnv, EnterCmdWordIndex,
TclCleanupByteCode, TclCompileScript): * generic/tclExecute.c (TclCompileObj, TclExecuteByteCode): * tclCompile.h (ExtCmdLoc): * tclInt.h (ExtIndex, CFWordBC, CmdFrame): * tclBasic.c (DeleteInterpProc, TclArgumentBCEnter, TclArgumentBCRelease, TclArgumentGet, SAVE_CONTEXT, RESTORE_CONTEXT, NRCoroutineExitCallback, TclNRCoroutineObjCmd): * generic/tclCmdAH.c (TclNRForObjCmd, TclNRForIterCallback, ForNextCallback): * generic/tclCmdMZ.c (TclNRWhileObjCmd): Extended the bytecode compiler initialization to recognize the compilation of whole files (NRE enabled 'source' command) and switch to the counting of absolute lines in that case. Further extended the bytecode compiler to track the start line in the generated information, and modified the bytecode execution to recompile an object if the location as per the calling context doesn't match the location saved in the bytecode. This part could be optimized more by using more memory to keep all possibilities which occur around, or by just adjusting the location information instead of a total recompile. Reworked the handling of literal command arguments in bytecode to be saved (compiler) and used (execution) per command (See the TCL_INVOKE_STK* instructions), and not per the whole bytecode. This, and the previous change remove the problems with location data caused by literal sharing (across whole files, but also proc bodies). Simplified the associated datastructures (ExtIndex is gone, as is the function EnterCmdWordIndex). The last change causes the hashtable 'lineLABCPtr' to be state which has to be kept per coroutine, like the CmdFrame stack. Reworked the coroutine support code to create, delete and switch the information as needed. Further reworked the tailcall command as well, it has to pop its own arguments when run in a bytecode context to keep a proper stack in 'lineLABCPtr'. Fixed the mishandling of line information in the NRE-enabled 'for' and 'while' commands introduced when both were made to share their iteration callbacks without taking into account that the loop body is found in different words of the command. Introduced a separate data structure to hold all the callback information, as we went over the limit of 4 direct client-data values for NRE callbacks. The above fixes [Bug 1605269].
Diffstat (limited to 'generic/tclInt.h')
-rw-r--r--generic/tclInt.h47
1 files changed, 33 insertions, 14 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 007facd..7374b23 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInt.h,v 1.427 2009/07/12 18:04:33 dkf Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.428 2009/07/14 16:34:09 andreas_kupries Exp $
*/
#ifndef _TCLINT
@@ -1114,7 +1114,10 @@ typedef struct CmdFrame {
CallFrame *framePtr; /* Procedure activation record, may be
* NULL. */
struct CmdFrame *nextPtr; /* Link to calling frame. */
-
+ const struct CFWordBC* litarg; /* Link to set of literal arguments which
+ * have ben pushed on the lineLABCPtr stack
+ * by TclArgumentBCEnter(). These will be
+ * removed by TclArgumentBCRelease. */
/*
* Data needed for Eval vs TEBC
*
@@ -1171,19 +1174,16 @@ typedef struct CFWord {
* stack. */
} CFWord;
-typedef struct ExtIndex {
- Tcl_Obj *obj; /* Reference to the word. */
+typedef struct CFWordBC {
+ Tcl_Obj* obj; /* Back reference to hashtable key */
+ CmdFrame *framePtr; /* CmdFrame to access. */
int pc; /* Instruction pointer of a command in
* ExtCmdLoc.loc[.] */
int word; /* Index of word in
* ExtCmdLoc.loc[cmd]->line[.] */
-} ExtIndex;
-
-typedef struct CFWordBC {
- CmdFrame *framePtr; /* CmdFrame to access. */
- ExtIndex *eiPtr; /* Word info: PC and index. */
- int refCount; /* Number of times the word is on the
- * stack. */
+ struct CFWordBC* prevPtr; /* Previous entry in stack for same Tcl_Obj */
+ struct CFWordBC* nextPtr; /* Next entry for same command call. See
+ * CmdFrame litarg field for the list start. */
} CFWordBC;
/*
@@ -1345,7 +1345,8 @@ typedef struct ExecStack {
typedef struct CorContext {
struct CallFrame *framePtr;
struct CallFrame *varFramePtr;
- struct CmdFrame *cmdFramePtr;
+ struct CmdFrame *cmdFramePtr; /* See Interp.cmdFramePtr */
+ Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */
} CorContext;
typedef struct CoroutineData {
@@ -2612,6 +2613,23 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd;
MODULE_SCOPE void TclClearTailcall(Tcl_Interp *interp,
struct TEOV_callback *tailcallPtr);
+/*
+ * This structure holds the data for the various iteration callbacks used to
+ * NRE the 'for' and 'while' commands. We need a separate structure because we
+ * have more than the 4 client data entries we can provide directly thorugh
+ * the callback API. It is the 'word' information which puts us over the
+ * limit. It is needed because the loop body is argument 4 of 'for' and
+ * argument 2 of 'while'. Not providing the correct index confuses the #280
+ * code. We TclSmallAlloc/Free this.
+ */
+
+typedef struct ForIterData {
+ Tcl_Obj* cond; /* loop condition expression */
+ Tcl_Obj* body; /* loop body */
+ Tcl_Obj* next; /* loop step script, NULL for 'while' */
+ char* msg; /* error message part */
+ int word; /* Index of the body script in the command */
+} ForIterData;
/*
*----------------------------------------------------------------
@@ -2629,9 +2647,10 @@ MODULE_SCOPE void TclArgumentEnter(Tcl_Interp *interp,
MODULE_SCOPE void TclArgumentRelease(Tcl_Interp *interp,
Tcl_Obj *objv[], int objc);
MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp,
- void *codePtr, CmdFrame *cfPtr);
+ Tcl_Obj* objv[], int objc,
+ void *codePtr, CmdFrame *cfPtr, int pc);
MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp,
- void *codePtr);
+ CmdFrame *cfPtr);
MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj,
CmdFrame **cfPtrPtr, int *wordPtr);
MODULE_SCOPE int TclArraySet(Tcl_Interp *interp,