List of usage examples for org.objectweb.asm Opcodes ACC_STATIC
int ACC_STATIC
To view the source code for org.objectweb.asm Opcodes ACC_STATIC.
Click Source Link
From source file:org.jacoco.core.runtime.ModifiedSystemClassRuntime.java
License:Open Source License
private static void createDataField(final ClassVisitor visitor, final String dataField) { visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_TRANSIENT, dataField, ACCESS_FIELD_TYPE, null, null); }
From source file:org.jacoco.core.test.validation.BootstrapMethodReferenceTest.java
License:Open Source License
@Test public void test() throws Exception { final String className = "Example"; final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null); final MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "run", "()I", null, null); mv.visitCode();/*from w ww .jav a 2 s . c o m*/ addCauseOfResizeInstructions(mv); final MethodType methodType = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); final Handle handle = new Handle(Opcodes.H_INVOKESTATIC, this.getClass().getCanonicalName().replace('.', '/'), "bootstrap", methodType.toMethodDescriptorString(), false); mv.visitInvokeDynamicInsn("invoke", "()I", handle); mv.visitInsn(Opcodes.IRETURN); mv.visitMaxs(1, 0); mv.visitEnd(); cw.visitEnd(); final byte[] original = cw.toByteArray(); assertEquals(42, run(className, original)); final byte[] instrumented = instrumenter.instrument(original, className); assertEquals(42, run(className, instrumented)); }
From source file:org.jboss.byteman.agent.adapter.RuleCheckMethodAdapter.java
License:Open Source License
protected void checkBindings() { if (!isTriggerPoint()) { transformContext.warn(name, descriptor, "no matching injection point"); return;/*w ww . j a v a2s .c o m*/ } Bindings bindings = rule.getBindings(); Iterator<Binding> bindingIter = bindings.iterator(); List<String> parameterTypenames = Type.parseMethodDescriptor(descriptor, true); int parameterCount = parameterTypenames.size() - 1; // allows for return type // make sure all entries are valid while (bindingIter.hasNext()) { Binding binding = bindingIter.next(); if (binding.isRecipient()) { if ((access & Opcodes.ACC_STATIC) != 0) { if (Transformer.isVerbose()) { System.out.println("RuleCheckMethodAdapter.checkBindings : found invalid recipient binding " + binding + " checking static method " + name + descriptor); } transformContext.warn(name, descriptor, "found invalid recipient binding " + binding + " injecting into static method"); } } else if (binding.isParam()) { int idx = binding.getIndex(); if (idx > parameterCount) { // parameter out of range if (Transformer.isVerbose()) { System.out.println( "RuleCheckMethodAdapter.checkBindings : found out of range parameter binding " + binding + " checking method " + name + descriptor); } transformContext.warn(name, descriptor, "found out of range parameter binding " + binding); } else { binding.setDescriptor(parameterTypenames.get(idx - 1)); } } else if (binding.isReturn()) { // this is a valid reference in an AT EXIT rule and in an AFTER INVOKE // but only if the corresponding returning or called method is non-void LocationType locationType = rule.getTargetLocation().getLocationType(); if (locationType == LocationType.EXIT) { if ("void".equals(getReturnBindingType())) { if (Transformer.isVerbose()) { System.out.println("RuleCheckMethodAdapter.checkBindings : found return value binding " + binding + " checking void trigger method " + name + descriptor + " in AT EXIT rule " + rule); } transformContext.warn(name, descriptor, "found return value binding " + binding + " checking void trigger method in AT EXIT rule"); } } else if (locationType == LocationType.INVOKE_COMPLETED) { if ("void".equals(getReturnBindingType())) { if (Transformer.isVerbose()) { System.out.println("RuleCheckMethodAdapter.checkBindings : found return value binding " + binding + " checking void called method in AFTER INVOKE rule " + rule.getName()); } transformContext.warn(name, descriptor, "found return value binding " + binding + " checking void called method in AFTER INVOKE rule"); } } else { if (Transformer.isVerbose()) { System.out.println("RuleCheckMethodAdapter.checkBindings : found return value binding " + binding + " in rule which is neither AT EXIT nor AFTER INVOKE " + rule.getName()); } transformContext.warn(name, descriptor, "found return value binding " + binding + " in rule which is neither AT EXIT nor AFTER INVOKE"); } } else if (binding.isThrowable()) { // we can only allow reference to the current throwable in an AT THROW rule if (rule.getTargetLocation().getLocationType() != LocationType.THROW) { if (Transformer.isVerbose()) { System.out.println("RuleCheckMethodAdapter.checkBindings : found throwable value binding " + binding + " in rule which is not AT THROW " + rule.getName()); } transformContext.warn(name, descriptor, "found throwable value binding " + binding + " in rule which is not AT THROW"); } // we will need to set the descriptor at some point } else if (binding.isParamArray()) { // this is ok } else if (binding.isParamCount()) { // this is ok } else if (binding.isInvokeParamArray()) { // we can only allow reference to the invoked method parameters in an AT INVOKE rule if (rule.getTargetLocation().getLocationType() != LocationType.INVOKE) { if (Transformer.isVerbose()) { System.out.println( "RuleCheckMethodAdapter.checkBindings : found invoke parameter array binding $@ in non-AT INVOKE rule " + rule.getName()); } transformContext.warn(name, descriptor, "found throwable value binding " + binding + " in rule which is not AT THROW"); } } else if (binding.isTriggerClass() || binding.isTriggerMethod()) { // this is ok } else if (binding.isLocalVar()) { // make sure we have a local variable with the correct name String localVarName = binding.getName().substring(1); List<LocalVar> localVars = lookup(localVarName); if (localVars == null || localVars.isEmpty()) { if (Transformer.isVerbose()) { System.out.println( "RuleCheckMethodAdapter.checkBindings : unsatisfiable local variable binding " + binding + " checking method " + name + descriptor); } transformContext.warn(name, descriptor, "unknown local variable " + binding); } else { String localDescriptor = null; int index = -1; Iterator<Label> labelIter = triggerPoints.iterator(); while (labelIter.hasNext()) { int triggerPos = labelIter.next().getOffset(); boolean found = false; Iterator<LocalVar> localVarIter = localVars.iterator(); while (localVarIter.hasNext()) { LocalVar localVar = localVarIter.next(); int start = localVar.start.getOffset(); int end = localVar.end.getOffset(); if (start <= triggerPos && triggerPos < end) { // only accept if the descriptor and index are the same or are not yet set if (localDescriptor == null) { localDescriptor = localVar.desc; index = localVar.index; found = true; } else if (localDescriptor.equals(localVar.desc) && index == localVar.index) { found = true; } // terminate the loop here break; } } // if there was no variable for this trigger point then fail if (!found) { if (Transformer.isVerbose()) { System.out.println( "RuleCheckMethodAdapter.checkBindings : invalid local variable binding " + binding + " checking method " + name + descriptor); } transformContext.warn(name, descriptor, "invalid local variable binding " + binding); // ok no point checking any further break; } } // if we got here with a non-null localDescriptor then we have a unique // local var descriptor and index for all trigger points so update the binding // if not then we have notified a fail for the transform so there is no // need to do the update anyway if (localDescriptor != null) { binding.setDescriptor(Type.parseFieldDescriptor(localDescriptor)); binding.setLocalIndex(index); } } } } }
From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java
License:Open Source License
/** * initialise the local slot types array with the types of the method target and parameters. * this is needed because we are only sent an initial frame identifying the local slots * which belong to the method if a stackmap table has been included in the bytecode and this * is nto always the case.//from ww w.j a va 2 s .c om */ private void initLocalTypes() { // owner of this method is an object // localTypes.add(Type.getType(Object.class)); String name = getTriggerClassName().replace('.', '/'); if ((access | Opcodes.ACC_STATIC) == 0) { // an instance method so slot 0 will contain the target object localTypes.add(Type.getType("L" + name + ";")); } for (int i = 0; i < argumentTypes.length; i++) { Type argumentType = argumentTypes[i]; int size = argumentType.getSize(); localTypes.add(argumentType); if (size > 1) { localTypes.add(null); } } nextLocal = localHighWater = localTypes.size(); }
From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java
License:Open Source License
/** * Returns the index of the given method argument in the frame's local * variables array./* w w w . j a v a2s .co m*/ * * @param arg the index of a method argument. * @return the index of the given method argument in the frame's local * variables array. */ private int getArgIndex(final int arg) { int index = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0; for (int i = 0; i < arg; i++) { index += argumentTypes[i].getSize(); } return index; }
From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java
License:Open Source License
/** * Generates the instruction to load 'this' on the stack. *//*from w w w. j av a2 s. co m*/ public void loadThis() { if ((access & Opcodes.ACC_STATIC) != 0) { throw new IllegalStateException("no 'this' pointer within static method"); } visitVarInsn(Opcodes.ALOAD, 0); }
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
private void setBindingIndices() { if (bindingIndicesSet) { return;/* w w w.j a va 2 s . co m*/ } Bindings bindings = rule.getBindings(); Iterator<Binding> iterator = bindings.iterator(); List<Binding> aliasBindings = new ArrayList<Binding>(); int argLocalIndex = 0; // if this is an instance method then the local 0 holds this and args start at local index 1 if ((access & Opcodes.ACC_STATIC) == 0) { argLocalIndex += 1; } // compute the local indices of each method parameter for (int i = 0; i < argumentTypes.length; i++) { argLocalIndices[i] = argLocalIndex; argLocalIndex += argumentTypes[i].getSize(); } // check the local var bindings and, if any of them are actually refereces to method params // alias them to the corresponding param binding while (iterator.hasNext()) { Binding binding = iterator.next(); if (binding.isLocalVar()) { int localIdx = binding.getLocalIndex(); if (localIdx < argLocalIndex) { binding = alias(binding, bindings, localIdx); if (binding != null) { // the aliased param binding was not present so ensure it gets added to the // binding set once we have finished iterating. there is no need to add it // to the call bindings since we pass the aliased method param instead aliasBindings.add(binding); } } else { callArrayBindings.add(binding); } } } bindings.addBindings(aliasBindings); // now iterate over the param vars and ensure they go into the call bindings list iterator = bindings.iterator(); while (iterator.hasNext()) { Binding binding = iterator.next(); if (binding.isParam()) { callArrayBindings.add(binding); } else if (binding.isReturn()) { // in order to be able to add the return value to the args array // we have to add a local var to store the value so track that requirement bindReturnOrThrowableValue = true; saveValueType = getReturnBindingType(); binding.setDescriptor(saveValueType.getClassName()); callArrayBindings.add(binding); } else if (binding.isThrowable()) { // in order to be able to add the return value or throwable value to the args array // we have to add a local var to store the value so track that requirement bindReturnOrThrowableValue = true; // TODO -- allow type to be more accurately identified than this saveValueType = Type.getType("Ljava/lang/Throwable;"); callArrayBindings.add(binding); } else if (binding.isParamCount() || binding.isParamArray()) { callArrayBindings.add(binding); } else if (binding.isInvokeParamArray()) { // in order to be able to ad th einvoke parameters to the args array we // have to add a local var to store the value so track that requirement callArrayBindings.add(binding); bindInvokeParams = true; } else if (binding.isTriggerClass() || binding.isTriggerMethod()) { callArrayBindings.add(binding); binding.setDescriptor("java.lang.String"); } } // we don't have to do this but it makes debugging easier if (true) { // ok now sort the callArrayBindings for later use // we sort param bindings before local bindings before the param count // and param array before the throwable or return binding // within param bindings we sort by param idx // within local bindings we sort by local var idx Comparator<Binding> comparator = new Comparator<Binding>() { public int compare(Binding b1, Binding b2) { if (b1.isParam()) { if (b2.isParam()) { // sort by param index int i1 = b1.getIndex(); int i2 = b2.getIndex(); return (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); } else { // param bindings precede all other types return -1; } } else if (b1.isLocalVar()) { if (b2.isParam()) { // param bindings precede all other types return 1; } else if (b2.isLocalVar()) { // sort by local index int i1 = b1.getLocalIndex(); int i2 = b2.getLocalIndex(); return (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); } else { // local vars precede all remaining types return -1; } } else if (b1.isParamCount()) { if (b2.isParam() || b2.isLocalVar()) { // param and local bindings precede param count return 1; } else if (b2.isParamCount()) { return 0; } else { // param count vars precede all remaining types return -1; } } else if (b1.isParamArray()) { if (b2.isParam() || b2.isLocalVar() || b2.isParamCount()) { // param, local and param count bindings precede param array return 1; } else if (b2.isParamArray()) { return 0; } else { // param array vars precede all remaining types return -1; } } else if (b1.isInvokeParamArray()) { if (b2.isParam() || b2.isLocalVar() || b2.isParamCount() || b2.isParamArray()) { // param, local and param count and param array bindings precede invoke param array return 1; } else if (b2.isInvokeParamArray()) { return 0; } else { // invoke param array vars precede all remaining types return -1; } } else if (b1.isTriggerClass()) { if (b2.isParam() || b2.isLocalVar() || b2.isParamCount() || b2.isParamArray() || b2.isInvokeParamArray()) { // param, local and param count, param array and invoke param array bindings precede trigger class return 1; } else if (b2.isTriggerClass()) { return 0; } else { return -1; } } else if (b1.isTriggerMethod()) { if (b2.isParam() || b2.isLocalVar() || b2.isParamCount() || b2.isParamArray() || b2.isInvokeParamArray() || b2.isTriggerClass()) { // param, local and param count, param array, invoke param array and trigger class bindings precede trigger method return 1; } else if (b2.isTriggerMethod()) { return 0; } else { return -1; } } else { // return var always sorts last return 1; } } }; Collections.sort(callArrayBindings, comparator); } // now give each binding a unique index in the object array int n = callArrayBindings.size(); for (int i = 0; i < n; i++) { callArrayBindings.get(i).setCallArrayIndex(i); } bindingIndicesSet = true; }
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
private Binding alias(Binding binding, Bindings bindings, int localIdx) { if (((access & Opcodes.ACC_STATIC) == 0) && (localIdx == 0)) { String name = "$0"; Binding alias = bindings.lookup(name); if (alias == null) { alias = new Binding(rule, name); alias.setDescriptor(binding.getDescriptor()); alias.setLocalIndex(binding.getLocalIndex()); binding.aliasTo(alias);//ww w . ja v a 2 s. com // alias var was new so return it for addition to the binding set return alias; } else { // just alias the binding binding.aliasTo(alias); return null; } } for (int i = 0; i < argLocalIndices.length; i++) { if (argLocalIndices[i] == localIdx) { String name = "$" + (i + 1); Binding alias = bindings.lookup(name); if (alias == null) { alias = new Binding(rule, name); alias.setDescriptor(binding.getDescriptor()); alias.setLocalIndex(binding.getLocalIndex()); binding.aliasTo(alias); // alias var was new so return it for addition to the binding set return alias; } else { // just alias the binding binding.aliasTo(alias); return null; } } } return null; }
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
/** * stack an argument array containing all the values which need to be bound to parameters or local variables * in the rule or a null pointer if no bindings are required. this method also inserts a copy of the array * below the initial two top entries if any of the bindings can potentially be updated by the rule, allowing * the updated values to be written back on return from the call to the rule engine. * @param saveSlot a local variable slot containing either the return value which the trigger method is about * to return or the Throwable the method is about to throw. this is only valid if, respectively, the rule * location is AT EXIT/AFTER INVOKE or AT THROW and the rule body contains a reference to the return value ($!) * or throwable value ($@).//from ww w.ja v a 2 s .co m * @return true if the rule may update the argument array and hence if a copy of the array has been inserted * below the initial two top entries otherwise false. */ private boolean doArgLoad(int saveSlot) { if (callArrayBindings.size() == 0) { push((org.objectweb.asm.Type) null); return false; } // create the array used to pass the bindings int arraySize = callArrayBindings.size(); push(arraySize); Type objectType = Type.getType(Object.class); newArray(objectType); // check if any of the bindings gets updated. if so we need to stash a copy of the bindings array // below the key and owner so we can pull out the updated values and update local var/param slots // once the call ahs completed boolean doUpdates = false; for (int i = 0; i < arraySize; i++) { Binding binding = callArrayBindings.get(i); if (binding.isUpdated()) { doUpdates = true; break; } } if (doUpdates) { // insert copy of array below first two call arguments // [.. key owner bindings ] ==> [.. bindings key owner bindings ] mv.visitInsn(Opcodes.DUP_X2); } // now install required values into bindings array for (int i = 0; i < arraySize; i++) { Binding binding = callArrayBindings.get(i); dup(); push(i); if (binding.isParam()) { int idx = binding.getIndex() - 1; loadArg(idx); box(argumentTypes[idx]); } else if (binding.isLocalVar()) { int idx = binding.getLocalIndex(); loadLocal(idx); box(getLocalType(idx)); } else if (binding.isParamCount()) { int count = argumentTypes.length; push(count); box(Type.INT_TYPE); } else if (binding.isParamArray()) { int count = argumentTypes.length; push(count + 1); newArray(objectType); dup(); push(0); if ((access & Opcodes.ACC_STATIC) == 0) { loadThis(); } else { push((Type) null); } arrayStore(objectType); for (int idx = 0; idx < count; idx++) { dup(); push(idx + 1); loadArg(idx); box(argumentTypes[idx]); arrayStore(objectType); } } else if (binding.isInvokeParamArray()) { loadLocal(saveSlot); } else if (binding.isTriggerClass()) { String triggerClassName = TypeHelper.internalizeClass(getTriggerClassName()); visitLdcInsn(triggerClassName); } else if (binding.isTriggerMethod()) { String triggerMethodName = name + TypeHelper.internalizeDescriptor(descriptor); visitLdcInsn(triggerMethodName); } else if (binding.isThrowable() | binding.isReturn()) { loadLocal(saveSlot); box(saveValueType); } arrayStore(objectType); } return doUpdates; }
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
/** * inject the rule trigger code/*from w ww .j av a 2s .c om*/ */ 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); }