/** * Replaces the void `<init>(boolean)` constructor for a call to the * `void <init>(int, int, int)` one. */ private void replaceGregorianCalendarBooleanConstructor(ListIterator<AbstractInsnNode> instructions, MethodInsnNode targetMethod) { // Remove the call to GregorianCalendar(boolean) instructions.remove(); // Discard the already-pushed parameter for GregorianCalendar(boolean) instructions.add(new InsnNode(Opcodes.POP)); // Add parameters values for calling GregorianCalendar(int, int, int) instructions.add(new InsnNode(Opcodes.ICONST_0)); instructions.add(new InsnNode(Opcodes.ICONST_0)); instructions.add(new InsnNode(Opcodes.ICONST_0)); // Call GregorianCalendar(int, int, int) instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, targetMethod.owner, targetMethod.name, "(III)V", targetMethod.itf)); }
static void box(final Type type, ListIterator<AbstractInsnNode> instructions) { if (type.getSort() == OBJECT || type.getSort() == ARRAY) { return; } if (Type.VOID_TYPE.equals(type)) { instructions.add(new InsnNode(Opcodes.ACONST_NULL)); } else { Type boxed = getBoxedType(type); instructions.add(new TypeInsnNode(Opcodes.NEW, boxed.getInternalName())); if (type.getSize() == 2) { // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o instructions.add(new InsnNode(Opcodes.DUP_X2)); instructions.add(new InsnNode(Opcodes.DUP_X2)); instructions.add(new InsnNode(Opcodes.POP)); } else { // p -> po -> opo -> oop -> o instructions.add(new InsnNode(Opcodes.DUP_X1)); instructions.add(new InsnNode(Opcodes.SWAP)); } instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, boxed.getInternalName(), "<init>", "(" + type.getDescriptor() + ")V", false)); } }
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getType(RobolectricInternals.class).getInternalName(), "intercept", "(Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;", case Type.LONG: instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(Long.class))); instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Long.class), "longValue", Type.getMethodDescriptor(Type.LONG_TYPE), false)); break; case Type.FLOAT: instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(Float.class))); instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Float.class), "floatValue", Type.getMethodDescriptor(Type.FLOAT_TYPE), false)); break; case Type.DOUBLE: instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(Double.class))); instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Double.class), "doubleValue", Type.getMethodDescriptor(Type.DOUBLE_TYPE), false)); break; case Type.BOOLEAN: instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(Boolean.class))); instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Boolean.class), "booleanValue", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false)); break; case Type.INT: instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(Integer.class))); instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Integer.class), "intValue", Type.getMethodDescriptor(Type.INT_TYPE), false)); break; case Type.SHORT: instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(Short.class))); instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Short.class), "shortValue", Type.getMethodDescriptor(Type.SHORT_TYPE), false)); break; case Type.BYTE:
void writeSysCall(String internalClassName, int INVOKE_TYPE, String method, Class returnClazz, Class... paramClasses) { Type[] args = new Type[paramClasses.length]; if (INVOKE_TYPE == INVOKEVIRTUAL || INVOKE_TYPE == INVOKEINTERFACE) stackPop(); // this for (int i = 0; i < args.length; i++) { args[i] = Type.getType(paramClasses[i]); stackPop(); } code.add(new MethodInsnNode( INVOKE_TYPE, internalClassName, method, Type.getMethodDescriptor(Type.getType(returnClazz), args), false )); if (returnClazz != void.class) { stackPush(null, StackItem.Type.valueOf(returnClazz)); } }
@SuppressWarnings("unchecked") void writeSysCall(Class clazz, int INVOKE_TYPE, String method, Class returnClazz, Class... paramClasses) { if (INVOKE_TYPE != INVOKESPECIAL && clazz != null) { if (compiler.getScope().isDebugMode()) { if (!methodExists(clazz, method, paramClasses)) { throw new NoSuchMethodException(clazz, method, paramClasses); } } } Type[] args = new Type[paramClasses.length]; if (INVOKE_TYPE == INVOKEVIRTUAL || INVOKE_TYPE == INVOKEINTERFACE) stackPop(); // this for (int i = 0; i < args.length; i++) { args[i] = Type.getType(paramClasses[i]); stackPop(); } String owner = clazz == null ? this.method.clazz.node.name : Type.getInternalName(clazz); if (clazz == null && this.method.clazz.entity.isTrait()) throw new CriticalException("[Compiler Error] Cannot use current classname in Trait"); code.add(new MethodInsnNode( INVOKE_TYPE, owner, method, Type.getMethodDescriptor(Type.getType(returnClazz), args), clazz != null && clazz.isInterface() )); if (returnClazz != void.class) { stackPush(null, StackItem.Type.valueOf(returnClazz)); } }
mi = new MethodInsnNode(INVOKESTATIC, cw.getName(), sw.getShimMethodName(), sw.getShimDesc(), cw.isInterface());
constructor.instructions.add(new MethodInsnNode( INVOKESPECIAL, node.superName,
constructor.instructions.add(new MethodInsnNode( INVOKESPECIAL, node.superName, expressionCompiler.writeVarLoad("~env"); expressionCompiler.writeVarLoad("~class"); constructor.instructions.add(new MethodInsnNode( INVOKESPECIAL, node.superName,
add(new MethodInsnNode( INVOKESPECIAL, entity.getInternalName(), Constants.INIT_METHOD, Type.getMethodDescriptor(
code.add(new TypeInsnNode(NEW, Type.getInternalName(ReferenceMemory.class))); code.add(new InsnNode(DUP)); code.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(ReferenceMemory.class), Constants.INIT_METHOD, "()V", false)); } else if (memory instanceof ArrayMemory) { ArrayMemory array = (ArrayMemory) memory;
@Test public void shouldMatchMethodCallByOwnerAndName() { final ClassName clazz = ClassName.fromString("clazz"); assertTrue(methodCallTo(clazz, "name") .test(this.context, new MethodInsnNode(Opcodes.INVOKEINTERFACE, "clazz", "name", "desc", true))); assertFalse(methodCallTo(clazz, "name") .test(this.context, new MethodInsnNode(Opcodes.INVOKEINTERFACE, "clazz", "notName", "desc", true))); assertFalse(methodCallTo(clazz, "name") .test(this.context, new MethodInsnNode(Opcodes.INVOKEINTERFACE, "notClazz", "name", "desc", true))); } }
@Override public void visitMethodInsn(int arg0, String arg1, String arg2, String arg3) { super.visitMethodInsn(arg0, arg1, arg2, arg3); appendToBacklog(new MethodInsnNode(arg0, arg1, arg2, arg3)); }
@Override public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) { return new MethodInsnNode(opcode, owner, name, desc, itf).cloneAnnotations(this); } }
@Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { if (api < Opcodes.ASM5) { super.visitMethodInsn(opcode, owner, name, desc, itf); return; } instructions.add(new MethodInsnNode(opcode, owner, name, desc, itf)); }
private void insertDoubleComparisonL(AbstractInsnNode position, InsnList list) { MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "doubleSubL", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.DOUBLE_TYPE, Type.DOUBLE_TYPE }), false); list.insert(position, get); list.remove(position); }
private void generateArmProxyMatcher() { String proxyMatcherType = Types.PROXY_MATCHER.getInternalName(); // stack: <proxyMatcher> :: <rule> insert(new InsnNode(DUP_X1)); // stack: <rule> :: <proxyMatcher> :: <rule> insert(new TypeInsnNode(CHECKCAST, Types.MATCHER.getInternalName())); // stack: <rule> :: <proxyMatcher> :: <matcher> insert(new MethodInsnNode(INVOKEVIRTUAL, proxyMatcherType, "arm", '(' + Types.MATCHER_DESC + ")V", false)); // stack: <rule> }
private static InsnList generateRunViewConstructorInstructions(final MethodInsnNode methodInsn) { final InsnList list = new InsnList(); // stack: this list.add(new InsnNode(DUP)); // stack: this, this list.add(new MethodInsnNode(INVOKEVIRTUAL, methodInsn.owner, VIEW_CONSTRUCTOR_NAME, "()V")); // stack: this return list; }
private void generateStoreNewProxyMatcher() { String proxyMatcherType = Types.PROXY_MATCHER.getInternalName(); // stack: insert(new TypeInsnNode(NEW, proxyMatcherType)); // stack: <proxyMatcher> insert(new InsnNode(DUP)); // stack: <proxyMatcher> :: <proxyMatcher> insert(new MethodInsnNode(INVOKESPECIAL, proxyMatcherType, "<init>", "()V", false)); // stack: <proxyMatcher> generateStoreInCache(); // stack: <proxyMatcher> }
@SuppressWarnings({"unchecked"}) private void createNewInstanceMethod(ParserClassNode classNode) { MethodNode method = new MethodNode(ACC_PUBLIC, "newInstance", "()L" + Types.BASE_PARSER.getInternalName() + ';', null, null); InsnList instructions = method.instructions; instructions.add(new TypeInsnNode(NEW, classNode.name)); instructions.add(new InsnNode(DUP)); instructions.add(new MethodInsnNode(INVOKESPECIAL, classNode.name, "<init>", "()V", classNode.isInterface())); instructions.add(new InsnNode(ARETURN)); classNode.methods.add(method); }
public void process(ParserClassNode classNode, RuleMethod method) throws Exception { checkArgNotNull(classNode, "classNode"); checkArgNotNull(method, "method"); // replace all method code with a simple call to the super method method.instructions.clear(); method.instructions.add(new VarInsnNode(ALOAD, 0)); method.instructions.add(createArgumentLoaders(method.desc)); method.instructions.add(new MethodInsnNode(INVOKESPECIAL, classNode.getParentType().getInternalName(), method.name, method.desc, classNode.isInterface())); method.instructions.add(new InsnNode(ARETURN)); }