
jas.InsnOperand Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasmin Show documentation
Show all versions of jasmin Show documentation
Java Assembler Interface for the Soot framework
// 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;
LabelOperand(Label l, Insn source)
{ target = l; this.source = source; this.wide = false; }
LabelOperand(Label l, Insn source, boolean wide)
{ target = l; this.source = source; this.wide = wide; }
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 { 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;
UnsignedByteWideOperand(int n) { val = n; }
int size(ClassEnv ce, CodeAttr code)
{
if (val >= 256) return 3;
return 1;
}
void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
throws IOException
{
if (val > 255)
out.writeByte((byte)(opc_wide));
}
void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
throws IOException
{
if (val > 255)
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)));
}
}
}
class PaddedCPOperand extends CPOperand {
PaddedCPOperand(CP cpe) {
super(cpe);
}
void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
throws IOException, jasError {
super.write(e, ce, out);
//add padding ("reserved for future use")
out.writeShort(0);
}
int size(ClassEnv ce, CodeAttr code) {
return super.size(ce, code) + 2 /*2 bytes padding*/;
}
}
// 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);
// LJH
// System.out.println("getting idx in size: " + idx);
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);
if (cpe instanceof ClassCP){
// If the constant is a Type (for .class constants),
// the class major version must be 49.0 (Java5) or more.
e.requireJava5();
}
}
void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
throws IOException, jasError
{
int idx = e.getCPIndex(cpe);
// LJH
// System.out.println("Writing " + idx + " which as a short is " +
// ((short) idx) + " and is " + wide);
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;
IincOperand(int vindex, int constt)
{ this.vindex = vindex; this.constt = constt; }
int size(ClassEnv ce, CodeAttr code)
{
if ((vindex > 255) ||
(constt > 127) ||
(constt < -128))
return 5;
else
return 2;
}
void resolve(ClassEnv e) { return; }
void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
throws IOException
{
if ((vindex > 255) ||
(constt > 127) ||
(constt < -128))
out.writeByte((byte)opc_wide);
}
void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
throws IOException
{
if ((vindex > 255) ||
(constt > 127) ||
(constt < -128))
{
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
{
Label dflt;
Insn source;
int match[];
Label jmp[];
LookupswitchOperand(Insn s, Label def, int m[], Label 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 - 2025 Weber Informatics LLC | Privacy Policy