96 lines
3.9 KiB
Java
96 lines
3.9 KiB
Java
|
package com.ibm.wala.shrikeCT;
|
||
|
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
|
||
|
import com.ibm.wala.shrikeCT.ClassReader.AttrIterator;
|
||
|
import com.ibm.wala.shrikeCT.StackMapConstants.Item;
|
||
|
import com.ibm.wala.shrikeCT.StackMapConstants.ObjectType;
|
||
|
import com.ibm.wala.shrikeCT.StackMapConstants.StackMapFrame;
|
||
|
import com.ibm.wala.shrikeCT.StackMapConstants.StackMapType;
|
||
|
|
||
|
public class StackMapTableReader extends AttributeReader {
|
||
|
private List<StackMapFrame> frames;
|
||
|
|
||
|
public List<StackMapFrame> frames() {
|
||
|
return frames;
|
||
|
}
|
||
|
|
||
|
private StackMapType item(int offset) throws InvalidClassFileException {
|
||
|
Item item = StackMapConstants.items[cr.getByte(offset)];
|
||
|
if (item.isObject()) {
|
||
|
return new ObjectType(cr.getCP().getCPClass(cr.getUShort(offset+1)));
|
||
|
} else {
|
||
|
return item;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public StackMapTableReader(AttrIterator iter) throws InvalidClassFileException {
|
||
|
super(iter, "StackMapTable");
|
||
|
frames = new ArrayList<StackMapFrame>();
|
||
|
int entries = cr.getUShort(attr+6);
|
||
|
int ptr = attr + 8;
|
||
|
for(int i = 0; i < entries; i++) {
|
||
|
int frameType = (0x000000ff & cr.getByte(ptr++));
|
||
|
if (frameType < 63) {
|
||
|
int offset = frameType;
|
||
|
frames.add(new StackMapFrame(frameType, offset, new StackMapType[0], new StackMapType[0]));
|
||
|
} else if (frameType < 128) {
|
||
|
int offset = frameType - 64;
|
||
|
StackMapType stack1 = item(ptr);
|
||
|
ptr += (stack1 instanceof ObjectType)? 3: 1;
|
||
|
frames.add(new StackMapFrame(frameType, offset, new StackMapType[0], new StackMapType[]{ stack1 }));
|
||
|
} else if (frameType == 247) {
|
||
|
int offset = cr.getUShort(ptr); ptr += 2;
|
||
|
StackMapType stack1 = item(ptr);
|
||
|
ptr += (stack1 instanceof ObjectType)? 3: 1;
|
||
|
frames.add(new StackMapFrame(frameType, offset, new StackMapType[0], new StackMapType[]{ stack1 }));
|
||
|
} else if (frameType >= 248 && frameType <= 250) {
|
||
|
int offset = cr.getUShort(ptr); ptr += 2;
|
||
|
frames.add(new StackMapFrame(frameType, offset, new StackMapType[0], new StackMapType[0]));
|
||
|
} else if (frameType == 251) {
|
||
|
int offset = cr.getUShort(ptr); ptr += 2;
|
||
|
frames.add(new StackMapFrame(frameType, offset, new StackMapType[0], new StackMapType[0]));
|
||
|
} else if (frameType >= 252 && frameType <= 254) {
|
||
|
StackMapType[] locals = new StackMapType[ frameType - 251 ];
|
||
|
int offset = cr.getUShort(ptr); ptr += 2;
|
||
|
for(int j = 0; j < locals.length; j++) {
|
||
|
locals[j] = item(ptr);
|
||
|
ptr += (locals[j] instanceof ObjectType)? 3: 1;
|
||
|
}
|
||
|
frames.add(new StackMapFrame(frameType, offset, locals, new StackMapType[0]));
|
||
|
} else if (frameType == 255) {
|
||
|
int offset = cr.getUShort(ptr); ptr += 2;
|
||
|
|
||
|
int numLocals = cr.getUShort(ptr); ptr += 2;
|
||
|
StackMapType[] locals = new StackMapType[ numLocals ];
|
||
|
for(int j = 0; j < numLocals; j++) {
|
||
|
locals[j] = item(ptr);
|
||
|
ptr += (locals[j] instanceof ObjectType)? 3: 1;
|
||
|
}
|
||
|
|
||
|
int numStack = cr.getUShort(ptr); ptr += 2;
|
||
|
StackMapType[] stack = new StackMapType[ numStack ];
|
||
|
for(int j = 0; j < numStack; j++) {
|
||
|
stack[j] = item(ptr);
|
||
|
ptr += (stack[j] instanceof ObjectType)? 3: 1;
|
||
|
}
|
||
|
|
||
|
frames.add(new StackMapFrame(frameType, offset, locals, stack));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static List<StackMapFrame> readStackMap(CodeReader code) throws InvalidClassFileException, IllegalArgumentException {
|
||
|
ClassReader.AttrIterator iter = new ClassReader.AttrIterator();
|
||
|
code.initAttributeIterator(iter);
|
||
|
for (; iter.isValid(); iter.advance()) {
|
||
|
if (iter.getName().equals("StackMapTable")) {
|
||
|
StackMapTableReader r = new StackMapTableReader(iter);
|
||
|
return r.frames();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
}
|