use of org.objectweb.asm.tree.MethodInsnNode in project malmo by Microsoft.
the class OverclockingClassTransformer method overclockRenderer.
private static void overclockRenderer(ClassNode node, boolean isObfuscated) {
// We're attempting to turn this line from Minecraft.runGameLoop:
// this.updateDisplay();
// into this:
// TimeHelper.updateDisplay();
// TimeHelper's method then decides whether or not to pass the call on to Minecraft.updateDisplay().
final String methodName = isObfuscated ? "as" : "runGameLoop";
// No params, returns void.
final String methodDescriptor = "()V";
System.out.println("MALMO: Found Minecraft, attempting to transform it");
for (MethodNode method : node.methods) {
if (method.name.equals(methodName) && method.desc.equals(methodDescriptor)) {
System.out.println("MALMO: Found Minecraft.runGameLoop() method, attempting to transform it");
for (AbstractInsnNode instruction : method.instructions.toArray()) {
if (instruction.getOpcode() == Opcodes.INVOKEVIRTUAL) {
MethodInsnNode visitMethodNode = (MethodInsnNode) instruction;
if (visitMethodNode.name.equals(isObfuscated ? "h" : "updateDisplay")) {
visitMethodNode.owner = "com/microsoft/Malmo/Utils/TimeHelper";
if (isObfuscated) {
visitMethodNode.name = "updateDisplay";
}
visitMethodNode.setOpcode(Opcodes.INVOKESTATIC);
// ALOAD 0 not needed for static invocation.
method.instructions.remove(visitMethodNode.getPrevious());
System.out.println("MALMO: Hooked into call to Minecraft.updateDisplay()");
}
}
}
}
}
}
use of org.objectweb.asm.tree.MethodInsnNode 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.MethodInsnNode in project enumerable by hraberg.
the class ExpressionInterpreter method naryOperation.
@SuppressWarnings({ "rawtypes", "unchecked" })
public Value naryOperation(final AbstractInsnNode insn, final List values) throws AnalyzerException {
if (insn.getOpcode() == MULTIANEWARRAY) {
throw new UnsupportedOperationException(AbstractVisitor.OPCODES[insn.getOpcode()]);
} else {
MethodInsnNode node = (MethodInsnNode) insn;
ClassOrInterfaceType returnType = createClassOrInterfaceType(getReturnType(node.desc).getClassName());
Expression scope = null;
boolean isConstructor = node.getOpcode() == INVOKESPECIAL && "<init>".equals(node.name);
if (node.getOpcode() == INVOKESTATIC) {
String className = getObjectType(node.owner).getClassName();
scope = new NameExpr(removeJavaLang(className));
} else if (!isConstructor) {
ExpressionValue target = (ExpressionValue) values.remove(0);
if (!(target.expression instanceof ThisExpr))
scope = target.expression;
}
List<Expression> arguments = values.isEmpty() ? null : new ArrayList<Expression>();
for (ExpressionValue value : (List<ExpressionValue>) values) arguments.add(value.expression);
if (isConstructor) {
arguments.remove(0);
ExpressionValue newExpressionValue = (ExpressionValue) values.remove(0);
ClassOrInterfaceType type = (ClassOrInterfaceType) newExpressionValue.type;
newExpressionValue.expression = new ObjectCreationExpr(scope, type, arguments.isEmpty() ? null : arguments);
return new ExpressionValue(returnType, newExpressionValue.expression);
}
return new ExpressionValue(returnType, new MethodCallExpr(scope, node.name, arguments));
}
}
use of org.objectweb.asm.tree.MethodInsnNode in project jphp by jphp-compiler.
the class ClosureValueCompiler method write.
@Override
public void write(ClosureStmtToken closure, boolean returnValue) {
if (returnValue) {
ClosureEntity entity = compiler.getModule().findClosure(closure.getId());
boolean thisExists = closure.getFunction().isThisExists();
boolean staticExists = closure.getFunction().isStaticExists();
if (closure.getFunction().getUses().isEmpty() && !thisExists && !staticExists && closure.getFunction().getStaticLocal().isEmpty()) {
expr.writePushEnv();
expr.writePushConstString(compiler.getModule().getInternalName());
expr.writePushConstInt((int) entity.getId());
expr.writeSysDynamicCall(Environment.class, "__getSingletonClosure", Memory.class, String.class, Integer.TYPE);
} else {
add(new TypeInsnNode(NEW, entity.getInternalName()));
expr.stackPush(Memory.Type.REFERENCE);
expr.writePushDup();
expr.writePushEnv();
expr.writePushEnv();
expr.writePushConstString(compiler.getModule().getInternalName());
expr.writePushConstInt((int) entity.getId());
expr.writeSysDynamicCall(Environment.class, "__getClosure", ClassEntity.class, String.class, Integer.TYPE);
if (thisExists)
expr.writePushThis();
else
expr.writePushNull();
writeContext();
writePushUses(closure.getFunction().getUses());
add(new MethodInsnNode(INVOKESPECIAL, entity.getInternalName(), Constants.INIT_METHOD, Type.getMethodDescriptor(Type.getType(void.class), Type.getType(Environment.class), Type.getType(ClassEntity.class), Type.getType(Memory.class), Type.getType(String.class), Type.getType(Memory[].class)), false));
expr.stackPop();
expr.stackPop();
expr.stackPop();
expr.stackPop();
expr.stackPop();
expr.stackPop();
expr.writeSysStaticCall(ObjectMemory.class, "valueOf", Memory.class, IObject.class);
}
expr.setStackPeekAsImmutable();
}
}
use of org.objectweb.asm.tree.MethodInsnNode in project pinpoint by naver.
the class ASMMethodNodeAdapter method addBeforeInterceptor.
public void addBeforeInterceptor(final int interceptorId, final InterceptorDefinition interceptorDefinition, final int apiId) {
initInterceptorLocalVariables(interceptorId, interceptorDefinition, apiId);
final InsnList instructions = new InsnList();
this.methodVariables.loadInterceptorLocalVariables(instructions, interceptorDefinition, false);
final String description = Type.getMethodDescriptor(interceptorDefinition.getBeforeMethod());
instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, Type.getInternalName(interceptorDefinition.getInterceptorBaseClass()), "before", description, true));
this.methodNode.instructions.insertBefore(this.methodVariables.getEnterInsnNode(), instructions);
}
Aggregations