Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Backdoor kludge to let traced ensemble subcommands gain access to the string command of the original, avoiding expensive reconstruction from the parsed words. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | bug-3485833 |
Files: | files | file ages | folders |
SHA1: |
a96d1454188b6567bd29e1e95b124741 |
User & Date: | dgp 2012-03-05 19:11:48 |
Context
2012-03-05
| ||
20:47 | Better conform to Tcl style guidelines. check-in: ffd6477611 user: dgp tags: bug-3485833 | |
19:11 | Backdoor kludge to let traced ensemble subcommands gain access to the string command of the original... check-in: a96d145418 user: dgp tags: bug-3485833 | |
2012-03-04
| ||
16:38 | Patch from the cygwin folks check-in: 8dafecc06c user: jan.nijtmans tags: core-8-5-branch | |
2012-03-01
| ||
09:29 | clarify and review code check-in: cda4203920 user: sebres tags: dgp-scan-element | |
Changes
Changes to generic/tclBasic.c.
︙ | ︙ | |||
3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 | *---------------------------------------------------------------------- * * GetCommandSource -- * * This function returns a Tcl_Obj with the full source string for the * command. This insures that traces get a correct NUL-terminated command * string. * *---------------------------------------------------------------------- */ static Tcl_Obj * GetCommandSource( Interp *iPtr, const char *command, int numChars, int objc, Tcl_Obj *const objv[]) { if (!command) { return Tcl_NewListObj(objc, objv); } if (command == (char *) -1) { command = TclGetSrcInfoForCmd(iPtr, &numChars); } return Tcl_NewStringObj(command, numChars); } /* *---------------------------------------------------------------------- * | > > > > > > | 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 | *---------------------------------------------------------------------- * * GetCommandSource -- * * This function returns a Tcl_Obj with the full source string for the * command. This insures that traces get a correct NUL-terminated command * string. * If parameter 'command' is (char*)-1 it returns a pointer to the command's * source using TclGetSrcInfoForCmd. As parameter 'numChars' could be used * an ENSEMBLE_PSEUDO_COMMAND to advise call of the ensemble command. * *---------------------------------------------------------------------- */ static Tcl_Obj * GetCommandSource( Interp *iPtr, const char *command, int numChars, int objc, Tcl_Obj *const objv[]) { if (!command) { return Tcl_NewListObj(objc, objv); } if (command == (char *) -1) { command = TclGetSrcInfoForCmd(iPtr, &numChars); if (!command) { return Tcl_NewListObj(objc, objv); } } return Tcl_NewStringObj(command, numChars); } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3529 3530 3531 3532 3533 3534 3535 | Tcl_Obj *const objv[], /* An array of pointers to objects that are * the words that make up the command. */ const char *command, /* Points to the beginning of the string * representation of the command; this is used * for traces. NULL if the string * representation of the command is unknown is * to be generated from (objc,objv), -1 if it | | > > | | 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 | Tcl_Obj *const objv[], /* An array of pointers to objects that are * the words that make up the command. */ const char *command, /* Points to the beginning of the string * representation of the command; this is used * for traces. NULL if the string * representation of the command is unknown is * to be generated from (objc,objv), -1 if it * is to be generated from bytecode source, * with length ENSEMBLE_PSEUDO_COMMAND it is * to be determined from the ensemble context. * This is only needed the traces. */ int length, /* Number of bytes in command; if -1, all * characters up to the first null byte are * used. */ int flags) /* Collection of OR-ed bits that control the * evaluation of the script. Only * TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE are * currently supported. */ |
︙ | ︙ |
Changes to generic/tclCompile.h.
︙ | ︙ | |||
839 840 841 842 843 844 845 846 847 848 849 850 851 852 | const char *op; /* Do not call it 'operator': C++ reserved */ const char *expected; union { int numArgs; int identity; } i; } TclOpCmdClientData; /* *---------------------------------------------------------------- * Procedures exported by tclBasic.c to be used within the engine. *---------------------------------------------------------------- */ | > > > > > > > > | 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 | const char *op; /* Do not call it 'operator': C++ reserved */ const char *expected; union { int numArgs; int identity; } i; } TclOpCmdClientData; /* * Special sentinel value for TclEvalObjvInternal's 'length' parameter to * cause it to retrieve command information for an ensemble from the * containing command (parameter 'command' is (char *)-1). */ #define ENSEMBLE_PSEUDO_COMMAND -2 /* *---------------------------------------------------------------- * Procedures exported by tclBasic.c to be used within the engine. *---------------------------------------------------------------- */ |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 | * Results: * If a command is found that encloses the program counter value, a * pointer to the command's source is returned and the length of the * source is stored at *lengthPtr. If multiple commands resulted in code * at pc, information about the closest enclosing command is returned. If * no matching command is found, NULL is returned and *lengthPtr is * unchanged. * * Side effects: * The CmdFrame at *cfPtr is updated. * *---------------------------------------------------------------------- */ const char * TclGetSrcInfoForCmd( Interp *iPtr, int *lenPtr) { CmdFrame *cfPtr = iPtr->cmdFramePtr; | > > > > > > > > | > > > > | | > > > > > > > > > > > > > > > > > > | 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 | * Results: * If a command is found that encloses the program counter value, a * pointer to the command's source is returned and the length of the * source is stored at *lengthPtr. If multiple commands resulted in code * at pc, information about the closest enclosing command is returned. If * no matching command is found, NULL is returned and *lengthPtr is * unchanged. * As input parameter '*lengthPtr' could be used an ENSEMBLE_PSEUDO_COMMAND * to advise call of the ensemble command. * * Side effects: * The CmdFrame at *cfPtr is updated. * *---------------------------------------------------------------------- */ const char * TclGetSrcInfoForCmd( Interp *iPtr, int *lenPtr) { CmdFrame *cfPtr = iPtr->cmdFramePtr; const char *command; ByteCode *codePtr; int len; if (!cfPtr) return NULL; codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; if (!codePtr) return NULL; if (!cfPtr->data.tebc.pc) return NULL; command = GetSrcInfoForPc((unsigned char *) cfPtr->data.tebc.pc, codePtr, &len); /* * [sebres]: If ensemble call (sentinel length == ENSEMBLE_PSEUDO_COMMAND), * shift string ptr to subcommand (string range -> range). */ if (command && len && (lenPtr && *lenPtr == ENSEMBLE_PSEUDO_COMMAND) && codePtr->objArrayPtr) { Tcl_Obj *objPtr = codePtr->objArrayPtr[0]; if (len > objPtr->length) { command += objPtr->length + 1; len -= objPtr->length + 1; } } if (lenPtr != NULL) *lenPtr = len; return command; } void TclGetSrcInfoForPc( CmdFrame *cfPtr) { ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; |
︙ | ︙ |
Changes to generic/tclNamesp.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * [email protected] * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" /* * Thread-local storage used to avoid having a global lock on data that is not * limited to a single interpreter. */ typedef struct ThreadSpecificData { | > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | * [email protected] * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #include "tclCompile.h" /* * Thread-local storage used to avoid having a global lock on data that is not * limited to a single interpreter. */ typedef struct ThreadSpecificData { |
︙ | ︙ | |||
6225 6226 6227 6228 6229 6230 6231 6232 6233 | tempObjv = (Tcl_Obj **) TclStackAlloc(interp, (int) sizeof(Tcl_Obj *) * (objc - 2 + prefixObjc)); memcpy(tempObjv, prefixObjv, sizeof(Tcl_Obj *) * prefixObjc); memcpy(tempObjv+prefixObjc, objv+2, sizeof(Tcl_Obj *) * (objc-2)); /* * Hand off to the target command. */ | > > | > | | 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 | tempObjv = (Tcl_Obj **) TclStackAlloc(interp, (int) sizeof(Tcl_Obj *) * (objc - 2 + prefixObjc)); memcpy(tempObjv, prefixObjv, sizeof(Tcl_Obj *) * prefixObjc); memcpy(tempObjv+prefixObjc, objv+2, sizeof(Tcl_Obj *) * (objc-2)); /* * Hand off to the target command. * [sebres] call from ensemble using ENSEMBLE_PSEUDO_COMMAND to * retrive subcommand from main ensemble. */ result = TclEvalObjvInternal(interp, objc-2+prefixObjc, tempObjv, /* call from TEBC, TclGetSrcInfoForCmd sentinel */(char *) -1, ENSEMBLE_PSEUDO_COMMAND, TCL_EVAL_INVOKE); /* * Clean up. */ TclStackFree(interp, tempObjv); Tcl_DecrRefCount(copyObj); |
︙ | ︙ |