/*
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package jdk.nashorn.internal.runtime.regexp.joni;

import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isNewLine;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindCondition;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindLongest;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindNotEmpty;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotBol;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotEol;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isPosixRegion;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;

class ByteCodeMachine extends StackMachine {
    private int bestLen;          // return value
    private int s = 0;            // current char

    private int range;            // right range
    private int sprev;
    private int sstart;
    private int sbegin;

    private final int[] code;       // byte code
    private int ip;                 // instruction pointer

    ByteCodeMachine(final Regex regex, final char[] chars, final int p, final int end) {
        super(regex, chars, p, end);
        this.code = regex.code;
    }

    private boolean stringCmpIC(final int caseFlodFlag, final int s1p, final IntHolder ps2, final int mbLen, final int textEnd) {
        int s1 = s1p;
        int s2 = ps2.value;
        final int end1 = s1 + mbLen;

        while (s1 < end1) {
            final char c1 = EncodingHelper.toLowerCase(chars[s1++]);
            final char c2 = EncodingHelper.toLowerCase(chars[s2++]);

            if (c1 != c2) {
                return false;
            }
        }
        ps2.value = s2;
        return true;
    }

    private void debugMatchBegin() {
        Config.log.println("match_at: " +
                "str: " + str +
                ", end: " + end +
                ", start: " + this.sstart +
                ", sprev: " + this.sprev);
        Config.log.println("size: " + (end - str) + ", start offset: " + (this.sstart - str));
    }

    private void debugMatchLoop() {
        if (Config.DEBUG_MATCH) {
            Config.log.printf("%4d", (s - str)).print("> \"");
            int q, i;
            for (i=0, q=s; i<7 && q<end && s>=0; i++) {
                if (q < end) {
                    Config.log.print(new String(new char[]{chars[q++]}));
                }
            }
            final String string = q < end ? "...\"" : "\"";
            q += string.length();
            Config.log.print(string);
            for (i=0; i<20-(q-s);i++) {
                Config.log.print(" ");
            }
            final StringBuilder sb = new StringBuilder();
            new ByteCodePrinter(regex).compiledByteCodeToString(sb, ip);
            Config.log.println(sb.toString());
        }
    }

    @Override
    protected final int matchAt(final int r, final int ss, final int sp) {
        this.range = r;
        this.sstart = ss;
        this.sprev = sp;

        stk = 0;
        ip = 0;

        if (Config.DEBUG_MATCH) {
            debugMatchBegin();
        }

        init();

        bestLen = -1;
        s = ss;

        final int[] c = this.code;
        while (true) {
            if (Config.DEBUG_MATCH) {
                debugMatchLoop();
            }

            sbegin = s;
            switch (c[ip++]) {
                case OPCode.END:    if (opEnd()) {
                    return finish();
                }                  break;
                case OPCode.EXACT1:                     opExact1();                break;
                case OPCode.EXACT2:                     opExact2();                continue;
                case OPCode.EXACT3:                     opExact3();                continue;
                case OPCode.EXACT4:                     opExact4();                continue;
                case OPCode.EXACT5:                     opExact5();                continue;
                case OPCode.EXACTN:                     opExactN();                continue;

                case OPCode.EXACT1_IC:                  opExact1IC();              break;
                case OPCode.EXACTN_IC:                  opExactNIC();              continue;

                case OPCode.CCLASS:                     opCClass();                break;
                case OPCode.CCLASS_MB:                  opCClassMB();              break;
                case OPCode.CCLASS_MIX:                 opCClassMIX();             break;
                case OPCode.CCLASS_NOT:                 opCClassNot();             break;
                case OPCode.CCLASS_MB_NOT:              opCClassMBNot();           break;
                case OPCode.CCLASS_MIX_NOT:             opCClassMIXNot();          break;
                case OPCode.CCLASS_NODE:                opCClassNode();            break;

                case OPCode.ANYCHAR:                    opAnyChar();               break;
                case OPCode.ANYCHAR_ML:                 opAnyCharML();             break;
                case OPCode.ANYCHAR_STAR:               opAnyCharStar();           break;
                case OPCode.ANYCHAR_ML_STAR:            opAnyCharMLStar();         break;
                case OPCode.ANYCHAR_STAR_PEEK_NEXT:     opAnyCharStarPeekNext();   break;
                case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:  opAnyCharMLStarPeekNext(); break;

                case OPCode.WORD:                       opWord();                  break;
                case OPCode.NOT_WORD:                   opNotWord();               break;
                case OPCode.WORD_BOUND:                 opWordBound();             continue;
                case OPCode.NOT_WORD_BOUND:             opNotWordBound();          continue;
                case OPCode.WORD_BEGIN:                 opWordBegin();             continue;
                case OPCode.WORD_END:                   opWordEnd();               continue;

                case OPCode.BEGIN_BUF:                  opBeginBuf();              continue;
                case OPCode.END_BUF:                    opEndBuf();                continue;
                case OPCode.BEGIN_LINE:                 opBeginLine();             continue;
                case OPCode.END_LINE:                   opEndLine();               continue;
                case OPCode.SEMI_END_BUF:               opSemiEndBuf();            continue;
                case OPCode.BEGIN_POSITION:             opBeginPosition();         continue;

                case OPCode.MEMORY_START_PUSH:          opMemoryStartPush();       continue;
                case OPCode.MEMORY_START:               opMemoryStart();           continue;
                case OPCode.MEMORY_END_PUSH:            opMemoryEndPush();         continue;
                case OPCode.MEMORY_END:                 opMemoryEnd();             continue;
                case OPCode.MEMORY_END_PUSH_REC:        opMemoryEndPushRec();      continue;
                case OPCode.MEMORY_END_REC:             opMemoryEndRec();          continue;

                case OPCode.BACKREF1:                   opBackRef1();              continue;
                case OPCode.BACKREF2:                   opBackRef2();              continue;
                case OPCode.BACKREFN:                   opBackRefN();              continue;
                case OPCode.BACKREFN_IC:                opBackRefNIC();            continue;
                case OPCode.BACKREF_MULTI:              opBackRefMulti();          continue;
                case OPCode.BACKREF_MULTI_IC:           opBackRefMultiIC();        continue;
                case OPCode.BACKREF_WITH_LEVEL:         opBackRefAtLevel();        continue;

                case OPCode.NULL_CHECK_START:           opNullCheckStart();        continue;
                case OPCode.NULL_CHECK_END:             opNullCheckEnd();          continue;
                case OPCode.NULL_CHECK_END_MEMST:       opNullCheckEndMemST();     continue;

                case OPCode.JUMP:                       opJump();                  continue;
                case OPCode.PUSH:                       opPush();                  continue;

                case OPCode.POP:                        opPop();                   continue;
                case OPCode.PUSH_OR_JUMP_EXACT1:        opPushOrJumpExact1();      continue;
                case OPCode.PUSH_IF_PEEK_NEXT:          opPushIfPeekNext();        continue;

                case OPCode.REPEAT:                     opRepeat();                continue;
                case OPCode.REPEAT_NG:                  opRepeatNG();              continue;
                case OPCode.REPEAT_INC:                 opRepeatInc();             continue;
                case OPCode.REPEAT_INC_SG:              opRepeatIncSG();           continue;
                case OPCode.REPEAT_INC_NG:              opRepeatIncNG();           continue;
                case OPCode.REPEAT_INC_NG_SG:           opRepeatIncNGSG();         continue;

                case OPCode.PUSH_POS:                   opPushPos();               continue;
                case OPCode.POP_POS:                    opPopPos();                continue;
                case OPCode.PUSH_POS_NOT:               opPushPosNot();            continue;
                case OPCode.FAIL_POS:                   opFailPos();               continue;
                case OPCode.PUSH_STOP_BT:               opPushStopBT();            continue;
                case OPCode.POP_STOP_BT:                opPopStopBT();             continue;

                case OPCode.LOOK_BEHIND:                opLookBehind();            continue;
                case OPCode.PUSH_LOOK_BEHIND_NOT:       opPushLookBehindNot();     continue;
                case OPCode.FAIL_LOOK_BEHIND_NOT:       opFailLookBehindNot();     continue;

                case OPCode.FINISH:
                    return finish();

                case OPCode.FAIL:                       opFail();                  continue;

                default:
                    throw new InternalException(ErrorMessages.ERR_UNDEFINED_BYTECODE);

            } // main switch
        } // main while
    }

    private boolean opEnd() {
        final int n = s - sstart;

        if (n > bestLen) {
            if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
                if (isFindLongest(regex.options)) {
                    if (n > msaBestLen) {
                        msaBestLen = n;
                        msaBestS = sstart;
                    } else {
                        // goto end_best_len;
                        return endBestLength();
                    }
                }
            } // USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE

            bestLen = n;
            final Region region = msaRegion;
            if (region != null) {
                // USE_POSIX_REGION_OPTION ... else ...
                region.beg[0] = msaBegin = sstart - str;
                region.end[0] = msaEnd   = s      - str;
                for (int i = 1; i <= regex.numMem; i++) {
                    // opt!
                    if (repeatStk[memEndStk + i] != INVALID_INDEX) {
                        region.beg[i] = bsAt(regex.btMemStart, i) ?
                                        stack[repeatStk[memStartStk + i]].getMemPStr() - str :
                                        repeatStk[memStartStk + i] - str;


                        region.end[i] = bsAt(regex.btMemEnd, i) ?
                                        stack[repeatStk[memEndStk + i]].getMemPStr() :
                                        repeatStk[memEndStk + i] - str;

                    } else {
                        region.beg[i] = region.end[i] = Region.REGION_NOTPOS;
                    }

                }

            } else {
                msaBegin = sstart - str;
                msaEnd   = s      - str;
            }
        } else {
            final Region region = msaRegion;
            if (Config.USE_POSIX_API_REGION_OPTION) {
                if (!isPosixRegion(regex.options)) {
                    if (region != null) {
                        region.clear();
                    } else {
                        msaBegin = msaEnd = 0;
                    }
                }
            } else {
                if (region != null) {
                    region.clear();
                } else {
                    msaBegin = msaEnd = 0;
                }
            } // USE_POSIX_REGION_OPTION
        }
        // end_best_len:
        /* default behavior: return first-matching result. */
        return endBestLength();
    }

    private boolean endBestLength() {
        if (isFindCondition(regex.options)) {
            if (isFindNotEmpty(regex.options) && s == sstart) {
                bestLen = -1;
                {opFail(); return false;} /* for retry */
            }
            if (isFindLongest(regex.options) && s < range) {
                {opFail(); return false;} /* for retry */
            }
        }
        // goto finish;
        return true;
    }

    private void opExact1() {
        if (s >= range || code[ip] != chars[s++]) {opFail(); return;}
        //if (s > range) {opFail(); return;}
        ip++;
        sprev = sbegin; // break;
    }

    private void opExact2() {
        if (s + 2 > range) {opFail(); return;}
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        sprev = s;
        ip++; s++;
    }

    private void opExact3() {
        if (s + 3 > range) {opFail(); return;}
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        sprev = s;
        ip++; s++;
    }

    private void opExact4() {
        if (s + 4 > range) {opFail(); return;}
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        sprev = s;
        ip++; s++;
    }

    private void opExact5() {
        if (s + 5 > range) {opFail(); return;}
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        ip++; s++;
        if (code[ip] != chars[s]) {opFail(); return;}
        sprev = s;
        ip++; s++;
    }

    private void opExactN() {
        int tlen = code[ip++];
        if (s + tlen > range) {opFail(); return;}

        if (Config.USE_STRING_TEMPLATES) {
            final char[] bs = regex.templates[code[ip++]];
            int ps = code[ip++];

            while (tlen-- > 0) {
                if (bs[ps++] != chars[s++]) {opFail(); return;}
            }

        } else {
            while (tlen-- > 0) {
                if (code[ip++] != chars[s++]) {opFail(); return;}
            }
        }
        sprev = s - 1;
    }

    private void opExact1IC() {
        if (s >= range || code[ip] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
        ip++;
        sprev = sbegin; // break;
    }

    private void opExactNIC() {
        int tlen = code[ip++];
        if (s + tlen > range) {opFail(); return;}

        if (Config.USE_STRING_TEMPLATES) {
            final char[] bs = regex.templates[code[ip++]];
            int ps = code[ip++];

            while (tlen-- > 0) {
                if (bs[ps++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
            }
        } else {

            while (tlen-- > 0) {
                if (code[ip++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
            }
        }
        sprev = s - 1;
    }

    private boolean isInBitSet() {
        final int c = chars[s];
        return (c <= 0xff && (code[ip + (c >>> BitSet.ROOM_SHIFT)] & (1 << c)) != 0);
    }

    private void opCClass() {
        if (s >= range || !isInBitSet()) {opFail(); return;}
        ip += BitSet.BITSET_SIZE;
        s++;
        sprev = sbegin; // break;
    }

    private boolean isInClassMB() {
        final int tlen = code[ip++];
        if (s >= range) {
            return false;
        }
        final int ss = s;
        s++;
        final int c = chars[ss];
        if (!EncodingHelper.isInCodeRange(code, ip, c)) {
            return false;
        }
        ip += tlen;
        return true;
    }

    private void opCClassMB() {
        // beyond string check
        if (s >= range || chars[s] <= 0xff) {opFail(); return;}
        if (!isInClassMB()) {opFail(); return;} // not!!!
        sprev = sbegin; // break;
    }

    private void opCClassMIX() {
        if (s >= range) {opFail(); return;}
        if (chars[s] > 0xff) {
            ip += BitSet.BITSET_SIZE;
            if (!isInClassMB()) {opFail(); return;}
        } else {
            if (!isInBitSet()) {opFail(); return;}
            ip += BitSet.BITSET_SIZE;
            final int tlen = code[ip++]; // by code range length
            ip += tlen;
            s++;
        }
        sprev = sbegin; // break;
    }

    private void opCClassNot() {
        if (s >= range || isInBitSet()) {opFail(); return;}
        ip += BitSet.BITSET_SIZE;
        s++;
        sprev = sbegin; // break;
    }

    private boolean isNotInClassMB() {
        final int tlen = code[ip++];

        if (!(s + 1 <= range)) {
            if (s >= range) {
                return false;
            }
            s = end;
            ip += tlen;
            return true;
        }

        final int ss = s;
        s++;
        final int c = chars[ss];

        if (EncodingHelper.isInCodeRange(code, ip, c)) {
            return false;
        }
        ip += tlen;
        return true;
    }

    private void opCClassMBNot() {
        if (s >= range) {opFail(); return;}
        if (chars[s] <= 0xff) {
            s++;
            final int tlen = code[ip++];
            ip += tlen;
            sprev = sbegin; // break;
            return;
        }
        if (!isNotInClassMB()) {opFail(); return;}
        sprev = sbegin; // break;
    }

    private void opCClassMIXNot() {
        if (s >= range) {opFail(); return;}
        if (chars[s] > 0xff) {
            ip += BitSet.BITSET_SIZE;
            if (!isNotInClassMB()) {opFail(); return;}
        } else {
            if (isInBitSet()) {opFail(); return;}
            ip += BitSet.BITSET_SIZE;
            final int tlen = code[ip++];
            ip += tlen;
            s++;
        }
        sprev = sbegin; // break;
    }

    private void opCClassNode() {
        if (s >= range) {opFail(); return;}
        final CClassNode cc = (CClassNode)regex.operands[code[ip++]];
        final int ss = s;
        s++;
        final int c = chars[ss];
        if (!cc.isCodeInCCLength(c)) {opFail(); return;}
        sprev = sbegin; // break;
    }

    private void opAnyChar() {
        if (s >= range) {opFail(); return;}
        if (isNewLine(chars[s])) {opFail(); return;}
        s++;
        sprev = sbegin; // break;
    }

    private void opAnyCharML() {
        if (s >= range) {opFail(); return;}
        s++;
        sprev = sbegin; // break;
    }

    private void opAnyCharStar() {
        final char[] ch = this.chars;
        while (s < range) {
            pushAlt(ip, s, sprev);
            if (isNewLine(ch, s, end)) {opFail(); return;}
            sprev = s;
            s++;
        }
        sprev = sbegin; // break;
    }

    private void opAnyCharMLStar() {
        while (s < range) {
            pushAlt(ip, s, sprev);
            sprev = s;
            s++;
        }
        sprev = sbegin; // break;
    }

    private void opAnyCharStarPeekNext() {
        final char c = (char)code[ip];
        final char[] ch = this.chars;

        while (s < range) {
            final char b = ch[s];
            if (c == b) {
                pushAlt(ip + 1, s, sprev);
            }
            if (isNewLine(b)) {opFail(); return;}
            sprev = s;
            s++;
        }
        ip++;
        sprev = sbegin; // break;
    }

    private void opAnyCharMLStarPeekNext() {
        final char c = (char)code[ip];
        final char[] ch = this.chars;

        while (s < range) {
            if (c == ch[s]) {
                pushAlt(ip + 1, s, sprev);
            }
            sprev = s;
            s++;
        }
        ip++;
        sprev = sbegin; // break;
    }

    private void opWord() {
        if (s >= range || !EncodingHelper.isWord(chars[s])) {opFail(); return;}
        s++;
        sprev = sbegin; // break;
    }

    private void opNotWord() {
        if (s >= range || EncodingHelper.isWord(chars[s])) {opFail(); return;}
        s++;
        sprev = sbegin; // break;
    }

    private void opWordBound() {
        if (s == str) {
            if (s >= range || !EncodingHelper.isWord(chars[s])) {opFail(); return;}
        } else if (s == end) {
            if (sprev >= end || !EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
        } else {
            if (EncodingHelper.isWord(chars[s]) == EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
        }
    }

    private void opNotWordBound() {
        if (s == str) {
            if (s < range && EncodingHelper.isWord(chars[s])) {opFail(); return;}
        } else if (s == end) {
            if (sprev < end && EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
        } else {
            if (EncodingHelper.isWord(chars[s]) != EncodingHelper.isWord(chars[sprev])) {opFail(); return;}
        }
    }

    private void opWordBegin() {
        if (s < range && EncodingHelper.isWord(chars[s])) {
            if (s == str || !EncodingHelper.isWord(chars[sprev])) {
                return;
            }
        }
        opFail();
    }

    private void opWordEnd() {
        if (s != str && EncodingHelper.isWord(chars[sprev])) {
            if (s == end || !EncodingHelper.isWord(chars[s])) {
                return;
            }
        }
        opFail();
    }

    private void opBeginBuf() {
        if (s != str) {
            opFail();
        }
    }

    private void opEndBuf() {
        if (s != end) {
            opFail();
        }
    }

    private void opBeginLine() {
        if (s == str) {
            if (isNotBol(msaOptions)) {
                opFail();
            }
            return;
        } else if (isNewLine(chars, sprev, end) && s != end) {
            return;
        }
        opFail();
    }

    private void opEndLine()  {
        if (s == end) {
            if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
                if (str == end || !isNewLine(chars, sprev, end)) {
                    if (isNotEol(msaOptions)) {
                        opFail();
                    }
                }
                return;
            }
            if (isNotEol(msaOptions)) {
                opFail();
            }
            return;
        } else if (isNewLine(chars, s, end)) {
            return;
        }
        opFail();
    }

    private void opSemiEndBuf() {
        if (s == end) {
            if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
                if (str == end || !isNewLine(chars, sprev, end)) {
                    if (isNotEol(msaOptions)) {
                        opFail();
                    }
                }
                return;
            }
            if (isNotEol(msaOptions)) {
                opFail();
            }
            return;
        } else if (isNewLine(chars, s, end) && s + 1 == end) {
            return;
        }
        opFail();
    }

    private void opBeginPosition() {
        if (s != msaStart) {
            opFail();
        }
    }

    private void opMemoryStartPush() {
        final int mem = code[ip++];
        pushMemStart(mem, s);
    }

    private void opMemoryStart() {
        final int mem = code[ip++];
        repeatStk[memStartStk + mem] = s;
    }

    private void opMemoryEndPush() {
        final int mem = code[ip++];
        pushMemEnd(mem, s);
    }

    private void opMemoryEnd() {
        final int mem = code[ip++];
        repeatStk[memEndStk + mem] = s;
    }

    private void opMemoryEndPushRec() {
        final int mem = code[ip++];
        final int stkp = getMemStart(mem); /* should be before push mem-end. */
        pushMemEnd(mem, s);
        repeatStk[memStartStk + mem] = stkp;
    }

    private void opMemoryEndRec() {
        final int mem = code[ip++];
        repeatStk[memEndStk + mem] = s;
        final int stkp = getMemStart(mem);

        if (BitStatus.bsAt(regex.btMemStart, mem)) {
            repeatStk[memStartStk + mem] = stkp;
        } else {
            repeatStk[memStartStk + mem] = stack[stkp].getMemPStr();
        }

        pushMemEndMark(mem);
    }

    private boolean backrefInvalid(final int mem) {
        return repeatStk[memEndStk + mem] == INVALID_INDEX || repeatStk[memStartStk + mem] == INVALID_INDEX;
    }

    private int backrefStart(final int mem) {
        return bsAt(regex.btMemStart, mem) ? stack[repeatStk[memStartStk + mem]].getMemPStr() : repeatStk[memStartStk + mem];
    }

    private int backrefEnd(final int mem) {
        return bsAt(regex.btMemEnd, mem) ? stack[repeatStk[memEndStk + mem]].getMemPStr() : repeatStk[memEndStk + mem];
    }

    private void backref(final int mem) {
        /* if you want to remove following line,
        you should check in parse and compile time. (numMem) */
        if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}

        int pstart = backrefStart(mem);
        final int pend = backrefEnd(mem);

        int n = pend - pstart;
        if (s + n > range) {opFail(); return;}
        sprev = s;

        // STRING_CMP
        while(n-- > 0) {
            if (chars[pstart++] != chars[s++]) {opFail(); return;}
        }

        // beyond string check
        if (sprev < range) {
            while (sprev + 1 < s) {
                sprev++;
            }
        }
    }

    private void opBackRef1() {
        backref(1);
    }

    private void opBackRef2() {
        backref(2);
    }

    private void opBackRefN() {
        backref(code[ip++]);
    }

    private void opBackRefNIC() {
        final int mem = code[ip++];
        /* if you want to remove following line,
        you should check in parse and compile time. (numMem) */
        if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}

        final int pstart = backrefStart(mem);
        final int pend = backrefEnd(mem);

        final int n = pend - pstart;
        if (s + n > range) {opFail(); return;}
        sprev = s;

        value = s;
        if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) {opFail(); return;}
        s = value;

        // if (sprev < chars.length)
        while (sprev + 1 < s) {
            sprev++;
        }
    }

    private void opBackRefMulti() {
        final int tlen = code[ip++];

        int i;
        loop:for (i=0; i<tlen; i++) {
            final int mem = code[ip++];
            if (backrefInvalid(mem)) {
                continue;
            }

            int pstart = backrefStart(mem);
            final int pend = backrefEnd(mem);

            int n = pend - pstart;
            if (s + n > range) {opFail(); return;}

            sprev = s;
            int swork = s;

            while (n-- > 0) {
                if (chars[pstart++] != chars[swork++]) {
                    continue loop;
                }
            }

            s = swork;

            // beyond string check
            if (sprev < range) {
                while (sprev + 1 < s) {
                    sprev++;
                }
            }

            ip += tlen - i  - 1; // * SIZE_MEMNUM (1)
            break; /* success */
        }
        if (i == tlen) {opFail(); return;}
    }

    private void opBackRefMultiIC() {
        final int tlen = code[ip++];

        int i;
        loop:for (i=0; i<tlen; i++) {
            final int mem = code[ip++];
            if (backrefInvalid(mem)) {
                continue;
            }

            final int pstart = backrefStart(mem);
            final int pend = backrefEnd(mem);

            final int n = pend - pstart;
            if (s + n > range) {opFail(); return;}

            sprev = s;

            value = s;
            if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end))
             {
                continue loop; // STRING_CMP_VALUE_IC
            }
            s = value;

            // if (sprev < chars.length)
            while (sprev + 1 < s) {
                sprev++;
            }

            ip += tlen - i  - 1; // * SIZE_MEMNUM (1)
            break;  /* success */
        }
        if (i == tlen) {opFail(); return;}
    }

    private boolean memIsInMemp(final int mem, final int num, final int mempp) {
        for (int i=0, memp = mempp; i<num; i++) {
            final int m = code[memp++];
            if (mem == m) {
                return true;
            }
        }
        return false;
    }

    // USE_BACKREF_AT_LEVEL // (s) and (end) implicit
    private boolean backrefMatchAtNestedLevel(final boolean ignoreCase, final int caseFoldFlag,
                                              final int nest, final int memNum, final int memp) {
        int pend = -1;
        int level = 0;
        int k = stk - 1;

        while (k >= 0) {
            final StackEntry e = stack[k];

            if (e.type == CALL_FRAME) {
                level--;
            } else if (e.type == RETURN) {
                level++;
            } else if (level == nest) {
                if (e.type == MEM_START) {
                    if (memIsInMemp(e.getMemNum(), memNum, memp)) {
                        final int pstart = e.getMemPStr();
                        if (pend != -1) {
                            if (pend - pstart > end - s) {
                                return false; /* or goto next_mem; */
                            }
                            int p = pstart;

                            value = s;
                            if (ignoreCase) {
                                if (!stringCmpIC(caseFoldFlag, pstart, this, pend - pstart, end)) {
                                    return false; /* or goto next_mem; */
                                }
                            } else {
                                while (p < pend) {
                                    if (chars[p++] != chars[value++]) {
                                        return false; /* or goto next_mem; */
                                    }
                                }
                            }
                            s = value;

                            return true;
                        }
                    }
                } else if (e.type == MEM_END) {
                    if (memIsInMemp(e.getMemNum(), memNum, memp)) {
                        pend = e.getMemPStr();
                    }
                }
            }
            k--;
        }
        return false;
    }

    private void opBackRefAtLevel() {
        final int ic      = code[ip++];
        final int level   = code[ip++];
        final int tlen    = code[ip++];

        sprev = s;
        if (backrefMatchAtNestedLevel(ic != 0, regex.caseFoldFlag, level, tlen, ip)) { // (s) and (end) implicit
            while (sprev + 1 < s) {
                sprev++;
            }
            ip += tlen; // * SIZE_MEMNUM
        } else {
            {opFail(); return;}
        }
    }

    private void opNullCheckStart() {
        final int mem = code[ip++];
        pushNullCheckStart(mem, s);
    }

    private void nullCheckFound() {
        // null_check_found:
        /* empty loop founded, skip next instruction */
        switch(code[ip++]) {
        case OPCode.JUMP:
        case OPCode.PUSH:
            ip++;       // p += SIZE_RELADDR;
            break;
        case OPCode.REPEAT_INC:
        case OPCode.REPEAT_INC_NG:
        case OPCode.REPEAT_INC_SG:
        case OPCode.REPEAT_INC_NG_SG:
            ip++;        // p += SIZE_MEMNUM;
            break;
        default:
            throw new InternalException(ErrorMessages.ERR_UNEXPECTED_BYTECODE);
        } // switch
    }

    private void opNullCheckEnd() {
        final int mem = code[ip++];
        final int isNull = nullCheck(mem, s); /* mem: null check id */

        if (isNull != 0) {
            if (Config.DEBUG_MATCH) {
                Config.log.println("NULL_CHECK_END: skip  id:" + mem + ", s:" + s);
            }

            nullCheckFound();
        }
    }

    // USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
    private void opNullCheckEndMemST() {
        final int mem = code[ip++];   /* mem: null check id */
        final int isNull = nullCheckMemSt(mem, s);

        if (isNull != 0) {
            if (Config.DEBUG_MATCH) {
                Config.log.println("NULL_CHECK_END_MEMST: skip  id:" + mem + ", s:" + s);
            }

            if (isNull == -1) {opFail(); return;}
            nullCheckFound();
        }
    }

    private void opJump() {
        ip += code[ip] + 1;
    }

    private void opPush() {
        final int addr = code[ip++];
        pushAlt(ip + addr, s, sprev);
    }

    private void opPop() {
        popOne();
    }

    private void opPushOrJumpExact1() {
        final int addr = code[ip++];
        // beyond string check
        if (s < range && code[ip] == chars[s]) {
            ip++;
            pushAlt(ip + addr, s, sprev);
            return;
        }
        ip += addr + 1;
    }

    private void opPushIfPeekNext() {
        final int addr = code[ip++];
        // beyond string check
        if (s < range && code[ip] == chars[s]) {
            ip++;
            pushAlt(ip + addr, s, sprev);
            return;
        }
        ip++;
    }

    private void opRepeat() {
        final int mem = code[ip++];   /* mem: OP_REPEAT ID */
        final int addr= code[ip++];

        // ensure1();
        repeatStk[mem] = stk;
        pushRepeat(mem, ip);

        if (regex.repeatRangeLo[mem] == 0) { // lower
            pushAlt(ip + addr, s, sprev);
        }
    }

    private void opRepeatNG() {
        final int mem = code[ip++];   /* mem: OP_REPEAT ID */
        final int addr= code[ip++];

        // ensure1();
        repeatStk[mem] = stk;
        pushRepeat(mem, ip);

        if (regex.repeatRangeLo[mem] == 0) {
            pushAlt(ip, s, sprev);
            ip += addr;
        }
    }

    private void repeatInc(final int mem, final int si) {
        final StackEntry e = stack[si];

        e.increaseRepeatCount();

        if (e.getRepeatCount() >= regex.repeatRangeHi[mem]) {
            /* end of repeat. Nothing to do. */
        } else if (e.getRepeatCount() >= regex.repeatRangeLo[mem]) {
            pushAlt(ip, s, sprev);
            ip = e.getRepeatPCode(); /* Don't use stkp after PUSH. */
        } else {
            ip = e.getRepeatPCode();
        }
        pushRepeatInc(si);
    }

    private void opRepeatInc() {
        final int mem = code[ip++];   /* mem: OP_REPEAT ID */
        final int si = repeatStk[mem];
        repeatInc(mem, si);
    }

    private void opRepeatIncSG() {
        final int mem = code[ip++];   /* mem: OP_REPEAT ID */
        final int si = getRepeat(mem);
        repeatInc(mem, si);
    }

    private void repeatIncNG(final int mem, final int si) {
        final StackEntry e = stack[si];

        e.increaseRepeatCount();

        if (e.getRepeatCount() < regex.repeatRangeHi[mem]) {
            if (e.getRepeatCount() >= regex.repeatRangeLo[mem]) {
                final int pcode = e.getRepeatPCode();
                pushRepeatInc(si);
                pushAlt(pcode, s, sprev);
            } else {
                ip = e.getRepeatPCode();
                pushRepeatInc(si);
            }
        } else if (e.getRepeatCount() == regex.repeatRangeHi[mem]) {
            pushRepeatInc(si);
        }
    }

    private void opRepeatIncNG() {
        final int mem = code[ip++];
        final int si = repeatStk[mem];
        repeatIncNG(mem, si);
    }

    private void opRepeatIncNGSG() {
        final int mem = code[ip++];
        final int si = getRepeat(mem);
        repeatIncNG(mem, si);
    }

    private void opPushPos() {
        pushPos(s, sprev);
    }

    private void opPopPos() {
        final StackEntry e = stack[posEnd()];
        s    = e.getStatePStr();
        sprev= e.getStatePStrPrev();
    }

    private void opPushPosNot() {
        final int addr = code[ip++];
        pushPosNot(ip + addr, s, sprev);
    }

    private void opFailPos() {
        popTilPosNot();
        opFail();
    }

    private void opPushStopBT() {
        pushStopBT();
    }

    private void opPopStopBT() {
        stopBtEnd();
    }

    private void opLookBehind() {
        final int tlen = code[ip++];
        s = EncodingHelper.stepBack(str, s, tlen);
        if (s == -1) {opFail(); return;}
        sprev = EncodingHelper.prevCharHead(str, s);
    }

    private void opPushLookBehindNot() {
        final int addr = code[ip++];
        final int tlen = code[ip++];
        final int q = EncodingHelper.stepBack(str, s, tlen);
        if (q == -1) {
            /* too short case -> success. ex. /(?<!XXX)a/.match("a")
            If you want to change to fail, replace following line. */
            ip += addr;
            // return FAIL;
        } else {
            pushLookBehindNot(ip + addr, s, sprev);
            s = q;
            sprev = EncodingHelper.prevCharHead(str, s);
        }
    }

    private void opFailLookBehindNot() {
        popTilLookBehindNot();
        opFail();
    }

    private void opFail() {
        if (stack == null) {
            ip = regex.codeLength - 1;
            return;
        }


        final StackEntry e = pop();
        ip    = e.getStatePCode();
        s     = e.getStatePStr();
        sprev = e.getStatePStrPrev();
    }

    private int finish() {
        return bestLen;
    }
}
