List of usage examples for org.objectweb.asm MethodVisitor visitMethodInsn
@Deprecated public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor)
From source file:com.facebook.presto.bytecode.instruction.InvokeInstruction.java
License:Apache License
@Override public void accept(MethodVisitor visitor, MethodGenerationContext generationContext) { visitor.visitMethodInsn(opCode.getOpCode(), target.getClassName(), name, getMethodDescription()); }
From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java
License:Open Source License
public static byte[] compileFunc(TokenSource<RPNToken> source, String variable) throws ParsingError { // initialize class ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null, CompiledClassBase.class.getName().replace('.', '/'), new String[] { Evaluator.Function.class.getName().replace('.', '/') }); // create constructor MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); construct.visitCode();/*ww w . ja v a2 s .c om*/ construct.visitVarInsn(Opcodes.ALOAD, 0); construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'), "<init>", "()V"); construct.visitInsn(Opcodes.RETURN); construct.visitMaxs(0, 0); construct.visitEnd(); MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "(D)D", null, new String[] { "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" }); compileCommon(source, method, variable); writer.visitEnd(); return writer.toByteArray(); }
From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java
License:Open Source License
public static byte[] compileBasic(TokenSource<RPNToken> source) throws ParsingError { // initialize class ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null, CompiledClassBase.class.getName().replace('.', '/'), new String[] { Evaluator.Basic.class.getName().replace('.', '/') }); // create constructor MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); construct.visitCode();/*from w ww . j a v a 2 s. com*/ construct.visitVarInsn(Opcodes.ALOAD, 0); construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'), "<init>", "()V"); construct.visitInsn(Opcodes.RETURN); construct.visitMaxs(0, 0); construct.visitEnd(); MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "()D", null, new String[] { "com/github/rgcjonas/kuemmelgtr/core/ParsingError", "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" }); compileCommon(source, method, null); writer.visitEnd(); return writer.toByteArray(); }
From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java
License:Open Source License
private static void compileCommon(TokenSource<RPNToken> source, MethodVisitor method, String variable) throws ParsingError { method.visitCode();/*from w ww . ja v a 2 s . com*/ // we now can compile our token stream int currentStackSize = 0; // we keep track of the current stack size to throw errors if we encounter an invalid instruction RPNToken t; while ((t = source.nextToken()) != null) { if (t instanceof RPNToken.Operand) { // we push it onto the stack method.visitLdcInsn(((RPNToken.Operand) t).getValue()); currentStackSize++; } else if (t instanceof RPNToken.Operator) { RPNToken.Operator op = (RPNToken.Operator) t; if (currentStackSize < op.getNumOperands()) throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand(s)"); switch (op.getName()) { case "_add": method.visitInsn(Opcodes.DADD); currentStackSize--; break; case "_mult": method.visitInsn(Opcodes.DMUL); currentStackSize--; break; case "_sub": method.visitInsn(Opcodes.DSUB); currentStackSize--; break; case "_div": method.visitInsn(Opcodes.DDIV); currentStackSize--; break; case "_pow": method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", "pow", "(DD)D"); currentStackSize--; break; default: //HACK: support every function in java/lang/Math. Will be way more performant than any lookup-and-evaluate //TODO: implement more functions inline if (currentStackSize < 1) throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand"); try { Method meth = Math.class.getDeclaredMethod(op.getName(), double.class); // just check if it's available and hope it returns a double if (meth.getReturnType() != double.class) throw new NoSuchMethodException(); // we don't want to blow up at runtime, do we? method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", op.getName(), "(D)D"); } catch (NoSuchMethodException e) { // we do not give up. The method may be available at runtime. method.visitVarInsn(Opcodes.ALOAD, 0); method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double method.visitInsn(Opcodes.POP); method.visitLdcInsn(op.getName()); method.visitLdcInsn((int) op.getSrcLine()); method.visitLdcInsn((int) op.getSrcColumn()); method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CompiledClassBase.class.getName().replace('.', '/'), "resolveAndEvaluateFunction", "(DLjava/lang/String;II)D"); } } } else if (t instanceof RPNToken.VariableRecall) { // maybe, maybe the variable is an argument we can load if (variable != null && ((RPNToken.VariableRecall) t).getName().equalsIgnoreCase(variable)) { method.visitVarInsn(Opcodes.DLOAD, 1); } else { // we let our parent class do the hard work method.visitVarInsn(Opcodes.ALOAD, 0); method.visitLdcInsn(((RPNToken.VariableRecall) t).getName()); method.visitLdcInsn(t.getSrcLine()); method.visitLdcInsn(t.getSrcColumn()); method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CompiledClassBase.class.getName().replace('.', '/'), "getVariable", "(Ljava/lang/String;II)D"); } currentStackSize++; } else if (t instanceof RPNToken.VariableAssignment) { // also defer to our parent class // we do not give up. The method may be available at runtime. method.visitVarInsn(Opcodes.ALOAD, 0); method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double method.visitInsn(Opcodes.POP); method.visitLdcInsn(((RPNToken.VariableAssignment) t).getVariableName()); method.visitLdcInsn(t.getSrcLine()); method.visitLdcInsn(t.getSrcColumn()); method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CompiledClassBase.class.getName().replace('.', '/'), "setVariable", "(DLjava/lang/String;II)D"); } else { throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Unknown instruction: " + t); } } if (currentStackSize != 1) throw new ParsingError(0, 0, "Expected stack to be one value, found " + currentStackSize); method.visitInsn(Opcodes.DRETURN); method.visitMaxs(0, 0); method.visitEnd(); }
From source file:com.github.stokito.gag.agent.AnswerToLifeGenerator.java
License:Apache License
/** TODO: Support BigDecimal and BigInteger. */ private void visitObject(MethodVisitor mv, LocalVarInfo param) { Type paramType = param.getType(); if (Type.getType(Character.class).equals(paramType)) { mv.visitLdcInsn((char) FORTY_TWO); mv.visitMethodInsn(INVOKESTATIC, paramType.getInternalName(), "valueOf", "(C)L" + paramType.getInternalName() + ";"); mv.visitVarInsn(ASTORE, param.getIndex()); } else if (supportedValueOfTypes.contains(paramType)) { mv.visitLdcInsn(String.valueOf(FORTY_TWO)); mv.visitMethodInsn(INVOKESTATIC, paramType.getInternalName(), "valueOf", "(Ljava/lang/String;)L" + paramType.getInternalName() + ";"); mv.visitVarInsn(ASTORE, param.getIndex()); } else {/*from w w w .j a va 2s .c om*/ throwUnsupportedException(param); } }
From source file:com.github.stokito.gag.agent.RouletteGenerator.java
License:Apache License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] exceptions) { MethodVisitor mv = writer().visitMethod(access, name, desc, sig, exceptions); mv.visitCode();//w w w. j a va2s . c om MethodInfo method = classInfo().getMethod(name, desc); AnnoInfo anno = method.getAnnoFor(ROULETTE_TYPE); if (anno != null) { Double probability = (Double) anno.getValue("probability"); if (probability < 0.0 || probability > 1.0) { throw new AnnotationStateError("Probability (" + probability + ") needs to be between 0 and 1"); } Type exception = (Type) anno.getValue("exception"); // TODO: Figure out how to get the default value from the annotation itself. if (exception == null) { exception = Type.getType(RuntimeException.class); } String message = (String) anno.getValue("message"); Label okay = new Label(); mv.visitTypeInsn(NEW, "java/util/Random"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/Random", "<init>", "()V"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Random", "nextDouble", "()D"); mv.visitLdcInsn(probability); mv.visitInsn(DCMPG); mv.visitJumpInsn(IFGT, okay); mv.visitTypeInsn(NEW, exception.getInternalName()); mv.visitInsn(DUP); mv.visitLdcInsn(message); mv.visitMethodInsn(INVOKESPECIAL, exception.getInternalName(), "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); mv.visitLabel(okay); setInstrumented(true); } mv.visitEnd(); return mv; }
From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java
License:Apache License
private static void visitComparable(MethodVisitor mv, boolean be, Property property, LocalVarInfo param, Label okay) {/*from ww w . j ava 2s. c om*/ Type type = param.getType(); int index = param.getIndex(); switch (type.getSort()) { case Type.INT: case Type.SHORT: mv.visitVarInsn(ILOAD, index); break; case Type.LONG: mv.visitVarInsn(LLOAD, index); mv.visitInsn(LCONST_0); mv.visitInsn(LCMP); break; case Type.DOUBLE: mv.visitVarInsn(DLOAD, index); mv.visitInsn(DCONST_0); mv.visitInsn(DCMPG); break; case Type.FLOAT: mv.visitVarInsn(FLOAD, index); mv.visitInsn(FCONST_0); mv.visitInsn(FCMPG); break; case Type.OBJECT: if (type.equals(Type.getType(Integer.class))) { mv.visitVarInsn(ALOAD, index); mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Integer.class).getInternalName(), "intValue", "()I"); } else if (type.equals(Type.getType(Short.class))) { mv.visitVarInsn(ALOAD, index); mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Short.class).getInternalName(), "intValue", "()I"); } else if (type.equals(Type.getType(Long.class))) { mv.visitVarInsn(ALOAD, index); mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Long.class).getInternalName(), "longValue", "()J"); mv.visitInsn(LCONST_0); mv.visitInsn(LCMP); } else if (type.equals(Type.getType(Double.class))) { mv.visitVarInsn(ALOAD, index); mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Double.class).getInternalName(), "doubleValue", "()D"); mv.visitInsn(DCONST_0); mv.visitInsn(DCMPG); } else if (type.equals(Type.getType(Float.class))) { mv.visitVarInsn(ALOAD, index); mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Float.class).getInternalName(), "floatValue", "()F"); mv.visitInsn(FCONST_0); mv.visitInsn(FCMPG); } else { throw new AnnotationStateError("Unsupported type: " + type); } break; default: throw new AnnotationStateError("Unsupported type: " + type); } switch (property) { case NEGATIVE: mv.visitJumpInsn(be ? IFLT : IFGE, okay); break; case POSITIVE: mv.visitJumpInsn(be ? IFGT : IFLE, okay); break; case ZERO: mv.visitJumpInsn(be ? IFEQ : IFNE, okay); break; } }
From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java
License:Apache License
/** * The given Property needs to be either {@link Property#THE_BLUE_PILL} or * {@link Property#THE_RED_PILL}./*from w w w . jav a 2 s . co m*/ */ private static void visitPill(MethodVisitor mv, boolean be, Property property, LocalVarInfo param, Label okay) { if (param.getType().getSort() != Type.OBJECT) { throw new AnnotationStateError("Unsupported type: " + param.getType()); } // TODO: Also handle if parameter is null. Label notOkay = new Label(); // See if the param type matches a Pill type mv.visitVarInsn(ALOAD, param.getIndex()); mv.visitMethodInsn(INVOKEVIRTUAL, param.getType().getInternalName(), "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;"); mv.visitLdcInsn("Pill|ThePill|.*[\\.$]Pill|.*[\\.$]ThePill"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "matches", "(Ljava/lang/String;)Z"); if (be) { // If the param type does not match a Pill type, that's not okay, go to exception. mv.visitJumpInsn(FALSE, notOkay); } else { // If the param type does not match a Pill type, then that's okay, skip exception. mv.visitJumpInsn(FALSE, okay); } // At this point, the param type matches a Pill type. // So check if the param type is an enum type. mv.visitVarInsn(ALOAD, param.getIndex()); mv.visitTypeInsn(INSTANCEOF, "java/lang/Enum"); if (be) { // If the param type is not an enum, that's not okay, go to exception. mv.visitJumpInsn(FALSE, notOkay); } else { // If the param type is not an enum, that's okay, skip exception. mv.visitJumpInsn(FALSE, okay); } // Check that the Pill type has the property specified in the annotation. // First try to match on "BLUE" (or "RED"). mv.visitVarInsn(ALOAD, param.getIndex()); mv.visitTypeInsn(CHECKCAST, "java/lang/Enum"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Enum", "name", "()Ljava/lang/String;"); mv.visitLdcInsn(property == THE_BLUE_PILL ? "BLUE" : "RED"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z"); mv.visitJumpInsn(TRUE, be ? okay : notOkay); // Then try to see if the value ends with "BLUE_PILL" (or "RED_PILL"). mv.visitVarInsn(ALOAD, param.getIndex()); mv.visitTypeInsn(CHECKCAST, "java/lang/Enum"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Enum", "name", "()Ljava/lang/String;"); mv.visitLdcInsn(property == THE_BLUE_PILL ? "BLUE_PILL" : "RED_PILL"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "endsWith", "(Ljava/lang/String;)Z"); mv.visitJumpInsn(be ? TRUE : FALSE, okay); mv.visitLabel(notOkay); }
From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java
License:Apache License
private static void visitDeathStarPlans(MethodVisitor mv, boolean be, LocalVarInfo param, Label okay) { if (param.getType().getSort() != Type.OBJECT) { throw new AnnotationStateError("Unsupported type: " + param.getType()); }// ww w .jav a2 s . com Label notOkay = new Label(); // See if the param type matches a DeathStarPlans type mv.visitVarInsn(ALOAD, param.getIndex()); mv.visitMethodInsn(INVOKEVIRTUAL, param.getType().getInternalName(), "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;"); mv.visitLdcInsn("DeathStarPlans|TheDeathStarPlans|.*[\\.$]DeathStarPlans|.*[\\.$]TheDeathStarPlans"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "matches", "(Ljava/lang/String;)Z"); if (be) { // If the param type does not match a DeathStarPlans type, that's not okay, go to exception. mv.visitJumpInsn(FALSE, notOkay); } else { // If the param type does not match a DeathStarPlans type, then that's okay, skip exception. mv.visitJumpInsn(FALSE, okay); } // At this point, the param type matches a DeathStarPlans type. // So check if the param has an isStolen method. Label start = new Label(); Label end = new Label(); Label handler = new Label(); mv.visitTryCatchBlock(start, end, handler, null); mv.visitLabel(start); mv.visitVarInsn(ALOAD, param.getIndex()); mv.visitMethodInsn(INVOKEVIRTUAL, param.getType().getInternalName(), "getClass", "()Ljava/lang/Class;"); mv.visitLdcInsn("isStolen"); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); mv.visitVarInsn(ALOAD, param.getIndex()); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); mv.visitJumpInsn(be ? TRUE : FALSE, okay); mv.visitLabel(end); mv.visitJumpInsn(GOTO, notOkay); mv.visitLabel(handler); mv.visitInsn(POP); mv.visitLabel(notOkay); }
From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java
License:Apache License
private static void visitException(MethodVisitor mv, LocalVarInfo param, String message) { mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP);/*from w w w . j ava 2 s . c o m*/ StringBuilderVisitor sb = new StringBuilderVisitor(mv); sb.visitAppend(param.getName() + " = "); sb.visitAppend(param.getType(), param.getIndex()); sb.visitAppend(message); sb.visitToString(); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); }