summaryrefslogtreecommitdiffstats
path: root/generic/tclCompile.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2005-07-14 10:50:08 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2005-07-14 10:50:08 (GMT)
commitd006a47d5d007d1b89e8c2118557e0ef08ac21d9 (patch)
tree1542aa6547005ee0530a25b459ab64f7b6452acb /generic/tclCompile.c
parentcadce06f20cd4c39398bb5e5640892ff743ca37c (diff)
downloadtcl-d006a47d5d007d1b89e8c2118557e0ef08ac21d9.zip
tcl-d006a47d5d007d1b89e8c2118557e0ef08ac21d9.tar.gz
tcl-d006a47d5d007d1b89e8c2118557e0ef08ac21d9.tar.bz2
Style improvements to tclCompile.c, plus bytecode printing enhancements.
Diffstat (limited to 'generic/tclCompile.c')
-rw-r--r--generic/tclCompile.c1796
1 files changed, 879 insertions, 917 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 5bb344c..72e99a2 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -1,17 +1,17 @@
-/*
+/*
* tclCompile.c --
*
- * This file contains procedures that compile Tcl commands or parts
- * of commands (like quoted strings or nested sub-commands) into a
- * sequence of instructions ("bytecodes").
+ * This file contains procedures that compile Tcl commands or parts of
+ * commands (like quoted strings or nested sub-commands) into a sequence
+ * of instructions ("bytecodes").
*
* Copyright (c) 1996-1998 Sun Microsystems, Inc.
* Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCompile.c,v 1.87 2005/06/20 22:55:20 dkf Exp $
+ * RCS: @(#) $Id: tclCompile.c,v 1.88 2005/07/14 10:50:25 dkf Exp $
*/
#include "tclInt.h"
@@ -20,7 +20,7 @@
/*
* Table of all AuxData types.
*/
-
+
static Tcl_HashTable auxDataTypeTable;
static int auxDataTypeTableInitialized; /* 0 means not yet initialized. */
@@ -42,10 +42,10 @@ static int traceInitialized = 0;
/*
* A table describing the Tcl bytecode instructions. Entries in this table
- * must correspond to the instruction opcode definitions in tclCompile.h.
- * The names "op1" and "op4" refer to an instruction's one or four byte
- * first operand. Similarly, "stktop" and "stknext" refer to the topmost
- * and next to topmost stack elements.
+ * must correspond to the instruction opcode definitions in tclCompile.h. The
+ * names "op1" and "op4" refer to an instruction's one or four byte first
+ * operand. Similarly, "stktop" and "stknext" refer to the topmost and next to
+ * topmost stack elements.
*
* Note that the load, store, and incr instructions do not distinguish local
* from global variables; the bytecode interpreter at runtime uses the
@@ -53,247 +53,247 @@ static int traceInitialized = 0;
*/
InstructionDesc tclInstructionTable[] = {
- /* Name Bytes stackEffect #Opnds Operand types Stack top, next */
- {"done", 1, -1, 0, {OPERAND_NONE}},
+ /* Name Bytes stackEffect #Opnds Operand types */
+ {"done", 1, -1, 0, {OPERAND_NONE}},
/* Finish ByteCode execution and return stktop (top stack item) */
- {"push1", 2, +1, 1, {OPERAND_UINT1}},
+ {"push1", 2, +1, 1, {OPERAND_UINT1}},
/* Push object at ByteCode objArray[op1] */
- {"push4", 5, +1, 1, {OPERAND_UINT4}},
+ {"push4", 5, +1, 1, {OPERAND_UINT4}},
/* Push object at ByteCode objArray[op4] */
- {"pop", 1, -1, 0, {OPERAND_NONE}},
+ {"pop", 1, -1, 0, {OPERAND_NONE}},
/* Pop the topmost stack object */
- {"dup", 1, +1, 0, {OPERAND_NONE}},
+ {"dup", 1, +1, 0, {OPERAND_NONE}},
/* Duplicate the topmost stack object and push the result */
- {"concat1", 2, INT_MIN, 1, {OPERAND_UINT1}},
+ {"concat1", 2, INT_MIN, 1, {OPERAND_UINT1}},
/* Concatenate the top op1 items and push result */
- {"invokeStk1", 2, INT_MIN, 1, {OPERAND_UINT1}},
+ {"invokeStk1", 2, INT_MIN, 1, {OPERAND_UINT1}},
/* Invoke command named objv[0]; <objc,objv> = <op1,top op1> */
- {"invokeStk4", 5, INT_MIN, 1, {OPERAND_UINT4}},
+ {"invokeStk4", 5, INT_MIN, 1, {OPERAND_UINT4}},
/* Invoke command named objv[0]; <objc,objv> = <op4,top op4> */
- {"evalStk", 1, 0, 0, {OPERAND_NONE}},
+ {"evalStk", 1, 0, 0, {OPERAND_NONE}},
/* Evaluate command in stktop using Tcl_EvalObj. */
- {"exprStk", 1, 0, 0, {OPERAND_NONE}},
+ {"exprStk", 1, 0, 0, {OPERAND_NONE}},
/* Execute expression in stktop using Tcl_ExprStringObj. */
-
- {"loadScalar1", 2, 1, 1, {OPERAND_UINT1}},
+
+ {"loadScalar1", 2, 1, 1, {OPERAND_LVT1}},
/* Load scalar variable at index op1 <= 255 in call frame */
- {"loadScalar4", 5, 1, 1, {OPERAND_UINT4}},
+ {"loadScalar4", 5, 1, 1, {OPERAND_LVT4}},
/* Load scalar variable at index op1 >= 256 in call frame */
- {"loadScalarStk", 1, 0, 0, {OPERAND_NONE}},
+ {"loadScalarStk", 1, 0, 0, {OPERAND_NONE}},
/* Load scalar variable; scalar's name is stktop */
- {"loadArray1", 2, 0, 1, {OPERAND_UINT1}},
+ {"loadArray1", 2, 0, 1, {OPERAND_LVT1}},
/* Load array element; array at slot op1<=255, element is stktop */
- {"loadArray4", 5, 0, 1, {OPERAND_UINT4}},
+ {"loadArray4", 5, 0, 1, {OPERAND_LVT4}},
/* Load array element; array at slot op1 > 255, element is stktop */
- {"loadArrayStk", 1, -1, 0, {OPERAND_NONE}},
+ {"loadArrayStk", 1, -1, 0, {OPERAND_NONE}},
/* Load array element; element is stktop, array name is stknext */
- {"loadStk", 1, 0, 0, {OPERAND_NONE}},
+ {"loadStk", 1, 0, 0, {OPERAND_NONE}},
/* Load general variable; unparsed variable name is stktop */
- {"storeScalar1", 2, 0, 1, {OPERAND_UINT1}},
+ {"storeScalar1", 2, 0, 1, {OPERAND_LVT1}},
/* Store scalar variable at op1<=255 in frame; value is stktop */
- {"storeScalar4", 5, 0, 1, {OPERAND_UINT4}},
+ {"storeScalar4", 5, 0, 1, {OPERAND_LVT4}},
/* Store scalar variable at op1 > 255 in frame; value is stktop */
- {"storeScalarStk", 1, -1, 0, {OPERAND_NONE}},
+ {"storeScalarStk", 1, -1, 0, {OPERAND_NONE}},
/* Store scalar; value is stktop, scalar name is stknext */
- {"storeArray1", 2, -1, 1, {OPERAND_UINT1}},
+ {"storeArray1", 2, -1, 1, {OPERAND_LVT1}},
/* Store array element; array at op1<=255, value is top then elem */
- {"storeArray4", 5, -1, 1, {OPERAND_UINT4}},
+ {"storeArray4", 5, -1, 1, {OPERAND_LVT4}},
/* Store array element; array at op1>=256, value is top then elem */
- {"storeArrayStk", 1, -2, 0, {OPERAND_NONE}},
+ {"storeArrayStk", 1, -2, 0, {OPERAND_NONE}},
/* Store array element; value is stktop, then elem, array names */
- {"storeStk", 1, -1, 0, {OPERAND_NONE}},
+ {"storeStk", 1, -1, 0, {OPERAND_NONE}},
/* Store general variable; value is stktop, then unparsed name */
-
- {"incrScalar1", 2, 0, 1, {OPERAND_UINT1}},
+
+ {"incrScalar1", 2, 0, 1, {OPERAND_LVT1}},
/* Incr scalar at index op1<=255 in frame; incr amount is stktop */
- {"incrScalarStk", 1, -1, 0, {OPERAND_NONE}},
+ {"incrScalarStk", 1, -1, 0, {OPERAND_NONE}},
/* Incr scalar; incr amount is stktop, scalar's name is stknext */
- {"incrArray1", 2, -1, 1, {OPERAND_UINT1}},
+ {"incrArray1", 2, -1, 1, {OPERAND_LVT1}},
/* Incr array elem; arr at slot op1<=255, amount is top then elem */
- {"incrArrayStk", 1, -2, 0, {OPERAND_NONE}},
+ {"incrArrayStk", 1, -2, 0, {OPERAND_NONE}},
/* Incr array element; amount is top then elem then array names */
- {"incrStk", 1, -1, 0, {OPERAND_NONE}},
+ {"incrStk", 1, -1, 0, {OPERAND_NONE}},
/* Incr general variable; amount is stktop then unparsed var name */
- {"incrScalar1Imm", 3, +1, 2, {OPERAND_UINT1, OPERAND_INT1}},
+ {"incrScalar1Imm", 3, +1, 2, {OPERAND_LVT1, OPERAND_INT1}},
/* Incr scalar at slot op1 <= 255; amount is 2nd operand byte */
- {"incrScalarStkImm", 2, 0, 1, {OPERAND_INT1}},
+ {"incrScalarStkImm", 2, 0, 1, {OPERAND_INT1}},
/* Incr scalar; scalar name is stktop; incr amount is op1 */
- {"incrArray1Imm", 3, 0, 2, {OPERAND_UINT1, OPERAND_INT1}},
+ {"incrArray1Imm", 3, 0, 2, {OPERAND_LVT1, OPERAND_INT1}},
/* Incr array elem; array at slot op1 <= 255, elem is stktop,
* amount is 2nd operand byte */
- {"incrArrayStkImm", 2, -1, 1, {OPERAND_INT1}},
+ {"incrArrayStkImm", 2, -1, 1, {OPERAND_INT1}},
/* Incr array element; elem is top then array name, amount is op1 */
- {"incrStkImm", 2, 0, 1, {OPERAND_INT1}},
+ {"incrStkImm", 2, 0, 1, {OPERAND_INT1}},
/* Incr general variable; unparsed name is top, amount is op1 */
-
- {"jump1", 2, 0, 1, {OPERAND_INT1}},
+
+ {"jump1", 2, 0, 1, {OPERAND_INT1}},
/* Jump relative to (pc + op1) */
- {"jump4", 5, 0, 1, {OPERAND_INT4}},
+ {"jump4", 5, 0, 1, {OPERAND_INT4}},
/* Jump relative to (pc + op4) */
- {"jumpTrue1", 2, -1, 1, {OPERAND_INT1}},
+ {"jumpTrue1", 2, -1, 1, {OPERAND_INT1}},
/* Jump relative to (pc + op1) if stktop expr object is true */
- {"jumpTrue4", 5, -1, 1, {OPERAND_INT4}},
+ {"jumpTrue4", 5, -1, 1, {OPERAND_INT4}},
/* Jump relative to (pc + op4) if stktop expr object is true */
- {"jumpFalse1", 2, -1, 1, {OPERAND_INT1}},
+ {"jumpFalse1", 2, -1, 1, {OPERAND_INT1}},
/* Jump relative to (pc + op1) if stktop expr object is false */
- {"jumpFalse4", 5, -1, 1, {OPERAND_INT4}},
+ {"jumpFalse4", 5, -1, 1, {OPERAND_INT4}},
/* Jump relative to (pc + op4) if stktop expr object is false */
- {"lor", 1, -1, 0, {OPERAND_NONE}},
+ {"lor", 1, -1, 0, {OPERAND_NONE}},
/* Logical or: push (stknext || stktop) */
- {"land", 1, -1, 0, {OPERAND_NONE}},
+ {"land", 1, -1, 0, {OPERAND_NONE}},
/* Logical and: push (stknext && stktop) */
- {"bitor", 1, -1, 0, {OPERAND_NONE}},
+ {"bitor", 1, -1, 0, {OPERAND_NONE}},
/* Bitwise or: push (stknext | stktop) */
- {"bitxor", 1, -1, 0, {OPERAND_NONE}},
+ {"bitxor", 1, -1, 0, {OPERAND_NONE}},
/* Bitwise xor push (stknext ^ stktop) */
- {"bitand", 1, -1, 0, {OPERAND_NONE}},
+ {"bitand", 1, -1, 0, {OPERAND_NONE}},
/* Bitwise and: push (stknext & stktop) */
- {"eq", 1, -1, 0, {OPERAND_NONE}},
+ {"eq", 1, -1, 0, {OPERAND_NONE}},
/* Equal: push (stknext == stktop) */
- {"neq", 1, -1, 0, {OPERAND_NONE}},
+ {"neq", 1, -1, 0, {OPERAND_NONE}},
/* Not equal: push (stknext != stktop) */
- {"lt", 1, -1, 0, {OPERAND_NONE}},
+ {"lt", 1, -1, 0, {OPERAND_NONE}},
/* Less: push (stknext < stktop) */
- {"gt", 1, -1, 0, {OPERAND_NONE}},
+ {"gt", 1, -1, 0, {OPERAND_NONE}},
/* Greater: push (stknext || stktop) */
- {"le", 1, -1, 0, {OPERAND_NONE}},
+ {"le", 1, -1, 0, {OPERAND_NONE}},
/* Logical or: push (stknext || stktop) */
- {"ge", 1, -1, 0, {OPERAND_NONE}},
+ {"ge", 1, -1, 0, {OPERAND_NONE}},
/* Logical or: push (stknext || stktop) */
- {"lshift", 1, -1, 0, {OPERAND_NONE}},
+ {"lshift", 1, -1, 0, {OPERAND_NONE}},
/* Left shift: push (stknext << stktop) */
- {"rshift", 1, -1, 0, {OPERAND_NONE}},
+ {"rshift", 1, -1, 0, {OPERAND_NONE}},
/* Right shift: push (stknext >> stktop) */
- {"add", 1, -1, 0, {OPERAND_NONE}},
+ {"add", 1, -1, 0, {OPERAND_NONE}},
/* Add: push (stknext + stktop) */
- {"sub", 1, -1, 0, {OPERAND_NONE}},
+ {"sub", 1, -1, 0, {OPERAND_NONE}},
/* Sub: push (stkext - stktop) */
- {"mult", 1, -1, 0, {OPERAND_NONE}},
+ {"mult", 1, -1, 0, {OPERAND_NONE}},
/* Multiply: push (stknext * stktop) */
- {"div", 1, -1, 0, {OPERAND_NONE}},
+ {"div", 1, -1, 0, {OPERAND_NONE}},
/* Divide: push (stknext / stktop) */
- {"mod", 1, -1, 0, {OPERAND_NONE}},
+ {"mod", 1, -1, 0, {OPERAND_NONE}},
/* Mod: push (stknext % stktop) */
- {"uplus", 1, 0, 0, {OPERAND_NONE}},
+ {"uplus", 1, 0, 0, {OPERAND_NONE}},
/* Unary plus: push +stktop */
- {"uminus", 1, 0, 0, {OPERAND_NONE}},
+ {"uminus", 1, 0, 0, {OPERAND_NONE}},
/* Unary minus: push -stktop */
- {"bitnot", 1, 0, 0, {OPERAND_NONE}},
+ {"bitnot", 1, 0, 0, {OPERAND_NONE}},
/* Bitwise not: push ~stktop */
- {"not", 1, 0, 0, {OPERAND_NONE}},
+ {"not", 1, 0, 0, {OPERAND_NONE}},
/* Logical not: push !stktop */
- {"callBuiltinFunc1", 2, 1, 1, {OPERAND_UINT1}},
+ {"callBuiltinFunc1", 2, 1, 1, {OPERAND_UINT1}},
/* Call builtin math function with index op1; any args are on stk */
- {"callFunc1", 2, INT_MIN, 1, {OPERAND_UINT1}},
+ {"callFunc1", 2, INT_MIN, 1, {OPERAND_UINT1}},
/* Call non-builtin func objv[0]; <objc,objv>=<op1,top op1> */
- {"tryCvtToNumeric", 1, 0, 0, {OPERAND_NONE}},
+ {"tryCvtToNumeric", 1, 0, 0, {OPERAND_NONE}},
/* Try converting stktop to first int then double if possible. */
- {"break", 1, 0, 0, {OPERAND_NONE}},
+ {"break", 1, 0, 0, {OPERAND_NONE}},
/* Abort closest enclosing loop; if none, return TCL_BREAK code. */
- {"continue", 1, 0, 0, {OPERAND_NONE}},
- /* Skip to next iteration of closest enclosing loop; if none,
- * return TCL_CONTINUE code. */
+ {"continue", 1, 0, 0, {OPERAND_NONE}},
+ /* Skip to next iteration of closest enclosing loop; if none, return
+ * TCL_CONTINUE code. */
- {"foreach_start4", 5, 0, 1, {OPERAND_UINT4}},
+ {"foreach_start4", 5, 0, 1, {OPERAND_UINT4}},
/* Initialize execution of a foreach loop. Operand is aux data index
* of the ForeachInfo structure for the foreach command. */
- {"foreach_step4", 5, +1, 1, {OPERAND_UINT4}},
+ {"foreach_step4", 5, +1, 1, {OPERAND_UINT4}},
/* "Step" or begin next iteration of foreach loop. Push 0 if to
* terminate loop, else push 1. */
- {"beginCatch4", 5, 0, 1, {OPERAND_UINT4}},
- /* Record start of catch with the operand's exception index.
- * Push the current stack depth onto a special catch stack. */
- {"endCatch", 1, 0, 0, {OPERAND_NONE}},
+ {"beginCatch4", 5, 0, 1, {OPERAND_UINT4}},
+ /* Record start of catch with the operand's exception index. Push the
+ * current stack depth onto a special catch stack. */
+ {"endCatch", 1, 0, 0, {OPERAND_NONE}},
/* End of last catch. Pop the bytecode interpreter's catch stack. */
- {"pushResult", 1, +1, 0, {OPERAND_NONE}},
+ {"pushResult", 1, +1, 0, {OPERAND_NONE}},
/* Push the interpreter's object result onto the stack. */
- {"pushReturnCode", 1, +1, 0, {OPERAND_NONE}},
- /* Push interpreter's return code (e.g. TCL_OK or TCL_ERROR) as
- * a new object onto the stack. */
+ {"pushReturnCode", 1, +1, 0, {OPERAND_NONE}},
+ /* Push interpreter's return code (e.g. TCL_OK or TCL_ERROR) as a new
+ * object onto the stack. */
- {"streq", 1, -1, 0, {OPERAND_NONE}},
+ {"streq", 1, -1, 0, {OPERAND_NONE}},
/* Str Equal: push (stknext eq stktop) */
- {"strneq", 1, -1, 0, {OPERAND_NONE}},
+ {"strneq", 1, -1, 0, {OPERAND_NONE}},
/* Str !Equal: push (stknext neq stktop) */
- {"strcmp", 1, -1, 0, {OPERAND_NONE}},
+ {"strcmp", 1, -1, 0, {OPERAND_NONE}},
/* Str Compare: push (stknext cmp stktop) */
- {"strlen", 1, 0, 0, {OPERAND_NONE}},
+ {"strlen", 1, 0, 0, {OPERAND_NONE}},
/* Str Length: push (strlen stktop) */
- {"strindex", 1, -1, 0, {OPERAND_NONE}},
+ {"strindex", 1, -1, 0, {OPERAND_NONE}},
/* Str Index: push (strindex stknext stktop) */
- {"strmatch", 2, -1, 1, {OPERAND_INT1}},
+ {"strmatch", 2, -1, 1, {OPERAND_INT1}},
/* Str Match: push (strmatch stknext stktop) opnd == nocase */
- {"list", 5, INT_MIN, 1, {OPERAND_UINT4}},
+ {"list", 5, INT_MIN, 1, {OPERAND_UINT4}},
/* List: push (stk1 stk2 ... stktop) */
- {"listIndex", 1, -1, 0, {OPERAND_NONE}},
+ {"listIndex", 1, -1, 0, {OPERAND_NONE}},
/* List Index: push (listindex stknext stktop) */
- {"listLength", 1, 0, 0, {OPERAND_NONE}},
+ {"listLength", 1, 0, 0, {OPERAND_NONE}},
/* List Len: push (listlength stktop) */
- {"appendScalar1", 2, 0, 1, {OPERAND_UINT1}},
+ {"appendScalar1", 2, 0, 1, {OPERAND_LVT1}},
/* Append scalar variable at op1<=255 in frame; value is stktop */
- {"appendScalar4", 5, 0, 1, {OPERAND_UINT4}},
+ {"appendScalar4", 5, 0, 1, {OPERAND_LVT4}},
/* Append scalar variable at op1 > 255 in frame; value is stktop */
- {"appendArray1", 2, -1, 1, {OPERAND_UINT1}},
+ {"appendArray1", 2, -1, 1, {OPERAND_LVT1}},
/* Append array element; array at op1<=255, value is top then elem */
- {"appendArray4", 5, -1, 1, {OPERAND_UINT4}},
+ {"appendArray4", 5, -1, 1, {OPERAND_LVT4}},
/* Append array element; array at op1>=256, value is top then elem */
- {"appendArrayStk", 1, -2, 0, {OPERAND_NONE}},
+ {"appendArrayStk", 1, -2, 0, {OPERAND_NONE}},
/* Append array element; value is stktop, then elem, array names */
- {"appendStk", 1, -1, 0, {OPERAND_NONE}},
+ {"appendStk", 1, -1, 0, {OPERAND_NONE}},
/* Append general variable; value is stktop, then unparsed name */
- {"lappendScalar1", 2, 0, 1, {OPERAND_UINT1}},
+ {"lappendScalar1", 2, 0, 1, {OPERAND_LVT1}},
/* Lappend scalar variable at op1<=255 in frame; value is stktop */
- {"lappendScalar4", 5, 0, 1, {OPERAND_UINT4}},
+ {"lappendScalar4", 5, 0, 1, {OPERAND_LVT4}},
/* Lappend scalar variable at op1 > 255 in frame; value is stktop */
- {"lappendArray1", 2, -1, 1, {OPERAND_UINT1}},
+ {"lappendArray1", 2, -1, 1, {OPERAND_LVT1}},
/* Lappend array element; array at op1<=255, value is top then elem */
- {"lappendArray4", 5, -1, 1, {OPERAND_UINT4}},
+ {"lappendArray4", 5, -1, 1, {OPERAND_LVT4}},
/* Lappend array element; array at op1>=256, value is top then elem */
- {"lappendArrayStk", 1, -2, 0, {OPERAND_NONE}},
+ {"lappendArrayStk", 1, -2, 0, {OPERAND_NONE}},
/* Lappend array element; value is stktop, then elem, array names */
- {"lappendStk", 1, -1, 0, {OPERAND_NONE}},
+ {"lappendStk", 1, -1, 0, {OPERAND_NONE}},
/* Lappend general variable; value is stktop, then unparsed name */
- {"lindexMulti", 5, INT_MIN, 1, {OPERAND_UINT4}},
- /* Lindex with generalized args, operand is number of stacked objs
+ {"lindexMulti", 5, INT_MIN, 1, {OPERAND_UINT4}},
+ /* Lindex with generalized args, operand is number of stacked objs
* used: (operand-1) entries from stktop are the indices; then list to
* process. */
- {"over", 5, +1, 1, {OPERAND_UINT4}},
- /* Duplicate the arg-th element from top of stack (TOS=0) */
- {"lsetList", 1, -2, 0, {OPERAND_NONE}},
- /* Four-arg version of 'lset'. stktop is old value; next is
- * new element value, next is the index list; pushes new value */
- {"lsetFlat", 5, INT_MIN, 1, {OPERAND_UINT4}},
- /* Three- or >=5-arg version of 'lset', operand is number of
- * stacked objs: stktop is old value, next is new element value, next
- * come (operand-2) indices; pushes the new value.
+ {"over", 5, +1, 1, {OPERAND_UINT4}},
+ /* Duplicate the arg-th element from top of stack (TOS=0) */
+ {"lsetList", 1, -2, 0, {OPERAND_NONE}},
+ /* Four-arg version of 'lset'. stktop is old value; next is new
+ * element value, next is the index list; pushes new value */
+ {"lsetFlat", 5, INT_MIN, 1, {OPERAND_UINT4}},
+ /* Three- or >=5-arg version of 'lset', operand is number of stacked
+ * objs: stktop is old value, next is new element value, next come
+ * (operand-2) indices; pushes the new value.
*/
- {"return", 9, -1, 2, {OPERAND_INT4, OPERAND_UINT4}},
- /* Compiled [return], code, level are operands; options and result
- * are on the stack. */
+ {"return", 9, -1, 2, {OPERAND_INT4, OPERAND_UINT4}},
+ /* Compiled [return], code, level are operands; options and result are
+ * on the stack. */
{"expon", 1, -1, 0, {OPERAND_NONE}},
/* Binary exponentiation operator: push (stknext ** stktop) */
- /*
- * NOTE: the stack effects of expandStkTop and invokeExpanded
- * are wrong - but it cannot be done right at compile time, the stack
- * effect is only known at run time. The value for invokeExpanded
- * is estimated better at compile time.
- * See the comments further down in this file, where INST_INVOKE_EXPANDED
+ /*
+ * NOTE: the stack effects of expandStkTop and invokeExpanded are wrong -
+ * but it cannot be done right at compile time, the stack effect is only
+ * known at run time. The value for invokeExpanded is estimated better at
+ * compile time.
+ * See the comments further down in this file, where INST_INVOKE_EXPANDED
* is emitted.
*/
- {"expandStart", 1, 0, 0, {OPERAND_NONE}},
+ {"expandStart", 1, 0, 0, {OPERAND_NONE}},
/* Start of command with {expand}ed arguments */
- {"expandStkTop", 5, 0, 1, {OPERAND_INT4}},
+ {"expandStkTop", 5, 0, 1, {OPERAND_INT4}},
/* Expand the list at stacktop: push its elements on the stack */
- {"invokeExpanded", 1, 0, 0, {OPERAND_NONE}},
+ {"invokeExpanded", 1, 0, 0, {OPERAND_NONE}},
/* Invoke the command marked by the last 'expandStart' */
{"listIndexImm", 5, 0, 1, {OPERAND_IDX4}},
@@ -301,7 +301,7 @@ InstructionDesc tclInstructionTable[] = {
{"listRangeImm", 9, 0, 2, {OPERAND_IDX4, OPERAND_IDX4}},
/* List Range: push (lrange stktop op4 op4) */
{"startCommand", 5, 0, 1, {OPERAND_UINT4}},
- /* Start of bytecoded command: op is the length of the cmd's code */
+ /* Start of bytecoded command: op is the length of the cmd's code */
{"listIn", 1, -1, 0, {OPERAND_NONE}},
/* List containment: push [lsearch stktop stknext]>=0) */
@@ -320,22 +320,17 @@ InstructionDesc tclInstructionTable[] = {
static void DupByteCodeInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
Tcl_Obj *copyPtr));
-static unsigned char * EncodeCmdLocMap _ANSI_ARGS_((
- CompileEnv *envPtr, ByteCode *codePtr,
- unsigned char *startPtr));
-static void EnterCmdExtentData _ANSI_ARGS_((
- CompileEnv *envPtr, int cmdNumber,
- int numSrcBytes, int numCodeBytes));
-static void EnterCmdStartData _ANSI_ARGS_((
- CompileEnv *envPtr, int cmdNumber,
- int srcOffset, int codeOffset));
-static void FreeByteCodeInternalRep _ANSI_ARGS_((
- Tcl_Obj *objPtr));
+static unsigned char * EncodeCmdLocMap _ANSI_ARGS_((CompileEnv *envPtr,
+ ByteCode *codePtr, unsigned char *startPtr));
+static void EnterCmdExtentData _ANSI_ARGS_((CompileEnv *envPtr,
+ int cmdNumber, int numSrcBytes, int numCodeBytes));
+static void EnterCmdStartData _ANSI_ARGS_((CompileEnv *envPtr,
+ int cmdNumber, int srcOffset, int codeOffset));
+static void FreeByteCodeInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr));
static int GetCmdLocEncodingSize _ANSI_ARGS_((
CompileEnv *envPtr));
#ifdef TCL_COMPILE_STATS
-static void RecordByteCodeStats _ANSI_ARGS_((
- ByteCode *codePtr));
+static void RecordByteCodeStats _ANSI_ARGS_((ByteCode *codePtr));
#endif /* TCL_COMPILE_STATS */
static int SetByteCodeFromAny _ANSI_ARGS_((Tcl_Interp *interp,
Tcl_Obj *objPtr));
@@ -360,10 +355,9 @@ Tcl_ObjType tclByteCodeType = {
*
* Part of the bytecode Tcl object type implementation. Attempts to
* generate an byte code internal form for the Tcl object "objPtr" by
- * compiling its string representation. This function also takes
- * a hook procedure that will be invoked to perform any needed post
- * processing on the compilation results before generating byte
- * codes.
+ * compiling its string representation. This function also takes a hook
+ * procedure that will be invoked to perform any needed post processing
+ * on the compilation results before generating byte codes.
*
* Results:
* The return value is a standard Tcl object result. If an error occurs
@@ -372,17 +366,17 @@ Tcl_ObjType tclByteCodeType = {
*
* Side effects:
* Frees the old internal representation. If no error occurs, then the
- * compiled code is stored as "objPtr"s bytecode representation.
- * Also, if debugging, initializes the "tcl_traceCompile" Tcl variable
- * used to trace compilations.
+ * compiled code is stored as "objPtr"s bytecode representation. Also, if
+ * debugging, initializes the "tcl_traceCompile" Tcl variable used to
+ * trace compilations.
*
*----------------------------------------------------------------------
*/
int
TclSetByteCodeFromAny(interp, objPtr, hookProc, clientData)
- Tcl_Interp *interp; /* The interpreter for which the code is
- * being compiled. Must not be NULL. */
+ Tcl_Interp *interp; /* The interpreter for which the code is being
+ * compiled. Must not be NULL. */
Tcl_Obj *objPtr; /* The object to make a ByteCode object. */
CompileHookProc *hookProc; /* Procedure to invoke after compilation. */
ClientData clientData; /* Hook procedure private data. */
@@ -390,8 +384,8 @@ TclSetByteCodeFromAny(interp, objPtr, hookProc, clientData)
#ifdef TCL_COMPILE_DEBUG
Interp *iPtr = (Interp *) interp;
#endif /*TCL_COMPILE_DEBUG*/
- CompileEnv compEnv; /* Compilation environment structure
- * allocated in frame. */
+ CompileEnv compEnv; /* Compilation environment structure allocated
+ * in frame. */
LiteralTable *localTablePtr = &(compEnv.localLitTable);
register AuxData *auxDataPtr;
LiteralEntry *entryPtr;
@@ -401,11 +395,11 @@ TclSetByteCodeFromAny(interp, objPtr, hookProc, clientData)
#ifdef TCL_COMPILE_DEBUG
if (!traceInitialized) {
- if (Tcl_LinkVar(interp, "tcl_traceCompile",
- (char *) &tclTraceCompile, TCL_LINK_INT) != TCL_OK) {
- Tcl_Panic("SetByteCodeFromAny: unable to create link for tcl_traceCompile variable");
- }
- traceInitialized = 1;
+ if (Tcl_LinkVar(interp, "tcl_traceCompile",
+ (char *) &tclTraceCompile, TCL_LINK_INT) != TCL_OK) {
+ Tcl_Panic("SetByteCodeFromAny: unable to create link for tcl_traceCompile variable");
+ }
+ traceInitialized = 1;
}
#endif
@@ -424,14 +418,14 @@ TclSetByteCodeFromAny(interp, objPtr, hookProc, clientData)
*/
if (hookProc) {
- result = (*hookProc)(interp, &compEnv, clientData);
+ result = (*hookProc)(interp, &compEnv, clientData);
}
/*
* Change the object into a ByteCode object. Ownership of the literal
* objects and aux data items is given to the ByteCode object.
*/
-
+
#ifdef TCL_COMPILE_DEBUG
TclVerifyLocalLiteralTable(&compEnv);
#endif /*TCL_COMPILE_DEBUG*/
@@ -439,10 +433,10 @@ TclSetByteCodeFromAny(interp, objPtr, hookProc, clientData)
TclInitByteCodeObj(objPtr, &compEnv);
#ifdef TCL_COMPILE_DEBUG
if (tclTraceCompile >= 2) {
- TclPrintByteCodeObj(interp, objPtr);
+ TclPrintByteCodeObj(interp, objPtr);
}
#endif /* TCL_COMPILE_DEBUG */
-
+
if (result != TCL_OK) {
/*
* Handle any error from the hookProc
@@ -466,11 +460,10 @@ TclSetByteCodeFromAny(interp, objPtr, hookProc, clientData)
}
}
-
/*
* Free storage allocated during compilation.
*/
-
+
if (localTablePtr->buckets != localTablePtr->staticBuckets) {
ckfree((char *) localTablePtr->buckets);
}
@@ -494,17 +487,17 @@ TclSetByteCodeFromAny(interp, objPtr, hookProc, clientData)
*
* Side effects:
* Frees the old internal representation. If no error occurs, then the
- * compiled code is stored as "objPtr"s bytecode representation.
- * Also, if debugging, initializes the "tcl_traceCompile" Tcl variable
- * used to trace compilations.
+ * compiled code is stored as "objPtr"s bytecode representation. Also,
+ * if debugging, initializes the "tcl_traceCompile" Tcl variable used to
+ * trace compilations.
*
*----------------------------------------------------------------------
*/
static int
SetByteCodeFromAny(interp, objPtr)
- Tcl_Interp *interp; /* The interpreter for which the code is
- * being compiled. Must not be NULL. */
+ Tcl_Interp *interp; /* The interpreter for which the code is being
+ * compiled. Must not be NULL. */
Tcl_Obj *objPtr; /* The object to make a ByteCode object. */
{
return TclSetByteCodeFromAny(interp, objPtr,
@@ -516,8 +509,8 @@ SetByteCodeFromAny(interp, objPtr)
*
* DupByteCodeInternalRep --
*
- * Part of the bytecode Tcl object type implementation. However, it
- * does not copy the internal representation of a bytecode Tcl_Obj, but
+ * Part of the bytecode Tcl object type implementation. However, it does
+ * not copy the internal representation of a bytecode Tcl_Obj, but
* instead leaves the new object untyped (with a NULL type pointer).
* Code will be compiled for the new object only if necessary.
*
@@ -543,18 +536,17 @@ DupByteCodeInternalRep(srcPtr, copyPtr)
*
* FreeByteCodeInternalRep --
*
- * Part of the bytecode Tcl object type implementation. Frees the
- * storage associated with a bytecode object's internal representation
- * unless its code is actively being executed.
+ * Part of the bytecode Tcl object type implementation. Frees the storage
+ * associated with a bytecode object's internal representation unless its
+ * code is actively being executed.
*
* Results:
* None.
*
* Side effects:
- * The bytecode object's internal rep is marked invalid and its
- * code gets freed unless the code is actively being executed.
- * In that case the cleanup is delayed until the last execution
- * of the code completes.
+ * The bytecode object's internal rep is marked invalid and its code gets
+ * freed unless the code is actively being executed. In that case the
+ * cleanup is delayed until the last execution of the code completes.
*
*----------------------------------------------------------------------
*/
@@ -563,8 +555,8 @@ static void
FreeByteCodeInternalRep(objPtr)
register Tcl_Obj *objPtr; /* Object whose internal rep to free. */
{
- register ByteCode *codePtr =
- (ByteCode *) objPtr->internalRep.otherValuePtr;
+ register ByteCode *codePtr = (ByteCode *)
+ objPtr->internalRep.otherValuePtr;
codePtr->refCount--;
if (codePtr->refCount <= 0) {
@@ -587,9 +579,9 @@ FreeByteCodeInternalRep(objPtr)
* None.
*
* Side effects:
- * Frees objPtr's bytecode internal representation and sets its type
- * and objPtr->internalRep.otherValuePtr NULL. Also releases its
- * literals and frees its auxiliary data items.
+ * Frees objPtr's bytecode internal representation and sets its type and
+ * objPtr->internalRep.otherValuePtr NULL. Also releases its literals and
+ * frees its auxiliary data items.
*
*----------------------------------------------------------------------
*/
@@ -617,13 +609,13 @@ TclCleanupByteCode(codePtr)
statsPtr->currentSrcBytes -= (double) codePtr->numSrcBytes;
statsPtr->currentByteCodeBytes -= (double) codePtr->structureSize;
- statsPtr->currentInstBytes -= (double) codePtr->numCodeBytes;
- statsPtr->currentLitBytes -=
- (double) (codePtr->numLitObjects * sizeof(Tcl_Obj *));
- statsPtr->currentExceptBytes -=
- (double) (codePtr->numExceptRanges * sizeof(ExceptionRange));
- statsPtr->currentAuxBytes -=
- (double) (codePtr->numAuxDataItems * sizeof(AuxData));
+ statsPtr->currentInstBytes -= (double) codePtr->numCodeBytes;
+ statsPtr->currentLitBytes -= (double)
+ codePtr->numLitObjects * sizeof(Tcl_Obj *);
+ statsPtr->currentExceptBytes -= (double)
+ codePtr->numExceptRanges * sizeof(ExceptionRange);
+ statsPtr->currentAuxBytes -= (double)
+ codePtr->numAuxDataItems * sizeof(AuxData);
statsPtr->currentCmdMapBytes -= (double) codePtr->numCmdLocBytes;
Tcl_GetTime(&destroyTime);
@@ -631,9 +623,9 @@ TclCleanupByteCode(codePtr)
if (lifetimeSec > 2000) { /* avoid overflow */
lifetimeSec = 2000;
}
- lifetimeMicroSec =
- 1000000*lifetimeSec + (destroyTime.usec - codePtr->createTime.usec);
-
+ lifetimeMicroSec = 1000000 * lifetimeSec +
+ (destroyTime.usec - codePtr->createTime.usec);
+
log2 = TclLog2(lifetimeMicroSec);
if (log2 > 31) {
log2 = 31;
@@ -643,28 +635,27 @@ TclCleanupByteCode(codePtr)
#endif /* TCL_COMPILE_STATS */
/*
- * A single heap object holds the ByteCode structure and its code,
- * object, command location, and auxiliary data arrays. This means we
- * only need to 1) decrement the ref counts of the LiteralEntry's in
- * its literal array, 2) call the free procs for the auxiliary data
- * items, and 3) free the ByteCode structure's heap object.
+ * A single heap object holds the ByteCode structure and its code, object,
+ * command location, and auxiliary data arrays. This means we only need to
+ * 1) decrement the ref counts of the LiteralEntry's in its literal array,
+ * 2) call the free procs for the auxiliary data items, and 3) free the
+ * ByteCode structure's heap object.
*
- * The case for TCL_BYTECODE_PRECOMPILED (precompiled ByteCodes,
- * like those generated from tbcload) is special, as they doesn't
- * make use of the global literal table. They instead maintain
- * private references to their literals which must be decremented.
+ * The case for TCL_BYTECODE_PRECOMPILED (precompiled ByteCodes, like
+ * those generated from tbcload) is special, as they doesn't make use of
+ * the global literal table. They instead maintain private references to
+ * their literals which must be decremented.
*
- * In order to insure a proper and efficient cleanup of the literal
- * array when it contains non-shared literals [Bug 983660], we also
- * distinguish the case of an interpreter being deleted (signaled by
- * interp == NULL). Also, as the interp deletion will remove the global
- * literal table anyway, we avoid the extra cost of updating it for each
- * literal being released.
+ * In order to insure a proper and efficient cleanup of the literal array
+ * when it contains non-shared literals [Bug 983660], we also distinguish
+ * the case of an interpreter being deleted (signaled by interp == NULL).
+ * Also, as the interp deletion will remove the global literal table
+ * anyway, we avoid the extra cost of updating it for each literal being
+ * released.
*/
- if ((codePtr->flags & TCL_BYTECODE_PRECOMPILED)
- || (interp == NULL)) {
-
+ if ((codePtr->flags & TCL_BYTECODE_PRECOMPILED) || (interp == NULL)) {
+
objArrayPtr = codePtr->objArrayPtr;
for (i = 0; i < numLitObjects; i++) {
objPtr = *objArrayPtr;
@@ -681,7 +672,7 @@ TclCleanupByteCode(codePtr)
* TclReleaseLiteral sets a ByteCode's object array entry NULL to
* indicate that it has already freed the literal.
*/
-
+
objPtr = *objArrayPtr;
if (objPtr != NULL) {
TclReleaseLiteral(interp, objPtr);
@@ -689,11 +680,11 @@ TclCleanupByteCode(codePtr)
objArrayPtr++;
}
}
-
+
auxDataPtr = codePtr->auxDataArrayPtr;
for (i = 0; i < numAuxDataItems; i++) {
if (auxDataPtr->type->freeProc != NULL) {
- (*auxDataPtr->type->freeProc)(auxDataPtr->clientData);
+ (auxDataPtr->type->freeProc)(auxDataPtr->clientData);
}
auxDataPtr++;
}
@@ -729,7 +720,7 @@ TclInitCompileEnv(interp, envPtr, stringPtr, numBytes)
int numBytes; /* Number of bytes in source string. */
{
Interp *iPtr = (Interp *) interp;
-
+
envPtr->iPtr = iPtr;
envPtr->source = stringPtr;
envPtr->numSrcBytes = numBytes;
@@ -750,16 +741,16 @@ TclInitCompileEnv(interp, envPtr, stringPtr, numBytes)
envPtr->literalArrayNext = 0;
envPtr->literalArrayEnd = COMPILEENV_INIT_NUM_OBJECTS;
envPtr->mallocedLiteralArray = 0;
-
+
envPtr->exceptArrayPtr = envPtr->staticExceptArraySpace;
envPtr->exceptArrayNext = 0;
envPtr->exceptArrayEnd = COMPILEENV_INIT_EXCEPT_RANGES;
envPtr->mallocedExceptArray = 0;
-
+
envPtr->cmdMapPtr = envPtr->staticCmdMapSpace;
envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE;
envPtr->mallocedCmdMap = 0;
-
+
envPtr->auxDataArrayPtr = envPtr->staticAuxDataArraySpace;
envPtr->auxDataArrayNext = 0;
envPtr->auxDataArrayEnd = COMPILEENV_INIT_AUX_DATA_SIZE;
@@ -776,14 +767,14 @@ TclInitCompileEnv(interp, envPtr, stringPtr, numBytes)
*
* Results:
* None.
- *
+ *
* Side effects:
- * Allocated storage in the CompileEnv structure is freed. Note that
- * its local literal table is not deleted and its literal objects are
- * not released. In addition, storage referenced by its auxiliary data
- * items is not freed. This is done so that, when compilation is
- * successful, "ownership" of these objects and aux data items is
- * handed over to the corresponding ByteCode structure.
+ * Allocated storage in the CompileEnv structure is freed. Note that its
+ * local literal table is not deleted and its literal objects are not
+ * released. In addition, storage referenced by its auxiliary data items
+ * is not freed. This is done so that, when compilation is successful,
+ * "ownership" of these objects and aux data items is handed over to the
+ * corresponding ByteCode structure.
*
*----------------------------------------------------------------------
*/
@@ -814,21 +805,20 @@ TclFreeCompileEnv(envPtr)
*
* TclWordKnownAtCompileTime --
*
- * Test whether the value of a token is completely known at compile
- * time.
+ * Test whether the value of a token is completely known at compile time.
*
* Results:
- * Returns true if the tokenPtr argument points to a word value that
- * is completely known at compile time. Generally, values that are
- * known at compile time can be compiled to their values, while values
- * that cannot be known until substitution at runtime must be compiled
- * to bytecode instructions that perform that substitution. For several
- * commands, whether or not arguments are known at compile time determine
- * whether it is worthwhile to compile at all.
+ * Returns true if the tokenPtr argument points to a word value that is
+ * completely known at compile time. Generally, values that are known at
+ * compile time can be compiled to their values, while values that cannot
+ * be known until substitution at runtime must be compiled to bytecode
+ * instructions that perform that substitution. For several commands,
+ * whether or not arguments are known at compile time determine whether
+ * it is worthwhile to compile at all.
*
* Side effects:
- * When returning true, appends the known value of the word to
- * the unshared Tcl_Obj (*valuePtr), unless valuePtr is NULL.
+ * When returning true, appends the known value of the word to the
+ * unshared Tcl_Obj (*valuePtr), unless valuePtr is NULL.
*
*----------------------------------------------------------------------
*/
@@ -859,26 +849,25 @@ TclWordKnownAtCompileTime(tokenPtr, valuePtr)
}
while (numComponents--) {
switch (tokenPtr->type) {
- case TCL_TOKEN_TEXT:
- if (tempPtr != NULL) {
- Tcl_AppendToObj(tempPtr, tokenPtr->start, tokenPtr->size);
- }
- break;
+ case TCL_TOKEN_TEXT:
+ if (tempPtr != NULL) {
+ Tcl_AppendToObj(tempPtr, tokenPtr->start, tokenPtr->size);
+ }
+ break;
- case TCL_TOKEN_BS:
- if (tempPtr != NULL) {
- char utfBuf[TCL_UTF_MAX];
- int length =
- Tcl_UtfBackslash(tokenPtr->start, NULL, utfBuf);
- Tcl_AppendToObj(tempPtr, utfBuf, length);
- }
- break;
-
- default:
- if (tempPtr != NULL) {
- Tcl_DecrRefCount(tempPtr);
- }
- return 0;
+ case TCL_TOKEN_BS:
+ if (tempPtr != NULL) {
+ char utfBuf[TCL_UTF_MAX];
+ int length = Tcl_UtfBackslash(tokenPtr->start, NULL, utfBuf);
+ Tcl_AppendToObj(tempPtr, utfBuf, length);
+ }
+ break;
+
+ default:
+ if (tempPtr != NULL) {
+ Tcl_DecrRefCount(tempPtr);
+ }
+ return 0;
}
tokenPtr++;
}
@@ -909,9 +898,9 @@ TclWordKnownAtCompileTime(tokenPtr, valuePtr)
void
TclCompileScript(interp, script, numBytes, envPtr)
- Tcl_Interp *interp; /* Used for error and status reporting.
- * Also serves as context for finding and
- * compiling commands. May not be NULL. */
+ Tcl_Interp *interp; /* Used for error and status reporting. Also
+ * serves as context for finding and compiling
+ * commands. May not be NULL. */
CONST char *script; /* The source script to compile. */
int numBytes; /* Number of bytes in script. If < 0, the
* script consists of all bytes up to the
@@ -922,10 +911,10 @@ TclCompileScript(interp, script, numBytes, envPtr)
Tcl_Parse parse;
int lastTopLevelCmdIndex = -1;
/* Index of most recent toplevel command in
- * the command location table. Initialized
- * to avoid compiler warning. */
+ * the command location table. Initialized *
+ * to avoid compiler warning. */
int startCodeOffset = -1; /* Offset of first byte of current command's
- * code. Init. to avoid compiler warning. */
+ * code. Init. to avoid compiler warning. */
unsigned char *entryCodeNext = envPtr->codeNext;
CONST char *p, *next;
Namespace *cmdNsPtr;
@@ -946,7 +935,7 @@ TclCompileScript(interp, script, numBytes, envPtr)
if (envPtr->procPtr != NULL) {
cmdNsPtr = envPtr->procPtr->cmdPtr->nsPtr;
} else {
- cmdNsPtr = NULL; /* use current NS */
+ cmdNsPtr = NULL; /* use current NS */
}
/*
@@ -973,9 +962,9 @@ TclCompileScript(interp, script, numBytes, envPtr)
Tcl_IncrRefCount(errInfo);
Tcl_AppendToObj(errInfo, "\n while executing\n\"", -1);
TclAppendLimitedToObj(errInfo, parse.commandStart,
- /* Drop the command terminator (";" or "]") if appropriate */
- (parse.term == parse.commandStart + parse.commandSize - 1) ?
- parse.commandSize - 1 : parse.commandSize, 153, NULL);
+ /* Drop the command terminator (";","]") if appropriate */
+ (parse.term == parse.commandStart + parse.commandSize - 1)?
+ parse.commandSize - 1 : parse.commandSize, 153, NULL);
Tcl_AppendToObj(errInfo, "\"", -1);
Tcl_ListObjAppendElement(NULL, returnCmd, errInfo);
@@ -1024,19 +1013,19 @@ TclCompileScript(interp, script, numBytes, envPtr)
commandLength = parse.commandSize;
if (parse.term == parse.commandStart + commandLength - 1) {
/*
- * The command terminator character (such as ; or ]) is
- * the last character in the parsed command. Reduce the
- * length by one so that the trace message doesn't include
- * the terminator character.
+ * The command terminator character (such as ; or ]) is the
+ * last character in the parsed command. Reduce the length by
+ * one so that the trace message doesn't include the
+ * terminator character.
*/
-
+
commandLength -= 1;
}
#ifdef TCL_COMPILE_DEBUG
/*
- * If tracing, print a line for each top level command compiled.
- */
+ * If tracing, print a line for each top level command compiled.
+ */
if ((tclTraceCompile >= 1) && (envPtr->procPtr == NULL)) {
fprintf(stdout, " Compiling: ");
@@ -1047,8 +1036,7 @@ TclCompileScript(interp, script, numBytes, envPtr)
#endif
/*
- * Check whether expansion has been requested for any of
- * the words
+ * Check whether expansion has been requested for any of the words
*/
for (wordIdx = 0, tokenPtr = parse.tokenPtr;
@@ -1056,7 +1044,7 @@ TclCompileScript(interp, script, numBytes, envPtr)
wordIdx++, tokenPtr += (tokenPtr->numComponents + 1)) {
if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
expand = 1;
- TclEmitOpcode(INST_EXPAND_START, envPtr);
+ TclEmitOpcode(INST_EXPAND_START, envPtr);
break;
}
}
@@ -1066,155 +1054,151 @@ TclCompileScript(interp, script, numBytes, envPtr)
lastTopLevelCmdIndex = currCmdIndex;
startCodeOffset = (envPtr->codeNext - envPtr->codeStart);
EnterCmdStartData(envPtr, currCmdIndex,
- (parse.commandStart - envPtr->source), startCodeOffset);
+ (parse.commandStart - envPtr->source), startCodeOffset);
/*
- * Each iteration of the following loop compiles one word
- * from the command.
+ * Each iteration of the following loop compiles one word from the
+ * command.
*/
-
+
for (wordIdx = 0, tokenPtr = parse.tokenPtr;
wordIdx < parse.numWords; wordIdx++,
tokenPtr += (tokenPtr->numComponents + 1)) {
- if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
/*
- * If this is the first word and the command has a
- * compile procedure, let it compile the command.
+ * The word is not a simple string of characters.
*/
- if ((wordIdx == 0) && !expand) {
- /*
- * We copy the string before trying to find the command
- * by name. We used to modify the string in place, but
- * this is not safe because the name resolution
- * handlers could have side effects that rely on the
- * unmodified string.
- */
+ TclCompileTokens(interp, tokenPtr+1,
+ tokenPtr->numComponents, envPtr);
+ if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+ TclEmitInstInt4(INST_EXPAND_STKTOP,
+ envPtr->currStackDepth, envPtr);
+ }
+ continue;
+ }
- Tcl_DStringSetLength(&ds, 0);
- Tcl_DStringAppend(&ds, tokenPtr[1].start,
- tokenPtr[1].size);
+ /*
+ * This is a simple string of literal characters (i.e. we know
+ * it absolutely and can use it directly). If this is the
+ * first word and the command has a compile procedure, let it
+ * compile the command.
+ */
- cmdPtr = (Command *) Tcl_FindCommand(interp,
- Tcl_DStringValue(&ds),
- (Tcl_Namespace *) cmdNsPtr, /*flags*/ 0);
+ if ((wordIdx == 0) && !expand) {
+ /*
+ * We copy the string before trying to find the command by
+ * name. We used to modify the string in place, but this
+ * is not safe because the name resolution handlers could
+ * have side effects that rely on the unmodified string.
+ */
- if ((cmdPtr != NULL)
- && (cmdPtr->compileProc != NULL)
- && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)
- && !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
- int savedNumCmds = envPtr->numCommands;
- unsigned int savedCodeNext =
- envPtr->codeNext - envPtr->codeStart;
+ Tcl_DStringSetLength(&ds, 0);
+ Tcl_DStringAppend(&ds, tokenPtr[1].start,tokenPtr[1].size);
- /*
- * Mark the start of the command; the proper
- * bytecode length will be updated later. There
- * is no need to do this for the first command
- * in the compile env, as the check is done before
- * calling TclExecuteByteCode(). Remark that we
- * are compiling the first cmd in the environment
- * exactly when (savedCodeNext == 0)
- */
+ cmdPtr = (Command *) Tcl_FindCommand(interp,
+ Tcl_DStringValue(&ds),
+ (Tcl_Namespace *) cmdNsPtr, /*flags*/ 0);
- if (savedCodeNext != 0) {
- TclEmitInstInt4(INST_START_CMD, 0, envPtr);
- }
-
- code = (*(cmdPtr->compileProc))(interp, &parse,
- envPtr);
-
- if (code == TCL_OK) {
- if (savedCodeNext != 0) {
- /*
- * Fix the bytecode length.
- */
- unsigned char *fixPtr = envPtr->codeStart
- + savedCodeNext + 1;
- unsigned int fixLen = envPtr->codeNext
- - envPtr->codeStart
- - savedCodeNext;
-
- TclStoreInt4AtPtr(fixLen, fixPtr);
- }
- goto finishCommand;
- } else {
- /*
- * Restore numCommands and codeNext to their
- * correct values, removing any commands
- * compiled before the failure to produce
- * bytecode got reported.
- * [Bugs 705406 and 735055]
- */
- envPtr->numCommands = savedNumCmds;
- envPtr->codeNext = envPtr->codeStart
- + savedCodeNext;
- }
- }
+ if ((cmdPtr != NULL)
+ && (cmdPtr->compileProc != NULL)
+ && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)
+ && !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
+ int savedNumCmds = envPtr->numCommands;
+ unsigned int savedCodeNext =
+ envPtr->codeNext - envPtr->codeStart;
/*
- * No compile procedure so push the word. If the
- * command was found, push a CmdName object to
- * reduce runtime lookups. Avoid sharing this literal
- * among different namespaces to reduce shimmering.
+ * Mark the start of the command; the proper bytecode
+ * length will be updated later. There is no need to
+ * do this for the first command in the compile env,
+ * as the check is done before calling
+ * TclExecuteByteCode(). Remark that we are compiling
+ * the first cmd in the environment exactly when
+ * (savedCodeNext == 0)
*/
- objIndex = TclRegisterNewNSLiteral(envPtr,
- tokenPtr[1].start, tokenPtr[1].size);
- if (cmdPtr != NULL) {
- TclSetCmdNameObj(interp,
- envPtr->literalArrayPtr[objIndex].objPtr,
- cmdPtr);
+ if (savedCodeNext != 0) {
+ TclEmitInstInt4(INST_START_CMD, 0, envPtr);
}
- if ((wordIdx == 0) && (parse.numWords == 1)) {
+
+ code = (cmdPtr->compileProc)(interp, &parse, envPtr);
+
+ if (code == TCL_OK) {
+ if (savedCodeNext != 0) {
+ /*
+ * Fix the bytecode length.
+ */
+ unsigned char *fixPtr = envPtr->codeStart
+ + savedCodeNext + 1;
+ unsigned int fixLen = envPtr->codeNext
+ - envPtr->codeStart - savedCodeNext;
+
+ TclStoreInt4AtPtr(fixLen, fixPtr);
+ }
+ goto finishCommand;
+ } else {
/*
- * Single word script: unshare the command name to
- * avoid shimmering between bytecode and cmdName
- * representations [Bug 458361]
+ * Restore numCommands and codeNext to their
+ * correct values, removing any commands compiled
+ * before the failure to produce bytecode got
+ * reported. [Bugs 705406 and 735055]
*/
-
- TclHideLiteral(interp, envPtr, objIndex);
+ envPtr->numCommands = savedNumCmds;
+ envPtr->codeNext = envPtr->codeStart+savedCodeNext;
}
- } else {
- objIndex = TclRegisterNewLiteral(envPtr,
- tokenPtr[1].start, tokenPtr[1].size);
}
- TclEmitPush(objIndex, envPtr);
- } else {
+
/*
- * The word is not a simple string of characters.
+ * No compile procedure so push the word. If the command
+ * was found, push a CmdName object to reduce runtime
+ * lookups. Avoid sharing this literal among different
+ * namespaces to reduce shimmering.
*/
-
- TclCompileTokens(interp, tokenPtr+1,
- tokenPtr->numComponents, envPtr);
- }
- if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
- TclEmitInstInt4(INST_EXPAND_STKTOP,
- envPtr->currStackDepth, envPtr);
+
+ objIndex = TclRegisterNewNSLiteral(envPtr,
+ tokenPtr[1].start, tokenPtr[1].size);
+ if (cmdPtr != NULL) {
+ TclSetCmdNameObj(interp,
+ envPtr->literalArrayPtr[objIndex].objPtr,cmdPtr);
+ }
+ if ((wordIdx == 0) && (parse.numWords == 1)) {
+ /*
+ * Single word script: unshare the command name to
+ * avoid shimmering between bytecode and cmdName
+ * representations [Bug 458361]
+ */
+
+ TclHideLiteral(interp, envPtr, objIndex);
+ }
+ } else {
+ objIndex = TclRegisterNewLiteral(envPtr,
+ tokenPtr[1].start, tokenPtr[1].size);
}
+ TclEmitPush(objIndex, envPtr);
}
/*
- * Emit an invoke instruction for the command. We skip this
- * if a compile procedure was found for the command.
+ * Emit an invoke instruction for the command. We skip this if a
+ * compile procedure was found for the command.
*/
if (expand) {
/*
* The stack depth during argument expansion can only be
* managed at runtime, as the number of elements in the
- * expanded lists is not known at compile time.
- * We adjust here the stack depth estimate so that it is
- * correct after the command with expanded arguments
- * returns.
- * The end effect of this command's invocation is that
- * all the words of the command are popped from the stack,
- * and the result is pushed: the stack top changes by
- * (1-wordIdx).
- * Note that the estimates are not correct while the
- * command is being prepared and run, INST_EXPAND_STKTOP
- * is not stack-neutral in general.
+ * expanded lists is not known at compile time. We adjust
+ * here the stack depth estimate so that it is correct after
+ * the command with expanded arguments returns.
+ *
+ * The end effect of this command's invocation is that all the
+ * words of the command are popped from the stack, and the
+ * result is pushed: the stack top changes by (1-wordIdx).
+ *
+ * Note that the estimates are not correct while the command
+ * is being prepared and run, INST_EXPAND_STKTOP is not
+ * stack-neutral in general.
*/
TclEmitOpcode(INST_INVOKE_EXPANDED, envPtr);
@@ -1225,7 +1209,7 @@ TclCompileScript(interp, script, numBytes, envPtr)
} else {
TclEmitInstInt4(INST_INVOKE_STK4, wordIdx, envPtr);
}
- }
+ }
/*
* Update the compilation environment structure and record the
@@ -1241,7 +1225,7 @@ TclCompileScript(interp, script, numBytes, envPtr)
/*
* Advance to the next command in the script.
*/
-
+
next = parse.commandStart + parse.commandSize;
bytesLeft -= (next - p);
p = next;
@@ -1259,11 +1243,11 @@ TclCompileScript(interp, script, numBytes, envPtr)
* have special code in TclReleaseLiteral to handle this particular
* self-reference, but now opt for avoiding its creation altogether.
*/
-
+
if (envPtr->codeNext == entryCodeNext) {
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_NewObj(), NULL), envPtr);
}
-
+
envPtr->numSrcBytes = (p - script);
Tcl_DStringFree(&ds);
}
@@ -1274,17 +1258,17 @@ TclCompileScript(interp, script, numBytes, envPtr)
* TclCompileTokens --
*
* Given an array of tokens parsed from a Tcl command (e.g., the tokens
- * that make up a word) this procedure emits instructions to evaluate
- * the tokens and concatenate their values to form a single result
- * value on the interpreter's runtime evaluation stack.
+ * that make up a word) this procedure emits instructions to evaluate the
+ * tokens and concatenate their values to form a single result value on
+ * the interpreter's runtime evaluation stack.
*
* Results:
* The return value is a standard Tcl result. If an error occurs, an
* error message is left in the interpreter's result.
- *
+ *
* Side effects:
- * Instructions are added to envPtr to push and evaluate the tokens
- * at runtime.
+ * Instructions are added to envPtr to push and evaluate the tokens at
+ * runtime.
*
*----------------------------------------------------------------------
*/
@@ -1292,8 +1276,8 @@ TclCompileScript(interp, script, numBytes, envPtr)
void
TclCompileTokens(interp, tokenPtr, count, envPtr)
Tcl_Interp *interp; /* Used for error and status reporting. */
- Tcl_Token *tokenPtr; /* Pointer to first in an array of tokens
- * to compile. */
+ Tcl_Token *tokenPtr; /* Pointer to first in an array of tokens to
+ * compile. */
int count; /* Number of tokens to consider at tokenPtr.
* Must be at least 1. */
CompileEnv *envPtr; /* Holds the resulting instructions. */
@@ -1310,130 +1294,124 @@ TclCompileTokens(interp, tokenPtr, count, envPtr)
numObjsToConcat = 0;
for ( ; count > 0; count--, tokenPtr++) {
switch (tokenPtr->type) {
- case TCL_TOKEN_TEXT:
- Tcl_DStringAppend(&textBuffer, tokenPtr->start,
- tokenPtr->size);
- break;
+ case TCL_TOKEN_TEXT:
+ Tcl_DStringAppend(&textBuffer, tokenPtr->start, tokenPtr->size);
+ break;
- case TCL_TOKEN_BS:
- length = Tcl_UtfBackslash(tokenPtr->start, (int *) NULL,
- buffer);
- Tcl_DStringAppend(&textBuffer, buffer, length);
- break;
+ case TCL_TOKEN_BS:
+ length = Tcl_UtfBackslash(tokenPtr->start, (int *) NULL, buffer);
+ Tcl_DStringAppend(&textBuffer, buffer, length);
+ break;
- case TCL_TOKEN_COMMAND:
- /*
- * Push any accumulated chars appearing before the command.
- */
-
- if (Tcl_DStringLength(&textBuffer) > 0) {
- int literal;
-
- literal = TclRegisterNewLiteral(envPtr,
- Tcl_DStringValue(&textBuffer),
- Tcl_DStringLength(&textBuffer));
- TclEmitPush(literal, envPtr);
- numObjsToConcat++;
- Tcl_DStringFree(&textBuffer);
- }
-
- TclCompileScript(interp, tokenPtr->start+1,
- tokenPtr->size-2, envPtr);
+ case TCL_TOKEN_COMMAND:
+ /*
+ * Push any accumulated chars appearing before the command.
+ */
+
+ if (Tcl_DStringLength(&textBuffer) > 0) {
+ int literal;
+
+ literal = TclRegisterNewLiteral(envPtr,
+ Tcl_DStringValue(&textBuffer),
+ Tcl_DStringLength(&textBuffer));
+ TclEmitPush(literal, envPtr);
numObjsToConcat++;
- break;
+ Tcl_DStringFree(&textBuffer);
+ }
- case TCL_TOKEN_VARIABLE:
- /*
- * Push any accumulated chars appearing before the $<var>.
- */
-
- if (Tcl_DStringLength(&textBuffer) > 0) {
- int literal;
-
- literal = TclRegisterNewLiteral(envPtr,
- Tcl_DStringValue(&textBuffer),
- Tcl_DStringLength(&textBuffer));
- TclEmitPush(literal, envPtr);
- numObjsToConcat++;
- Tcl_DStringFree(&textBuffer);
- }
-
- /*
- * Determine how the variable name should be handled: if it contains
- * any namespace qualifiers it is not a local variable (localVarName=-1);
- * if it looks like an array element and the token has a single component,
- * it should not be created here [Bug 569438] (localVarName=0); otherwise,
- * the local variable can safely be created (localVarName=1).
- */
-
- name = tokenPtr[1].start;
- nameBytes = tokenPtr[1].size;
- localVarName = -1;
- if (envPtr->procPtr != NULL) {
- localVarName = 1;
- for (i = 0, p = name; i < nameBytes; i++, p++) {
- if ((*p == ':') && (i < (nameBytes-1))
- && (*(p+1) == ':')) {
- localVarName = -1;
- break;
- } else if ((*p == '(')
- && (tokenPtr->numComponents == 1)
- && (*(name + nameBytes - 1) == ')')) {
- localVarName = 0;
- break;
- }
+ TclCompileScript(interp, tokenPtr->start+1,
+ tokenPtr->size-2, envPtr);
+ numObjsToConcat++;
+ break;
+
+ case TCL_TOKEN_VARIABLE:
+ /*
+ * Push any accumulated chars appearing before the $<var>.
+ */
+
+ if (Tcl_DStringLength(&textBuffer) > 0) {
+ int literal;
+
+ literal = TclRegisterNewLiteral(envPtr,
+ Tcl_DStringValue(&textBuffer),
+ Tcl_DStringLength(&textBuffer));
+ TclEmitPush(literal, envPtr);
+ numObjsToConcat++;
+ Tcl_DStringFree(&textBuffer);
+ }
+
+ /*
+ * Determine how the variable name should be handled: if it
+ * contains any namespace qualifiers it is not a local variable
+ * (localVarName=-1); if it looks like an array element and the
+ * token has a single component, it should not be created here
+ * [Bug 569438] (localVarName=0); otherwise, the local variable
+ * can safely be created (localVarName=1).
+ */
+
+ name = tokenPtr[1].start;
+ nameBytes = tokenPtr[1].size;
+ localVarName = -1;
+ if (envPtr->procPtr != NULL) {
+ localVarName = 1;
+ for (i = 0, p = name; i < nameBytes; i++, p++) {
+ if ((*p == ':') && (i < nameBytes-1) && (*(p+1) == ':')) {
+ localVarName = -1;
+ break;
+ } else if ((*p == '(')
+ && (tokenPtr->numComponents == 1)
+ && (*(name + nameBytes - 1) == ')')) {
+ localVarName = 0;
+ break;
}
}
+ }
- /*
- * Either push the variable's name, or find its index in
- * the array of local variables in a procedure frame.
- */
+ /*
+ * Either push the variable's name, or find its index in the array
+ * of local variables in a procedure frame.
+ */
- localVar = -1;
- if (localVarName != -1) {
- localVar = TclFindCompiledLocal(name, nameBytes,
- localVarName, /*flags*/ 0, envPtr->procPtr);
- }
+ localVar = -1;
+ if (localVarName != -1) {
+ localVar = TclFindCompiledLocal(name, nameBytes, localVarName,
+ /*flags*/ 0, envPtr->procPtr);
+ }
+ if (localVar < 0) {
+ TclEmitPush(TclRegisterNewLiteral(envPtr, name, nameBytes),
+ envPtr);
+ }
+
+ /*
+ * Emit instructions to load the variable.
+ */
+
+ if (tokenPtr->numComponents == 1) {
if (localVar < 0) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, name, nameBytes),
- envPtr);
+ TclEmitOpcode(INST_LOAD_SCALAR_STK, envPtr);
+ } else if (localVar <= 255) {
+ TclEmitInstInt1(INST_LOAD_SCALAR1, localVar, envPtr);
+ } else {
+ TclEmitInstInt4(INST_LOAD_SCALAR4, localVar, envPtr);
}
-
- /*
- * Emit instructions to load the variable.
- */
-
- if (tokenPtr->numComponents == 1) {
- if (localVar < 0) {
- TclEmitOpcode(INST_LOAD_SCALAR_STK, envPtr);
- } else if (localVar <= 255) {
- TclEmitInstInt1(INST_LOAD_SCALAR1, localVar,
- envPtr);
- } else {
- TclEmitInstInt4(INST_LOAD_SCALAR4, localVar,
- envPtr);
- }
+ } else {
+ TclCompileTokens(interp, tokenPtr+2,
+ tokenPtr->numComponents-1, envPtr);
+ if (localVar < 0) {
+ TclEmitOpcode(INST_LOAD_ARRAY_STK, envPtr);
+ } else if (localVar <= 255) {
+ TclEmitInstInt1(INST_LOAD_ARRAY1, localVar, envPtr);
} else {
- TclCompileTokens(interp, tokenPtr+2,
- tokenPtr->numComponents-1, envPtr);
- if (localVar < 0) {
- TclEmitOpcode(INST_LOAD_ARRAY_STK, envPtr);
- } else if (localVar <= 255) {
- TclEmitInstInt1(INST_LOAD_ARRAY1, localVar,
- envPtr);
- } else {
- TclEmitInstInt4(INST_LOAD_ARRAY4, localVar,
- envPtr);
- }
+ TclEmitInstInt4(INST_LOAD_ARRAY4, localVar, envPtr);
}
- numObjsToConcat++;
- count -= tokenPtr->numComponents;
- tokenPtr += tokenPtr->numComponents;
- break;
+ }
+ numObjsToConcat++;
+ count -= tokenPtr->numComponents;
+ tokenPtr += tokenPtr->numComponents;
+ break;
- default:
- Tcl_Panic("Unexpected token type in TclCompileTokens");
+ default:
+ Tcl_Panic("Unexpected token type in TclCompileTokens");
}
}
@@ -1445,7 +1423,7 @@ TclCompileTokens(interp, tokenPtr, count, envPtr)
int literal;
literal = TclRegisterNewLiteral(envPtr, Tcl_DStringValue(&textBuffer),
- Tcl_DStringLength(&textBuffer));
+ Tcl_DStringLength(&textBuffer));
TclEmitPush(literal, envPtr);
numObjsToConcat++;
}
@@ -1465,10 +1443,9 @@ TclCompileTokens(interp, tokenPtr, count, envPtr)
/*
* If the tokens yielded no instructions, push an empty string.
*/
-
+
if (envPtr->codeNext == entryCodeNext) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0),
- envPtr);
+ TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
}
Tcl_DStringFree(&textBuffer);
}
@@ -1481,13 +1458,13 @@ TclCompileTokens(interp, tokenPtr, count, envPtr)
* Given an array of parse tokens for a word containing one or more Tcl
* commands, emit inline instructions to execute them. This procedure
* differs from TclCompileTokens in that a simple word such as a loop
- * body enclosed in braces is not just pushed as a string, but is
- * itself parsed into tokens and compiled.
+ * body enclosed in braces is not just pushed as a string, but is itself
+ * parsed into tokens and compiled.
*
* Results:
* The return value is a standard Tcl result. If an error occurs, an
* error message is left in the interpreter's result.
- *
+ *
* Side effects:
* Instructions are added to envPtr to execute the tokens at runtime.
*
@@ -1497,8 +1474,8 @@ TclCompileTokens(interp, tokenPtr, count, envPtr)
void
TclCompileCmdWord(interp, tokenPtr, count, envPtr)
Tcl_Interp *interp; /* Used for error and status reporting. */
- Tcl_Token *tokenPtr; /* Pointer to first in an array of tokens
- * for a command word to compile inline. */
+ Tcl_Token *tokenPtr; /* Pointer to first in an array of tokens for
+ * a command word to compile inline. */
int count; /* Number of tokens to consider at tokenPtr.
* Must be at least 1. */
CompileEnv *envPtr; /* Holds the resulting instructions. */
@@ -1508,13 +1485,13 @@ TclCompileCmdWord(interp, tokenPtr, count, envPtr)
* Handle the common case: if there is a single text token,
* compile it into an inline sequence of instructions.
*/
-
+
TclCompileScript(interp, tokenPtr->start, tokenPtr->size, envPtr);
} else {
/*
- * Multiple tokens or the single token involves substitutions.
- * Emit instructions to invoke the eval command procedure at
- * runtime on the result of evaluating the tokens.
+ * Multiple tokens or the single token involves substitutions. Emit
+ * instructions to invoke the eval command procedure at runtime on the
+ * result of evaluating the tokens.
*/
TclCompileTokens(interp, tokenPtr, count, envPtr);
@@ -1536,7 +1513,7 @@ TclCompileCmdWord(interp, tokenPtr, count, envPtr)
* Results:
* The return value is a standard Tcl result. If an error occurs, an
* error message is left in the interpreter's result.
- *
+ *
* Side effects:
* Instructions are added to envPtr to execute the expression.
*
@@ -1546,20 +1523,20 @@ TclCompileCmdWord(interp, tokenPtr, count, envPtr)
void
TclCompileExprWords(interp, tokenPtr, numWords, envPtr)
Tcl_Interp *interp; /* Used for error and status reporting. */
- Tcl_Token *tokenPtr; /* Points to first in an array of word
- * tokens tokens for the expression to
- * compile inline. */
- int numWords; /* Number of word tokens starting at
- * tokenPtr. Must be at least 1. Each word
- * token contains one or more subtokens. */
+ Tcl_Token *tokenPtr; /* Points to first in an array of word tokens
+ * tokens for the expression to compile
+ * inline. */
+ int numWords; /* Number of word tokens starting at tokenPtr.
+ * Must be at least 1. Each word token
+ * contains one or more subtokens. */
CompileEnv *envPtr; /* Holds the resulting instructions. */
{
Tcl_Token *wordPtr;
int i, concatItems;
/*
- * If the expression is a single word that doesn't require
- * substitutions, just compile its string into inline instructions.
+ * If the expression is a single word that doesn't require substitutions,
+ * just compile its string into inline instructions.
*/
if ((numWords == 1) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
@@ -1574,7 +1551,7 @@ TclCompileExprWords(interp, tokenPtr, numWords, envPtr)
envPtr->numCommands = savedNumCmds;
envPtr->codeNext = envPtr->codeStart + savedCodeNext;
}
-
+
/*
* Emit code to call the expr command proc at runtime. Concatenate the
* (already substituted once) expr tokens with a space between each.
@@ -1584,8 +1561,7 @@ TclCompileExprWords(interp, tokenPtr, numWords, envPtr)
for (i = 0; i < numWords; i++) {
TclCompileTokens(interp, wordPtr+1, wordPtr->numComponents, envPtr);
if (i < (numWords - 1)) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, " ", 1),
- envPtr);
+ TclEmitPush(TclRegisterNewLiteral(envPtr, " ", 1), envPtr);
}
wordPtr += (wordPtr->numComponents + 1);
}
@@ -1606,10 +1582,10 @@ TclCompileExprWords(interp, tokenPtr, numWords, envPtr)
* TclInitByteCodeObj --
*
* Create a ByteCode structure and initialize it from a CompileEnv
- * compilation environment structure. The ByteCode structure is
- * smaller and contains just that information needed to execute
- * the bytecode instructions resulting from compiling a Tcl script.
- * The resulting structure is placed in the specified object.
+ * compilation environment structure. The ByteCode structure is smaller
+ * and contains just that information needed to execute the bytecode
+ * instructions resulting from compiling a Tcl script. The resulting
+ * structure is placed in the specified object.
*
* Results:
* A newly constructed ByteCode object is stored in the internal
@@ -1617,19 +1593,19 @@ TclCompileExprWords(interp, tokenPtr, numWords, envPtr)
*
* Side effects:
* A single heap object is allocated to hold the new ByteCode structure
- * and its code, object, command location, and aux data arrays. Note
- * that "ownership" (i.e., the pointers to) the Tcl objects and aux
- * data items will be handed over to the new ByteCode structure from
- * the CompileEnv structure.
+ * and its code, object, command location, and aux data arrays. Note that
+ * "ownership" (i.e., the pointers to) the Tcl objects and aux data items
+ * will be handed over to the new ByteCode structure from the CompileEnv
+ * structure.
*
*----------------------------------------------------------------------
*/
void
TclInitByteCodeObj(objPtr, envPtr)
- Tcl_Obj *objPtr; /* Points object that should be
- * initialized, and whose string rep
- * contains the source code. */
+ Tcl_Obj *objPtr; /* Points object that should be initialized,
+ * and whose string rep contains the source
+ * code. */
register CompileEnv *envPtr; /* Points to the CompileEnv structure from
* which to create a ByteCode structure. */
{
@@ -1652,24 +1628,24 @@ TclInitByteCodeObj(objPtr, envPtr)
exceptArrayBytes = (envPtr->exceptArrayNext * sizeof(ExceptionRange));
auxDataArrayBytes = (envPtr->auxDataArrayNext * sizeof(AuxData));
cmdLocBytes = GetCmdLocEncodingSize(envPtr);
-
+
/*
* Compute the total number of bytes needed for this bytecode.
*/
structureSize = sizeof(ByteCode);
- structureSize += TCL_ALIGN(codeBytes); /* align object array */
- structureSize += TCL_ALIGN(objArrayBytes); /* align exc range arr */
+ structureSize += TCL_ALIGN(codeBytes); /* align object array */
+ structureSize += TCL_ALIGN(objArrayBytes); /* align exc range arr */
structureSize += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
structureSize += auxDataArrayBytes;
structureSize += cmdLocBytes;
if (envPtr->iPtr->varFramePtr != NULL) {
- namespacePtr = envPtr->iPtr->varFramePtr->nsPtr;
+ namespacePtr = envPtr->iPtr->varFramePtr->nsPtr;
} else {
- namespacePtr = envPtr->iPtr->globalNsPtr;
+ namespacePtr = envPtr->iPtr->globalNsPtr;
}
-
+
p = (unsigned char *) ckalloc((size_t) structureSize);
codePtr = (ByteCode *) p;
codePtr->interpHandle = TclHandlePreserve(iPtr->handle);
@@ -1698,27 +1674,27 @@ TclInitByteCodeObj(objPtr, envPtr)
p += sizeof(ByteCode);
codePtr->codeStart = p;
memcpy((VOID *) p, (VOID *) envPtr->codeStart, (size_t) codeBytes);
-
- p += TCL_ALIGN(codeBytes); /* align object array */
+
+ p += TCL_ALIGN(codeBytes); /* align object array */
codePtr->objArrayPtr = (Tcl_Obj **) p;
for (i = 0; i < numLitObjects; i++) {
codePtr->objArrayPtr[i] = envPtr->literalArrayPtr[i].objPtr;
}
- p += TCL_ALIGN(objArrayBytes); /* align exception range array */
+ p += TCL_ALIGN(objArrayBytes); /* align exception range array */
if (exceptArrayBytes > 0) {
codePtr->exceptArrayPtr = (ExceptionRange *) p;
memcpy((VOID *) p, (VOID *) envPtr->exceptArrayPtr,
- (size_t) exceptArrayBytes);
+ (size_t) exceptArrayBytes);
} else {
codePtr->exceptArrayPtr = NULL;
}
-
- p += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
+
+ p += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
if (auxDataArrayBytes > 0) {
codePtr->auxDataArrayPtr = (AuxData *) p;
memcpy((VOID *) p, (VOID *) envPtr->auxDataArrayPtr,
- (size_t) auxDataArrayBytes);
+ (size_t) auxDataArrayBytes);
} else {
codePtr->auxDataArrayPtr = NULL;
}
@@ -1728,11 +1704,11 @@ TclInitByteCodeObj(objPtr, envPtr)
EncodeCmdLocMap(envPtr, codePtr, (unsigned char *) p);
#else
nextPtr = EncodeCmdLocMap(envPtr, codePtr, (unsigned char *) p);
- if (((size_t)(nextPtr - p)) != cmdLocBytes) {
+ if (((size_t)(nextPtr - p)) != cmdLocBytes) {
Tcl_Panic("TclInitByteCodeObj: encoded cmd location bytes %d != expected size %d\n", (nextPtr - p), cmdLocBytes);
}
#endif
-
+
/*
* Record various compilation-related statistics about the new ByteCode
* structure. Don't include overhead for statistics-related fields.
@@ -1742,16 +1718,15 @@ TclInitByteCodeObj(objPtr, envPtr)
codePtr->structureSize = structureSize
- (sizeof(size_t) + sizeof(Tcl_Time));
Tcl_GetTime(&(codePtr->createTime));
-
+
RecordByteCodeStats(codePtr);
#endif /* TCL_COMPILE_STATS */
-
+
/*
- * Free the old internal rep then convert the object to a
- * bytecode object by making its internal rep point to the just
- * compiled ByteCode.
+ * Free the old internal rep then convert the object to a bytecode object
+ * by making its internal rep point to the just compiled ByteCode.
*/
-
+
TclFreeIntRep(objPtr);
objPtr->internalRep.otherValuePtr = (VOID *) codePtr;
objPtr->typePtr = &tclByteCodeType;
@@ -1771,26 +1746,25 @@ TclInitByteCodeObj(objPtr, envPtr)
* Results:
* If create is 0 and the name is non-NULL, then if the variable is
* found, the index of its entry in the procedure's array of local
- * variables is returned; otherwise -1 is returned. If name is NULL,
- * the index of a new temporary variable is returned. Finally, if
- * create is 1 and name is non-NULL, the index of a new entry is
- * returned.
+ * variables is returned; otherwise -1 is returned. If name is NULL, the
+ * index of a new temporary variable is returned. Finally, if create is 1
+ * and name is non-NULL, the index of a new entry is returned.
*
* Side effects:
- * Creates and registers a new local variable if create is 1 and
- * the variable is unknown, or if the name is NULL.
+ * Creates and registers a new local variable if create is 1 and the
+ * variable is unknown, or if the name is NULL.
*
*----------------------------------------------------------------------
*/
int
TclFindCompiledLocal(name, nameBytes, create, flags, procPtr)
- register CONST char *name; /* Points to first character of the name of
- * a scalar or array variable. If NULL, a
+ register CONST char *name; /* Points to first character of the name of a
+ * scalar or array variable. If NULL, a
* temporary var should be created. */
int nameBytes; /* Number of bytes in the name. */
- int create; /* If 1, allocate a local frame entry for
- * the variable if it is new. */
+ int create; /* If 1, allocate a local frame entry for the
+ * variable if it is new. */
int flags; /* Flag bits for the compiled local if
* created. Only VAR_SCALAR, VAR_ARRAY, and
* VAR_LINK make sense. */
@@ -1806,14 +1780,14 @@ TclFindCompiledLocal(name, nameBytes, create, flags, procPtr)
* name already exist?
*/
- if (name != NULL) {
+ if (name != NULL) {
int localCt = procPtr->numCompiledLocals;
localPtr = procPtr->firstLocalPtr;
for (i = 0; i < localCt; i++) {
if (!TclIsVarTemporary(localPtr)) {
char *localName = localPtr->name;
- if ((nameBytes == localPtr->nameLength)
- && (strncmp(name, localName, (unsigned) nameBytes) == 0)) {
+ if ((nameBytes == localPtr->nameLength) &&
+ (strncmp(name,localName,(unsigned)nameBytes) == 0)) {
return i;
}
}
@@ -1824,11 +1798,11 @@ TclFindCompiledLocal(name, nameBytes, create, flags, procPtr)
/*
* Create a new variable if appropriate.
*/
-
+
if (create || (name == NULL)) {
localVar = procPtr->numCompiledLocals;
- localPtr = (CompiledLocal *) ckalloc((unsigned)
- (sizeof(CompiledLocal) - sizeof(localPtr->name)
+ localPtr = (CompiledLocal *) ckalloc((unsigned)
+ (sizeof(CompiledLocal) - sizeof(localPtr->name)
+ nameBytes+1));
if (procPtr->firstLocalPtr == NULL) {
procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
@@ -1847,8 +1821,7 @@ TclFindCompiledLocal(name, nameBytes, create, flags, procPtr)
localPtr->resolveInfo = NULL;
if (name != NULL) {
- memcpy((VOID *) localPtr->name, (VOID *) name,
- (size_t) nameBytes);
+ memcpy((VOID *) localPtr->name, (VOID *) name, (size_t) nameBytes);
}
localPtr->name[nameBytes] = '\0';
procPtr->numCompiledLocals++;
@@ -1861,17 +1834,16 @@ TclFindCompiledLocal(name, nameBytes, create, flags, procPtr)
*
* TclExpandCodeArray --
*
- * Procedure that uses malloc to allocate more storage for a
- * CompileEnv's code array.
+ * Procedure that uses malloc to allocate more storage for a CompileEnv's
+ * code array.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The byte code array in *envPtr is reallocated to a new array of
- * double the size, and if envPtr->mallocedCodeArray is non-zero the
- * old array is freed. Byte codes are copied from the old array to the
- * new one.
+ * The byte code array in *envPtr is reallocated to a new array of double
+ * the size, and if envPtr->mallocedCodeArray is non-zero the old array
+ * is freed. Byte codes are copied from the old array to the new one.
*
*----------------------------------------------------------------------
*/
@@ -1886,26 +1858,26 @@ TclExpandCodeArray(envArgPtr)
/*
* envPtr->codeNext is equal to envPtr->codeEnd. The currently defined
- * code bytes are stored between envPtr->codeStart and
- * (envPtr->codeNext - 1) [inclusive].
+ * code bytes are stored between envPtr->codeStart and envPtr->codeNext-1
+ * [inclusive].
*/
-
+
size_t currBytes = (envPtr->codeNext - envPtr->codeStart);
- size_t newBytes = 2*(envPtr->codeEnd - envPtr->codeStart);
+ size_t newBytes = 2*(envPtr->codeEnd - envPtr->codeStart);
unsigned char *newPtr = (unsigned char *) ckalloc((unsigned) newBytes);
/*
* Copy from old code array to new, free old code array if needed, and
* mark new code array as malloced.
*/
-
+
memcpy((VOID *) newPtr, (VOID *) envPtr->codeStart, currBytes);
if (envPtr->mallocedCodeArray) {
- ckfree((char *) envPtr->codeStart);
+ ckfree((char *) envPtr->codeStart);
}
envPtr->codeStart = newPtr;
envPtr->codeNext = (newPtr + currBytes);
- envPtr->codeEnd = (newPtr + newBytes);
+ envPtr->codeEnd = (newPtr + newBytes);
envPtr->mallocedCodeArray = 1;
}
@@ -1914,17 +1886,17 @@ TclExpandCodeArray(envArgPtr)
*
* EnterCmdStartData --
*
- * Registers the starting source and bytecode location of a
- * command. This information is used at runtime to map between
- * instruction pc and source locations.
+ * Registers the starting source and bytecode location of a command. This
+ * information is used at runtime to map between instruction pc and
+ * source locations.
*
* Results:
* None.
*
* Side effects:
* Inserts source and code location information into the compilation
- * environment envPtr for the command at index cmdIndex. The
- * compilation environment's CmdLocation array is grown if necessary.
+ * environment envPtr for the command at index cmdIndex. The compilation
+ * environment's CmdLocation array is grown if necessary.
*
*----------------------------------------------------------------------
*/
@@ -1934,17 +1906,17 @@ EnterCmdStartData(envPtr, cmdIndex, srcOffset, codeOffset)
CompileEnv *envPtr; /* Points to the compilation environment
* structure in which to enter command
* location information. */
- int cmdIndex; /* Index of the command whose start data
- * is being set. */
+ int cmdIndex; /* Index of the command whose start data is
+ * being set. */
int srcOffset; /* Offset of first char of the command. */
int codeOffset; /* Offset of first byte of command code. */
{
CmdLocation *cmdLocPtr;
-
+
if ((cmdIndex < 0) || (cmdIndex >= envPtr->numCommands)) {
Tcl_Panic("EnterCmdStartData: bad command index %d\n", cmdIndex);
}
-
+
if (cmdIndex >= envPtr->cmdMapEnd) {
/*
* Expand the command location array by allocating more storage from
@@ -1953,16 +1925,16 @@ EnterCmdStartData(envPtr, cmdIndex, srcOffset, codeOffset)
*/
size_t currElems = envPtr->cmdMapEnd;
- size_t newElems = 2*currElems;
+ size_t newElems = 2*currElems;
size_t currBytes = currElems * sizeof(CmdLocation);
- size_t newBytes = newElems * sizeof(CmdLocation);
+ size_t newBytes = newElems * sizeof(CmdLocation);
CmdLocation *newPtr = (CmdLocation *) ckalloc((unsigned) newBytes);
-
+
/*
* Copy from old command location array to new, free old command
* location array if needed, and mark new array as malloced.
*/
-
+
memcpy((VOID *) newPtr, (VOID *) envPtr->cmdMapPtr, currBytes);
if (envPtr->mallocedCmdMap) {
ckfree((char *) envPtr->cmdMapPtr);
@@ -1999,9 +1971,9 @@ EnterCmdStartData(envPtr, cmdIndex, srcOffset, codeOffset)
*
* Side effects:
* Inserts source and code length information into the compilation
- * environment envPtr for the command at index cmdIndex. Starting
- * source and bytecode information for the command must already
- * have been registered.
+ * environment envPtr for the command at index cmdIndex. Starting source
+ * and bytecode information for the command must already have been
+ * registered.
*
*----------------------------------------------------------------------
*/
@@ -2011,8 +1983,8 @@ EnterCmdExtentData(envPtr, cmdIndex, numSrcBytes, numCodeBytes)
CompileEnv *envPtr; /* Points to the compilation environment
* structure in which to enter command
* location information. */
- int cmdIndex; /* Index of the command whose source and
- * code length data is being set. */
+ int cmdIndex; /* Index of the command whose source and code
+ * length data is being set. */
int numSrcBytes; /* Number of command source chars. */
int numCodeBytes; /* Offset of last byte of command code. */
{
@@ -2021,10 +1993,10 @@ EnterCmdExtentData(envPtr, cmdIndex, numSrcBytes, numCodeBytes)
if ((cmdIndex < 0) || (cmdIndex >= envPtr->numCommands)) {
Tcl_Panic("EnterCmdExtentData: bad command index %d\n", cmdIndex);
}
-
+
if (cmdIndex > envPtr->cmdMapEnd) {
Tcl_Panic("EnterCmdExtentData: missing start data for command %d\n",
- cmdIndex);
+ cmdIndex);
}
cmdLocPtr = &(envPtr->cmdMapPtr[cmdIndex]);
@@ -2044,11 +2016,10 @@ EnterCmdExtentData(envPtr, cmdIndex, numSrcBytes, numCodeBytes)
* Returns the index for the newly created ExceptionRange.
*
* Side effects:
- * If there is not enough room in the CompileEnv's ExceptionRange
- * array, the array in expanded: a new array of double the size is
- * allocated, if envPtr->mallocedExceptArray is non-zero the old
- * array is freed, and ExceptionRange entries are copied from the old
- * array to the new one.
+ * If there is not enough room in the CompileEnv's ExceptionRange array,
+ * the array in expanded: a new array of double the size is allocated, if
+ * envPtr->mallocedExceptArray is non-zero the old array is freed, and
+ * ExceptionRange entries are copied from the old array to the new one.
*
*----------------------------------------------------------------------
*/
@@ -2056,34 +2027,32 @@ EnterCmdExtentData(envPtr, cmdIndex, numSrcBytes, numCodeBytes)
int
TclCreateExceptRange(type, envPtr)
ExceptionRangeType type; /* The kind of ExceptionRange desired. */
- register CompileEnv *envPtr;/* Points to CompileEnv for which to
- * create a new ExceptionRange structure. */
+ register CompileEnv *envPtr;/* Points to CompileEnv for which to create a
+ * new ExceptionRange structure. */
{
register ExceptionRange *rangePtr;
int index = envPtr->exceptArrayNext;
-
+
if (index >= envPtr->exceptArrayEnd) {
- /*
+ /*
* Expand the ExceptionRange array. The currently allocated entries
* are stored between elements 0 and (envPtr->exceptArrayNext - 1)
* [inclusive].
*/
-
+
size_t currBytes =
- envPtr->exceptArrayNext * sizeof(ExceptionRange);
+ envPtr->exceptArrayNext * sizeof(ExceptionRange);
int newElems = 2*envPtr->exceptArrayEnd;
size_t newBytes = newElems * sizeof(ExceptionRange);
ExceptionRange *newPtr = (ExceptionRange *)
- ckalloc((unsigned) newBytes);
-
+ ckalloc((unsigned) newBytes);
+
/*
- * Copy from old ExceptionRange array to new, free old
- * ExceptionRange array if needed, and mark the new ExceptionRange
- * array as malloced.
+ * Copy from old ExceptionRange array to new, free old ExceptionRange
+ * array if needed, and mark the new ExceptionRange array as malloced.
*/
-
- memcpy((VOID *) newPtr, (VOID *) envPtr->exceptArrayPtr,
- currBytes);
+
+ memcpy((VOID *) newPtr, (VOID *) envPtr->exceptArrayPtr, currBytes);
if (envPtr->mallocedExceptArray) {
ckfree((char *) envPtr->exceptArrayPtr);
}
@@ -2092,7 +2061,7 @@ TclCreateExceptRange(type, envPtr)
envPtr->mallocedExceptArray = 1;
}
envPtr->exceptArrayNext++;
-
+
rangePtr = &(envPtr->exceptArrayPtr[index]);
rangePtr->type = type;
rangePtr->nestingLevel = envPtr->exceptDepth;
@@ -2109,8 +2078,8 @@ TclCreateExceptRange(type, envPtr)
*
* TclCreateAuxData --
*
- * Procedure that allocates and initializes a new AuxData structure in
- * a CompileEnv's array of compilation auxiliary data records. These
+ * Procedure that allocates and initializes a new AuxData structure in a
+ * CompileEnv's array of compilation auxiliary data records. These
* AuxData records hold information created during compilation by
* CompileProcs and used by instructions during execution.
*
@@ -2118,47 +2087,47 @@ TclCreateExceptRange(type, envPtr)
* Returns the index for the newly created AuxData structure.
*
* Side effects:
- * If there is not enough room in the CompileEnv's AuxData array,
- * the AuxData array in expanded: a new array of double the size
- * is allocated, if envPtr->mallocedAuxDataArray is non-zero
- * the old array is freed, and AuxData entries are copied from
- * the old array to the new one.
+ * If there is not enough room in the CompileEnv's AuxData array, the
+ * AuxData array in expanded: a new array of double the size is
+ * allocated, if envPtr->mallocedAuxDataArray is non-zero the old array
+ * is freed, and AuxData entries are copied from the old array to the new
+ * one.
*
*----------------------------------------------------------------------
*/
int
TclCreateAuxData(clientData, typePtr, envPtr)
- ClientData clientData; /* The compilation auxiliary data to store
- * in the new aux data record. */
- AuxDataType *typePtr; /* Pointer to the type to attach to this AuxData */
+ ClientData clientData; /* The compilation auxiliary data to store in
+ * the new aux data record. */
+ AuxDataType *typePtr; /* Pointer to the type to attach to this
+ * AuxData */
register CompileEnv *envPtr;/* Points to the CompileEnv for which a new
* aux data structure is to be allocated. */
{
int index; /* Index for the new AuxData structure. */
register AuxData *auxDataPtr;
/* Points to the new AuxData structure */
-
+
index = envPtr->auxDataArrayNext;
if (index >= envPtr->auxDataArrayEnd) {
- /*
+ /*
* Expand the AuxData array. The currently allocated entries are
* stored between elements 0 and (envPtr->auxDataArrayNext - 1)
* [inclusive].
*/
-
+
size_t currBytes = envPtr->auxDataArrayNext * sizeof(AuxData);
int newElems = 2*envPtr->auxDataArrayEnd;
size_t newBytes = newElems * sizeof(AuxData);
AuxData *newPtr = (AuxData *) ckalloc((unsigned) newBytes);
-
+
/*
* Copy from old AuxData array to new, free old AuxData array if
* needed, and mark the new AuxData array as malloced.
*/
-
- memcpy((VOID *) newPtr, (VOID *) envPtr->auxDataArrayPtr,
- currBytes);
+
+ memcpy((VOID *) newPtr, (VOID *) envPtr->auxDataArrayPtr, currBytes);
if (envPtr->mallocedAuxDataArray) {
ckfree((char *) envPtr->auxDataArrayPtr);
}
@@ -2167,7 +2136,7 @@ TclCreateAuxData(clientData, typePtr, envPtr)
envPtr->mallocedAuxDataArray = 1;
}
envPtr->auxDataArrayNext++;
-
+
auxDataPtr = &(envPtr->auxDataArrayPtr[index]);
auxDataPtr->clientData = clientData;
auxDataPtr->type = typePtr;
@@ -2179,8 +2148,8 @@ TclCreateAuxData(clientData, typePtr, envPtr)
*
* TclInitJumpFixupArray --
*
- * Initializes a JumpFixupArray structure to hold some number of
- * jump fixup entries.
+ * Initializes a JumpFixupArray structure to hold some number of jump
+ * fixup entries.
*
* Results:
* None.
@@ -2194,8 +2163,8 @@ TclCreateAuxData(clientData, typePtr, envPtr)
void
TclInitJumpFixupArray(fixupArrayPtr)
register JumpFixupArray *fixupArrayPtr;
- /* Points to the JumpFixupArray structure
- * to initialize. */
+ /* Points to the JumpFixupArray structure to
+ * initialize. */
{
fixupArrayPtr->fixup = fixupArrayPtr->staticFixupSpace;
fixupArrayPtr->next = 0;
@@ -2208,8 +2177,8 @@ TclInitJumpFixupArray(fixupArrayPtr)
*
* TclExpandJumpFixupArray --
*
- * Procedure that uses malloc to allocate more storage for a
- * jump fixup array.
+ * Procedure that uses malloc to allocate more storage for a jump fixup
+ * array.
*
* Results:
* None.
@@ -2217,8 +2186,8 @@ TclInitJumpFixupArray(fixupArrayPtr)
* Side effects:
* The jump fixup array in *fixupArrayPtr is reallocated to a new array
* of double the size, and if fixupArrayPtr->mallocedArray is non-zero
- * the old array is freed. Jump fixup structures are copied from the
- * old array to the new one.
+ * the old array is freed. Jump fixup structures are copied from the old
+ * array to the new one.
*
*----------------------------------------------------------------------
*/
@@ -2226,12 +2195,12 @@ TclInitJumpFixupArray(fixupArrayPtr)
void
TclExpandJumpFixupArray(fixupArrayPtr)
register JumpFixupArray *fixupArrayPtr;
- /* Points to the JumpFixupArray structure
- * to enlarge. */
+ /* Points to the JumpFixupArray structure
+ * to enlarge. */
{
/*
- * The currently allocated jump fixup entries are stored from fixup[0]
- * up to fixup[fixupArrayPtr->fixupNext] (*not* inclusive). We assume
+ * The currently allocated jump fixup entries are stored from fixup[0] up
+ * to fixup[fixupArrayPtr->fixupNext] (*not* inclusive). We assume
* fixupArrayPtr->fixupNext is equal to fixupArrayPtr->fixupEnd.
*/
@@ -2241,10 +2210,10 @@ TclExpandJumpFixupArray(fixupArrayPtr)
JumpFixup *newPtr = (JumpFixup *) ckalloc((unsigned) newBytes);
/*
- * Copy from the old array to new, free the old array if needed,
- * and mark the new array as malloced.
+ * Copy from the old array to new, free the old array if needed, and mark
+ * the new array as malloced.
*/
-
+
memcpy((VOID *) newPtr, (VOID *) fixupArrayPtr->fixup, currBytes);
if (fixupArrayPtr->mallocedArray) {
ckfree((char *) fixupArrayPtr->fixup);
@@ -2273,8 +2242,8 @@ TclExpandJumpFixupArray(fixupArrayPtr)
void
TclFreeJumpFixupArray(fixupArrayPtr)
register JumpFixupArray *fixupArrayPtr;
- /* Points to the JumpFixupArray structure
- * to free. */
+ /* Points to the JumpFixupArray structure to
+ * free. */
{
if (fixupArrayPtr->mallocedArray) {
ckfree((char *) fixupArrayPtr->fixup);
@@ -2289,16 +2258,16 @@ TclFreeJumpFixupArray(fixupArrayPtr)
* Procedure to emit a two-byte forward jump of kind "jumpType". Since
* the jump may later have to be grown to five bytes if the jump target
* is more than, say, 127 bytes away, this procedure also initializes a
- * JumpFixup record with information about the jump.
+ * JumpFixup record with information about the jump.
*
* Results:
* None.
*
* Side effects:
- * The JumpFixup record pointed to by "jumpFixupPtr" is initialized
- * with information needed later if the jump is to be grown. Also,
- * a two byte jump of the designated type is emitted at the current
- * point in the bytecode stream.
+ * The JumpFixup record pointed to by "jumpFixupPtr" is initialized with
+ * information needed later if the jump is to be grown. Also, a two byte
+ * jump of the designated type is emitted at the current point in the
+ * bytecode stream.
*
*----------------------------------------------------------------------
*/
@@ -2317,15 +2286,15 @@ TclEmitForwardJump(envPtr, jumpType, jumpFixupPtr)
* Initialize the JumpFixup structure:
* - codeOffset is offset of first byte of jump below
* - cmdIndex is index of the command after the current one
- * - exceptIndex is the index of the first ExceptionRange after
- * the current one.
+ * - exceptIndex is the index of the first ExceptionRange after the
+ * current one.
*/
-
+
jumpFixupPtr->jumpType = jumpType;
jumpFixupPtr->codeOffset = (envPtr->codeNext - envPtr->codeStart);
jumpFixupPtr->cmdIndex = envPtr->numCommands;
jumpFixupPtr->exceptIndex = envPtr->exceptArrayNext;
-
+
switch (jumpType) {
case TCL_UNCONDITIONAL_JUMP:
TclEmitInstInt1(INST_JUMP1, 0, envPtr);
@@ -2344,24 +2313,23 @@ TclEmitForwardJump(envPtr, jumpType, jumpFixupPtr)
*
* TclFixupForwardJump --
*
- * Procedure that updates a previously-emitted forward jump to jump
- * a specified number of bytes, "jumpDist". If necessary, the jump is
- * grown from two to five bytes; this is done if the jump distance is
- * greater than "distThreshold" (normally 127 bytes). The jump is
- * described by a JumpFixup record previously initialized by
- * TclEmitForwardJump.
+ * Procedure that updates a previously-emitted forward jump to jump a
+ * specified number of bytes, "jumpDist". If necessary, the jump is grown
+ * from two to five bytes; this is done if the jump distance is greater
+ * than "distThreshold" (normally 127 bytes). The jump is described by a
+ * JumpFixup record previously initialized by TclEmitForwardJump.
*
* Results:
* 1 if the jump was grown and subsequent instructions had to be moved;
- * otherwise 0. This result is returned to allow callers to update
- * any additional code offsets they may hold.
+ * otherwise 0. This result is returned to allow callers to update any
+ * additional code offsets they may hold.
*
* Side effects:
* The jump may be grown and subsequent instructions moved. If this
* happens, the code offsets for any commands and any ExceptionRange
- * records between the jump and the current code address will be
- * updated to reflect the moved code. Also, the bytecode instruction
- * array in the CompileEnv structure may be grown and reallocated.
+ * records between the jump and the current code address will be updated
+ * to reflect the moved code. Also, the bytecode instruction array in the
+ * CompileEnv structure may be grown and reallocated.
*
*----------------------------------------------------------------------
*/
@@ -2372,15 +2340,14 @@ TclFixupForwardJump(envPtr, jumpFixupPtr, jumpDist, distThreshold)
* holds the resulting instruction. */
JumpFixup *jumpFixupPtr; /* Points to the JumpFixup structure that
* describes the forward jump. */
- int jumpDist; /* Jump distance to set in jump
- * instruction. */
- int distThreshold; /* Maximum distance before the two byte
- * jump is grown to five bytes. */
+ int jumpDist; /* Jump distance to set in jump instr. */
+ int distThreshold; /* Maximum distance before the two byte jump
+ * is grown to five bytes. */
{
unsigned char *jumpPc, *p;
int firstCmd, lastCmd, firstRange, lastRange, k;
unsigned int numBytes;
-
+
if (jumpDist <= distThreshold) {
jumpPc = (envPtr->codeStart + jumpFixupPtr->codeOffset);
switch (jumpFixupPtr->jumpType) {
@@ -2398,14 +2365,14 @@ TclFixupForwardJump(envPtr, jumpFixupPtr, jumpDist, distThreshold)
}
/*
- * We must grow the jump then move subsequent instructions down.
- * Note that if we expand the space for generated instructions,
- * code addresses might change; be careful about updating any of
- * these addresses held in variables.
+ * We must grow the jump then move subsequent instructions down. Note
+ * that if we expand the space for generated instructions, code addresses
+ * might change; be careful about updating any of these addresses held in
+ * variables.
*/
-
+
if ((envPtr->codeNext + 3) > envPtr->codeEnd) {
- TclExpandCodeArray(envPtr);
+ TclExpandCodeArray(envPtr);
}
jumpPc = (envPtr->codeStart + jumpFixupPtr->codeOffset);
for (numBytes = envPtr->codeNext-jumpPc-2, p = jumpPc+2+numBytes-1;
@@ -2425,26 +2392,26 @@ TclFixupForwardJump(envPtr, jumpFixupPtr, jumpDist, distThreshold)
TclUpdateInstInt4AtPc(INST_JUMP_FALSE4, jumpDist, jumpPc);
break;
}
-
+
/*
- * Adjust the code offsets for any commands and any ExceptionRange
- * records between the jump and the current code address.
+ * Adjust the code offsets for any commands and any ExceptionRange records
+ * between the jump and the current code address.
*/
-
+
firstCmd = jumpFixupPtr->cmdIndex;
- lastCmd = (envPtr->numCommands - 1);
+ lastCmd = (envPtr->numCommands - 1);
if (firstCmd < lastCmd) {
for (k = firstCmd; k <= lastCmd; k++) {
(envPtr->cmdMapPtr[k]).codeOffset += 3;
}
}
-
+
firstRange = jumpFixupPtr->exceptIndex;
- lastRange = (envPtr->exceptArrayNext - 1);
+ lastRange = (envPtr->exceptArrayNext - 1);
for (k = firstRange; k <= lastRange; k++) {
ExceptionRange *rangePtr = &(envPtr->exceptArrayPtr[k]);
rangePtr->codeOffset += 3;
-
+
switch (rangePtr->type) {
case LOOP_EXCEPTION_RANGE:
rangePtr->breakOffset += 3;
@@ -2457,7 +2424,7 @@ TclFixupForwardJump(envPtr, jumpFixupPtr, jumpDist, distThreshold)
break;
default:
Tcl_Panic("TclFixupForwardJump: bad ExceptionRange type %d\n",
- rangePtr->type);
+ rangePtr->type);
}
}
return 1; /* the jump was grown */
@@ -2468,9 +2435,9 @@ TclFixupForwardJump(envPtr, jumpFixupPtr, jumpDist, distThreshold)
*
* TclGetInstructionTable --
*
- * Returns a pointer to the table describing Tcl bytecode instructions.
- * This procedure is defined so that clients can access the pointer from
- * outside the TCL DLLs.
+ * Returns a pointer to the table describing Tcl bytecode instructions.
+ * This procedure is defined so that clients can access the pointer from
+ * outside the TCL DLLs.
*
* Results:
* Returns a pointer to the global instruction table, same as the
@@ -2493,32 +2460,32 @@ TclGetInstructionTable()
*
* TclRegisterAuxDataType --
*
- * This procedure is called to register a new AuxData type
- * in the table of all AuxData types supported by Tcl.
+ * This procedure is called to register a new AuxData type in the table
+ * of all AuxData types supported by Tcl.
*
* Results:
* None.
*
* Side effects:
* The type is registered in the AuxData type table. If there was already
- * a type with the same name as in typePtr, it is replaced with the
- * new type.
+ * a type with the same name as in typePtr, it is replaced with the new
+ * type.
*
*--------------------------------------------------------------
*/
void
TclRegisterAuxDataType(typePtr)
- AuxDataType *typePtr; /* Information about object type;
- * storage must be statically
- * allocated (must live forever). */
+ AuxDataType *typePtr; /* Information about object type; storage must
+ * be statically allocated (must live
+ * forever). */
{
register Tcl_HashEntry *hPtr;
int new;
Tcl_MutexLock(&tableMutex);
if (!auxDataTypeTableInitialized) {
- TclInitAuxDataTypeTable();
+ TclInitAuxDataTypeTable();
}
/*
@@ -2527,7 +2494,7 @@ TclRegisterAuxDataType(typePtr)
hPtr = Tcl_FindHashEntry(&auxDataTypeTable, typePtr->name);
if (hPtr != (Tcl_HashEntry *) NULL) {
- Tcl_DeleteHashEntry(hPtr);
+ Tcl_DeleteHashEntry(hPtr);
}
/*
@@ -2536,7 +2503,7 @@ TclRegisterAuxDataType(typePtr)
hPtr = Tcl_CreateHashEntry(&auxDataTypeTable, typePtr->name, &new);
if (new) {
- Tcl_SetHashValue(hPtr, typePtr);
+ Tcl_SetHashValue(hPtr, typePtr);
}
Tcl_MutexUnlock(&tableMutex);
}
@@ -2567,12 +2534,12 @@ TclGetAuxDataType(typeName)
Tcl_MutexLock(&tableMutex);
if (!auxDataTypeTableInitialized) {
- TclInitAuxDataTypeTable();
+ TclInitAuxDataTypeTable();
}
hPtr = Tcl_FindHashEntry(&auxDataTypeTable, typeName);
if (hPtr != (Tcl_HashEntry *) NULL) {
- typePtr = (AuxDataType *) Tcl_GetHashValue(hPtr);
+ typePtr = (AuxDataType *) Tcl_GetHashValue(hPtr);
}
Tcl_MutexUnlock(&tableMutex);
@@ -2584,8 +2551,8 @@ TclGetAuxDataType(typeName)
*
* TclInitAuxDataTypeTable --
*
- * This procedure is invoked to perform once-only initialization of
- * the AuxData type table. It also registers the AuxData types defined in
+ * This procedure is invoked to perform once-only initialization of the
+ * AuxData type table. It also registers the AuxData types defined in
* this file.
*
* Results:
@@ -2620,10 +2587,10 @@ TclInitAuxDataTypeTable()
*
* TclFinalizeAuxDataTypeTable --
*
- * This procedure is called by Tcl_Finalize after all exit handlers
- * have been run to free up storage associated with the table of AuxData
- * types. This procedure is called by TclFinalizeExecution() which
- * is called by Tcl_Finalize().
+ * This procedure is called by Tcl_Finalize after all exit handlers have
+ * been run to free up storage associated with the table of AuxData
+ * types. This procedure is called by TclFinalizeExecution() which is
+ * called by Tcl_Finalize().
*
* Results:
* None.
@@ -2639,8 +2606,8 @@ TclFinalizeAuxDataTypeTable()
{
Tcl_MutexLock(&tableMutex);
if (auxDataTypeTableInitialized) {
- Tcl_DeleteHashTable(&auxDataTypeTable);
- auxDataTypeTableInitialized = 0;
+ Tcl_DeleteHashTable(&auxDataTypeTable);
+ auxDataTypeTableInitialized = 0;
}
Tcl_MutexUnlock(&tableMutex);
}
@@ -2664,17 +2631,17 @@ TclFinalizeAuxDataTypeTable()
static int
GetCmdLocEncodingSize(envPtr)
- CompileEnv *envPtr; /* Points to compilation environment
- * structure containing the CmdLocation
- * structure to encode. */
+ CompileEnv *envPtr; /* Points to compilation environment structure
+ * containing the CmdLocation structure to
+ * encode. */
{
register CmdLocation *mapPtr = envPtr->cmdMapPtr;
int numCmds = envPtr->numCommands;
int codeDelta, codeLen, srcDelta, srcLen;
int codeDeltaNext, codeLengthNext, srcDeltaNext, srcLengthNext;
/* The offsets in their respective byte
- * sequences where the next encoded offset
- * or length should go. */
+ * sequences where the next encoded offset or
+ * length should go. */
int prevCodeOffset, prevSrcOffset, i;
codeDeltaNext = codeLengthNext = srcDeltaNext = srcLengthNext = 0;
@@ -2725,8 +2692,8 @@ GetCmdLocEncodingSize(envPtr)
*
* EncodeCmdLocMap --
*
- * Encode the command location information for some compiled code into
- * a ByteCode structure. The encoded command location map is stored as
+ * Encode the command location information for some compiled code into a
+ * ByteCode structure. The encoded command location map is stored as
* three adjacent byte sequences.
*
* Results:
@@ -2734,30 +2701,30 @@ GetCmdLocEncodingSize(envPtr)
* information.
*
* Side effects:
- * The encoded information is stored into the block of memory headed
- * by codePtr. Also records pointers to the start of the four byte
- * sequences in fields in codePtr's ByteCode header structure.
+ * The encoded information is stored into the block of memory headed by
+ * codePtr. Also records pointers to the start of the four byte sequences
+ * in fields in codePtr's ByteCode header structure.
*
*----------------------------------------------------------------------
*/
static unsigned char *
EncodeCmdLocMap(envPtr, codePtr, startPtr)
- CompileEnv *envPtr; /* Points to compilation environment
- * structure containing the CmdLocation
- * structure to encode. */
- ByteCode *codePtr; /* ByteCode in which to encode envPtr's
+ CompileEnv *envPtr; /* Points to compilation environment structure
+ * containing the CmdLocation structure to
+ * encode. */
+ ByteCode *codePtr; /* ByteCode in which to encode envPtr's
* command location information. */
- unsigned char *startPtr; /* Points to the first byte in codePtr's
- * memory block where the location
- * information is to be stored. */
+ unsigned char *startPtr; /* Points to the first byte in codePtr's
+ * memory block where the location information
+ * is to be stored. */
{
register CmdLocation *mapPtr = envPtr->cmdMapPtr;
int numCmds = envPtr->numCommands;
register unsigned char *p = startPtr;
int codeDelta, codeLen, srcDelta, srcLen, prevOffset;
register int i;
-
+
/*
* Encode the code offset for each command as a sequence of deltas.
*/
@@ -2839,7 +2806,7 @@ EncodeCmdLocMap(envPtr, codePtr, startPtr)
p += 4;
}
}
-
+
return p;
}
@@ -2849,8 +2816,8 @@ EncodeCmdLocMap(envPtr, codePtr, startPtr)
*
* TclPrintByteCodeObj --
*
- * This procedure prints ("disassembles") the instructions of a
- * bytecode object to stdout.
+ * This procedure prints ("disassembles") the instructions of a bytecode
+ * object to stdout.
*
* Results:
* None.
@@ -2897,11 +2864,11 @@ TclPrintByteCodeObj(interp, objPtr)
codePtr->numLitObjects, codePtr->numAuxDataItems,
codePtr->maxStackDepth,
#ifdef TCL_COMPILE_STATS
- (codePtr->numSrcBytes?
- ((float)codePtr->structureSize)/((float)codePtr->numSrcBytes) : 0.0));
-#else
- 0.0);
+ codePtr->numSrcBytes?
+ codePtr->structureSize/(float)codePtr->numSrcBytes :
#endif
+ 0.0);
+
#ifdef TCL_COMPILE_STATS
fprintf(stdout,
" Code %d = header %d+inst %d+litObj %d+exc %d+aux %d+cmdMap %d\n",
@@ -2913,34 +2880,34 @@ TclPrintByteCodeObj(interp, objPtr)
(codePtr->numAuxDataItems * sizeof(AuxData)),
codePtr->numCmdLocBytes);
#endif /* TCL_COMPILE_STATS */
-
+
/*
* If the ByteCode is the compiled body of a Tcl procedure, print
* information about that procedure. Note that we don't know the
* procedure's name since ByteCode's can be shared among procedures.
*/
-
+
if (codePtr->procPtr != NULL) {
Proc *procPtr = codePtr->procPtr;
int numCompiledLocals = procPtr->numCompiledLocals;
fprintf(stdout,
- " Proc 0x%x, refCt %d, args %d, compiled locals %d\n",
+ " Proc 0x%x, refCt %d, args %d, compiled locals %d\n",
(unsigned int) procPtr, procPtr->refCount, procPtr->numArgs,
numCompiledLocals);
if (numCompiledLocals > 0) {
CompiledLocal *localPtr = procPtr->firstLocalPtr;
for (i = 0; i < numCompiledLocals; i++) {
- fprintf(stdout, " slot %d%s%s%s%s%s%s", i,
- ((localPtr->flags & VAR_SCALAR)? ", scalar" : ""),
- ((localPtr->flags & VAR_ARRAY)? ", array" : ""),
- ((localPtr->flags & VAR_LINK)? ", link" : ""),
- ((localPtr->flags & VAR_ARGUMENT)? ", arg" : ""),
- ((localPtr->flags & VAR_TEMPORARY)? ", temp" : ""),
- ((localPtr->flags & VAR_RESOLVED)? ", resolved" : ""));
+ fprintf(stdout, " slot %d%s%s%s%s%s%s", i,
+ (localPtr->flags & VAR_SCALAR) ? ", scalar" : "",
+ (localPtr->flags & VAR_ARRAY) ? ", array" : "",
+ (localPtr->flags & VAR_LINK) ? ", link" : "",
+ (localPtr->flags & VAR_ARGUMENT) ? ", arg" : "",
+ (localPtr->flags & VAR_TEMPORARY) ? ", temp" : "",
+ (localPtr->flags & VAR_RESOLVED) ? ", resolved" : "");
if (TclIsVarTemporary(localPtr)) {
- fprintf(stdout, "\n");
+ fprintf(stdout, "\n");
} else {
- fprintf(stdout, ", \"%s\"\n", localPtr->name);
+ fprintf(stdout, ", \"%s\"\n", localPtr->name);
}
localPtr = localPtr->nextPtr;
}
@@ -2953,33 +2920,32 @@ TclPrintByteCodeObj(interp, objPtr)
if (codePtr->numExceptRanges > 0) {
fprintf(stdout, " Exception ranges %d, depth %d:\n",
- codePtr->numExceptRanges, codePtr->maxExceptDepth);
+ codePtr->numExceptRanges, codePtr->maxExceptDepth);
for (i = 0; i < codePtr->numExceptRanges; i++) {
ExceptionRange *rangePtr = &(codePtr->exceptArrayPtr[i]);
fprintf(stdout, " %d: level %d, %s, pc %d-%d, ",
i, rangePtr->nestingLevel,
- ((rangePtr->type == LOOP_EXCEPTION_RANGE)
- ? "loop" : "catch"),
+ (rangePtr->type==LOOP_EXCEPTION_RANGE ? "loop" : "catch"),
rangePtr->codeOffset,
(rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
switch (rangePtr->type) {
case LOOP_EXCEPTION_RANGE:
fprintf(stdout, "continue %d, break %d\n",
- rangePtr->continueOffset, rangePtr->breakOffset);
+ rangePtr->continueOffset, rangePtr->breakOffset);
break;
case CATCH_EXCEPTION_RANGE:
fprintf(stdout, "catch %d\n", rangePtr->catchOffset);
break;
default:
Tcl_Panic("TclPrintByteCodeObj: bad ExceptionRange type %d\n",
- rangePtr->type);
+ rangePtr->type);
}
}
}
-
+
/*
- * If there were no commands (e.g., an expression or an empty string
- * was compiled), just print all instructions and return.
+ * If there were no commands (e.g., an expression or an empty string was
+ * compiled), just print all instructions and return.
*/
if (numCmds == 0) {
@@ -2990,16 +2956,16 @@ TclPrintByteCodeObj(interp, objPtr)
}
return;
}
-
+
/*
- * Print table showing the code offset, source offset, and source
- * length for each command. These are encoded as a sequence of bytes.
+ * Print table showing the code offset, source offset, and source length
+ * for each command. These are encoded as a sequence of bytes.
*/
fprintf(stdout, " Commands %d:", numCmds);
codeDeltaNext = codePtr->codeDeltaStart;
codeLengthNext = codePtr->codeLengthStart;
- srcDeltaNext = codePtr->srcDeltaStart;
+ srcDeltaNext = codePtr->srcDeltaStart;
srcLengthNext = codePtr->srcLengthStart;
codeOffset = srcOffset = 0;
for (i = 0; i < numCmds; i++) {
@@ -3021,7 +2987,7 @@ TclPrintByteCodeObj(interp, objPtr)
codeLen = TclGetInt1AtPtr(codeLengthNext);
codeLengthNext++;
}
-
+
if ((unsigned int) (*srcDeltaNext) == (unsigned int) 0xFF) {
srcDeltaNext++;
delta = TclGetInt4AtPtr(srcDeltaNext);
@@ -3040,7 +3006,7 @@ TclPrintByteCodeObj(interp, objPtr)
srcLen = TclGetInt1AtPtr(srcLengthNext);
srcLengthNext++;
}
-
+
fprintf(stdout, "%s%4d: pc %d-%d, src %d-%d",
((i % 2)? " " : "\n "),
(i+1), codeOffset, (codeOffset + codeLen - 1),
@@ -3049,15 +3015,15 @@ TclPrintByteCodeObj(interp, objPtr)
if (numCmds > 0) {
fprintf(stdout, "\n");
}
-
+
/*
- * Print each instruction. If the instruction corresponds to the start
- * of a command, print the command's source. Note that we don't need
- * the code length here.
+ * Print each instruction. If the instruction corresponds to the start of
+ * a command, print the command's source. Note that we don't need the code
+ * length here.
*/
codeDeltaNext = codePtr->codeDeltaStart;
- srcDeltaNext = codePtr->srcDeltaStart;
+ srcDeltaNext = codePtr->srcDeltaStart;
srcLengthNext = codePtr->srcLengthStart;
codeOffset = srcOffset = 0;
pc = codeStart;
@@ -3094,7 +3060,7 @@ TclPrintByteCodeObj(interp, objPtr)
/*
* Print instructions before command i.
*/
-
+
while ((pc-codeStart) < codeOffset) {
fprintf(stdout, " ");
pc += TclPrintInstruction(codePtr, pc);
@@ -3102,7 +3068,7 @@ TclPrintByteCodeObj(interp, objPtr)
fprintf(stdout, " Command %d: ", (i+1));
TclPrintSource(stdout, (codePtr->source + srcOffset),
- TclMin(srcLen, 55));
+ TclMin(srcLen, 55));
fprintf(stdout, "\n");
}
if (pc < codeLimit) {
@@ -3116,16 +3082,14 @@ TclPrintByteCodeObj(interp, objPtr)
}
}
}
-#endif /* TCL_COMPILE_DEBUG */
-#ifdef TCL_COMPILE_DEBUG
/*
*----------------------------------------------------------------------
*
* TclPrintInstruction --
*
- * This procedure prints ("disassembles") one instruction from a
- * bytecode object to stdout.
+ * This procedure prints ("disassembles") one instruction from a bytecode
+ * object to stdout.
*
* Results:
* Returns the length in bytes of the current instruiction.
@@ -3147,89 +3111,50 @@ TclPrintInstruction(codePtr, pc)
unsigned char *codeStart = codePtr->codeStart;
unsigned int pcOffset = (pc - codeStart);
int opnd, i, j, numBytes = 1;
-
+ int localCt = procPtr ? procPtr->numCompiledLocals : 0;
+ CompiledLocal *localPtr = procPtr ? procPtr->firstLocalPtr : NULL;
+
+ char suffixBuffer[64]; /* Additional info to print after main opcode
+ * and immediates. */
+ char *suffixSrc = NULL;
+ Tcl_Obj *suffixObj = NULL;
+
+ suffixBuffer[0] = '\0';
fprintf(stdout, "(%u) %s ", pcOffset, instDesc->name);
for (i = 0; i < instDesc->numOperands; i++) {
switch (instDesc->opTypes[i]) {
case OPERAND_INT1:
opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++;
- if ((i == 0) && ((opCode == INST_JUMP1)
- || (opCode == INST_JUMP_TRUE1)
- || (opCode == INST_JUMP_FALSE1))) {
- fprintf(stdout, "%d # pc %u", opnd, (pcOffset + opnd));
- } else {
- fprintf(stdout, "%d ", opnd);
+ if (opCode == INST_JUMP1 || opCode == INST_JUMP_TRUE1
+ || opCode == INST_JUMP_FALSE1) {
+ sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
}
+ fprintf(stdout, "%+d ", opnd);
break;
case OPERAND_INT4:
opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
- if ((i == 0) && ((opCode == INST_JUMP4)
- || (opCode == INST_JUMP_TRUE4)
- || (opCode == INST_JUMP_FALSE4))) {
- fprintf(stdout, "%d # pc %u", opnd, (pcOffset + opnd));
- } else {
- fprintf(stdout, "%d ", opnd);
+ if (opCode == INST_JUMP4 || opCode == INST_JUMP_TRUE4
+ || opCode == INST_JUMP_FALSE4) {
+ sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
}
+ fprintf(stdout, "%+d ", opnd);
break;
case OPERAND_UINT1:
opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
- if ((i == 0) && (opCode == INST_PUSH1)) {
- fprintf(stdout, "%u # ", (unsigned int) opnd);
- TclPrintObject(stdout, codePtr->objArrayPtr[opnd], 40);
- } else if ((i == 0) && ((opCode == INST_LOAD_SCALAR1)
- || (opCode == INST_LOAD_ARRAY1)
- || (opCode == INST_STORE_SCALAR1)
- || (opCode == INST_STORE_ARRAY1))) {
- int localCt = procPtr->numCompiledLocals;
- CompiledLocal *localPtr = procPtr->firstLocalPtr;
- if (opnd >= localCt) {
- Tcl_Panic("TclPrintInstruction: bad local var index %u (%u locals)\n",
- (unsigned int) opnd, localCt);
- }
- for (j = 0; j < opnd; j++) {
- localPtr = localPtr->nextPtr;
- }
- if (TclIsVarTemporary(localPtr)) {
- fprintf(stdout, "%u # temp var %u",
- (unsigned int) opnd, (unsigned int) opnd);
- } else {
- fprintf(stdout, "%u # var ", (unsigned int) opnd);
- TclPrintSource(stdout, localPtr->name, 40);
- }
- } else {
- fprintf(stdout, "%u ", (unsigned int) opnd);
+ if (opCode == INST_PUSH1) {
+ suffixObj = codePtr->objArrayPtr[opnd];
}
+ fprintf(stdout, "%u ", (unsigned int) opnd);
break;
case OPERAND_UINT4:
opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
if (opCode == INST_PUSH4) {
- fprintf(stdout, "%u # ", opnd);
- TclPrintObject(stdout, codePtr->objArrayPtr[opnd], 40);
- } else if ((i == 0) && ((opCode == INST_LOAD_SCALAR4)
- || (opCode == INST_LOAD_ARRAY4)
- || (opCode == INST_STORE_SCALAR4)
- || (opCode == INST_STORE_ARRAY4))) {
- int localCt = procPtr->numCompiledLocals;
- CompiledLocal *localPtr = procPtr->firstLocalPtr;
- if (opnd >= localCt) {
- Tcl_Panic("TclPrintInstruction: bad local var index %u (%u locals)\n",
- (unsigned int) opnd, localCt);
- }
- for (j = 0; j < opnd; j++) {
- localPtr = localPtr->nextPtr;
- }
- if (TclIsVarTemporary(localPtr)) {
- fprintf(stdout, "%u # temp var %u",
- (unsigned int) opnd, (unsigned int) opnd);
- } else {
- fprintf(stdout, "%u # var ", (unsigned int) opnd);
- TclPrintSource(stdout, localPtr->name, 40);
- }
- } else {
- fprintf(stdout, "%u ", (unsigned int) opnd);
+ suffixObj = codePtr->objArrayPtr[opnd];
+ } else if (opCode == INST_START_CMD) {
+ sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd);
}
+ fprintf(stdout, "%u ", (unsigned int) opnd);
break;
-
case OPERAND_IDX4:
opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
if (opnd >= -1) {
@@ -3238,20 +3163,51 @@ TclPrintInstruction(codePtr, pc)
fprintf(stdout, "end ");
} else {
fprintf(stdout, "end-%d ", -2-opnd);
- }
+ }
+ break;
+ case OPERAND_LVT1:
+ opnd = TclGetUInt1AtPtr(pc+numBytes);
+ numBytes++;
+ goto printLVTindex;
+ case OPERAND_LVT4:
+ opnd = TclGetUInt4AtPtr(pc+numBytes);
+ numBytes += 4;
+ printLVTindex:
+ if (localPtr != NULL) {
+ if (opnd >= localCt) {
+ Tcl_Panic("TclPrintInstruction: bad local var index %u (%u locals)\n",
+ (unsigned int) opnd, localCt);
+ }
+ for (j = 0; j < opnd; j++) {
+ localPtr = localPtr->nextPtr;
+ }
+ if (TclIsVarTemporary(localPtr)) {
+ sprintf(suffixBuffer, "temp var %u", (unsigned) opnd);
+ } else {
+ sprintf(suffixBuffer, "var ");
+ suffixSrc = localPtr->name;
+ }
+ }
+ fprintf(stdout, "%%v%u ", (unsigned) opnd);
break;
-
case OPERAND_NONE:
default:
break;
}
}
+ if (suffixObj) {
+ fprintf(stdout, "\t# ");
+ TclPrintObject(stdout, codePtr->objArrayPtr[opnd], 40);
+ } else if (suffixBuffer[0]) {
+ fprintf(stdout, "\t# %s", suffixBuffer);
+ if (suffixSrc) {
+ TclPrintSource(stdout, suffixSrc, 40);
+ }
+ }
fprintf(stdout, "\n");
return numBytes;
}
-#endif /* TCL_COMPILE_DEBUG */
-#ifdef TCL_COMPILE_DEBUG
/*
*----------------------------------------------------------------------
*
@@ -3278,20 +3234,18 @@ TclPrintObject(outFile, objPtr, maxChars)
{
char *bytes;
int length;
-
+
bytes = Tcl_GetStringFromObj(objPtr, &length);
TclPrintSource(outFile, bytes, TclMin(length, maxChars));
}
-#endif /* TCL_COMPILE_DEBUG */
-#ifdef TCL_COMPILE_DEBUG
/*
*----------------------------------------------------------------------
*
* TclPrintSource --
*
- * This procedure prints up to a specified number of characters from
- * the argument string to a specified file. It tries to produce legible
+ * This procedure prints up to a specified number of characters from the
+ * argument string to a specified file. It tries to produce legible
* output by adding backslashes as necessary.
*
* Results:
@@ -3321,27 +3275,27 @@ TclPrintSource(outFile, stringPtr, maxChars)
p = stringPtr;
for (; (*p != '\0') && (i < maxChars); p++, i++) {
switch (*p) {
- case '"':
- fprintf(outFile, "\\\"");
- continue;
- case '\f':
- fprintf(outFile, "\\f");
- continue;
- case '\n':
- fprintf(outFile, "\\n");
- continue;
- case '\r':
- fprintf(outFile, "\\r");
- continue;
- case '\t':
- fprintf(outFile, "\\t");
- continue;
- case '\v':
- fprintf(outFile, "\\v");
- continue;
- default:
- fprintf(outFile, "%c", *p);
- continue;
+ case '"':
+ fprintf(outFile, "\\\"");
+ continue;
+ case '\f':
+ fprintf(outFile, "\\f");
+ continue;
+ case '\n':
+ fprintf(outFile, "\\n");
+ continue;
+ case '\r':
+ fprintf(outFile, "\\r");
+ continue;
+ case '\t':
+ fprintf(outFile, "\\t");
+ continue;
+ case '\v':
+ fprintf(outFile, "\\v");
+ continue;
+ default:
+ fprintf(outFile, "%c", *p);
+ continue;
}
}
fprintf(outFile, "\"");
@@ -3363,8 +3317,8 @@ TclPrintSource(outFile, stringPtr, maxChars)
*
* Side effects:
* Accumulates aggregate code-related statistics in the interpreter's
- * ByteCodeStats structure. Records statistics specific to a ByteCode
- * in its ByteCode structure.
+ * ByteCodeStats structure. Records statistics specific to a ByteCode in
+ * its ByteCode structure.
*
*----------------------------------------------------------------------
*/
@@ -3378,21 +3332,29 @@ RecordByteCodeStats(codePtr)
register ByteCodeStats *statsPtr = &(iPtr->stats);
statsPtr->numCompilations++;
- statsPtr->totalSrcBytes += (double) codePtr->numSrcBytes;
- statsPtr->totalByteCodeBytes += (double) codePtr->structureSize;
- statsPtr->currentSrcBytes += (double) codePtr->numSrcBytes;
+ statsPtr->totalSrcBytes += (double) codePtr->numSrcBytes;
+ statsPtr->totalByteCodeBytes += (double) codePtr->structureSize;
+ statsPtr->currentSrcBytes += (double) codePtr->numSrcBytes;
statsPtr->currentByteCodeBytes += (double) codePtr->structureSize;
-
+
statsPtr->srcCount[TclLog2(codePtr->numSrcBytes)]++;
statsPtr->byteCodeCount[TclLog2((int)(codePtr->structureSize))]++;
- statsPtr->currentInstBytes += (double) codePtr->numCodeBytes;
- statsPtr->currentLitBytes +=
- (double) (codePtr->numLitObjects * sizeof(Tcl_Obj *));
- statsPtr->currentExceptBytes +=
- (double) (codePtr->numExceptRanges * sizeof(ExceptionRange));
- statsPtr->currentAuxBytes +=
- (double) (codePtr->numAuxDataItems * sizeof(AuxData));
+ statsPtr->currentInstBytes += (double) codePtr->numCodeBytes;
+ statsPtr->currentLitBytes += (double)
+ codePtr->numLitObjects * sizeof(Tcl_Obj *);
+ statsPtr->currentExceptBytes += (double)
+ codePtr->numExceptRanges * sizeof(ExceptionRange);
+ statsPtr->currentAuxBytes += (double)
+ codePtr->numAuxDataItems * sizeof(AuxData);
statsPtr->currentCmdMapBytes += (double) codePtr->numCmdLocBytes;
}
#endif /* TCL_COMPILE_STATS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */