VirtualBox

Changeset 2770 in kBuild for trunk


Ignore:
Timestamp:
Feb 1, 2015 5:12:37 PM (10 years ago)
Author:
bird
Message:

string expansion debugged and enabled. fixed access-after-alloc bug in func_sort and could lead to heap corruption.

Location:
trunk/src/kmk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/expand.c

    r2769 r2770  
    256256      v->expand_count++;
    257257      if (   v->expandprog
    258           || (v->expand_count == 10 && kmk_cc_compile_variable_for_expand (v)) )
     258          || (v->expand_count == 3 && kmk_cc_compile_variable_for_expand (v)) )
    259259        o = kmk_exec_expand_to_var_buf (v, o);
    260260      else
     
    10811081      v->value_length = p - v->value;
    10821082      v->value_alloc_len = variable_buffer_length;
     1083      VARIABLE_CHANGED(v);
    10831084
    10841085      /* Restore the variable buffer, but without freeing the current. */
  • trunk/src/kmk/function.c

    r2768 r2770  
    13601360      var->value[len] = '\0';
    13611361      var->value_length = len;
     1362      VARIABLE_CHANGED (var);
    13621363
    13631364      variable_expand_string_2 (o, body, body_len, &o);
     
    17541755  while ((p = find_next_token (&t, &len)) != 0)
    17551756    {
    1756       ++t;
     1757      if (*t != '\0') /* bird: Fixes access beyond end of string and overflowing words array. */
     1758        ++t;
    17571759      p[len] = '\0';
    17581760      words[wordi++] = p;
     
    21602162              v->value_length = dst - v->value;
    21612163            }
     2164
     2165          VARIABLE_CHANGED (v);
    21622166
    21632167# ifdef CONFIG_WITH_COMPILER
     
    46484652              stack_var->value_length = lastitem - stack_var->value;
    46494653#endif
     4654              VARIABLE_CHANGED (stack_var);
    46504655            }
    46514656        }
  • trunk/src/kmk/kbuild.c

    r2540 r2770  
    570570    }
    571571    pVar->recursive = 0;
     572    VARIABLE_CHANGED(pVar);
    572573    return pVar;
    573574}
     
    26212622            pDefTemplate->value_length = off;
    26222623            pDefTemplate->value[off] = '\0';
     2624
     2625            VARIABLE_CHANGED(pDefTemplate);
    26232626        }
    26242627
  • trunk/src/kmk/kmk_cc_exec.c

    r2769 r2770  
    7070typedef struct KMKCCEXPSTATS
    7171{
    72     /** Max expanded size. */
    73     uint32_t                    cchMax;
    7472    /** Recent average size. */
    7573    uint32_t                    cchAvg;
     
    198196    /** Number of arguments. */
    199197    uint32_t                cArgs;
     198    /** Set if the function could be modifying the input arguments. */
     199    uint8_t                 fDirty;
    200200    /** Where to continue after this instruction.  (This is necessary since the
    201201     * instructions are of variable size and may be followed by string data.) */
     
    209209     * @param   pszFuncName The name of the function being called.
    210210     */
    211     char *                 (*pfnFunction)(char *pchDst, char **papszArgs, const char *pszFuncName);
     211    char *                (*pfnFunction)(char *pchDst, char **papszArgs, const char *pszFuncName);
    212212    /** Pointer to the function name in the variable string cache. */
    213213    const char             *pszFuncName;
     
    295295
    296296/*******************************************************************************
     297*   Defined Constants And Macros                                               *
     298*******************************************************************************/
     299#ifndef NDEBUG
     300# ifdef _MSC_VER
     301#  define KMK_CC_ASSERT(a_TrueExpr)         do { if (!(a_TrueExpr)) __debugbreak(); } while (0)
     302# else
     303#  define KMK_CC_ASSERT(a_TrueExpr)         assert(a_TrueExpr)
     304# endif
     305#else
     306# define KMK_CC_ASSERT(a_TrueExpr)          do {} while (0)
     307#endif
     308#define KMK_CC_ASSERT_ALIGNED(a_uValue, a_uAlignment) \
     309    KMK_CC_ASSERT( ((a_uValue) & ((a_uAlignment) - 1)) == 0 )
     310
     311
     312/*******************************************************************************
    297313*   Global Variables                                                           *
    298314*******************************************************************************/
     
    327343    PKMKCCBLOCK     pNewBlock;
    328344
    329     assert(((cbFirst + sizeof(void *) - 1) & (sizeof(void *) - 1)) == 0);
     345    KMK_CC_ASSERT_ALIGNED(cbFirst, sizeof(void *));
    330346
    331347    /*
     
    377393    {
    378394        pBlockTail->offNext = (pBlockTail->offNext + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
    379         assert(pBlockTail->cbBlock - pBlockTail->offNext >= sizeof(KMKCCEXPJUMP));
     395        KMK_CC_ASSERT(pBlockTail->cbBlock - pBlockTail->offNext >= sizeof(KMKCCEXPJUMP));
    380396    }
    381397}
     
    441457    uint32_t    cbLeft = pBlockTail->cbBlock - pBlockTail->offNext;
    442458
    443     assert(cbLeft >= sizeof(KMKCCEXPJUMP));
     459    KMK_CC_ASSERT(cbLeft >= sizeof(KMKCCEXPJUMP));
    444460    if (cbLeft >= cb + sizeof(KMKCCEXPJUMP))
    445461    {
     
    508524    pJump->pNext = pRet;
    509525    pOldBlock->offNext += sizeof(*pJump);
    510     assert(pOldBlock->offNext <= pOldBlock->cbBlock);
     526    KMK_CC_ASSERT(pOldBlock->offNext <= pOldBlock->cbBlock);
    511527
    512528    return pRet;
     
    526542    uint32_t    cbLeft = pBlockTail->cbBlock - pBlockTail->offNext;
    527543
    528     assert(cbLeft >= sizeof(KMKCCEXPJUMP));
    529     assert(((cb + sizeof(void *) - 1) & (sizeof(void *) - 1)) == 0 || cb == sizeof(KMKCCEXPCORE));
     544    KMK_CC_ASSERT(cbLeft >= sizeof(KMKCCEXPJUMP));
     545    KMK_CC_ASSERT( (cb & (sizeof(void *) - 1)) == 0 || cb == sizeof(KMKCCEXPCORE) /* final */ );
    530546
    531547    if (cbLeft >= cb + sizeof(KMKCCEXPJUMP))
     
    588604    pCore->enmOpCode = kKmkCcExpInstr_Return;
    589605    return 0;
     606}
     607
     608
     609/**
     610 * Checks if a function is known to mess up the arguments its given.
     611 *
     612 * When executing calls to "dirty" functions, all arguments must be duplicated
     613 * on the heap.
     614 *
     615 * @returns 1 if dirty, 0 if clean.
     616 * @param   pszFunction         The function name.
     617 */
     618static uint8_t kmk_cc_is_dirty_function(const char *pszFunction)
     619{
     620    switch (pszFunction[0])
     621    {
     622        default:
     623            return 0;
     624        case 'f':
     625            if (pszFunction[1] == 'i')
     626            {
     627                if (!strcmp(pszFunction, "filter"))
     628                    return 1;
     629                if (!strcmp(pszFunction, "filter-out"))
     630                    return 1;
     631            }
     632            return 0;
     633        case 's':
     634            if (!strcmp(pszFunction, "sort"))
     635                return 1;
     636            return 0;
     637    }
    590638}
    591639
     
    624672    pInstr->Core.pfnFunction    = pfnFunction;
    625673    pInstr->Core.pszFuncName    = pszFunction;
     674    pInstr->Core.fDirty         = kmk_cc_is_dirty_function(pszFunction);
    626675
    627676    /*
     
    645694            if (ch == chClose)
    646695            {
    647                 assert(cDepth > 0);
     696                KMK_CC_ASSERT(cDepth > 0);
    648697                if (cDepth > 0)
    649698                    cDepth--;
     
    651700            else if (ch == chOpen)
    652701                cDepth++;
    653             else if (ch == ',' && cDepth == 0)
     702            else if (ch == ',' && cDepth == 0 && iArg + 1 < cActualArgs)
    654703                break;
    655704            else if (ch == '$')
     
    658707        }
    659708
    660         pInstr->aArgs[iArg].fPlain = fDollar;
     709        pInstr->aArgs[iArg].fPlain = !fDollar;
    661710        if (fDollar)
    662711        {
     
    679728        cchArgs -= cchThisArg + 1;
    680729    }
    681     assert(iArg == cActualArgs);
     730    KMK_CC_ASSERT(iArg == cActualArgs);
    682731
    683732    /*
     
    723772    pInstr->Core.pfnFunction    = pfnFunction;
    724773    pInstr->Core.pszFuncName    = pszFunction;
     774    pInstr->Core.fDirty         = kmk_cc_is_dirty_function(pszFunction);
    725775
    726776    /*
     
    742792            if (ch == chClose)
    743793            {
    744                 assert(cDepth > 0);
     794                KMK_CC_ASSERT(cDepth > 0);
    745795                if (cDepth > 0)
    746796                    cDepth--;
     
    748798            else if (ch == chOpen)
    749799                cDepth++;
    750             else if (ch == ',' && cDepth == 0)
     800            else if (ch == ',' && cDepth == 0 && iArg + 1 < cActualArgs)
    751801                break;
    752802            cchThisArg++;
     
    761811    }
    762812
    763     assert(iArg == cActualArgs);
     813    KMK_CC_ASSERT(iArg == cActualArgs);
    764814    pInstr->apszArgs[iArg] = NULL;
    765815
     
    787837    PKMKCCEXPDYNVAR pInstr;
    788838    int rc;
    789     assert(cchNameExpr > 0);
     839    KMK_CC_ASSERT(cchNameExpr > 0);
    790840
    791841    pInstr = (PKMKCCEXPDYNVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
     
    10021052
    10031053                        /* First loop: Identify potential function calls and dynamic expansion. */
    1004                         assert(!func_char_map[chOpen]); assert(!func_char_map[chClose]); assert(!func_char_map['$']);
     1054                        KMK_CC_ASSERT(!func_char_map[chOpen]);
     1055                        KMK_CC_ASSERT(!func_char_map[chClose]);
     1056                        KMK_CC_ASSERT(!func_char_map['$']);
    10051057                        while (cchName < cchStr)
    10061058                        {
     
    11981250{
    11991251    pStats->cchAvg = 0;
    1200     pStats->cchMax = 0;
    12011252}
    12021253
     
    12191270static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg)
    12201271{
    1221     assert(cchStr);
     1272    KMK_CC_ASSERT(cchStr > 0);
    12221273    pSubProg->pFirstInstr = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
    12231274    kmk_cc_exp_stats_init(&pSubProg->Stats);
     
    12861337struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar)
    12871338{
    1288     assert(!pVar->expandprog);
     1339    KMK_CC_ASSERT(!pVar->expandprog);
    12891340    if (   !pVar->expandprog
    12901341        && pVar->value_length > 0
    12911342        && pVar->recursive)
    12921343    {
    1293         assert(strlen(pVar->value) == pVar->value_length);
    1294 #if 0 /** @todo test & debug this code. Write interpreters! */
     1344        KMK_CC_ASSERT(strlen(pVar->value) == pVar->value_length);
    12951345        pVar->expandprog = kmk_cc_exp_compile(pVar->value, pVar->value_length);
    1296 #endif
    12971346    }
    12981347    return pVar->expandprog;
     
    14751524            {
    14761525                PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)pInstrCore;
     1526                uint32_t iArg;
     1527                if (!pInstr->Core.fDirty)
     1528                {
    14771529#ifndef NDEBUG
    1478                 uint32_t uCrcBefore = 0;
    1479                 uint32_t uCrcAfter = 0;
    1480                 uint32_t iArg = pInstr->Core.cArgs;
    1481                 while (iArg-- > 0)
    1482                     uCrcBefore = kmk_exec_debug_string_hash(uCrcBefore, pInstr->apszArgs[iArg]);
     1530                    uint32_t uCrcBefore = 0;
     1531                    uint32_t uCrcAfter = 0;
     1532                    iArg = pInstr->Core.cArgs;
     1533                    while (iArg-- > 0)
     1534                        uCrcBefore = kmk_exec_debug_string_hash(uCrcBefore, pInstr->apszArgs[iArg]);
    14831535#endif
    14841536
    1485                 pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
     1537                    pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
    14861538
    14871539#ifndef NDEBUG
    1488                 iArg = pInstr->Core.cArgs;
    1489                 while (iArg-- > 0)
    1490                     uCrcAfter = kmk_exec_debug_string_hash(uCrcAfter, pInstr->apszArgs[iArg]);
    1491                 assert(uCrcBefore == uCrcAfter);
     1540                    iArg = pInstr->Core.cArgs;
     1541                    while (iArg-- > 0)
     1542                        uCrcAfter = kmk_exec_debug_string_hash(uCrcAfter, pInstr->apszArgs[iArg]);
     1543                    KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
    14921544#endif
     1545                }
     1546                else
     1547                {
     1548                    char **papszShadowArgs = xmalloc((pInstr->Core.cArgs * 2 + 1) * sizeof(papszShadowArgs[0]));
     1549                    char **papszArgs = &papszShadowArgs[pInstr->Core.cArgs];
     1550
     1551                    iArg = pInstr->Core.cArgs;
     1552                    papszArgs[iArg] = NULL;
     1553                    while (iArg-- > 0)
     1554                        papszArgs[iArg] = papszShadowArgs[iArg] = xstrdup(pInstr->apszArgs[iArg]);
     1555
     1556                    pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
     1557
     1558                    iArg = pInstr->Core.cArgs;
     1559                    while (iArg-- > 0)
     1560                        free(papszShadowArgs[iArg]);
     1561                    free(papszShadowArgs);
     1562                }
    14931563
    14941564                pInstrCore = pInstr->Core.pNext;
     
    15021572                char           **papszArgs = &papszArgsShadow[pInstr->Core.cArgs];
    15031573                uint32_t         iArg;
    1504 #ifndef NDEBUG
    1505                 uint32_t         uCrcBefore = 0;
    1506                 uint32_t         uCrcAfter = 0;
    1507 #endif
    1508                 iArg = pInstr->Core.cArgs;
    1509                 papszArgs[iArg] = NULL;
    1510                 while (iArg-- > 0)
    1511                 {
    1512                     char *pszArg;
    1513                     if (pInstr->aArgs[iArg].fPlain)
    1514                         pszArg = (char *)pInstr->aArgs[iArg].u.Plain.pszArg;
    1515                     else
    1516                         pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
    1517                     papszArgsShadow[iArg] = pszArg;
    1518                     papszArgs[iArg]       = pszArg;
    1519 #ifndef NDEBUG
    1520                     uCrcBefore = kmk_exec_debug_string_hash(uCrcBefore, pszArg);
    1521 #endif
    1522                 }
    1523 
    1524                 pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
    1525 
    1526                 iArg = pInstr->Core.cArgs;
    1527                 while (iArg-- > 0)
     1574
     1575                if (!pInstr->Core.fDirty)
    15281576                {
    15291577#ifndef NDEBUG
    1530                     assert(papszArgsShadow[iArg] == papszArgs[iArg]);
    1531                     uCrcAfter = kmk_exec_debug_string_hash(uCrcAfter, papszArgsShadow[iArg]);
     1578                    uint32_t    uCrcBefore = 0;
     1579                    uint32_t    uCrcAfter = 0;
    15321580#endif
    1533                     if (!pInstr->aArgs[iArg].fPlain)
    1534                         free(papszArgsShadow);
     1581                    iArg = pInstr->Core.cArgs;
     1582                    papszArgs[iArg] = NULL;
     1583                    while (iArg-- > 0)
     1584                    {
     1585                        char *pszArg;
     1586                        if (!pInstr->aArgs[iArg].fPlain)
     1587                            pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
     1588                        else
     1589                            pszArg = (char *)pInstr->aArgs[iArg].u.Plain.pszArg;
     1590                        papszArgsShadow[iArg] = pszArg;
     1591                        papszArgs[iArg]       = pszArg;
     1592#ifndef NDEBUG
     1593                        uCrcBefore = kmk_exec_debug_string_hash(uCrcBefore, pszArg);
     1594#endif
     1595                    }
     1596                    pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
     1597
     1598                    iArg = pInstr->Core.cArgs;
     1599                    while (iArg-- > 0)
     1600                    {
     1601#ifndef NDEBUG
     1602                        KMK_CC_ASSERT(papszArgsShadow[iArg] == papszArgs[iArg]);
     1603                        uCrcAfter = kmk_exec_debug_string_hash(uCrcAfter, papszArgsShadow[iArg]);
     1604#endif
     1605                        if (!pInstr->aArgs[iArg].fPlain)
     1606                            free(papszArgsShadow[iArg]);
     1607                    }
     1608                    KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
    15351609                }
    1536                 assert(uCrcBefore == uCrcAfter);
     1610                else
     1611                {
     1612                    iArg = pInstr->Core.cArgs;
     1613                    papszArgs[iArg] = NULL;
     1614                    while (iArg-- > 0)
     1615                    {
     1616                        char *pszArg;
     1617                        if (!pInstr->aArgs[iArg].fPlain)
     1618                            pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
     1619                        else
     1620                            pszArg = xstrdup(pInstr->aArgs[iArg].u.Plain.pszArg);
     1621                        papszArgsShadow[iArg] = pszArg;
     1622                        papszArgs[iArg]       = pszArg;
     1623                    }
     1624
     1625                    pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
     1626
     1627                    iArg = pInstr->Core.cArgs;
     1628                    while (iArg-- > 0)
     1629                        free(papszArgsShadow[iArg]);
     1630                }
    15371631                free(papszArgsShadow);
    15381632
     
    15691663{
    15701664    /*
    1571      * Keep statistics on output size.  The average is simplified and not an
    1572      * exact average for every expansion that has taken place.
     1665     * The average is simplified and not an exact average for every
     1666     * expansion that has taken place.
    15731667     */
    1574     if (cchResult > pStats->cchMax)
    1575     {
    1576         if (pStats->cchMax)
    1577             pStats->cchAvg = cchResult;
    1578         pStats->cchMax = cchResult;
    1579     }
    15801668    pStats->cchAvg = (pStats->cchAvg * 7 + cchResult) / 8;
    15811669}
     
    16161704    kmk_cc_exp_stats_update(&pSubProg->Stats, cchResult);
    16171705
    1618     restore_variable_buffer(pchOldVarBuf, cbOldVarBuf);
     1706    variable_buffer = pchOldVarBuf;
     1707    variable_buffer_length = cbOldVarBuf;
    16191708
    16201709    return pszResult;
     
    16411730
    16421731    cchResult = (uint32_t)(pchDst - variable_buffer);
    1643     assert(cchResult >= offStart);
     1732    KMK_CC_ASSERT(cchResult >= offStart);
    16441733    cchResult -= offStart;
    16451734    kmk_cc_exp_stats_update(&pProg->Stats, cchResult);
     
    16561745void kmk_exec_evalval(struct variable *pVar)
    16571746{
    1658     assert(pVar->evalprog);
     1747    KMK_CC_ASSERT(pVar->evalprog);
    16591748    assert(0);
    16601749}
     
    16701759char *kmk_exec_expand_to_var_buf(struct variable *pVar, char *pchDst)
    16711760{
    1672     assert(pVar->expandprog);
     1761    KMK_CC_ASSERT(pVar->expandprog);
    16731762    return kmk_exec_expand_prog_to_var_buf(pVar->expandprog, pchDst);
    16741763}
     
    16821771void  kmk_cc_variable_changed(struct variable *pVar)
    16831772{
    1684     assert(pVar->evalprog || pVar->expandprog);
     1773    KMK_CC_ASSERT(pVar->evalprog || pVar->expandprog);
    16851774#if 0
    16861775    if (pVar->evalprog)
     
    17051794void  kmk_cc_variable_deleted(struct variable *pVar)
    17061795{
    1707     assert(pVar->evalprog || pVar->expandprog);
     1796    KMK_CC_ASSERT(pVar->evalprog || pVar->expandprog);
    17081797#if 0
    17091798    if (pVar->evalprog)
  • trunk/src/kmk/read.c

    r2717 r2770  
    22962296
    22972297          v->origin = origin;
     2298#ifndef CONFIG_WITH_VALUE_LENGTH
    22982299          if (v->flavor == f_simple)
    22992300            v->value = allocated_variable_expand (v->value);
    23002301          else
    23012302            v->value = xstrdup (v->value);
     2303#else
     2304          v->value_length = strlen (v->value);
     2305          if (v->flavor == f_simple)
     2306            v->value = allocated_variable_expand_2 (v->value, v->value_length, &v->value_length);
     2307          else
     2308            v->value = (char *)memcpy (xmalloc (v->value_length + 1), v->value, v->value_length + 1);
     2309          v->value_alloc_len = v->value_length + 1;
     2310#endif
    23022311
    23032312          fname = p->target;
     
    23702379              v->recursive = gv->recursive;
    23712380              v->append = 0;
     2381              VARIABLE_CHANGED (v);
    23722382            }
    23732383        }
  • trunk/src/kmk/variable.c

    r2769 r2770  
    386386          v->origin = origin;
    387387          v->recursive = recursive;
    388          MAKE_STATS_2(v->changes++);
    389 #ifdef CONFIG_WITH_COMPILER
    390          if (v->evalprog || v->expandprog)
    391            kmk_cc_variable_changed (v);
    392 #endif
     388         VARIABLE_CHANGED (v);
    393389        }
    394390      return v;
     
    603599      if (v->value != 0 && !v->rdonly_val)
    604600          free (v->value);
    605       MAKE_STATS_2(v->changes++);
    606 #ifdef CONFIG_WITH_COMPILER
    607       if (v->evalprog || v->expandprog)
    608         kmk_cc_variable_changed (v);
    609 #endif
     601      VARIABLE_CHANGED (v);
    610602    }
    611603  else
     
    764756      var->value_alloc_len = max;
    765757#endif
     758      VARIABLE_CHANGED (var);
    766759
    767760      /* Remember how many variables are in our current count.  Since we never
     
    22252218    memcpy (v->value, value, value_len + 1);
    22262219  v->value_length = new_value_len;
     2220  VARIABLE_CHANGED (v);
    22272221}
    22282222
     
    24392433            if (free_value)
    24402434               free (free_value);
    2441             MAKE_STATS_2(v->changes++);
    2442 # ifdef CONFIG_WITH_COMPILER
    2443             if (v->evalprog || v->expandprog)
    2444               kmk_cc_variable_changed (v);
    2445 # endif
    24462435            return v;
    24472436#else /* !CONFIG_WITH_VALUE_LENGTH */
  • trunk/src/kmk/variable.h

    r2769 r2770  
    116116#endif
    117117#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
    118     unsigned int evalval_count; /* Times used with $(evalval ) or $(evalctx ). */
    119     unsigned int expand_count;  /* Times expanded (not to be confused with exp_count). */
     118    unsigned int evalval_count; /* Times used with $(evalval ) or $(evalctx ) since last change. */
     119    unsigned int expand_count;  /* Times expanded since last change (not to be confused with exp_count). */
    120120#endif
    121121#ifdef CONFIG_WITH_COMPILER
     
    124124#endif
    125125  };
     126
     127/* Update statistics and invalidates optimizations when a variable changes. */
     128#ifdef CONFIG_WITH_COMPILER
     129# define VARIABLE_CHANGED(v) \
     130  do { \
     131      MAKE_STATS_2((v)->changes++); \
     132      if ((v)->evalprog || (v)->expandprog) kmk_cc_variable_changed(v); \
     133      (v)->expand_count = 0; \
     134      (v)->evalval_count = 0; \
     135    } while (0)
     136#else
     137# define VARIABLE_CHANGED(v) MAKE_STATS_2((v)->changes++)
     138#endif
     139
     140
    126141
    127142/* Structure that represents a variable set.  */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette