[25] | 1 | /* |
---|
| 2 | * tclCompile.h -- |
---|
| 3 | * |
---|
| 4 | * Copyright (c) 1996-1998 Sun Microsystems, Inc. |
---|
| 5 | * Copyright (c) 1998-2000 by Scriptics Corporation. |
---|
| 6 | * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved. |
---|
| 7 | * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net> |
---|
| 8 | * |
---|
| 9 | * See the file "license.terms" for information on usage and redistribution of |
---|
| 10 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
| 11 | * |
---|
| 12 | * RCS: @(#) $Id: tclCompile.h,v 1.90 2008/02/26 20:28:59 jenglish Exp $ |
---|
| 13 | */ |
---|
| 14 | |
---|
| 15 | #ifndef _TCLCOMPILATION |
---|
| 16 | #define _TCLCOMPILATION 1 |
---|
| 17 | |
---|
| 18 | #include "tclInt.h" |
---|
| 19 | |
---|
| 20 | struct ByteCode; /* Forward declaration. */ |
---|
| 21 | |
---|
| 22 | /* |
---|
| 23 | *------------------------------------------------------------------------ |
---|
| 24 | * Variables related to compilation. These are used in tclCompile.c, |
---|
| 25 | * tclExecute.c, tclBasic.c, and their clients. |
---|
| 26 | *------------------------------------------------------------------------ |
---|
| 27 | */ |
---|
| 28 | |
---|
| 29 | #ifdef TCL_COMPILE_DEBUG |
---|
| 30 | /* |
---|
| 31 | * Variable that controls whether compilation tracing is enabled and, if so, |
---|
| 32 | * what level of tracing is desired: |
---|
| 33 | * 0: no compilation tracing |
---|
| 34 | * 1: summarize compilation of top level cmds and proc bodies |
---|
| 35 | * 2: display all instructions of each ByteCode compiled |
---|
| 36 | * This variable is linked to the Tcl variable "tcl_traceCompile". |
---|
| 37 | */ |
---|
| 38 | |
---|
| 39 | MODULE_SCOPE int tclTraceCompile; |
---|
| 40 | |
---|
| 41 | /* |
---|
| 42 | * Variable that controls whether execution tracing is enabled and, if so, |
---|
| 43 | * what level of tracing is desired: |
---|
| 44 | * 0: no execution tracing |
---|
| 45 | * 1: trace invocations of Tcl procs only |
---|
| 46 | * 2: trace invocations of all (not compiled away) commands |
---|
| 47 | * 3: display each instruction executed |
---|
| 48 | * This variable is linked to the Tcl variable "tcl_traceExec". |
---|
| 49 | */ |
---|
| 50 | |
---|
| 51 | MODULE_SCOPE int tclTraceExec; |
---|
| 52 | #endif |
---|
| 53 | |
---|
| 54 | /* |
---|
| 55 | *------------------------------------------------------------------------ |
---|
| 56 | * Data structures related to compilation. |
---|
| 57 | *------------------------------------------------------------------------ |
---|
| 58 | */ |
---|
| 59 | |
---|
| 60 | /* |
---|
| 61 | * The structure used to implement Tcl "exceptions" (exceptional returns): for |
---|
| 62 | * example, those generated in loops by the break and continue commands, and |
---|
| 63 | * those generated by scripts and caught by the catch command. This |
---|
| 64 | * ExceptionRange structure describes a range of code (e.g., a loop body), the |
---|
| 65 | * kind of exceptions (e.g., a break or continue) that might occur, and the PC |
---|
| 66 | * offsets to jump to if a matching exception does occur. Exception ranges can |
---|
| 67 | * nest so this structure includes a nesting level that is used at runtime to |
---|
| 68 | * find the closest exception range surrounding a PC. For example, when a |
---|
| 69 | * break command is executed, the ExceptionRange structure for the most deeply |
---|
| 70 | * nested loop, if any, is found and used. These structures are also generated |
---|
| 71 | * for the "next" subcommands of for loops since a break there terminates the |
---|
| 72 | * for command. This means a for command actually generates two LoopInfo |
---|
| 73 | * structures. |
---|
| 74 | */ |
---|
| 75 | |
---|
| 76 | typedef enum { |
---|
| 77 | LOOP_EXCEPTION_RANGE, /* Exception's range is part of a loop. Break |
---|
| 78 | * and continue "exceptions" cause jumps to |
---|
| 79 | * appropriate PC offsets. */ |
---|
| 80 | CATCH_EXCEPTION_RANGE /* Exception's range is controlled by a catch |
---|
| 81 | * command. Errors in the range cause a jump |
---|
| 82 | * to a catch PC offset. */ |
---|
| 83 | } ExceptionRangeType; |
---|
| 84 | |
---|
| 85 | typedef struct ExceptionRange { |
---|
| 86 | ExceptionRangeType type; /* The kind of ExceptionRange. */ |
---|
| 87 | int nestingLevel; /* Static depth of the exception range. Used |
---|
| 88 | * to find the most deeply-nested range |
---|
| 89 | * surrounding a PC at runtime. */ |
---|
| 90 | int codeOffset; /* Offset of the first instruction byte of the |
---|
| 91 | * code range. */ |
---|
| 92 | int numCodeBytes; /* Number of bytes in the code range. */ |
---|
| 93 | int breakOffset; /* If LOOP_EXCEPTION_RANGE, the target PC |
---|
| 94 | * offset for a break command in the range. */ |
---|
| 95 | int continueOffset; /* If LOOP_EXCEPTION_RANGE and not -1, the |
---|
| 96 | * target PC offset for a continue command in |
---|
| 97 | * the code range. Otherwise, ignore this |
---|
| 98 | * range when processing a continue |
---|
| 99 | * command. */ |
---|
| 100 | int catchOffset; /* If a CATCH_EXCEPTION_RANGE, the target PC |
---|
| 101 | * offset for any "exception" in range. */ |
---|
| 102 | } ExceptionRange; |
---|
| 103 | |
---|
| 104 | /* |
---|
| 105 | * Structure used to map between instruction pc and source locations. It |
---|
| 106 | * defines for each compiled Tcl command its code's starting offset and its |
---|
| 107 | * source's starting offset and length. Note that the code offset increases |
---|
| 108 | * monotonically: that is, the table is sorted in code offset order. The |
---|
| 109 | * source offset is not monotonic. |
---|
| 110 | */ |
---|
| 111 | |
---|
| 112 | typedef struct CmdLocation { |
---|
| 113 | int codeOffset; /* Offset of first byte of command code. */ |
---|
| 114 | int numCodeBytes; /* Number of bytes for command's code. */ |
---|
| 115 | int srcOffset; /* Offset of first char of the command. */ |
---|
| 116 | int numSrcBytes; /* Number of command source chars. */ |
---|
| 117 | } CmdLocation; |
---|
| 118 | |
---|
| 119 | /* |
---|
| 120 | * TIP #280 |
---|
| 121 | * Structure to record additional location information for byte code. This |
---|
| 122 | * information is internal and not saved. i.e. tbcload'ed code will not have |
---|
| 123 | * this information. It records the lines for all words of all commands found |
---|
| 124 | * in the byte code. The association with a ByteCode structure BC is done |
---|
| 125 | * through the 'lineBCPtr' HashTable in Interp, keyed by the address of BC. |
---|
| 126 | * Also recorded is information coming from the context, i.e. type of the |
---|
| 127 | * frame and associated information, like the path of a sourced file. |
---|
| 128 | */ |
---|
| 129 | |
---|
| 130 | typedef struct ECL { |
---|
| 131 | int srcOffset; /* Command location to find the entry. */ |
---|
| 132 | int nline; |
---|
| 133 | int *line; /* Line information for all words in the |
---|
| 134 | * command. */ |
---|
| 135 | } ECL; |
---|
| 136 | |
---|
| 137 | typedef struct ExtCmdLoc { |
---|
| 138 | int type; /* Context type. */ |
---|
| 139 | Tcl_Obj *path; /* Path of the sourced file the command is |
---|
| 140 | * in. */ |
---|
| 141 | ECL *loc; /* Command word locations (lines). */ |
---|
| 142 | int nloc; /* Number of allocated entries in 'loc'. */ |
---|
| 143 | int nuloc; /* Number of used entries in 'loc'. */ |
---|
| 144 | } ExtCmdLoc; |
---|
| 145 | |
---|
| 146 | /* |
---|
| 147 | * CompileProcs need the ability to record information during compilation that |
---|
| 148 | * can be used by bytecode instructions during execution. The AuxData |
---|
| 149 | * structure provides this "auxiliary data" mechanism. An arbitrary number of |
---|
| 150 | * these structures can be stored in the ByteCode record (during compilation |
---|
| 151 | * they are stored in a CompileEnv structure). Each AuxData record holds one |
---|
| 152 | * word of client-specified data (often a pointer) and is given an index that |
---|
| 153 | * instructions can later use to look up the structure and its data. |
---|
| 154 | * |
---|
| 155 | * The following definitions declare the types of procedures that are called |
---|
| 156 | * to duplicate or free this auxiliary data when the containing ByteCode |
---|
| 157 | * objects are duplicated and freed. Pointers to these procedures are kept in |
---|
| 158 | * the AuxData structure. |
---|
| 159 | */ |
---|
| 160 | |
---|
| 161 | typedef ClientData (AuxDataDupProc) (ClientData clientData); |
---|
| 162 | typedef void (AuxDataFreeProc) (ClientData clientData); |
---|
| 163 | typedef void (AuxDataPrintProc)(ClientData clientData, |
---|
| 164 | Tcl_Obj *appendObj, struct ByteCode *codePtr, |
---|
| 165 | unsigned int pcOffset); |
---|
| 166 | |
---|
| 167 | /* |
---|
| 168 | * We define a separate AuxDataType struct to hold type-related information |
---|
| 169 | * for the AuxData structure. This separation makes it possible for clients |
---|
| 170 | * outside of the TCL core to manipulate (in a limited fashion!) AuxData; for |
---|
| 171 | * example, it makes it possible to pickle and unpickle AuxData structs. |
---|
| 172 | */ |
---|
| 173 | |
---|
| 174 | typedef struct AuxDataType { |
---|
| 175 | char *name; /* The name of the type. Types can be |
---|
| 176 | * registered and found by name */ |
---|
| 177 | AuxDataDupProc *dupProc; /* Callback procedure to invoke when the aux |
---|
| 178 | * data is duplicated (e.g., when the ByteCode |
---|
| 179 | * structure containing the aux data is |
---|
| 180 | * duplicated). NULL means just copy the |
---|
| 181 | * source clientData bits; no proc need be |
---|
| 182 | * called. */ |
---|
| 183 | AuxDataFreeProc *freeProc; /* Callback procedure to invoke when the aux |
---|
| 184 | * data is freed. NULL means no proc need be |
---|
| 185 | * called. */ |
---|
| 186 | AuxDataPrintProc *printProc;/* Callback function to invoke when printing |
---|
| 187 | * the aux data as part of debugging. NULL |
---|
| 188 | * means that the data can't be printed. */ |
---|
| 189 | } AuxDataType; |
---|
| 190 | |
---|
| 191 | /* |
---|
| 192 | * The definition of the AuxData structure that holds information created |
---|
| 193 | * during compilation by CompileProcs and used by instructions during |
---|
| 194 | * execution. |
---|
| 195 | */ |
---|
| 196 | |
---|
| 197 | typedef struct AuxData { |
---|
| 198 | AuxDataType *type; /* Pointer to the AuxData type associated with |
---|
| 199 | * this ClientData. */ |
---|
| 200 | ClientData clientData; /* The compilation data itself. */ |
---|
| 201 | } AuxData; |
---|
| 202 | |
---|
| 203 | /* |
---|
| 204 | * Structure defining the compilation environment. After compilation, fields |
---|
| 205 | * describing bytecode instructions are copied out into the more compact |
---|
| 206 | * ByteCode structure defined below. |
---|
| 207 | */ |
---|
| 208 | |
---|
| 209 | #define COMPILEENV_INIT_CODE_BYTES 250 |
---|
| 210 | #define COMPILEENV_INIT_NUM_OBJECTS 60 |
---|
| 211 | #define COMPILEENV_INIT_EXCEPT_RANGES 5 |
---|
| 212 | #define COMPILEENV_INIT_CMD_MAP_SIZE 40 |
---|
| 213 | #define COMPILEENV_INIT_AUX_DATA_SIZE 5 |
---|
| 214 | |
---|
| 215 | typedef struct CompileEnv { |
---|
| 216 | Interp *iPtr; /* Interpreter containing the code being |
---|
| 217 | * compiled. Commands and their compile procs |
---|
| 218 | * are specific to an interpreter so the code |
---|
| 219 | * emitted will depend on the interpreter. */ |
---|
| 220 | const char *source; /* The source string being compiled by |
---|
| 221 | * SetByteCodeFromAny. This pointer is not |
---|
| 222 | * owned by the CompileEnv and must not be |
---|
| 223 | * freed or changed by it. */ |
---|
| 224 | int numSrcBytes; /* Number of bytes in source. */ |
---|
| 225 | Proc *procPtr; /* If a procedure is being compiled, a pointer |
---|
| 226 | * to its Proc structure; otherwise NULL. Used |
---|
| 227 | * to compile local variables. Set from |
---|
| 228 | * information provided by ObjInterpProc in |
---|
| 229 | * tclProc.c. */ |
---|
| 230 | int numCommands; /* Number of commands compiled. */ |
---|
| 231 | int exceptDepth; /* Current exception range nesting level; -1 |
---|
| 232 | * if not in any range currently. */ |
---|
| 233 | int maxExceptDepth; /* Max nesting level of exception ranges; -1 |
---|
| 234 | * if no ranges have been compiled. */ |
---|
| 235 | int maxStackDepth; /* Maximum number of stack elements needed to |
---|
| 236 | * execute the code. Set by compilation |
---|
| 237 | * procedures before returning. */ |
---|
| 238 | int currStackDepth; /* Current stack depth. */ |
---|
| 239 | LiteralTable localLitTable; /* Contains LiteralEntry's describing all Tcl |
---|
| 240 | * objects referenced by this compiled code. |
---|
| 241 | * Indexed by the string representations of |
---|
| 242 | * the literals. Used to avoid creating |
---|
| 243 | * duplicate objects. */ |
---|
| 244 | unsigned char *codeStart; /* Points to the first byte of the code. */ |
---|
| 245 | unsigned char *codeNext; /* Points to next code array byte to use. */ |
---|
| 246 | unsigned char *codeEnd; /* Points just after the last allocated code |
---|
| 247 | * array byte. */ |
---|
| 248 | int mallocedCodeArray; /* Set 1 if code array was expanded and |
---|
| 249 | * codeStart points into the heap.*/ |
---|
| 250 | LiteralEntry *literalArrayPtr; |
---|
| 251 | /* Points to start of LiteralEntry array. */ |
---|
| 252 | int literalArrayNext; /* Index of next free object array entry. */ |
---|
| 253 | int literalArrayEnd; /* Index just after last obj array entry. */ |
---|
| 254 | int mallocedLiteralArray; /* 1 if object array was expanded and objArray |
---|
| 255 | * points into the heap, else 0. */ |
---|
| 256 | ExceptionRange *exceptArrayPtr; |
---|
| 257 | /* Points to start of the ExceptionRange |
---|
| 258 | * array. */ |
---|
| 259 | int exceptArrayNext; /* Next free ExceptionRange array index. |
---|
| 260 | * exceptArrayNext is the number of ranges and |
---|
| 261 | * (exceptArrayNext-1) is the index of the |
---|
| 262 | * current range's array entry. */ |
---|
| 263 | int exceptArrayEnd; /* Index after the last ExceptionRange array |
---|
| 264 | * entry. */ |
---|
| 265 | int mallocedExceptArray; /* 1 if ExceptionRange array was expanded and |
---|
| 266 | * exceptArrayPtr points in heap, else 0. */ |
---|
| 267 | CmdLocation *cmdMapPtr; /* Points to start of CmdLocation array. |
---|
| 268 | * numCommands is the index of the next entry |
---|
| 269 | * to use; (numCommands-1) is the entry index |
---|
| 270 | * for the last command. */ |
---|
| 271 | int cmdMapEnd; /* Index after last CmdLocation entry. */ |
---|
| 272 | int mallocedCmdMap; /* 1 if command map array was expanded and |
---|
| 273 | * cmdMapPtr points in the heap, else 0. */ |
---|
| 274 | AuxData *auxDataArrayPtr; /* Points to auxiliary data array start. */ |
---|
| 275 | int auxDataArrayNext; /* Next free compile aux data array index. |
---|
| 276 | * auxDataArrayNext is the number of aux data |
---|
| 277 | * items and (auxDataArrayNext-1) is index of |
---|
| 278 | * current aux data array entry. */ |
---|
| 279 | int auxDataArrayEnd; /* Index after last aux data array entry. */ |
---|
| 280 | int mallocedAuxDataArray; /* 1 if aux data array was expanded and |
---|
| 281 | * auxDataArrayPtr points in heap else 0. */ |
---|
| 282 | unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES]; |
---|
| 283 | /* Initial storage for code. */ |
---|
| 284 | LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS]; |
---|
| 285 | /* Initial storage of LiteralEntry array. */ |
---|
| 286 | ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES]; |
---|
| 287 | /* Initial ExceptionRange array storage. */ |
---|
| 288 | CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE]; |
---|
| 289 | /* Initial storage for cmd location map. */ |
---|
| 290 | AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE]; |
---|
| 291 | /* Initial storage for aux data array. */ |
---|
| 292 | /* TIP #280 */ |
---|
| 293 | ExtCmdLoc *extCmdMapPtr; /* Extended command location information for |
---|
| 294 | * 'info frame'. */ |
---|
| 295 | int line; /* First line of the script, based on the |
---|
| 296 | * invoking context, then the line of the |
---|
| 297 | * command currently compiled. */ |
---|
| 298 | int atCmdStart; /* Flag to say whether an INST_START_CMD |
---|
| 299 | * should be issued; they should never be |
---|
| 300 | * issued repeatedly, as that is significantly |
---|
| 301 | * inefficient. */ |
---|
| 302 | } CompileEnv; |
---|
| 303 | |
---|
| 304 | /* |
---|
| 305 | * The structure defining the bytecode instructions resulting from compiling a |
---|
| 306 | * Tcl script. Note that this structure is variable length: a single heap |
---|
| 307 | * object is allocated to hold the ByteCode structure immediately followed by |
---|
| 308 | * the code bytes, the literal object array, the ExceptionRange array, the |
---|
| 309 | * CmdLocation map, and the compilation AuxData array. |
---|
| 310 | */ |
---|
| 311 | |
---|
| 312 | /* |
---|
| 313 | * A PRECOMPILED bytecode struct is one that was generated from a compiled |
---|
| 314 | * image rather than implicitly compiled from source |
---|
| 315 | */ |
---|
| 316 | |
---|
| 317 | #define TCL_BYTECODE_PRECOMPILED 0x0001 |
---|
| 318 | |
---|
| 319 | /* |
---|
| 320 | * When a bytecode is compiled, interp or namespace resolvers have not been |
---|
| 321 | * applied yet: this is indicated by the TCL_BYTECODE_RESOLVE_VARS flag. |
---|
| 322 | */ |
---|
| 323 | |
---|
| 324 | #define TCL_BYTECODE_RESOLVE_VARS 0x0002 |
---|
| 325 | |
---|
| 326 | typedef struct ByteCode { |
---|
| 327 | TclHandle interpHandle; /* Handle for interpreter containing the |
---|
| 328 | * compiled code. Commands and their compile |
---|
| 329 | * procs are specific to an interpreter so the |
---|
| 330 | * code emitted will depend on the |
---|
| 331 | * interpreter. */ |
---|
| 332 | int compileEpoch; /* Value of iPtr->compileEpoch when this |
---|
| 333 | * ByteCode was compiled. Used to invalidate |
---|
| 334 | * code when, e.g., commands with compile |
---|
| 335 | * procs are redefined. */ |
---|
| 336 | Namespace *nsPtr; /* Namespace context in which this code was |
---|
| 337 | * compiled. If the code is executed if a |
---|
| 338 | * different namespace, it must be |
---|
| 339 | * recompiled. */ |
---|
| 340 | int nsEpoch; /* Value of nsPtr->resolverEpoch when this |
---|
| 341 | * ByteCode was compiled. Used to invalidate |
---|
| 342 | * code when new namespace resolution rules |
---|
| 343 | * are put into effect. */ |
---|
| 344 | int refCount; /* Reference count: set 1 when created plus 1 |
---|
| 345 | * for each execution of the code currently |
---|
| 346 | * active. This structure can be freed when |
---|
| 347 | * refCount becomes zero. */ |
---|
| 348 | unsigned int flags; /* flags describing state for the codebyte. |
---|
| 349 | * this variable holds ORed values from the |
---|
| 350 | * TCL_BYTECODE_ masks defined above */ |
---|
| 351 | const char *source; /* The source string from which this ByteCode |
---|
| 352 | * was compiled. Note that this pointer is not |
---|
| 353 | * owned by the ByteCode and must not be freed |
---|
| 354 | * or modified by it. */ |
---|
| 355 | Proc *procPtr; /* If the ByteCode was compiled from a |
---|
| 356 | * procedure body, this is a pointer to its |
---|
| 357 | * Proc structure; otherwise NULL. This |
---|
| 358 | * pointer is also not owned by the ByteCode |
---|
| 359 | * and must not be freed by it. */ |
---|
| 360 | size_t structureSize; /* Number of bytes in the ByteCode structure |
---|
| 361 | * itself. Does not include heap space for |
---|
| 362 | * literal Tcl objects or storage referenced |
---|
| 363 | * by AuxData entries. */ |
---|
| 364 | int numCommands; /* Number of commands compiled. */ |
---|
| 365 | int numSrcBytes; /* Number of source bytes compiled. */ |
---|
| 366 | int numCodeBytes; /* Number of code bytes. */ |
---|
| 367 | int numLitObjects; /* Number of objects in literal array. */ |
---|
| 368 | int numExceptRanges; /* Number of ExceptionRange array elems. */ |
---|
| 369 | int numAuxDataItems; /* Number of AuxData items. */ |
---|
| 370 | int numCmdLocBytes; /* Number of bytes needed for encoded command |
---|
| 371 | * location information. */ |
---|
| 372 | int maxExceptDepth; /* Maximum nesting level of ExceptionRanges; |
---|
| 373 | * -1 if no ranges were compiled. */ |
---|
| 374 | int maxStackDepth; /* Maximum number of stack elements needed to |
---|
| 375 | * execute the code. */ |
---|
| 376 | unsigned char *codeStart; /* Points to the first byte of the code. This |
---|
| 377 | * is just after the final ByteCode member |
---|
| 378 | * cmdMapPtr. */ |
---|
| 379 | Tcl_Obj **objArrayPtr; /* Points to the start of the literal object |
---|
| 380 | * array. This is just after the last code |
---|
| 381 | * byte. */ |
---|
| 382 | ExceptionRange *exceptArrayPtr; |
---|
| 383 | /* Points to the start of the ExceptionRange |
---|
| 384 | * array. This is just after the last object |
---|
| 385 | * in the object array. */ |
---|
| 386 | AuxData *auxDataArrayPtr; /* Points to the start of the auxiliary data |
---|
| 387 | * array. This is just after the last entry in |
---|
| 388 | * the ExceptionRange array. */ |
---|
| 389 | unsigned char *codeDeltaStart; |
---|
| 390 | /* Points to the first of a sequence of bytes |
---|
| 391 | * that encode the change in the starting |
---|
| 392 | * offset of each command's code. If -127 <= |
---|
| 393 | * delta <= 127, it is encoded as 1 byte, |
---|
| 394 | * otherwise 0xFF (128) appears and the delta |
---|
| 395 | * is encoded by the next 4 bytes. Code deltas |
---|
| 396 | * are always positive. This sequence is just |
---|
| 397 | * after the last entry in the AuxData |
---|
| 398 | * array. */ |
---|
| 399 | unsigned char *codeLengthStart; |
---|
| 400 | /* Points to the first of a sequence of bytes |
---|
| 401 | * that encode the length of each command's |
---|
| 402 | * code. The encoding is the same as for code |
---|
| 403 | * deltas. Code lengths are always positive. |
---|
| 404 | * This sequence is just after the last entry |
---|
| 405 | * in the code delta sequence. */ |
---|
| 406 | unsigned char *srcDeltaStart; |
---|
| 407 | /* Points to the first of a sequence of bytes |
---|
| 408 | * that encode the change in the starting |
---|
| 409 | * offset of each command's source. The |
---|
| 410 | * encoding is the same as for code deltas. |
---|
| 411 | * Source deltas can be negative. This |
---|
| 412 | * sequence is just after the last byte in the |
---|
| 413 | * code length sequence. */ |
---|
| 414 | unsigned char *srcLengthStart; |
---|
| 415 | /* Points to the first of a sequence of bytes |
---|
| 416 | * that encode the length of each command's |
---|
| 417 | * source. The encoding is the same as for |
---|
| 418 | * code deltas. Source lengths are always |
---|
| 419 | * positive. This sequence is just after the |
---|
| 420 | * last byte in the source delta sequence. */ |
---|
| 421 | LocalCache *localCachePtr; /* Pointer to the start of the cached variable |
---|
| 422 | * names and initialisation data for local |
---|
| 423 | * variables. */ |
---|
| 424 | #ifdef TCL_COMPILE_STATS |
---|
| 425 | Tcl_Time createTime; /* Absolute time when the ByteCode was |
---|
| 426 | * created. */ |
---|
| 427 | #endif /* TCL_COMPILE_STATS */ |
---|
| 428 | } ByteCode; |
---|
| 429 | |
---|
| 430 | /* |
---|
| 431 | * Opcodes for the Tcl bytecode instructions. These must correspond to the |
---|
| 432 | * entries in the table of instruction descriptions, tclInstructionTable, in |
---|
| 433 | * tclCompile.c. Also, the order and number of the expression opcodes (e.g., |
---|
| 434 | * INST_LOR) must match the entries in the array operatorStrings in |
---|
| 435 | * tclExecute.c. |
---|
| 436 | */ |
---|
| 437 | |
---|
| 438 | /* Opcodes 0 to 9 */ |
---|
| 439 | #define INST_DONE 0 |
---|
| 440 | #define INST_PUSH1 1 |
---|
| 441 | #define INST_PUSH4 2 |
---|
| 442 | #define INST_POP 3 |
---|
| 443 | #define INST_DUP 4 |
---|
| 444 | #define INST_CONCAT1 5 |
---|
| 445 | #define INST_INVOKE_STK1 6 |
---|
| 446 | #define INST_INVOKE_STK4 7 |
---|
| 447 | #define INST_EVAL_STK 8 |
---|
| 448 | #define INST_EXPR_STK 9 |
---|
| 449 | |
---|
| 450 | /* Opcodes 10 to 23 */ |
---|
| 451 | #define INST_LOAD_SCALAR1 10 |
---|
| 452 | #define INST_LOAD_SCALAR4 11 |
---|
| 453 | #define INST_LOAD_SCALAR_STK 12 |
---|
| 454 | #define INST_LOAD_ARRAY1 13 |
---|
| 455 | #define INST_LOAD_ARRAY4 14 |
---|
| 456 | #define INST_LOAD_ARRAY_STK 15 |
---|
| 457 | #define INST_LOAD_STK 16 |
---|
| 458 | #define INST_STORE_SCALAR1 17 |
---|
| 459 | #define INST_STORE_SCALAR4 18 |
---|
| 460 | #define INST_STORE_SCALAR_STK 19 |
---|
| 461 | #define INST_STORE_ARRAY1 20 |
---|
| 462 | #define INST_STORE_ARRAY4 21 |
---|
| 463 | #define INST_STORE_ARRAY_STK 22 |
---|
| 464 | #define INST_STORE_STK 23 |
---|
| 465 | |
---|
| 466 | /* Opcodes 24 to 33 */ |
---|
| 467 | #define INST_INCR_SCALAR1 24 |
---|
| 468 | #define INST_INCR_SCALAR_STK 25 |
---|
| 469 | #define INST_INCR_ARRAY1 26 |
---|
| 470 | #define INST_INCR_ARRAY_STK 27 |
---|
| 471 | #define INST_INCR_STK 28 |
---|
| 472 | #define INST_INCR_SCALAR1_IMM 29 |
---|
| 473 | #define INST_INCR_SCALAR_STK_IMM 30 |
---|
| 474 | #define INST_INCR_ARRAY1_IMM 31 |
---|
| 475 | #define INST_INCR_ARRAY_STK_IMM 32 |
---|
| 476 | #define INST_INCR_STK_IMM 33 |
---|
| 477 | |
---|
| 478 | /* Opcodes 34 to 39 */ |
---|
| 479 | #define INST_JUMP1 34 |
---|
| 480 | #define INST_JUMP4 35 |
---|
| 481 | #define INST_JUMP_TRUE1 36 |
---|
| 482 | #define INST_JUMP_TRUE4 37 |
---|
| 483 | #define INST_JUMP_FALSE1 38 |
---|
| 484 | #define INST_JUMP_FALSE4 39 |
---|
| 485 | |
---|
| 486 | /* Opcodes 40 to 64 */ |
---|
| 487 | #define INST_LOR 40 |
---|
| 488 | #define INST_LAND 41 |
---|
| 489 | #define INST_BITOR 42 |
---|
| 490 | #define INST_BITXOR 43 |
---|
| 491 | #define INST_BITAND 44 |
---|
| 492 | #define INST_EQ 45 |
---|
| 493 | #define INST_NEQ 46 |
---|
| 494 | #define INST_LT 47 |
---|
| 495 | #define INST_GT 48 |
---|
| 496 | #define INST_LE 49 |
---|
| 497 | #define INST_GE 50 |
---|
| 498 | #define INST_LSHIFT 51 |
---|
| 499 | #define INST_RSHIFT 52 |
---|
| 500 | #define INST_ADD 53 |
---|
| 501 | #define INST_SUB 54 |
---|
| 502 | #define INST_MULT 55 |
---|
| 503 | #define INST_DIV 56 |
---|
| 504 | #define INST_MOD 57 |
---|
| 505 | #define INST_UPLUS 58 |
---|
| 506 | #define INST_UMINUS 59 |
---|
| 507 | #define INST_BITNOT 60 |
---|
| 508 | #define INST_LNOT 61 |
---|
| 509 | #define INST_CALL_BUILTIN_FUNC1 62 |
---|
| 510 | #define INST_CALL_FUNC1 63 |
---|
| 511 | #define INST_TRY_CVT_TO_NUMERIC 64 |
---|
| 512 | |
---|
| 513 | /* Opcodes 65 to 66 */ |
---|
| 514 | #define INST_BREAK 65 |
---|
| 515 | #define INST_CONTINUE 66 |
---|
| 516 | |
---|
| 517 | /* Opcodes 67 to 68 */ |
---|
| 518 | #define INST_FOREACH_START4 67 |
---|
| 519 | #define INST_FOREACH_STEP4 68 |
---|
| 520 | |
---|
| 521 | /* Opcodes 69 to 72 */ |
---|
| 522 | #define INST_BEGIN_CATCH4 69 |
---|
| 523 | #define INST_END_CATCH 70 |
---|
| 524 | #define INST_PUSH_RESULT 71 |
---|
| 525 | #define INST_PUSH_RETURN_CODE 72 |
---|
| 526 | |
---|
| 527 | /* Opcodes 73 to 78 */ |
---|
| 528 | #define INST_STR_EQ 73 |
---|
| 529 | #define INST_STR_NEQ 74 |
---|
| 530 | #define INST_STR_CMP 75 |
---|
| 531 | #define INST_STR_LEN 76 |
---|
| 532 | #define INST_STR_INDEX 77 |
---|
| 533 | #define INST_STR_MATCH 78 |
---|
| 534 | |
---|
| 535 | /* Opcodes 78 to 81 */ |
---|
| 536 | #define INST_LIST 79 |
---|
| 537 | #define INST_LIST_INDEX 80 |
---|
| 538 | #define INST_LIST_LENGTH 81 |
---|
| 539 | |
---|
| 540 | /* Opcodes 82 to 87 */ |
---|
| 541 | #define INST_APPEND_SCALAR1 82 |
---|
| 542 | #define INST_APPEND_SCALAR4 83 |
---|
| 543 | #define INST_APPEND_ARRAY1 84 |
---|
| 544 | #define INST_APPEND_ARRAY4 85 |
---|
| 545 | #define INST_APPEND_ARRAY_STK 86 |
---|
| 546 | #define INST_APPEND_STK 87 |
---|
| 547 | |
---|
| 548 | /* Opcodes 88 to 93 */ |
---|
| 549 | #define INST_LAPPEND_SCALAR1 88 |
---|
| 550 | #define INST_LAPPEND_SCALAR4 89 |
---|
| 551 | #define INST_LAPPEND_ARRAY1 90 |
---|
| 552 | #define INST_LAPPEND_ARRAY4 91 |
---|
| 553 | #define INST_LAPPEND_ARRAY_STK 92 |
---|
| 554 | #define INST_LAPPEND_STK 93 |
---|
| 555 | |
---|
| 556 | /* TIP #22 - LINDEX operator with flat arg list */ |
---|
| 557 | |
---|
| 558 | #define INST_LIST_INDEX_MULTI 94 |
---|
| 559 | |
---|
| 560 | /* |
---|
| 561 | * TIP #33 - 'lset' command. Code gen also required a Forth-like |
---|
| 562 | * OVER operation. |
---|
| 563 | */ |
---|
| 564 | |
---|
| 565 | #define INST_OVER 95 |
---|
| 566 | #define INST_LSET_LIST 96 |
---|
| 567 | #define INST_LSET_FLAT 97 |
---|
| 568 | |
---|
| 569 | /* TIP#90 - 'return' command. */ |
---|
| 570 | |
---|
| 571 | #define INST_RETURN_IMM 98 |
---|
| 572 | |
---|
| 573 | /* TIP#123 - exponentiation operator. */ |
---|
| 574 | |
---|
| 575 | #define INST_EXPON 99 |
---|
| 576 | |
---|
| 577 | /* TIP #157 - {*}... (word expansion) language syntax support. */ |
---|
| 578 | |
---|
| 579 | #define INST_EXPAND_START 100 |
---|
| 580 | #define INST_EXPAND_STKTOP 101 |
---|
| 581 | #define INST_INVOKE_EXPANDED 102 |
---|
| 582 | |
---|
| 583 | /* |
---|
| 584 | * TIP #57 - 'lassign' command. Code generation requires immediate |
---|
| 585 | * LINDEX and LRANGE operators. |
---|
| 586 | */ |
---|
| 587 | |
---|
| 588 | #define INST_LIST_INDEX_IMM 103 |
---|
| 589 | #define INST_LIST_RANGE_IMM 104 |
---|
| 590 | |
---|
| 591 | #define INST_START_CMD 105 |
---|
| 592 | |
---|
| 593 | #define INST_LIST_IN 106 |
---|
| 594 | #define INST_LIST_NOT_IN 107 |
---|
| 595 | |
---|
| 596 | #define INST_PUSH_RETURN_OPTIONS 108 |
---|
| 597 | #define INST_RETURN_STK 109 |
---|
| 598 | |
---|
| 599 | /* |
---|
| 600 | * Dictionary (TIP#111) related commands. |
---|
| 601 | */ |
---|
| 602 | |
---|
| 603 | #define INST_DICT_GET 110 |
---|
| 604 | #define INST_DICT_SET 111 |
---|
| 605 | #define INST_DICT_UNSET 112 |
---|
| 606 | #define INST_DICT_INCR_IMM 113 |
---|
| 607 | #define INST_DICT_APPEND 114 |
---|
| 608 | #define INST_DICT_LAPPEND 115 |
---|
| 609 | #define INST_DICT_FIRST 116 |
---|
| 610 | #define INST_DICT_NEXT 117 |
---|
| 611 | #define INST_DICT_DONE 118 |
---|
| 612 | #define INST_DICT_UPDATE_START 119 |
---|
| 613 | #define INST_DICT_UPDATE_END 120 |
---|
| 614 | |
---|
| 615 | /* |
---|
| 616 | * Instruction to support jumps defined by tables (instead of the classic |
---|
| 617 | * [switch] technique of chained comparisons). |
---|
| 618 | */ |
---|
| 619 | |
---|
| 620 | #define INST_JUMP_TABLE 121 |
---|
| 621 | |
---|
| 622 | /* |
---|
| 623 | * Instructions to support compilation of global, variable, upvar and |
---|
| 624 | * [namespace upvar]. |
---|
| 625 | */ |
---|
| 626 | |
---|
| 627 | #define INST_UPVAR 122 |
---|
| 628 | #define INST_NSUPVAR 123 |
---|
| 629 | #define INST_VARIABLE 124 |
---|
| 630 | |
---|
| 631 | /* Instruction to support compiling syntax error to bytecode */ |
---|
| 632 | |
---|
| 633 | #define INST_SYNTAX 125 |
---|
| 634 | |
---|
| 635 | /* Instruction to reverse N items on top of stack */ |
---|
| 636 | |
---|
| 637 | #define INST_REVERSE 126 |
---|
| 638 | |
---|
| 639 | /* regexp instruction */ |
---|
| 640 | |
---|
| 641 | #define INST_REGEXP 127 |
---|
| 642 | |
---|
| 643 | /* For [info exists] compilation */ |
---|
| 644 | #define INST_EXIST_SCALAR 128 |
---|
| 645 | #define INST_EXIST_ARRAY 129 |
---|
| 646 | #define INST_EXIST_ARRAY_STK 130 |
---|
| 647 | #define INST_EXIST_STK 131 |
---|
| 648 | |
---|
| 649 | /* The last opcode */ |
---|
| 650 | #define LAST_INST_OPCODE 131 |
---|
| 651 | |
---|
| 652 | /* |
---|
| 653 | * Table describing the Tcl bytecode instructions: their name (for displaying |
---|
| 654 | * code), total number of code bytes required (including operand bytes), and a |
---|
| 655 | * description of the type of each operand. These operand types include signed |
---|
| 656 | * and unsigned integers of length one and four bytes. The unsigned integers |
---|
| 657 | * are used for indexes or for, e.g., the count of objects to push in a "push" |
---|
| 658 | * instruction. |
---|
| 659 | */ |
---|
| 660 | |
---|
| 661 | #define MAX_INSTRUCTION_OPERANDS 2 |
---|
| 662 | |
---|
| 663 | typedef enum InstOperandType { |
---|
| 664 | OPERAND_NONE, |
---|
| 665 | OPERAND_INT1, /* One byte signed integer. */ |
---|
| 666 | OPERAND_INT4, /* Four byte signed integer. */ |
---|
| 667 | OPERAND_UINT1, /* One byte unsigned integer. */ |
---|
| 668 | OPERAND_UINT4, /* Four byte unsigned integer. */ |
---|
| 669 | OPERAND_IDX4, /* Four byte signed index (actually an |
---|
| 670 | * integer, but displayed differently.) */ |
---|
| 671 | OPERAND_LVT1, /* One byte unsigned index into the local |
---|
| 672 | * variable table. */ |
---|
| 673 | OPERAND_LVT4, /* Four byte unsigned index into the local |
---|
| 674 | * variable table. */ |
---|
| 675 | OPERAND_AUX4 /* Four byte unsigned index into the aux data |
---|
| 676 | * table. */ |
---|
| 677 | } InstOperandType; |
---|
| 678 | |
---|
| 679 | typedef struct InstructionDesc { |
---|
| 680 | char *name; /* Name of instruction. */ |
---|
| 681 | int numBytes; /* Total number of bytes for instruction. */ |
---|
| 682 | int stackEffect; /* The worst-case balance stack effect of the |
---|
| 683 | * instruction, used for stack requirements |
---|
| 684 | * computations. The value INT_MIN signals |
---|
| 685 | * that the instruction's worst case effect is |
---|
| 686 | * (1-opnd1). */ |
---|
| 687 | int numOperands; /* Number of operands. */ |
---|
| 688 | InstOperandType opTypes[MAX_INSTRUCTION_OPERANDS]; |
---|
| 689 | /* The type of each operand. */ |
---|
| 690 | } InstructionDesc; |
---|
| 691 | |
---|
| 692 | MODULE_SCOPE InstructionDesc tclInstructionTable[]; |
---|
| 693 | |
---|
| 694 | /* |
---|
| 695 | * Compilation of some Tcl constructs such as if commands and the logical or |
---|
| 696 | * (||) and logical and (&&) operators in expressions requires the generation |
---|
| 697 | * of forward jumps. Since the PC target of these jumps isn't known when the |
---|
| 698 | * jumps are emitted, we record the offset of each jump in an array of |
---|
| 699 | * JumpFixup structures. There is one array for each sequence of jumps to one |
---|
| 700 | * target PC. When we learn the target PC, we update the jumps with the |
---|
| 701 | * correct distance. Also, if the distance is too great (> 127 bytes), we |
---|
| 702 | * replace the single-byte jump with a four byte jump instruction, move the |
---|
| 703 | * instructions after the jump down, and update the code offsets for any |
---|
| 704 | * commands between the jump and the target. |
---|
| 705 | */ |
---|
| 706 | |
---|
| 707 | typedef enum { |
---|
| 708 | TCL_UNCONDITIONAL_JUMP, |
---|
| 709 | TCL_TRUE_JUMP, |
---|
| 710 | TCL_FALSE_JUMP |
---|
| 711 | } TclJumpType; |
---|
| 712 | |
---|
| 713 | typedef struct JumpFixup { |
---|
| 714 | TclJumpType jumpType; /* Indicates the kind of jump. */ |
---|
| 715 | int codeOffset; /* Offset of the first byte of the one-byte |
---|
| 716 | * forward jump's code. */ |
---|
| 717 | int cmdIndex; /* Index of the first command after the one |
---|
| 718 | * for which the jump was emitted. Used to |
---|
| 719 | * update the code offsets for subsequent |
---|
| 720 | * commands if the two-byte jump at jumpPc |
---|
| 721 | * must be replaced with a five-byte one. */ |
---|
| 722 | int exceptIndex; /* Index of the first range entry in the |
---|
| 723 | * ExceptionRange array after the current one. |
---|
| 724 | * This field is used to adjust the code |
---|
| 725 | * offsets in subsequent ExceptionRange |
---|
| 726 | * records when a jump is grown from 2 bytes |
---|
| 727 | * to 5 bytes. */ |
---|
| 728 | } JumpFixup; |
---|
| 729 | |
---|
| 730 | #define JUMPFIXUP_INIT_ENTRIES 10 |
---|
| 731 | |
---|
| 732 | typedef struct JumpFixupArray { |
---|
| 733 | JumpFixup *fixup; /* Points to start of jump fixup array. */ |
---|
| 734 | int next; /* Index of next free array entry. */ |
---|
| 735 | int end; /* Index of last usable entry in array. */ |
---|
| 736 | int mallocedArray; /* 1 if array was expanded and fixups points |
---|
| 737 | * into the heap, else 0. */ |
---|
| 738 | JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES]; |
---|
| 739 | /* Initial storage for jump fixup array. */ |
---|
| 740 | } JumpFixupArray; |
---|
| 741 | |
---|
| 742 | /* |
---|
| 743 | * The structure describing one variable list of a foreach command. Note that |
---|
| 744 | * only foreach commands inside procedure bodies are compiled inline so a |
---|
| 745 | * ForeachVarList structure always describes local variables. Furthermore, |
---|
| 746 | * only scalar variables are supported for inline-compiled foreach loops. |
---|
| 747 | */ |
---|
| 748 | |
---|
| 749 | typedef struct ForeachVarList { |
---|
| 750 | int numVars; /* The number of variables in the list. */ |
---|
| 751 | int varIndexes[1]; /* An array of the indexes ("slot numbers") |
---|
| 752 | * for each variable in the procedure's array |
---|
| 753 | * of local variables. Only scalar variables |
---|
| 754 | * are supported. The actual size of this |
---|
| 755 | * field will be large enough to numVars |
---|
| 756 | * indexes. THIS MUST BE THE LAST FIELD IN THE |
---|
| 757 | * STRUCTURE! */ |
---|
| 758 | } ForeachVarList; |
---|
| 759 | |
---|
| 760 | /* |
---|
| 761 | * Structure used to hold information about a foreach command that is needed |
---|
| 762 | * during program execution. These structures are stored in CompileEnv and |
---|
| 763 | * ByteCode structures as auxiliary data. |
---|
| 764 | */ |
---|
| 765 | |
---|
| 766 | typedef struct ForeachInfo { |
---|
| 767 | int numLists; /* The number of both the variable and value |
---|
| 768 | * lists of the foreach command. */ |
---|
| 769 | int firstValueTemp; /* Index of the first temp var in a proc frame |
---|
| 770 | * used to point to a value list. */ |
---|
| 771 | int loopCtTemp; /* Index of temp var in a proc frame holding |
---|
| 772 | * the loop's iteration count. Used to |
---|
| 773 | * determine next value list element to assign |
---|
| 774 | * each loop var. */ |
---|
| 775 | ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList |
---|
| 776 | * structures describing each var list. The |
---|
| 777 | * actual size of this field will be large |
---|
| 778 | * enough to numVars indexes. THIS MUST BE THE |
---|
| 779 | * LAST FIELD IN THE STRUCTURE! */ |
---|
| 780 | } ForeachInfo; |
---|
| 781 | |
---|
| 782 | MODULE_SCOPE AuxDataType tclForeachInfoType; |
---|
| 783 | |
---|
| 784 | /* |
---|
| 785 | * Structure used to hold information about a switch command that is needed |
---|
| 786 | * during program execution. These structures are stored in CompileEnv and |
---|
| 787 | * ByteCode structures as auxiliary data. |
---|
| 788 | */ |
---|
| 789 | |
---|
| 790 | typedef struct JumptableInfo { |
---|
| 791 | Tcl_HashTable hashTable; /* Hash that maps strings to signed ints (PC |
---|
| 792 | * offsets). */ |
---|
| 793 | } JumptableInfo; |
---|
| 794 | |
---|
| 795 | MODULE_SCOPE AuxDataType tclJumptableInfoType; |
---|
| 796 | |
---|
| 797 | /* |
---|
| 798 | * Structure used to hold information about a [dict update] command that is |
---|
| 799 | * needed during program execution. These structures are stored in CompileEnv |
---|
| 800 | * and ByteCode structures as auxiliary data. |
---|
| 801 | */ |
---|
| 802 | |
---|
| 803 | typedef struct { |
---|
| 804 | int length; /* Size of array */ |
---|
| 805 | int varIndices[1]; /* Array of variable indices to manage when |
---|
| 806 | * processing the start and end of a [dict |
---|
| 807 | * update]. There is really more than one |
---|
| 808 | * entry, and the structure is allocated to |
---|
| 809 | * take account of this. MUST BE LAST FIELD IN |
---|
| 810 | * STRUCTURE. */ |
---|
| 811 | } DictUpdateInfo; |
---|
| 812 | |
---|
| 813 | MODULE_SCOPE AuxDataType tclDictUpdateInfoType; |
---|
| 814 | |
---|
| 815 | /* |
---|
| 816 | * ClientData type used by the math operator commands. |
---|
| 817 | */ |
---|
| 818 | |
---|
| 819 | typedef struct { |
---|
| 820 | const char *op; /* Do not call it 'operator': C++ reserved */ |
---|
| 821 | const char *expected; |
---|
| 822 | union { |
---|
| 823 | int numArgs; |
---|
| 824 | int identity; |
---|
| 825 | } i; |
---|
| 826 | } TclOpCmdClientData; |
---|
| 827 | |
---|
| 828 | /* |
---|
| 829 | *---------------------------------------------------------------- |
---|
| 830 | * Procedures exported by tclBasic.c to be used within the engine. |
---|
| 831 | *---------------------------------------------------------------- |
---|
| 832 | */ |
---|
| 833 | |
---|
| 834 | MODULE_SCOPE int TclEvalObjvInternal(Tcl_Interp *interp, |
---|
| 835 | int objc, Tcl_Obj *const objv[], |
---|
| 836 | CONST char *command, int length, int flags); |
---|
| 837 | /* |
---|
| 838 | *---------------------------------------------------------------- |
---|
| 839 | * Procedures exported by the engine to be used by tclBasic.c |
---|
| 840 | *---------------------------------------------------------------- |
---|
| 841 | */ |
---|
| 842 | |
---|
| 843 | MODULE_SCOPE int TclCompEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr, |
---|
| 844 | const CmdFrame *invoker, int word); |
---|
| 845 | |
---|
| 846 | /* |
---|
| 847 | *---------------------------------------------------------------- |
---|
| 848 | * Procedures shared among Tcl bytecode compilation and execution modules but |
---|
| 849 | * not used outside: |
---|
| 850 | *---------------------------------------------------------------- |
---|
| 851 | */ |
---|
| 852 | |
---|
| 853 | MODULE_SCOPE void TclCleanupByteCode(ByteCode *codePtr); |
---|
| 854 | MODULE_SCOPE void TclCompileCmdWord(Tcl_Interp *interp, |
---|
| 855 | Tcl_Token *tokenPtr, int count, |
---|
| 856 | CompileEnv *envPtr); |
---|
| 857 | MODULE_SCOPE void TclCompileExpr(Tcl_Interp *interp, CONST char *script, |
---|
| 858 | int numBytes, CompileEnv *envPtr, int optimize); |
---|
| 859 | MODULE_SCOPE void TclCompileExprWords(Tcl_Interp *interp, |
---|
| 860 | Tcl_Token *tokenPtr, int numWords, |
---|
| 861 | CompileEnv *envPtr); |
---|
| 862 | MODULE_SCOPE void TclCompileScript(Tcl_Interp *interp, |
---|
| 863 | CONST char *script, int numBytes, |
---|
| 864 | CompileEnv *envPtr); |
---|
| 865 | MODULE_SCOPE void TclCompileSyntaxError(Tcl_Interp *interp, |
---|
| 866 | CompileEnv *envPtr); |
---|
| 867 | MODULE_SCOPE void TclCompileTokens(Tcl_Interp *interp, |
---|
| 868 | Tcl_Token *tokenPtr, int count, |
---|
| 869 | CompileEnv *envPtr); |
---|
| 870 | MODULE_SCOPE int TclCreateAuxData(ClientData clientData, |
---|
| 871 | AuxDataType *typePtr, CompileEnv *envPtr); |
---|
| 872 | MODULE_SCOPE int TclCreateExceptRange(ExceptionRangeType type, |
---|
| 873 | CompileEnv *envPtr); |
---|
| 874 | MODULE_SCOPE ExecEnv * TclCreateExecEnv(Tcl_Interp *interp); |
---|
| 875 | MODULE_SCOPE Tcl_Obj * TclCreateLiteral(Interp *iPtr, char *bytes, |
---|
| 876 | int length, unsigned int hash, int *newPtr, |
---|
| 877 | Namespace *nsPtr, int flags, |
---|
| 878 | LiteralEntry **globalPtrPtr); |
---|
| 879 | MODULE_SCOPE void TclDeleteExecEnv(ExecEnv *eePtr); |
---|
| 880 | MODULE_SCOPE void TclDeleteLiteralTable(Tcl_Interp *interp, |
---|
| 881 | LiteralTable *tablePtr); |
---|
| 882 | MODULE_SCOPE void TclEmitForwardJump(CompileEnv *envPtr, |
---|
| 883 | TclJumpType jumpType, JumpFixup *jumpFixupPtr); |
---|
| 884 | MODULE_SCOPE ExceptionRange * TclGetExceptionRangeForPc(unsigned char *pc, |
---|
| 885 | int catchOnly, ByteCode* codePtr); |
---|
| 886 | MODULE_SCOPE void TclExpandJumpFixupArray(JumpFixupArray *fixupArrayPtr); |
---|
| 887 | MODULE_SCOPE int TclExecuteByteCode(Tcl_Interp *interp, |
---|
| 888 | ByteCode *codePtr); |
---|
| 889 | MODULE_SCOPE void TclFinalizeAuxDataTypeTable(void); |
---|
| 890 | MODULE_SCOPE int TclFindCompiledLocal(CONST char *name, int nameChars, |
---|
| 891 | int create, Proc *procPtr); |
---|
| 892 | MODULE_SCOPE LiteralEntry * TclLookupLiteralEntry(Tcl_Interp *interp, |
---|
| 893 | Tcl_Obj *objPtr); |
---|
| 894 | MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr, |
---|
| 895 | JumpFixup *jumpFixupPtr, int jumpDist, |
---|
| 896 | int distThreshold); |
---|
| 897 | MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr); |
---|
| 898 | MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr); |
---|
| 899 | MODULE_SCOPE void TclInitAuxDataTypeTable(void); |
---|
| 900 | MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr, |
---|
| 901 | CompileEnv *envPtr); |
---|
| 902 | MODULE_SCOPE void TclInitCompilation(void); |
---|
| 903 | MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp, |
---|
| 904 | CompileEnv *envPtr, const char *string, |
---|
| 905 | int numBytes, CONST CmdFrame* invoker, int word); |
---|
| 906 | MODULE_SCOPE void TclInitJumpFixupArray(JumpFixupArray *fixupArrayPtr); |
---|
| 907 | MODULE_SCOPE void TclInitLiteralTable(LiteralTable *tablePtr); |
---|
| 908 | #ifdef TCL_COMPILE_STATS |
---|
| 909 | MODULE_SCOPE char * TclLiteralStats(LiteralTable *tablePtr); |
---|
| 910 | MODULE_SCOPE int TclLog2(int value); |
---|
| 911 | #endif |
---|
| 912 | #ifdef TCL_COMPILE_DEBUG |
---|
| 913 | MODULE_SCOPE void TclPrintByteCodeObj(Tcl_Interp *interp, |
---|
| 914 | Tcl_Obj *objPtr); |
---|
| 915 | #endif |
---|
| 916 | MODULE_SCOPE int TclPrintInstruction(ByteCode* codePtr, |
---|
| 917 | unsigned char *pc); |
---|
| 918 | MODULE_SCOPE void TclPrintObject(FILE *outFile, |
---|
| 919 | Tcl_Obj *objPtr, int maxChars); |
---|
| 920 | MODULE_SCOPE void TclPrintSource(FILE *outFile, |
---|
| 921 | CONST char *string, int maxChars); |
---|
| 922 | MODULE_SCOPE void TclRegisterAuxDataType(AuxDataType *typePtr); |
---|
| 923 | MODULE_SCOPE int TclRegisterLiteral(CompileEnv *envPtr, |
---|
| 924 | char *bytes, int length, int flags); |
---|
| 925 | MODULE_SCOPE void TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr); |
---|
| 926 | MODULE_SCOPE int TclSingleOpCmd(ClientData clientData, |
---|
| 927 | Tcl_Interp *interp, int objc, |
---|
| 928 | Tcl_Obj *CONST objv[]); |
---|
| 929 | MODULE_SCOPE int TclSortingOpCmd(ClientData clientData, |
---|
| 930 | Tcl_Interp *interp, int objc, |
---|
| 931 | Tcl_Obj *CONST objv[]); |
---|
| 932 | MODULE_SCOPE int TclVariadicOpCmd(ClientData clientData, |
---|
| 933 | Tcl_Interp *interp, int objc, |
---|
| 934 | Tcl_Obj *CONST objv[]); |
---|
| 935 | MODULE_SCOPE int TclNoIdentOpCmd(ClientData clientData, |
---|
| 936 | Tcl_Interp *interp, int objc, |
---|
| 937 | Tcl_Obj *CONST objv[]); |
---|
| 938 | #ifdef TCL_COMPILE_DEBUG |
---|
| 939 | MODULE_SCOPE void TclVerifyGlobalLiteralTable(Interp *iPtr); |
---|
| 940 | MODULE_SCOPE void TclVerifyLocalLiteralTable(CompileEnv *envPtr); |
---|
| 941 | #endif |
---|
| 942 | MODULE_SCOPE int TclWordKnownAtCompileTime(Tcl_Token *tokenPtr, |
---|
| 943 | Tcl_Obj *valuePtr); |
---|
| 944 | |
---|
| 945 | /* |
---|
| 946 | *---------------------------------------------------------------- |
---|
| 947 | * Macros and flag values used by Tcl bytecode compilation and execution |
---|
| 948 | * modules inside the Tcl core but not used outside. |
---|
| 949 | *---------------------------------------------------------------- |
---|
| 950 | */ |
---|
| 951 | |
---|
| 952 | #define LITERAL_ON_HEAP 0x01 |
---|
| 953 | #define LITERAL_NS_SCOPE 0x02 |
---|
| 954 | |
---|
| 955 | /* |
---|
| 956 | * Form of TclRegisterLiteral with onHeap == 0. In that case, it is safe to |
---|
| 957 | * cast away CONSTness, and it is cleanest to do that here, all in one place. |
---|
| 958 | * |
---|
| 959 | * int TclRegisterNewLiteral(CompileEnv *envPtr, const char *bytes, |
---|
| 960 | * int length); |
---|
| 961 | */ |
---|
| 962 | |
---|
| 963 | #define TclRegisterNewLiteral(envPtr, bytes, length) \ |
---|
| 964 | TclRegisterLiteral(envPtr, (char *)(bytes), length, /*flags*/ 0) |
---|
| 965 | |
---|
| 966 | /* |
---|
| 967 | * Form of TclRegisterNSLiteral with onHeap == 0. In that case, it is safe to |
---|
| 968 | * cast away CONSTness, and it is cleanest to do that here, all in one place. |
---|
| 969 | * |
---|
| 970 | * int TclRegisterNewNSLiteral(CompileEnv *envPtr, const char *bytes, |
---|
| 971 | * int length); |
---|
| 972 | */ |
---|
| 973 | |
---|
| 974 | #define TclRegisterNewNSLiteral(envPtr, bytes, length) \ |
---|
| 975 | TclRegisterLiteral(envPtr, (char *)(bytes), length, \ |
---|
| 976 | /*flags*/ LITERAL_NS_SCOPE) |
---|
| 977 | |
---|
| 978 | /* |
---|
| 979 | * Macro used to manually adjust the stack requirements; used in cases where |
---|
| 980 | * the stack effect cannot be computed from the opcode and its operands, but |
---|
| 981 | * is still known at compile time. |
---|
| 982 | * |
---|
| 983 | * void TclAdjustStackDepth(int delta, CompileEnv *envPtr); |
---|
| 984 | */ |
---|
| 985 | |
---|
| 986 | #define TclAdjustStackDepth(delta, envPtr) \ |
---|
| 987 | if ((delta) < 0) {\ |
---|
| 988 | if((envPtr)->maxStackDepth < (envPtr)->currStackDepth) {\ |
---|
| 989 | (envPtr)->maxStackDepth = (envPtr)->currStackDepth;\ |
---|
| 990 | }\ |
---|
| 991 | }\ |
---|
| 992 | (envPtr)->currStackDepth += (delta) |
---|
| 993 | |
---|
| 994 | /* |
---|
| 995 | * Macro used to update the stack requirements. It is called by the macros |
---|
| 996 | * TclEmitOpCode, TclEmitInst1 and TclEmitInst4. |
---|
| 997 | * Remark that the very last instruction of a bytecode always reduces the |
---|
| 998 | * stack level: INST_DONE or INST_POP, so that the maxStackdepth is always |
---|
| 999 | * updated. |
---|
| 1000 | * |
---|
| 1001 | * void TclUpdateStackReqs(unsigned char op, int i, CompileEnv *envPtr); |
---|
| 1002 | */ |
---|
| 1003 | |
---|
| 1004 | #define TclUpdateStackReqs(op, i, envPtr) \ |
---|
| 1005 | {\ |
---|
| 1006 | int delta = tclInstructionTable[(op)].stackEffect;\ |
---|
| 1007 | if (delta) {\ |
---|
| 1008 | if (delta == INT_MIN) {\ |
---|
| 1009 | delta = 1 - (i);\ |
---|
| 1010 | }\ |
---|
| 1011 | TclAdjustStackDepth(delta, envPtr);\ |
---|
| 1012 | }\ |
---|
| 1013 | } |
---|
| 1014 | |
---|
| 1015 | /* |
---|
| 1016 | * Macro to emit an opcode byte into a CompileEnv's code array. The ANSI C |
---|
| 1017 | * "prototype" for this macro is: |
---|
| 1018 | * |
---|
| 1019 | * void TclEmitOpcode(unsigned char op, CompileEnv *envPtr); |
---|
| 1020 | */ |
---|
| 1021 | |
---|
| 1022 | #define TclEmitOpcode(op, envPtr) \ |
---|
| 1023 | if ((envPtr)->codeNext == (envPtr)->codeEnd) { \ |
---|
| 1024 | TclExpandCodeArray(envPtr); \ |
---|
| 1025 | } \ |
---|
| 1026 | *(envPtr)->codeNext++ = (unsigned char) (op);\ |
---|
| 1027 | (envPtr)->atCmdStart = ((op) == INST_START_CMD); \ |
---|
| 1028 | TclUpdateStackReqs(op, 0, envPtr) |
---|
| 1029 | |
---|
| 1030 | /* |
---|
| 1031 | * Macros to emit an integer operand. The ANSI C "prototype" for these macros |
---|
| 1032 | * are: |
---|
| 1033 | * |
---|
| 1034 | * void TclEmitInt1(int i, CompileEnv *envPtr); |
---|
| 1035 | * void TclEmitInt4(int i, CompileEnv *envPtr); |
---|
| 1036 | */ |
---|
| 1037 | |
---|
| 1038 | #define TclEmitInt1(i, envPtr) \ |
---|
| 1039 | if ((envPtr)->codeNext == (envPtr)->codeEnd) { \ |
---|
| 1040 | TclExpandCodeArray(envPtr); \ |
---|
| 1041 | } \ |
---|
| 1042 | *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i)) |
---|
| 1043 | |
---|
| 1044 | #define TclEmitInt4(i, envPtr) \ |
---|
| 1045 | if (((envPtr)->codeNext + 4) > (envPtr)->codeEnd) { \ |
---|
| 1046 | TclExpandCodeArray(envPtr); \ |
---|
| 1047 | } \ |
---|
| 1048 | *(envPtr)->codeNext++ = \ |
---|
| 1049 | (unsigned char) ((unsigned int) (i) >> 24); \ |
---|
| 1050 | *(envPtr)->codeNext++ = \ |
---|
| 1051 | (unsigned char) ((unsigned int) (i) >> 16); \ |
---|
| 1052 | *(envPtr)->codeNext++ = \ |
---|
| 1053 | (unsigned char) ((unsigned int) (i) >> 8); \ |
---|
| 1054 | *(envPtr)->codeNext++ = \ |
---|
| 1055 | (unsigned char) ((unsigned int) (i) ) |
---|
| 1056 | |
---|
| 1057 | /* |
---|
| 1058 | * Macros to emit an instruction with signed or unsigned integer operands. |
---|
| 1059 | * Four byte integers are stored in "big-endian" order with the high order |
---|
| 1060 | * byte stored at the lowest address. The ANSI C "prototypes" for these macros |
---|
| 1061 | * are: |
---|
| 1062 | * |
---|
| 1063 | * void TclEmitInstInt1(unsigned char op, int i, CompileEnv *envPtr); |
---|
| 1064 | * void TclEmitInstInt4(unsigned char op, int i, CompileEnv *envPtr); |
---|
| 1065 | */ |
---|
| 1066 | |
---|
| 1067 | #define TclEmitInstInt1(op, i, envPtr) \ |
---|
| 1068 | if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) { \ |
---|
| 1069 | TclExpandCodeArray(envPtr); \ |
---|
| 1070 | } \ |
---|
| 1071 | *(envPtr)->codeNext++ = (unsigned char) (op); \ |
---|
| 1072 | *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i));\ |
---|
| 1073 | (envPtr)->atCmdStart = ((op) == INST_START_CMD); \ |
---|
| 1074 | TclUpdateStackReqs(op, i, envPtr) |
---|
| 1075 | |
---|
| 1076 | #define TclEmitInstInt4(op, i, envPtr) \ |
---|
| 1077 | if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \ |
---|
| 1078 | TclExpandCodeArray(envPtr); \ |
---|
| 1079 | } \ |
---|
| 1080 | *(envPtr)->codeNext++ = (unsigned char) (op); \ |
---|
| 1081 | *(envPtr)->codeNext++ = \ |
---|
| 1082 | (unsigned char) ((unsigned int) (i) >> 24); \ |
---|
| 1083 | *(envPtr)->codeNext++ = \ |
---|
| 1084 | (unsigned char) ((unsigned int) (i) >> 16); \ |
---|
| 1085 | *(envPtr)->codeNext++ = \ |
---|
| 1086 | (unsigned char) ((unsigned int) (i) >> 8); \ |
---|
| 1087 | *(envPtr)->codeNext++ = \ |
---|
| 1088 | (unsigned char) ((unsigned int) (i) );\ |
---|
| 1089 | (envPtr)->atCmdStart = ((op) == INST_START_CMD); \ |
---|
| 1090 | TclUpdateStackReqs(op, i, envPtr) |
---|
| 1091 | |
---|
| 1092 | /* |
---|
| 1093 | * Macro to push a Tcl object onto the Tcl evaluation stack. It emits the |
---|
| 1094 | * object's one or four byte array index into the CompileEnv's code array. |
---|
| 1095 | * These support, respectively, a maximum of 256 (2**8) and 2**32 objects in a |
---|
| 1096 | * CompileEnv. The ANSI C "prototype" for this macro is: |
---|
| 1097 | * |
---|
| 1098 | * void TclEmitPush(int objIndex, CompileEnv *envPtr); |
---|
| 1099 | */ |
---|
| 1100 | |
---|
| 1101 | #define TclEmitPush(objIndex, envPtr) \ |
---|
| 1102 | {\ |
---|
| 1103 | register int objIndexCopy = (objIndex);\ |
---|
| 1104 | if (objIndexCopy <= 255) { \ |
---|
| 1105 | TclEmitInstInt1(INST_PUSH1, objIndexCopy, (envPtr)); \ |
---|
| 1106 | } else { \ |
---|
| 1107 | TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \ |
---|
| 1108 | }\ |
---|
| 1109 | } |
---|
| 1110 | |
---|
| 1111 | /* |
---|
| 1112 | * Macros to update a (signed or unsigned) integer starting at a pointer. The |
---|
| 1113 | * two variants depend on the number of bytes. The ANSI C "prototypes" for |
---|
| 1114 | * these macros are: |
---|
| 1115 | * |
---|
| 1116 | * void TclStoreInt1AtPtr(int i, unsigned char *p); |
---|
| 1117 | * void TclStoreInt4AtPtr(int i, unsigned char *p); |
---|
| 1118 | */ |
---|
| 1119 | |
---|
| 1120 | #define TclStoreInt1AtPtr(i, p) \ |
---|
| 1121 | *(p) = (unsigned char) ((unsigned int) (i)) |
---|
| 1122 | |
---|
| 1123 | #define TclStoreInt4AtPtr(i, p) \ |
---|
| 1124 | *(p) = (unsigned char) ((unsigned int) (i) >> 24); \ |
---|
| 1125 | *(p+1) = (unsigned char) ((unsigned int) (i) >> 16); \ |
---|
| 1126 | *(p+2) = (unsigned char) ((unsigned int) (i) >> 8); \ |
---|
| 1127 | *(p+3) = (unsigned char) ((unsigned int) (i) ) |
---|
| 1128 | |
---|
| 1129 | /* |
---|
| 1130 | * Macros to update instructions at a particular pc with a new op code and a |
---|
| 1131 | * (signed or unsigned) int operand. The ANSI C "prototypes" for these macros |
---|
| 1132 | * are: |
---|
| 1133 | * |
---|
| 1134 | * void TclUpdateInstInt1AtPc(unsigned char op, int i, unsigned char *pc); |
---|
| 1135 | * void TclUpdateInstInt4AtPc(unsigned char op, int i, unsigned char *pc); |
---|
| 1136 | */ |
---|
| 1137 | |
---|
| 1138 | #define TclUpdateInstInt1AtPc(op, i, pc) \ |
---|
| 1139 | *(pc) = (unsigned char) (op); \ |
---|
| 1140 | TclStoreInt1AtPtr((i), ((pc)+1)) |
---|
| 1141 | |
---|
| 1142 | #define TclUpdateInstInt4AtPc(op, i, pc) \ |
---|
| 1143 | *(pc) = (unsigned char) (op); \ |
---|
| 1144 | TclStoreInt4AtPtr((i), ((pc)+1)) |
---|
| 1145 | |
---|
| 1146 | /* |
---|
| 1147 | * Macro to fix up a forward jump to point to the current code-generation |
---|
| 1148 | * position in the bytecode being created (the most common case). The ANSI C |
---|
| 1149 | * "prototypes" for this macro is: |
---|
| 1150 | * |
---|
| 1151 | * int TclFixupForwardJumpToHere(CompileEnv *envPtr, JumpFixup *fixupPtr, |
---|
| 1152 | * int threshold); |
---|
| 1153 | */ |
---|
| 1154 | |
---|
| 1155 | #define TclFixupForwardJumpToHere(envPtr, fixupPtr, threshold) \ |
---|
| 1156 | TclFixupForwardJump((envPtr), (fixupPtr), \ |
---|
| 1157 | (envPtr)->codeNext-(envPtr)->codeStart-(fixupPtr)->codeOffset, \ |
---|
| 1158 | (threshold)) |
---|
| 1159 | |
---|
| 1160 | /* |
---|
| 1161 | * Macros to get a signed integer (GET_INT{1,2}) or an unsigned int |
---|
| 1162 | * (GET_UINT{1,2}) from a pointer. There are two variants for each return type |
---|
| 1163 | * that depend on the number of bytes fetched. The ANSI C "prototypes" for |
---|
| 1164 | * these macros are: |
---|
| 1165 | * |
---|
| 1166 | * int TclGetInt1AtPtr(unsigned char *p); |
---|
| 1167 | * int TclGetInt4AtPtr(unsigned char *p); |
---|
| 1168 | * unsigned int TclGetUInt1AtPtr(unsigned char *p); |
---|
| 1169 | * unsigned int TclGetUInt4AtPtr(unsigned char *p); |
---|
| 1170 | */ |
---|
| 1171 | |
---|
| 1172 | /* |
---|
| 1173 | * The TclGetInt1AtPtr macro is tricky because we want to do sign extension on |
---|
| 1174 | * the 1-byte value. Unfortunately the "char" type isn't signed on all |
---|
| 1175 | * platforms so sign-extension doesn't always happen automatically. Sometimes |
---|
| 1176 | * we can explicitly declare the pointer to be signed, but other times we have |
---|
| 1177 | * to explicitly sign-extend the value in software. |
---|
| 1178 | */ |
---|
| 1179 | |
---|
| 1180 | #ifndef __CHAR_UNSIGNED__ |
---|
| 1181 | # define TclGetInt1AtPtr(p) ((int) *((char *) p)) |
---|
| 1182 | #else |
---|
| 1183 | # ifdef HAVE_SIGNED_CHAR |
---|
| 1184 | # define TclGetInt1AtPtr(p) ((int) *((signed char *) p)) |
---|
| 1185 | # else |
---|
| 1186 | # define TclGetInt1AtPtr(p) (((int) *((char *) p)) \ |
---|
| 1187 | | ((*(p) & 0200) ? (-256) : 0)) |
---|
| 1188 | # endif |
---|
| 1189 | #endif |
---|
| 1190 | |
---|
| 1191 | #define TclGetInt4AtPtr(p) (((int) TclGetInt1AtPtr(p) << 24) | \ |
---|
| 1192 | (*((p)+1) << 16) | \ |
---|
| 1193 | (*((p)+2) << 8) | \ |
---|
| 1194 | (*((p)+3))) |
---|
| 1195 | |
---|
| 1196 | #define TclGetUInt1AtPtr(p) ((unsigned int) *(p)) |
---|
| 1197 | #define TclGetUInt4AtPtr(p) ((unsigned int) (*(p) << 24) | \ |
---|
| 1198 | (*((p)+1) << 16) | \ |
---|
| 1199 | (*((p)+2) << 8) | \ |
---|
| 1200 | (*((p)+3))) |
---|
| 1201 | |
---|
| 1202 | /* |
---|
| 1203 | * Macros used to compute the minimum and maximum of two integers. The ANSI C |
---|
| 1204 | * "prototypes" for these macros are: |
---|
| 1205 | * |
---|
| 1206 | * int TclMin(int i, int j); |
---|
| 1207 | * int TclMax(int i, int j); |
---|
| 1208 | */ |
---|
| 1209 | |
---|
| 1210 | #define TclMin(i, j) ((((int) i) < ((int) j))? (i) : (j)) |
---|
| 1211 | #define TclMax(i, j) ((((int) i) > ((int) j))? (i) : (j)) |
---|
| 1212 | |
---|
| 1213 | /* |
---|
| 1214 | * DTrace probe macros (NOPs if DTrace support is not enabled). |
---|
| 1215 | */ |
---|
| 1216 | |
---|
| 1217 | #ifdef USE_DTRACE |
---|
| 1218 | |
---|
| 1219 | #include "tclDTrace.h" |
---|
| 1220 | |
---|
| 1221 | #if defined(__GNUC__ ) && __GNUC__ > 2 |
---|
| 1222 | /* Use gcc branch prediction hint to minimize cost of DTrace ENABLED checks. */ |
---|
| 1223 | #define unlikely(x) (__builtin_expect((x), 0)) |
---|
| 1224 | #else |
---|
| 1225 | #define unlikely(x) (x) |
---|
| 1226 | #endif |
---|
| 1227 | |
---|
| 1228 | #define TCL_DTRACE_PROC_ENTRY_ENABLED() unlikely(TCL_PROC_ENTRY_ENABLED()) |
---|
| 1229 | #define TCL_DTRACE_PROC_RETURN_ENABLED() unlikely(TCL_PROC_RETURN_ENABLED()) |
---|
| 1230 | #define TCL_DTRACE_PROC_RESULT_ENABLED() unlikely(TCL_PROC_RESULT_ENABLED()) |
---|
| 1231 | #define TCL_DTRACE_PROC_ARGS_ENABLED() unlikely(TCL_PROC_ARGS_ENABLED()) |
---|
| 1232 | #define TCL_DTRACE_PROC_INFO_ENABLED() unlikely(TCL_PROC_INFO_ENABLED()) |
---|
| 1233 | #define TCL_DTRACE_PROC_ENTRY(a0, a1, a2) TCL_PROC_ENTRY(a0, a1, a2) |
---|
| 1234 | #define TCL_DTRACE_PROC_RETURN(a0, a1) TCL_PROC_RETURN(a0, a1) |
---|
| 1235 | #define TCL_DTRACE_PROC_RESULT(a0, a1, a2, a3) TCL_PROC_RESULT(a0, a1, a2, a3) |
---|
| 1236 | #define TCL_DTRACE_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ |
---|
| 1237 | TCL_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) |
---|
| 1238 | #define TCL_DTRACE_PROC_INFO(a0, a1, a2, a3, a4, a5) \ |
---|
| 1239 | TCL_PROC_INFO(a0, a1, a2, a3, a4, a5) |
---|
| 1240 | |
---|
| 1241 | #define TCL_DTRACE_CMD_ENTRY_ENABLED() unlikely(TCL_CMD_ENTRY_ENABLED()) |
---|
| 1242 | #define TCL_DTRACE_CMD_RETURN_ENABLED() unlikely(TCL_CMD_RETURN_ENABLED()) |
---|
| 1243 | #define TCL_DTRACE_CMD_RESULT_ENABLED() unlikely(TCL_CMD_RESULT_ENABLED()) |
---|
| 1244 | #define TCL_DTRACE_CMD_ARGS_ENABLED() unlikely(TCL_CMD_ARGS_ENABLED()) |
---|
| 1245 | #define TCL_DTRACE_CMD_INFO_ENABLED() unlikely(TCL_CMD_INFO_ENABLED()) |
---|
| 1246 | #define TCL_DTRACE_CMD_ENTRY(a0, a1, a2) TCL_CMD_ENTRY(a0, a1, a2) |
---|
| 1247 | #define TCL_DTRACE_CMD_RETURN(a0, a1) TCL_CMD_RETURN(a0, a1) |
---|
| 1248 | #define TCL_DTRACE_CMD_RESULT(a0, a1, a2, a3) TCL_CMD_RESULT(a0, a1, a2, a3) |
---|
| 1249 | #define TCL_DTRACE_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ |
---|
| 1250 | TCL_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) |
---|
| 1251 | #define TCL_DTRACE_CMD_INFO(a0, a1, a2, a3, a4, a5) \ |
---|
| 1252 | TCL_CMD_INFO(a0, a1, a2, a3, a4, a5) |
---|
| 1253 | |
---|
| 1254 | #define TCL_DTRACE_INST_START_ENABLED() unlikely(TCL_INST_START_ENABLED()) |
---|
| 1255 | #define TCL_DTRACE_INST_DONE_ENABLED() unlikely(TCL_INST_DONE_ENABLED()) |
---|
| 1256 | #define TCL_DTRACE_INST_START(a0, a1, a2) TCL_INST_START(a0, a1, a2) |
---|
| 1257 | #define TCL_DTRACE_INST_DONE(a0, a1, a2) TCL_INST_DONE(a0, a1, a2) |
---|
| 1258 | |
---|
| 1259 | #define TCL_DTRACE_TCL_PROBE_ENABLED() unlikely(TCL_TCL_PROBE_ENABLED()) |
---|
| 1260 | #define TCL_DTRACE_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ |
---|
| 1261 | TCL_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) |
---|
| 1262 | |
---|
| 1263 | MODULE_SCOPE void TclDTraceInfo(Tcl_Obj *info, char **args, int *argsi); |
---|
| 1264 | |
---|
| 1265 | #else /* USE_DTRACE */ |
---|
| 1266 | |
---|
| 1267 | #define TCL_DTRACE_PROC_ENTRY_ENABLED() 0 |
---|
| 1268 | #define TCL_DTRACE_PROC_RETURN_ENABLED() 0 |
---|
| 1269 | #define TCL_DTRACE_PROC_RESULT_ENABLED() 0 |
---|
| 1270 | #define TCL_DTRACE_PROC_ARGS_ENABLED() 0 |
---|
| 1271 | #define TCL_DTRACE_PROC_INFO_ENABLED() 0 |
---|
| 1272 | #define TCL_DTRACE_PROC_ENTRY(a0, a1, a2) {} |
---|
| 1273 | #define TCL_DTRACE_PROC_RETURN(a0, a1) {} |
---|
| 1274 | #define TCL_DTRACE_PROC_RESULT(a0, a1, a2, a3) {} |
---|
| 1275 | #define TCL_DTRACE_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} |
---|
| 1276 | #define TCL_DTRACE_PROC_INFO(a0, a1, a2, a3, a4, a5) {} |
---|
| 1277 | |
---|
| 1278 | #define TCL_DTRACE_CMD_ENTRY_ENABLED() 0 |
---|
| 1279 | #define TCL_DTRACE_CMD_RETURN_ENABLED() 0 |
---|
| 1280 | #define TCL_DTRACE_CMD_RESULT_ENABLED() 0 |
---|
| 1281 | #define TCL_DTRACE_CMD_ARGS_ENABLED() 0 |
---|
| 1282 | #define TCL_DTRACE_CMD_INFO_ENABLED() 0 |
---|
| 1283 | #define TCL_DTRACE_CMD_ENTRY(a0, a1, a2) {} |
---|
| 1284 | #define TCL_DTRACE_CMD_RETURN(a0, a1) {} |
---|
| 1285 | #define TCL_DTRACE_CMD_RESULT(a0, a1, a2, a3) {} |
---|
| 1286 | #define TCL_DTRACE_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} |
---|
| 1287 | #define TCL_DTRACE_CMD_INFO(a0, a1, a2, a3, a4, a5) {} |
---|
| 1288 | |
---|
| 1289 | #define TCL_DTRACE_INST_START_ENABLED() 0 |
---|
| 1290 | #define TCL_DTRACE_INST_DONE_ENABLED() 0 |
---|
| 1291 | #define TCL_DTRACE_INST_START(a0, a1, a2) {} |
---|
| 1292 | #define TCL_DTRACE_INST_DONE(a0, a1, a2) {} |
---|
| 1293 | |
---|
| 1294 | #define TCL_DTRACE_TCL_PROBE_ENABLED() 0 |
---|
| 1295 | #define TCL_DTRACE_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} |
---|
| 1296 | |
---|
| 1297 | #define TclDTraceInfo(info, args, argsi) {*args = ""; *argsi = 0;} |
---|
| 1298 | |
---|
| 1299 | #endif /* USE_DTRACE */ |
---|
| 1300 | |
---|
| 1301 | #endif /* _TCLCOMPILATION */ |
---|
| 1302 | |
---|
| 1303 | /* |
---|
| 1304 | * Local Variables: |
---|
| 1305 | * mode: c |
---|
| 1306 | * c-basic-offset: 4 |
---|
| 1307 | * fill-column: 78 |
---|
| 1308 | * End: |
---|
| 1309 | */ |
---|