Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Rewrite of parts of the [switch] compiler to better use the powers of TclFindElement() and do less parsing on its own. Needs review and testing. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dgp-switch-compile |
Files: | files | file ages | folders |
SHA1: |
5f8dcf50a20d1154bad524463f42f190 |
User & Date: | dgp 2011-04-28 20:40:46 |
Context
2011-05-02
| ||
12:18 | Tighten up the patch. check-in: a4d8498860 user: dgp tags: dgp-switch-compile | |
2011-04-28
| ||
20:40 | Rewrite of parts of the [switch] compiler to better use the powers of TclFindElement() and do less p... check-in: 5f8dcf50a2 user: dgp tags: dgp-switch-compile | |
16:00 | More isspace() callers. check-in: 88095bbde0 user: dgp tags: core-8-5-branch | |
Changes
Changes to generic/tclCompCmds.c.
︙ | ︙ | |||
3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 | * there aren't any. */ int contFixCount; /* Number of continuation bodies pointing to * the current (or next) real body. */ int savedStackDepth = envPtr->currStackDepth; int noCase; /* Has the -nocase flag been given? */ int foundMode = 0; /* Have we seen a mode flag yet? */ int isListedArms = 0; int i, valueIndex; DefineLineInformation; /* TIP #280 */ int* clNext = envPtr->clNext; /* * Only handle the following versions: * switch ?--? word {pattern body ...} | > > | 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 | * there aren't any. */ int contFixCount; /* Number of continuation bodies pointing to * the current (or next) real body. */ int savedStackDepth = envPtr->currStackDepth; int noCase; /* Has the -nocase flag been given? */ int foundMode = 0; /* Have we seen a mode flag yet? */ #if 0 int isListedArms = 0; #endif int i, valueIndex; DefineLineInformation; /* TIP #280 */ int* clNext = envPtr->clNext; /* * Only handle the following versions: * switch ?--? word {pattern body ...} |
︙ | ︙ | |||
4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 | * that in the case of the quoted bodies, this is tricky as we cannot use * copies of the string from the input token for the generated tokens (it * causes a crash during exception handling). When multiple tokens are * available at this point, this is pretty easy. */ if (numWords == 1) { Tcl_DString bodyList; const char **argv = NULL, *tokenStartPtr, *p; int bline; /* TIP #280: line of the pattern/action list, * and start of list for when tracking the * location. This list comes immediately after * the value we switch on. */ int isTokenBraced; | > | 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 | * that in the case of the quoted bodies, this is tricky as we cannot use * copies of the string from the input token for the generated tokens (it * causes a crash during exception handling). When multiple tokens are * available at this point, this is pretty easy. */ if (numWords == 1) { #if 0 Tcl_DString bodyList; const char **argv = NULL, *tokenStartPtr, *p; int bline; /* TIP #280: line of the pattern/action list, * and start of list for when tracking the * location. This list comes immediately after * the value we switch on. */ int isTokenBraced; |
︙ | ︙ | |||
4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 | */ if (numWords == 0 || numWords % 2) { ckfree((char *) argv); return TCL_ERROR; } isListedArms = 1; bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * numWords); bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords); bodyLines = (int *) ckalloc(sizeof(int) * numWords); bodyNext = (int **) ckalloc(sizeof(int*) * numWords); /* * Locate the start of the arms within the overall word. | > > | 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 | */ if (numWords == 0 || numWords % 2) { ckfree((char *) argv); return TCL_ERROR; } #if 0 isListedArms = 1; #endif bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * numWords); bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords); bodyLines = (int *) ckalloc(sizeof(int) * numWords); bodyNext = (int **) ckalloc(sizeof(int*) * numWords); /* * Locate the start of the arms within the overall word. |
︙ | ︙ | |||
4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 | if (tokenStartPtr != tokenPtr[1].start+tokenPtr[1].size) { ckfree((char *) bodyToken); ckfree((char *) bodyTokenArray); ckfree((char *) bodyLines); ckfree((char *) bodyNext); return TCL_ERROR; } } else if (numWords % 2 || numWords == 0) { /* * Odd number of words (>1) available, or no words at all available. * Both are error cases, so punt and let the interpreted-version * generate the error message. Note that the second case probably * should get caught earlier, but it's easy to check here again anyway | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 | if (tokenStartPtr != tokenPtr[1].start+tokenPtr[1].size) { ckfree((char *) bodyToken); ckfree((char *) bodyTokenArray); ckfree((char *) bodyLines); ckfree((char *) bodyNext); return TCL_ERROR; } #else CONST char *bytes, *p; int maxLen, braced, numBytes; int bline; /* TIP #280: line of the pattern/action list, * and start of list for when tracking the * location. This list comes immediately after * the value we switch on. */ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } bytes = tokenPtr[1].start; numBytes = tokenPtr[1].size; /* * A list can have at most one more element than the number * of runs of element-separating white space. */ maxLen = TclCountSpaceRuns(bytes, numBytes, NULL) + 1; if (maxLen < 2) { return TCL_ERROR; } bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * maxLen); bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * maxLen); bodyLines = (int *) ckalloc(sizeof(int) * maxLen); bodyNext = (int **) ckalloc(sizeof(int*) * maxLen); bline = mapPtr->loc[eclIndex].line[valueIndex+1]; p = bytes; numWords = 0; while (numBytes > 0) { CONST char *start, *prevBytes = bytes; int size; if (TCL_OK != TclFindElement(NULL, bytes, numBytes, &start, &bytes, &size, &braced)) { abort: ckfree((char *) bodyToken); ckfree((char *) bodyTokenArray); ckfree((char *) bodyLines); ckfree((char *) bodyNext); return TCL_ERROR; } numBytes -= (bytes - prevBytes); if (numWords == 0 && numBytes == 0) { break; } bodyTokenArray[numWords].type = TCL_TOKEN_TEXT; bodyTokenArray[numWords].start = start; bodyTokenArray[numWords].size = size; bodyTokenArray[numWords].numComponents = 0; bodyToken[numWords] = bodyTokenArray + numWords; if (!braced) { while (size--) { if (*start++ == '\\') { goto abort; } } } /* * TIP #280: Now determine the line the list element starts on * (there is no need to do it earlier, due to the possibility of * aborting, see above). */ TclAdvanceLines(&bline, p, bodyTokenArray[numWords].start); TclAdvanceContinuations (&bline, &clNext, bodyTokenArray[numWords].start - envPtr->source); bodyLines[numWords] = bline; bodyNext[numWords] = clNext; p = bodyTokenArray[numWords].start; numWords++; } if (numWords % 2) { goto abort; } #endif } else if (numWords % 2 || numWords == 0) { /* * Odd number of words (>1) available, or no words at all available. * Both are error cases, so punt and let the interpreted-version * generate the error message. Note that the second case probably * should get caught earlier, but it's easy to check here again anyway |
︙ | ︙ | |||
4201 4202 4203 4204 4205 4206 4207 | for (i=0 ; i<numWords ; i++) { /* * We only handle the very simplest case. Anything more complex is * a good reason to go to the interpreted case anyway due to * traces, etc. */ | | > | > > | 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 | for (i=0 ; i<numWords ; i++) { /* * We only handle the very simplest case. Anything more complex is * a good reason to go to the interpreted case anyway due to * traces, etc. */ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD #if 0 || tokenPtr->numComponents != 1 #endif ) { ckfree((char *) bodyToken); ckfree((char *) bodyLines); ckfree((char *) bodyNext); return TCL_ERROR; } bodyToken[i] = tokenPtr+1; |
︙ | ︙ | |||
4251 4252 4253 4254 4255 4256 4257 | /* * Check if we can generate a jump table, since if so that's faster than * doing an explicit compare with each body. Note that we're definitely * over-conservative with determining whether we can do the jump table, * but it handles the most common case well enough. */ | > > > > | > > > > | 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 | /* * Check if we can generate a jump table, since if so that's faster than * doing an explicit compare with each body. Note that we're definitely * over-conservative with determining whether we can do the jump table, * but it handles the most common case well enough. */ if ( #if 0 isListedArms && #endif mode == Switch_Exact #if 0 && !noCase #endif ) { JumptableInfo *jtPtr; int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation; int mustGenerate, jumpToDefault; Tcl_DString buffer; Tcl_HashEntry *hPtr; /* |
︙ | ︙ |