Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | ItclMemberCode: use reference counting instead of Itcl_PreserveData. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
7388d76981118df3531e35c268c4a44c |
User & Date: | pooryorick 2018-06-06 05:27:19 |
Context
2018-06-14
| ||
12:41 | Remove [source -rsrc] check-in: 97d99ccccd user: dgp tags: trunk | |
2018-06-06
| ||
05:27 | ItclMemberCode: use reference counting instead of Itcl_PreserveData. check-in: 7388d76981 user: pooryorick tags: trunk | |
2018-06-05
| ||
15:01 | Add TCLLIBPATH to valgrind invocation. check-in: 0f3ae00c14 user: pooryorick tags: trunk | |
Changes
Changes to generic/itclClass.c.
︙ | ︙ | |||
2051 2052 2053 2054 2055 2056 2057 | */ if (config) { if (Itcl_CreateMemberCode(interp, iclsPtr, (char*)NULL, config, &mCodePtr) != TCL_OK) { Tcl_DeleteHashEntry(hPtr); return TCL_ERROR; } | | < | 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 | */ if (config) { if (Itcl_CreateMemberCode(interp, iclsPtr, (char*)NULL, config, &mCodePtr) != TCL_OK) { Tcl_DeleteHashEntry(hPtr); return TCL_ERROR; } ItclPreserveMemberCode(mCodePtr); } else { mCodePtr = NULL; } /* * If everything looks good, create the variable definition. |
︙ | ︙ | |||
2115 2116 2117 2118 2119 2120 2121 | int Itcl_CreateOption( Tcl_Interp *interp, /* interpreter managing this transaction */ ItclClass* iclsPtr, /* class containing this variable */ ItclOption* ioptPtr) /* new option definition */ { int newEntry; | < < | | 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 | int Itcl_CreateOption( Tcl_Interp *interp, /* interpreter managing this transaction */ ItclClass* iclsPtr, /* class containing this variable */ ItclOption* ioptPtr) /* new option definition */ { int newEntry; Tcl_HashEntry *hPtr; /* * Add this option to the options table for the class. * Make sure that the option name does not already exist. */ hPtr = Tcl_CreateHashEntry(&iclsPtr->options, (char *)ioptPtr->namePtr, &newEntry); if (!newEntry) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "option name \"", Tcl_GetString(ioptPtr->namePtr), "\" already defined in class \"", Tcl_GetString(iclsPtr->fullNamePtr), "\"", (char*)NULL); return TCL_ERROR; } iclsPtr->numOptions++; ioptPtr->iclsPtr = iclsPtr; ioptPtr->codePtr = NULL; ioptPtr->fullNamePtr = Tcl_NewStringObj( Tcl_GetString(iclsPtr->fullNamePtr), -1); Tcl_AppendToObj(ioptPtr->fullNamePtr, "::", 2); Tcl_AppendToObj(ioptPtr->fullNamePtr, Tcl_GetString(ioptPtr->namePtr), -1); Tcl_IncrRefCount(ioptPtr->fullNamePtr); Tcl_SetHashValue(hPtr, (ClientData)ioptPtr); Itcl_PreserveData((ClientData)ioptPtr); |
︙ | ︙ | |||
2427 2428 2429 2430 2431 2432 2433 | hPtr = Tcl_FindHashEntry(&ivPtr->iclsPtr->variables, (char *)ivPtr->namePtr); if (hPtr != NULL) { Tcl_DeleteHashEntry(hPtr); } } if (ivPtr->codePtr != NULL) { | | | 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 | hPtr = Tcl_FindHashEntry(&ivPtr->iclsPtr->variables, (char *)ivPtr->namePtr); if (hPtr != NULL) { Tcl_DeleteHashEntry(hPtr); } } if (ivPtr->codePtr != NULL) { ItclReleaseMemberCode(ivPtr->codePtr); } Tcl_DecrRefCount(ivPtr->namePtr); Tcl_DecrRefCount(ivPtr->fullNamePtr); if (ivPtr->init) { Tcl_DecrRefCount(ivPtr->init); } if (ivPtr->arrayInitPtr) { |
︙ | ︙ | |||
2464 2465 2466 2467 2468 2469 2470 | if (ioptPtr->resourceNamePtr != NULL) { Tcl_DecrRefCount(ioptPtr->resourceNamePtr); } if (ioptPtr->resourceNamePtr != NULL) { Tcl_DecrRefCount(ioptPtr->classNamePtr); } | | > > | 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 | if (ioptPtr->resourceNamePtr != NULL) { Tcl_DecrRefCount(ioptPtr->resourceNamePtr); } if (ioptPtr->resourceNamePtr != NULL) { Tcl_DecrRefCount(ioptPtr->classNamePtr); } if (ioptPtr->codePtr) { ItclReleaseMemberCode(ioptPtr->codePtr); } if (ioptPtr->defaultValuePtr != NULL) { Tcl_DecrRefCount(ioptPtr->defaultValuePtr); } if (ioptPtr->cgetMethodPtr != NULL) { Tcl_DecrRefCount(ioptPtr->cgetMethodPtr); } if (ioptPtr->cgetMethodVarPtr != NULL) { |
︙ | ︙ | |||
2520 2521 2522 2523 2524 2525 2526 | hPtr = Tcl_FindHashEntry(&imPtr->iclsPtr->functions, (char *)imPtr->namePtr); if (hPtr != NULL) { Tcl_DeleteHashEntry(hPtr); } } if (imPtr->codePtr != NULL) { | | | 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 | hPtr = Tcl_FindHashEntry(&imPtr->iclsPtr->functions, (char *)imPtr->namePtr); if (hPtr != NULL) { Tcl_DeleteHashEntry(hPtr); } } if (imPtr->codePtr != NULL) { ItclReleaseMemberCode(imPtr->codePtr); } Tcl_DecrRefCount(imPtr->namePtr); Tcl_DecrRefCount(imPtr->fullNamePtr); if (imPtr->usagePtr != NULL) { Tcl_DecrRefCount(imPtr->usagePtr); } if (imPtr->argumentPtr != NULL) { |
︙ | ︙ |
Changes to generic/itclInt.h.
︙ | ︙ | |||
411 412 413 414 415 416 417 418 419 420 421 422 423 424 | Tcl_Obj *bodyPtr; /* the function body */ ItclArgList *argListPtr; /* the parsed arguments */ union { Tcl_CmdProc *argCmd; /* (argc,argv) C implementation */ Tcl_ObjCmdProc *objCmd; /* (objc,objv) C implementation */ } cfunc; ClientData clientData; /* client data for C implementations */ } ItclMemberCode; /* * Flag bits for ItclMemberCode: */ #define ITCL_IMPLEMENT_NONE 0x001 /* no implementation */ #define ITCL_IMPLEMENT_TCL 0x002 /* Tcl implementation */ | > | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | Tcl_Obj *bodyPtr; /* the function body */ ItclArgList *argListPtr; /* the parsed arguments */ union { Tcl_CmdProc *argCmd; /* (argc,argv) C implementation */ Tcl_ObjCmdProc *objCmd; /* (objc,objv) C implementation */ } cfunc; ClientData clientData; /* client data for C implementations */ int refCount; } ItclMemberCode; /* * Flag bits for ItclMemberCode: */ #define ITCL_IMPLEMENT_NONE 0x001 /* no implementation */ #define ITCL_IMPLEMENT_TCL 0x002 /* Tcl implementation */ |
︙ | ︙ | |||
683 684 685 686 687 688 689 690 691 692 693 694 695 696 | Tcl_ObjectContext contextPtr, Tcl_CallFrame *framePtr, int *isFinished); MODULE_SCOPE void ItclPreserveIMF(ItclMemberFunc *imPtr); MODULE_SCOPE void ItclReleaseIMF(ClientData imPtr); MODULE_SCOPE void ItclPreserveClass(ItclClass *iclsPtr); MODULE_SCOPE void ItclReleaseClass(ClientData iclsPtr); MODULE_SCOPE void ItclPreserveObject(ItclObject *ioPtr); MODULE_SCOPE void ItclReleaseObject(ClientData ioPtr); MODULE_SCOPE ItclFoundation *ItclGetFoundation(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc ItclClassCommandDispatcher; MODULE_SCOPE Tcl_Command Itcl_CmdAliasProc(Tcl_Interp *interp, | > > > | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 | Tcl_ObjectContext contextPtr, Tcl_CallFrame *framePtr, int *isFinished); MODULE_SCOPE void ItclPreserveIMF(ItclMemberFunc *imPtr); MODULE_SCOPE void ItclReleaseIMF(ClientData imPtr); MODULE_SCOPE void ItclPreserveClass(ItclClass *iclsPtr); MODULE_SCOPE void ItclReleaseClass(ClientData iclsPtr); MODULE_SCOPE void ItclPreserveMemberCode(ItclMemberCode *mcodePtr); MODULE_SCOPE void ItclReleaseMemberCode(ItclMemberCode *mcodePtr); MODULE_SCOPE void ItclPreserveObject(ItclObject *ioPtr); MODULE_SCOPE void ItclReleaseObject(ClientData ioPtr); MODULE_SCOPE ItclFoundation *ItclGetFoundation(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc ItclClassCommandDispatcher; MODULE_SCOPE Tcl_Command Itcl_CmdAliasProc(Tcl_Interp *interp, |
︙ | ︙ |
Changes to generic/itclMethod.c.
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | ItclArgList *realArgs); static int ItclCreateMemberCode(Tcl_Interp* interp, ItclClass *iclsPtr, const char* arglist, const char* body, ItclMemberCode** mcodePtr, Tcl_Obj *namePtr, int flags); static int ItclCreateMemberFunc(Tcl_Interp* interp, ItclClass *iclsPtr, Tcl_Obj *namePtr, const char* arglist, const char* body, ItclMemberFunc** imPtrPtr, int flags); void ItclPreserveIMF( ItclMemberFunc *imPtr) { imPtr->refCount++; } void ItclReleaseIMF( ClientData clientData) { ItclMemberFunc *imPtr = (ItclMemberFunc *)clientData; if (--imPtr->refCount == 0) { Itcl_DeleteMemberFunc(clientData); } } /* * ------------------------------------------------------------------------ * Itcl_BodyCmd() * * Invoked by Tcl whenever the user issues an "itcl::body" command to * define or redefine the implementation for a class method/proc. | > > > > > > > > > > > > > > > > > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | ItclArgList *realArgs); static int ItclCreateMemberCode(Tcl_Interp* interp, ItclClass *iclsPtr, const char* arglist, const char* body, ItclMemberCode** mcodePtr, Tcl_Obj *namePtr, int flags); static int ItclCreateMemberFunc(Tcl_Interp* interp, ItclClass *iclsPtr, Tcl_Obj *namePtr, const char* arglist, const char* body, ItclMemberFunc** imPtrPtr, int flags); void ItclFreeMemberCode (ItclMemberCode *mcodePtr); void ItclPreserveIMF( ItclMemberFunc *imPtr) { imPtr->refCount++; } void ItclReleaseIMF( ClientData clientData) { ItclMemberFunc *imPtr = (ItclMemberFunc *)clientData; if (--imPtr->refCount == 0) { Itcl_DeleteMemberFunc(clientData); } } void ItclPreserveMemberCode( ItclMemberCode *mcodePtr) { mcodePtr->refCount++; } void ItclReleaseMemberCode( ItclMemberCode *mcodePtr) { if (--mcodePtr->refCount == 0) { ItclFreeMemberCode(mcodePtr); } } /* * ------------------------------------------------------------------------ * Itcl_BodyCmd() * * Invoked by Tcl whenever the user issues an "itcl::body" command to * define or redefine the implementation for a class method/proc. |
︙ | ︙ | |||
289 290 291 292 293 294 295 | if (Itcl_CreateMemberCode(interp, iclsPtr, (char*)NULL, token, &mcode) != TCL_OK) { status = TCL_ERROR; goto configBodyCmdDone; } | | < | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | if (Itcl_CreateMemberCode(interp, iclsPtr, (char*)NULL, token, &mcode) != TCL_OK) { status = TCL_ERROR; goto configBodyCmdDone; } ItclPreserveMemberCode(mcode); if (ivPtr->codePtr) { ItclReleaseMemberCode(ivPtr->codePtr); } ivPtr->codePtr = mcode; configBodyCmdDone: Tcl_DStringFree(&buffer); return status; } |
︙ | ︙ | |||
494 495 496 497 498 499 500 | if (ItclCreateMemberCode(interp, iclsPtr, arglist, body, &mcode, namePtr, flags) != TCL_OK) { Tcl_DeleteHashEntry(hPtr); return TCL_ERROR; } | < < < > | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | if (ItclCreateMemberCode(interp, iclsPtr, arglist, body, &mcode, namePtr, flags) != TCL_OK) { Tcl_DeleteHashEntry(hPtr); return TCL_ERROR; } /* * Allocate a member function definition and return. */ imPtr = (ItclMemberFunc*)ckalloc(sizeof(ItclMemberFunc)); memset(imPtr, 0, sizeof(ItclMemberFunc)); imPtr->iclsPtr = iclsPtr; imPtr->infoPtr = iclsPtr->infoPtr; imPtr->protection = Itcl_Protection(interp, 0); imPtr->namePtr = Tcl_NewStringObj(Tcl_GetString(namePtr), -1); Tcl_IncrRefCount(imPtr->namePtr); imPtr->fullNamePtr = Tcl_NewStringObj( Tcl_GetString(iclsPtr->fullNamePtr), -1); Tcl_AppendToObj(imPtr->fullNamePtr, "::", 2); Tcl_AppendToObj(imPtr->fullNamePtr, Tcl_GetString(namePtr), -1); Tcl_IncrRefCount(imPtr->fullNamePtr); if (arglist != NULL) { imPtr->origArgsPtr = Tcl_NewStringObj(arglist, -1); Tcl_IncrRefCount(imPtr->origArgsPtr); } imPtr->codePtr = mcode; ItclPreserveMemberCode(mcode); if (imPtr->protection == ITCL_DEFAULT_PROTECT) { imPtr->protection = ITCL_PUBLIC; } imPtr->declaringClassPtr = iclsPtr; |
︙ | ︙ | |||
775 776 777 778 779 780 781 | mcode->bodyPtr = newBody; Tcl_IncrRefCount(mcode->bodyPtr); } /* * Free up the old implementation and install the new one. */ | < < | | | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | mcode->bodyPtr = newBody; Tcl_IncrRefCount(mcode->bodyPtr); } /* * Free up the old implementation and install the new one. */ ItclPreserveMemberCode(mcode); ItclReleaseMemberCode(imPtr->codePtr); imPtr->codePtr = mcode; if (mcode->flags & ITCL_IMPLEMENT_TCL) { ClientData pmPtr; imPtr->tmPtr = (ClientData)Itcl_NewProcClassMethod(interp, imPtr->iclsPtr->clsPtr, ItclCheckCallMethod, ItclAfterCallMethod, ItclProcErrorProc, imPtr, imPtr->namePtr, mcode->argumentPtr, mcode->bodyPtr, &pmPtr); |
︙ | ︙ | |||
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 | * Otherwise, treat the body as a chunk of Tcl code. */ mcode->flags |= ITCL_IMPLEMENT_TCL; } } *mcodePtr = mcode; return TCL_OK; } /* * ------------------------------------------------------------------------ * Itcl_CreateMemberCode() * * Creates the data record representing the implementation behind a * class member function. This includes the argument list and the body * of the function. If the body is of the form "@name", then it is * treated as a label for a C procedure registered by Itcl_RegisterC(). * | > | | < < | | | < | < < | | < > > > > > > > > | 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 | * Otherwise, treat the body as a chunk of Tcl code. */ mcode->flags |= ITCL_IMPLEMENT_TCL; } } *mcodePtr = mcode; return TCL_OK; } /* * ------------------------------------------------------------------------ * Itcl_CreateMemberCode() * * Creates the data record representing the implementation behind a * class member function. This includes the argument list and the body * of the function. If the body is of the form "@name", then it is * treated as a label for a C procedure registered by Itcl_RegisterC(). * * A member function definition holds a handle for the implementation, and * calls ItclReleaseMemberCode when finished with it. * * If any errors are encountered, this procedure returns TCL_ERROR * along with an error message in the interpreter. Otherwise, it * returns TCL_OK, and stores a pointer to the new implementation in * "mcodePtr". * ------------------------------------------------------------------------ */ int Itcl_CreateMemberCode( Tcl_Interp* interp, /* interpreter managing this action */ ItclClass *iclsPtr, /* class containing this member */ const char* arglist, /* space-separated list of arg names */ const char* body, /* body of commands for the method */ ItclMemberCode** mcodePtr) /* returns: pointer to new implementation */ { return ItclCreateMemberCode(interp, iclsPtr, arglist, body, mcodePtr, NULL, 0); } /* * ------------------------------------------------------------------------ * Itcl_DeleteMemberCode() * * Destroys all data associated with the given command implementation. * Invoked automatically by ItclReleaseData() when the implementation * is no longer being used. * ------------------------------------------------------------------------ */ void ItclFreeMemberCode ( ItclMemberCode* mCodePtr) { if (mCodePtr == NULL) { return; } if (mCodePtr->argListPtr != NULL) { ItclDeleteArgList(mCodePtr->argListPtr); } if (mCodePtr->usagePtr != NULL) { Tcl_DecrRefCount(mCodePtr->usagePtr); } if (mCodePtr->argumentPtr != NULL) { Tcl_DecrRefCount(mCodePtr->argumentPtr); } if (mCodePtr->bodyPtr != NULL) { Tcl_DecrRefCount(mCodePtr->bodyPtr); } /* do NOT free mCodePtr->bodyPtr here !! that is done in TclOO!! */ ckfree((char*)mCodePtr); } void Itcl_DeleteMemberCode( char* cdata) /* pointer to member code definition */ { ItclReleaseMemberCode((ItclMemberCode *)cdata); } /* * ------------------------------------------------------------------------ * Itcl_GetMemberCode() * * Makes sure that the implementation for an [incr Tcl] code body is * ready to run. Note that a member function can be declared without |
︙ | ︙ | |||
1272 1273 1274 1275 1276 1277 1278 | } mcode = imPtr->codePtr; /* * Bump the reference count on this code, in case it is * redefined or deleted during execution. */ | | | 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 | } mcode = imPtr->codePtr; /* * Bump the reference count on this code, in case it is * redefined or deleted during execution. */ ItclPreserveMemberCode(mcode); if ((imPtr->flags & ITCL_DESTRUCTOR) && (contextIoPtr != NULL)) { contextIoPtr->destructorHasBeenCalled = 1; } /* * Execute the code body... |
︙ | ︙ | |||
1310 1311 1312 1313 1314 1315 1316 | callbackPtr = Itcl_GetCurrentCallbackPtr(interp); Tcl_NRAddCallback(interp, CallItclObjectCmd, imPtr, contextIoPtr, INT2PTR(objc), (void *)objv); result = Itcl_NRRunCallbacks(interp, callbackPtr); } } | | | 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 | callbackPtr = Itcl_GetCurrentCallbackPtr(interp); Tcl_NRAddCallback(interp, CallItclObjectCmd, imPtr, contextIoPtr, INT2PTR(objc), (void *)objv); result = Itcl_NRRunCallbacks(interp, callbackPtr); } } ItclReleaseMemberCode(mcode); return result; } /* * ------------------------------------------------------------------------ * ItclEquivArgLists() * |
︙ | ︙ |