stateStack[stateStackTop].min = GET_ARG(pc); pc += ARG_LEN; stateStack[stateStackTop].max = GET_ARG(pc);
stateStack[stateStackTop].min = (int32)GET_ARG(pc); pc += ARG_LEN; stateStack[stateStackTop].max = (int32)GET_ARG(pc);
static REMatchState *executeREBytecode(REuint8 *pc, REGlobalData *gData, REMatchState *x){    REOp op = (REOp)(*pc++);    REContinuationData currentContinuation;    REMatchState *result;    REBackTrackData *backTrackData;    REint32 k, length, offset, parenIndex, index;    REbool anchor = RE_FALSE;    REchar anchorCh;    REchar matchCh;    REuint8 *nextpc;    REOp nextop;    currentContinuation.pc = NULL;    currentContinuation.op = REOP_END;    /*     *   If the first node is a literal match, step the index into     *   the string until that match is made, or fail if it can't be     *   found at all.     */    switch (op) {    case REOP_FLAT1:    case REOP_FLAT1i:        anchorCh = GET_ARG(pc);        anchor = RE_TRUE;        break;    case REOP_FLATN:            case REOP_FLATNi:        k = GET_ARG(pc);        anchorCh = gData->regexp->srcStart[k];        anchor = RE_TRUE;        break;    }    if (anchor) {        anchor = RE_FALSE;        for (k = x->endIndex; k < gData->length; k++) {            matchCh = gData->input[k];            if ((matchCh == anchorCh) ||                                    ((gData->regexp->flags & RE_IGNORECASE)                    && (canonicalize(matchCh) == canonicalize(anchorCh)))) {                x->endIndex = k;                x->startIndex = k;  /* inform caller that we bumped along */                anchor = RE_TRUE;                break;            }        }        if (!anchor)            return NULL;    }    while (RE_TRUE) {        switch (op) {        case REOP_EMPTY:            result = x;            break;        case REOP_BOL:            result = bolMatcher(gData, x);            break;        case REOP_EOL:            result = eolMatcher(gData, x);            break;        case REOP_WBND:            result = wbndMatcher(gData, x, RE_TRUE);            break;        case REOP_UNWBND:            result = wbndMatcher(gData, x, RE_FALSE);            break;        case REOP_DOT:            result = dotMatcher(gData, x);            break;        case REOP_DEC:            result = decMatcher(gData, x, RE_TRUE);            break;        case REOP_UNDEC:            result = decMatcher(gData, x, RE_FALSE);            break;        case REOP_WS:            result = wsMatcher(gData, x, RE_TRUE);            break;        case REOP_UNWS:            result = wsMatcher(gData, x, RE_FALSE);            break;        case REOP_LETDIG:            result = letdigMatcher(gData, x, RE_TRUE);            break;        case REOP_UNLETDIG:            result = letdigMatcher(gData, x, RE_FALSE);            break;        case REOP_FLATN:            offset = GET_ARG(pc);            pc += ARG_LEN;            length = GET_ARG(pc);            pc += ARG_LEN;            result = flatNMatcher(gData, x, gData->regexp->srcStart + offset,                                                                         length);            break;        case REOP_FLATNi:            offset = GET_ARG(pc);            pc += ARG_LEN;            length = GET_ARG(pc);            pc += ARG_LEN;            result = flatNIMatcher(gData, x, gData->regexp->srcStart + offset,                                                                        length);            break;        case REOP_FLAT1:            matchCh = GET_ARG(pc);            pc += ARG_LEN;            result = flatMatcher(gData, x, matchCh);            break;        case REOP_FLAT1i:            matchCh = GET_ARG(pc);            pc += ARG_LEN;            result = flatIMatcher(gData, x, matchCh);            break;        case REOP_ALT:            nextpc = pc + GET_ARG(pc);            nextop = (REOp)(*nextpc++);            stateStack[stateStackTop].continuation = currentContinuation;            ++stateStackTop;            pushBackTrackState(gData, nextop, nextpc, x);            pc += ARG_LEN;            op = (REOp)(*pc++);            continue;        case REOP_ENDALT:            --stateStackTop;            currentContinuation = stateStack[stateStackTop].continuation;            offset = GET_ARG(pc);            pc += offset;            op = (REOp)(*pc++);            continue;                    case REOP_PAREN:            parenIndex = GET_ARG(pc);            pc += ARG_LEN;            x->parens[parenIndex].index = x->endIndex;            x->parens[parenIndex].length = 0;            op = (REOp)(*pc++);            continue;        case REOP_CLOSEPAREN:            parenIndex = GET_ARG(pc);            pc += ARG_LEN;            x->parens[parenIndex].length = x->endIndex                                                 - x->parens[parenIndex].index;            if (parenIndex > gData->lastParen)                gData->lastParen = parenIndex;            op = (REOp)(*pc++);            continue;        case REOP_BACKREF:            parenIndex = GET_ARG(pc);            pc += ARG_LEN;            result = backrefMatcher(gData, x, parenIndex);            break;        case REOP_ASSERT:            stateStack[stateStackTop].continuation = currentContinuation;            stateStack[stateStackTop].parenCount = backTrackStackTop;            stateStack[stateStackTop].index = x->endIndex;            ++stateStackTop;            if (!pushBackTrackState(gData, REOP_ASSERTTEST,                                                         pc + GET_ARG(pc), x))                return NULL;            pc += ARG_LEN;            op = (REOp)(*pc++);            continue;        case REOP_ASSERTNOT:            stateStack[stateStackTop].continuation = currentContinuation;            stateStack[stateStackTop].parenCount = backTrackStackTop;            stateStack[stateStackTop].index = x->endIndex;            ++stateStackTop;            if (!pushBackTrackState(gData, REOP_ASSERTNOTTEST,                                                         pc + GET_ARG(pc), x))                return NULL;            pc += ARG_LEN;            op = (REOp)(*pc++);            continue;        case REOP_ASSERTTEST:            --stateStackTop;            x->endIndex = stateStack[stateStackTop].index;            for (k = stateStack[stateStackTop].parenCount;                     k < backTrackStackTop; k++) {                if (backTrackStack[k].precedingState)                    free(backTrackStack[k].precedingState);                free(backTrackStack[k].state);            }            backTrackStackTop = stateStack[stateStackTop].parenCount;            currentContinuation = stateStack[stateStackTop].continuation;                            if (result != NULL)                result = x;            break;        case REOP_ASSERTNOTTEST:            --stateStackTop;            x->endIndex = stateStack[stateStackTop].index;            for (k = stateStack[stateStackTop].parenCount;                     k < backTrackStackTop; k++) {                if (backTrackStack[k].precedingState)                    free(backTrackStack[k].precedingState);                free(backTrackStack[k].state);            }            backTrackStackTop = stateStack[stateStackTop].parenCount;            currentContinuation = stateStack[stateStackTop].continuation;                            if (result == NULL)                result = x;            else                result = NULL;            break;        case REOP_CLASS:            index = GET_ARG(pc);            pc += ARG_LEN;            result = classMatcher(gData, x, index);            if (gData->error != RE_NO_ERROR) return NULL;            break;        case REOP_END:            if (x != NULL)                return x;            break;        case REOP_STAR:            stateStack[stateStackTop].min = 0;            stateStack[stateStackTop].max = -1;            goto quantcommon;        case REOP_PLUS:            stateStack[stateStackTop].min = 1;            stateStack[stateStackTop].max = -1;            goto quantcommon;        case REOP_OPT:            stateStack[stateStackTop].min = 0;            stateStack[stateStackTop].max = 1;            goto quantcommon;        case REOP_QUANT:            stateStack[stateStackTop].min = GET_ARG(pc);            pc += ARG_LEN;            stateStack[stateStackTop].max = GET_ARG(pc);            pc += ARG_LEN;quantcommon:            stateStack[stateStackTop].parenCount = GET_ARG(pc);            pc += ARG_LEN;            stateStack[stateStackTop].parenIndex = GET_ARG(pc);            pc += ARG_LEN;            stateStack[stateStackTop].index = x->endIndex;            stateStack[stateStackTop].continuation = currentContinuation;            ++stateStackTop;            currentContinuation.op = REOP_REPEAT;            currentContinuation.pc = pc;            if (!pushBackTrackState(gData, REOP_REPEAT, pc, x)) return NULL;            pc += ARG_LEN;            op = (REOp)(*pc++);            continue;        case REOP_ENDCHILD:            pc = currentContinuation.pc;            op = currentContinuation.op;            continue;        case REOP_REPEAT:            --stateStackTop;            if (result == NULL) {                /*                 *  There's been a failure, see if we have enough children                 */                currentContinuation = stateStack[stateStackTop].continuation;                if (stateStack[stateStackTop].min == 0)                    result = x;                pc = pc + GET_ARG(pc);                break;            }            else {                if ((stateStack[stateStackTop].min == 0)                        && (x->endIndex == stateStack[stateStackTop].index)) {                    /* matched an empty string, that'll get us nowhere */                    result = NULL;                    currentContinuation = stateStack[stateStackTop].continuation;                    pc = pc + GET_ARG(pc);                    break;                }                if (stateStack[stateStackTop].min > 0)                                             stateStack[stateStackTop].min--;                if (stateStack[stateStackTop].max != -1)                                             stateStack[stateStackTop].max--;                if (stateStack[stateStackTop].max == 0) {                    result = x;                    currentContinuation = stateStack[stateStackTop].continuation;                    pc = pc + GET_ARG(pc);                    break;                }                stateStack[stateStackTop].index = x->endIndex;                ++stateStackTop;                currentContinuation.op = REOP_REPEAT;                currentContinuation.pc = pc;                if (!pushBackTrackState(gData, REOP_REPEAT, pc, x)) return NULL;                pc += ARG_LEN;                op = (REOp)(*pc++);                parenIndex = stateStack[stateStackTop - 1].parenIndex;                for (k = 0; k <= stateStack[stateStackTop - 1].parenCount; k++)                    x->parens[parenIndex + k].index = -1;            }            continue;                               case REOP_MINIMALSTAR:            stateStack[stateStackTop].min = 0;            stateStack[stateStackTop].max = -1;            goto minimalquantcommon;        case REOP_MINIMALPLUS:            stateStack[stateStackTop].min = 1;            stateStack[stateStackTop].max = -1;            goto minimalquantcommon;        case REOP_MINIMALOPT:            stateStack[stateStackTop].min = 0;            stateStack[stateStackTop].max = 1;            goto minimalquantcommon;        case REOP_MINIMALQUANT:            stateStack[stateStackTop].min = GET_ARG(pc);            pc += ARG_LEN;            stateStack[stateStackTop].max = GET_ARG(pc);            pc += ARG_LEN;minimalquantcommon:            stateStack[stateStackTop].parenCount = GET_ARG(pc);            pc += ARG_LEN;            stateStack[stateStackTop].parenIndex = GET_ARG(pc);            pc += ARG_LEN;            stateStack[stateStackTop].index = x->endIndex;            stateStack[stateStackTop].continuation = currentContinuation;            ++stateStackTop;            if (stateStack[stateStackTop - 1].min > 0) {                currentContinuation.op = REOP_MINIMALREPEAT;                currentContinuation.pc = pc;                pc += ARG_LEN;                op = (REOp)(*pc++);            }            else {                if (!pushBackTrackState(gData, REOP_MINIMALREPEAT, pc, x))                    return NULL;                --stateStackTop;                pc = pc + GET_ARG(pc);                op = (REOp)(*pc++);            }            continue;        case REOP_MINIMALREPEAT:            --stateStackTop;            currentContinuation = stateStack[stateStackTop].continuation;            if (result == NULL) {                /*                  * Non-greedy failure - try to consume another child                 */                if ((stateStack[stateStackTop].max == -1)                        || (stateStack[stateStackTop].max > 0)) {                    parenIndex = stateStack[stateStackTop].parenIndex;                    for (k = 0; k <= stateStack[stateStackTop].parenCount; k++)                        x->parens[parenIndex + k].index = -1;                    stateStack[stateStackTop].index = x->endIndex;                    stateStack[stateStackTop].continuation = currentContinuation;                    ++stateStackTop;                    currentContinuation.op = REOP_MINIMALREPEAT;                    currentContinuation.pc = pc;                    pc += ARG_LEN;                    op = (REOp)(*pc++);                    continue;                }                else {                    currentContinuation = stateStack[stateStackTop].continuation;                    break;                }            }            else {                if ((stateStack[stateStackTop].min == 0)                        && (x->endIndex == stateStack[stateStackTop].index)) {                    /* matched an empty string, that'll get us nowhere */                    result = NULL;                    currentContinuation = stateStack[stateStackTop].continuation;                    break;                }                if (stateStack[stateStackTop].min > 0)                                                 stateStack[stateStackTop].min--;                if (stateStack[stateStackTop].max != -1)                                                 stateStack[stateStackTop].max--;                if (stateStack[stateStackTop].min > 0) {                    parenIndex = stateStack[stateStackTop].parenIndex;                    for (k = 0; k <= stateStack[stateStackTop].parenCount; k++)                        x->parens[parenIndex + k].index = -1;                    stateStack[stateStackTop].index = x->endIndex;                    ++stateStackTop;                    currentContinuation.op = REOP_MINIMALREPEAT;                    currentContinuation.pc = pc;                    pc += ARG_LEN;                    op = (REOp)(*pc++);                    continue;                                       }                else {                    stateStack[stateStackTop].index = x->endIndex;                    ++stateStackTop;                    if (!pushBackTrackState(gData, REOP_MINIMALREPEAT, pc, x))                         return NULL;                    --stateStackTop;                    pc = pc + GET_ARG(pc);                    op = (REOp)(*pc++);                    continue;                }            }        }        /*         *  If the match failed and there's a backtrack option, take it.         *  Otherwise this is a match failure.         */        if (result == NULL) {            if (backTrackStackTop > 0) {                backTrackStackTop--;                backTrackData = &backTrackStack[backTrackStackTop];                gData->lastParen = backTrackData->lastParen;                recoverState(x, backTrackData->state);                free(backTrackData->state);                for (k = 0; k < backTrackData->precedingStateTop; k++) {                    stateStack[k] = backTrackData->precedingState[k];                }                stateStackTop = backTrackData->precedingStateTop;                if (backTrackData->precedingState)                    free(backTrackData->precedingState);                if (stateStackTop > 0)                    currentContinuation = stateStack[stateStackTop - 1].continuation;                                pc = backTrackData->continuation.pc;                 op = backTrackData->continuation.op;                continue;            }            else                return NULL;        }        else            x = result;                /*         *  Continue with the expression. If this the end of the child, use         *  the current continuation.         */        op = (REOp)*pc++;        if (op == REOP_ENDCHILD) {            pc = currentContinuation.pc;            op = currentContinuation.op;        }    }    return NULL;}