diff options
author | dgp <dgp@users.sourceforge.net> | 2016-04-29 17:34:14 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2016-04-29 17:34:14 (GMT) |
commit | 8be766f938d6042a4a05a1ddd6dcb4ec3b99f27b (patch) | |
tree | 1a8252ea3dab9eac3c8a7113e2bbb3365fe80429 | |
parent | 3bfb07250564332f61ec4e54c108735ca94f68c7 (diff) | |
download | tcl-8be766f938d6042a4a05a1ddd6dcb4ec3b99f27b.zip tcl-8be766f938d6042a4a05a1ddd6dcb4ec3b99f27b.tar.gz tcl-8be766f938d6042a4a05a1ddd6dcb4ec3b99f27b.tar.bz2 |
Refactor bytecode initialization machinery.
-rw-r--r-- | generic/tclCompile.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 002b551..8665187 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -2735,6 +2735,29 @@ TclInitByteCodeObj( iPtr = envPtr->iPtr; + for (i = 0; i < numLitObjects; i++) { + if (objPtr == TclFetchLiteral(envPtr, i)) { + /* + * Prevent circular reference where the bytecode intrep of + * a value contains a literal which is that same value. + * If this is allowed to happen, refcount decrements may not + * reach zero, and memory may leak. Bugs 467523, 3357771 + * + * NOTE: [Bugs 3392070, 3389764] We make a copy based completely + * on the string value, and do not call Tcl_DuplicateObj() so we + * can be sure we do not have any lingering cycles hiding in + * the intrep. + */ + int numBytes; + const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes); + Tcl_Obj *copyPtr = Tcl_NewStringObj(bytes, numBytes); + + Tcl_IncrRefCount(copyPtr); + TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr); + + envPtr->literalArrayPtr[i].objPtr = copyPtr; + } + } codeBytes = envPtr->codeNext - envPtr->codeStart; objArrayBytes = envPtr->literalArrayNext * sizeof(Tcl_Obj *); exceptArrayBytes = envPtr->exceptArrayNext * sizeof(ExceptionRange); @@ -2791,29 +2814,7 @@ TclInitByteCodeObj( p += TCL_ALIGN(codeBytes); /* align object array */ codePtr->objArrayPtr = (Tcl_Obj **) p; for (i = 0; i < numLitObjects; i++) { - Tcl_Obj *fetched = TclFetchLiteral(envPtr, i); - - if (objPtr == fetched) { - /* - * Prevent circular reference where the bytecode intrep of - * a value contains a literal which is that same value. - * If this is allowed to happen, refcount decrements may not - * reach zero, and memory may leak. Bugs 467523, 3357771 - * - * NOTE: [Bugs 3392070, 3389764] We make a copy based completely - * on the string value, and do not call Tcl_DuplicateObj() so we - * can be sure we do not have any lingering cycles hiding in - * the intrep. - */ - int numBytes; - const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes); - - codePtr->objArrayPtr[i] = Tcl_NewStringObj(bytes, numBytes); - Tcl_IncrRefCount(codePtr->objArrayPtr[i]); - TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr); - } else { - codePtr->objArrayPtr[i] = fetched; - } + codePtr->objArrayPtr[i] = TclFetchLiteral(envPtr, i); } p += TCL_ALIGN(objArrayBytes); /* align exception range array */ |