All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.d2j.dex.writer.insn.JumpOp Maven / Gradle / Ivy

There is a newer version: 2.4.22
Show newest version
package com.googlecode.d2j.dex.writer.insn;

import com.googlecode.d2j.dex.writer.CodeWriter;
import com.googlecode.d2j.reader.Op;
import java.nio.ByteBuffer;

public class JumpOp extends OpInsn {

    final int a;

    final int b;

    final Label label;

    public JumpOp(Op op, int a, int b, Label label) {
        super(op);
        switch (op.format) {
        case kFmt31t:
        case kFmt21t:
            CodeWriter.checkRegAA(op, "vAA", a);
            break;
        case kFmt22t:
            CodeWriter.checkRegA(op, "vA", a);
            CodeWriter.checkRegA(op, "vB", b);
            break;
        default:
        }
        this.label = label;
        this.a = a;
        this.b = b;
    }

    @Override
    public void write(ByteBuffer out) {
        out.put((byte) op.opcode);
        int offset = label.offset - this.offset;
        switch (op.format) {
        case kFmt10t: // AA|op
            CodeWriter.checkContentByte(op, "+AA", offset);
            out.put((byte) offset);
            break;
        case kFmt20t: // ØØ|op AAAA
            CodeWriter.checkContentShort(op, "+AAAA", offset);
            out.put((byte) 0).putShort((short) offset);
            break;
        case kFmt30t: // ØØ|op AAAAlo AAAAhi
            out.put((byte) 0).putInt(offset);
            break;
        case kFmt31t: // AA|op BBBBlo BBBBhi
            out.put((byte) a).putInt(offset);
            break;
        case kFmt22t: // B|A|op CCCC
            CodeWriter.checkContentShort(op, "+CCCC", offset);
            out.put((byte) ((a & 0xF) | (b << 4))).putShort((short) offset);
            break;
        case kFmt21t: // AA|op BBBB
            CodeWriter.checkContentShort(op, "+BBBB", offset);
            out.put((byte) a).putShort((short) offset);
            break;
        default:
            throw new RuntimeException("not support");
        }
    }

    public boolean fit() {
        int offset = label.offset - this.offset;
        if ((op == Op.GOTO && (offset > Byte.MAX_VALUE || offset < Byte.MIN_VALUE))
                || (op == Op.GOTO_16 && (offset > Short.MAX_VALUE || offset < Short.MIN_VALUE))) {
            if ((offset > Short.MAX_VALUE || offset < Short.MIN_VALUE)) {
                op = Op.GOTO_32;
            } else {
                op = Op.GOTO_16;
            }
            return false;
        }
        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy