diff options
author | dgp <dgp@users.sourceforge.net> | 2013-09-16 18:59:14 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2013-09-16 18:59:14 (GMT) |
commit | b0e7980ba4b61bfc9867143b3a08fe0d74894690 (patch) | |
tree | beaad334c814a35e3e90e6297ed8886ee837c853 /generic/tclOOMethod.c | |
parent | ee5dada68d84581a9b0c3ac970c11b862f0eb186 (diff) | |
parent | fe8ae4eafcd82339318ba2c288431d00bbee06d9 (diff) | |
download | tcl-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.c | 50 |
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); } |