Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Reproduce TclOO's practice of sticking context info in the clientdata of the current frame. This is needed because ItclObjectCommand goes poking in there expecting to find it. One internals intrusion leads to more. Ugly! But for now it fixes [Itk Bug 38744a21a0]. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
23b1e4cd73c0fe71b1c200d32dae8896 |
User & Date: | dgp 2017-07-07 18:48:31 |
Context
2017-07-20
| ||
20:54 | Revert last commit and take the better approach. Stop ItclObjectCmd from going poking into Tcl's areas of the CallFrame. Use Itcl's own mechanisms for fetching proper context information. check-in: 3e21a7bc42 user: dgp tags: trunk | |
2017-07-07
| ||
18:48 | Reproduce TclOO's practice of sticking context info in the clientdata of the current frame. This is needed because ItclObjectCommand goes poking in there expecting to find it. One internals intrusion leads to more. Ugly! But for now it fixes [Itk Bug 38744a21a0]. check-in: 23b1e4cd73 user: dgp tags: trunk | |
2017-06-29
| ||
11:51 | merge bug fixes from 4.0.6 check-in: fa9bab3e83 user: dgp tags: trunk | |
Changes
Changes to generic/itclInt.h.
︙ | ︙ | |||
694 695 696 697 698 699 700 701 702 703 704 705 706 707 | MODULE_SCOPE Tcl_Var Itcl_VarAliasProc(Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *VarName, ClientData clientData); MODULE_SCOPE int ItclIsClass(Tcl_Interp *interp, Tcl_Command cmd); MODULE_SCOPE int ItclCheckCallMethod(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext contextPtr, Tcl_CallFrame *framePtr, int *isFinished); MODULE_SCOPE int ItclAfterCallMethod(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext contextPtr, Tcl_Namespace *nsPtr, int result); MODULE_SCOPE void ItclReportObjectUsage(Tcl_Interp *interp, ItclObject *contextIoPtr, Tcl_Namespace *callerNsPtr, Tcl_Namespace *contextNsPtr); MODULE_SCOPE int ItclMapMethodNameProc(Tcl_Interp *interp, Tcl_Object oPtr, Tcl_Class *startClsPtr, Tcl_Obj *methodObj); MODULE_SCOPE int ItclCreateArgList(Tcl_Interp *interp, const char *str, int *argcPtr, int *maxArgcPtr, Tcl_Obj **usagePtr, | > > | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | MODULE_SCOPE Tcl_Var Itcl_VarAliasProc(Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *VarName, ClientData clientData); MODULE_SCOPE int ItclIsClass(Tcl_Interp *interp, Tcl_Command cmd); MODULE_SCOPE int ItclCheckCallMethod(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext contextPtr, Tcl_CallFrame *framePtr, int *isFinished); MODULE_SCOPE int ItclAfterCallMethod(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext contextPtr, Tcl_Namespace *nsPtr, int result); MODULE_SCOPE int ItclSetCallFrameClientData(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE void ItclReportObjectUsage(Tcl_Interp *interp, ItclObject *contextIoPtr, Tcl_Namespace *callerNsPtr, Tcl_Namespace *contextNsPtr); MODULE_SCOPE int ItclMapMethodNameProc(Tcl_Interp *interp, Tcl_Object oPtr, Tcl_Class *startClsPtr, Tcl_Obj *methodObj); MODULE_SCOPE int ItclCreateArgList(Tcl_Interp *interp, const char *str, int *argcPtr, int *maxArgcPtr, Tcl_Obj **usagePtr, |
︙ | ︙ |
Changes to generic/itclMigrate2TclCore.c.
︙ | ︙ | |||
147 148 149 150 151 152 153 154 155 156 157 158 159 160 | */ CallFrame *framePtr = ((Interp *)interp)->varFramePtr; if (framePtr == NULL) { return NULL; } return framePtr->clientData; } int Itcl_SetCallFrameNamespace( Tcl_Interp *interp, Tcl_Namespace *nsPtr) { CallFrame *framePtr = ((Interp *)interp)->varFramePtr; | > > > > > > > > > > > > > | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | */ CallFrame *framePtr = ((Interp *)interp)->varFramePtr; if (framePtr == NULL) { return NULL; } return framePtr->clientData; } int ItclSetCallFrameClientData( Tcl_Interp *interp, ClientData clientData) { CallFrame *framePtr = ((Interp *)interp)->varFramePtr; if (framePtr == NULL) { return TCL_ERROR; } framePtr->clientData = clientData; return TCL_OK; } int Itcl_SetCallFrameNamespace( Tcl_Interp *interp, Tcl_Namespace *nsPtr) { CallFrame *framePtr = ((Interp *)interp)->varFramePtr; |
︙ | ︙ |
Changes to generic/itclParse.c.
︙ | ︙ | |||
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 | CallAfterCallMethod( ClientData data[], Tcl_Interp *interp, int result) { ClientData clientData = data[0]; Tcl_ObjectContext context = data[1]; return ItclAfterCallMethod(clientData, interp, context, NULL, result); } static int ObjCallProc( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { ItclMemberFunc *imPtr = (ItclMemberFunc *)clientData; if (TCL_ERROR == ItclCheckCallMethod(clientData, interp, context, NULL, NULL)) { return TCL_ERROR; } Tcl_NRAddCallback(interp, CallAfterCallMethod, clientData, context, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 | CallAfterCallMethod( ClientData data[], Tcl_Interp *interp, int result) { ClientData clientData = data[0]; Tcl_ObjectContext context = data[1]; ClientData save = data[2]; ItclSetCallFrameClientData(interp, save); return ItclAfterCallMethod(clientData, interp, context, NULL, result); } static int ObjCallProc( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { ItclMemberFunc *imPtr = (ItclMemberFunc *)clientData; Tcl_ObjectContext save = Itcl_GetCallFrameClientData(interp); if (TCL_ERROR == ItclCheckCallMethod(clientData, interp, context, NULL, NULL)) { return TCL_ERROR; } /* * This is an ugly workaround. Someday Itcl 4 should be generally * better designed to replace such nastiness. * * This exists to fix [Itk Bug 38744a21a0] in Itk 4.1. Starting * with Itcl 4.1, we have the itclObjMethodType to attach Itcl * methods coded as C routines to the TclOO foundation. Trouble * happens when one of those C routines calls Tcl*Eval*() and * expects an Itcl object context to be in control. * * The Itcl routine ItclObjectCommand goes looking directly at * the clientData of the interp's current frame to get the * controlling Tcl_ObjectContext. This is a horrifying internals * intrusion that's been inherited. Since that routine is expecting * to find what's been left there by Tcl's procedure method machinery, * we have to duplicate it here in our own method invocation machinery. * * Note that a lot of Itcl itself could be implemented via direct * dispatch to C routines, but even more ugly somersaults are turned * to fake passing through procedure methods instead. This might * be a first step to untangling some of those awful knots too. */ if (TCL_OK != ItclSetCallFrameClientData(interp, (ClientData) context)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "ObjCallProc: FAILED to set callframe context")); return TCL_ERROR; } Tcl_NRAddCallback(interp, CallAfterCallMethod, clientData, context, save, NULL); if ((imPtr->flags & ITCL_COMMON) == 0) { return Itcl_ExecMethod(clientData, interp, objc-1, objv+1); } else { return Itcl_ExecProc(clientData, interp, objc-1, objv+1); } } |
︙ | ︙ |