Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new ICL mechanism (TIP 280+530 replacement) v3, partial string segments back-port #6

Open
wants to merge 16 commits into
base: core-8-6-branch
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
d7738cc
eliminate iPtr->lineBCPtr hash table (replaced with reference in BCEx…
sebres May 31, 2019
7b2d534
eliminate iPtr->linePBodyPtr hash table (replaced with reference cfPt…
sebres Jun 3, 2019
3fff9dd
**interim commit** try to cherry-pick and back-port from future branc…
sebres Jun 3, 2019
a9401c5
review (small fixes after back-porting)
sebres Jun 18, 2019
e6f9b97
fixed wrapping to the code segment object (info.test)
sebres Jun 24, 2019
58c7906
introduced new function to check obj has bytes (now also if obj->byte…
sebres Jun 24, 2019
179e582
fixed encoding.test (allow sharing of small literals)
sebres Jun 24, 2019
5411275
fixed compile lambda and CompileSubstObj - share segment of compiled …
sebres Sep 16, 2019
fa49025
TclContinuationsEnter/TclContinuationsGet rewritten without cont-line…
sebres Sep 18, 2019
f62058b
fix segment handling in lists and extended TclGetStringSegmentFromObj…
sebres Sep 18, 2019
f80a3ec
info.test: fixed mistakenly recognized (artificial) line in info-30.1…
sebres Sep 18, 2019
5faa305
**temp commit** several fixes, review needed (**SF/BO** in string.tes…
sebres Sep 18, 2019
9ba9f32
list internals obtain only ICL now (no sharing of string segment poss…
sebres Sep 18, 2019
0b8156a
stability fix - be sure TclGetStringSegmentFromObj with TCLSEG_FULL_S…
sebres Sep 18, 2019
d92408b
code cleanup (removed unused code and old unneeded handling)
sebres Mar 12, 2020
4c47fbe
review: remove forgotten debugging stuff (no functional changes)
sebres Oct 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions generic/tcl.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,10 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
#else
typedef struct stat Tcl_StatBuf;
#endif

#ifndef TCL_HASH_TYPE
# define TCL_HASH_TYPE unsigned
#endif

/*
*----------------------------------------------------------------------------
Expand Down
48 changes: 12 additions & 36 deletions generic/tclAssembly.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,6 @@ static int CreateMirrorJumpTable(AssemblyEnv* assemEnvPtr,
static int FindLocalVar(AssemblyEnv* envPtr,
Tcl_Token** tokenPtrPtr);
static int FinishAssembly(AssemblyEnv*);
static void FreeAssembleCodeInternalRep(Tcl_Obj *objPtr);
static void FreeAssemblyEnv(AssemblyEnv*);
static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*);
static int GetListIndexOperand(AssemblyEnv*, Tcl_Token**, int*);
Expand Down Expand Up @@ -319,7 +318,7 @@ static void UnstackExpiredCatches(CompileEnv*, BasicBlock*, int,

static const Tcl_ObjType assembleCodeType = {
"assemblecode",
FreeAssembleCodeInternalRep, /* freeIntRepProc */
TclFreeByteCodeInternalRep, /* freeIntRepProc */
DupAssembleCodeInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
NULL /* setFromAnyProc */
Expand Down Expand Up @@ -847,8 +846,11 @@ CompileAssembleObj(
int status; /* Status return from Tcl_AssembleCode */
const char* source; /* String representation of the source code */
int sourceLen; /* Length of the source code in bytes */
StringSegment *strSegPtr;


source = Tcl_GetUtfFromObj(objPtr, &sourceLen);

/*
* Get the expression ByteCode from the object. If it exists, make sure it
* is valid in the current context.
Expand All @@ -867,18 +869,23 @@ CompileAssembleObj(
}

/*
* Not valid, so free it and regenerate.
* Not valid, so obtain string segment, free code and regenerate.
*/

FreeAssembleCodeInternalRep(objPtr);
strSegPtr = codePtr->strSegPtr;
strSegPtr->refCount++;
TclInvalidateByteCodeInternalRep(objPtr);
} else {
strSegPtr = TclGetStringSegmentFromObj(objPtr, 0);
strSegPtr->refCount++;
}

/*
* Set up the compilation environment, and assemble the code.
*/

source = TclGetStringFromObj(objPtr, &sourceLen);
TclInitCompileEnv(interp, &compEnv, source, sourceLen, NULL, 0);
compEnv.strSegPtr = strSegPtr;
status = TclAssembleCode(&compEnv, source, sourceLen, TCL_EVAL_DIRECT);
if (status != TCL_OK) {
/*
Expand Down Expand Up @@ -4312,37 +4319,6 @@ DupAssembleCodeInternalRep(
return;
}

/*
*-----------------------------------------------------------------------------
*
* FreeAssembleCodeInternalRep --
*
* Part of the Tcl object type implementation for Tcl expression
* bytecode. Frees the storage allocated to hold the internal rep, unless
* ref counts indicate bytecode execution is still in progress.
*
* Results:
* None.
*
* Side effects:
* May free allocated memory. Leaves objPtr untyped.
*
*-----------------------------------------------------------------------------
*/

static void
FreeAssembleCodeInternalRep(
Tcl_Obj *objPtr)
{
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;

codePtr->refCount--;
if (codePtr->refCount <= 0) {
TclCleanupByteCode(codePtr);
}
objPtr->typePtr = NULL;
}

/*
* Local Variables:
* mode: c
Expand Down
69 changes: 5 additions & 64 deletions generic/tclBasic.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,12 +540,8 @@ Tcl_CreateInterp(void)
*/

iPtr->cmdFramePtr = NULL;
iPtr->linePBodyPtr = ckalloc(sizeof(Tcl_HashTable));
iPtr->lineBCPtr = ckalloc(sizeof(Tcl_HashTable));
iPtr->lineLAPtr = ckalloc(sizeof(Tcl_HashTable));
iPtr->lineLABCPtr = ckalloc(sizeof(Tcl_HashTable));
Tcl_InitHashTable(iPtr->linePBodyPtr, TCL_ONE_WORD_KEYS);
Tcl_InitHashTable(iPtr->lineBCPtr, TCL_ONE_WORD_KEYS);
Tcl_InitHashTable(iPtr->lineLAPtr, TCL_ONE_WORD_KEYS);
Tcl_InitHashTable(iPtr->lineLABCPtr, TCL_ONE_WORD_KEYS);
iPtr->scriptCLLocPtr = NULL;
Expand Down Expand Up @@ -1388,7 +1384,6 @@ DeleteInterpProc(
Tcl_HashSearch search;
Tcl_HashTable *hTablePtr;
ResolverScheme *resPtr, *nextResPtr;
int i;

/*
* Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup,
Expand Down Expand Up @@ -1587,58 +1582,6 @@ DeleteInterpProc(

TclDeleteLiteralTable(interp, &iPtr->literalTable);

/*
* TIP #280 - Release the arrays for ByteCode/Proc extension, and
* contents.
*/

for (hPtr = Tcl_FirstHashEntry(iPtr->linePBodyPtr, &search);
hPtr != NULL;
hPtr = Tcl_NextHashEntry(&search)) {
CmdFrame *cfPtr = Tcl_GetHashValue(hPtr);
Proc *procPtr = (Proc *) Tcl_GetHashKey(iPtr->linePBodyPtr, hPtr);

procPtr->iPtr = NULL;
if (cfPtr) {
if (cfPtr->type == TCL_LOCATION_SOURCE) {
Tcl_DecrRefCount(cfPtr->data.eval.path);
}
ckfree(cfPtr->line);
ckfree(cfPtr);
}
Tcl_DeleteHashEntry(hPtr);
}
Tcl_DeleteHashTable(iPtr->linePBodyPtr);
ckfree(iPtr->linePBodyPtr);
iPtr->linePBodyPtr = NULL;

/*
* See also tclCompile.c, TclCleanupByteCode
*/

for (hPtr = Tcl_FirstHashEntry(iPtr->lineBCPtr, &search);
hPtr != NULL;
hPtr = Tcl_NextHashEntry(&search)) {
ExtCmdLoc *eclPtr = Tcl_GetHashValue(hPtr);

if (eclPtr->type == TCL_LOCATION_SOURCE) {
Tcl_DecrRefCount(eclPtr->path);
}
for (i=0; i< eclPtr->nuloc; i++) {
ckfree(eclPtr->loc[i].line);
}

if (eclPtr->loc != NULL) {
ckfree(eclPtr->loc);
}

ckfree(eclPtr);
Tcl_DeleteHashEntry(hPtr);
}
Tcl_DeleteHashTable(iPtr->lineBCPtr);
ckfree(iPtr->lineBCPtr);
iPtr->lineBCPtr = NULL;

/*
* Location stack for uplevel/eval/... scripts which were passed through
* proc arguments. Actually we track all arguments as we do not and cannot
Expand Down Expand Up @@ -5719,19 +5662,17 @@ TclArgumentBCEnter(
int cmd,
int pc)
{
ExtCmdLoc *eclPtr;
BCExtLineInfo *bcLI;
int word;
ECL *ePtr;
CFWordBC *lastPtr = NULL;
Interp *iPtr = (Interp *) interp;
Tcl_HashEntry *hePtr =
Tcl_FindHashEntry(iPtr->lineBCPtr, (char *) codePtr);

if (!hePtr) {
bcLI = TclByteCodeGetELI((ByteCode *)codePtr);
if (!bcLI || !bcLI->eclPtr) {
return;
}
eclPtr = Tcl_GetHashValue(hePtr);
ePtr = &eclPtr->loc[cmd];
ePtr = &bcLI->eclPtr->loc[cmd];

/*
* ePtr->nline is the number of words originally parsed.
Expand Down Expand Up @@ -5887,7 +5828,7 @@ TclArgumentGet(
* up by the caller. It knows better than us.
*/

if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) {
if (!Tcl_ObjHasBytes(obj) || TclListObjIsCanonical(obj)) {
return;
}

Expand Down
32 changes: 17 additions & 15 deletions generic/tclCmdMZ.c
Original file line number Diff line number Diff line change
Expand Up @@ -5455,27 +5455,28 @@ TclNRWhileObjCmd(
*
* TclListLines --
*
* ???
* Retrieve line(s) inside of given listObj from its source considering
* continuations.
*
* Results:
* Filled in array of line numbers?
* Last line found, filled in array of line numbers if not NULL.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/

void
int
TclListLines(
Tcl_Obj *listObj, /* Pointer to obj holding a string with list
* structure. Assumed to be valid. Assumed to
* contain n elements. */
int line, /* Line the list as a whole starts on. */
int n, /* #elements in lines */
int *lines, /* Array of line numbers, to fill. */
int *lines, /* Array of line numbers, to fill (or NULL). */
Tcl_Obj *const *elems) /* The list elems as Tcl_Obj*, in need of
* derived continuation data */
* derived continuation data (or NULL) */
{
const char *listStr = Tcl_GetString(listObj);
const char *listHead = listStr;
Expand All @@ -5484,26 +5485,27 @@ TclListLines(
ContLineLoc *clLocPtr = TclContinuationsGet(listObj);
int *clNext = (clLocPtr ? &clLocPtr->loc[0] : NULL);

for (i = 0; i < n; i++) {
n--;
for (i = 0; i <= n; i++) {
TclFindElement(NULL, listStr, length, &element, &next, NULL, NULL);

TclAdvanceLines(&line, listStr, element);
/* Leading whitespace */
TclAdvanceLines(&line, listStr, element); /* Leading whitespace */
TclAdvanceContinuations(&line, &clNext, element - listHead);
if (elems && clNext) {
TclContinuationsEnterDerived(elems[i], element-listHead, clNext);
}
lines[i] = line;
length -= (next - listStr);
TclAdvanceLines(&line, element, next);
/* Element */
listStr = next;

if (*element == 0) {
if (lines) {
lines[i] = line;
}
if (*element == 0 || i == n) {
/* ASSERT i == n */
break;
}
length -= (next - listStr);
TclAdvanceLines(&line, element, next); /* Element */
listStr = next;
}
return line;
}

/*
Expand Down
Loading