⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsregexp.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
        case 't':            c = 0x9;            goto doFlat;        case 'v':            c = 0xB;            goto doFlat;        /* Control letter */        case 'c':            if (state->cp + 1 < state->cpend && RE_IS_LETTER(state->cp[1])) {                c = (jschar) (*state->cp++ & 0x1F);            } else {                /* back off to accepting the original '\' as a literal */                --state->cp;                c = '\\';            }            goto doFlat;        /* HexEscapeSequence */        case 'x':            nDigits = 2;            goto lexHex;        /* UnicodeEscapeSequence */        case 'u':            nDigits = 4;lexHex:            n = 0;            for (i = 0; i < nDigits && state->cp < state->cpend; i++) {                uintN digit;                c = *state->cp++;                if (!isASCIIHexDigit(c, &digit)) {                    /*                     *  back off to accepting the original                     *  'u' or 'x' as a literal                     */                    state->cp -= i + 2;                    n = *state->cp++;                    break;                }                n = (n << 4) | digit;            }            c = (jschar) n;            goto doFlat;        /* Character class escapes */        case 'd':            state->result = NewRENode(state, REOP_DIGIT);doSimple:            if (!state->result)                return JS_FALSE;            state->progLength++;            break;        case 'D':            state->result = NewRENode(state, REOP_NONDIGIT);            goto doSimple;        case 's':            state->result = NewRENode(state, REOP_SPACE);            goto doSimple;        case 'S':            state->result = NewRENode(state, REOP_NONSPACE);            goto doSimple;        case 'w':            state->result = NewRENode(state, REOP_ALNUM);            goto doSimple;        case 'W':            state->result = NewRENode(state, REOP_NONALNUM);            goto doSimple;        /* IdentityEscape */        default:            state->result = NewRENode(state, REOP_FLAT);            if (!state->result)                return JS_FALSE;            state->result->u.flat.chr = c;            state->result->u.flat.length = 1;            state->result->kid = (void *) (state->cp - 1);            state->progLength += 3;            break;        }        break;    case '[':        state->result = NewRENode(state, REOP_CLASS);        if (!state->result)            return JS_FALSE;        termStart = state->cp;        state->result->u.ucclass.startIndex = termStart - state->cpbegin;        while (JS_TRUE) {            if (state->cp == state->cpend) {                js_ReportCompileErrorNumber(state->context, state->tokenStream,                                            NULL, JSREPORT_ERROR,                                            JSMSG_UNTERM_CLASS, termStart);                return JS_FALSE;            }            if (*state->cp == '\\') {                state->cp++;            } else {                if (*state->cp == ']') {                    state->result->u.ucclass.kidlen = state->cp - termStart;                    break;                }            }            state->cp++;        }        for (i = 0; i < CLASS_CACHE_SIZE; i++) {            if (!state->classCache[i].start) {                state->classCache[i].start = termStart;                state->classCache[i].length = state->result->u.ucclass.kidlen;                state->classCache[i].index = state->classCount;                break;            }            if (state->classCache[i].length ==                state->result->u.ucclass.kidlen) {                for (n = 0; ; n++) {                    if (n == state->classCache[i].length) {                        state->result->u.ucclass.index =                            state->classCache[i].index;                        goto claim;                    }                    if (state->classCache[i].start[n] != termStart[n])                        break;                }            }        }        state->result->u.ucclass.index = state->classCount++;    claim:        /*         * Call CalculateBitmapSize now as we want any errors it finds         * to be reported during the parse phase, not at execution.         */        if (!CalculateBitmapSize(state, state->result, termStart, state->cp++))            return JS_FALSE;        state->progLength += 3; /* CLASS, <index> */        break;    case '.':        state->result = NewRENode(state, REOP_DOT);        goto doSimple;    case '*':    case '+':    case '?':        js_ReportCompileErrorNumber(state->context, state->tokenStream,                                    NULL, JSREPORT_ERROR,                                    JSMSG_BAD_QUANTIFIER, state->cp - 1);        return JS_FALSE;    default:        state->result = NewRENode(state, REOP_FLAT);        if (!state->result)            return JS_FALSE;        state->result->u.flat.chr = c;        state->result->u.flat.length = 1;        state->result->kid = (void *) (state->cp - 1);        state->progLength += 3;        break;    }    return ParseQuantifier(state);}static JSBoolParseQuantifier(CompilerState *state){    RENode *term;    term = state->result;    if (state->cp < state->cpend) {        switch (*state->cp) {        case '+':            state->result = NewRENode(state, REOP_QUANT);            if (!state->result)                return JS_FALSE;            state->result->u.range.min = 1;            state->result->u.range.max = (uint16)-1;            /* <PLUS>, <next> ... <ENDCHILD> */            state->progLength += 4;            goto quantifier;        case '*':            state->result = NewRENode(state, REOP_QUANT);            if (!state->result)                return JS_FALSE;            state->result->u.range.min = 0;            state->result->u.range.max = (uint16)-1;            /* <STAR>, <next> ... <ENDCHILD> */            state->progLength += 4;            goto quantifier;        case '?':            state->result = NewRENode(state, REOP_QUANT);            if (!state->result)                return JS_FALSE;            state->result->u.range.min = 0;            state->result->u.range.max = 1;            /* <OPT>, <next> ... <ENDCHILD> */            state->progLength += 4;            goto quantifier;        case '{':       /* balance '}' */            {                intN err;                uintN min, max;                jschar c;                const jschar *errp = state->cp++;                c = *state->cp;                if (JS7_ISDEC(c)) {                    ++state->cp;                    min = GetDecimalValue(c, 0xFFFF, NULL, state);                    c = *state->cp;                    if (min == OVERFLOW_VALUE) {                        err = JSMSG_MIN_TOO_BIG;                        goto quantError;                    }                    if (c == ',') {                        c = *++state->cp;                        if (JS7_ISDEC(c)) {                            ++state->cp;                            max = GetDecimalValue(c, 0xFFFF, NULL, state);                            c = *state->cp;                            if (max == OVERFLOW_VALUE) {                                err = JSMSG_MAX_TOO_BIG;                                goto quantError;                            }                            if (min > max) {                                err = JSMSG_OUT_OF_ORDER;                                goto quantError;                            }                        } else {                            max = (uintN)-1;                        }                    } else {                        max = min;                    }                    if (c == '}') {                        state->result = NewRENode(state, REOP_QUANT);                        if (!state->result)                            return JS_FALSE;                        state->result->u.range.min = min;                        state->result->u.range.max = max;                        /* QUANT, <min>, <max>, <next> ... <ENDCHILD> */                        state->progLength += 8;                        goto quantifier;                    }                }                state->cp = errp;                return JS_TRUE;quantError:                js_ReportCompileErrorNumber(state->context,                                            state->tokenStream,                                            NULL, JSREPORT_ERROR,                                            err, errp);                return JS_FALSE;            }        }    }    return JS_TRUE;quantifier:    ++state->treeDepth;    ++state->cp;    state->result->kid = term;    if (state->cp < state->cpend && *state->cp == '?') {        ++state->cp;        state->result->u.range.greedy = JS_FALSE;    }    else        state->result->u.range.greedy = JS_TRUE;    return JS_TRUE;}#define CHECK_OFFSET(diff) (JS_ASSERT(((diff) >= -32768) && ((diff) <= 32767)))#define SET_OFFSET(pc,off) ((pc)[0] = JUMP_OFFSET_HI(off),                     \                                 (pc)[1] = JUMP_OFFSET_LO(off))#define GET_OFFSET(pc)     ((int16)(((pc)[0] << 8) | (pc)[1]))#define OFFSET_LEN         (2)#define GET_ARG(pc)        GET_OFFSET(pc)#define SET_ARG(pc,arg)    SET_OFFSET(pc,arg)#define ARG_LEN            OFFSET_LEN/* * Recursively generate bytecode for the tree rooted at t. Iteratively. */typedef struct {    RENode *nextAlt;    jsbytecode *nextAltFixup, *nextTermFixup, *endTermFixup;    RENode *continueNode;    REOp continueOp;} EmitStateStackEntry;static jsbytecode *EmitREBytecode(CompilerState *state, JSRegExp *re, intN treeDepth,               jsbytecode *pc, RENode *t){    ptrdiff_t diff;    RECharSet *charSet;    EmitStateStackEntry *emitStateSP, *emitStateStack = NULL;    REOp op;    if (treeDepth) {        emitStateStack =            (EmitStateStackEntry *)JS_malloc(state->context,                                             sizeof(EmitStateStackEntry) *                                             treeDepth);        if (!emitStateStack)            return NULL;    }    emitStateSP = emitStateStack;    op = t->op;    while (JS_TRUE) {        *pc++ = op;        switch (op) {        case REOP_EMPTY:            --pc;            break;        case REOP_ALTPREREQ2:        case REOP_ALTPREREQ:            JS_ASSERT(emitStateSP);            emitStateSP->endTermFixup = pc;            pc += OFFSET_LEN;            SET_ARG(pc, t->u.altprereq.ch1);            pc += ARG_LEN;            SET_ARG(pc, t->u.altprereq.ch2);            pc += ARG_LEN;            emitStateSP->nextAltFixup = pc;    /* address of next alternate */            pc += OFFSET_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_JUMP;            ++emitStateSP;            JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->kid;            op = t->op;            continue;        case REOP_JUMP:            emitStateSP->nextTermFixup = pc;    /* address of following term */            pc += OFFSET_LEN;            diff = pc - emitStateSP->nextAltFixup;            CHECK_OFFSET(diff);            SET_OFFSET(emitStateSP->nextAltFixup, diff);            emitStateSP->continueOp = REOP_ENDALT;            ++emitStateSP;            JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->u.kid2;            op = t->op;            continue;        case REOP_ENDALT:            diff = pc - emitStateSP->nextTermFixup;            CHECK_OFFSET(diff);            SET_OFFSET(emitStateSP->nextTermFixup, diff);            if (t->op != REOP_ALT) {                diff = pc - emitStateSP->endTermFixup;                CHECK_OFFSET(diff);                SET_OFFSET(emitStateSP->endTermFixup, diff);            }            break;        case REOP_ALT:            JS_ASSERT(emitStateSP);            emitStateSP->nextAltFixup = pc; /* address of pointer to next alternate */            pc += OFFSET_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_JUMP;            ++emitStateSP;            JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->kid;            op = t->op;            continue;        case REOP_FLAT:            /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -