diff options
author | dgp <dgp@users.sourceforge.net> | 2013-07-18 20:27:01 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2013-07-18 20:27:01 (GMT) |
commit | 06b6a3eb94e2e9cd2c73e08ba68bb234bf6b6d4f (patch) | |
tree | 054d9ea09ad9e162f640d47306181917d0f14df2 /generic/tclBasic.c | |
parent | 517197f8571ca5ff1c51b2cadc771505922d9137 (diff) | |
parent | f06af4fe86a953a20b9ef90f5605331707370765 (diff) | |
download | tcl-06b6a3eb94e2e9cd2c73e08ba68bb234bf6b6d4f.zip tcl-06b6a3eb94e2e9cd2c73e08ba68bb234bf6b6d4f.tar.gz tcl-06b6a3eb94e2e9cd2c73e08ba68bb234bf6b6d4f.tar.bz2 |
Rewrite of the TclCompileScript() routine.
Primarily this breaks that large, rather convoluted routine into many
smaller more single-purpose routines for greater clarity. This also
permits more sharing of function components. Ensemble compiles now share
the same low level routines as top-level command compiles. This refactoring
should also have the benefit of easing merging between branches by better
locating patches according to what function or data structure they tweak.
Also in this checkin:
Minimized calls to Tcl_ResetResult() during compile.
Several commands compile their detected syntax errors into
bytecode that reports the syntax error.
Significant reform to the TIP 280 machinery, including elimination
of the litInfo hash table. Its function of finding the index
of a compiled command in a script from a pc value has been redone
using the codeDelta information already stored in ByteCode.
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r-- | generic/tclBasic.c | 122 |
1 files changed, 66 insertions, 56 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 1d35034..82affb0 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -1609,8 +1609,6 @@ DeleteInterpProc( ckfree(eclPtr->loc); } - Tcl_DeleteHashTable(&eclPtr->litInfo); - ckfree(eclPtr); Tcl_DeleteHashEntry(hPtr); } @@ -5617,76 +5615,88 @@ TclArgumentBCEnter( int objc, void *codePtr, CmdFrame *cfPtr, + int cmd, int pc) { + ExtCmdLoc *eclPtr; + int word; + ECL *ePtr; + CFWordBC *lastPtr = NULL; Interp *iPtr = (Interp *) interp; Tcl_HashEntry *hePtr = Tcl_FindHashEntry(iPtr->lineBCPtr, (char *) codePtr); - ExtCmdLoc *eclPtr; if (!hePtr) { return; } eclPtr = Tcl_GetHashValue(hePtr); - hePtr = Tcl_FindHashEntry(&eclPtr->litInfo, INT2PTR(pc)); - if (hePtr) { - int word; - int cmd = PTR2INT(Tcl_GetHashValue(hePtr)); - ECL *ePtr = &eclPtr->loc[cmd]; - CFWordBC *lastPtr = NULL; + ePtr = &eclPtr->loc[cmd]; - /* - * A few truths ... - * (1) ePtr->nline == objc - * (2) (ePtr->line[word] < 0) => !literal, for all words - * (3) (word == 0) => !literal - * - * Item (2) is why we can use objv to get the literals, and do not - * have to save them at compile time. - */ + /* + * ePtr->nline is the number of words originally parsed. + * + * objc is the number of elements getting invoked. + * + * If they are not the same, we arrived here by compiling an + * ensemble dispatch. Ensemble subcommands that lead to script + * evaluation are not supposed to get compiled, because a command + * such as [info level] in the script can expose some of the dispatch + * shenanigans. This means that we don't have to tend to the + * housekeeping, and can escape now. + */ + + if (ePtr->nline != objc) { + return; + } - if (ePtr->nline != objc) { - Tcl_Panic ("TIP 280 data structure inconsistency"); - } + /* + * Having disposed of the ensemble cases, we can state... + * A few truths ... + * (1) ePtr->nline == objc + * (2) (ePtr->line[word] < 0) => !literal, for all words + * (3) (word == 0) => !literal + * + * Item (2) is why we can use objv to get the literals, and do not + * have to save them at compile time. + */ - for (word = 1; word < objc; word++) { - if (ePtr->line[word] >= 0) { - int isnew; - Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(iPtr->lineLABCPtr, - objv[word], &isnew); - CFWordBC *cfwPtr = ckalloc(sizeof(CFWordBC)); - - cfwPtr->framePtr = cfPtr; - cfwPtr->obj = objv[word]; - cfwPtr->pc = pc; - cfwPtr->word = word; - cfwPtr->nextPtr = lastPtr; - lastPtr = cfwPtr; - - if (isnew) { - /* - * The word is not on the stack yet, remember the current - * location and initialize references. - */ - - cfwPtr->prevPtr = NULL; - } else { - /* - * The object is already on the stack, however it may have - * a different location now (literal sharing may map - * multiple location to a single Tcl_Obj*. Save the old - * information in the new structure. - */ - - cfwPtr->prevPtr = Tcl_GetHashValue(hPtr); - } + for (word = 1; word < objc; word++) { + if (ePtr->line[word] >= 0) { + int isnew; + Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(iPtr->lineLABCPtr, + objv[word], &isnew); + CFWordBC *cfwPtr = ckalloc(sizeof(CFWordBC)); + + cfwPtr->framePtr = cfPtr; + cfwPtr->obj = objv[word]; + cfwPtr->pc = pc; + cfwPtr->word = word; + cfwPtr->nextPtr = lastPtr; + lastPtr = cfwPtr; + + if (isnew) { + /* + * The word is not on the stack yet, remember the current + * location and initialize references. + */ - Tcl_SetHashValue(hPtr, cfwPtr); + cfwPtr->prevPtr = NULL; + } else { + /* + * The object is already on the stack, however it may have + * a different location now (literal sharing may map + * multiple location to a single Tcl_Obj*. Save the old + * information in the new structure. + */ + + cfwPtr->prevPtr = Tcl_GetHashValue(hPtr); } - } /* for */ - cfPtr->litarg = lastPtr; - } /* if */ + Tcl_SetHashValue(hPtr, cfwPtr); + } + } /* for */ + + cfPtr->litarg = lastPtr; } /* |