~peter-pearse/ubuntu/natty/tcl8.5/prop001

« back to all changes in this revision

Viewing changes to generic/tclCompCmds.c

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-11-22 14:23:53 UTC
  • mfrom: (10.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20091122142353-a0awlv6cays5y50f
Tags: 8.5.8-2
Fixed building on MIPS architectures. The upstream changes in 8.5.8
include changing FPU settings which isn't possible in Debian GNU/Linux
(and isn't required also).

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 * See the file "license.terms" for information on usage and redistribution of
13
13
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
14
14
 *
15
 
 * RCS: @(#) $Id: tclCompCmds.c,v 1.143.2.1 2008/05/07 10:39:38 dkf Exp $
 
15
 * RCS: @(#) $Id: tclCompCmds.c,v 1.143.2.2 2009/08/25 21:01:05 andreas_kupries Exp $
16
16
 */
17
17
 
18
18
#include "tclInt.h"
31
31
        TclEmitPush(TclRegisterNewLiteral((envPtr), (tokenPtr)[1].start, \
32
32
                (tokenPtr)[1].size), (envPtr)); \
33
33
    } else { \
34
 
        envPtr->line = mapPtr->loc[eclIndex].line[word]; \
 
34
        envPtr->line   = mapPtr->loc[eclIndex].line[word]; \
 
35
        envPtr->clNext = mapPtr->loc[eclIndex].next[word]; \
35
36
        TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
36
37
                (envPtr)); \
37
38
    }
49
50
    ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \
50
51
    int eclIndex = mapPtr->nuloc - 1
51
52
 
 
53
#define SetLineInformation(word) \
 
54
    envPtr->line   = mapPtr->loc [eclIndex].line [(word)]; \
 
55
    envPtr->clNext = mapPtr->loc [eclIndex].next [(word)]
 
56
 
52
57
/*
53
58
 * Convenience macro for use when compiling bodies of commands. The ANSI C
54
59
 * "prototype" for this macro is:
152
157
static int              PushVarName(Tcl_Interp *interp,
153
158
                            Tcl_Token *varTokenPtr, CompileEnv *envPtr,
154
159
                            int flags, int *localIndexPtr,
155
 
                            int *simpleVarNamePtr, int *isScalarPtr, int line);
 
160
                            int *simpleVarNamePtr, int *isScalarPtr,
 
161
                            int line, int* clNext);
156
162
static int              CompileAssociativeBinaryOpCmd(Tcl_Interp *interp,
157
163
                            Tcl_Parse *parsePtr, const char *identity,
158
164
                            int instruction, CompileEnv *envPtr);
169
175
                            unsigned char op, int code, int level,
170
176
                            Tcl_Obj *returnOpts);
171
177
 
 
178
#define PushVarNameWord(i,v,e,f,l,s,sc,word) \
 
179
    PushVarName (i,v,e,f,l,s,sc,                       \
 
180
                    mapPtr->loc [eclIndex].line [(word)], \
 
181
                    mapPtr->loc [eclIndex].next [(word)])
 
182
 
172
183
/*
173
184
 * Flags bits used by PushVarName.
174
185
 */
259
270
 
260
271
    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
261
272
 
262
 
    PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
263
 
                &localIndex, &simpleVarName, &isScalar,
264
 
                mapPtr->loc[eclIndex].line[1]);
 
273
    PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
 
274
                    &localIndex, &simpleVarName, &isScalar, 1);
265
275
 
266
276
    /*
267
277
     * We are doing an assignment, otherwise TclCompileSetCmd was called, so
449
459
     * range so that errors in the substitution are not catched [Bug 219184]
450
460
     */
451
461
 
452
 
    envPtr->line = mapPtr->loc[eclIndex].line[1];
 
462
    SetLineInformation (1);
453
463
    if (cmdTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
454
464
        ExceptionRangeStarts(envPtr, range);
455
465
        CompileBody(envPtr, cmdTokenPtr, interp);
921
931
     * Compile the loop body itself. It should be stack-neutral.
922
932
     */
923
933
 
924
 
    envPtr->line = mapPtr->loc[eclIndex].line[4];
 
934
    SetLineInformation (4);
925
935
    CompileBody(envPtr, bodyTokenPtr, interp);
926
936
    TclEmitOpcode(   INST_POP,                                  envPtr);
927
937
 
1447
1457
     * Inline compile the initial command.
1448
1458
     */
1449
1459
 
1450
 
    envPtr->line = mapPtr->loc[eclIndex].line[1];
 
1460
    SetLineInformation (1);
1451
1461
    CompileBody(envPtr, startTokenPtr, interp);
1452
1462
    TclEmitOpcode(INST_POP, envPtr);
1453
1463
 
1470
1480
     */
1471
1481
 
1472
1482
    bodyCodeOffset = ExceptionRangeStarts(envPtr, bodyRange);
1473
 
    envPtr->line = mapPtr->loc[eclIndex].line[4];
 
1483
    SetLineInformation (4);
1474
1484
    CompileBody(envPtr, bodyTokenPtr, interp);
1475
1485
    ExceptionRangeEnds(envPtr, bodyRange);
1476
1486
    envPtr->currStackDepth = savedStackDepth + 1;
1482
1492
 
1483
1493
    envPtr->currStackDepth = savedStackDepth;
1484
1494
    nextCodeOffset = ExceptionRangeStarts(envPtr, nextRange);
1485
 
    envPtr->line = mapPtr->loc[eclIndex].line[3];
 
1495
    SetLineInformation (3);
1486
1496
    CompileBody(envPtr, nextTokenPtr, interp);
1487
1497
    ExceptionRangeEnds(envPtr, nextRange);
1488
1498
    envPtr->currStackDepth = savedStackDepth + 1;
1503
1513
        testCodeOffset += 3;
1504
1514
    }
1505
1515
 
1506
 
    envPtr->line = mapPtr->loc[eclIndex].line[2];
 
1516
    SetLineInformation (2);
1507
1517
    envPtr->currStackDepth = savedStackDepth;
1508
1518
    TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
1509
1519
    envPtr->currStackDepth = savedStackDepth + 1;
1753
1763
            i < numWords-1;
1754
1764
            i++, tokenPtr = TokenAfter(tokenPtr)) {
1755
1765
        if ((i%2 == 0) && (i > 0)) {
1756
 
            envPtr->line = mapPtr->loc[eclIndex].line[i];
 
1766
            SetLineInformation (i);
1757
1767
            CompileTokens(envPtr, tokenPtr, interp);
1758
1768
            tempVar = (firstValueTemp + loopIndex);
1759
1769
            if (tempVar <= 255) {
1785
1795
     * Inline compile the loop body.
1786
1796
     */
1787
1797
 
1788
 
    envPtr->line = mapPtr->loc[eclIndex].line[bodyIndex];
 
1798
    SetLineInformation (bodyIndex);
1789
1799
    ExceptionRangeStarts(envPtr, range);
1790
1800
    CompileBody(envPtr, bodyTokenPtr, interp);
1791
1801
    ExceptionRangeEnds(envPtr, range);
2124
2134
                    compileScripts = 0;
2125
2135
                }
2126
2136
            } else {
2127
 
                envPtr->line = mapPtr->loc[eclIndex].line[wordIdx];
 
2137
                SetLineInformation (wordIdx);
2128
2138
                Tcl_ResetResult(interp);
2129
2139
                TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
2130
2140
                if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
2166
2176
         */
2167
2177
 
2168
2178
        if (compileScripts) {
2169
 
            envPtr->line = mapPtr->loc[eclIndex].line[wordIdx];
 
2179
            SetLineInformation (wordIdx);
2170
2180
            envPtr->currStackDepth = savedStackDepth;
2171
2181
            CompileBody(envPtr, tokenPtr, interp);
2172
2182
        }
2254
2264
             * Compile the else command body.
2255
2265
             */
2256
2266
 
2257
 
            envPtr->line = mapPtr->loc[eclIndex].line[wordIdx];
 
2267
            SetLineInformation (wordIdx);
2258
2268
            CompileBody(envPtr, tokenPtr, interp);
2259
2269
        }
2260
2270
 
2356
2366
 
2357
2367
    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
2358
2368
 
2359
 
    PushVarName(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX|TCL_CREATE_VAR,
2360
 
                &localIndex, &simpleVarName, &isScalar,
2361
 
                mapPtr->loc[eclIndex].line[1]);
 
2369
    PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX|TCL_CREATE_VAR,
 
2370
                    &localIndex, &simpleVarName, &isScalar, 1);
