/[dtapublic]/projs/dtats/trunk/shared_source/c_tcl_base_7_5_w_mods/tclcompile.h
ViewVC logotype

Diff of /projs/dtats/trunk/shared_source/c_tcl_base_7_5_w_mods/tclcompile.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

projs/trunk/shared_source/c_tcl_base_7_5_w_mods/tclcompile.h revision 64 by dashley, Sun Oct 30 04:21:11 2016 UTC projs/dtats/trunk/shared_source/c_tcl_base_7_5_w_mods/tclcompile.h revision 98 by dashley, Sun Dec 18 00:57:31 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2  /*  /*
3   * tclCompile.h --   * tclCompile.h --
4   *   *
5   * Copyright (c) 1996-1998 Sun Microsystems, Inc.   * Copyright (c) 1996-1998 Sun Microsystems, Inc.
6   *   *
7   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
8   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9   *   *
10   * RCS: @(#) $Id: tclcompile.h,v 1.1.1.1 2001/06/13 04:36:28 dtashley Exp $   * RCS: @(#) $Id: tclcompile.h,v 1.1.1.1 2001/06/13 04:36:28 dtashley Exp $
11   */   */
12    
13  #ifndef _TCLCOMPILATION  #ifndef _TCLCOMPILATION
14  #define _TCLCOMPILATION 1  #define _TCLCOMPILATION 1
15    
16  #ifndef _TCLINT  #ifndef _TCLINT
17  #include "tclInt.h"  #include "tclInt.h"
18  #endif /* _TCLINT */  #endif /* _TCLINT */
19    
20  #ifdef BUILD_tcl  #ifdef BUILD_tcl
21  # undef TCL_STORAGE_CLASS  # undef TCL_STORAGE_CLASS
22  # define TCL_STORAGE_CLASS DLLEXPORT  # define TCL_STORAGE_CLASS DLLEXPORT
23  #endif  #endif
24    
25  /*  /*
26   *------------------------------------------------------------------------   *------------------------------------------------------------------------
27   * Variables related to compilation. These are used in tclCompile.c,   * Variables related to compilation. These are used in tclCompile.c,
28   * tclExecute.c, tclBasic.c, and their clients.   * tclExecute.c, tclBasic.c, and their clients.
29   *------------------------------------------------------------------------   *------------------------------------------------------------------------
30   */   */
31    
32  /*  /*
33   * Variable that denotes the command name Tcl object type. Objects of this   * Variable that denotes the command name Tcl object type. Objects of this
34   * type cache the Command pointer that results from looking up command names   * type cache the Command pointer that results from looking up command names
35   * in the command hashtable.   * in the command hashtable.
36   */   */
37    
38  extern Tcl_ObjType      tclCmdNameType;  extern Tcl_ObjType      tclCmdNameType;
39    
40  /*  /*
41   * Variable that controls whether compilation tracing is enabled and, if so,   * Variable that controls whether compilation tracing is enabled and, if so,
42   * what level of tracing is desired:   * what level of tracing is desired:
43   *    0: no compilation tracing   *    0: no compilation tracing
44   *    1: summarize compilation of top level cmds and proc bodies   *    1: summarize compilation of top level cmds and proc bodies
45   *    2: display all instructions of each ByteCode compiled   *    2: display all instructions of each ByteCode compiled
46   * This variable is linked to the Tcl variable "tcl_traceCompile".   * This variable is linked to the Tcl variable "tcl_traceCompile".
47   */   */
48    
49  extern int              tclTraceCompile;  extern int              tclTraceCompile;
50    
51  /*  /*
52   * Variable that controls whether execution tracing is enabled and, if so,   * Variable that controls whether execution tracing is enabled and, if so,
53   * what level of tracing is desired:   * what level of tracing is desired:
54   *    0: no execution tracing   *    0: no execution tracing
55   *    1: trace invocations of Tcl procs only   *    1: trace invocations of Tcl procs only
56   *    2: trace invocations of all (not compiled away) commands   *    2: trace invocations of all (not compiled away) commands
57   *    3: display each instruction executed   *    3: display each instruction executed
58   * This variable is linked to the Tcl variable "tcl_traceExec".   * This variable is linked to the Tcl variable "tcl_traceExec".
59   */   */
60    
61  extern int              tclTraceExec;  extern int              tclTraceExec;
62    
63  /*  /*
64   *------------------------------------------------------------------------   *------------------------------------------------------------------------
65   * Data structures related to compilation.   * Data structures related to compilation.
66   *------------------------------------------------------------------------   *------------------------------------------------------------------------
67   */   */
68    
69  /*  /*
70   * The structure used to implement Tcl "exceptions" (exceptional returns):   * The structure used to implement Tcl "exceptions" (exceptional returns):
71   * for example, those generated in loops by the break and continue commands,   * for example, those generated in loops by the break and continue commands,
72   * and those generated by scripts and caught by the catch command. This   * and those generated by scripts and caught by the catch command. This
73   * ExceptionRange structure describes a range of code (e.g., a loop body),   * ExceptionRange structure describes a range of code (e.g., a loop body),
74   * the kind of exceptions (e.g., a break or continue) that might occur, and   * the kind of exceptions (e.g., a break or continue) that might occur, and
75   * the PC offsets to jump to if a matching exception does occur. Exception   * the PC offsets to jump to if a matching exception does occur. Exception
76   * ranges can nest so this structure includes a nesting level that is used   * ranges can nest so this structure includes a nesting level that is used
77   * at runtime to find the closest exception range surrounding a PC. For   * at runtime to find the closest exception range surrounding a PC. For
78   * example, when a break command is executed, the ExceptionRange structure   * example, when a break command is executed, the ExceptionRange structure
79   * for the most deeply nested loop, if any, is found and used. These   * for the most deeply nested loop, if any, is found and used. These
80   * structures are also generated for the "next" subcommands of for loops   * structures are also generated for the "next" subcommands of for loops
81   * since a break there terminates the for command. This means a for command   * since a break there terminates the for command. This means a for command
82   * actually generates two LoopInfo structures.   * actually generates two LoopInfo structures.
83   */   */
84    
85  typedef enum {  typedef enum {
86      LOOP_EXCEPTION_RANGE,       /* Exception's range is part of a loop.      LOOP_EXCEPTION_RANGE,       /* Exception's range is part of a loop.
87                                   * Break and continue "exceptions" cause                                   * Break and continue "exceptions" cause
88                                   * jumps to appropriate PC offsets. */                                   * jumps to appropriate PC offsets. */
89      CATCH_EXCEPTION_RANGE       /* Exception's range is controlled by a      CATCH_EXCEPTION_RANGE       /* Exception's range is controlled by a
90                                   * catch command. Errors in the range cause                                   * catch command. Errors in the range cause
91                                   * a jump to a catch PC offset. */                                   * a jump to a catch PC offset. */
92  } ExceptionRangeType;  } ExceptionRangeType;
93    
94  typedef struct ExceptionRange {  typedef struct ExceptionRange {
95      ExceptionRangeType type;    /* The kind of ExceptionRange. */      ExceptionRangeType type;    /* The kind of ExceptionRange. */
96      int nestingLevel;           /* Static depth of the exception range.      int nestingLevel;           /* Static depth of the exception range.
97                                   * Used to find the most deeply-nested                                   * Used to find the most deeply-nested
98                                   * range surrounding a PC at runtime. */                                   * range surrounding a PC at runtime. */
99      int codeOffset;             /* Offset of the first instruction byte of      int codeOffset;             /* Offset of the first instruction byte of
100                                   * the code range. */                                   * the code range. */
101      int numCodeBytes;           /* Number of bytes in the code range. */      int numCodeBytes;           /* Number of bytes in the code range. */
102      int breakOffset;            /* If LOOP_EXCEPTION_RANGE, the target PC      int breakOffset;            /* If LOOP_EXCEPTION_RANGE, the target PC
103                                   * offset for a break command in the range. */                                   * offset for a break command in the range. */
104      int continueOffset;         /* If LOOP_EXCEPTION_RANGE and not -1, the      int continueOffset;         /* If LOOP_EXCEPTION_RANGE and not -1, the
105                                   * target PC offset for a continue command in                                   * target PC offset for a continue command in
106                                   * the code range. Otherwise, ignore this range                                   * the code range. Otherwise, ignore this range
107                                   * when processing a continue command. */                                   * when processing a continue command. */
108      int catchOffset;            /* If a CATCH_EXCEPTION_RANGE, the target PC      int catchOffset;            /* If a CATCH_EXCEPTION_RANGE, the target PC
109                                   * offset for any "exception" in range. */                                   * offset for any "exception" in range. */
110  } ExceptionRange;  } ExceptionRange;
111    
112  /*  /*
113   * Structure used to map between instruction pc and source locations. It   * Structure used to map between instruction pc and source locations. It
114   * defines for each compiled Tcl command its code's starting offset and   * defines for each compiled Tcl command its code's starting offset and
115   * its source's starting offset and length. Note that the code offset   * its source's starting offset and length. Note that the code offset
116   * increases monotonically: that is, the table is sorted in code offset   * increases monotonically: that is, the table is sorted in code offset
117   * order. The source offset is not monotonic.   * order. The source offset is not monotonic.
118   */   */
119    
120  typedef struct CmdLocation {  typedef struct CmdLocation {
121      int codeOffset;             /* Offset of first byte of command code. */      int codeOffset;             /* Offset of first byte of command code. */
122      int numCodeBytes;           /* Number of bytes for command's code. */      int numCodeBytes;           /* Number of bytes for command's code. */
123      int srcOffset;              /* Offset of first char of the command. */      int srcOffset;              /* Offset of first char of the command. */
124      int numSrcBytes;            /* Number of command source chars. */      int numSrcBytes;            /* Number of command source chars. */
125  } CmdLocation;  } CmdLocation;
126    
127  /*  /*
128   * CompileProcs need the ability to record information during compilation   * CompileProcs need the ability to record information during compilation
129   * that can be used by bytecode instructions during execution. The AuxData   * that can be used by bytecode instructions during execution. The AuxData
130   * structure provides this "auxiliary data" mechanism. An arbitrary number   * structure provides this "auxiliary data" mechanism. An arbitrary number
131   * of these structures can be stored in the ByteCode record (during   * of these structures can be stored in the ByteCode record (during
132   * compilation they are stored in a CompileEnv structure). Each AuxData   * compilation they are stored in a CompileEnv structure). Each AuxData
133   * record holds one word of client-specified data (often a pointer) and is   * record holds one word of client-specified data (often a pointer) and is
134   * given an index that instructions can later use to look up the structure   * given an index that instructions can later use to look up the structure
135   * and its data.   * and its data.
136   *   *
137   * The following definitions declare the types of procedures that are called   * The following definitions declare the types of procedures that are called
138   * to duplicate or free this auxiliary data when the containing ByteCode   * to duplicate or free this auxiliary data when the containing ByteCode
139   * objects are duplicated and freed. Pointers to these procedures are kept   * objects are duplicated and freed. Pointers to these procedures are kept
140   * in the AuxData structure.   * in the AuxData structure.
141   */   */
142    
143  typedef ClientData (AuxDataDupProc)  _ANSI_ARGS_((ClientData clientData));  typedef ClientData (AuxDataDupProc)  _ANSI_ARGS_((ClientData clientData));
144  typedef void       (AuxDataFreeProc) _ANSI_ARGS_((ClientData clientData));  typedef void       (AuxDataFreeProc) _ANSI_ARGS_((ClientData clientData));
145    
146  /*  /*
147   * We define a separate AuxDataType struct to hold type-related information   * We define a separate AuxDataType struct to hold type-related information
148   * for the AuxData structure. This separation makes it possible for clients   * for the AuxData structure. This separation makes it possible for clients
149   * outside of the TCL core to manipulate (in a limited fashion!) AuxData;   * outside of the TCL core to manipulate (in a limited fashion!) AuxData;
150   * for example, it makes it possible to pickle and unpickle AuxData structs.   * for example, it makes it possible to pickle and unpickle AuxData structs.
151   */   */
152    
153  typedef struct AuxDataType {  typedef struct AuxDataType {
154      char *name;                                 /* the name of the type. Types can be      char *name;                                 /* the name of the type. Types can be
155                                   * registered and found by name */                                   * registered and found by name */
156      AuxDataDupProc *dupProc;    /* Callback procedure to invoke when the      AuxDataDupProc *dupProc;    /* Callback procedure to invoke when the
157                                   * aux data is duplicated (e.g., when the                                   * aux data is duplicated (e.g., when the
158                                   * ByteCode structure containing the aux                                   * ByteCode structure containing the aux
159                                   * data is duplicated). NULL means just                                   * data is duplicated). NULL means just
160                                   * copy the source clientData bits; no                                   * copy the source clientData bits; no
161                                   * proc need be called. */                                   * proc need be called. */
162      AuxDataFreeProc *freeProc;  /* Callback procedure to invoke when the      AuxDataFreeProc *freeProc;  /* Callback procedure to invoke when the
163                                   * aux data is freed. NULL means no                                   * aux data is freed. NULL means no
164                                   * proc need be called. */                                   * proc need be called. */
165  } AuxDataType;  } AuxDataType;
166    
167  /*  /*
168   * The definition of the AuxData structure that holds information created   * The definition of the AuxData structure that holds information created
169   * during compilation by CompileProcs and used by instructions during   * during compilation by CompileProcs and used by instructions during
170   * execution.   * execution.
171   */   */
172    
173  typedef struct AuxData {  typedef struct AuxData {
174      AuxDataType *type;          /* pointer to the AuxData type associated with      AuxDataType *type;          /* pointer to the AuxData type associated with
175                               * this ClientData. */                               * this ClientData. */
176      ClientData clientData;      /* The compilation data itself. */      ClientData clientData;      /* The compilation data itself. */
177  } AuxData;  } AuxData;
178    
179  /*  /*
180   * Structure defining the compilation environment. After compilation, fields   * Structure defining the compilation environment. After compilation, fields
181   * describing bytecode instructions are copied out into the more compact   * describing bytecode instructions are copied out into the more compact
182   * ByteCode structure defined below.   * ByteCode structure defined below.
183   */   */
184    
185  #define COMPILEENV_INIT_CODE_BYTES    250  #define COMPILEENV_INIT_CODE_BYTES    250
186  #define COMPILEENV_INIT_NUM_OBJECTS    60  #define COMPILEENV_INIT_NUM_OBJECTS    60
187  #define COMPILEENV_INIT_EXCEPT_RANGES   5  #define COMPILEENV_INIT_EXCEPT_RANGES   5
188  #define COMPILEENV_INIT_CMD_MAP_SIZE   40  #define COMPILEENV_INIT_CMD_MAP_SIZE   40
189  #define COMPILEENV_INIT_AUX_DATA_SIZE   5  #define COMPILEENV_INIT_AUX_DATA_SIZE   5
190    
191  typedef struct CompileEnv {  typedef struct CompileEnv {
192      Interp *iPtr;               /* Interpreter containing the code being      Interp *iPtr;               /* Interpreter containing the code being
193                                   * compiled. Commands and their compile                                   * compiled. Commands and their compile
194                                   * procs are specific to an interpreter so                                   * procs are specific to an interpreter so
195                                   * the code emitted will depend on the                                   * the code emitted will depend on the
196                                   * interpreter. */                                   * interpreter. */
197      char *source;               /* The source string being compiled by      char *source;               /* The source string being compiled by
198                                   * SetByteCodeFromAny. This pointer is not                                   * SetByteCodeFromAny. This pointer is not
199                                   * owned by the CompileEnv and must not be                                   * owned by the CompileEnv and must not be
200                                   * freed or changed by it. */                                   * freed or changed by it. */
201      int numSrcBytes;            /* Number of bytes in source. */      int numSrcBytes;            /* Number of bytes in source. */
202      Proc *procPtr;              /* If a procedure is being compiled, a      Proc *procPtr;              /* If a procedure is being compiled, a
203                                   * pointer to its Proc structure; otherwise                                   * pointer to its Proc structure; otherwise
204                                   * NULL. Used to compile local variables.                                   * NULL. Used to compile local variables.
205                                   * Set from information provided by                                   * Set from information provided by
206                                   * ObjInterpProc in tclProc.c. */                                   * ObjInterpProc in tclProc.c. */
207      int numCommands;            /* Number of commands compiled. */      int numCommands;            /* Number of commands compiled. */
208      int exceptDepth;            /* Current exception range nesting level;      int exceptDepth;            /* Current exception range nesting level;
209                                   * -1 if not in any range currently. */                                   * -1 if not in any range currently. */
210      int maxExceptDepth;         /* Max nesting level of exception ranges;      int maxExceptDepth;         /* Max nesting level of exception ranges;
211                                   * -1 if no ranges have been compiled. */                                   * -1 if no ranges have been compiled. */
212      int maxStackDepth;          /* Maximum number of stack elements needed      int maxStackDepth;          /* Maximum number of stack elements needed
213                                   * to execute the code. Set by compilation                                   * to execute the code. Set by compilation
214                                   * procedures before returning. */                                   * procedures before returning. */
215      LiteralTable localLitTable; /* Contains LiteralEntry's describing      LiteralTable localLitTable; /* Contains LiteralEntry's describing
216                                   * all Tcl objects referenced by this                                   * all Tcl objects referenced by this
217                                   * compiled code. Indexed by the string                                   * compiled code. Indexed by the string
218                                   * representations of the literals. Used to                                   * representations of the literals. Used to
219                                   * avoid creating duplicate objects. */                                   * avoid creating duplicate objects. */
220      int exprIsJustVarRef;       /* Set 1 if the expression last compiled by      int exprIsJustVarRef;       /* Set 1 if the expression last compiled by
221                                   * TclCompileExpr consisted of just a                                   * TclCompileExpr consisted of just a
222                                   * variable reference as in the expression                                   * variable reference as in the expression
223                                   * of "if $b then...". Otherwise 0. Used                                   * of "if $b then...". Otherwise 0. Used
224                                   * to implement expr's 2 level substitution                                   * to implement expr's 2 level substitution
225                                   * semantics properly. */                                   * semantics properly. */
226      int exprIsComparison;       /* Set 1 if the top-level operator in the      int exprIsComparison;       /* Set 1 if the top-level operator in the
227                                   * expression last compiled is a comparison.                                   * expression last compiled is a comparison.
228                                   * Otherwise 0. If 1, since the operands                                   * Otherwise 0. If 1, since the operands
229                                   * might be strings, the expr is compiled                                   * might be strings, the expr is compiled
230                                   * out-of-line to implement expr's 2 level                                   * out-of-line to implement expr's 2 level
231                                   * substitution semantics properly. */                                   * substitution semantics properly. */
232      unsigned char *codeStart;   /* Points to the first byte of the code. */      unsigned char *codeStart;   /* Points to the first byte of the code. */
233      unsigned char *codeNext;    /* Points to next code array byte to use. */      unsigned char *codeNext;    /* Points to next code array byte to use. */
234      unsigned char *codeEnd;     /* Points just after the last allocated      unsigned char *codeEnd;     /* Points just after the last allocated
235                                   * code array byte. */                                   * code array byte. */
236      int mallocedCodeArray;      /* Set 1 if code array was expanded      int mallocedCodeArray;      /* Set 1 if code array was expanded
237                                   * and codeStart points into the heap.*/                                   * and codeStart points into the heap.*/
238      LiteralEntry *literalArrayPtr;      LiteralEntry *literalArrayPtr;
239                                  /* Points to start of LiteralEntry array. */                                  /* Points to start of LiteralEntry array. */
240      int literalArrayNext;       /* Index of next free object array entry. */      int literalArrayNext;       /* Index of next free object array entry. */
241      int literalArrayEnd;        /* Index just after last obj array entry. */      int literalArrayEnd;        /* Index just after last obj array entry. */
242      int mallocedLiteralArray;   /* 1 if object array was expanded and      int mallocedLiteralArray;   /* 1 if object array was expanded and
243                                   * objArray points into the heap, else 0. */                                   * objArray points into the heap, else 0. */
244      ExceptionRange *exceptArrayPtr;      ExceptionRange *exceptArrayPtr;
245                                  /* Points to start of the ExceptionRange                                  /* Points to start of the ExceptionRange
246                                   * array. */                                   * array. */
247      int exceptArrayNext;        /* Next free ExceptionRange array index.      int exceptArrayNext;        /* Next free ExceptionRange array index.
248                                   * exceptArrayNext is the number of ranges                                   * exceptArrayNext is the number of ranges
249                                   * and (exceptArrayNext-1) is the index of                                   * and (exceptArrayNext-1) is the index of
250                                   * the current range's array entry. */                                   * the current range's array entry. */
251      int exceptArrayEnd;         /* Index after the last ExceptionRange      int exceptArrayEnd;         /* Index after the last ExceptionRange
252                                   * array entry. */                                   * array entry. */
253      int mallocedExceptArray;    /* 1 if ExceptionRange array was expanded      int mallocedExceptArray;    /* 1 if ExceptionRange array was expanded
254                                   * and exceptArrayPtr points in heap,                                   * and exceptArrayPtr points in heap,
255                                   * else 0. */                                   * else 0. */
256      CmdLocation *cmdMapPtr;     /* Points to start of CmdLocation array.      CmdLocation *cmdMapPtr;     /* Points to start of CmdLocation array.
257                                   * numCommands is the index of the next                                   * numCommands is the index of the next
258                                   * entry to use; (numCommands-1) is the                                   * entry to use; (numCommands-1) is the
259                                   * entry index for the last command. */                                   * entry index for the last command. */
260      int cmdMapEnd;              /* Index after last CmdLocation entry. */      int cmdMapEnd;              /* Index after last CmdLocation entry. */
261      int mallocedCmdMap;         /* 1 if command map array was expanded and      int mallocedCmdMap;         /* 1 if command map array was expanded and
262                                   * cmdMapPtr points in the heap, else 0. */                                   * cmdMapPtr points in the heap, else 0. */
263      AuxData *auxDataArrayPtr;   /* Points to auxiliary data array start. */      AuxData *auxDataArrayPtr;   /* Points to auxiliary data array start. */
264      int auxDataArrayNext;       /* Next free compile aux data array index.      int auxDataArrayNext;       /* Next free compile aux data array index.
265                                   * auxDataArrayNext is the number of aux                                   * auxDataArrayNext is the number of aux
266                                   * data items and (auxDataArrayNext-1) is                                   * data items and (auxDataArrayNext-1) is
267                                   * index of current aux data array entry. */                                   * index of current aux data array entry. */
268      int auxDataArrayEnd;        /* Index after last aux data array entry. */      int auxDataArrayEnd;        /* Index after last aux data array entry. */
269      int mallocedAuxDataArray;   /* 1 if aux data array was expanded and      int mallocedAuxDataArray;   /* 1 if aux data array was expanded and
270                                   * auxDataArrayPtr points in heap else 0. */                                   * auxDataArrayPtr points in heap else 0. */
271      unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES];      unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES];
272                                  /* Initial storage for code. */                                  /* Initial storage for code. */
273      LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS];      LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS];
274                                  /* Initial storage of LiteralEntry array. */                                  /* Initial storage of LiteralEntry array. */
275      ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];      ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
276                                  /* Initial ExceptionRange array storage. */                                  /* Initial ExceptionRange array storage. */
277      CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];      CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
278                                  /* Initial storage for cmd location map. */                                  /* Initial storage for cmd location map. */
279      AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];      AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
280                                  /* Initial storage for aux data array. */                                  /* Initial storage for aux data array. */
281  } CompileEnv;  } CompileEnv;
282    
283  /*  /*
284   * The structure defining the bytecode instructions resulting from compiling   * The structure defining the bytecode instructions resulting from compiling
285   * a Tcl script. Note that this structure is variable length: a single heap   * a Tcl script. Note that this structure is variable length: a single heap
286   * object is allocated to hold the ByteCode structure immediately followed   * object is allocated to hold the ByteCode structure immediately followed
287   * by the code bytes, the literal object array, the ExceptionRange array,   * by the code bytes, the literal object array, the ExceptionRange array,
288   * the CmdLocation map, and the compilation AuxData array.   * the CmdLocation map, and the compilation AuxData array.
289   */   */
290    
291  /*  /*
292   * A PRECOMPILED bytecode struct is one that was generated from a compiled   * A PRECOMPILED bytecode struct is one that was generated from a compiled
293   * image rather than implicitly compiled from source   * image rather than implicitly compiled from source
294   */   */
295  #define TCL_BYTECODE_PRECOMPILED                0x0001  #define TCL_BYTECODE_PRECOMPILED                0x0001
296    
297  typedef struct ByteCode {  typedef struct ByteCode {
298      TclHandle interpHandle;     /* Handle for interpreter containing the      TclHandle interpHandle;     /* Handle for interpreter containing the
299                                   * compiled code.  Commands and their compile                                   * compiled code.  Commands and their compile
300                                   * procs are specific to an interpreter so the                                   * procs are specific to an interpreter so the
301                                   * code emitted will depend on the                                   * code emitted will depend on the
302                                   * interpreter. */                                   * interpreter. */
303      int compileEpoch;           /* Value of iPtr->compileEpoch when this      int compileEpoch;           /* Value of iPtr->compileEpoch when this
304                                   * ByteCode was compiled. Used to invalidate                                   * ByteCode was compiled. Used to invalidate
305                                   * code when, e.g., commands with compile                                   * code when, e.g., commands with compile
306                                   * procs are redefined. */                                   * procs are redefined. */
307      Namespace *nsPtr;           /* Namespace context in which this code      Namespace *nsPtr;           /* Namespace context in which this code
308                                   * was compiled. If the code is executed                                   * was compiled. If the code is executed
309                                   * if a different namespace, it must be                                   * if a different namespace, it must be
310                                   * recompiled. */                                   * recompiled. */
311      int nsEpoch;                /* Value of nsPtr->resolverEpoch when this      int nsEpoch;                /* Value of nsPtr->resolverEpoch when this
312                                   * ByteCode was compiled. Used to invalidate                                   * ByteCode was compiled. Used to invalidate
313                                   * code when new namespace resolution rules                                   * code when new namespace resolution rules
314                                   * are put into effect. */                                   * are put into effect. */
315      int refCount;               /* Reference count: set 1 when created      int refCount;               /* Reference count: set 1 when created
316                                   * plus 1 for each execution of the code                                   * plus 1 for each execution of the code
317                                   * currently active. This structure can be                                   * currently active. This structure can be
318                                   * freed when refCount becomes zero. */                                   * freed when refCount becomes zero. */
319      unsigned int flags;         /* flags describing state for the codebyte.      unsigned int flags;         /* flags describing state for the codebyte.
320                                   * this variable holds ORed values from the                                   * this variable holds ORed values from the
321                                   * TCL_BYTECODE_ masks defined above */                                   * TCL_BYTECODE_ masks defined above */
322      char *source;               /* The source string from which this      char *source;               /* The source string from which this
323                                   * ByteCode was compiled. Note that this                                   * ByteCode was compiled. Note that this
324                                   * pointer is not owned by the ByteCode and                                   * pointer is not owned by the ByteCode and
325                                   * must not be freed or modified by it. */                                   * must not be freed or modified by it. */
326      Proc *procPtr;              /* If the ByteCode was compiled from a      Proc *procPtr;              /* If the ByteCode was compiled from a
327                                   * procedure body, this is a pointer to its                                   * procedure body, this is a pointer to its
328                                   * Proc structure; otherwise NULL. This                                   * Proc structure; otherwise NULL. This
329                                   * pointer is also not owned by the ByteCode                                   * pointer is also not owned by the ByteCode
330                                   * and must not be freed by it. */                                   * and must not be freed by it. */
331      size_t structureSize;       /* Number of bytes in the ByteCode structure      size_t structureSize;       /* Number of bytes in the ByteCode structure
332                                   * itself. Does not include heap space for                                   * itself. Does not include heap space for
333                                   * literal Tcl objects or storage referenced                                   * literal Tcl objects or storage referenced
334                                   * by AuxData entries. */                                   * by AuxData entries. */
335      int numCommands;            /* Number of commands compiled. */      int numCommands;            /* Number of commands compiled. */
336      int numSrcBytes;            /* Number of source bytes compiled. */      int numSrcBytes;            /* Number of source bytes compiled. */
337      int numCodeBytes;           /* Number of code bytes. */      int numCodeBytes;           /* Number of code bytes. */
338      int numLitObjects;          /* Number of objects in literal array. */      int numLitObjects;          /* Number of objects in literal array. */
339      int numExceptRanges;        /* Number of ExceptionRange array elems. */      int numExceptRanges;        /* Number of ExceptionRange array elems. */
340      int numAuxDataItems;        /* Number of AuxData items. */      int numAuxDataItems;        /* Number of AuxData items. */
341      int numCmdLocBytes;         /* Number of bytes needed for encoded      int numCmdLocBytes;         /* Number of bytes needed for encoded
342                                   * command location information. */                                   * command location information. */
343      int maxExceptDepth;         /* Maximum nesting level of ExceptionRanges;      int maxExceptDepth;         /* Maximum nesting level of ExceptionRanges;
344                                   * -1 if no ranges were compiled. */                                   * -1 if no ranges were compiled. */
345      int maxStackDepth;          /* Maximum number of stack elements needed      int maxStackDepth;          /* Maximum number of stack elements needed
346                                   * to execute the code. */                                   * to execute the code. */
347      unsigned char *codeStart;   /* Points to the first byte of the code.      unsigned char *codeStart;   /* Points to the first byte of the code.
348                                   * This is just after the final ByteCode                                   * This is just after the final ByteCode
349                                   * member cmdMapPtr. */                                   * member cmdMapPtr. */
350      Tcl_Obj **objArrayPtr;      /* Points to the start of the literal      Tcl_Obj **objArrayPtr;      /* Points to the start of the literal
351                                   * object array. This is just after the                                   * object array. This is just after the
352                                   * last code byte. */                                   * last code byte. */
353      ExceptionRange *exceptArrayPtr;      ExceptionRange *exceptArrayPtr;
354                                  /* Points to the start of the ExceptionRange                                  /* Points to the start of the ExceptionRange
355                                   * array. This is just after the last                                   * array. This is just after the last
356                                   * object in the object array. */                                   * object in the object array. */
357      AuxData *auxDataArrayPtr;   /* Points to the start of the auxiliary data      AuxData *auxDataArrayPtr;   /* Points to the start of the auxiliary data
358                                   * array. This is just after the last entry                                   * array. This is just after the last entry
359                                   * in the ExceptionRange array. */                                   * in the ExceptionRange array. */
360      unsigned char *codeDeltaStart;      unsigned char *codeDeltaStart;
361                                  /* Points to the first of a sequence of                                  /* Points to the first of a sequence of
362                                   * bytes that encode the change in the                                   * bytes that encode the change in the
363                                   * starting offset of each command's code.                                   * starting offset of each command's code.
364                                   * If -127<=delta<=127, it is encoded as 1                                   * If -127<=delta<=127, it is encoded as 1
365                                   * byte, otherwise 0xFF (128) appears and                                   * byte, otherwise 0xFF (128) appears and
366                                   * the delta is encoded by the next 4 bytes.                                   * the delta is encoded by the next 4 bytes.
367                                   * Code deltas are always positive. This                                   * Code deltas are always positive. This
368                                   * sequence is just after the last entry in                                   * sequence is just after the last entry in
369                                   * the AuxData array. */                                   * the AuxData array. */
370      unsigned char *codeLengthStart;      unsigned char *codeLengthStart;
371                                  /* Points to the first of a sequence of                                  /* Points to the first of a sequence of
372                                   * bytes that encode the length of each                                   * bytes that encode the length of each
373                                   * command's code. The encoding is the same                                   * command's code. The encoding is the same
374                                   * as for code deltas. Code lengths are                                   * as for code deltas. Code lengths are
375                                   * always positive. This sequence is just                                   * always positive. This sequence is just
376                                   * after the last entry in the code delta                                   * after the last entry in the code delta
377                                   * sequence. */                                   * sequence. */
378      unsigned char *srcDeltaStart;      unsigned char *srcDeltaStart;
379                                  /* Points to the first of a sequence of                                  /* Points to the first of a sequence of
380                                   * bytes that encode the change in the                                   * bytes that encode the change in the
381                                   * starting offset of each command's source.                                   * starting offset of each command's source.
382                                   * The encoding is the same as for code                                   * The encoding is the same as for code
383                                   * deltas. Source deltas can be negative.                                   * deltas. Source deltas can be negative.
384                                   * This sequence is just after the last byte                                   * This sequence is just after the last byte
385                                   * in the code length sequence. */                                   * in the code length sequence. */
386      unsigned char *srcLengthStart;      unsigned char *srcLengthStart;
387                                  /* Points to the first of a sequence of                                  /* Points to the first of a sequence of
388                                   * bytes that encode the length of each                                   * bytes that encode the length of each
389                                   * command's source. The encoding is the                                   * command's source. The encoding is the
390                                   * same as for code deltas. Source lengths                                   * same as for code deltas. Source lengths
391                                   * are always positive. This sequence is                                   * are always positive. This sequence is
392                                   * just after the last byte in the source                                   * just after the last byte in the source
393                                   * delta sequence. */                                   * delta sequence. */
394  #ifdef TCL_COMPILE_STATS  #ifdef TCL_COMPILE_STATS
395      Tcl_Time createTime;        /* Absolute time when the ByteCode was      Tcl_Time createTime;        /* Absolute time when the ByteCode was
396                                   * created. */                                   * created. */
397  #endif /* TCL_COMPILE_STATS */  #endif /* TCL_COMPILE_STATS */
398  } ByteCode;  } ByteCode;
399    
400  /*  /*
401   * Opcodes for the Tcl bytecode instructions. These must correspond to the   * Opcodes for the Tcl bytecode instructions. These must correspond to the
402   * entries in the table of instruction descriptions, instructionTable, in   * entries in the table of instruction descriptions, instructionTable, in
403   * tclCompile.c. Also, the order and number of the expression opcodes   * tclCompile.c. Also, the order and number of the expression opcodes
404   * (e.g., INST_LOR) must match the entries in the array operatorStrings in   * (e.g., INST_LOR) must match the entries in the array operatorStrings in
405   * tclExecute.c.   * tclExecute.c.
406   */   */
407    
408  /* Opcodes 0 to 9 */  /* Opcodes 0 to 9 */
409  #define INST_DONE                       0  #define INST_DONE                       0
410  #define INST_PUSH1                      1  #define INST_PUSH1                      1
411  #define INST_PUSH4                      2  #define INST_PUSH4                      2
412  #define INST_POP                        3  #define INST_POP                        3
413  #define INST_DUP                        4  #define INST_DUP                        4
414  #define INST_CONCAT1                    5  #define INST_CONCAT1                    5
415  #define INST_INVOKE_STK1                6  #define INST_INVOKE_STK1                6
416  #define INST_INVOKE_STK4                7  #define INST_INVOKE_STK4                7
417  #define INST_EVAL_STK                   8  #define INST_EVAL_STK                   8
418  #define INST_EXPR_STK                   9  #define INST_EXPR_STK                   9
419    
420  /* Opcodes 10 to 23 */  /* Opcodes 10 to 23 */
421  #define INST_LOAD_SCALAR1               10  #define INST_LOAD_SCALAR1               10
422  #define INST_LOAD_SCALAR4               11  #define INST_LOAD_SCALAR4               11
423  #define INST_LOAD_SCALAR_STK            12  #define INST_LOAD_SCALAR_STK            12
424  #define INST_LOAD_ARRAY1                13  #define INST_LOAD_ARRAY1                13
425  #define INST_LOAD_ARRAY4                14  #define INST_LOAD_ARRAY4                14
426  #define INST_LOAD_ARRAY_STK             15  #define INST_LOAD_ARRAY_STK             15
427  #define INST_LOAD_STK                   16  #define INST_LOAD_STK                   16
428  #define INST_STORE_SCALAR1              17  #define INST_STORE_SCALAR1              17
429  #define INST_STORE_SCALAR4              18  #define INST_STORE_SCALAR4              18
430  #define INST_STORE_SCALAR_STK           19  #define INST_STORE_SCALAR_STK           19
431  #define INST_STORE_ARRAY1               20  #define INST_STORE_ARRAY1               20
432  #define INST_STORE_ARRAY4               21  #define INST_STORE_ARRAY4               21
433  #define INST_STORE_ARRAY_STK            22  #define INST_STORE_ARRAY_STK            22
434  #define INST_STORE_STK                  23  #define INST_STORE_STK                  23
435    
436  /* Opcodes 24 to 33 */  /* Opcodes 24 to 33 */
437  #define INST_INCR_SCALAR1               24  #define INST_INCR_SCALAR1               24
438  #define INST_INCR_SCALAR_STK            25  #define INST_INCR_SCALAR_STK            25
439  #define INST_INCR_ARRAY1                26  #define INST_INCR_ARRAY1                26
440  #define INST_INCR_ARRAY_STK             27  #define INST_INCR_ARRAY_STK             27
441  #define INST_INCR_STK                   28  #define INST_INCR_STK                   28
442  #define INST_INCR_SCALAR1_IMM           29  #define INST_INCR_SCALAR1_IMM           29
443  #define INST_INCR_SCALAR_STK_IMM        30  #define INST_INCR_SCALAR_STK_IMM        30
444  #define INST_INCR_ARRAY1_IMM            31  #define INST_INCR_ARRAY1_IMM            31
445  #define INST_INCR_ARRAY_STK_IMM         32  #define INST_INCR_ARRAY_STK_IMM         32
446  #define INST_INCR_STK_IMM               33  #define INST_INCR_STK_IMM               33
447    
448  /* Opcodes 34 to 39 */  /* Opcodes 34 to 39 */
449  #define INST_JUMP1                      34  #define INST_JUMP1                      34
450  #define INST_JUMP4                      35  #define INST_JUMP4                      35
451  #define INST_JUMP_TRUE1                 36  #define INST_JUMP_TRUE1                 36
452  #define INST_JUMP_TRUE4                 37  #define INST_JUMP_TRUE4                 37
453  #define INST_JUMP_FALSE1                38  #define INST_JUMP_FALSE1                38
454  #define INST_JUMP_FALSE4                39  #define INST_JUMP_FALSE4                39
455    
456  /* Opcodes 40 to 64 */  /* Opcodes 40 to 64 */
457  #define INST_LOR                        40  #define INST_LOR                        40
458  #define INST_LAND                       41  #define INST_LAND                       41
459  #define INST_BITOR                      42  #define INST_BITOR                      42
460  #define INST_BITXOR                     43  #define INST_BITXOR                     43
461  #define INST_BITAND                     44  #define INST_BITAND                     44
462  #define INST_EQ                         45  #define INST_EQ                         45
463  #define INST_NEQ                        46  #define INST_NEQ                        46
464  #define INST_LT                         47  #define INST_LT                         47
465  #define INST_GT                         48  #define INST_GT                         48
466  #define INST_LE                         49  #define INST_LE                         49
467  #define INST_GE                         50  #define INST_GE                         50
468  #define INST_LSHIFT                     51  #define INST_LSHIFT                     51
469  #define INST_RSHIFT                     52  #define INST_RSHIFT                     52
470  #define INST_ADD                        53  #define INST_ADD                        53
471  #define INST_SUB                        54  #define INST_SUB                        54
472  #define INST_MULT                       55  #define INST_MULT                       55
473  #define INST_DIV                        56  #define INST_DIV                        56
474  #define INST_MOD                        57  #define INST_MOD                        57
475  #define INST_UPLUS                      58  #define INST_UPLUS                      58
476  #define INST_UMINUS                     59  #define INST_UMINUS                     59
477  #define INST_BITNOT                     60  #define INST_BITNOT                     60
478  #define INST_LNOT                       61  #define INST_LNOT                       61
479  #define INST_CALL_BUILTIN_FUNC1         62  #define INST_CALL_BUILTIN_FUNC1         62
480  #define INST_CALL_FUNC1                 63  #define INST_CALL_FUNC1                 63
481  #define INST_TRY_CVT_TO_NUMERIC         64  #define INST_TRY_CVT_TO_NUMERIC         64
482    
483  /* Opcodes 65 to 66 */  /* Opcodes 65 to 66 */
484  #define INST_BREAK                      65  #define INST_BREAK                      65
485  #define INST_CONTINUE                   66  #define INST_CONTINUE                   66
486    
487  /* Opcodes 67 to 68 */  /* Opcodes 67 to 68 */
488  #define INST_FOREACH_START4             67  #define INST_FOREACH_START4             67
489  #define INST_FOREACH_STEP4              68  #define INST_FOREACH_STEP4              68
490    
491  /* Opcodes 69 to 72 */  /* Opcodes 69 to 72 */
492  #define INST_BEGIN_CATCH4               69  #define INST_BEGIN_CATCH4               69
493  #define INST_END_CATCH                  70  #define INST_END_CATCH                  70
494  #define INST_PUSH_RESULT                71  #define INST_PUSH_RESULT                71
495  #define INST_PUSH_RETURN_CODE           72  #define INST_PUSH_RETURN_CODE           72
496    
497  /* The last opcode */  /* The last opcode */
498  #define LAST_INST_OPCODE                72  #define LAST_INST_OPCODE                72
499    
500  /*  /*
501   * Table describing the Tcl bytecode instructions: their name (for   * Table describing the Tcl bytecode instructions: their name (for
502   * displaying code), total number of code bytes required (including   * displaying code), total number of code bytes required (including
503   * operand bytes), and a description of the type of each operand.   * operand bytes), and a description of the type of each operand.
504   * These operand types include signed and unsigned integers of length   * These operand types include signed and unsigned integers of length
505   * one and four bytes. The unsigned integers are used for indexes or   * one and four bytes. The unsigned integers are used for indexes or
506   * for, e.g., the count of objects to push in a "push" instruction.   * for, e.g., the count of objects to push in a "push" instruction.
507   */   */
508    
509  #define MAX_INSTRUCTION_OPERANDS 2  #define MAX_INSTRUCTION_OPERANDS 2
510    
511  typedef enum InstOperandType {  typedef enum InstOperandType {
512      OPERAND_NONE,      OPERAND_NONE,
513      OPERAND_INT1,               /* One byte signed integer. */      OPERAND_INT1,               /* One byte signed integer. */
514      OPERAND_INT4,               /* Four byte signed integer. */      OPERAND_INT4,               /* Four byte signed integer. */
515      OPERAND_UINT1,              /* One byte unsigned integer. */      OPERAND_UINT1,              /* One byte unsigned integer. */
516      OPERAND_UINT4               /* Four byte unsigned integer. */      OPERAND_UINT4               /* Four byte unsigned integer. */
517  } InstOperandType;  } InstOperandType;
518    
519  typedef struct InstructionDesc {  typedef struct InstructionDesc {
520      char *name;                 /* Name of instruction. */      char *name;                 /* Name of instruction. */
521      int numBytes;               /* Total number of bytes for instruction. */      int numBytes;               /* Total number of bytes for instruction. */
522      int numOperands;            /* Number of operands. */      int numOperands;            /* Number of operands. */
523      InstOperandType opTypes[MAX_INSTRUCTION_OPERANDS];      InstOperandType opTypes[MAX_INSTRUCTION_OPERANDS];
524                                  /* The type of each operand. */                                  /* The type of each operand. */
525  } InstructionDesc;  } InstructionDesc;
526    
527  extern InstructionDesc instructionTable[];  extern InstructionDesc instructionTable[];
528    
529  /*  /*
530   * Definitions of the values of the INST_CALL_BUILTIN_FUNC instruction's   * Definitions of the values of the INST_CALL_BUILTIN_FUNC instruction's
531   * operand byte. Each value denotes a builtin Tcl math function. These   * operand byte. Each value denotes a builtin Tcl math function. These
532   * values must correspond to the entries in the builtinFuncTable array   * values must correspond to the entries in the builtinFuncTable array
533   * below and to the values stored in the tclInt.h MathFunc structure's   * below and to the values stored in the tclInt.h MathFunc structure's
534   * builtinFuncIndex field.   * builtinFuncIndex field.
535   */   */
536    
537  #define BUILTIN_FUNC_ACOS               0  #define BUILTIN_FUNC_ACOS               0
538  #define BUILTIN_FUNC_ASIN               1  #define BUILTIN_FUNC_ASIN               1
539  #define BUILTIN_FUNC_ATAN               2  #define BUILTIN_FUNC_ATAN               2
540  #define BUILTIN_FUNC_ATAN2              3  #define BUILTIN_FUNC_ATAN2              3
541  #define BUILTIN_FUNC_CEIL               4  #define BUILTIN_FUNC_CEIL               4
542  #define BUILTIN_FUNC_COS                5  #define BUILTIN_FUNC_COS                5
543  #define BUILTIN_FUNC_COSH               6  #define BUILTIN_FUNC_COSH               6
544  #define BUILTIN_FUNC_EXP                7  #define BUILTIN_FUNC_EXP                7
545  #define BUILTIN_FUNC_FLOOR              8  #define BUILTIN_FUNC_FLOOR              8
546  #define BUILTIN_FUNC_FMOD               9  #define BUILTIN_FUNC_FMOD               9
547  #define BUILTIN_FUNC_HYPOT              10  #define BUILTIN_FUNC_HYPOT              10
548  #define BUILTIN_FUNC_LOG                11  #define BUILTIN_FUNC_LOG                11
549  #define BUILTIN_FUNC_LOG10              12  #define BUILTIN_FUNC_LOG10              12
550  #define BUILTIN_FUNC_POW                13  #define BUILTIN_FUNC_POW                13
551  #define BUILTIN_FUNC_SIN                14  #define BUILTIN_FUNC_SIN                14
552  #define BUILTIN_FUNC_SINH               15  #define BUILTIN_FUNC_SINH               15
553  #define BUILTIN_FUNC_SQRT               16  #define BUILTIN_FUNC_SQRT               16
554  #define BUILTIN_FUNC_TAN                17  #define BUILTIN_FUNC_TAN                17
555  #define BUILTIN_FUNC_TANH               18  #define BUILTIN_FUNC_TANH               18
556  #define BUILTIN_FUNC_ABS                19  #define BUILTIN_FUNC_ABS                19
557  #define BUILTIN_FUNC_DOUBLE             20  #define BUILTIN_FUNC_DOUBLE             20
558  #define BUILTIN_FUNC_INT                21  #define BUILTIN_FUNC_INT                21
559  #define BUILTIN_FUNC_RAND               22  #define BUILTIN_FUNC_RAND               22
560  #define BUILTIN_FUNC_ROUND              23  #define BUILTIN_FUNC_ROUND              23
561  #define BUILTIN_FUNC_SRAND              24  #define BUILTIN_FUNC_SRAND              24
562    
563  #define LAST_BUILTIN_FUNC               24  #define LAST_BUILTIN_FUNC               24
564    
565  /*  /*
566   * Table describing the built-in math functions. Entries in this table are   * Table describing the built-in math functions. Entries in this table are
567   * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's   * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's
568   * operand byte.   * operand byte.
569   */   */
570    
571  typedef int (CallBuiltinFuncProc) _ANSI_ARGS_((Tcl_Interp *interp,  typedef int (CallBuiltinFuncProc) _ANSI_ARGS_((Tcl_Interp *interp,
572          ExecEnv *eePtr, ClientData clientData));          ExecEnv *eePtr, ClientData clientData));
573    
574  typedef struct {  typedef struct {
575      char *name;                 /* Name of function. */      char *name;                 /* Name of function. */
576      int numArgs;                /* Number of arguments for function. */      int numArgs;                /* Number of arguments for function. */
577      Tcl_ValueType argTypes[MAX_MATH_ARGS];      Tcl_ValueType argTypes[MAX_MATH_ARGS];
578                                  /* Acceptable types for each argument. */                                  /* Acceptable types for each argument. */
579      CallBuiltinFuncProc *proc;  /* Procedure implementing this function. */      CallBuiltinFuncProc *proc;  /* Procedure implementing this function. */
580      ClientData clientData;      /* Additional argument to pass to the      ClientData clientData;      /* Additional argument to pass to the
581                                   * function when invoking it. */                                   * function when invoking it. */
582  } BuiltinFunc;  } BuiltinFunc;
583    
584  extern BuiltinFunc builtinFuncTable[];  extern BuiltinFunc builtinFuncTable[];
585    
586  /*  /*
587   * Compilation of some Tcl constructs such as if commands and the logical or   * Compilation of some Tcl constructs such as if commands and the logical or
588   * (||) and logical and (&&) operators in expressions requires the   * (||) and logical and (&&) operators in expressions requires the
589   * generation of forward jumps. Since the PC target of these jumps isn't   * generation of forward jumps. Since the PC target of these jumps isn't
590   * known when the jumps are emitted, we record the offset of each jump in an   * known when the jumps are emitted, we record the offset of each jump in an
591   * array of JumpFixup structures. There is one array for each sequence of   * array of JumpFixup structures. There is one array for each sequence of
592   * jumps to one target PC. When we learn the target PC, we update the jumps   * jumps to one target PC. When we learn the target PC, we update the jumps
593   * with the correct distance. Also, if the distance is too great (> 127   * with the correct distance. Also, if the distance is too great (> 127
594   * bytes), we replace the single-byte jump with a four byte jump   * bytes), we replace the single-byte jump with a four byte jump
595   * instruction, move the instructions after the jump down, and update the   * instruction, move the instructions after the jump down, and update the
596   * code offsets for any commands between the jump and the target.   * code offsets for any commands between the jump and the target.
597   */   */
598    
599  typedef enum {  typedef enum {
600      TCL_UNCONDITIONAL_JUMP,      TCL_UNCONDITIONAL_JUMP,
601      TCL_TRUE_JUMP,      TCL_TRUE_JUMP,
602      TCL_FALSE_JUMP      TCL_FALSE_JUMP
603  } TclJumpType;  } TclJumpType;
604    
605  typedef struct JumpFixup {  typedef struct JumpFixup {
606      TclJumpType jumpType;       /* Indicates the kind of jump. */      TclJumpType jumpType;       /* Indicates the kind of jump. */
607      int codeOffset;             /* Offset of the first byte of the one-byte      int codeOffset;             /* Offset of the first byte of the one-byte
608                                   * forward jump's code. */                                   * forward jump's code. */
609      int cmdIndex;               /* Index of the first command after the one      int cmdIndex;               /* Index of the first command after the one
610                                   * for which the jump was emitted. Used to                                   * for which the jump was emitted. Used to
611                                   * update the code offsets for subsequent                                   * update the code offsets for subsequent
612                                   * commands if the two-byte jump at jumpPc                                   * commands if the two-byte jump at jumpPc
613                                   * must be replaced with a five-byte one. */                                   * must be replaced with a five-byte one. */
614      int exceptIndex;            /* Index of the first range entry in the      int exceptIndex;            /* Index of the first range entry in the
615                                   * ExceptionRange array after the current                                   * ExceptionRange array after the current
616                                   * one. This field is used to adjust the                                   * one. This field is used to adjust the
617                                   * code offsets in subsequent ExceptionRange                                   * code offsets in subsequent ExceptionRange
618                                   * records when a jump is grown from 2 bytes                                   * records when a jump is grown from 2 bytes
619                                   * to 5 bytes. */                                   * to 5 bytes. */
620  } JumpFixup;  } JumpFixup;
621    
622  #define JUMPFIXUP_INIT_ENTRIES    10  #define JUMPFIXUP_INIT_ENTRIES    10
623    
624  typedef struct JumpFixupArray {  typedef struct JumpFixupArray {
625      JumpFixup *fixup;           /* Points to start of jump fixup array. */      JumpFixup *fixup;           /* Points to start of jump fixup array. */
626      int next;                   /* Index of next free array entry. */      int next;                   /* Index of next free array entry. */
627      int end;                    /* Index of last usable entry in array. */      int end;                    /* Index of last usable entry in array. */
628      int mallocedArray;          /* 1 if array was expanded and fixups points      int mallocedArray;          /* 1 if array was expanded and fixups points
629                                   * into the heap, else 0. */                                   * into the heap, else 0. */
630      JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES];      JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES];
631                                  /* Initial storage for jump fixup array. */                                  /* Initial storage for jump fixup array. */
632  } JumpFixupArray;  } JumpFixupArray;
633    
634  /*  /*
635   * The structure describing one variable list of a foreach command. Note   * The structure describing one variable list of a foreach command. Note
636   * that only foreach commands inside procedure bodies are compiled inline so   * that only foreach commands inside procedure bodies are compiled inline so
637   * a ForeachVarList structure always describes local variables. Furthermore,   * a ForeachVarList structure always describes local variables. Furthermore,
638   * only scalar variables are supported for inline-compiled foreach loops.   * only scalar variables are supported for inline-compiled foreach loops.
639   */   */
640    
641  typedef struct ForeachVarList {  typedef struct ForeachVarList {
642      int numVars;                /* The number of variables in the list. */      int numVars;                /* The number of variables in the list. */
643      int varIndexes[1];          /* An array of the indexes ("slot numbers")      int varIndexes[1];          /* An array of the indexes ("slot numbers")
644                                   * for each variable in the procedure's                                   * for each variable in the procedure's
645                                   * array of local variables. Only scalar                                   * array of local variables. Only scalar
646                                   * variables are supported. The actual                                   * variables are supported. The actual
647                                   * size of this field will be large enough                                   * size of this field will be large enough
648                                   * to numVars indexes. THIS MUST BE THE                                   * to numVars indexes. THIS MUST BE THE
649                                   * LAST FIELD IN THE STRUCTURE! */                                   * LAST FIELD IN THE STRUCTURE! */
650  } ForeachVarList;  } ForeachVarList;
651    
652  /*  /*
653   * Structure used to hold information about a foreach command that is needed   * Structure used to hold information about a foreach command that is needed
654   * during program execution. These structures are stored in CompileEnv and   * during program execution. These structures are stored in CompileEnv and
655   * ByteCode structures as auxiliary data.   * ByteCode structures as auxiliary data.
656   */   */
657    
658  typedef struct ForeachInfo {  typedef struct ForeachInfo {
659      int numLists;               /* The number of both the variable and value      int numLists;               /* The number of both the variable and value
660                                   * lists of the foreach command. */                                   * lists of the foreach command. */
661      int firstValueTemp;         /* Index of the first temp var in a proc      int firstValueTemp;         /* Index of the first temp var in a proc
662                                   * frame used to point to a value list. */                                   * frame used to point to a value list. */
663      int loopCtTemp;             /* Index of temp var in a proc frame      int loopCtTemp;             /* Index of temp var in a proc frame
664                                   * holding the loop's iteration count. Used                                   * holding the loop's iteration count. Used
665                                   * to determine next value list element to                                   * to determine next value list element to
666                                   * assign each loop var. */                                   * assign each loop var. */
667      ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList      ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList
668                                   * structures describing each var list. The                                   * structures describing each var list. The
669                                   * actual size of this field will be large                                   * actual size of this field will be large
670                                   * enough to numVars indexes. THIS MUST BE                                   * enough to numVars indexes. THIS MUST BE
671                                   * THE LAST FIELD IN THE STRUCTURE! */                                   * THE LAST FIELD IN THE STRUCTURE! */
672  } ForeachInfo;  } ForeachInfo;
673    
674  extern AuxDataType              tclForeachInfoType;  extern AuxDataType              tclForeachInfoType;
675    
676  /*  /*
677   * Structure containing a cached pointer to a command that is the result   * Structure containing a cached pointer to a command that is the result
678   * of resolving the command's name in some namespace. It is the internal   * of resolving the command's name in some namespace. It is the internal
679   * representation for a cmdName object. It contains the pointer along   * representation for a cmdName object. It contains the pointer along
680   * with some information that is used to check the pointer's validity.   * with some information that is used to check the pointer's validity.
681   */   */
682    
683  typedef struct ResolvedCmdName {  typedef struct ResolvedCmdName {
684      Command *cmdPtr;            /* A cached Command pointer. */      Command *cmdPtr;            /* A cached Command pointer. */
685      Namespace *refNsPtr;        /* Points to the namespace containing the      Namespace *refNsPtr;        /* Points to the namespace containing the
686                                   * reference (not the namespace that                                   * reference (not the namespace that
687                                   * contains the referenced command). */                                   * contains the referenced command). */
688      long refNsId;               /* refNsPtr's unique namespace id. Used to      long refNsId;               /* refNsPtr's unique namespace id. Used to
689                                   * verify that refNsPtr is still valid                                   * verify that refNsPtr is still valid
690                                   * (e.g., it's possible that the cmd's                                   * (e.g., it's possible that the cmd's
691                                   * containing namespace was deleted and a                                   * containing namespace was deleted and a
692                                   * new one created at the same address). */                                   * new one created at the same address). */
693      int refNsCmdEpoch;          /* Value of the referencing namespace's      int refNsCmdEpoch;          /* Value of the referencing namespace's
694                                   * cmdRefEpoch when the pointer was cached.                                   * cmdRefEpoch when the pointer was cached.
695                                   * Before using the cached pointer, we check                                   * Before using the cached pointer, we check
696                                   * if the namespace's epoch was incremented;                                   * if the namespace's epoch was incremented;
697                                   * if so, this cached pointer is invalid. */                                   * if so, this cached pointer is invalid. */
698      int cmdEpoch;               /* Value of the command's cmdEpoch when this      int cmdEpoch;               /* Value of the command's cmdEpoch when this
699                                   * pointer was cached. Before using the                                   * pointer was cached. Before using the
700                                   * cached pointer, we check if the cmd's                                   * cached pointer, we check if the cmd's
701                                   * epoch was incremented; if so, the cmd was                                   * epoch was incremented; if so, the cmd was
702                                   * renamed, deleted, hidden, or exposed, and                                   * renamed, deleted, hidden, or exposed, and
703                                   * so the pointer is invalid. */                                   * so the pointer is invalid. */
704      int refCount;               /* Reference count: 1 for each cmdName      int refCount;               /* Reference count: 1 for each cmdName
705                                   * object that has a pointer to this                                   * object that has a pointer to this
706                                   * ResolvedCmdName structure as its internal                                   * ResolvedCmdName structure as its internal
707                                   * rep. This structure can be freed when                                   * rep. This structure can be freed when
708                                   * refCount becomes zero. */                                   * refCount becomes zero. */
709  } ResolvedCmdName;  } ResolvedCmdName;
710    
711  /*  /*
712   *----------------------------------------------------------------   *----------------------------------------------------------------
713   * Procedures shared among Tcl bytecode compilation and execution   * Procedures shared among Tcl bytecode compilation and execution
714   * modules but not used outside:   * modules but not used outside:
715   *----------------------------------------------------------------   *----------------------------------------------------------------
716   */   */
717    
718  EXTERN void             TclCleanupByteCode _ANSI_ARGS_((ByteCode *codePtr));  EXTERN void             TclCleanupByteCode _ANSI_ARGS_((ByteCode *codePtr));
719  EXTERN int              TclCompileCmdWord _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN int              TclCompileCmdWord _ANSI_ARGS_((Tcl_Interp *interp,
720                              Tcl_Token *tokenPtr, int count,                              Tcl_Token *tokenPtr, int count,
721                              CompileEnv *envPtr));                              CompileEnv *envPtr));
722  EXTERN int              TclCompileExpr _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN int              TclCompileExpr _ANSI_ARGS_((Tcl_Interp *interp,
723                              char *script, int numBytes,                              char *script, int numBytes,
724                              CompileEnv *envPtr));                              CompileEnv *envPtr));
725  EXTERN int              TclCompileExprWords _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN int              TclCompileExprWords _ANSI_ARGS_((Tcl_Interp *interp,
726                              Tcl_Token *tokenPtr, int numWords,                              Tcl_Token *tokenPtr, int numWords,
727                              CompileEnv *envPtr));                              CompileEnv *envPtr));
728  EXTERN int              TclCompileScript _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN int              TclCompileScript _ANSI_ARGS_((Tcl_Interp *interp,
729                              char *script, int numBytes, int nested,                              char *script, int numBytes, int nested,
730                              CompileEnv *envPtr));                              CompileEnv *envPtr));
731  EXTERN int              TclCompileTokens _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN int              TclCompileTokens _ANSI_ARGS_((Tcl_Interp *interp,
732                              Tcl_Token *tokenPtr, int count,                              Tcl_Token *tokenPtr, int count,
733                              CompileEnv *envPtr));                              CompileEnv *envPtr));
734  EXTERN int              TclCreateAuxData _ANSI_ARGS_((ClientData clientData,  EXTERN int              TclCreateAuxData _ANSI_ARGS_((ClientData clientData,
735                              AuxDataType *typePtr, CompileEnv *envPtr));                              AuxDataType *typePtr, CompileEnv *envPtr));
736  EXTERN int              TclCreateExceptRange _ANSI_ARGS_((  EXTERN int              TclCreateExceptRange _ANSI_ARGS_((
737                              ExceptionRangeType type, CompileEnv *envPtr));                              ExceptionRangeType type, CompileEnv *envPtr));
738  EXTERN ExecEnv *        TclCreateExecEnv _ANSI_ARGS_((Tcl_Interp *interp));  EXTERN ExecEnv *        TclCreateExecEnv _ANSI_ARGS_((Tcl_Interp *interp));
739  EXTERN void             TclDeleteExecEnv _ANSI_ARGS_((ExecEnv *eePtr));  EXTERN void             TclDeleteExecEnv _ANSI_ARGS_((ExecEnv *eePtr));
740  EXTERN void             TclDeleteLiteralTable _ANSI_ARGS_((  EXTERN void             TclDeleteLiteralTable _ANSI_ARGS_((
741                              Tcl_Interp *interp, LiteralTable *tablePtr));                              Tcl_Interp *interp, LiteralTable *tablePtr));
742  EXTERN void             TclEmitForwardJump _ANSI_ARGS_((CompileEnv *envPtr,  EXTERN void             TclEmitForwardJump _ANSI_ARGS_((CompileEnv *envPtr,
743                              TclJumpType jumpType, JumpFixup *jumpFixupPtr));                              TclJumpType jumpType, JumpFixup *jumpFixupPtr));
744  EXTERN ExceptionRange * TclGetExceptionRangeForPc _ANSI_ARGS_((  EXTERN ExceptionRange * TclGetExceptionRangeForPc _ANSI_ARGS_((
745                              unsigned char *pc, int catchOnly,                              unsigned char *pc, int catchOnly,
746                              ByteCode* codePtr));                              ByteCode* codePtr));
747  EXTERN InstructionDesc * TclGetInstructionTable _ANSI_ARGS_(());  EXTERN InstructionDesc * TclGetInstructionTable _ANSI_ARGS_(());
748  EXTERN int              TclExecuteByteCode _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN int              TclExecuteByteCode _ANSI_ARGS_((Tcl_Interp *interp,
749                              ByteCode *codePtr));                              ByteCode *codePtr));
750  EXTERN void             TclExpandCodeArray _ANSI_ARGS_((  EXTERN void             TclExpandCodeArray _ANSI_ARGS_((
751                              CompileEnv *envPtr));                              CompileEnv *envPtr));
752  EXTERN void             TclExpandJumpFixupArray _ANSI_ARGS_((  EXTERN void             TclExpandJumpFixupArray _ANSI_ARGS_((
753                              JumpFixupArray *fixupArrayPtr));                              JumpFixupArray *fixupArrayPtr));
754  EXTERN void             TclFinalizeAuxDataTypeTable _ANSI_ARGS_((void));  EXTERN void             TclFinalizeAuxDataTypeTable _ANSI_ARGS_((void));
755  EXTERN int              TclFindCompiledLocal _ANSI_ARGS_((char *name,  EXTERN int              TclFindCompiledLocal _ANSI_ARGS_((char *name,
756                              int nameChars, int create, int flags,                              int nameChars, int create, int flags,
757                              Proc *procPtr));                              Proc *procPtr));
758  EXTERN LiteralEntry *   TclLookupLiteralEntry _ANSI_ARGS_((  EXTERN LiteralEntry *   TclLookupLiteralEntry _ANSI_ARGS_((
759                              Tcl_Interp *interp, Tcl_Obj *objPtr));                              Tcl_Interp *interp, Tcl_Obj *objPtr));
760  EXTERN int              TclFixupForwardJump _ANSI_ARGS_((  EXTERN int              TclFixupForwardJump _ANSI_ARGS_((
761                              CompileEnv *envPtr, JumpFixup *jumpFixupPtr,                              CompileEnv *envPtr, JumpFixup *jumpFixupPtr,
762                              int jumpDist, int distThreshold));                              int jumpDist, int distThreshold));
763  EXTERN void             TclFreeCompileEnv _ANSI_ARGS_((CompileEnv *envPtr));  EXTERN void             TclFreeCompileEnv _ANSI_ARGS_((CompileEnv *envPtr));
764  EXTERN void             TclFreeJumpFixupArray _ANSI_ARGS_((  EXTERN void             TclFreeJumpFixupArray _ANSI_ARGS_((
765                              JumpFixupArray *fixupArrayPtr));                              JumpFixupArray *fixupArrayPtr));
766  EXTERN void             TclInitAuxDataTypeTable _ANSI_ARGS_((void));  EXTERN void             TclInitAuxDataTypeTable _ANSI_ARGS_((void));
767  EXTERN void             TclInitByteCodeObj _ANSI_ARGS_((Tcl_Obj *objPtr,  EXTERN void             TclInitByteCodeObj _ANSI_ARGS_((Tcl_Obj *objPtr,
768                              CompileEnv *envPtr));                              CompileEnv *envPtr));
769  EXTERN void             TclInitCompilation _ANSI_ARGS_((void));  EXTERN void             TclInitCompilation _ANSI_ARGS_((void));
770  EXTERN void             TclInitCompileEnv _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN void             TclInitCompileEnv _ANSI_ARGS_((Tcl_Interp *interp,
771                              CompileEnv *envPtr, char *string,                              CompileEnv *envPtr, char *string,
772                              int numBytes));                              int numBytes));
773  EXTERN void             TclInitJumpFixupArray _ANSI_ARGS_((  EXTERN void             TclInitJumpFixupArray _ANSI_ARGS_((
774                              JumpFixupArray *fixupArrayPtr));                              JumpFixupArray *fixupArrayPtr));
775  EXTERN void             TclInitLiteralTable _ANSI_ARGS_((  EXTERN void             TclInitLiteralTable _ANSI_ARGS_((
776                              LiteralTable *tablePtr));                              LiteralTable *tablePtr));
777  #ifdef TCL_COMPILE_STATS  #ifdef TCL_COMPILE_STATS
778  EXTERN char *           TclLiteralStats _ANSI_ARGS_((  EXTERN char *           TclLiteralStats _ANSI_ARGS_((
779                              LiteralTable *tablePtr));                              LiteralTable *tablePtr));
780  EXTERN int              TclLog2 _ANSI_ARGS_((int value));  EXTERN int              TclLog2 _ANSI_ARGS_((int value));
781  #endif  #endif
782  #ifdef TCL_COMPILE_DEBUG  #ifdef TCL_COMPILE_DEBUG
783  EXTERN void             TclPrintByteCodeObj _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN void             TclPrintByteCodeObj _ANSI_ARGS_((Tcl_Interp *interp,
784                              Tcl_Obj *objPtr));                              Tcl_Obj *objPtr));
785  #endif  #endif
786  EXTERN int              TclPrintInstruction _ANSI_ARGS_((ByteCode* codePtr,  EXTERN int              TclPrintInstruction _ANSI_ARGS_((ByteCode* codePtr,
787                              unsigned char *pc));                              unsigned char *pc));
788  EXTERN void             TclPrintObject _ANSI_ARGS_((FILE *outFile,  EXTERN void             TclPrintObject _ANSI_ARGS_((FILE *outFile,
789                              Tcl_Obj *objPtr, int maxChars));                              Tcl_Obj *objPtr, int maxChars));
790  EXTERN void             TclPrintSource _ANSI_ARGS_((FILE *outFile,  EXTERN void             TclPrintSource _ANSI_ARGS_((FILE *outFile,
791                              char *string, int maxChars));                              char *string, int maxChars));
792  EXTERN void             TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));  EXTERN void             TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
793  EXTERN int              TclRegisterLiteral _ANSI_ARGS_((CompileEnv *envPtr,  EXTERN int              TclRegisterLiteral _ANSI_ARGS_((CompileEnv *envPtr,
794                              char *bytes, int length, int onHeap));                              char *bytes, int length, int onHeap));
795  EXTERN void             TclReleaseLiteral _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN void             TclReleaseLiteral _ANSI_ARGS_((Tcl_Interp *interp,
796                              Tcl_Obj *objPtr));                              Tcl_Obj *objPtr));
797  EXTERN void             TclSetCmdNameObj _ANSI_ARGS_((Tcl_Interp *interp,  EXTERN void             TclSetCmdNameObj _ANSI_ARGS_((Tcl_Interp *interp,
798                              Tcl_Obj *objPtr, Command *cmdPtr));                              Tcl_Obj *objPtr, Command *cmdPtr));
799  #ifdef TCL_COMPILE_DEBUG  #ifdef TCL_COMPILE_DEBUG
800  EXTERN void             TclVerifyGlobalLiteralTable _ANSI_ARGS_((  EXTERN void             TclVerifyGlobalLiteralTable _ANSI_ARGS_((
801                              Interp *iPtr));                              Interp *iPtr));
802  EXTERN void             TclVerifyLocalLiteralTable _ANSI_ARGS_((  EXTERN void             TclVerifyLocalLiteralTable _ANSI_ARGS_((
803                              CompileEnv *envPtr));                              CompileEnv *envPtr));
804  #endif  #endif
805    
806  /*  /*
807   *----------------------------------------------------------------   *----------------------------------------------------------------
808   * Macros used by Tcl bytecode compilation and execution modules   * Macros used by Tcl bytecode compilation and execution modules
809   * inside the Tcl core but not used outside.   * inside the Tcl core but not used outside.
810   *----------------------------------------------------------------   *----------------------------------------------------------------
811   */   */
812    
813  /*  /*
814   * Macro to emit an opcode byte into a CompileEnv's code array.   * Macro to emit an opcode byte into a CompileEnv's code array.
815   * The ANSI C "prototype" for this macro is:   * The ANSI C "prototype" for this macro is:
816   *   *
817   * EXTERN void  TclEmitOpcode _ANSI_ARGS_((unsigned char op,   * EXTERN void  TclEmitOpcode _ANSI_ARGS_((unsigned char op,
818   *                  CompileEnv *envPtr));   *                  CompileEnv *envPtr));
819   */   */
820    
821  #define TclEmitOpcode(op, envPtr) \  #define TclEmitOpcode(op, envPtr) \
822      if ((envPtr)->codeNext == (envPtr)->codeEnd) \      if ((envPtr)->codeNext == (envPtr)->codeEnd) \
823          TclExpandCodeArray(envPtr); \          TclExpandCodeArray(envPtr); \
824      *(envPtr)->codeNext++ = (unsigned char) (op)      *(envPtr)->codeNext++ = (unsigned char) (op)
825    
826  /*  /*
827   * Macro to emit an integer operand.   * Macro to emit an integer operand.
828   * The ANSI C "prototype" for this macro is:   * The ANSI C "prototype" for this macro is:
829   *   *
830   * EXTERN void  TclEmitInt1 _ANSI_ARGS_((int i, CompileEnv *envPtr));   * EXTERN void  TclEmitInt1 _ANSI_ARGS_((int i, CompileEnv *envPtr));
831   */   */
832    
833  #define TclEmitInt1(i, envPtr) \  #define TclEmitInt1(i, envPtr) \
834      if ((envPtr)->codeNext == (envPtr)->codeEnd) \      if ((envPtr)->codeNext == (envPtr)->codeEnd) \
835          TclExpandCodeArray(envPtr); \          TclExpandCodeArray(envPtr); \
836      *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))      *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))
837    
838  /*  /*
839   * Macros to emit an instruction with signed or unsigned integer operands.   * Macros to emit an instruction with signed or unsigned integer operands.
840   * Four byte integers are stored in "big-endian" order with the high order   * Four byte integers are stored in "big-endian" order with the high order
841   * byte stored at the lowest address.   * byte stored at the lowest address.
842   * The ANSI C "prototypes" for these macros are:   * The ANSI C "prototypes" for these macros are:
843   *   *
844   * EXTERN void  TclEmitInstInt1 _ANSI_ARGS_((unsigned char op, int i,   * EXTERN void  TclEmitInstInt1 _ANSI_ARGS_((unsigned char op, int i,
845   *                  CompileEnv *envPtr));   *                  CompileEnv *envPtr));
846   * EXTERN void  TclEmitInstInt4 _ANSI_ARGS_((unsigned char op, int i,   * EXTERN void  TclEmitInstInt4 _ANSI_ARGS_((unsigned char op, int i,
847   *                  CompileEnv *envPtr));   *                  CompileEnv *envPtr));
848   */   */
849    
850  #define TclEmitInstInt1(op, i, envPtr) \  #define TclEmitInstInt1(op, i, envPtr) \
851      if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) { \      if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) { \
852          TclExpandCodeArray(envPtr); \          TclExpandCodeArray(envPtr); \
853      } \      } \
854      *(envPtr)->codeNext++ = (unsigned char) (op); \      *(envPtr)->codeNext++ = (unsigned char) (op); \
855      *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))      *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))
856    
857  #define TclEmitInstInt4(op, i, envPtr) \  #define TclEmitInstInt4(op, i, envPtr) \
858      if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \      if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \
859          TclExpandCodeArray(envPtr); \          TclExpandCodeArray(envPtr); \
860      } \      } \
861      *(envPtr)->codeNext++ = (unsigned char) (op); \      *(envPtr)->codeNext++ = (unsigned char) (op); \
862      *(envPtr)->codeNext++ = \      *(envPtr)->codeNext++ = \
863          (unsigned char) ((unsigned int) (i) >> 24); \          (unsigned char) ((unsigned int) (i) >> 24); \
864      *(envPtr)->codeNext++ = \      *(envPtr)->codeNext++ = \
865          (unsigned char) ((unsigned int) (i) >> 16); \          (unsigned char) ((unsigned int) (i) >> 16); \
866      *(envPtr)->codeNext++ = \      *(envPtr)->codeNext++ = \
867          (unsigned char) ((unsigned int) (i) >>  8); \          (unsigned char) ((unsigned int) (i) >>  8); \
868      *(envPtr)->codeNext++ = \      *(envPtr)->codeNext++ = \
869          (unsigned char) ((unsigned int) (i)      )          (unsigned char) ((unsigned int) (i)      )
870            
871  /*  /*
872   * Macro to push a Tcl object onto the Tcl evaluation stack. It emits the   * Macro to push a Tcl object onto the Tcl evaluation stack. It emits the
873   * object's one or four byte array index into the CompileEnv's code   * object's one or four byte array index into the CompileEnv's code
874   * array. These support, respectively, a maximum of 256 (2**8) and 2**32   * array. These support, respectively, a maximum of 256 (2**8) and 2**32
875   * objects in a CompileEnv. The ANSI C "prototype" for this macro is:   * objects in a CompileEnv. The ANSI C "prototype" for this macro is:
876   *   *
877   * EXTERN void  TclEmitPush _ANSI_ARGS_((int objIndex, CompileEnv *envPtr));   * EXTERN void  TclEmitPush _ANSI_ARGS_((int objIndex, CompileEnv *envPtr));
878   */   */
879    
880  #define TclEmitPush(objIndex, envPtr) \  #define TclEmitPush(objIndex, envPtr) \
881      if ((objIndex) <= 255) { \      if ((objIndex) <= 255) { \
882          TclEmitInstInt1(INST_PUSH1, (objIndex), (envPtr)); \          TclEmitInstInt1(INST_PUSH1, (objIndex), (envPtr)); \
883      } else { \      } else { \
884          TclEmitInstInt4(INST_PUSH4, (objIndex), (envPtr)); \          TclEmitInstInt4(INST_PUSH4, (objIndex), (envPtr)); \
885      }      }
886    
887  /*  /*
888   * Macros to update a (signed or unsigned) integer starting at a pointer.   * Macros to update a (signed or unsigned) integer starting at a pointer.
889   * The two variants depend on the number of bytes. The ANSI C "prototypes"   * The two variants depend on the number of bytes. The ANSI C "prototypes"
890   * for these macros are:   * for these macros are:
891   *   *
892   * EXTERN void  TclStoreInt1AtPtr _ANSI_ARGS_((int i, unsigned char *p));   * EXTERN void  TclStoreInt1AtPtr _ANSI_ARGS_((int i, unsigned char *p));
893   * EXTERN void  TclStoreInt4AtPtr _ANSI_ARGS_((int i, unsigned char *p));   * EXTERN void  TclStoreInt4AtPtr _ANSI_ARGS_((int i, unsigned char *p));
894   */   */
895            
896  #define TclStoreInt1AtPtr(i, p) \  #define TclStoreInt1AtPtr(i, p) \
897      *(p)   = (unsigned char) ((unsigned int) (i))      *(p)   = (unsigned char) ((unsigned int) (i))
898            
899  #define TclStoreInt4AtPtr(i, p) \  #define TclStoreInt4AtPtr(i, p) \
900      *(p)   = (unsigned char) ((unsigned int) (i) >> 24); \      *(p)   = (unsigned char) ((unsigned int) (i) >> 24); \
901      *(p+1) = (unsigned char) ((unsigned int) (i) >> 16); \      *(p+1) = (unsigned char) ((unsigned int) (i) >> 16); \
902      *(p+2) = (unsigned char) ((unsigned int) (i) >>  8); \      *(p+2) = (unsigned char) ((unsigned int) (i) >>  8); \
903      *(p+3) = (unsigned char) ((unsigned int) (i)      )      *(p+3) = (unsigned char) ((unsigned int) (i)      )
904    
905  /*  /*
906   * Macros to update instructions at a particular pc with a new op code   * Macros to update instructions at a particular pc with a new op code
907   * and a (signed or unsigned) int operand. The ANSI C "prototypes" for   * and a (signed or unsigned) int operand. The ANSI C "prototypes" for
908   * these macros are:   * these macros are:
909   *   *
910   * EXTERN void  TclUpdateInstInt1AtPc _ANSI_ARGS_((unsigned char op, int i,   * EXTERN void  TclUpdateInstInt1AtPc _ANSI_ARGS_((unsigned char op, int i,
911   *                  unsigned char *pc));   *                  unsigned char *pc));
912   * EXTERN void  TclUpdateInstInt4AtPc _ANSI_ARGS_((unsigned char op, int i,   * EXTERN void  TclUpdateInstInt4AtPc _ANSI_ARGS_((unsigned char op, int i,
913   *                  unsigned char *pc));   *                  unsigned char *pc));
914   */   */
915    
916  #define TclUpdateInstInt1AtPc(op, i, pc) \  #define TclUpdateInstInt1AtPc(op, i, pc) \
917      *(pc) = (unsigned char) (op); \      *(pc) = (unsigned char) (op); \
918      TclStoreInt1AtPtr((i), ((pc)+1))      TclStoreInt1AtPtr((i), ((pc)+1))
919    
920  #define TclUpdateInstInt4AtPc(op, i, pc) \  #define TclUpdateInstInt4AtPc(op, i, pc) \
921      *(pc) = (unsigned char) (op); \      *(pc) = (unsigned char) (op); \
922      TclStoreInt4AtPtr((i), ((pc)+1))      TclStoreInt4AtPtr((i), ((pc)+1))
923            
924  /*  /*
925   * Macros to get a signed integer (GET_INT{1,2}) or an unsigned int   * Macros to get a signed integer (GET_INT{1,2}) or an unsigned int
926   * (GET_UINT{1,2}) from a pointer. There are two variants for each   * (GET_UINT{1,2}) from a pointer. There are two variants for each
927   * return type that depend on the number of bytes fetched.   * return type that depend on the number of bytes fetched.
928   * The ANSI C "prototypes" for these macros are:   * The ANSI C "prototypes" for these macros are:
929   *   *
930   * EXTERN int           TclGetInt1AtPtr  _ANSI_ARGS_((unsigned char *p));   * EXTERN int           TclGetInt1AtPtr  _ANSI_ARGS_((unsigned char *p));
931   * EXTERN int           TclGetInt4AtPtr  _ANSI_ARGS_((unsigned char *p));   * EXTERN int           TclGetInt4AtPtr  _ANSI_ARGS_((unsigned char *p));
932   * EXTERN unsigned int  TclGetUInt1AtPtr _ANSI_ARGS_((unsigned char *p));   * EXTERN unsigned int  TclGetUInt1AtPtr _ANSI_ARGS_((unsigned char *p));
933   * EXTERN unsigned int  TclGetUInt4AtPtr _ANSI_ARGS_((unsigned char *p));   * EXTERN unsigned int  TclGetUInt4AtPtr _ANSI_ARGS_((unsigned char *p));
934   */   */
935    
936  /*  /*
937   * The TclGetInt1AtPtr macro is tricky because we want to do sign   * The TclGetInt1AtPtr macro is tricky because we want to do sign
938   * extension on the 1-byte value. Unfortunately the "char" type isn't   * extension on the 1-byte value. Unfortunately the "char" type isn't
939   * signed on all platforms so sign-extension doesn't always happen   * signed on all platforms so sign-extension doesn't always happen
940   * automatically. Sometimes we can explicitly declare the pointer to be   * automatically. Sometimes we can explicitly declare the pointer to be
941   * signed, but other times we have to explicitly sign-extend the value   * signed, but other times we have to explicitly sign-extend the value
942   * in software.   * in software.
943   */   */
944    
945  #ifndef __CHAR_UNSIGNED__  #ifndef __CHAR_UNSIGNED__
946  #   define TclGetInt1AtPtr(p) ((int) *((char *) p))  #   define TclGetInt1AtPtr(p) ((int) *((char *) p))
947  #else  #else
948  #   ifdef HAVE_SIGNED_CHAR  #   ifdef HAVE_SIGNED_CHAR
949  #       define TclGetInt1AtPtr(p) ((int) *((signed char *) p))  #       define TclGetInt1AtPtr(p) ((int) *((signed char *) p))
950  #    else  #    else
951  #       define TclGetInt1AtPtr(p) (((int) *((char *) p)) \  #       define TclGetInt1AtPtr(p) (((int) *((char *) p)) \
952                  | ((*(p) & 0200) ? (-256) : 0))                  | ((*(p) & 0200) ? (-256) : 0))
953  #    endif  #    endif
954  #endif  #endif
955    
956  #define TclGetInt4AtPtr(p) (((int) TclGetInt1AtPtr(p) << 24) | \  #define TclGetInt4AtPtr(p) (((int) TclGetInt1AtPtr(p) << 24) | \
957                                              (*((p)+1) << 16) | \                                              (*((p)+1) << 16) | \
958                                              (*((p)+2) <<  8) | \                                              (*((p)+2) <<  8) | \
959                                              (*((p)+3)))                                              (*((p)+3)))
960    
961  #define TclGetUInt1AtPtr(p) ((unsigned int) *(p))  #define TclGetUInt1AtPtr(p) ((unsigned int) *(p))
962  #define TclGetUInt4AtPtr(p) ((unsigned int) (*(p)     << 24) | \  #define TclGetUInt4AtPtr(p) ((unsigned int) (*(p)     << 24) | \
963                                              (*((p)+1) << 16) | \                                              (*((p)+1) << 16) | \
964                                              (*((p)+2) <<  8) | \                                              (*((p)+2) <<  8) | \
965                                              (*((p)+3)))                                              (*((p)+3)))
966    
967  /*  /*
968   * Macros used to compute the minimum and maximum of two integers.   * Macros used to compute the minimum and maximum of two integers.
969   * The ANSI C "prototypes" for these macros are:   * The ANSI C "prototypes" for these macros are:
970   *   *
971   * EXTERN int  TclMin _ANSI_ARGS_((int i, int j));   * EXTERN int  TclMin _ANSI_ARGS_((int i, int j));
972   * EXTERN int  TclMax _ANSI_ARGS_((int i, int j));   * EXTERN int  TclMax _ANSI_ARGS_((int i, int j));
973   */   */
974    
975  #define TclMin(i, j)   ((((int) i) < ((int) j))? (i) : (j))  #define TclMin(i, j)   ((((int) i) < ((int) j))? (i) : (j))
976  #define TclMax(i, j)   ((((int) i) > ((int) j))? (i) : (j))  #define TclMax(i, j)   ((((int) i) > ((int) j))? (i) : (j))
977    
978  # undef TCL_STORAGE_CLASS  # undef TCL_STORAGE_CLASS
979  # define TCL_STORAGE_CLASS DLLIMPORT  # define TCL_STORAGE_CLASS DLLIMPORT
980    
981  #endif /* _TCLCOMPILATION */  #endif /* _TCLCOMPILATION */
982    
983  /* End of tclcompile.h */  /* End of tclcompile.h */

Legend:
Removed from v.64  
changed lines
  Added in v.98

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25