summaryrefslogtreecommitdiffstats
path: root/generic/tclOOMethod.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-09-16 18:59:14 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-09-16 18:59:14 (GMT)
commitb0e7980ba4b61bfc9867143b3a08fe0d74894690 (patch)
treebeaad334c814a35e3e90e6297ed8886ee837c853 /generic/tclOOMethod.c
parentee5dada68d84581a9b0c3ac970c11b862f0eb186 (diff)
parentfe8ae4eafcd82339318ba2c288431d00bbee06d9 (diff)
downloadtcl-b0e7980ba4b61bfc9867143b3a08fe0d74894690.zip
tcl-b0e7980ba4b61bfc9867143b3a08fe0d74894690.tar.gz
tcl-b0e7980ba4b61bfc9867143b3a08fe0d74894690.tar.bz2
merge trunk; update changes
Diffstat (limited to 'generic/tclOOMethod.c')
-rw-r--r--generic/tclOOMethod.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c
index 81293c7..61215de 100644
--- a/generic/tclOOMethod.c
+++ b/generic/tclOOMethod.c
@@ -1290,11 +1290,57 @@ CloneProcedureMethod(
ClientData *newClientData)
{
ProcedureMethod *pmPtr = clientData;
- ProcedureMethod *pm2Ptr = ckalloc(sizeof(ProcedureMethod));
+ ProcedureMethod *pm2Ptr;
+ Tcl_Obj *bodyObj, *argsObj;
+ CompiledLocal *localPtr;
+ /*
+ * Copy the argument list.
+ */
+
+ argsObj = Tcl_NewObj();
+ for (localPtr=pmPtr->procPtr->firstLocalPtr; localPtr!=NULL;
+ localPtr=localPtr->nextPtr) {
+ if (TclIsVarArgument(localPtr)) {
+ Tcl_Obj *argObj = Tcl_NewObj();
+
+ Tcl_ListObjAppendElement(NULL, argObj,
+ Tcl_NewStringObj(localPtr->name, -1));
+ if (localPtr->defValuePtr != NULL) {
+ Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
+ }
+ Tcl_ListObjAppendElement(NULL, argsObj, argObj);
+ }
+ }
+
+ /*
+ * Must strip the internal representation in order to ensure that any
+ * bound references to instance variables are removed. [Bug 3609693]
+ */
+
+ bodyObj = Tcl_DuplicateObj(pmPtr->procPtr->bodyPtr);
+ TclFreeIntRep(bodyObj);
+
+ /*
+ * Create the actual copy of the method record, manufacturing a new proc
+ * record.
+ */
+
+ pm2Ptr = ckalloc(sizeof(ProcedureMethod));
memcpy(pm2Ptr, pmPtr, sizeof(ProcedureMethod));
pm2Ptr->refCount = 1;
- pm2Ptr->procPtr->refCount++;
+ Tcl_IncrRefCount(argsObj);
+ Tcl_IncrRefCount(bodyObj);
+ if (TclCreateProc(interp, NULL, "", argsObj, bodyObj,
+ &pm2Ptr->procPtr) != TCL_OK) {
+ Tcl_DecrRefCount(argsObj);
+ Tcl_DecrRefCount(bodyObj);
+ ckfree(pm2Ptr);
+ return TCL_ERROR;
+ }
+ Tcl_DecrRefCount(argsObj);
+ Tcl_DecrRefCount(bodyObj);
+
if (pmPtr->cloneClientdataProc) {
pm2Ptr->clientData = pmPtr->cloneClientdataProc(pmPtr->clientData);
}