Logo Search packages:      
Sourcecode: jruby-joni version File versions  Download package

ByteCodePrinter.java

/*
 * 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 org.joni;

import org.jcodings.Encoding;
import org.joni.ast.CClassNode;
import org.joni.constants.Arguments;
import org.joni.constants.OPCode;
import org.joni.constants.OPSize;
import org.joni.exception.InternalException;

00029 class ByteCodePrinter {
    int[]code;
    int codeLength;
    
    Object[]operands;
    int operantCount;
    Encoding enc;
    WarnCallback warnings;
    
    public ByteCodePrinter(Regex regex) {
        code = regex.code;
        codeLength = regex.codeLength;
        operands = regex.operands;
        operantCount = regex.operandLength;
        enc = regex.enc;        
        warnings = regex.warnings;
    }
    
    public String byteCodeListToString() {
        return compiledByteCodeListToString();
    }
    
    private void pString(StringBuilder sb, int len, int s) {
        sb.append(":");
        while (len-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
    }
    
    private void pLenString(StringBuilder sb, int len, int mbLen, int s) {
        int x = len * mbLen;
        sb.append(":" + len + ":");
        while (x-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
    }
    
    public int compiledByteCodeToString(StringBuilder sb, int bp) {
        int len, n, mem, addr, scn, cod;
        BitSet bs;
        CClassNode cc;

        sb.append("[" + OPCode.OpCodeNames[code[bp]]);
        int argType = OPCode.OpCodeArgTypes[code[bp]];
        int ip = bp;
        if (argType != Arguments.SPECIAL) {
            bp++;
            switch (argType) {
            case Arguments.NON:
                break;

            case Arguments.RELADDR:
                sb.append(":(" + code[bp] + ")");
                bp += OPSize.RELADDR;
                break;
                
            case Arguments.ABSADDR:
                sb.append(":(" + code[bp] + ")");
                bp += OPSize.ABSADDR;
                break;
                
            case Arguments.LENGTH:
                sb.append(":" + code[bp]);
                bp += OPSize.LENGTH;
                break;
                
            case Arguments.MEMNUM:
                sb.append(":" + code[bp]);
                bp += OPSize.MEMNUM;
                break;
            
            case Arguments.OPTION:
                sb.append(":" + code[bp]);
                bp += OPSize.OPTION;
                break;
                
            case Arguments.STATE_CHECK:
                sb.append(":" + code[bp]);
                bp += OPSize.STATE_CHECK;
                break;
            }
        } else {
            switch (code[bp++]) {
            case OPCode.EXACT1:
            case OPCode.ANYCHAR_STAR_PEEK_NEXT:
            case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:
            case OPCode.ANYCHAR_STAR_PEEK_NEXT_SB:                
            case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT_SB:
                  pString(sb, 1, bp++);
                break;
                
            case OPCode.EXACT2:
                pString(sb, 2, bp);
                bp += 2;
                break;
            
            case OPCode.EXACT3:
                pString(sb, 3, bp);
                bp += 3;
                break;
                
            case OPCode.EXACT4:
                pString(sb, 4, bp);
                bp += 4;
                break;
                
            case OPCode.EXACT5:
                pString(sb, 5, bp);                
                bp += 5;
                break;
                
            case OPCode.EXACTN:
                len = code[bp];
                bp += OPSize.LENGTH;
                pLenString(sb, len, 1, bp);
                bp += len;
                break;
                
            case OPCode.EXACTMB2N1:
                pString(sb, 2, bp);
                bp += 2;
                break;
                
            case OPCode.EXACTMB2N2:
                pString(sb, 4, bp);
                bp += 4;
                break;
                
            case OPCode.EXACTMB2N3:
                pString(sb, 6, bp);
                bp += 6;
                break;
                
            case OPCode.EXACTMB2N:
                len = code[bp];
                bp += OPSize.LENGTH;
                pLenString(sb, len, 2, bp);
                bp += len * 2;
                break;

            case OPCode.EXACTMB3N:
                len = code[bp];
                bp += OPSize.LENGTH;
                pLenString(sb, len, 3, bp);
                bp += len * 3;
                break;
                
            case OPCode.EXACTMBN:
                int mbLen = code[bp];
                bp += OPSize.LENGTH;
                len = code[bp];
                bp += OPSize.LENGTH;
                sb.append(":" + mbLen + ":" + len + ":");
                n = len * mbLen;
                while (n-- > 0) sb.append(new String(new byte[]{(byte)code[bp++]}));
                break;
                
            case OPCode.EXACT1_IC:
            case OPCode.EXACT1_IC_SB:
                final int MAX_CHAR_LENGTH = 6;
                byte[]bytes = new byte[MAX_CHAR_LENGTH];
                for (int i = 0; bp + i < code.length && i < MAX_CHAR_LENGTH; i++) bytes[i] = (byte)code[bp + i]; 
                len = enc.length(bytes, 0, MAX_CHAR_LENGTH);
                pString(sb, len, bp);
                bp += len;
                break;
                
            case OPCode.EXACTN_IC:
            case OPCode.EXACTN_IC_SB:
                len = code[bp];
                bp += OPSize.LENGTH;
                pLenString(sb, len, 1, bp);
                bp += len;
                break;
                
            case OPCode.CCLASS:
            case OPCode.CCLASS_SB:
                bs = new BitSet();
                System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
                n = bs.numOn();
                bp += BitSet.BITSET_SIZE;
                sb.append(":" + n);
                break;
                
            case OPCode.CCLASS_NOT:
            case OPCode.CCLASS_NOT_SB:
                bs = new BitSet();
                System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
                n = bs.numOn();
                bp += BitSet.BITSET_SIZE;
                sb.append(":" + n);
                break;
                
            case OPCode.CCLASS_MB:
            case OPCode.CCLASS_MB_NOT:                
                len = code[bp];
                bp += OPSize.LENGTH;
                cod = code[bp];
                //bp += OPSize.CODE_POINT;
                bp += len;
                sb.append(":" + cod + ":" + len); 
                break;

            case OPCode.CCLASS_MIX:
            case OPCode.CCLASS_MIX_NOT:
                bs = new BitSet();
                System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
                n = bs.numOn();
                bp += BitSet.BITSET_SIZE;
                len = code[bp];
                bp += OPSize.LENGTH;
                cod = code[bp];
                //bp += OPSize.CODE_POINT;
                bp += len;
                sb.append(":" + n + ":" + cod + ":" + len);
                break;

            case OPCode.CCLASS_NODE:
                cc = (CClassNode)operands[code[bp]];
                bp += OPSize.POINTER;
                n = cc.bs.numOn();
                sb.append(":" + cc + ":" + n);
                break;
                
            case OPCode.BACKREFN_IC:
                mem = code[bp];
                bp += OPSize.MEMNUM;
                sb.append(":" + mem);
                break;
                
            case OPCode.BACKREF_MULTI_IC:
            case OPCode.BACKREF_MULTI:
                sb.append(" ");
                len = code[bp];
                bp += OPSize.LENGTH;
                for (int i=0; i<len; i++) {
                    mem = code[bp];
                    bp += OPSize.MEMNUM;
                    if (i > 0) sb.append(", ");
                    sb.append(mem);
                }
                break;
                
            case OPCode.BACKREF_WITH_LEVEL: {
                int option = code[bp];
                bp += OPSize.OPTION;
                sb.append(":" + option);
                int level = code[bp];
                bp += OPSize.LENGTH;
                sb.append(":" + level);
                sb.append(" ");
                len = code[bp];
                bp += OPSize.LENGTH;
                for (int i=0; i<len; i++) {
                    mem = code[bp];
                    bp += OPSize.MEMNUM;
                    if (i > 0) sb.append(", ");
                    sb.append(mem);
                }
                break;
            }
            
            case OPCode.REPEAT:
            case OPCode.REPEAT_NG:
                mem = code[bp];
                bp += OPSize.MEMNUM;
                addr = code[bp];
                bp += OPSize.RELADDR;
                sb.append(":" + mem + ":" + addr);
                break;
                
            case OPCode.PUSH_OR_JUMP_EXACT1:
            case OPCode.PUSH_IF_PEEK_NEXT:
                addr = code[bp];
                bp += OPSize.RELADDR;
                sb.append(":(" + addr + ")");
                pString(sb, 1, bp);
                bp++;
                break;
                
            case OPCode.LOOK_BEHIND:
            case OPCode.LOOK_BEHIND_SB:
                len = code[bp];
                bp += OPSize.LENGTH;
                sb.append(":" + len);
                break;
                
            case OPCode.PUSH_LOOK_BEHIND_NOT:
                addr = code[bp];
                bp += OPSize.RELADDR;
                len = code[bp];
                bp += OPSize.LENGTH;
                sb.append(":" + len + ":(" + addr + ")");
                break;
                
            case OPCode.STATE_CHECK_PUSH:
            case OPCode.STATE_CHECK_PUSH_OR_JUMP:
                scn = code[bp];
                bp += OPSize.STATE_CHECK_NUM;
                addr = code[bp];
                bp += OPSize.RELADDR;
                sb.append(":" + scn + ":(" + addr + ")");
                break;
                
            default:
                throw new InternalException("undefined code: " + code[--bp]);
            }
        }

        sb.append("]");

        // @opcode_address(opcode_size)
        if (Config.DEBUG_COMPILE_BYTE_CODE_INFO) sb.append("@" + ip + "(" + (bp - ip) + ")");

        return bp;
    }

    private String compiledByteCodeListToString() {
        StringBuilder sb = new StringBuilder();
        sb.append("code length: " + codeLength + "\n");
        
        int ncode = 0;
        int bp = 0;
        int end = codeLength;
        
        while (bp < end) {
            ncode++;
            
            if (bp > 0) sb.append(ncode % 5 == 0 ? "\n" : " ");

            bp = compiledByteCodeToString(sb, bp);
        }
        sb.append("\n");
        return sb.toString();
    }
}

Generated by  Doxygen 1.6.0   Back to index