tclCompile.h

Go to the documentation of this file.
00001 /*
00002  * tclCompile.h --
00003  *
00004  * Copyright (c) 1996-1998 Sun Microsystems, Inc.
00005  * Copyright (c) 1998-2000 by Scriptics Corporation.
00006  * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
00007  * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
00008  *
00009  * See the file "license.terms" for information on usage and redistribution of
00010  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
00011  *
00012  * RCS: @(#) $Id: tclCompile.h,v 1.89 2008/01/23 17:31:42 dgp Exp $
00013  */
00014 
00015 #ifndef _TCLCOMPILATION
00016 #define _TCLCOMPILATION 1
00017 
00018 #include "tclInt.h"
00019 
00020 struct ByteCode;                /* Forward declaration. */
00021 
00022 /*
00023  *------------------------------------------------------------------------
00024  * Variables related to compilation. These are used in tclCompile.c,
00025  * tclExecute.c, tclBasic.c, and their clients.
00026  *------------------------------------------------------------------------
00027  */
00028 
00029 #ifdef TCL_COMPILE_DEBUG
00030 /*
00031  * Variable that controls whether compilation tracing is enabled and, if so,
00032  * what level of tracing is desired:
00033  *    0: no compilation tracing
00034  *    1: summarize compilation of top level cmds and proc bodies
00035  *    2: display all instructions of each ByteCode compiled
00036  * This variable is linked to the Tcl variable "tcl_traceCompile".
00037  */
00038 
00039 MODULE_SCOPE int        tclTraceCompile;
00040 
00041 /*
00042  * Variable that controls whether execution tracing is enabled and, if so,
00043  * what level of tracing is desired:
00044  *    0: no execution tracing
00045  *    1: trace invocations of Tcl procs only
00046  *    2: trace invocations of all (not compiled away) commands
00047  *    3: display each instruction executed
00048  * This variable is linked to the Tcl variable "tcl_traceExec".
00049  */
00050 
00051 MODULE_SCOPE int        tclTraceExec;
00052 #endif
00053 
00054 /*
00055  *------------------------------------------------------------------------
00056  * Data structures related to compilation.
00057  *------------------------------------------------------------------------
00058  */
00059 
00060 /*
00061  * The structure used to implement Tcl "exceptions" (exceptional returns): for
00062  * example, those generated in loops by the break and continue commands, and
00063  * those generated by scripts and caught by the catch command. This
00064  * ExceptionRange structure describes a range of code (e.g., a loop body), the
00065  * kind of exceptions (e.g., a break or continue) that might occur, and the PC
00066  * offsets to jump to if a matching exception does occur. Exception ranges can
00067  * nest so this structure includes a nesting level that is used at runtime to
00068  * find the closest exception range surrounding a PC. For example, when a
00069  * break command is executed, the ExceptionRange structure for the most deeply
00070  * nested loop, if any, is found and used. These structures are also generated
00071  * for the "next" subcommands of for loops since a break there terminates the
00072  * for command. This means a for command actually generates two LoopInfo
00073  * structures.
00074  */
00075 
00076 typedef enum {
00077     LOOP_EXCEPTION_RANGE,       /* Exception's range is part of a loop. Break
00078                                  * and continue "exceptions" cause jumps to
00079                                  * appropriate PC offsets. */
00080     CATCH_EXCEPTION_RANGE       /* Exception's range is controlled by a catch
00081                                  * command. Errors in the range cause a jump
00082                                  * to a catch PC offset. */
00083 } ExceptionRangeType;
00084 
00085 typedef struct ExceptionRange {
00086     ExceptionRangeType type;    /* The kind of ExceptionRange. */
00087     int nestingLevel;           /* Static depth of the exception range. Used
00088                                  * to find the most deeply-nested range
00089                                  * surrounding a PC at runtime. */
00090     int codeOffset;             /* Offset of the first instruction byte of the
00091                                  * code range. */
00092     int numCodeBytes;           /* Number of bytes in the code range. */
00093     int breakOffset;            /* If LOOP_EXCEPTION_RANGE, the target PC
00094                                  * offset for a break command in the range. */
00095     int continueOffset;         /* If LOOP_EXCEPTION_RANGE and not -1, the
00096                                  * target PC offset for a continue command in
00097                                  * the code range. Otherwise, ignore this
00098                                  * range when processing a continue
00099                                  * command. */
00100     int catchOffset;            /* If a CATCH_EXCEPTION_RANGE, the target PC
00101                                  * offset for any "exception" in range. */
00102 } ExceptionRange;
00103 
00104 /*
00105  * Structure used to map between instruction pc and source locations. It
00106  * defines for each compiled Tcl command its code's starting offset and its
00107  * source's starting offset and length. Note that the code offset increases
00108  * monotonically: that is, the table is sorted in code offset order. The
00109  * source offset is not monotonic.
00110  */
00111 
00112 typedef struct CmdLocation {
00113     int codeOffset;             /* Offset of first byte of command code. */
00114     int numCodeBytes;           /* Number of bytes for command's code. */
00115     int srcOffset;              /* Offset of first char of the command. */
00116     int numSrcBytes;            /* Number of command source chars. */
00117 } CmdLocation;
00118 
00119 /*
00120  * TIP #280
00121  * Structure to record additional location information for byte code. This
00122  * information is internal and not saved. i.e. tbcload'ed code will not have
00123  * this information. It records the lines for all words of all commands found
00124  * in the byte code. The association with a ByteCode structure BC is done
00125  * through the 'lineBCPtr' HashTable in Interp, keyed by the address of BC.
00126  * Also recorded is information coming from the context, i.e. type of the
00127  * frame and associated information, like the path of a sourced file.
00128  */
00129 
00130 typedef struct ECL {
00131     int srcOffset;              /* Command location to find the entry. */
00132     int nline;
00133     int *line;                  /* Line information for all words in the
00134                                  * command. */
00135 } ECL;
00136 
00137 typedef struct ExtCmdLoc {
00138     int type;                   /* Context type. */
00139     Tcl_Obj *path;              /* Path of the sourced file the command is
00140                                  * in. */
00141     ECL *loc;                   /* Command word locations (lines). */
00142     int nloc;                   /* Number of allocated entries in 'loc'. */
00143     int nuloc;                  /* Number of used entries in 'loc'. */
00144 } ExtCmdLoc;
00145 
00146 /*
00147  * CompileProcs need the ability to record information during compilation that
00148  * can be used by bytecode instructions during execution. The AuxData
00149  * structure provides this "auxiliary data" mechanism. An arbitrary number of
00150  * these structures can be stored in the ByteCode record (during compilation
00151  * they are stored in a CompileEnv structure). Each AuxData record holds one
00152  * word of client-specified data (often a pointer) and is given an index that
00153  * instructions can later use to look up the structure and its data.
00154  *
00155  * The following definitions declare the types of procedures that are called
00156  * to duplicate or free this auxiliary data when the containing ByteCode
00157  * objects are duplicated and freed. Pointers to these procedures are kept in
00158  * the AuxData structure.
00159  */
00160 
00161 typedef ClientData (AuxDataDupProc)  (ClientData clientData);
00162 typedef void       (AuxDataFreeProc) (ClientData clientData);
00163 typedef void       (AuxDataPrintProc)(ClientData clientData,
00164                             Tcl_Obj *appendObj, struct ByteCode *codePtr,
00165                             unsigned int pcOffset);
00166 
00167 /*
00168  * We define a separate AuxDataType struct to hold type-related information
00169  * for the AuxData structure. This separation makes it possible for clients
00170  * outside of the TCL core to manipulate (in a limited fashion!) AuxData; for
00171  * example, it makes it possible to pickle and unpickle AuxData structs.
00172  */
00173 
00174 typedef struct AuxDataType {
00175     char *name;                 /* The name of the type. Types can be
00176                                  * registered and found by name */
00177     AuxDataDupProc *dupProc;    /* Callback procedure to invoke when the aux
00178                                  * data is duplicated (e.g., when the ByteCode
00179                                  * structure containing the aux data is
00180                                  * duplicated). NULL means just copy the
00181                                  * source clientData bits; no proc need be
00182                                  * called. */
00183     AuxDataFreeProc *freeProc;  /* Callback procedure to invoke when the aux
00184                                  * data is freed. NULL means no proc need be
00185                                  * called. */
00186     AuxDataPrintProc *printProc;/* Callback function to invoke when printing
00187                                  * the aux data as part of debugging. NULL
00188                                  * means that the data can't be printed. */
00189 } AuxDataType;
00190 
00191 /*
00192  * The definition of the AuxData structure that holds information created
00193  * during compilation by CompileProcs and used by instructions during
00194  * execution.
00195  */
00196 
00197 typedef struct AuxData {
00198     AuxDataType *type;          /* Pointer to the AuxData type associated with
00199                                  * this ClientData. */
00200     ClientData clientData;      /* The compilation data itself. */
00201 } AuxData;
00202 
00203 /*
00204  * Structure defining the compilation environment. After compilation, fields
00205  * describing bytecode instructions are copied out into the more compact
00206  * ByteCode structure defined below.
00207  */
00208 
00209 #define COMPILEENV_INIT_CODE_BYTES    250
00210 #define COMPILEENV_INIT_NUM_OBJECTS    60
00211 #define COMPILEENV_INIT_EXCEPT_RANGES   5
00212 #define COMPILEENV_INIT_CMD_MAP_SIZE   40
00213 #define COMPILEENV_INIT_AUX_DATA_SIZE   5
00214 
00215 typedef struct CompileEnv {
00216     Interp *iPtr;               /* Interpreter containing the code being
00217                                  * compiled. Commands and their compile procs
00218                                  * are specific to an interpreter so the code
00219                                  * emitted will depend on the interpreter. */
00220     const char *source;         /* The source string being compiled by
00221                                  * SetByteCodeFromAny. This pointer is not
00222                                  * owned by the CompileEnv and must not be
00223                                  * freed or changed by it. */
00224     int numSrcBytes;            /* Number of bytes in source. */
00225     Proc *procPtr;              /* If a procedure is being compiled, a pointer
00226                                  * to its Proc structure; otherwise NULL. Used
00227                                  * to compile local variables. Set from
00228                                  * information provided by ObjInterpProc in
00229                                  * tclProc.c. */
00230     int numCommands;            /* Number of commands compiled. */
00231     int exceptDepth;            /* Current exception range nesting level; -1
00232                                  * if not in any range currently. */
00233     int maxExceptDepth;         /* Max nesting level of exception ranges; -1
00234                                  * if no ranges have been compiled. */
00235     int maxStackDepth;          /* Maximum number of stack elements needed to
00236                                  * execute the code. Set by compilation
00237                                  * procedures before returning. */
00238     int currStackDepth;         /* Current stack depth. */
00239     LiteralTable localLitTable; /* Contains LiteralEntry's describing all Tcl
00240                                  * objects referenced by this compiled code.
00241                                  * Indexed by the string representations of
00242                                  * the literals. Used to avoid creating
00243                                  * duplicate objects. */
00244     unsigned char *codeStart;   /* Points to the first byte of the code. */
00245     unsigned char *codeNext;    /* Points to next code array byte to use. */
00246     unsigned char *codeEnd;     /* Points just after the last allocated code
00247                                  * array byte. */
00248     int mallocedCodeArray;      /* Set 1 if code array was expanded and
00249                                  * codeStart points into the heap.*/
00250     LiteralEntry *literalArrayPtr;
00251                                 /* Points to start of LiteralEntry array. */
00252     int literalArrayNext;       /* Index of next free object array entry. */
00253     int literalArrayEnd;        /* Index just after last obj array entry. */
00254     int mallocedLiteralArray;   /* 1 if object array was expanded and objArray
00255                                  * points into the heap, else 0. */
00256     ExceptionRange *exceptArrayPtr;
00257                                 /* Points to start of the ExceptionRange
00258                                  * array. */
00259     int exceptArrayNext;        /* Next free ExceptionRange array index.
00260                                  * exceptArrayNext is the number of ranges and
00261                                  * (exceptArrayNext-1) is the index of the
00262                                  * current range's array entry. */
00263     int exceptArrayEnd;         /* Index after the last ExceptionRange array
00264                                  * entry. */
00265     int mallocedExceptArray;    /* 1 if ExceptionRange array was expanded and
00266                                  * exceptArrayPtr points in heap, else 0. */
00267     CmdLocation *cmdMapPtr;     /* Points to start of CmdLocation array.
00268                                  * numCommands is the index of the next entry
00269                                  * to use; (numCommands-1) is the entry index
00270                                  * for the last command. */
00271     int cmdMapEnd;              /* Index after last CmdLocation entry. */
00272     int mallocedCmdMap;         /* 1 if command map array was expanded and
00273                                  * cmdMapPtr points in the heap, else 0. */
00274     AuxData *auxDataArrayPtr;   /* Points to auxiliary data array start. */
00275     int auxDataArrayNext;       /* Next free compile aux data array index.
00276                                  * auxDataArrayNext is the number of aux data
00277                                  * items and (auxDataArrayNext-1) is index of
00278                                  * current aux data array entry. */
00279     int auxDataArrayEnd;        /* Index after last aux data array entry. */
00280     int mallocedAuxDataArray;   /* 1 if aux data array was expanded and
00281                                  * auxDataArrayPtr points in heap else 0. */
00282     unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES];
00283                                 /* Initial storage for code. */
00284     LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS];
00285                                 /* Initial storage of LiteralEntry array. */
00286     ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
00287                                 /* Initial ExceptionRange array storage. */
00288     CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
00289                                 /* Initial storage for cmd location map. */
00290     AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
00291                                 /* Initial storage for aux data array. */
00292     /* TIP #280 */
00293     ExtCmdLoc *extCmdMapPtr;    /* Extended command location information for
00294                                  * 'info frame'. */
00295     int line;                   /* First line of the script, based on the
00296                                  * invoking context, then the line of the
00297                                  * command currently compiled. */
00298     int atCmdStart;             /* Flag to say whether an INST_START_CMD
00299                                  * should be issued; they should never be
00300                                  * issued repeatedly, as that is significantly
00301                                  * inefficient. */
00302 } CompileEnv;
00303 
00304 /*
00305  * The structure defining the bytecode instructions resulting from compiling a
00306  * Tcl script. Note that this structure is variable length: a single heap
00307  * object is allocated to hold the ByteCode structure immediately followed by
00308  * the code bytes, the literal object array, the ExceptionRange array, the
00309  * CmdLocation map, and the compilation AuxData array.
00310  */
00311 
00312 /*
00313  * A PRECOMPILED bytecode struct is one that was generated from a compiled
00314  * image rather than implicitly compiled from source
00315  */
00316 
00317 #define TCL_BYTECODE_PRECOMPILED                0x0001
00318 
00319 /*
00320  * When a bytecode is compiled, interp or namespace resolvers have not been
00321  * applied yet: this is indicated by the TCL_BYTECODE_RESOLVE_VARS flag.
00322  */
00323 
00324 #define TCL_BYTECODE_RESOLVE_VARS               0x0002
00325 
00326 typedef struct ByteCode {
00327     TclHandle interpHandle;     /* Handle for interpreter containing the
00328                                  * compiled code. Commands and their compile
00329                                  * procs are specific to an interpreter so the
00330                                  * code emitted will depend on the
00331                                  * interpreter. */
00332     int compileEpoch;           /* Value of iPtr->compileEpoch when this
00333                                  * ByteCode was compiled. Used to invalidate
00334                                  * code when, e.g., commands with compile
00335                                  * procs are redefined. */
00336     Namespace *nsPtr;           /* Namespace context in which this code was
00337                                  * compiled. If the code is executed if a
00338                                  * different namespace, it must be
00339                                  * recompiled. */
00340     int nsEpoch;                /* Value of nsPtr->resolverEpoch when this
00341                                  * ByteCode was compiled. Used to invalidate
00342                                  * code when new namespace resolution rules
00343                                  * are put into effect. */
00344     int refCount;               /* Reference count: set 1 when created plus 1
00345                                  * for each execution of the code currently
00346                                  * active. This structure can be freed when
00347                                  * refCount becomes zero. */
00348     unsigned int flags;         /* flags describing state for the codebyte.
00349                                  * this variable holds ORed values from the
00350                                  * TCL_BYTECODE_ masks defined above */
00351     const char *source;         /* The source string from which this ByteCode
00352                                  * was compiled. Note that this pointer is not
00353                                  * owned by the ByteCode and must not be freed
00354                                  * or modified by it. */
00355     Proc *procPtr;              /* If the ByteCode was compiled from a
00356                                  * procedure body, this is a pointer to its
00357                                  * Proc structure; otherwise NULL. This
00358                                  * pointer is also not owned by the ByteCode
00359                                  * and must not be freed by it. */
00360     size_t structureSize;       /* Number of bytes in the ByteCode structure
00361                                  * itself. Does not include heap space for
00362                                  * literal Tcl objects or storage referenced
00363                                  * by AuxData entries. */
00364     int numCommands;            /* Number of commands compiled. */
00365     int numSrcBytes;            /* Number of source bytes compiled. */
00366     int numCodeBytes;           /* Number of code bytes. */
00367     int numLitObjects;          /* Number of objects in literal array. */
00368     int numExceptRanges;        /* Number of ExceptionRange array elems. */
00369     int numAuxDataItems;        /* Number of AuxData items. */
00370     int numCmdLocBytes;         /* Number of bytes needed for encoded command
00371                                  * location information. */
00372     int maxExceptDepth;         /* Maximum nesting level of ExceptionRanges;
00373                                  * -1 if no ranges were compiled. */
00374     int maxStackDepth;          /* Maximum number of stack elements needed to
00375                                  * execute the code. */
00376     unsigned char *codeStart;   /* Points to the first byte of the code. This
00377                                  * is just after the final ByteCode member
00378                                  * cmdMapPtr. */
00379     Tcl_Obj **objArrayPtr;      /* Points to the start of the literal object
00380                                  * array. This is just after the last code
00381                                  * byte. */
00382     ExceptionRange *exceptArrayPtr;
00383                                 /* Points to the start of the ExceptionRange
00384                                  * array. This is just after the last object
00385                                  * in the object array. */
00386     AuxData *auxDataArrayPtr;   /* Points to the start of the auxiliary data
00387                                  * array. This is just after the last entry in
00388                                  * the ExceptionRange array. */
00389     unsigned char *codeDeltaStart;
00390                                 /* Points to the first of a sequence of bytes
00391                                  * that encode the change in the starting
00392                                  * offset of each command's code. If -127 <=
00393                                  * delta <= 127, it is encoded as 1 byte,
00394                                  * otherwise 0xFF (128) appears and the delta
00395                                  * is encoded by the next 4 bytes. Code deltas
00396                                  * are always positive. This sequence is just
00397                                  * after the last entry in the AuxData
00398                                  * array. */
00399     unsigned char *codeLengthStart;
00400                                 /* Points to the first of a sequence of bytes
00401                                  * that encode the length of each command's
00402                                  * code. The encoding is the same as for code
00403                                  * deltas. Code lengths are always positive.
00404                                  * This sequence is just after the last entry
00405                                  * in the code delta sequence. */
00406     unsigned char *srcDeltaStart;
00407                                 /* Points to the first of a sequence of bytes
00408                                  * that encode the change in the starting
00409                                  * offset of each command's source. The
00410                                  * encoding is the same as for code deltas.
00411                                  * Source deltas can be negative. This
00412                                  * sequence is just after the last byte in the
00413                                  * code length sequence. */
00414     unsigned char *srcLengthStart;
00415                                 /* Points to the first of a sequence of bytes
00416                                  * that encode the length of each command's
00417                                  * source. The encoding is the same as for
00418                                  * code deltas. Source lengths are always
00419                                  * positive. This sequence is just after the
00420                                  * last byte in the source delta sequence. */
00421     LocalCache *localCachePtr;  /* Pointer to the start of the cached variable
00422                                  * names and initialisation data for local
00423                                  * variables. */
00424 #ifdef TCL_COMPILE_STATS
00425     Tcl_Time createTime;        /* Absolute time when the ByteCode was
00426                                  * created. */
00427 #endif /* TCL_COMPILE_STATS */
00428 } ByteCode;
00429 
00430 /*
00431  * Opcodes for the Tcl bytecode instructions. These must correspond to the
00432  * entries in the table of instruction descriptions, tclInstructionTable, in
00433  * tclCompile.c. Also, the order and number of the expression opcodes (e.g.,
00434  * INST_LOR) must match the entries in the array operatorStrings in
00435  * tclExecute.c.
00436  */
00437 
00438 /* Opcodes 0 to 9 */
00439 #define INST_DONE                       0
00440 #define INST_PUSH1                      1
00441 #define INST_PUSH4                      2
00442 #define INST_POP                        3
00443 #define INST_DUP                        4
00444 #define INST_CONCAT1                    5
00445 #define INST_INVOKE_STK1                6
00446 #define INST_INVOKE_STK4                7
00447 #define INST_EVAL_STK                   8
00448 #define INST_EXPR_STK                   9
00449 
00450 /* Opcodes 10 to 23 */
00451 #define INST_LOAD_SCALAR1               10
00452 #define INST_LOAD_SCALAR4               11
00453 #define INST_LOAD_SCALAR_STK            12
00454 #define INST_LOAD_ARRAY1                13
00455 #define INST_LOAD_ARRAY4                14
00456 #define INST_LOAD_ARRAY_STK             15
00457 #define INST_LOAD_STK                   16
00458 #define INST_STORE_SCALAR1              17
00459 #define INST_STORE_SCALAR4              18
00460 #define INST_STORE_SCALAR_STK           19
00461 #define INST_STORE_ARRAY1               20
00462 #define INST_STORE_ARRAY4               21
00463 #define INST_STORE_ARRAY_STK            22
00464 #define INST_STORE_STK                  23
00465 
00466 /* Opcodes 24 to 33 */
00467 #define INST_INCR_SCALAR1               24
00468 #define INST_INCR_SCALAR_STK            25
00469 #define INST_INCR_ARRAY1                26
00470 #define INST_INCR_ARRAY_STK             27
00471 #define INST_INCR_STK                   28
00472 #define INST_INCR_SCALAR1_IMM           29
00473 #define INST_INCR_SCALAR_STK_IMM        30
00474 #define INST_INCR_ARRAY1_IMM            31
00475 #define INST_INCR_ARRAY_STK_IMM         32
00476 #define INST_INCR_STK_IMM               33
00477 
00478 /* Opcodes 34 to 39 */
00479 #define INST_JUMP1                      34
00480 #define INST_JUMP4                      35
00481 #define INST_JUMP_TRUE1                 36
00482 #define INST_JUMP_TRUE4                 37
00483 #define INST_JUMP_FALSE1                38
00484 #define INST_JUMP_FALSE4                39
00485 
00486 /* Opcodes 40 to 64 */
00487 #define INST_LOR                        40
00488 #define INST_LAND                       41
00489 #define INST_BITOR                      42
00490 #define INST_BITXOR                     43
00491 #define INST_BITAND                     44
00492 #define INST_EQ                         45
00493 #define INST_NEQ                        46
00494 #define INST_LT                         47
00495 #define INST_GT                         48
00496 #define INST_LE                         49
00497 #define INST_GE                         50
00498 #define INST_LSHIFT                     51
00499 #define INST_RSHIFT                     52
00500 #define INST_ADD                        53
00501 #define INST_SUB                        54
00502 #define INST_MULT                       55
00503 #define INST_DIV                        56
00504 #define INST_MOD                        57
00505 #define INST_UPLUS                      58
00506 #define INST_UMINUS                     59
00507 #define INST_BITNOT                     60
00508 #define INST_LNOT                       61
00509 #define INST_CALL_BUILTIN_FUNC1         62
00510 #define INST_CALL_FUNC1                 63
00511 #define INST_TRY_CVT_TO_NUMERIC         64
00512 
00513 /* Opcodes 65 to 66 */
00514 #define INST_BREAK                      65
00515 #define INST_CONTINUE                   66
00516 
00517 /* Opcodes 67 to 68 */
00518 #define INST_FOREACH_START4             67
00519 #define INST_FOREACH_STEP4              68
00520 
00521 /* Opcodes 69 to 72 */
00522 #define INST_BEGIN_CATCH4               69
00523 #define INST_END_CATCH                  70
00524 #define INST_PUSH_RESULT                71
00525 #define INST_PUSH_RETURN_CODE           72
00526 
00527 /* Opcodes 73 to 78 */
00528 #define INST_STR_EQ                     73
00529 #define INST_STR_NEQ                    74
00530 #define INST_STR_CMP                    75
00531 #define INST_STR_LEN                    76
00532 #define INST_STR_INDEX                  77
00533 #define INST_STR_MATCH                  78
00534 
00535 /* Opcodes 78 to 81 */
00536 #define INST_LIST                       79
00537 #define INST_LIST_INDEX                 80
00538 #define INST_LIST_LENGTH                81
00539 
00540 /* Opcodes 82 to 87 */
00541 #define INST_APPEND_SCALAR1             82
00542 #define INST_APPEND_SCALAR4             83
00543 #define INST_APPEND_ARRAY1              84
00544 #define INST_APPEND_ARRAY4              85
00545 #define INST_APPEND_ARRAY_STK           86
00546 #define INST_APPEND_STK                 87
00547 
00548 /* Opcodes 88 to 93 */
00549 #define INST_LAPPEND_SCALAR1            88
00550 #define INST_LAPPEND_SCALAR4            89
00551 #define INST_LAPPEND_ARRAY1             90
00552 #define INST_LAPPEND_ARRAY4             91
00553 #define INST_LAPPEND_ARRAY_STK          92
00554 #define INST_LAPPEND_STK                93
00555 
00556 /* TIP #22 - LINDEX operator with flat arg list */
00557 
00558 #define INST_LIST_INDEX_MULTI           94
00559 
00560 /*
00561  * TIP #33 - 'lset' command. Code gen also required a Forth-like
00562  *           OVER operation.
00563  */
00564 
00565 #define INST_OVER                       95
00566 #define INST_LSET_LIST                  96
00567 #define INST_LSET_FLAT                  97
00568 
00569 /* TIP#90 - 'return' command. */
00570 
00571 #define INST_RETURN_IMM                 98
00572 
00573 /* TIP#123 - exponentiation operator. */
00574 
00575 #define INST_EXPON                      99
00576 
00577 /* TIP #157 - {*}... (word expansion) language syntax support. */
00578 
00579 #define INST_EXPAND_START               100
00580 #define INST_EXPAND_STKTOP              101
00581 #define INST_INVOKE_EXPANDED            102
00582 
00583 /*
00584  * TIP #57 - 'lassign' command. Code generation requires immediate
00585  *           LINDEX and LRANGE operators.
00586  */
00587 
00588 #define INST_LIST_INDEX_IMM             103
00589 #define INST_LIST_RANGE_IMM             104
00590 
00591 #define INST_START_CMD                  105
00592 
00593 #define INST_LIST_IN                    106
00594 #define INST_LIST_NOT_IN                107
00595 
00596 #define INST_PUSH_RETURN_OPTIONS        108
00597 #define INST_RETURN_STK                 109
00598 
00599 /*
00600  * Dictionary (TIP#111) related commands.
00601  */
00602 
00603 #define INST_DICT_GET                   110
00604 #define INST_DICT_SET                   111
00605 #define INST_DICT_UNSET                 112
00606 #define INST_DICT_INCR_IMM              113
00607 #define INST_DICT_APPEND                114
00608 #define INST_DICT_LAPPEND               115
00609 #define INST_DICT_FIRST                 116
00610 #define INST_DICT_NEXT                  117
00611 #define INST_DICT_DONE                  118
00612 #define INST_DICT_UPDATE_START          119
00613 #define INST_DICT_UPDATE_END            120
00614 
00615 /*
00616  * Instruction to support jumps defined by tables (instead of the classic
00617  * [switch] technique of chained comparisons).
00618  */
00619 
00620 #define INST_JUMP_TABLE                 121
00621 
00622 /*
00623  * Instructions to support compilation of global, variable, upvar and
00624  * [namespace upvar].
00625  */
00626 
00627 #define INST_UPVAR                      122
00628 #define INST_NSUPVAR                    123
00629 #define INST_VARIABLE                   124
00630 
00631 /* Instruction to support compiling syntax error to bytecode */
00632 
00633 #define INST_SYNTAX                     125
00634 
00635 /* Instruction to reverse N items on top of stack */
00636 
00637 #define INST_REVERSE                    126
00638 
00639 /* regexp instruction */
00640 
00641 #define INST_REGEXP                     127
00642 
00643 /* For [info exists] compilation */
00644 #define INST_EXIST_SCALAR               128
00645 #define INST_EXIST_ARRAY                129
00646 #define INST_EXIST_ARRAY_STK            130
00647 #define INST_EXIST_STK                  131
00648 
00649 /* The last opcode */
00650 #define LAST_INST_OPCODE                131
00651 
00652 /*
00653  * Table describing the Tcl bytecode instructions: their name (for displaying
00654  * code), total number of code bytes required (including operand bytes), and a
00655  * description of the type of each operand. These operand types include signed
00656  * and unsigned integers of length one and four bytes. The unsigned integers
00657  * are used for indexes or for, e.g., the count of objects to push in a "push"
00658  * instruction.
00659  */
00660 
00661 #define MAX_INSTRUCTION_OPERANDS 2
00662 
00663 typedef enum InstOperandType {
00664     OPERAND_NONE,
00665     OPERAND_INT1,               /* One byte signed integer. */
00666     OPERAND_INT4,               /* Four byte signed integer. */
00667     OPERAND_UINT1,              /* One byte unsigned integer. */
00668     OPERAND_UINT4,              /* Four byte unsigned integer. */
00669     OPERAND_IDX4,               /* Four byte signed index (actually an
00670                                  * integer, but displayed differently.) */
00671     OPERAND_LVT1,               /* One byte unsigned index into the local
00672                                  * variable table. */
00673     OPERAND_LVT4,               /* Four byte unsigned index into the local
00674                                  * variable table. */
00675     OPERAND_AUX4,               /* Four byte unsigned index into the aux data
00676                                  * table. */
00677 } InstOperandType;
00678 
00679 typedef struct InstructionDesc {
00680     char *name;                 /* Name of instruction. */
00681     int numBytes;               /* Total number of bytes for instruction. */
00682     int stackEffect;            /* The worst-case balance stack effect of the
00683                                  * instruction, used for stack requirements
00684                                  * computations. The value INT_MIN signals
00685                                  * that the instruction's worst case effect is
00686                                  * (1-opnd1). */
00687     int numOperands;            /* Number of operands. */
00688     InstOperandType opTypes[MAX_INSTRUCTION_OPERANDS];
00689                                 /* The type of each operand. */
00690 } InstructionDesc;
00691 
00692 MODULE_SCOPE InstructionDesc tclInstructionTable[];
00693 
00694 /*
00695  * Compilation of some Tcl constructs such as if commands and the logical or
00696  * (||) and logical and (&&) operators in expressions requires the generation
00697  * of forward jumps. Since the PC target of these jumps isn't known when the
00698  * jumps are emitted, we record the offset of each jump in an array of
00699  * JumpFixup structures. There is one array for each sequence of jumps to one
00700  * target PC. When we learn the target PC, we update the jumps with the
00701  * correct distance. Also, if the distance is too great (> 127 bytes), we
00702  * replace the single-byte jump with a four byte jump instruction, move the
00703  * instructions after the jump down, and update the code offsets for any
00704  * commands between the jump and the target.
00705  */
00706 
00707 typedef enum {
00708     TCL_UNCONDITIONAL_JUMP,
00709     TCL_TRUE_JUMP,
00710     TCL_FALSE_JUMP
00711 } TclJumpType;
00712 
00713 typedef struct JumpFixup {
00714     TclJumpType jumpType;       /* Indicates the kind of jump. */
00715     int codeOffset;             /* Offset of the first byte of the one-byte
00716                                  * forward jump's code. */
00717     int cmdIndex;               /* Index of the first command after the one
00718                                  * for which the jump was emitted. Used to
00719                                  * update the code offsets for subsequent
00720                                  * commands if the two-byte jump at jumpPc
00721                                  * must be replaced with a five-byte one. */
00722     int exceptIndex;            /* Index of the first range entry in the
00723                                  * ExceptionRange array after the current one.
00724                                  * This field is used to adjust the code
00725                                  * offsets in subsequent ExceptionRange
00726                                  * records when a jump is grown from 2 bytes
00727                                  * to 5 bytes. */
00728 } JumpFixup;
00729 
00730 #define JUMPFIXUP_INIT_ENTRIES  10
00731 
00732 typedef struct JumpFixupArray {
00733     JumpFixup *fixup;           /* Points to start of jump fixup array. */
00734     int next;                   /* Index of next free array entry. */
00735     int end;                    /* Index of last usable entry in array. */
00736     int mallocedArray;          /* 1 if array was expanded and fixups points
00737                                  * into the heap, else 0. */
00738     JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES];
00739                                 /* Initial storage for jump fixup array. */
00740 } JumpFixupArray;
00741 
00742 /*
00743  * The structure describing one variable list of a foreach command. Note that
00744  * only foreach commands inside procedure bodies are compiled inline so a
00745  * ForeachVarList structure always describes local variables. Furthermore,
00746  * only scalar variables are supported for inline-compiled foreach loops.
00747  */
00748 
00749 typedef struct ForeachVarList {
00750     int numVars;                /* The number of variables in the list. */
00751     int varIndexes[1];          /* An array of the indexes ("slot numbers")
00752                                  * for each variable in the procedure's array
00753                                  * of local variables. Only scalar variables
00754                                  * are supported. The actual size of this
00755                                  * field will be large enough to numVars
00756                                  * indexes. THIS MUST BE THE LAST FIELD IN THE
00757                                  * STRUCTURE! */
00758 } ForeachVarList;
00759 
00760 /*
00761  * Structure used to hold information about a foreach command that is needed
00762  * during program execution. These structures are stored in CompileEnv and
00763  * ByteCode structures as auxiliary data.
00764  */
00765 
00766 typedef struct ForeachInfo {
00767     int numLists;               /* The number of both the variable and value
00768                                  * lists of the foreach command. */
00769     int firstValueTemp;         /* Index of the first temp var in a proc frame
00770                                  * used to point to a value list. */
00771     int loopCtTemp;             /* Index of temp var in a proc frame holding
00772                                  * the loop's iteration count. Used to
00773                                  * determine next value list element to assign
00774                                  * each loop var. */
00775     ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList
00776                                  * structures describing each var list. The
00777                                  * actual size of this field will be large
00778                                  * enough to numVars indexes. THIS MUST BE THE
00779                                  * LAST FIELD IN THE STRUCTURE! */
00780 } ForeachInfo;
00781 
00782 MODULE_SCOPE AuxDataType        tclForeachInfoType;
00783 
00784 /*
00785  * Structure used to hold information about a switch command that is needed
00786  * during program execution. These structures are stored in CompileEnv and
00787  * ByteCode structures as auxiliary data.
00788  */
00789 
00790 typedef struct JumptableInfo {
00791     Tcl_HashTable hashTable;    /* Hash that maps strings to signed ints (PC
00792                                  * offsets). */
00793 } JumptableInfo;
00794 
00795 MODULE_SCOPE AuxDataType        tclJumptableInfoType;
00796 
00797 /*
00798  * Structure used to hold information about a [dict update] command that is
00799  * needed during program execution. These structures are stored in CompileEnv
00800  * and ByteCode structures as auxiliary data.
00801  */
00802 
00803 typedef struct {
00804     int length;                 /* Size of array */
00805     int varIndices[1];          /* Array of variable indices to manage when
00806                                  * processing the start and end of a [dict
00807                                  * update]. There is really more than one
00808                                  * entry, and the structure is allocated to
00809                                  * take account of this. MUST BE LAST FIELD IN
00810                                  * STRUCTURE. */
00811 } DictUpdateInfo;
00812 
00813 MODULE_SCOPE AuxDataType        tclDictUpdateInfoType;
00814 
00815 /*
00816  * ClientData type used by the math operator commands.
00817  */
00818 
00819 typedef struct {
00820     const char *op;   /* Do not call it 'operator': C++ reserved */
00821     const char *expected;
00822     union {
00823         int numArgs;
00824         int identity;
00825     } i;
00826 } TclOpCmdClientData;
00827 
00828 /*
00829  *----------------------------------------------------------------
00830  * Procedures exported by tclBasic.c to be used within the engine.
00831  *----------------------------------------------------------------
00832  */
00833 
00834 MODULE_SCOPE int        TclEvalObjvInternal(Tcl_Interp *interp,
00835                             int objc, Tcl_Obj *const objv[],
00836                             CONST char *command, int length, int flags);
00837 /*
00838  *----------------------------------------------------------------
00839  * Procedures exported by the engine to be used by tclBasic.c
00840  *----------------------------------------------------------------
00841  */
00842 
00843 MODULE_SCOPE int        TclCompEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
00844                             const CmdFrame *invoker, int word);
00845 
00846 /*
00847  *----------------------------------------------------------------
00848  * Procedures shared among Tcl bytecode compilation and execution modules but
00849  * not used outside:
00850  *----------------------------------------------------------------
00851  */
00852 
00853 MODULE_SCOPE void       TclCleanupByteCode(ByteCode *codePtr);
00854 MODULE_SCOPE void       TclCompileCmdWord(Tcl_Interp *interp,
00855                             Tcl_Token *tokenPtr, int count,
00856                             CompileEnv *envPtr);
00857 MODULE_SCOPE void       TclCompileExpr(Tcl_Interp *interp, CONST char *script,
00858                             int numBytes, CompileEnv *envPtr, int optimize);
00859 MODULE_SCOPE void       TclCompileExprWords(Tcl_Interp *interp,
00860                             Tcl_Token *tokenPtr, int numWords,
00861                             CompileEnv *envPtr);
00862 MODULE_SCOPE void       TclCompileScript(Tcl_Interp *interp,
00863                             CONST char *script, int numBytes,
00864                             CompileEnv *envPtr);
00865 MODULE_SCOPE void       TclCompileSyntaxError(Tcl_Interp *interp,
00866                             CompileEnv *envPtr);
00867 MODULE_SCOPE void       TclCompileTokens(Tcl_Interp *interp,
00868                             Tcl_Token *tokenPtr, int count,
00869                             CompileEnv *envPtr);
00870 MODULE_SCOPE int        TclCreateAuxData(ClientData clientData,
00871                             AuxDataType *typePtr, CompileEnv *envPtr);
00872 MODULE_SCOPE int        TclCreateExceptRange(ExceptionRangeType type,
00873                             CompileEnv *envPtr);
00874 MODULE_SCOPE ExecEnv *  TclCreateExecEnv(Tcl_Interp *interp);
00875 MODULE_SCOPE Tcl_Obj *  TclCreateLiteral(Interp *iPtr, char *bytes,
00876                             int length, unsigned int hash, int *newPtr,
00877                             Namespace *nsPtr, int flags,
00878                             LiteralEntry **globalPtrPtr);
00879 MODULE_SCOPE void       TclDeleteExecEnv(ExecEnv *eePtr);
00880 MODULE_SCOPE void       TclDeleteLiteralTable(Tcl_Interp *interp,
00881                             LiteralTable *tablePtr);
00882 MODULE_SCOPE void       TclEmitForwardJump(CompileEnv *envPtr,
00883                             TclJumpType jumpType, JumpFixup *jumpFixupPtr);
00884 MODULE_SCOPE ExceptionRange * TclGetExceptionRangeForPc(unsigned char *pc,
00885                             int catchOnly, ByteCode* codePtr);
00886 MODULE_SCOPE void       TclExpandJumpFixupArray(JumpFixupArray *fixupArrayPtr);
00887 MODULE_SCOPE int        TclExecuteByteCode(Tcl_Interp *interp,
00888                             ByteCode *codePtr);
00889 MODULE_SCOPE void       TclFinalizeAuxDataTypeTable(void);
00890 MODULE_SCOPE int        TclFindCompiledLocal(CONST char *name, int nameChars,
00891                             int create, Proc *procPtr);
00892 MODULE_SCOPE LiteralEntry * TclLookupLiteralEntry(Tcl_Interp *interp,
00893                             Tcl_Obj *objPtr);
00894 MODULE_SCOPE int        TclFixupForwardJump(CompileEnv *envPtr,
00895                             JumpFixup *jumpFixupPtr, int jumpDist,
00896                             int distThreshold);
00897 MODULE_SCOPE void       TclFreeCompileEnv(CompileEnv *envPtr);
00898 MODULE_SCOPE void       TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr);
00899 MODULE_SCOPE void       TclInitAuxDataTypeTable(void);
00900 MODULE_SCOPE void       TclInitByteCodeObj(Tcl_Obj *objPtr,
00901                             CompileEnv *envPtr);
00902 MODULE_SCOPE void       TclInitCompilation(void);
00903 MODULE_SCOPE void       TclInitCompileEnv(Tcl_Interp *interp,
00904                             CompileEnv *envPtr, const char *string,
00905                             int numBytes, CONST CmdFrame* invoker, int word);
00906 MODULE_SCOPE void       TclInitJumpFixupArray(JumpFixupArray *fixupArrayPtr);
00907 MODULE_SCOPE void       TclInitLiteralTable(LiteralTable *tablePtr);
00908 #ifdef TCL_COMPILE_STATS
00909 MODULE_SCOPE char *     TclLiteralStats(LiteralTable *tablePtr);
00910 MODULE_SCOPE int        TclLog2(int value);
00911 #endif
00912 #ifdef TCL_COMPILE_DEBUG
00913 MODULE_SCOPE void       TclPrintByteCodeObj(Tcl_Interp *interp,
00914                             Tcl_Obj *objPtr);
00915 #endif
00916 MODULE_SCOPE int        TclPrintInstruction(ByteCode* codePtr,
00917                             unsigned char *pc);
00918 MODULE_SCOPE void       TclPrintObject(FILE *outFile,
00919                             Tcl_Obj *objPtr, int maxChars);
00920 MODULE_SCOPE void       TclPrintSource(FILE *outFile,
00921                             CONST char *string, int maxChars);
00922 MODULE_SCOPE void       TclRegisterAuxDataType(AuxDataType *typePtr);
00923 MODULE_SCOPE int        TclRegisterLiteral(CompileEnv *envPtr,
00924                             char *bytes, int length, int flags);
00925 MODULE_SCOPE void       TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr);
00926 MODULE_SCOPE int        TclSingleOpCmd(ClientData clientData,
00927                             Tcl_Interp *interp, int objc,
00928                             Tcl_Obj *CONST objv[]);
00929 MODULE_SCOPE int        TclSortingOpCmd(ClientData clientData,
00930                             Tcl_Interp *interp, int objc,
00931                             Tcl_Obj *CONST objv[]);
00932 MODULE_SCOPE int        TclVariadicOpCmd(ClientData clientData,
00933                             Tcl_Interp *interp, int objc,
00934                             Tcl_Obj *CONST objv[]);
00935 MODULE_SCOPE int        TclNoIdentOpCmd(ClientData clientData,
00936                             Tcl_Interp *interp, int objc,
00937                             Tcl_Obj *CONST objv[]);
00938 #ifdef TCL_COMPILE_DEBUG
00939 MODULE_SCOPE void       TclVerifyGlobalLiteralTable(Interp *iPtr);
00940 MODULE_SCOPE void       TclVerifyLocalLiteralTable(CompileEnv *envPtr);
00941 #endif
00942 MODULE_SCOPE int        TclWordKnownAtCompileTime(Tcl_Token *tokenPtr,
00943                             Tcl_Obj *valuePtr);
00944 
00945 /*
00946  *----------------------------------------------------------------
00947  * Macros and flag values used by Tcl bytecode compilation and execution
00948  * modules inside the Tcl core but not used outside.
00949  *----------------------------------------------------------------
00950  */
00951 
00952 #define LITERAL_ON_HEAP    0x01
00953 #define LITERAL_NS_SCOPE   0x02
00954 
00955 /*
00956  * Form of TclRegisterLiteral with onHeap == 0. In that case, it is safe to
00957  * cast away CONSTness, and it is cleanest to do that here, all in one place.
00958  *
00959  * int TclRegisterNewLiteral(CompileEnv *envPtr, const char *bytes,
00960  *                           int length);
00961  */
00962 
00963 #define TclRegisterNewLiteral(envPtr, bytes, length) \
00964         TclRegisterLiteral(envPtr, (char *)(bytes), length, /*flags*/ 0)
00965 
00966 /*
00967  * Form of TclRegisterNSLiteral with onHeap == 0. In that case, it is safe to
00968  * cast away CONSTness, and it is cleanest to do that here, all in one place.
00969  *
00970  * int TclRegisterNewNSLiteral(CompileEnv *envPtr, const char *bytes,
00971  *                             int length);
00972  */
00973 
00974 #define TclRegisterNewNSLiteral(envPtr, bytes, length) \
00975         TclRegisterLiteral(envPtr, (char *)(bytes), length, \
00976                 /*flags*/ LITERAL_NS_SCOPE)
00977 
00978 /*
00979  * Macro used to manually adjust the stack requirements; used in cases where
00980  * the stack effect cannot be computed from the opcode and its operands, but
00981  * is still known at compile time.
00982  *
00983  * void TclAdjustStackDepth(int delta, CompileEnv *envPtr);
00984  */
00985 
00986 #define TclAdjustStackDepth(delta, envPtr) \
00987     if ((delta) < 0) {\
00988         if((envPtr)->maxStackDepth < (envPtr)->currStackDepth) {\
00989             (envPtr)->maxStackDepth = (envPtr)->currStackDepth;\
00990         }\
00991     }\
00992     (envPtr)->currStackDepth += (delta)
00993 
00994 /*
00995  * Macro used to update the stack requirements. It is called by the macros
00996  * TclEmitOpCode, TclEmitInst1 and TclEmitInst4.
00997  * Remark that the very last instruction of a bytecode always reduces the
00998  * stack level: INST_DONE or INST_POP, so that the maxStackdepth is always
00999  * updated.
01000  *
01001  * void TclUpdateStackReqs(unsigned char op, int i, CompileEnv *envPtr);
01002  */
01003 
01004 #define TclUpdateStackReqs(op, i, envPtr) \
01005     {\
01006         int delta = tclInstructionTable[(op)].stackEffect;\
01007         if (delta) {\
01008             if (delta == INT_MIN) {\
01009                 delta = 1 - (i);\
01010             }\
01011             TclAdjustStackDepth(delta, envPtr);\
01012         }\
01013     }
01014 
01015 /*
01016  * Macro to emit an opcode byte into a CompileEnv's code array. The ANSI C
01017  * "prototype" for this macro is:
01018  *
01019  * void TclEmitOpcode(unsigned char op, CompileEnv *envPtr);
01020  */
01021 
01022 #define TclEmitOpcode(op, envPtr) \
01023     if ((envPtr)->codeNext == (envPtr)->codeEnd) { \
01024         TclExpandCodeArray(envPtr); \
01025     } \
01026     *(envPtr)->codeNext++ = (unsigned char) (op);\
01027     (envPtr)->atCmdStart = ((op) == INST_START_CMD); \
01028     TclUpdateStackReqs(op, 0, envPtr)
01029 
01030 /*
01031  * Macros to emit an integer operand. The ANSI C "prototype" for these macros
01032  * are:
01033  *
01034  * void TclEmitInt1(int i, CompileEnv *envPtr);
01035  * void TclEmitInt4(int i, CompileEnv *envPtr);
01036  */
01037 
01038 #define TclEmitInt1(i, envPtr) \
01039     if ((envPtr)->codeNext == (envPtr)->codeEnd) { \
01040         TclExpandCodeArray(envPtr); \
01041     } \
01042     *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))
01043 
01044 #define TclEmitInt4(i, envPtr) \
01045     if (((envPtr)->codeNext + 4) > (envPtr)->codeEnd) { \
01046         TclExpandCodeArray(envPtr); \
01047     } \
01048     *(envPtr)->codeNext++ = \
01049         (unsigned char) ((unsigned int) (i) >> 24); \
01050     *(envPtr)->codeNext++ = \
01051         (unsigned char) ((unsigned int) (i) >> 16); \
01052     *(envPtr)->codeNext++ = \
01053         (unsigned char) ((unsigned int) (i) >>  8); \
01054     *(envPtr)->codeNext++ = \
01055         (unsigned char) ((unsigned int) (i)      )
01056 
01057 /*
01058  * Macros to emit an instruction with signed or unsigned integer operands.
01059  * Four byte integers are stored in "big-endian" order with the high order
01060  * byte stored at the lowest address. The ANSI C "prototypes" for these macros
01061  * are:
01062  *
01063  * void TclEmitInstInt1(unsigned char op, int i, CompileEnv *envPtr);
01064  * void TclEmitInstInt4(unsigned char op, int i, CompileEnv *envPtr);
01065  */
01066 
01067 #define TclEmitInstInt1(op, i, envPtr) \
01068     if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) { \
01069         TclExpandCodeArray(envPtr); \
01070     } \
01071     *(envPtr)->codeNext++ = (unsigned char) (op); \
01072     *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i));\
01073     (envPtr)->atCmdStart = ((op) == INST_START_CMD); \
01074     TclUpdateStackReqs(op, i, envPtr)
01075 
01076 #define TclEmitInstInt4(op, i, envPtr) \
01077     if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \
01078         TclExpandCodeArray(envPtr); \
01079     } \
01080     *(envPtr)->codeNext++ = (unsigned char) (op); \
01081     *(envPtr)->codeNext++ = \
01082         (unsigned char) ((unsigned int) (i) >> 24); \
01083     *(envPtr)->codeNext++ = \
01084         (unsigned char) ((unsigned int) (i) >> 16); \
01085     *(envPtr)->codeNext++ = \
01086         (unsigned char) ((unsigned int) (i) >>  8); \
01087     *(envPtr)->codeNext++ = \
01088         (unsigned char) ((unsigned int) (i)      );\
01089     (envPtr)->atCmdStart = ((op) == INST_START_CMD); \
01090     TclUpdateStackReqs(op, i, envPtr)
01091 
01092 /*
01093  * Macro to push a Tcl object onto the Tcl evaluation stack. It emits the
01094  * object's one or four byte array index into the CompileEnv's code array.
01095  * These support, respectively, a maximum of 256 (2**8) and 2**32 objects in a
01096  * CompileEnv. The ANSI C "prototype" for this macro is:
01097  *
01098  * void TclEmitPush(int objIndex, CompileEnv *envPtr);
01099  */
01100 
01101 #define TclEmitPush(objIndex, envPtr) \
01102     {\
01103         register int objIndexCopy = (objIndex);\
01104         if (objIndexCopy <= 255) { \
01105             TclEmitInstInt1(INST_PUSH1, objIndexCopy, (envPtr)); \
01106         } else { \
01107             TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \
01108         }\
01109     }
01110 
01111 /*
01112  * Macros to update a (signed or unsigned) integer starting at a pointer. The
01113  * two variants depend on the number of bytes. The ANSI C "prototypes" for
01114  * these macros are:
01115  *
01116  * void TclStoreInt1AtPtr(int i, unsigned char *p);
01117  * void TclStoreInt4AtPtr(int i, unsigned char *p);
01118  */
01119 
01120 #define TclStoreInt1AtPtr(i, p) \
01121     *(p)   = (unsigned char) ((unsigned int) (i))
01122 
01123 #define TclStoreInt4AtPtr(i, p) \
01124     *(p)   = (unsigned char) ((unsigned int) (i) >> 24); \
01125     *(p+1) = (unsigned char) ((unsigned int) (i) >> 16); \
01126     *(p+2) = (unsigned char) ((unsigned int) (i) >>  8); \
01127     *(p+3) = (unsigned char) ((unsigned int) (i)      )
01128 
01129 /*
01130  * Macros to update instructions at a particular pc with a new op code and a
01131  * (signed or unsigned) int operand. The ANSI C "prototypes" for these macros
01132  * are:
01133  *
01134  * void TclUpdateInstInt1AtPc(unsigned char op, int i, unsigned char *pc);
01135  * void TclUpdateInstInt4AtPc(unsigned char op, int i, unsigned char *pc);
01136  */
01137 
01138 #define TclUpdateInstInt1AtPc(op, i, pc) \
01139     *(pc) = (unsigned char) (op); \
01140     TclStoreInt1AtPtr((i), ((pc)+1))
01141 
01142 #define TclUpdateInstInt4AtPc(op, i, pc) \
01143     *(pc) = (unsigned char) (op); \
01144     TclStoreInt4AtPtr((i), ((pc)+1))
01145 
01146 /*
01147  * Macro to fix up a forward jump to point to the current code-generation
01148  * position in the bytecode being created (the most common case). The ANSI C
01149  * "prototypes" for this macro is:
01150  *
01151  * int TclFixupForwardJumpToHere(CompileEnv *envPtr, JumpFixup *fixupPtr,
01152  *                               int threshold);
01153  */
01154 
01155 #define TclFixupForwardJumpToHere(envPtr, fixupPtr, threshold) \
01156     TclFixupForwardJump((envPtr), (fixupPtr), \
01157             (envPtr)->codeNext-(envPtr)->codeStart-(fixupPtr)->codeOffset, \
01158             (threshold))
01159 
01160 /*
01161  * Macros to get a signed integer (GET_INT{1,2}) or an unsigned int
01162  * (GET_UINT{1,2}) from a pointer. There are two variants for each return type
01163  * that depend on the number of bytes fetched. The ANSI C "prototypes" for
01164  * these macros are:
01165  *
01166  * int TclGetInt1AtPtr(unsigned char *p);
01167  * int TclGetInt4AtPtr(unsigned char *p);
01168  * unsigned int TclGetUInt1AtPtr(unsigned char *p);
01169  * unsigned int TclGetUInt4AtPtr(unsigned char *p);
01170  */
01171 
01172 /*
01173  * The TclGetInt1AtPtr macro is tricky because we want to do sign extension on
01174  * the 1-byte value. Unfortunately the "char" type isn't signed on all
01175  * platforms so sign-extension doesn't always happen automatically. Sometimes
01176  * we can explicitly declare the pointer to be signed, but other times we have
01177  * to explicitly sign-extend the value in software.
01178  */
01179 
01180 #ifndef __CHAR_UNSIGNED__
01181 #   define TclGetInt1AtPtr(p) ((int) *((char *) p))
01182 #else
01183 #   ifdef HAVE_SIGNED_CHAR
01184 #       define TclGetInt1AtPtr(p) ((int) *((signed char *) p))
01185 #   else
01186 #       define TclGetInt1AtPtr(p) (((int) *((char *) p)) \
01187                 | ((*(p) & 0200) ? (-256) : 0))
01188 #   endif
01189 #endif
01190 
01191 #define TclGetInt4AtPtr(p) (((int) TclGetInt1AtPtr(p) << 24) | \
01192                                             (*((p)+1) << 16) | \
01193                                             (*((p)+2) <<  8) | \
01194                                             (*((p)+3)))
01195 
01196 #define TclGetUInt1AtPtr(p) ((unsigned int) *(p))
01197 #define TclGetUInt4AtPtr(p) ((unsigned int) (*(p)     << 24) | \
01198                                             (*((p)+1) << 16) | \
01199                                             (*((p)+2) <<  8) | \
01200                                             (*((p)+3)))
01201 
01202 /*
01203  * Macros used to compute the minimum and maximum of two integers. The ANSI C
01204  * "prototypes" for these macros are:
01205  *
01206  * int TclMin(int i, int j);
01207  * int TclMax(int i, int j);
01208  */
01209 
01210 #define TclMin(i, j)   ((((int) i) < ((int) j))? (i) : (j))
01211 #define TclMax(i, j)   ((((int) i) > ((int) j))? (i) : (j))
01212 
01213 /*
01214  * DTrace probe macros (NOPs if DTrace support is not enabled).
01215  */
01216 
01217 #ifdef USE_DTRACE
01218 
01219 #include "tclDTrace.h"
01220 
01221 #if defined(__GNUC__ ) && __GNUC__ > 2
01222 /* Use gcc branch prediction hint to minimize cost of DTrace ENABLED checks. */
01223 #define unlikely(x) (__builtin_expect((x), 0))
01224 #else
01225 #define unlikely(x) (x)
01226 #endif
01227 
01228 #define TCL_DTRACE_PROC_ENTRY_ENABLED()     unlikely(TCL_PROC_ENTRY_ENABLED())
01229 #define TCL_DTRACE_PROC_RETURN_ENABLED()    unlikely(TCL_PROC_RETURN_ENABLED())
01230 #define TCL_DTRACE_PROC_RESULT_ENABLED()    unlikely(TCL_PROC_RESULT_ENABLED())
01231 #define TCL_DTRACE_PROC_ARGS_ENABLED()      unlikely(TCL_PROC_ARGS_ENABLED())
01232 #define TCL_DTRACE_PROC_INFO_ENABLED()      unlikely(TCL_PROC_INFO_ENABLED())
01233 #define TCL_DTRACE_PROC_ENTRY(a0, a1, a2)   TCL_PROC_ENTRY(a0, a1, a2)
01234 #define TCL_DTRACE_PROC_RETURN(a0, a1)      TCL_PROC_RETURN(a0, a1)
01235 #define TCL_DTRACE_PROC_RESULT(a0, a1, a2, a3) TCL_PROC_RESULT(a0, a1, a2, a3)
01236 #define TCL_DTRACE_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
01237         TCL_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
01238 #define TCL_DTRACE_PROC_INFO(a0, a1, a2, a3, a4, a5) \
01239         TCL_PROC_INFO(a0, a1, a2, a3, a4, a5)
01240 
01241 #define TCL_DTRACE_CMD_ENTRY_ENABLED()      unlikely(TCL_CMD_ENTRY_ENABLED())
01242 #define TCL_DTRACE_CMD_RETURN_ENABLED()     unlikely(TCL_CMD_RETURN_ENABLED())
01243 #define TCL_DTRACE_CMD_RESULT_ENABLED()     unlikely(TCL_CMD_RESULT_ENABLED())
01244 #define TCL_DTRACE_CMD_ARGS_ENABLED()       unlikely(TCL_CMD_ARGS_ENABLED())
01245 #define TCL_DTRACE_CMD_INFO_ENABLED()       unlikely(TCL_CMD_INFO_ENABLED())
01246 #define TCL_DTRACE_CMD_ENTRY(a0, a1, a2)    TCL_CMD_ENTRY(a0, a1, a2)
01247 #define TCL_DTRACE_CMD_RETURN(a0, a1)       TCL_CMD_RETURN(a0, a1)
01248 #define TCL_DTRACE_CMD_RESULT(a0, a1, a2, a3) TCL_CMD_RESULT(a0, a1, a2, a3)
01249 #define TCL_DTRACE_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
01250         TCL_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
01251 #define TCL_DTRACE_CMD_INFO(a0, a1, a2, a3, a4, a5) \
01252         TCL_CMD_INFO(a0, a1, a2, a3, a4, a5)
01253 
01254 #define TCL_DTRACE_INST_START_ENABLED()     unlikely(TCL_INST_START_ENABLED())
01255 #define TCL_DTRACE_INST_DONE_ENABLED()      unlikely(TCL_INST_DONE_ENABLED())
01256 #define TCL_DTRACE_INST_START(a0, a1, a2)   TCL_INST_START(a0, a1, a2)
01257 #define TCL_DTRACE_INST_DONE(a0, a1, a2)    TCL_INST_DONE(a0, a1, a2)
01258 
01259 #define TCL_DTRACE_TCL_PROBE_ENABLED()      unlikely(TCL_TCL_PROBE_ENABLED())
01260 #define TCL_DTRACE_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
01261         TCL_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
01262 
01263 MODULE_SCOPE void TclDTraceInfo(Tcl_Obj *info, char **args, int *argsi);
01264 
01265 #else /* USE_DTRACE */
01266 
01267 #define TCL_DTRACE_PROC_ENTRY_ENABLED()     0
01268 #define TCL_DTRACE_PROC_RETURN_ENABLED()    0
01269 #define TCL_DTRACE_PROC_RESULT_ENABLED()    0
01270 #define TCL_DTRACE_PROC_ARGS_ENABLED()      0
01271 #define TCL_DTRACE_PROC_INFO_ENABLED()      0
01272 #define TCL_DTRACE_PROC_ENTRY(a0, a1, a2)   {}
01273 #define TCL_DTRACE_PROC_RETURN(a0, a1)      {}
01274 #define TCL_DTRACE_PROC_RESULT(a0, a1, a2, a3) {}
01275 #define TCL_DTRACE_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
01276 #define TCL_DTRACE_PROC_INFO(a0, a1, a2, a3, a4, a5) {}
01277 
01278 #define TCL_DTRACE_CMD_ENTRY_ENABLED()      0
01279 #define TCL_DTRACE_CMD_RETURN_ENABLED()     0
01280 #define TCL_DTRACE_CMD_RESULT_ENABLED()     0
01281 #define TCL_DTRACE_CMD_ARGS_ENABLED()       0
01282 #define TCL_DTRACE_CMD_INFO_ENABLED()       0
01283 #define TCL_DTRACE_CMD_ENTRY(a0, a1, a2)    {}
01284 #define TCL_DTRACE_CMD_RETURN(a0, a1)       {}
01285 #define TCL_DTRACE_CMD_RESULT(a0, a1, a2, a3) {}
01286 #define TCL_DTRACE_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
01287 #define TCL_DTRACE_CMD_INFO(a0, a1, a2, a3, a4, a5) {}
01288 
01289 #define TCL_DTRACE_INST_START_ENABLED()     0
01290 #define TCL_DTRACE_INST_DONE_ENABLED()      0
01291 #define TCL_DTRACE_INST_START(a0, a1, a2)   {}
01292 #define TCL_DTRACE_INST_DONE(a0, a1, a2)    {}
01293 
01294 #define TCL_DTRACE_TCL_PROBE_ENABLED()      0
01295 #define TCL_DTRACE_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
01296 
01297 #define TclDTraceInfo(info, args, argsi)    {*args = ""; *argsi = 0;}
01298 
01299 #endif /* USE_DTRACE */
01300 
01301 #endif /* _TCLCOMPILATION */
01302 
01303 /*
01304  * Local Variables:
01305  * mode: c
01306  * c-basic-offset: 4
01307  * fill-column: 78
01308  * End:
01309  */



Generated on Wed Mar 12 12:18:14 2008 by  doxygen 1.5.1