diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2007-03-02 10:32:11 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2007-03-02 10:32:11 (GMT) |
commit | 48983007bc418e8c97a2e3ee2583678ed4a7fad8 (patch) | |
tree | 0c0e997fd383d7e41d06b24792e65acc89232733 /generic/tclCompile.c | |
parent | 57b319287e05948bc3a93c9517e50e42b59e9f44 (diff) | |
download | tcl-48983007bc418e8c97a2e3ee2583678ed4a7fad8.zip tcl-48983007bc418e8c97a2e3ee2583678ed4a7fad8.tar.gz tcl-48983007bc418e8c97a2e3ee2583678ed4a7fad8.tar.bz2 |
Added a scheme to allow aux-data to be printed out for debugging. For this to work, immediate operands referring to aux-data must be identified as such in the instruction descriptor table using OPERAND_AUX4 (all are always 4 bytes).
Rewrote the compiled [dict update] so that it stores critical non-varying data in an aux-data value instead of a (shimmerable) literal. [Bug 1671001]
Diffstat (limited to 'generic/tclCompile.c')
-rw-r--r-- | generic/tclCompile.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 8509b60..02e23c7 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -11,7 +11,7 @@ * 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.107 2007/02/20 23:24:02 nijtmans Exp $ + * RCS: @(#) $Id: tclCompile.c,v 1.108 2007/03/02 10:32:12 dkf Exp $ */ #include "tclInt.h" @@ -196,10 +196,10 @@ InstructionDesc tclInstructionTable[] = { /* 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_AUX4}}, /* 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_AUX4}}, /* "Step" or begin next iteration of foreach loop. Push 0 if to * terminate loop, else push 1. */ @@ -350,19 +350,21 @@ InstructionDesc tclInstructionTable[] = { * Stack: ... => ... value key doneBool */ {"dictDone", 5, 0, 1, {OPERAND_LVT4}}, /* Terminate the iterator in op4's local scalar. */ - {"dictUpdateStart", 5, -2, 1, {OPERAND_LVT4}}, - /* Create the variables to mirror the state of the dictionary in the - * variable referred to by the immediate argument. - * Stack: ... keyList LVTindexList => ... - * Note that the list of LVT indices is assumed to be the same length - * as the keyList, and the indices should be only ever generated by the - * compiler. */ - {"dictUpdateEnd", 5, -2, 1, {OPERAND_LVT4}}, - /* Reflect the state of local variables back to the state of the - * dictionary in the variable referred to by the immediate argument. - * Stack: ... keyList LVTindexList => ... - * Same notes as in "dictUpdateStart" apply here. */ - {"jumpTable", 5, -1, 1, {OPERAND_UINT4}}, + {"dictUpdateStart", 5, -1, 2, {OPERAND_LVT4, OPERAND_AUX4}}, + /* Create the variables (described in the aux data referred to by the + * second immediate argument) to mirror the state of the dictionary in + * the variable referred to by the first immediate argument. The list + * of keys (popped from the stack) must be the same length as the list + * of variables. + * Stack: ... keyList => ... */ + {"dictUpdateEnd", 5, -1, 1, {OPERAND_LVT4, OPERAND_AUX4}}, + /* Reflect the state of local variables (described in the aux data + * referred to by the second immediate argument) back to the state of + * the dictionary in the variable referred to by the first immediate + * argument. The list of keys (popped from the stack) must be the same + * length as the list of variables. + * Stack: ... keyList => ... */ + {"jumpTable", 5, -1, 1, {OPERAND_AUX4}}, /* Jump according to the jump-table (in AuxData as indicated by the * operand) and the argument popped from the list. Always executes the * next instruction if no match against the table's entries was found. @@ -3641,6 +3643,7 @@ TclPrintInstruction( * and immediates. */ char *suffixSrc = NULL; Tcl_Obj *suffixObj = NULL; + AuxData *auxPtr = NULL; suffixBuffer[0] = '\0'; fprintf(stdout, "(%u) %s ", pcOffset, instDesc->name); @@ -3669,6 +3672,7 @@ TclPrintInstruction( } fprintf(stdout, "%u ", (unsigned int) opnd); break; + case OPERAND_AUX4: case OPERAND_UINT4: opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4; if (opCode == INST_PUSH4) { @@ -3677,6 +3681,9 @@ TclPrintInstruction( sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd); } fprintf(stdout, "%u ", (unsigned int) opnd); + if (instDesc->opTypes[i] == OPERAND_AUX4) { + auxPtr = &codePtr->auxDataArrayPtr[opnd]; + } break; case OPERAND_IDX4: opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; @@ -3728,6 +3735,11 @@ TclPrintInstruction( } } fprintf(stdout, "\n"); + if (auxPtr && auxPtr->type->printProc) { + fprintf(stdout, "\t\t["); + auxPtr->type->printProc(auxPtr->clientData, codePtr, pcOffset); + fprintf(stdout, "]\n"); + } return numBytes; } |