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

📄 jsregexp.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
             * Consecutize FLAT's if possible.             */            if (t->kid) {                while (t->next &&                       t->next->op == REOP_FLAT &&                       (jschar*)t->kid + t->u.flat.length ==                       (jschar*)t->next->kid) {                    t->u.flat.length += t->next->u.flat.length;                    t->next = t->next->next;                }            }            if (t->kid && (t->u.flat.length > 1)) {                if (state->flags & JSREG_FOLD)                    pc[-1] = REOP_FLATi;                else                    pc[-1] = REOP_FLAT;                SET_ARG(pc, (jschar *)t->kid - state->cpbegin);                pc += ARG_LEN;                SET_ARG(pc, t->u.flat.length);                pc += ARG_LEN;            } else if (t->u.flat.chr < 256) {                if (state->flags & JSREG_FOLD)                    pc[-1] = REOP_FLAT1i;                else                    pc[-1] = REOP_FLAT1;                *pc++ = (jsbytecode) t->u.flat.chr;            } else {                if (state->flags & JSREG_FOLD)                    pc[-1] = REOP_UCFLAT1i;                else                    pc[-1] = REOP_UCFLAT1;                SET_ARG(pc, t->u.flat.chr);                pc += ARG_LEN;            }            break;        case REOP_LPAREN:            JS_ASSERT(emitStateSP);            SET_ARG(pc, t->u.parenIndex);            pc += ARG_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_RPAREN;            ++emitStateSP;            JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->kid;            op = t->op;            continue;        case REOP_RPAREN:            SET_ARG(pc, t->u.parenIndex);            pc += ARG_LEN;            break;        case REOP_BACKREF:            SET_ARG(pc, t->u.parenIndex);            pc += ARG_LEN;            break;        case REOP_ASSERT:            JS_ASSERT(emitStateSP);            emitStateSP->nextTermFixup = pc;            pc += OFFSET_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_ASSERTTEST;            ++emitStateSP;            JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->kid;            op = t->op;            continue;        case REOP_ASSERTTEST:        case REOP_ASSERTNOTTEST:            diff = pc - emitStateSP->nextTermFixup;            CHECK_OFFSET(diff);            SET_OFFSET(emitStateSP->nextTermFixup, diff);            break;        case REOP_ASSERT_NOT:            JS_ASSERT(emitStateSP);            emitStateSP->nextTermFixup = pc;            pc += OFFSET_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_ASSERTNOTTEST;            ++emitStateSP;            JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->kid;            op = t->op;            continue;        case REOP_QUANT:            JS_ASSERT(emitStateSP);            if (t->u.range.min == 0 && t->u.range.max == (uint16)-1) {                pc[-1] = (t->u.range.greedy) ? REOP_STAR : REOP_MINIMALSTAR;            } else if (t->u.range.min == 0 && t->u.range.max == 1) {                pc[-1] = (t->u.range.greedy) ? REOP_OPT : REOP_MINIMALOPT;            } else if (t->u.range.min == 1 && t->u.range.max == (uint16) -1) {                pc[-1] = (t->u.range.greedy) ? REOP_PLUS : REOP_MINIMALPLUS;            } else {                if (!t->u.range.greedy)                    pc[-1] = REOP_MINIMALQUANT;                SET_ARG(pc, t->u.range.min);                pc += ARG_LEN;                SET_ARG(pc, t->u.range.max);                pc += ARG_LEN;            }            emitStateSP->nextTermFixup = pc;            pc += OFFSET_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_ENDCHILD;            ++emitStateSP;            JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->kid;            op = t->op;            continue;        case REOP_ENDCHILD:            diff = pc - emitStateSP->nextTermFixup;            CHECK_OFFSET(diff);            SET_OFFSET(emitStateSP->nextTermFixup, diff);            break;        case REOP_CLASS:            if (!t->u.ucclass.sense)                pc[-1] = REOP_NCLASS;            SET_ARG(pc, t->u.ucclass.index);            pc += ARG_LEN;            charSet = &re->classList[t->u.ucclass.index];            charSet->converted = JS_FALSE;            charSet->length = t->u.ucclass.bmsize;            charSet->u.src.startIndex = t->u.ucclass.startIndex;            charSet->u.src.length = t->u.ucclass.kidlen;            charSet->sense = t->u.ucclass.sense;            break;        default:            break;        }        t = t->next;        if (!t) {            if (emitStateSP == emitStateStack)                break;            --emitStateSP;            t = emitStateSP->continueNode;            op = emitStateSP->continueOp;        }        else            op = t->op;    }    if (emitStateStack)        JS_free(state->context, emitStateStack);    return pc;}JSRegExp *js_NewRegExp(JSContext *cx, JSTokenStream *ts,             JSString *str, uintN flags, JSBool flat){    JSRegExp *re;    void *mark;    CompilerState state;    size_t resize;    jsbytecode *endPC;    uint32 i;    size_t len;    re = NULL;    mark = JS_ARENA_MARK(&cx->tempPool);    state.context = cx;    state.tokenStream = ts;    state.cpbegin = state.cp = JSSTRING_CHARS(str);    state.cpend = state.cp + JSSTRING_LENGTH(str);    state.flags = flags;    state.parenCount = 0;    state.classCount = 0;    state.progLength = 0;    state.treeDepth = 0;    for (i = 0; i < CLASS_CACHE_SIZE; i++)        state.classCache[i].start = NULL;    len = JSSTRING_LENGTH(str);    if (len != 0 && flat) {        state.result = NewRENode(&state, REOP_FLAT);        state.result->u.flat.chr = *state.cpbegin;        state.result->u.flat.length = JSSTRING_LENGTH(str);        state.result->kid = (void *) state.cpbegin;        state.progLength += 5;    } else {        if (!ParseRegExp(&state))            goto out;    }    resize = sizeof *re + state.progLength + 1;    re = (JSRegExp *) JS_malloc(cx, JS_ROUNDUP(resize, sizeof(jsword)));    if (!re)        goto out;    re->classCount = state.classCount;    if (state.classCount) {        re->classList = (RECharSet *)JS_malloc(cx,                                               sizeof(RECharSet) *                                               state.classCount);        if (!re->classList)            goto out;    }    else        re->classList = NULL;    endPC = EmitREBytecode(&state, re, state.treeDepth, re->program, state.result);    if (!endPC) {        re = NULL;        goto out;    }    *endPC++ = REOP_END;    JS_ASSERT(endPC <= (re->program + (state.progLength + 1)));    re->nrefs = 1;    re->parenCount = state.parenCount;    re->flags = flags;    re->source = str;out:    JS_ARENA_RELEASE(&cx->tempPool, mark);    return re;}JSRegExp *js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts,                JSString *str, JSString *opt, JSBool flat){    uintN flags;    jschar *s;    size_t i, n;    char charBuf[2];    flags = 0;    if (opt) {        s = JSSTRING_CHARS(opt);        for (i = 0, n = JSSTRING_LENGTH(opt); i < n; i++) {            switch (s[i]) {            case 'g':                flags |= JSREG_GLOB;                break;            case 'i':                flags |= JSREG_FOLD;                break;            case 'm':                flags |= JSREG_MULTILINE;                break;            default:                charBuf[0] = (char)s[i];                charBuf[1] = '\0';                js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                            JSMSG_BAD_FLAG, charBuf);                return NULL;            }        }    }    return js_NewRegExp(cx, ts, str, flags, flat);}#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs)#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re)/* * Save the current state of the match - the position in the input * text as well as the position in the bytecode. The state of any * parent expressions is also saved (preceding state). * Contents of parenCount parentheses from parenIndex are also saved. */static REBackTrackData *PushBackTrackState(REGlobalData *gData, REOp op,                   jsbytecode *target, REMatchState *x, const jschar *cp,                   uintN parenIndex, intN parenCount){    intN i;    REBackTrackData *result =        (REBackTrackData *) ((char *)gData->backTrackSP + gData->cursz);    size_t sz = sizeof(REBackTrackData) +                gData->stateStackTop * sizeof(REProgState) +                parenCount * sizeof(RECapture);    ptrdiff_t btsize = gData->backTrackStackSize;    ptrdiff_t btincr = ((char *)result + sz) -                       ((char *)gData->backTrackStack + btsize);    if (btincr > 0) {        ptrdiff_t offset = (char *)result - (char *)gData->backTrackStack;        btincr = JS_ROUNDUP(btincr, btsize);        JS_ARENA_GROW_CAST(gData->backTrackStack, REBackTrackData *,                           &gData->pool, btsize, btincr);        if (!gData->backTrackStack)            return NULL;        gData->backTrackStackSize = btsize + btincr;        result = (REBackTrackData *) ((char *)gData->backTrackStack + offset);    }    gData->backTrackSP = result;    result->sz = gData->cursz;    gData->cursz = sz;    result->backtrack_op = op;    result->backtrack_pc = target;    result->cp = cp;    result->parenCount = parenCount;    result->saveStateStackTop = gData->stateStackTop;    JS_ASSERT(gData->stateStackTop);    memcpy(result + 1, gData->stateStack,           sizeof(REProgState) * result->saveStateStackTop);    /* FIXME: parenCount should be uintN */    JS_ASSERT(parenCount >= 0);    if (parenCount > 0) {        result->parenIndex = parenIndex;        memcpy((char *)(result + 1) +               sizeof(REProgState) * result->saveStateStackTop,               &x->parens[parenIndex],               sizeof(RECapture) * parenCount);        for (i = 0; i < parenCount; i++)            x->parens[parenIndex + i].index = -1;    }    return result;}/* *   Consecutive literal characters. */#if 0static REMatchState *FlatNMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,             intN length){    intN i;    if (x->cp + length > gData->cpend)        return NULL;    for (i = 0; i < length; i++) {        if (matchChars[i] != x->cp[i])            return NULL;    }    x->cp += length;    return x;}#endifstatic REMatchState *FlatNIMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,              intN length){    intN i;    if (x->cp + length > gData->cpend)        return NULL;    for (i = 0; i < length; i++) {        if (upcase(matchChars[i]) != upcase(x->cp[i]))            return NULL;    }    x->cp += length;    return x;}/* * 1. Evaluate DecimalEscape to obtain an EscapeValue E. * 2. If E is not a character then go to step 6. * 3. Let ch be E's character. * 4. Let A be a one-element RECharSet containing the character ch. * 5. Call CharacterSetMatcher(A, false) and return its Matcher result. * 6. E must be an integer. Let n be that integer. * 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception. * 8. Return an internal Matcher closure that takes two arguments, a State x *    and a Continuation c, and performs the following: *     1. Le

⌨️ 快捷键说明

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