2362
2371
 
2363
2372
    /*
2364
2373
     * If an increment is given, push it, but see first if it's a small
2384
2393
                PushLiteral(envPtr, word, numBytes);
2385
2394
            }
2386
2395
        } else {
2387
 
            envPtr->line = mapPtr->loc[eclIndex].line[2];
 
2396
            SetLineInformation (2);
2388
2397
            CompileTokens(envPtr, incrTokenPtr, interp);
2389
2398
        }
2390
2399
    } else {                    /* No incr amount given so use 1. */
2499
2508
 
2500
2509
    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
2501
2510
 
2502
 
    PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
2503
 
                &localIndex, &simpleVarName, &isScalar,
2504
 
                mapPtr->loc[eclIndex].line[1]);
 
2511
    PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
 
2512
                    &localIndex, &simpleVarName, &isScalar, 1);
2505
2513
 
2506
2514
    /*
2507
2515
     * If we are doing an assignment, push the new value. In the no values
2606
2614
         * Generate the next variable name.
2607
2615
         */
2608
2616
 
2609
 
        PushVarName(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex,
2610
 
                &simpleVarName, &isScalar, mapPtr->loc[eclIndex].line[idx+2]);
 
2617
        PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex,
 
2618
                        &simpleVarName, &isScalar, idx+2);
2611
2619
 
2612
2620
        /*
2613
2621
         * Emit instructions to get the idx'th item out of the list value on
2943
2951
     */
2944
2952
 
2945
2953
    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
2946
 
    PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
2947
 
                &localIndex, &simpleVarName, &isScalar,
2948
 
                mapPtr->loc[eclIndex].line[1]);
 
2954
    PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
 
2955
                    &localIndex, &simpleVarName, &isScalar, 1);
2949
2956
 
2950
2957
    /*
2951
2958
     * Push the "index" args and the new element value.
3445
3452
     */
3446
3453
 
3447
3454
    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
3448
 
    PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
3449
 
                &localIndex, &simpleVarName, &isScalar,
3450
 
                mapPtr->loc[eclIndex].line[1]);
 
3455
    PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
 
3456
                    &localIndex, &simpleVarName, &isScalar, 1);
3451
3457
 
3452
3458
    /*
3453
3459
     * If we are doing an assignment, push the new value.
3728
3734
            }
3729
3735
            PushLiteral(envPtr, str, length);
3730
3736
        } else {
3731
 
            envPtr->line = mapPtr->loc[eclIndex].line[i+1+nocase];
 
3737
            SetLineInformation (i+1+nocase);
3732
3738
            CompileTokens(envPtr, tokenPtr, interp);
3733
3739
        }
3734
3740
        tokenPtr = TokenAfter(tokenPtr);
3794
3800
        len = sprintf(buf, "%d", len);
3795
3801
        PushLiteral(envPtr, buf, len);
3796
3802
    } else {
3797
 
        envPtr->line = mapPtr->loc[eclIndex].line[1];
 
3803
        SetLineInformation (1);
3798
3804
        CompileTokens(envPtr, tokenPtr, interp);
3799
3805
        TclEmitOpcode(INST_STR_LEN, envPtr);
3800
3806
    }
3844
3850
    Tcl_Token **bodyToken;      /* Array of pointers to pattern list items. */
3845
3851
    int *bodyLines;             /* Array of line numbers for body list
3846
3852
                                 * items. */
 
3853
    int** bodyNext;
3847
3854
    int foundDefault;           /* Flag to indicate whether a "default" clause
3848
3855
                                 * is present. */
3849
3856
 
3862
3869
    int isListedArms = 0;
3863
3870
    int i, valueIndex;
3864
3871
    DefineLineInformation;      /* TIP #280 */
 
3872
    int* clNext = envPtr->clNext;
3865
3873
 
3866
3874
    /*
3867
3875
     * Only handle the following versions:
4040
4048
        bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * numWords);
4041
4049
        bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords);
4042
4050
        bodyLines = (int *) ckalloc(sizeof(int) * numWords);
 
4051
        bodyNext  = (int **) ckalloc(sizeof(int*) * numWords);
4043
4052
 
4044
4053
        /*
4045
4054
         * Locate the start of the arms within the overall word.
4083
4092
                ckfree((char *) bodyToken);
4084
4093
                ckfree((char *) bodyTokenArray);
4085
4094
                ckfree((char *) bodyLines);
 
4095
                ckfree((char *) bodyNext);
4086
4096
                return TCL_ERROR;
4087
4097
            }
4088
4098
 
4093
4103
             */
4094
4104
 
4095
4105
            TclAdvanceLines(&bline, p, bodyTokenArray[i].start);
 
4106
            TclAdvanceContinuations (&bline, &clNext,
 
4107
                                 bodyTokenArray[i].start - envPtr->source);
4096
4108
            bodyLines[i] = bline;
 
4109
            bodyNext[i] = clNext;
4097
4110
            p = bodyTokenArray[i].start;
4098
4111
 
4099
4112
            while (isspace(UCHAR(*tokenStartPtr))) {
4121
4134
            ckfree((char *) bodyToken);
4122
4135
            ckfree((char *) bodyTokenArray);
4123
4136
            ckfree((char *) bodyLines);
 
4137
            ckfree((char *) bodyNext);
4124
4138
            return TCL_ERROR;
4125
4139
        }
4126
4140
 
4141
4155
 
4142
4156
        bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords);
4143
4157
        bodyLines = (int *) ckalloc(sizeof(int) * numWords);
 
4158
        bodyNext  = (int **) ckalloc(sizeof(int*) * numWords);
4144
4159
        bodyTokenArray = NULL;
4145
4160
        for (i=0 ; i<numWords ; i++) {
4146
4161
            /*
4153
4168
                    tokenPtr->numComponents != 1) {
4154
4169
                ckfree((char *) bodyToken);
4155
4170
                ckfree((char *) bodyLines);
 
4171
                ckfree((char *) bodyNext);
4156
4172
                return TCL_ERROR;
4157
4173
            }
4158
4174
            bodyToken[i] = tokenPtr+1;
4162
4178
             */
4163
4179
 
4164
4180
            bodyLines[i] = mapPtr->loc[eclIndex].line[valueIndex+1+i];
 
4181
            bodyNext[i] = mapPtr->loc[eclIndex].next[valueIndex+1+i];
4165
4182
            tokenPtr = TokenAfter(tokenPtr);
4166
4183
        }
4167
4184
    }
4175
4192
            bodyToken[numWords-1]->start[0] == '-') {
4176
4193
        ckfree((char *) bodyToken);
4177
4194
        ckfree((char *) bodyLines);
 
4195
        ckfree((char *) bodyNext);
4178
4196
        if (bodyTokenArray != NULL) {
4179
4197
            ckfree((char *) bodyTokenArray);
4180
4198
        }
4186
4204
     * First, we push the value we're matching against on the stack.
4187
4205
     */
4188
4206
 
4189
 
    envPtr->line = mapPtr->loc[eclIndex].line[valueIndex];
 
4207
    SetLineInformation (valueIndex);
4190
4208
    CompileTokens(envPtr, valueTokenPtr, interp);
4191
4209
 
4192
4210
    /*
4308
4326
             */
4309
4327
 
4310
4328
            envPtr->line = bodyLines[i+1];      /* TIP #280 */
 
4329
            envPtr->clNext = bodyNext[i+1];     /* TIP #280 */
4311
4330
            TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
4312
4331
 
4313
4332
            /*
4359
4378
        ckfree((char *) finalFixups);
4360
4379
        ckfree((char *) bodyToken);
4361
4380
        ckfree((char *) bodyLines);
 
4381
        ckfree((char *) bodyNext);
4362
4382
        if (bodyTokenArray != NULL) {
4363
4383
            ckfree((char *) bodyTokenArray);
4364
4384
        }
4520
4540
        TclEmitOpcode(INST_POP, envPtr);
4521
4541
        envPtr->currStackDepth = savedStackDepth + 1;
4522
4542
        envPtr->line = bodyLines[i+1];          /* TIP #280 */
 
4543
        envPtr->clNext = bodyNext[i+1];         /* TIP #280 */
4523
4544
        TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
4524
4545
 
4525
4546
        if (!foundDefault) {
4536
4557
 
4537
4558
    ckfree((char *) bodyToken);
4538
4559
    ckfree((char *) bodyLines);
 
4560
    ckfree((char *) bodyNext);
4539
4561
    if (bodyTokenArray != NULL) {
4540
4562
        ckfree((char *) bodyTokenArray);
4541
4563
    }
4792
4814
     * Compile the loop body.
4793
4815
     */
4794
4816
 
4795
 
    envPtr->line = mapPtr->loc[eclIndex].line[2];
 
4817
    SetLineInformation (2);
4796
4818
    bodyCodeOffset = ExceptionRangeStarts(envPtr, range);
4797
4819
    CompileBody(envPtr, bodyTokenPtr, interp);
4798
4820
    ExceptionRangeEnds(envPtr, range);
4812
4834
            testCodeOffset += 3;
4813
4835
        }
4814
4836
        envPtr->currStackDepth = savedStackDepth;
4815
 
        envPtr->line = mapPtr->loc[eclIndex].line[1];
 
4837
        SetLineInformation (1);
4816
4838
        TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
4817
4839
        envPtr->currStackDepth = savedStackDepth + 1;
4818
4840
 
4877
4899
    int *localIndexPtr,         /* Must not be NULL. */
4878
4900
    int *simpleVarNamePtr,      /* Must not be NULL. */
4879
4901
    int *isScalarPtr,           /* Must not be NULL. */
4880
 
    int line)                   /* Line the token starts on. */
 
