tclCompile.hGo 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 1.5.1 |