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

opu.lljvm-python.0.2.0-EXPERIMENTAL.source-code.InsnOperand Maven / Gradle / Ivy

The newest version!
                                // This is not visible outside the
                                // package. It is used to
                                // handle the various types
                                // of operands used by Insns.
package jas;

import java.io.*;

abstract class InsnOperand
{
  abstract void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError;
  abstract int size(ClassEnv e, CodeAttr code) throws jasError;
  abstract void resolve(ClassEnv e);
  void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  { return; }
}

                                // Used to implement targets of Insns
class LabelOperand extends InsnOperand
{
  Label target;
  Insn source;
  boolean wide;
  int ref;

  LabelOperand(Label l, Insn source, int line)
  { target = l; this.source = source; this.wide = false; this.ref = line; }
  LabelOperand(Label l, Insn source, boolean wide, int line)
  { target = l; this.source = source; this.wide = wide; this.ref = line; }
  int size(ClassEnv ce, CodeAttr code) { if (wide) return 4; else return 2; }
  void resolve(ClassEnv e) { return; }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  {
    if (wide) { target.writeWideOffset(ce, source, out); }
    else {
      int offset = ce.getPc(target);
      if (source != null)
        offset -= ce.getPc(source);
      if (offset > 32767 || offset < -32768)
        throw new jasError
          ("reference from line " +ref+ " exceed size for short");
      target.writeOffset(ce, source, out); }
    }
  }

class UnsignedByteOperand extends InsnOperand
{
  int val;

  UnsignedByteOperand(int n) { val = n; }
  int size(ClassEnv ce, CodeAttr code)  { return 1; }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  {
    if (val >= 256)
      throw
        new jasError("Operand is too large (" +val+ ") for this instruction");
    out.writeByte((byte)(0xff & val));
  }
  void resolve(ClassEnv e) { return; }
}

                                // This (conditionally) adds a wide
                                // prefix if the value is larger than
                                // 256
class UnsignedByteWideOperand extends InsnOperand
  implements RuntimeConstants
{
  int val;
  boolean Wide;

  UnsignedByteWideOperand(int n, boolean Wide)
  {
    val = n;
    this.Wide = (Wide || val > 255);
  }

  int size(ClassEnv ce, CodeAttr code)
  { return Wide ? 3: 1; }

  void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException
  {
    if (Wide)
      out.writeByte((byte)(opc_wide));
  }

  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException
  {
    if (Wide)
      out.writeShort((short)(0xffff & val));
    else
      out.writeByte((byte)(val & 0xff));
  }
  void resolve(ClassEnv e) { return; }
}

class ByteOperand extends InsnOperand
{
  int val;

  ByteOperand(int n) { val = n; }
  int size(ClassEnv ce, CodeAttr code) { return 1; }
  void resolve(ClassEnv e) { return; }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException
  { out.writeByte((byte)val); }
}

class IntegerOperand extends InsnOperand
{
  int val;

  IntegerOperand(int n) { val = n; }
  int size(ClassEnv ce, CodeAttr code) { return 4; }
  void resolve(ClassEnv e) { return; }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException
  { out.writeInt(val); }
}

class ShortOperand extends InsnOperand
{
  int offset;
  ShortOperand(int n) { offset = n; }
  void resolve(ClassEnv e) { return; }
  int size(ClassEnv ce, CodeAttr code) { return 2; }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException
  { out.writeShort((short)offset); }
}

class CPOperand extends InsnOperand
{
  CP cpe;
  boolean wide;
  int size(ClassEnv ce, CodeAttr code) { if (wide) return 2; else return 1; }
  CPOperand(CP cpe) { this.cpe = cpe; wide = true; }
  CPOperand(CP cpe, boolean wide)
  { this.cpe = cpe; this.wide = wide; }
  void resolve(ClassEnv e)
  { e.addCPItem(cpe); }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  {
    int idx = e.getCPIndex(cpe);
    if (wide)
      { out.writeShort((short) idx); }
    else
      {
        if (idx > 255)
          { throw new jasError("exceeded size for small cpidx" + cpe); }
        out.writeByte((byte) (0xff & (idx)));
      }
  }
}

                                // these are unique enough that
                                // they need a separate handler for their
                                // args
class LdcOperand extends InsnOperand implements RuntimeConstants
{
  CP cpe;
  Insn source;
  boolean wide;

  int size(ClassEnv ce, CodeAttr code) throws jasError
  {
    if (wide)
      { return 2; }
    else
      {
                                // Should we promote it?
        int idx = ce.getCPIndex(cpe);
        if (idx > 255)
          {
            wide = true;
            source.opc = opc_ldc_w;
            return 2;
          }
        return 1;
      }
  }
  LdcOperand(Insn s, CP cpe) { source = s; this.cpe = cpe; wide = true; }
  LdcOperand(Insn s, CP cpe, boolean wide)
  { source = s; this.cpe = cpe; this.wide = wide; }
  void resolve(ClassEnv e)
  { e.addCPItem(cpe); }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  {
    int idx = e.getCPIndex(cpe);
    if (wide)
      { out.writeShort((short) idx); }
    else
      {
        if (idx > 255)
          { throw new jasError("exceeded size for small cpidx" + cpe); }
        out.writeByte((byte) (0xff & (idx)));
      }
  }
}


class InvokeinterfaceOperand extends InsnOperand
{
  CP cpe;
  int nargs;

  InvokeinterfaceOperand(CP cpe, int nargs)
  { this.cpe = cpe; this.nargs = nargs; }

  int size(ClassEnv ce, CodeAttr code) { return 4; }

  void resolve(ClassEnv e)
  { e.addCPItem(cpe); }

  void write (ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  {
    out.writeShort(e.getCPIndex(cpe));
    out.writeByte((byte) (0xff & nargs));
    out.writeByte(0);
  }
}

class IincOperand extends InsnOperand
  implements RuntimeConstants
{
  int vindex, constt;
  boolean Wide;

  IincOperand(int vindex, int constt, boolean Wide)
  {
    this.vindex = vindex;
    this.constt = constt;
    this.Wide = (Wide ||
                 vindex > 255 ||
                 constt > 127 ||
                 constt < 127);
  }

  int size(ClassEnv ce, CodeAttr code)
  {
    return Wide ? 5 : 2;
  }

  void resolve(ClassEnv e) { return; }

  void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException
  {
    if (Wide)
      out.writeByte((byte)opc_wide);
  }

  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException
  {
    if (Wide)
      {
        out.writeShort((short)(0xffff & vindex));
        out.writeShort((short)(0xffff & constt));
      }
    else
      {
        out.writeByte((byte) (0xff & vindex));
        out.writeByte((byte) (0xff & constt));
      }
  }
}

class MultiarrayOperand extends InsnOperand
{
  CP cpe;
  int sz;

  MultiarrayOperand(CP cpe, int sz)
  { this.cpe = cpe; this.sz = sz; }
  void resolve(ClassEnv e) { e.addCPItem(cpe); }
  int size(ClassEnv ce, CodeAttr code) { return 3; }
  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  {
    out.writeShort(e.getCPIndex(cpe));
    out.writeByte((byte)(0xff & sz));
  }
}

class LookupswitchOperand extends InsnOperand
{
  LabelOrOffset dflt;
  Insn source;
  int match[];
  LabelOrOffset jmp[];

  LookupswitchOperand(Insn s, LabelOrOffset def, int m[], LabelOrOffset j[])
  { dflt = def; jmp = j;  match = m;  source = s; }

  void resolve (ClassEnv e) { return; }
  int size(ClassEnv ce, CodeAttr code) throws jasError
  {
    int sz = 8;			// 4 + 4 + padding + jumptable
    int source_pc = code.getPc(source);
    if (((source_pc+1) % 4) != 0)
      {
				// need padding
	sz += (4 - ((source_pc+1) % 4));
      }

    if (jmp != null)
      { sz += 8*(jmp.length); }
    return sz;
  }

  void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
    throws IOException, jasError
  {
    int pad;
    int source_pc = ce.getPc(source);

    if (((source_pc+1) % 4) != 0)
      {				// need padding
	pad = (4 - ((source_pc+1) % 4));
	for (int x=0; x




© 2015 - 2024 Weber Informatics LLC | Privacy Policy