List of usage examples for org.objectweb.asm.commons Method getMethod
public static Method getMethod(final String method)
From source file:org.glowroot.agent.weaving.WeavingClassVisitor.java
License:Apache License
@RequiresNonNull("type") private void addShim(ShimType shimType) { for (java.lang.reflect.Method reflectMethod : shimType.shimMethods()) { Method method = Method.getMethod(reflectMethod); Shim shim = reflectMethod.getAnnotation(Shim.class); checkNotNull(shim);// w ww. j a va 2 s . c o m Method targetMethod = Method.getMethod(shim.value()); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, method.getName(), method.getDescriptor(), null, null); mv.visitCode(); int i = 0; mv.visitVarInsn(ALOAD, i++); for (Type argumentType : method.getArgumentTypes()) { mv.visitVarInsn(argumentType.getOpcode(ILOAD), i++); } mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), targetMethod.getName(), targetMethod.getDescriptor(), false); mv.visitInsn(method.getReturnType().getOpcode(IRETURN)); mv.visitMaxs(0, 0); mv.visitEnd(); } }
From source file:org.glowroot.weaving.AdviceBuilder.java
License:Apache License
private void initOnBeforeAdvice(Class<?> adviceClass, java.lang.reflect.Method method) throws AdviceConstructionException { checkState(!hasOnBeforeAdvice,/*from w ww. j a v a2s. co m*/ "@Pointcut '" + adviceClass.getName() + "' has more than one @OnBefore method"); Method onBeforeAdvice = Method.getMethod(method); builder.onBeforeAdvice(onBeforeAdvice); List<AdviceParameter> parameters = getAdviceParameters(method.getParameterAnnotations(), method.getParameterTypes(), onBeforeBindAnnotationTypes, OnBefore.class); builder.addAllOnBeforeParameters(parameters); if (onBeforeAdvice.getReturnType().getSort() != Type.VOID) { builder.travelerType(onBeforeAdvice.getReturnType()); } hasOnBeforeAdvice = true; }
From source file:org.glowroot.weaving.AdviceBuilder.java
License:Apache License
private void initOnReturnAdvice(Class<?> adviceClass, java.lang.reflect.Method method) throws AdviceConstructionException { checkState(!hasOnReturnAdvice,// ww w .j a va2 s . c o m "@Pointcut '" + adviceClass.getName() + "' has more than one @OnReturn method"); List<AdviceParameter> parameters = getAdviceParameters(method.getParameterAnnotations(), method.getParameterTypes(), onReturnBindAnnotationTypes, OnReturn.class); for (int i = 1; i < parameters.size(); i++) { checkState(parameters.get(i).kind() != ParameterKind.RETURN, "@BindReturn must be the first argument to @OnReturn"); checkState(parameters.get(i).kind() != ParameterKind.OPTIONAL_RETURN, "@BindOptionalReturn must be the first argument to @OnReturn"); } builder.onReturnAdvice(Method.getMethod(method)); builder.addAllOnReturnParameters(parameters); hasOnReturnAdvice = true; }
From source file:org.glowroot.weaving.AdviceBuilder.java
License:Apache License
private void initOnThrowAdvice(Class<?> adviceClass, java.lang.reflect.Method method) throws AdviceConstructionException { checkState(!hasOnThrowAdvice,//from w w w. j a v a 2 s . c o m "@Pointcut '" + adviceClass.getName() + "' has more than one @OnThrow method"); List<AdviceParameter> parameters = getAdviceParameters(method.getParameterAnnotations(), method.getParameterTypes(), onThrowBindAnnotationTypes, OnThrow.class); for (int i = 1; i < parameters.size(); i++) { checkState(parameters.get(i).kind() != ParameterKind.THROWABLE, "@BindThrowable must be the first argument to @OnThrow"); } Method asmMethod = Method.getMethod(method); checkState(asmMethod.getReturnType().getSort() == Type.VOID, "@OnThrow method must return void (for now)"); builder.onThrowAdvice(asmMethod); builder.addAllOnThrowParameters(parameters); hasOnThrowAdvice = true; }
From source file:org.glowroot.weaving.AdviceBuilder.java
License:Apache License
private void initOnAfterAdvice(Class<?> adviceClass, java.lang.reflect.Method method) throws AdviceConstructionException { checkState(!hasOnAfterAdvice,// ww w . j a va 2s. c o m "@Pointcut '" + adviceClass.getName() + "' has more than one @OnAfter method"); Method asmMethod = Method.getMethod(method); checkState(asmMethod.getReturnType().getSort() == Type.VOID, "@OnAfter method must return void"); builder.onAfterAdvice(asmMethod); List<AdviceParameter> parameters = getAdviceParameters(method.getParameterAnnotations(), method.getParameterTypes(), onAfterBindAnnotationTypes, OnAfter.class); builder.addAllOnAfterParameters(parameters); hasOnAfterAdvice = true; }
From source file:org.glowroot.weaving.WeavingClassVisitor.java
License:Apache License
@RequiresNonNull("type") private void addShim(ShimType shimType) { for (java.lang.reflect.Method reflectMethod : shimType.shimMethods()) { Method method = Method.getMethod(reflectMethod); Shim shim = reflectMethod.getAnnotation(Shim.class); checkNotNull(shim);//from ww w. j av a 2 s . c om Method targetMethod = Method.getMethod(shim.value()); MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, method.getName(), method.getDescriptor(), null, null); checkNotNull(mv); mv.visitCode(); int i = 0; mv.visitVarInsn(ALOAD, i++); for (Type argumentType : method.getArgumentTypes()) { mv.visitVarInsn(argumentType.getOpcode(ILOAD), i++); } mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), targetMethod.getName(), targetMethod.getDescriptor(), false); mv.visitInsn(method.getReturnType().getOpcode(IRETURN)); mv.visitMaxs(0, 0); mv.visitEnd(); } }
From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java
License:Open Source License
/** * Generates the instructions to create and throw an exception. The * exception class must have a constructor with a single String argument. * * @param type the class of the exception to be thrown. * @param msg the detailed message of the exception. *//* w w w .ja va 2s. c o m*/ public void throwException(final Type type, final String msg) { newInstance(type); dup(); push(msg); invokeConstructor(type, Method.getMethod("void <init> (String)")); throwException(); }
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
@Override public void visitMaxs(int maxStack, int maxLocals) { Type returnType = Type.getReturnType(descriptor); // check whether there are outstanding monitor opens at the start of the trigger // block and, if so, insert a handler which unlocks the monitor and then rethrows // the exception. Iterator<TriggerDetails> iterator = cfg.triggerDetails(); boolean noneLeft = true; while (iterator.hasNext()) { TriggerDetails details = iterator.next(); // see if this trigger has any open monitor enters which will need closing Iterator<CodeLocation> openEnters = cfg.getOpenMonitors(details); if (openEnters.hasNext()) { // add a handler here which unlocks each object and rethrows the // saved exception then protect it with a try catch block and update // the trigger details so that it is the target of this block // generate a rethrow handler for each exception type Label newStart = newLabel(); Label newEnd = newLabel(); // if we get here the return and throw handlers labels should be null if (details.getEarlyReturnHandler() != null || details.getThrowHandler() != null) { System.out.println("unexpected : trigger region with open monitorenters has subtype handler!"); }//from w w w . j a v a 2 s. co m // generate rethrow code and mark the handler as a try catch block for all // three exception types newStart = newLabel(); newEnd = newLabel(); Label newEarlyReturn = newLabel(); Label newThrow = newLabel(); visitLabel(details.getExecuteHandler()); Label newExecute = newLabel(); visitLabel(newStart); while (openEnters.hasNext()) { CodeLocation enterLocation = openEnters.next(); int varIdx = cfg.getSavedMonitorIdx(enterLocation); // call super method to avoid indexing these instructions visitVarInsn(Opcodes.ALOAD, varIdx); visitInsn(Opcodes.MONITOREXIT); } visitInsn(Opcodes.ATHROW); // add try catch blocks for the 3 exception types visitTryCatchBlock(newStart, newEnd, newEarlyReturn, CFG.EARLY_RETURN_EXCEPTION_TYPE_NAME); visitTryCatchBlock(newStart, newEnd, newThrow, CFG.THROW_EXCEPTION_TYPE_NAME); visitTryCatchBlock(newStart, newEnd, newExecute, CFG.EXECUTE_EXCEPTION_TYPE_NAME); // visit the end of the handler blocks so they gets processed visitLabel(newEnd); // update the details so it tracks these new ecetpion regions details.setThrowHandler(newThrow); details.setEarlyReturnHandler(newEarlyReturn); details.setExecuteHandler(newExecute); } } // ok, so now we have to add the handler code for trigger block try catch handlers // we only need to add the handler code once but we need to make sure it is the target of // all the try catch blocks by visiting their handler label before we insert the code iterator = cfg.triggerDetails(); while (iterator.hasNext()) { TriggerDetails details = iterator.next(); visitLabel(details.getEarlyReturnHandler()); } if (Transformer.isVerbose()) { getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class)); visitLdcInsn("caught ReturnException"); invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println(String)")); } // add exception handling code subclass first if (returnType == Type.VOID_TYPE) { // drop exception and just return pop(); visitInsn(Opcodes.RETURN); } else { // fetch value from exception, unbox if needed and return value Method getReturnValueMethod = Method.getMethod("Object getReturnValue()"); invokeVirtual(CFG.EARLY_RETURN_EXCEPTION_TYPE, getReturnValueMethod); unbox(returnType); returnValue(); } iterator = cfg.triggerDetails(); while (iterator.hasNext()) { TriggerDetails details = iterator.next(); visitLabel(details.getThrowHandler()); } if (Transformer.isVerbose()) { getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class)); visitLdcInsn("caught ThrowException"); invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println(String)")); } // fetch value from exception, unbox if needed and return value Method getThrowableMethod = Method.getMethod("Throwable getThrowable()"); invokeVirtual(CFG.THROW_EXCEPTION_TYPE, getThrowableMethod); throwException(); // execute exception comes last because it is the super of the othher two classes iterator = cfg.triggerDetails(); while (iterator.hasNext()) { TriggerDetails details = iterator.next(); visitLabel(details.getExecuteHandler()); } if (Transformer.isVerbose()) { getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class)); visitLdcInsn("caught ExecuteException"); invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println(String)")); } // rethrow an execute exception throwException(); super.visitMaxs(maxStack, maxLocals); // hmm, don't think we need this cfg.visitMaxs(); }
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
/** * inject the rule trigger code/* ww w . j a v a2 s . co m*/ */ protected void injectTriggerPoint() { // we need to set this here to avoid recursive re-entry into inject routine rule.setTypeInfo(getTriggerClassName(), access, name, descriptor, exceptions); String key = rule.getKey(); Type ruleType = Type.getType(TypeHelper.externalizeType("org.jboss.byteman.rule.Rule")); Method method = Method.getMethod("void execute(String, Object, Object[])"); // we are at the relevant line in the method -- so add a trigger call here if (Transformer.isVerbose()) { System.out.println("RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into " + getTriggerClassName() + "." + getMethodName() + " for rule " + rule.getName()); } Label startLabel = newLabel(); Label endLabel = newLabel(); visitTriggerStart(startLabel); // ensure binding indices have been installed setBindingIndices(); // a local var slot to store a value for $! (AT RETURN), $^ (AT THROW) or $@ (AT INVOKE) // note that only one of these can appear in any given rule so we only need one slot int saveValueSlot; if (bindReturnOrThrowableValue) { saveValueSlot = doReturnOrThrowSave(); } else if (bindInvokeParams) { saveValueSlot = doInvokeBindingsSave(); } else { saveValueSlot = -1; } push(key); if ((access & Opcodes.ACC_STATIC) == 0) { loadThis(); } else { push((Type) null); } boolean handleUpdates; handleUpdates = doArgLoad(saveValueSlot); // free the local slot if we need to if (saveValueSlot >= 0) { popLocal(saveValueSlot); } invokeStatic(ruleType, method); // if the rule can modify local variables then generate code to perform the update if (handleUpdates) { doArgUpdate(); } visitTriggerEnd(endLabel); }
From source file:org.jruby.anno.IndyBinder.java
License:LGPL
public void processMethodDeclarationMulti(List<ExecutableElement> methods) { Handle[] handles = new Handle[5]; List<ExecutableElementDescriptor> descs = new ArrayList<>(); boolean meta = false; boolean isStatic = false; JRubyMethod anno = null;/*from w w w . j a v a 2 s .c o m*/ int min = Integer.MAX_VALUE; int max = 0; Map<Handle, ExecutableElementDescriptor> handleToDesc = new HashMap<>(); for (ExecutableElement method : methods) { anno = method.getAnnotation(JRubyMethod.class); ExecutableElementDescriptor desc = new ExecutableElementDescriptor(method); descs.add(desc); if (anno != null && mv != null) { isStatic |= desc.isStatic; CharSequence qualifiedName = desc.declaringClassName; boolean hasContext = desc.hasContext; boolean hasBlock = desc.hasBlock; StringBuilder buffer = new StringBuilder(method.getReturnType().toString()).append(" foo("); boolean first = true; for (VariableElement parameter : method.getParameters()) { if (!first) buffer.append(','); first = false; buffer.append(parameter.asType().toString()); } buffer.append(')'); Handle handle = new Handle(isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, qualifiedName.toString().replace('.', '/'), method.getSimpleName().toString(), Method.getMethod(buffer.toString()).getDescriptor()); int handleOffset = calculateHandleOffset(method.getParameters().size(), anno.required(), anno.optional(), anno.rest(), isStatic, hasContext, hasBlock); handles[handleOffset] = handle; handleToDesc.put(handle, desc); meta |= anno.meta(); int specificArity = -1; if (desc.optional == 0 && !desc.rest) { if (desc.required == 0) { if (desc.actualRequired <= 3) { specificArity = desc.actualRequired; } } else if (desc.required >= 0 && desc.required <= 3) { specificArity = desc.required; } } if (specificArity != -1) { if (specificArity < min) min = specificArity; if (specificArity > max) max = specificArity; } else { if (desc.required < min) min = desc.required; if (desc.rest) max = Integer.MAX_VALUE; if (desc.required + desc.optional > max) max = desc.required + desc.optional; } } } int implClass = meta ? SINGLETONCLASS : CLASS; mv.newobj("org/jruby/internal/runtime/methods/HandleMethod"); mv.dup(); mv.aload(implClass); mv.getstatic(p(Visibility.class), anno.visibility().name(), ci(Visibility.class)); mv.ldc(encodeSignature(0, 0, 0, 0, 0, true, false)); mv.ldc(true); mv.ldc(anno.notImplemented()); DescriptorInfo info = new DescriptorInfo(descs); mv.ldc(info.getParameterDesc()); mv.ldc(min); mv.ldc(max); for (int i = 0; i < 5; i++) { if (handles[i] != null) { mv.ldc(handles[i]); adaptHandle(handleToDesc.get(handles[i]), implClass); } else { mv.aconst_null(); } } Method handleInit = Method.getMethod( "void foo(org.jruby.RubyModule, org.jruby.runtime.Visibility, long, boolean, boolean, java.lang.String, int, int, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable)"); mv.invokespecial("org/jruby/internal/runtime/methods/HandleMethod", "<init>", handleInit.getDescriptor()); mv.astore(BASEMETHOD); generateMethodAddCalls(methods.get(0), anno); }