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