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

📄 wrecgenerator.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if (m_parser.ignoreCase() && hasUpper) {        // for unicode case insensitive matches, branch here if upper matches.        isUpper.link(this);    }        // on success consume the char    add32(Imm32(1), index);}void Generator::generateCharacterClassInvertedRange(JumpList& failures, JumpList& matchDest, const CharacterRange* ranges, unsigned count, unsigned* matchIndex, const UChar* matches, unsigned matchCount){    do {        // pick which range we're going to generate        int which = count >> 1;        char lo = ranges[which].begin;        char hi = ranges[which].end;                // check if there are any ranges or matches below lo.  If not, just jl to failure -        // if there is anything else to check, check that first, if it falls through jmp to failure.        if ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {            Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));                        // generate code for all ranges before this one            if (which)                generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);                        while ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {                matchDest.append(branch32(Equal, character, Imm32((unsigned short)matches[*matchIndex])));                ++*matchIndex;            }            failures.append(jump());            loOrAbove.link(this);        } else if (which) {            Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));            generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);            failures.append(jump());            loOrAbove.link(this);        } else            failures.append(branch32(LessThan, character, Imm32((unsigned short)lo)));        while ((*matchIndex < matchCount) && (matches[*matchIndex] <= hi))            ++*matchIndex;        matchDest.append(branch32(LessThanOrEqual, character, Imm32((unsigned short)hi)));        // fall through to here, the value is above hi.        // shuffle along & loop around if there are any more matches to handle.        unsigned next = which + 1;        ranges += next;        count -= next;    } while (count);}void Generator::generateCharacterClassInverted(JumpList& matchDest, const CharacterClass& charClass){    Jump unicodeFail;    if (charClass.numMatchesUnicode || charClass.numRangesUnicode) {        Jump isAscii = branch32(LessThanOrEqual, character, Imm32(0x7f));            if (charClass.numMatchesUnicode) {            for (unsigned i = 0; i < charClass.numMatchesUnicode; ++i) {                UChar ch = charClass.matchesUnicode[i];                matchDest.append(branch32(Equal, character, Imm32(ch)));            }        }                if (charClass.numRangesUnicode) {            for (unsigned i = 0; i < charClass.numRangesUnicode; ++i) {                UChar lo = charClass.rangesUnicode[i].begin;                UChar hi = charClass.rangesUnicode[i].end;                                Jump below = branch32(LessThan, character, Imm32(lo));                matchDest.append(branch32(LessThanOrEqual, character, Imm32(hi)));                below.link(this);            }        }        unicodeFail = jump();        isAscii.link(this);    }    if (charClass.numRanges) {        unsigned matchIndex = 0;        JumpList failures;         generateCharacterClassInvertedRange(failures, matchDest, charClass.ranges, charClass.numRanges, &matchIndex, charClass.matches, charClass.numMatches);        while (matchIndex < charClass.numMatches)            matchDest.append(branch32(Equal, character, Imm32((unsigned short)charClass.matches[matchIndex++])));        failures.link(this);    } else if (charClass.numMatches) {        // optimization: gather 'a','A' etc back together, can mask & test once.        Vector<char> matchesAZaz;        for (unsigned i = 0; i < charClass.numMatches; ++i) {            char ch = charClass.matches[i];            if (m_parser.ignoreCase()) {                if (isASCIILower(ch)) {                    matchesAZaz.append(ch);                    continue;                }                if (isASCIIUpper(ch))                    continue;            }            matchDest.append(branch32(Equal, character, Imm32((unsigned short)ch)));        }        if (unsigned countAZaz = matchesAZaz.size()) {            or32(Imm32(32), character);            for (unsigned i = 0; i < countAZaz; ++i)                matchDest.append(branch32(Equal, character, Imm32(matchesAZaz[i])));        }    }    if (charClass.numMatchesUnicode || charClass.numRangesUnicode)        unicodeFail.link(this);}void Generator::generateCharacterClass(JumpList& failures, const CharacterClass& charClass, bool invert){    generateLoadCharacter(failures);    if (invert)        generateCharacterClassInverted(failures, charClass);    else {        JumpList successes;        generateCharacterClassInverted(successes, charClass);        failures.append(jump());        successes.link(this);    }        add32(Imm32(1), index);}void Generator::generateParenthesesAssertion(JumpList& failures){    JumpList disjunctionFailed;    push(index);    m_parser.parseDisjunction(disjunctionFailed);    Jump success = jump();    disjunctionFailed.link(this);    pop(index);    failures.append(jump());    success.link(this);    pop(index);}void Generator::generateParenthesesInvertedAssertion(JumpList& failures){    JumpList disjunctionFailed;    push(index);    m_parser.parseDisjunction(disjunctionFailed);    // If the disjunction succeeded, the inverted assertion failed.    pop(index);    failures.append(jump());    // If the disjunction failed, the inverted assertion succeeded.    disjunctionFailed.link(this);    pop(index);}void Generator::generateParenthesesNonGreedy(JumpList& failures, Label start, Jump success, Jump fail){    jump(start);    success.link(this);    failures.append(fail);}Generator::Jump Generator::generateParenthesesResetTrampoline(JumpList& newFailures, unsigned subpatternIdBefore, unsigned subpatternIdAfter){    Jump skip = jump();    newFailures.link(this);    for (unsigned i = subpatternIdBefore + 1; i <= subpatternIdAfter; ++i) {        store32(Imm32(-1), Address(output, (2 * i) * sizeof(int)));        store32(Imm32(-1), Address(output, (2 * i + 1) * sizeof(int)));    }        Jump newFailJump = jump();    skip.link(this);        return newFailJump;}void Generator::generateAssertionBOL(JumpList& failures){    if (m_parser.multiline()) {        JumpList previousIsNewline;        // begin of input == success        previousIsNewline.append(branch32(Equal, index, Imm32(0)));        // now check prev char against newline characters.        load16(BaseIndex(input, index, TimesTwo, -2), character);        generateCharacterClassInverted(previousIsNewline, CharacterClass::newline());        failures.append(jump());        previousIsNewline.link(this);    } else        failures.append(branch32(NotEqual, index, Imm32(0)));}void Generator::generateAssertionEOL(JumpList& failures){    if (m_parser.multiline()) {        JumpList nextIsNewline;        generateLoadCharacter(nextIsNewline); // end of input == success        generateCharacterClassInverted(nextIsNewline, CharacterClass::newline());        failures.append(jump());        nextIsNewline.link(this);    } else {        failures.append(branch32(NotEqual, length, index));    }}void Generator::generateAssertionWordBoundary(JumpList& failures, bool invert){    JumpList wordBoundary;    JumpList notWordBoundary;    // (1) Check if the previous value was a word char    // (1.1) check for begin of input    Jump atBegin = branch32(Equal, index, Imm32(0));    // (1.2) load the last char, and chck if is word character    load16(BaseIndex(input, index, TimesTwo, -2), character);    JumpList previousIsWord;    generateCharacterClassInverted(previousIsWord, CharacterClass::wordchar());    // (1.3) if we get here, previous is not a word char    atBegin.link(this);    // (2) Handle situation where previous was NOT a \w    generateLoadCharacter(notWordBoundary);    generateCharacterClassInverted(wordBoundary, CharacterClass::wordchar());    // (2.1) If we get here, neither chars are word chars    notWordBoundary.append(jump());    // (3) Handle situation where previous was a \w    // (3.0) link success in first match to here    previousIsWord.link(this);    generateLoadCharacter(wordBoundary);    generateCharacterClassInverted(notWordBoundary, CharacterClass::wordchar());    // (3.1) If we get here, this is an end of a word, within the input.        // (4) Link everything up        if (invert) {        // handle the fall through case        wordBoundary.append(jump());            // looking for non word boundaries, so link boundary fails to here.        notWordBoundary.link(this);        failures.append(wordBoundary);    } else {        // looking for word boundaries, so link successes here.        wordBoundary.link(this);                failures.append(notWordBoundary);    }}void Generator::generateBackreference(JumpList& failures, unsigned subpatternId){    push(index);    push(repeatCount);    // get the start pos of the backref into repeatCount (multipurpose!)    load32(Address(output, (2 * subpatternId) * sizeof(int)), repeatCount);    Jump skipIncrement = jump();    Label topOfLoop(this);    add32(Imm32(1), index);    add32(Imm32(1), repeatCount);    skipIncrement.link(this);    // check if we're at the end of backref (if we are, success!)    Jump endOfBackRef = branch32(Equal, Address(output, ((2 * subpatternId) + 1) * sizeof(int)), repeatCount);    load16(BaseIndex(input, repeatCount, MacroAssembler::TimesTwo), character);    // check if we've run out of input (this would be a can o'fail)    Jump endOfInput = branch32(Equal, length, index);    branch16(Equal, BaseIndex(input, index, TimesTwo), character, topOfLoop);    endOfInput.link(this);    // Failure    pop(repeatCount);    pop(index);    failures.append(jump());    // Success    endOfBackRef.link(this);    pop(repeatCount);    pop();}void Generator::terminateAlternative(JumpList& successes, JumpList& failures){    successes.append(jump());        failures.link(this);    peek(index);}void Generator::terminateDisjunction(JumpList& successes){    successes.link(this);}} } // namespace JSC::WREC#endif // ENABLE(WREC)

⌨️ 快捷键说明

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