
jas.CodeAttr 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
The newest version!
// CHANGES,
// Instead of calling soot.tagkits.JasminAttribute.decode,
// jas has its own CodeAttributeDecode class which performs
// the same functionality. It will remove the dependency to
// soot package. However, the decode method should be changed
// according to the format of CodeAttribute if the format is
// changed in the future.
// Feng Qian
// Jan 25, 2001
/**
* CodeAttr's are used as a bag to hold lists of instructions
* until it is time to put them into a Class.
* @see ClassEnv#addMethod
* @author $Author: olhota $
* @version $Revision: 1.2 $
*/
package jas;
import java.io.*;
import java.util.*;
public class CodeAttr
{
static CP attr = new AsciiCP("Code");
short stack_size, num_locals;
int code_size;
Vector insns;
Hashtable insn_pc;
Catchtable ctb;
LineTableAttr ltab;
LocalVarTableAttr lvar;
Vector generic;
Vector sootAttrNames = new Vector();
Vector sootAttrValues = new Vector();
Hashtable labels;
/**
* Create a new bag. Add instructions with the addInsn() method,
* set the catch table with the setCatchTable() method.
* @see Insn
* @see Catchtable
* @see ClassEnv#addMethod
*/
public CodeAttr()
{
this.stack_size = 1;
this.num_locals = 1;
this.ctb = null;
this.insns = new Vector();
generic = new Vector();
}
/**
* Set the catchtable for this code
*/
public void setCatchtable(Catchtable ctb)
{ this.ctb = ctb; }
/**
* Set the line number table for this method
*/
public void setLineTable(LineTableAttr ltab)
{ this.ltab = ltab; }
/**
* Set the local variable information for this method
*/
public void setLocalVarTable(LocalVarTableAttr lvar)
{ this.lvar = lvar; }
/**
* Add a generic attribute to the method. A generic attribute
* contains a stream of uninterpreted bytes which is ignored by
* the VM (as long as its name doesn't conflict with other names
* for attributes that are understood by the VM)
*/
public void addGenericAttr(GenericAttr g)
{ generic.addElement(g); }
public void addSootCodeAttr(String name, String value)
{
sootAttrNames.addElement(name);
sootAttrValues.addElement(value);
}
Label getLabel(String name) {
Label lab = (Label)labels.get(name);
if (lab == null) {
lab = new Label(name);
labels.put(name, lab);
}
return lab;
}
public void setLabelTable(Hashtable labelTable)
{
labels = labelTable;
}
private int processSootAttributes() {
Hashtable labelToPc = new Hashtable();
int totalSize = 0;
Enumeration enumeration = sootAttrValues.elements();
Enumeration nameEnum = sootAttrNames.elements();
while(enumeration.hasMoreElements()) {
String attrValue = (String) enumeration.nextElement();
String attrName = (String) nameEnum.nextElement();
boolean isLabel = false;//xx what if it starts with %
StringTokenizer st = new StringTokenizer(attrValue, "%", true);
while(st.hasMoreTokens()) {
String token = (String) st.nextElement();
if( token.equals( "%" ) ) {
isLabel = !isLabel;
continue;
}
if(isLabel) {
Integer i = (Integer) labelToPc.get(token);
try {
if(i == null)
labelToPc.put(token, new Integer( getPc(getLabel(token))));
} catch(jas.jasError e) {throw new RuntimeException(e.toString());}
}
}
byte[] data = CodeAttributeDecoder.decode(attrValue, labelToPc);
GenericAttr ga = new GenericAttr(attrName, data);
totalSize += ga.size();
addGenericAttr(ga);
}
sootAttrNames.removeAllElements();
sootAttrValues.removeAllElements();
return totalSize;
}
/**
* Append a new Insn to this code. Insn's are sequentially
* stored, in the order in which this method is called. You
* can't reorder code fragments after you've added it here.
*/
public void addInsn(Insn insn)
{ insns.addElement(insn); }
public void setStackSize(short stack_size)
{ this.stack_size = stack_size; }
public void setVarSize(short num_vars)
{ num_locals = num_vars; }
void resolve(ClassEnv e)
{
// propagate this resolution to
// the insns and catch table, so
// that any CP's referenced by them
// also get added.
e.addCPItem(attr);
for (Enumeration en = insns.elements(); en.hasMoreElements();)
{
Insn i = (Insn)(en.nextElement());
i.resolve(e);
}
if (ctb != null) ctb.resolve(e);
if (ltab != null) ltab.resolve(e);
if (lvar != null) lvar.resolve(e);
for (Enumeration gen = generic.elements(); gen.hasMoreElements();)
{
GenericAttr gattr = (GenericAttr)gen.nextElement();
gattr.resolve(e);
}
}
public int getPc(Insn i)
throws jasError
{
if (insn_pc == null){
throw new jasError("Internal error, insn_pc has not been initialized");
}
Integer tmp;
if (i instanceof Label)
{
tmp = (Integer)(insn_pc.get(((Label)i).id));
}
else
{
tmp = (Integer)(insn_pc.get(i));
}
if (tmp == null)
throw new jasError(i + " has not been added to the code");
return tmp.intValue();
}
void write(ClassEnv e, DataOutputStream out)
throws IOException, jasError
{
// First, resolve all labels and
// compute total size
int code_size = 0;
insn_pc = new Hashtable();
for (Enumeration en = insns.elements(); en.hasMoreElements();)
{
Insn now = (Insn)(en.nextElement());
if (now instanceof Label)
{
insn_pc.put(((Label)now).id, new Integer(code_size));
}
else
{ insn_pc.put(now, new Integer(code_size)); }
code_size += now.size(e, this);
}
int total_size = code_size;
if (ctb != null) total_size += ctb.size();
if (ltab != null) total_size += ltab.size();
if (lvar != null) total_size += lvar.size();
for (Enumeration gen = generic.elements(); gen.hasMoreElements();)
{
GenericAttr gattr = (GenericAttr)(gen.nextElement());
total_size += gattr.size();
}
total_size += processSootAttributes();
// extra headers
total_size += 12;
out.writeShort(e.getCPIndex(attr));
out.writeInt(total_size);
out.writeShort(stack_size);
out.writeShort(num_locals);
out.writeInt(code_size);
for (Enumeration en = insns.elements(); en.hasMoreElements();)
{
Insn now = (Insn)(en.nextElement());
now.write(e, this, out);
}
if (ctb != null)
{ ctb.write(e, this, out); }
else
{ out.writeShort(0); }
short extra = 0;
if (ltab != null) extra++;
if (lvar != null) extra++;
extra += generic.size();
out.writeShort(extra);
if (ltab != null)
{ ltab.write(e, this, out); }
if (lvar != null)
{ lvar.write(e, this, out); }
for (Enumeration gen = generic.elements(); gen.hasMoreElements();)
{
GenericAttr gattr = (GenericAttr)gen.nextElement();
gattr.write(e, out);
}
}
public String toString()
{ return ("<#code-attr>"); }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy