summaryrefslogtreecommitdiffstats
path: root/generic/tclCompile.h
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclCompile.h')
-rw-r--r--generic/tclCompile.h554
1 files changed, 267 insertions, 287 deletions
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index 44eac12..4a718fd 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -1,12 +1,12 @@
/*
* tclCompile.h --
*
- * Copyright (c) 1996-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1996-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCompile.h,v 1.9 1999/03/10 05:52:47 stanton Exp $
+ * RCS: @(#) $Id: tclCompile.h,v 1.10 1999/04/16 00:46:45 stanton Exp $
*/
#ifndef _TCLCOMPILATION
@@ -60,32 +60,6 @@ extern int tclTraceCompile;
extern int tclTraceExec;
/*
- * The number of bytecode compilations and various other compilation-related
- * statistics. The tclByteCodeCount and tclSourceCount arrays are used to
- * hold the count of ByteCodes and sources whose sizes fall into various
- * binary decades; e.g., tclByteCodeCount[5] is a count of the ByteCodes
- * with size larger than 2**4 and less than or equal to 2**5.
- */
-
-#ifdef TCL_COMPILE_STATS
-extern long tclNumCompilations;
-extern double tclTotalSourceBytes;
-extern double tclTotalCodeBytes;
-
-extern double tclTotalInstBytes;
-extern double tclTotalObjBytes;
-extern double tclTotalExceptBytes;
-extern double tclTotalAuxBytes;
-extern double tclTotalCmdMapBytes;
-
-extern double tclCurrentSourceBytes;
-extern double tclCurrentCodeBytes;
-
-extern int tclSourceCount[32];
-extern int tclByteCodeCount[32];
-#endif /* TCL_COMPILE_STATS */
-
-/*
*------------------------------------------------------------------------
* Data structures related to compilation.
*------------------------------------------------------------------------
@@ -108,12 +82,12 @@ extern int tclByteCodeCount[32];
*/
typedef enum {
- LOOP_EXCEPTION_RANGE, /* Code range is part of a loop command.
- * break and continue "exceptions" cause
+ LOOP_EXCEPTION_RANGE, /* Exception's range is part of a loop.
+ * Break and continue "exceptions" cause
* jumps to appropriate PC offsets. */
- CATCH_EXCEPTION_RANGE /* Code range is controlled by a catch
- * command. Errors in the range cause a
- * jump to a particular PC offset. */
+ CATCH_EXCEPTION_RANGE /* Exception's range is controlled by a
+ * catch command. Errors in the range cause
+ * a jump to a catch PC offset. */
} ExceptionRangeType;
typedef struct ExceptionRange {
@@ -124,16 +98,14 @@ typedef struct ExceptionRange {
int codeOffset; /* Offset of the first instruction byte of
* the code range. */
int numCodeBytes; /* Number of bytes in the code range. */
- int breakOffset; /* If a LOOP_EXCEPTION_RANGE, the target
- * PC offset for a break command in the
- * range. */
- int continueOffset; /* If a LOOP_EXCEPTION_RANGE and not -1,
- * the target PC offset for a continue
- * command in the code range. Otherwise,
- * ignore this range when processing a
- * continue command. */
+ int breakOffset; /* If LOOP_EXCEPTION_RANGE, the target PC
+ * offset for a break command in the range. */
+ int continueOffset; /* If LOOP_EXCEPTION_RANGE and not -1, the
+ * target PC offset for a continue command in
+ * the code range. Otherwise, ignore this range
+ * when processing a continue command. */
int catchOffset; /* If a CATCH_EXCEPTION_RANGE, the target PC
- * offset for an "exception" in range. */
+ * offset for any "exception" in range. */
} ExceptionRange;
/*
@@ -148,17 +120,69 @@ typedef struct CmdLocation {
int codeOffset; /* Offset of first byte of command code. */
int numCodeBytes; /* Number of bytes for command's code. */
int srcOffset; /* Offset of first char of the command. */
- int numSrcChars; /* Number of command source chars. */
+ int numSrcBytes; /* Number of command source chars. */
} CmdLocation;
/*
+ * CompileProcs need the ability to record information during compilation
+ * that can be used by bytecode instructions during execution. The AuxData
+ * structure provides this "auxiliary data" mechanism. An arbitrary number
+ * of these structures can be stored in the ByteCode record (during
+ * compilation they are stored in a CompileEnv structure). Each AuxData
+ * record holds one word of client-specified data (often a pointer) and is
+ * given an index that instructions can later use to look up the structure
+ * and its data.
+ *
+ * The following definitions declare the types of procedures that are called
+ * to duplicate or free this auxiliary data when the containing ByteCode
+ * objects are duplicated and freed. Pointers to these procedures are kept
+ * in the AuxData structure.
+ */
+
+typedef ClientData (AuxDataDupProc) _ANSI_ARGS_((ClientData clientData));
+typedef void (AuxDataFreeProc) _ANSI_ARGS_((ClientData clientData));
+
+/*
+ * We define a separate AuxDataType struct to hold type-related information
+ * for the AuxData structure. This separation makes it possible for clients
+ * outside of the TCL core to manipulate (in a limited fashion!) AuxData;
+ * for example, it makes it possible to pickle and unpickle AuxData structs.
+ */
+
+typedef struct AuxDataType {
+ char *name; /* the name of the type. Types can be
+ * registered and found by name */
+ AuxDataDupProc *dupProc; /* Callback procedure to invoke when the
+ * aux data is duplicated (e.g., when the
+ * ByteCode structure containing the aux
+ * data is duplicated). NULL means just
+ * copy the source clientData bits; no
+ * proc need be called. */
+ AuxDataFreeProc *freeProc; /* Callback procedure to invoke when the
+ * aux data is freed. NULL means no
+ * proc need be called. */
+} AuxDataType;
+
+/*
+ * The definition of the AuxData structure that holds information created
+ * during compilation by CompileProcs and used by instructions during
+ * execution.
+ */
+
+typedef struct AuxData {
+ AuxDataType *type; /* pointer to the AuxData type associated with
+ * this ClientData. */
+ ClientData clientData; /* The compilation data itself. */
+} AuxData;
+
+/*
* Structure defining the compilation environment. After compilation, fields
* describing bytecode instructions are copied out into the more compact
* ByteCode structure defined below.
*/
#define COMPILEENV_INIT_CODE_BYTES 250
-#define COMPILEENV_INIT_NUM_OBJECTS 40
+#define COMPILEENV_INIT_NUM_OBJECTS 60
#define COMPILEENV_INIT_EXCEPT_RANGES 5
#define COMPILEENV_INIT_CMD_MAP_SIZE 40
#define COMPILEENV_INIT_AUX_DATA_SIZE 5
@@ -173,36 +197,25 @@ typedef struct CompileEnv {
* SetByteCodeFromAny. This pointer is not
* owned by the CompileEnv and must not be
* freed or changed by it. */
+ int numSrcBytes; /* Number of bytes in source. */
Proc *procPtr; /* If a procedure is being compiled, a
* pointer to its Proc structure; otherwise
* NULL. Used to compile local variables.
* Set from information provided by
* ObjInterpProc in tclProc.c. */
int numCommands; /* Number of commands compiled. */
- int excRangeDepth; /* Current exception range nesting level;
+ int exceptDepth; /* Current exception range nesting level;
* -1 if not in any range currently. */
- int maxExcRangeDepth; /* Max nesting level of exception ranges;
+ int maxExceptDepth; /* Max nesting level of exception ranges;
* -1 if no ranges have been compiled. */
int maxStackDepth; /* Maximum number of stack elements needed
* to execute the code. Set by compilation
* procedures before returning. */
- Tcl_HashTable objTable; /* Contains all Tcl objects referenced by
- * the compiled code. Indexed by the string
- * representations of the objects. Used to
+ LiteralTable localLitTable; /* Contains LiteralEntry's describing
+ * all Tcl objects referenced by this
+ * compiled code. Indexed by the string
+ * representations of the literals. Used to
* avoid creating duplicate objects. */
- int pushSimpleWords; /* Set 1 by callers of compilation routines
- * if they should emit instructions to push
- * "simple" command words (those that are
- * just a sequence of characters). If 0, the
- * callers are responsible for compiling
- * simple words. */
- int wordIsSimple; /* Set 1 by compilation procedures before
- * returning if the previous command word
- * was just a sequence of characters,
- * otherwise 0. Used to help determine the
- * command being compiled. */
- int numSimpleWordChars; /* If wordIsSimple is 1 then the number of
- * characters in the simple word, else 0. */
int exprIsJustVarRef; /* Set 1 if the expression last compiled by
* TclCompileExpr consisted of just a
* variable reference as in the expression
@@ -215,31 +228,29 @@ typedef struct CompileEnv {
* might be strings, the expr is compiled
* out-of-line to implement expr's 2 level
* substitution semantics properly. */
- int termOffset; /* Offset of character just after the last
- * one compiled. Set by compilation
- * procedures before returning. */
unsigned char *codeStart; /* Points to the first byte of the code. */
unsigned char *codeNext; /* Points to next code array byte to use. */
unsigned char *codeEnd; /* Points just after the last allocated
* code array byte. */
int mallocedCodeArray; /* Set 1 if code array was expanded
* and codeStart points into the heap.*/
- Tcl_Obj **objArrayPtr; /* Points to start of object array. */
- int objArrayNext; /* Index of next free object array entry. */
- int objArrayEnd; /* Index just after last obj array entry. */
- int mallocedObjArray; /* 1 if object array was expanded and
+ LiteralEntry *literalArrayPtr;
+ /* Points to start of LiteralEntry array. */
+ int literalArrayNext; /* Index of next free object array entry. */
+ int literalArrayEnd; /* Index just after last obj array entry. */
+ int mallocedLiteralArray; /* 1 if object array was expanded and
* objArray points into the heap, else 0. */
- ExceptionRange *excRangeArrayPtr;
+ ExceptionRange *exceptArrayPtr;
/* Points to start of the ExceptionRange
* array. */
- int excRangeArrayNext; /* Next free ExceptionRange array index.
- * excRangeArrayNext is the number of ranges
- * and (excRangeArrayNext-1) is the index of
+ int exceptArrayNext; /* Next free ExceptionRange array index.
+ * exceptArrayNext is the number of ranges
+ * and (exceptArrayNext-1) is the index of
* the current range's array entry. */
- int excRangeArrayEnd; /* Index after the last ExceptionRange
+ int exceptArrayEnd; /* Index after the last ExceptionRange
* array entry. */
- int mallocedExcRangeArray; /* 1 if ExceptionRange array was expanded
- * and excRangeArrayPtr points in heap,
+ int mallocedExceptArray; /* 1 if ExceptionRange array was expanded
+ * and exceptArrayPtr points in heap,
* else 0. */
CmdLocation *cmdMapPtr; /* Points to start of CmdLocation array.
* numCommands is the index of the next
@@ -258,9 +269,9 @@ typedef struct CompileEnv {
* auxDataArrayPtr points in heap else 0. */
unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES];
/* Initial storage for code. */
- Tcl_Obj *staticObjArraySpace[COMPILEENV_INIT_NUM_OBJECTS];
- /* Initial storage for object array. */
- ExceptionRange staticExcRangeArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
+ LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS];
+ /* Initial storage of LiteralEntry array. */
+ ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
/* Initial ExceptionRange array storage. */
CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
/* Initial storage for cmd location map. */
@@ -272,8 +283,8 @@ typedef struct CompileEnv {
* The structure defining the bytecode instructions resulting from compiling
* a Tcl script. Note that this structure is variable length: a single heap
* object is allocated to hold the ByteCode structure immediately followed
- * by the code bytes, the object array, the ExceptionRange array, the
- * CmdLocation map, and the compilation AuxData array.
+ * by the code bytes, the literal object array, the ExceptionRange array,
+ * the CmdLocation map, and the compilation AuxData array.
*/
/*
@@ -283,10 +294,10 @@ typedef struct CompileEnv {
#define TCL_BYTECODE_PRECOMPILED 0x0001
typedef struct ByteCode {
- Interp *iPtr; /* Interpreter containing the code being
- * compiled. Commands and their compile
- * procs are specific to an interpreter so
- * the code emitted will depend on the
+ TclHandle interpHandle; /* Handle for interpreter containing the
+ * compiled code. Commands and their compile
+ * procs are specific to an interpreter so the
+ * code emitted will depend on the
* interpreter. */
int compileEpoch; /* Value of iPtr->compileEpoch when this
* ByteCode was compiled. Used to invalidate
@@ -315,29 +326,30 @@ typedef struct ByteCode {
* procedure body, this is a pointer to its
* Proc structure; otherwise NULL. This
* pointer is also not owned by the ByteCode
- * and must not be freed by it. Used for
- * debugging. */
- size_t totalSize; /* Total number of bytes required for this
- * ByteCode structure including the storage
- * for Tcl objects in its object array. */
+ * and must not be freed by it. */
+ size_t structureSize; /* Number of bytes in the ByteCode structure
+ * itself. Does not include heap space for
+ * literal Tcl objects or storage referenced
+ * by AuxData entries. */
int numCommands; /* Number of commands compiled. */
- int numSrcChars; /* Number of source chars compiled. */
+ int numSrcBytes; /* Number of source bytes compiled. */
int numCodeBytes; /* Number of code bytes. */
- int numObjects; /* Number of Tcl objects in object array. */
- int numExcRanges; /* Number of ExceptionRange array elems. */
+ int numLitObjects; /* Number of objects in literal array. */
+ int numExceptRanges; /* Number of ExceptionRange array elems. */
int numAuxDataItems; /* Number of AuxData items. */
int numCmdLocBytes; /* Number of bytes needed for encoded
* command location information. */
- int maxExcRangeDepth; /* Maximum nesting level of ExceptionRanges;
+ int maxExceptDepth; /* Maximum nesting level of ExceptionRanges;
* -1 if no ranges were compiled. */
int maxStackDepth; /* Maximum number of stack elements needed
* to execute the code. */
unsigned char *codeStart; /* Points to the first byte of the code.
* This is just after the final ByteCode
* member cmdMapPtr. */
- Tcl_Obj **objArrayPtr; /* Points to the start of the object array.
- * This is just after the last code byte. */
- ExceptionRange *excRangeArrayPtr;
+ Tcl_Obj **objArrayPtr; /* Points to the start of the literal
+ * object array. This is just after the
+ * last code byte. */
+ ExceptionRange *exceptArrayPtr;
/* Points to the start of the ExceptionRange
* array. This is just after the last
* object in the object array. */
@@ -378,106 +390,111 @@ typedef struct ByteCode {
* are always positive. This sequence is
* just after the last byte in the source
* delta sequence. */
+#ifdef TCL_COMPILE_STATS
+ Tcl_Time createTime; /* Absolute time when the ByteCode was
+ * created. */
+#endif /* TCL_COMPILE_STATS */
} ByteCode;
/*
- * Opcodes for the Tcl bytecode instructions. These opcodes must correspond
- * to the entries in the table of instruction descriptions in tclCompile.c.
- * Also, the order and number of the expression opcodes (e.g., INST_LOR)
- * must match the entries in the array operatorStrings in tclExecute.c.
+ * Opcodes for the Tcl bytecode instructions. These must correspond to the
+ * entries in the table of instruction descriptions, instructionTable, in
+ * tclCompile.c. Also, the order and number of the expression opcodes
+ * (e.g., INST_LOR) must match the entries in the array operatorStrings in
+ * tclExecute.c.
*/
/* Opcodes 0 to 9 */
#define INST_DONE 0
-#define INST_PUSH1 (INST_DONE + 1)
-#define INST_PUSH4 (INST_DONE + 2)
-#define INST_POP (INST_DONE + 3)
-#define INST_DUP (INST_DONE + 4)
-#define INST_CONCAT1 (INST_DONE + 5)
-#define INST_INVOKE_STK1 (INST_DONE + 6)
-#define INST_INVOKE_STK4 (INST_DONE + 7)
-#define INST_EVAL_STK (INST_DONE + 8)
-#define INST_EXPR_STK (INST_DONE + 9)
+#define INST_PUSH1 1
+#define INST_PUSH4 2
+#define INST_POP 3
+#define INST_DUP 4
+#define INST_CONCAT1 5
+#define INST_INVOKE_STK1 6
+#define INST_INVOKE_STK4 7
+#define INST_EVAL_STK 8
+#define INST_EXPR_STK 9
/* Opcodes 10 to 23 */
-#define INST_LOAD_SCALAR1 (INST_EXPR_STK + 1)
-#define INST_LOAD_SCALAR4 (INST_LOAD_SCALAR1 + 1)
-#define INST_LOAD_SCALAR_STK (INST_LOAD_SCALAR1 + 2)
-#define INST_LOAD_ARRAY1 (INST_LOAD_SCALAR1 + 3)
-#define INST_LOAD_ARRAY4 (INST_LOAD_SCALAR1 + 4)
-#define INST_LOAD_ARRAY_STK (INST_LOAD_SCALAR1 + 5)
-#define INST_LOAD_STK (INST_LOAD_SCALAR1 + 6)
-#define INST_STORE_SCALAR1 (INST_LOAD_SCALAR1 + 7)
-#define INST_STORE_SCALAR4 (INST_LOAD_SCALAR1 + 8)
-#define INST_STORE_SCALAR_STK (INST_LOAD_SCALAR1 + 9)
-#define INST_STORE_ARRAY1 (INST_LOAD_SCALAR1 + 10)
-#define INST_STORE_ARRAY4 (INST_LOAD_SCALAR1 + 11)
-#define INST_STORE_ARRAY_STK (INST_LOAD_SCALAR1 + 12)
-#define INST_STORE_STK (INST_LOAD_SCALAR1 + 13)
+#define INST_LOAD_SCALAR1 10
+#define INST_LOAD_SCALAR4 11
+#define INST_LOAD_SCALAR_STK 12
+#define INST_LOAD_ARRAY1 13
+#define INST_LOAD_ARRAY4 14
+#define INST_LOAD_ARRAY_STK 15
+#define INST_LOAD_STK 16
+#define INST_STORE_SCALAR1 17
+#define INST_STORE_SCALAR4 18
+#define INST_STORE_SCALAR_STK 19
+#define INST_STORE_ARRAY1 20
+#define INST_STORE_ARRAY4 21
+#define INST_STORE_ARRAY_STK 22
+#define INST_STORE_STK 23
/* Opcodes 24 to 33 */
-#define INST_INCR_SCALAR1 (INST_STORE_STK + 1)
-#define INST_INCR_SCALAR_STK (INST_INCR_SCALAR1 + 1)
-#define INST_INCR_ARRAY1 (INST_INCR_SCALAR1 + 2)
-#define INST_INCR_ARRAY_STK (INST_INCR_SCALAR1 + 3)
-#define INST_INCR_STK (INST_INCR_SCALAR1 + 4)
-#define INST_INCR_SCALAR1_IMM (INST_INCR_SCALAR1 + 5)
-#define INST_INCR_SCALAR_STK_IMM (INST_INCR_SCALAR1 + 6)
-#define INST_INCR_ARRAY1_IMM (INST_INCR_SCALAR1 + 7)
-#define INST_INCR_ARRAY_STK_IMM (INST_INCR_SCALAR1 + 8)
-#define INST_INCR_STK_IMM (INST_INCR_SCALAR1 + 9)
+#define INST_INCR_SCALAR1 24
+#define INST_INCR_SCALAR_STK 25
+#define INST_INCR_ARRAY1 26
+#define INST_INCR_ARRAY_STK 27
+#define INST_INCR_STK 28
+#define INST_INCR_SCALAR1_IMM 29
+#define INST_INCR_SCALAR_STK_IMM 30
+#define INST_INCR_ARRAY1_IMM 31
+#define INST_INCR_ARRAY_STK_IMM 32
+#define INST_INCR_STK_IMM 33
/* Opcodes 34 to 39 */
-#define INST_JUMP1 (INST_INCR_STK_IMM + 1)
-#define INST_JUMP4 (INST_JUMP1 + 1)
-#define INST_JUMP_TRUE1 (INST_JUMP1 + 2)
-#define INST_JUMP_TRUE4 (INST_JUMP1 + 3)
-#define INST_JUMP_FALSE1 (INST_JUMP1 + 4)
-#define INST_JUMP_FALSE4 (INST_JUMP1 + 5)
+#define INST_JUMP1 34
+#define INST_JUMP4 35
+#define INST_JUMP_TRUE1 36
+#define INST_JUMP_TRUE4 37
+#define INST_JUMP_FALSE1 38
+#define INST_JUMP_FALSE4 39
/* Opcodes 40 to 64 */
-#define INST_LOR (INST_JUMP_FALSE4 + 1)
-#define INST_LAND (INST_LOR + 1)
-#define INST_BITOR (INST_LOR + 2)
-#define INST_BITXOR (INST_LOR + 3)
-#define INST_BITAND (INST_LOR + 4)
-#define INST_EQ (INST_LOR + 5)
-#define INST_NEQ (INST_LOR + 6)
-#define INST_LT (INST_LOR + 7)
-#define INST_GT (INST_LOR + 8)
-#define INST_LE (INST_LOR + 9)
-#define INST_GE (INST_LOR + 10)
-#define INST_LSHIFT (INST_LOR + 11)
-#define INST_RSHIFT (INST_LOR + 12)
-#define INST_ADD (INST_LOR + 13)
-#define INST_SUB (INST_LOR + 14)
-#define INST_MULT (INST_LOR + 15)
-#define INST_DIV (INST_LOR + 16)
-#define INST_MOD (INST_LOR + 17)
-#define INST_UPLUS (INST_LOR + 18)
-#define INST_UMINUS (INST_LOR + 19)
-#define INST_BITNOT (INST_LOR + 20)
-#define INST_LNOT (INST_LOR + 21)
-#define INST_CALL_BUILTIN_FUNC1 (INST_LOR + 22)
-#define INST_CALL_FUNC1 (INST_LOR + 23)
-#define INST_TRY_CVT_TO_NUMERIC (INST_LOR + 24)
+#define INST_LOR 40
+#define INST_LAND 41
+#define INST_BITOR 42
+#define INST_BITXOR 43
+#define INST_BITAND 44
+#define INST_EQ 45
+#define INST_NEQ 46
+#define INST_LT 47
+#define INST_GT 48
+#define INST_LE 49
+#define INST_GE 50
+#define INST_LSHIFT 51
+#define INST_RSHIFT 52
+#define INST_ADD 53
+#define INST_SUB 54
+#define INST_MULT 55
+#define INST_DIV 56
+#define INST_MOD 57
+#define INST_UPLUS 58
+#define INST_UMINUS 59
+#define INST_BITNOT 60
+#define INST_LNOT 61
+#define INST_CALL_BUILTIN_FUNC1 62
+#define INST_CALL_FUNC1 63
+#define INST_TRY_CVT_TO_NUMERIC 64
/* Opcodes 65 to 66 */
-#define INST_BREAK (INST_TRY_CVT_TO_NUMERIC + 1)
-#define INST_CONTINUE (INST_BREAK + 1)
+#define INST_BREAK 65
+#define INST_CONTINUE 66
/* Opcodes 67 to 68 */
-#define INST_FOREACH_START4 (INST_CONTINUE + 1)
-#define INST_FOREACH_STEP4 (INST_FOREACH_START4 + 1)
+#define INST_FOREACH_START4 67
+#define INST_FOREACH_STEP4 68
/* Opcodes 69 to 72 */
-#define INST_BEGIN_CATCH4 (INST_FOREACH_STEP4 + 1)
-#define INST_END_CATCH (INST_BEGIN_CATCH4 + 1)
-#define INST_PUSH_RESULT (INST_BEGIN_CATCH4 + 2)
-#define INST_PUSH_RETURN_CODE (INST_BEGIN_CATCH4 + 3)
+#define INST_BEGIN_CATCH4 69
+#define INST_END_CATCH 70
+#define INST_PUSH_RESULT 71
+#define INST_PUSH_RETURN_CODE 72
/* The last opcode */
-#define LAST_INST_OPCODE INST_PUSH_RETURN_CODE
+#define LAST_INST_OPCODE 72
/*
* Table describing the Tcl bytecode instructions: their name (for
@@ -542,7 +559,7 @@ extern InstructionDesc instructionTable[];
#define BUILTIN_FUNC_ROUND 23
#define BUILTIN_FUNC_SRAND 24
-#define LAST_BUILTIN_FUNC BUILTIN_FUNC_SRAND
+#define LAST_BUILTIN_FUNC 24
/*
* Table describing the built-in math functions. Entries in this table are
@@ -566,30 +583,6 @@ typedef struct {
extern BuiltinFunc builtinFuncTable[];
/*
- * The structure used to hold information about the start and end of each
- * argument word in a command.
- */
-
-#define ARGINFO_INIT_ENTRIES 5
-
-typedef struct ArgInfo {
- int numArgs; /* Number of argument words in command. */
- char **startArray; /* Array of pointers to the first character
- * of each argument word. */
- char **endArray; /* Array of pointers to the last character
- * of each argument word. */
- int allocArgs; /* Number of array entries currently
- * allocated. */
- int mallocedArrays; /* 1 if the arrays were expanded and
- * wordStartArray/wordEndArray point into
- * the heap, else 0. */
- char *staticStartSpace[ARGINFO_INIT_ENTRIES];
- /* Initial storage for word start array. */
- char *staticEndSpace[ARGINFO_INIT_ENTRIES];
- /* Initial storage for word end array. */
-} ArgInfo;
-
-/*
* Compilation of some Tcl constructs such as if commands and the logical or
* (||) and logical and (&&) operators in expressions requires the
* generation of forward jumps. Since the PC target of these jumps isn't
@@ -617,7 +610,7 @@ typedef struct JumpFixup {
* update the code offsets for subsequent
* commands if the two-byte jump at jumpPc
* must be replaced with a five-byte one. */
- int excRangeIndex; /* Index of the first range entry in the
+ int exceptIndex; /* Index of the first range entry in the
* ExceptionRange array after the current
* one. This field is used to adjust the
* code offsets in subsequent ExceptionRange
@@ -664,12 +657,12 @@ typedef struct ForeachVarList {
typedef struct ForeachInfo {
int numLists; /* The number of both the variable and value
* lists of the foreach command. */
- int firstListTmp; /* The slot number of the first temporary
- * variable holding the lists themselves. */
- int loopIterNumTmp; /* The slot number of the temp var holding
- * the count of times the loop body has been
- * executed. This is used to determine which
- * list element to assign each loop var. */
+ int firstValueTemp; /* Index of the first temp var in a proc
+ * frame used to point to a value list. */
+ int loopCtTemp; /* Index of temp var in a proc frame
+ * holding the loop's iteration count. Used
+ * to determine next value list element to
+ * assign each loop var. */
ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList
* structures describing each var list. The
* actual size of this field will be large
@@ -677,6 +670,8 @@ typedef struct ForeachInfo {
* THE LAST FIELD IN THE STRUCTURE! */
} ForeachInfo;
+extern AuxDataType tclForeachInfoType;
+
/*
* Structure containing a cached pointer to a command that is the result
* of resolving the command's name in some namespace. It is the internal
@@ -720,24 +715,32 @@ typedef struct ResolvedCmdName {
*/
EXTERN void TclCleanupByteCode _ANSI_ARGS_((ByteCode *codePtr));
+EXTERN int TclCompileCmdWord _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Token *tokenPtr, int count,
+ CompileEnv *envPtr));
EXTERN int TclCompileExpr _ANSI_ARGS_((Tcl_Interp *interp,
- char *string, char *lastChar, int flags,
+ char *script, int numBytes,
CompileEnv *envPtr));
-EXTERN int TclCompileQuotes _ANSI_ARGS_((Tcl_Interp *interp,
- char *string, char *lastChar, int termChar,
- int flags, CompileEnv *envPtr));
-EXTERN int TclCompileString _ANSI_ARGS_((Tcl_Interp *interp,
- char *string, char *lastChar, int flags,
+EXTERN int TclCompileExprWords _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Token *tokenPtr, int numWords,
CompileEnv *envPtr));
-EXTERN int TclCompileDollarVar _ANSI_ARGS_((Tcl_Interp *interp,
- char *string, char *lastChar, int flags,
+EXTERN int TclCompileScript _ANSI_ARGS_((Tcl_Interp *interp,
+ char *script, int numBytes, int nested,
+ CompileEnv *envPtr));
+EXTERN int TclCompileTokens _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Token *tokenPtr, int count,
CompileEnv *envPtr));
EXTERN int TclCreateAuxData _ANSI_ARGS_((ClientData clientData,
- AuxDataType *typePtr, CompileEnv *envPtr));
+ AuxDataType *typePtr, CompileEnv *envPtr));
+EXTERN int TclCreateExceptRange _ANSI_ARGS_((
+ ExceptionRangeType type, CompileEnv *envPtr));
EXTERN ExecEnv * TclCreateExecEnv _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void TclDeleteExecEnv _ANSI_ARGS_((ExecEnv *eePtr));
+EXTERN void TclDeleteLiteralTable _ANSI_ARGS_((
+ Tcl_Interp *interp, LiteralTable *tablePtr));
EXTERN void TclEmitForwardJump _ANSI_ARGS_((CompileEnv *envPtr,
TclJumpType jumpType, JumpFixup *jumpFixupPtr));
+EXTERN AuxDataType *TclGetAuxDataType _ANSI_ARGS_((char *typeName));
EXTERN ExceptionRange * TclGetExceptionRangeForPc _ANSI_ARGS_((
unsigned char *pc, int catchOnly,
ByteCode* codePtr));
@@ -745,10 +748,15 @@ EXTERN InstructionDesc * TclGetInstructionTable _ANSI_ARGS_(());
EXTERN int TclExecuteByteCode _ANSI_ARGS_((Tcl_Interp *interp,
ByteCode *codePtr));
EXTERN void TclExpandCodeArray _ANSI_ARGS_((
- CompileEnv *envPtr));
+ CompileEnv *envPtr));
EXTERN void TclExpandJumpFixupArray _ANSI_ARGS_((
JumpFixupArray *fixupArrayPtr));
EXTERN void TclFinalizeAuxDataTypeTable _ANSI_ARGS_((void));
+EXTERN int TclFindCompiledLocal _ANSI_ARGS_((char *name,
+ int nameChars, int create, int flags,
+ Proc *procPtr));
+EXTERN LiteralEntry * TclLookupLiteralEntry _ANSI_ARGS_((
+ Tcl_Interp *interp, Tcl_Obj *objPtr));
EXTERN int TclFixupForwardJump _ANSI_ARGS_((
CompileEnv *envPtr, JumpFixup *jumpFixupPtr,
int jumpDist, int distThreshold));
@@ -758,21 +766,42 @@ EXTERN void TclFreeJumpFixupArray _ANSI_ARGS_((
EXTERN void TclInitAuxDataTypeTable _ANSI_ARGS_((void));
EXTERN void TclInitByteCodeObj _ANSI_ARGS_((Tcl_Obj *objPtr,
CompileEnv *envPtr));
+EXTERN void TclInitCompilation _ANSI_ARGS_((void));
EXTERN void TclInitCompileEnv _ANSI_ARGS_((Tcl_Interp *interp,
- CompileEnv *envPtr, char *string));
+ CompileEnv *envPtr, char *string,
+ int numBytes));
EXTERN void TclInitJumpFixupArray _ANSI_ARGS_((
JumpFixupArray *fixupArrayPtr));
+EXTERN void TclInitLiteralTable _ANSI_ARGS_((
+ LiteralTable *tablePtr));
#ifdef TCL_COMPILE_STATS
+EXTERN char * TclLiteralStats _ANSI_ARGS_((
+ LiteralTable *tablePtr));
EXTERN int TclLog2 _ANSI_ARGS_((int value));
-#endif /*TCL_COMPILE_STATS*/
-EXTERN int TclObjIndexForString _ANSI_ARGS_((char *start,
- int length, int allocStrRep, int inHeap,
- CompileEnv *envPtr));
+#endif
+#ifdef TCL_COMPILE_DEBUG
+EXTERN void TclPrintByteCodeObj _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *objPtr));
+#endif
EXTERN int TclPrintInstruction _ANSI_ARGS_((ByteCode* codePtr,
unsigned char *pc));
+EXTERN void TclPrintObject _ANSI_ARGS_((FILE *outFile,
+ Tcl_Obj *objPtr, int maxChars));
EXTERN void TclPrintSource _ANSI_ARGS_((FILE *outFile,
char *string, int maxChars));
EXTERN void TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
+EXTERN int TclRegisterLiteral _ANSI_ARGS_((CompileEnv *envPtr,
+ char *bytes, int length, int onHeap));
+EXTERN void TclReleaseLiteral _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *objPtr));
+EXTERN void TclSetCmdNameObj _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *objPtr, Command *cmdPtr));
+#ifdef TCL_COMPILE_DEBUG
+EXTERN void TclVerifyGlobalLiteralTable _ANSI_ARGS_((
+ Interp *iPtr));
+EXTERN void TclVerifyLocalLiteralTable _ANSI_ARGS_((
+ CompileEnv *envPtr));
+#endif
/*
*----------------------------------------------------------------
@@ -782,23 +811,6 @@ EXTERN void TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
*/
/*
- * Macros to ensure there is enough room in a CompileEnv's code array.
- * The ANSI C "prototypes" for these macros are:
- *
- * EXTERN void TclEnsureCodeSpace1 _ANSI_ARGS_((CompileEnv *envPtr));
- * EXTERN void TclEnsureCodeSpace _ANSI_ARGS_((int nBytes,
- * CompileEnv *envPtr));
- */
-
-#define TclEnsureCodeSpace1(envPtr) \
- if ((envPtr)->codeNext == (envPtr)->codeEnd) \
- TclExpandCodeArray(envPtr)
-
-#define TclEnsureCodeSpace(nBytes, envPtr) \
- if (((envPtr)->codeNext + nBytes) > (envPtr)->codeEnd) \
- TclExpandCodeArray(envPtr)
-
-/*
* Macro to emit an opcode byte into a CompileEnv's code array.
* The ANSI C "prototype" for this macro is:
*
@@ -807,55 +819,45 @@ EXTERN void TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
*/
#define TclEmitOpcode(op, envPtr) \
- TclEnsureCodeSpace1(envPtr); \
+ if ((envPtr)->codeNext == (envPtr)->codeEnd) \
+ TclExpandCodeArray(envPtr); \
*(envPtr)->codeNext++ = (unsigned char) (op)
/*
- * Macros to emit a (signed or unsigned) int operand. The two variants
- * depend on the number of bytes needed for the int. Four byte integers
- * are stored in "big-endian" order with the high order byte stored at
- * the lowest address. The ANSI C "prototypes" for these macros are:
+ * Macro to emit an integer operand.
+ * The ANSI C "prototype" for this macro is:
*
* EXTERN void TclEmitInt1 _ANSI_ARGS_((int i, CompileEnv *envPtr));
- * EXTERN void TclEmitInt4 _ANSI_ARGS_((int i, CompileEnv *envPtr));
*/
#define TclEmitInt1(i, envPtr) \
- TclEnsureCodeSpace(1, (envPtr)); \
+ if ((envPtr)->codeNext == (envPtr)->codeEnd) \
+ TclExpandCodeArray(envPtr); \
*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))
-#define TclEmitInt4(i, envPtr) \
- TclEnsureCodeSpace(4, (envPtr)); \
- *(envPtr)->codeNext++ = \
- (unsigned char) ((unsigned int) (i) >> 24); \
- *(envPtr)->codeNext++ = \
- (unsigned char) ((unsigned int) (i) >> 16); \
- *(envPtr)->codeNext++ = \
- (unsigned char) ((unsigned int) (i) >> 8); \
- *(envPtr)->codeNext++ = \
- (unsigned char) ((unsigned int) (i) )
-
/*
- * Macros to emit an instruction with signed or unsigned int operands.
+ * Macros to emit an instruction with signed or unsigned integer operands.
+ * Four byte integers are stored in "big-endian" order with the high order
+ * byte stored at the lowest address.
* The ANSI C "prototypes" for these macros are:
*
* EXTERN void TclEmitInstInt1 _ANSI_ARGS_((unsigned char op, int i,
* CompileEnv *envPtr));
* EXTERN void TclEmitInstInt4 _ANSI_ARGS_((unsigned char op, int i,
* CompileEnv *envPtr));
- * EXTERN void TclEmitInstUInt1 _ANSI_ARGS_((unsigned char op,
- * unsigned int i, CompileEnv *envPtr));
- * EXTERN void TclEmitInstUInt4 _ANSI_ARGS_((unsigned char op,
- * unsigned int i, CompileEnv *envPtr));
*/
#define TclEmitInstInt1(op, i, envPtr) \
- TclEnsureCodeSpace(2, (envPtr)); \
+ if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) { \
+ TclExpandCodeArray(envPtr); \
+ } \
*(envPtr)->codeNext++ = (unsigned char) (op); \
*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))
#define TclEmitInstInt4(op, i, envPtr) \
- TclEnsureCodeSpace(5, (envPtr)); \
+ if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \
+ TclExpandCodeArray(envPtr); \
+ } \
*(envPtr)->codeNext++ = (unsigned char) (op); \
*(envPtr)->codeNext++ = \
(unsigned char) ((unsigned int) (i) >> 24); \
@@ -866,12 +868,6 @@ EXTERN void TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
*(envPtr)->codeNext++ = \
(unsigned char) ((unsigned int) (i) )
-#define TclEmitInstUInt1(op, i, envPtr) \
- TclEmitInstInt1((op), (i), (envPtr))
-
-#define TclEmitInstUInt4(op, i, envPtr) \
- TclEmitInstInt4((op), (i), (envPtr))
-
/*
* Macro to push a Tcl object onto the Tcl evaluation stack. It emits the
* object's one or four byte array index into the CompileEnv's code
@@ -883,9 +879,9 @@ EXTERN void TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
#define TclEmitPush(objIndex, envPtr) \
if ((objIndex) <= 255) { \
- TclEmitInstUInt1(INST_PUSH1, (objIndex), (envPtr)); \
+ TclEmitInstInt1(INST_PUSH1, (objIndex), (envPtr)); \
} else { \
- TclEmitInstUInt4(INST_PUSH4, (objIndex), (envPtr)); \
+ TclEmitInstInt4(INST_PUSH4, (objIndex), (envPtr)); \
}
/*
@@ -979,22 +975,6 @@ EXTERN void TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
#define TclMin(i, j) ((((int) i) < ((int) j))? (i) : (j))
#define TclMax(i, j) ((((int) i) > ((int) j))? (i) : (j))
-/*
- * Macro used to compute the offset of the current instruction in the
- * bytecode instruction stream. The ANSI C "prototypes" for this macro is:
- *
- * EXTERN int TclCurrCodeOffset _ANSI_ARGS_((void));
- */
-
-#define TclCurrCodeOffset() ((envPtr)->codeNext - (envPtr)->codeStart)
-
-/*
- * Upper bound for legal jump distances. Checked during compilation if
- * debugging.
- */
-
-#define MAX_JUMP_DIST 5000
-
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT