summaryrefslogtreecommitdiffstats
path: root/generic/tclCompile.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-04-29 17:52:30 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-04-29 17:52:30 (GMT)
commit9c0f41cddeb0177e88e3c3f378ab16ef7a5c9b96 (patch)
treed12a2296ec5dfd43ded49c1454b5747e23adc4f3 /generic/tclCompile.c
parent012caa867f6ba20a1a88d7d71a9a1cfea749930d (diff)
downloadtcl-9c0f41cddeb0177e88e3c3f378ab16ef7a5c9b96.zip
tcl-9c0f41cddeb0177e88e3c3f378ab16ef7a5c9b96.tar.gz
tcl-9c0f41cddeb0177e88e3c3f378ab16ef7a5c9b96.tar.bz2
Tease apart the bytecode creation machinery from the Tcl_Obj intrep machinery.
Diffstat (limited to 'generic/tclCompile.c')
-rw-r--r--generic/tclCompile.c92
1 files changed, 57 insertions, 35 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 8665187..8837f06 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -2709,33 +2709,14 @@ TclCompileNoOp(
*----------------------------------------------------------------------
*/
-void
-TclInitByteCodeObj(
- Tcl_Obj *objPtr, /* Points object that should be initialized,
- * and whose string rep contains the source
- * code. */
- register CompileEnv *envPtr)/* Points to the CompileEnv structure from
- * which to create a ByteCode structure. */
+static void
+PreventCycle(
+ Tcl_Obj *objPtr,
+ CompileEnv *envPtr)
{
- register ByteCode *codePtr;
- size_t codeBytes, objArrayBytes, exceptArrayBytes, cmdLocBytes;
- size_t auxDataArrayBytes, structureSize;
- register unsigned char *p;
-#ifdef TCL_COMPILE_DEBUG
- unsigned char *nextPtr;
-#endif
- int numLitObjects = envPtr->literalArrayNext;
- Namespace *namespacePtr;
- int i, isNew;
- Interp *iPtr;
-
- if (envPtr->iPtr == NULL) {
- Tcl_Panic("TclInitByteCodeObj() called on uninitialized CompileEnv");
- }
-
- iPtr = envPtr->iPtr;
+ int i;
- for (i = 0; i < numLitObjects; i++) {
+ for (i = 0; i < envPtr->literalArrayNext; i++) {
if (objPtr == TclFetchLiteral(envPtr, i)) {
/*
* Prevent circular reference where the bytecode intrep of
@@ -2753,11 +2734,36 @@ TclInitByteCodeObj(
Tcl_Obj *copyPtr = Tcl_NewStringObj(bytes, numBytes);
Tcl_IncrRefCount(copyPtr);
- TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr);
+ TclReleaseLiteral((Tcl_Interp *)envPtr->iPtr, objPtr);
envPtr->literalArrayPtr[i].objPtr = copyPtr;
}
}
+}
+
+static ByteCode *
+TclInitByteCode(
+ register CompileEnv *envPtr)/* Points to the CompileEnv structure from
+ * which to create a ByteCode structure. */
+{
+ register ByteCode *codePtr;
+ size_t codeBytes, objArrayBytes, exceptArrayBytes, cmdLocBytes;
+ size_t auxDataArrayBytes, structureSize;
+ register unsigned char *p;
+#ifdef TCL_COMPILE_DEBUG
+ unsigned char *nextPtr;
+#endif
+ int numLitObjects = envPtr->literalArrayNext;
+ Namespace *namespacePtr;
+ int i, isNew;
+ Interp *iPtr;
+
+ if (envPtr->iPtr == NULL) {
+ Tcl_Panic("TclInitByteCodeObj() called on uninitialized CompileEnv");
+ }
+
+ iPtr = envPtr->iPtr;
+
codeBytes = envPtr->codeNext - envPtr->codeStart;
objArrayBytes = envPtr->literalArrayNext * sizeof(Tcl_Obj *);
exceptArrayBytes = envPtr->exceptArrayNext * sizeof(ExceptionRange);
@@ -2857,15 +2863,6 @@ TclInitByteCodeObj(
#endif /* TCL_COMPILE_STATS */
/*
- * Free the old internal rep then convert the object to a bytecode object
- * by making its internal rep point to the just compiled ByteCode.
- */
-
- TclFreeIntRep(objPtr);
- objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
- objPtr->typePtr = &tclByteCodeType;
-
- /*
* TIP #280. Associate the extended per-word line information with the
* byte code object (internal rep), for use with the bc compiler.
*/
@@ -2878,6 +2875,31 @@ TclInitByteCodeObj(
envPtr->iPtr = NULL;
codePtr->localCachePtr = NULL;
+ return codePtr;
+}
+
+void
+TclInitByteCodeObj(
+ Tcl_Obj *objPtr, /* Points object that should be initialized,
+ * and whose string rep contains the source
+ * code. */
+ register CompileEnv *envPtr)/* Points to the CompileEnv structure from
+ * which to create a ByteCode structure. */
+{
+ ByteCode *codePtr;
+
+ PreventCycle(objPtr, envPtr);
+
+ codePtr = TclInitByteCode(envPtr);
+
+ /*
+ * Free the old internal rep then convert the object to a bytecode object
+ * by making its internal rep point to the just compiled ByteCode.
+ */
+
+ TclFreeIntRep(objPtr);
+ objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
+ objPtr->typePtr = &tclByteCodeType;
}
/*