use of org.objectweb.asm.tree.FieldInsnNode in project enumerable by hraberg.
the class ExpressionInterpreter method newOperation.
public Value newOperation(final AbstractInsnNode insn) throws AnalyzerException {
switch(insn.getOpcode()) {
case ACONST_NULL:
return new ExpressionValue(createClassOrInterfaceType(Object.class.getName()), new NullLiteralExpr());
case ICONST_M1:
return new ExpressionValue(PRIMITIVE_INT, new UnaryExpr(new IntegerLiteralExpr("1"), UnaryExpr.Operator.negative));
case ICONST_0:
return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("0"));
case ICONST_1:
return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("1"));
case ICONST_2:
return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("2"));
case ICONST_3:
return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("3"));
case ICONST_4:
return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("4"));
case ICONST_5:
return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("5"));
case LCONST_0:
return new ExpressionValue(PRIMITIVE_LONG, new LongLiteralExpr("0L"));
case LCONST_1:
return new ExpressionValue(PRIMITIVE_LONG, new LongLiteralExpr("1L"));
case FCONST_0:
return new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr("0.0f"));
case FCONST_1:
return new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr("1.0f"));
case FCONST_2:
return new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr("2.0f"));
case DCONST_0:
return new ExpressionValue(PRIMITIVE_DOUBLE, new DoubleLiteralExpr("0.0"));
case DCONST_1:
return new ExpressionValue(PRIMITIVE_DOUBLE, new DoubleLiteralExpr("1.0"));
case BIPUSH:
case SIPUSH:
int operand = ((IntInsnNode) insn).operand;
if (operand < 0)
return new ExpressionValue(PRIMITIVE_INT, new UnaryExpr(new IntegerLiteralExpr("" + Math.abs(operand)), UnaryExpr.Operator.negative));
return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("" + operand));
case LDC:
Object cst = ((LdcInsnNode) insn).cst;
if (cst instanceof Number) {
ExpressionValue value = null;
if (cst instanceof Integer) {
value = new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr(cst.toString()));
} else if (cst instanceof Float) {
value = new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr(cst.toString() + "f"));
} else if (cst instanceof Long) {
value = new ExpressionValue(PRIMITIVE_LONG, new LongLiteralExpr(cst.toString() + "L"));
} else if (cst instanceof Double) {
value = new ExpressionValue(PRIMITIVE_DOUBLE, new DoubleLiteralExpr(cst.toString()));
}
if (((Number) cst).intValue() < 0) {
StringLiteralExpr expr = (StringLiteralExpr) value.expression;
expr.setValue(expr.getValue().substring("-".length()));
value.expression = new UnaryExpr(expr, UnaryExpr.Operator.negative);
}
return value;
} else if (cst instanceof Type) {
ClassExpr classExpr = new ClassExpr(new ReferenceType(createClassOrInterfaceType(((Type) cst).getClassName())));
return new ExpressionValue(createClassOrInterfaceType(Class.class.getName()), classExpr);
} else {
return new ExpressionValue(createClassOrInterfaceType(String.class.getName()), new StringLiteralExpr(cst.toString()));
}
case JSR:
throw new UnsupportedOperationException(AbstractVisitor.OPCODES[insn.getOpcode()]);
case GETSTATIC:
FieldInsnNode fieldNode = (FieldInsnNode) insn;
ExpressionValue getField = (ExpressionValue) newValue(getType(fieldNode.desc));
getField.expression = new FieldAccessExpr(new NameExpr(removeJavaLang(getObjectType(fieldNode.owner).getClassName())), fieldNode.name);
return getField;
case NEW:
return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
default:
throw new Error("Internal error.");
}
}
use of org.objectweb.asm.tree.FieldInsnNode in project MinecraftForge by MinecraftForge.
the class EventSubscriptionTransformer method buildEvents.
private boolean buildEvents(ClassNode classNode) throws Exception {
// Yes, this recursively loads classes until we get this base class. THIS IS NOT A ISSUE. Coremods should handle re-entry just fine.
// If they do not this a COREMOD issue NOT a Forge/LaunchWrapper issue.
Class<?> parent = this.getClass().getClassLoader().loadClass(classNode.superName.replace('/', '.'));
if (!Event.class.isAssignableFrom(parent)) {
return false;
}
//Class<?> listenerListClazz = Class.forName("net.minecraftforge.fml.common.eventhandler.ListenerList", false, getClass().getClassLoader());
Type tList = Type.getType("Lnet/minecraftforge/fml/common/eventhandler/ListenerList;");
boolean edited = false;
boolean hasSetup = false;
boolean hasGetListenerList = false;
boolean hasDefaultCtr = false;
boolean hasCancelable = false;
boolean hasResult = false;
String voidDesc = Type.getMethodDescriptor(VOID_TYPE);
String boolDesc = Type.getMethodDescriptor(BOOLEAN_TYPE);
String listDesc = tList.getDescriptor();
String listDescM = Type.getMethodDescriptor(tList);
for (MethodNode method : classNode.methods) {
if (method.name.equals("setup") && method.desc.equals(voidDesc) && (method.access & ACC_PROTECTED) == ACC_PROTECTED)
hasSetup = true;
if ((method.access & ACC_PUBLIC) == ACC_PUBLIC) {
if (method.name.equals("getListenerList") && method.desc.equals(listDescM))
hasGetListenerList = true;
if (method.name.equals("isCancelable") && method.desc.equals(boolDesc))
hasCancelable = true;
if (method.name.equals("hasResult") && method.desc.equals(boolDesc))
hasResult = true;
}
if (method.name.equals("<init>") && method.desc.equals(voidDesc))
hasDefaultCtr = true;
}
if (classNode.visibleAnnotations != null) {
for (AnnotationNode node : classNode.visibleAnnotations) {
if (!hasResult && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Event$HasResult;")) {
/* Add:
* public boolean hasResult()
* {
* return true;
* }
*/
MethodNode method = new MethodNode(ACC_PUBLIC, "hasResult", boolDesc, null, null);
method.instructions.add(new InsnNode(ICONST_1));
method.instructions.add(new InsnNode(IRETURN));
classNode.methods.add(method);
edited = true;
} else if (!hasCancelable && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Cancelable;")) {
/* Add:
* public boolean isCancelable()
* {
* return true;
* }
*/
MethodNode method = new MethodNode(ACC_PUBLIC, "isCancelable", boolDesc, null, null);
method.instructions.add(new InsnNode(ICONST_1));
method.instructions.add(new InsnNode(IRETURN));
classNode.methods.add(method);
edited = true;
}
}
}
if (hasSetup) {
if (!hasGetListenerList)
throw new RuntimeException("Event class defines setup() but does not define getListenerList! " + classNode.name);
else
return edited;
}
Type tSuper = Type.getType(classNode.superName);
//Add private static ListenerList LISTENER_LIST
classNode.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, "LISTENER_LIST", listDesc, null, null));
/*Add:
* public <init>()
* {
* super();
* }
*/
if (!hasDefaultCtr) {
MethodNode method = new MethodNode(ACC_PUBLIC, "<init>", voidDesc, null, null);
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "<init>", voidDesc, false));
method.instructions.add(new InsnNode(RETURN));
classNode.methods.add(method);
}
/*Add:
* protected void setup()
* {
* super.setup();
* if (LISTENER_LIST != NULL)
* {
* return;
* }
* LISTENER_LIST = new ListenerList(super.getListenerList());
* }
*/
MethodNode method = new MethodNode(ACC_PROTECTED, "setup", voidDesc, null, null);
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "setup", voidDesc, false));
method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
LabelNode initListener = new LabelNode();
method.instructions.add(new JumpInsnNode(IFNULL, initListener));
method.instructions.add(new InsnNode(RETURN));
method.instructions.add(initListener);
method.instructions.add(new FrameNode(F_SAME, 0, null, 0, null));
method.instructions.add(new TypeInsnNode(NEW, tList.getInternalName()));
method.instructions.add(new InsnNode(DUP));
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "getListenerList", listDescM, false));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tList.getInternalName(), "<init>", getMethodDescriptor(VOID_TYPE, tList), false));
method.instructions.add(new FieldInsnNode(PUTSTATIC, classNode.name, "LISTENER_LIST", listDesc));
method.instructions.add(new InsnNode(RETURN));
classNode.methods.add(method);
/*Add:
* public ListenerList getListenerList()
* {
* return this.LISTENER_LIST;
* }
*/
method = new MethodNode(ACC_PUBLIC, "getListenerList", listDescM, null, null);
method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
method.instructions.add(new InsnNode(ARETURN));
classNode.methods.add(method);
return true;
}
use of org.objectweb.asm.tree.FieldInsnNode in project flink by apache.
the class NestedMethodAnalyzer method binaryOperation.
@Override
public BasicValue binaryOperation(AbstractInsnNode insn, BasicValue value1, BasicValue value2) throws AnalyzerException {
switch(insn.getOpcode()) {
case // put value2 into value1
PUTFIELD:
// skip untagged values
if (!isTagged(value1)) {
return null;
}
final TaggedValue taggedValue = (TaggedValue) value1;
final FieldInsnNode field = (FieldInsnNode) insn;
final boolean value2HasInputDependency = hasImportantDependencies(value2);
// PUTFIELD on inputs is not allowed
if (!taggedValue.isInput() && value2HasInputDependency) {
if (!taggedValue.canContainFields()) {
taggedValue.setTag(Tag.CONTAINER);
}
taggedValue.addContainerMapping(field.name, tagged(value2), currentFrame);
} else // PUTFIELD on inputs is not allowed
if (!taggedValue.isInput() && !value2HasInputDependency) {
if (!taggedValue.canContainFields()) {
taggedValue.setTag(Tag.CONTAINER);
}
taggedValue.addContainerMapping(field.name, null, currentFrame);
} else // make input regular
if (taggedValue.isInput()) {
taggedValue.makeRegular();
}
return null;
default:
return super.binaryOperation(insn, value1, value2);
}
}
use of org.objectweb.asm.tree.FieldInsnNode in project bytecode-viewer by Konloch.
the class MemberQuery method matches.
@Override
public boolean matches(AbstractInsnNode ain) {
if (!(ain instanceof FieldInsnNode) && !(ain instanceof MethodInsnNode))
return false;
int opcode = ain.opcode();
String owner, name, desc;
if (ain instanceof FieldInsnNode) {
FieldInsnNode fin = (FieldInsnNode) ain;
owner = fin.owner;
name = fin.name;
desc = fin.desc;
} else {
MethodInsnNode min = (MethodInsnNode) ain;
owner = min.owner;
name = min.name;
desc = min.desc;
}
if (this.opcode == -1 || this.opcode == opcode) {
if (this.owner == null || this.owner.equals(owner)) {
if (this.name == null || this.name.equals(name)) {
if (this.desc == null || this.desc.equals(desc) || desc.matches(this.desc)) {
return true;
}
}
}
}
return false;
}
use of org.objectweb.asm.tree.FieldInsnNode in project bytecode-viewer by Konloch.
the class BasicVerifier method binaryOperation.
@Override
public BasicValue binaryOperation(final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2) throws AnalyzerException {
BasicValue expected1;
BasicValue expected2;
switch(insn.opcode()) {
case IALOAD:
expected1 = newValue(Type.getType("[I"));
expected2 = BasicValue.INT_VALUE;
break;
case BALOAD:
if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
expected1 = newValue(Type.getType("[Z"));
} else {
expected1 = newValue(Type.getType("[B"));
}
expected2 = BasicValue.INT_VALUE;
break;
case CALOAD:
expected1 = newValue(Type.getType("[C"));
expected2 = BasicValue.INT_VALUE;
break;
case SALOAD:
expected1 = newValue(Type.getType("[S"));
expected2 = BasicValue.INT_VALUE;
break;
case LALOAD:
expected1 = newValue(Type.getType("[J"));
expected2 = BasicValue.INT_VALUE;
break;
case FALOAD:
expected1 = newValue(Type.getType("[F"));
expected2 = BasicValue.INT_VALUE;
break;
case DALOAD:
expected1 = newValue(Type.getType("[D"));
expected2 = BasicValue.INT_VALUE;
break;
case AALOAD:
expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
expected2 = BasicValue.INT_VALUE;
break;
case IADD:
case ISUB:
case IMUL:
case IDIV:
case IREM:
case ISHL:
case ISHR:
case IUSHR:
case IAND:
case IOR:
case IXOR:
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
expected1 = BasicValue.INT_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case FADD:
case FSUB:
case FMUL:
case FDIV:
case FREM:
case FCMPL:
case FCMPG:
expected1 = BasicValue.FLOAT_VALUE;
expected2 = BasicValue.FLOAT_VALUE;
break;
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LREM:
case LAND:
case LOR:
case LXOR:
case LCMP:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.LONG_VALUE;
break;
case LSHL:
case LSHR:
case LUSHR:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case DADD:
case DSUB:
case DMUL:
case DDIV:
case DREM:
case DCMPL:
case DCMPG:
expected1 = BasicValue.DOUBLE_VALUE;
expected2 = BasicValue.DOUBLE_VALUE;
break;
case IF_ACMPEQ:
case IF_ACMPNE:
expected1 = BasicValue.REFERENCE_VALUE;
expected2 = BasicValue.REFERENCE_VALUE;
break;
case PUTFIELD:
FieldInsnNode fin = (FieldInsnNode) insn;
expected1 = newValue(Type.getObjectType(fin.owner));
expected2 = newValue(Type.getType(fin.desc));
break;
default:
throw new Error("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(insn, "First argument", expected1, value1);
} else if (!isSubTypeOf(value2, expected2)) {
throw new AnalyzerException(insn, "Second argument", expected2, value2);
}
if (insn.opcode() == AALOAD) {
return getElementValue(value1);
} else {
return super.binaryOperation(insn, value1, value2);
}
}
Aggregations