4902
    int line,                   /* Line the token starts on. */
 
4903
    int* clNext)                /* Reference to offset of next hidden cont. line */
4881
4904
{
4882
4905
    register const char *p;
4883
4906
    const char *name, *elName;
5061
5084
        if (elName != NULL) {
5062
5085
            if (elNameChars) {
5063
5086
                envPtr->line = line;
 
5087
                envPtr->clNext = clNext;
5064
5088
                TclCompileTokens(interp, elemTokenPtr, elemTokenCount, envPtr);
5065
5089
            } else {
5066
5090
                PushLiteral(envPtr, "", 0);
5072
5096
         */
5073
5097
 
5074
5098
        envPtr->line = line;
 
5099
        envPtr->clNext = clNext;
5075
5100
        CompileTokens(envPtr, varTokenPtr, interp);
5076
5101
    }
5077
5102
 
5849
5874
        localTokenPtr = TokenAfter(otherTokenPtr);
5850
5875
 
5851
5876
        CompileWord(envPtr, otherTokenPtr, interp, 1);
5852
 
        PushVarName(interp, localTokenPtr, envPtr, TCL_CREATE_VAR,
5853
 
                &localIndex, &simpleVarName, &isScalar,
5854
 
                mapPtr->loc[eclIndex].line[1]);
 
5877
        PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR,
 
5878
                        &localIndex, &simpleVarName, &isScalar, 1);
5855
5879
 
5856
5880
        if((localIndex < 0) || !isScalar) {
5857
5881
            return TCL_ERROR;
5942
5966
        localTokenPtr = TokenAfter(otherTokenPtr);
5943
5967
 
5944
5968
        CompileWord(envPtr, otherTokenPtr, interp, 1);
5945
 
        PushVarName(interp, localTokenPtr, envPtr, TCL_CREATE_VAR,
5946
 
                &localIndex, &simpleVarName, &isScalar,
5947
 
                mapPtr->loc[eclIndex].line[1]);
 
5969
        PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR,
 
5970
                        &localIndex, &simpleVarName, &isScalar, 1);
5948
5971
 
5949
5972
        if((localIndex < 0) || !isScalar) {
5950
5973
            return TCL_ERROR;
6444
6467
     */
6445
6468
 
6446
6469
    tokenPtr = TokenAfter(parsePtr->tokenPtr);
6447
 
    PushVarName(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex,
6448
 
            &simpleVarName, &isScalar, mapPtr->loc[eclIndex].line[1]);
 
6470
    PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex,
 
6471
                    &simpleVarName, &isScalar, 1);
6449
6472
 
6450
6473
    /*
6451
6474
     * Emit instruction to check the variable for existence.