blob: c9c86ebd3a8d0ede514e16bff59310fd38903a7c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.aries.proxy.impl.common;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.DISPATCHER_FIELD;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.DISPATCHER_TYPE;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.OBJECT_TYPE;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
public final class WovenProxyConcreteMethodAdapter extends AbstractWovenProxyMethodAdapter {
/** Jump here to start executing the original method body **/
private final Label executeDispatch = new Label();
public WovenProxyConcreteMethodAdapter(MethodVisitor mv, int access, String name,
String desc, String[] exceptions, String methodStaticFieldName, Method currentTransformMethod,
Type typeBeingWoven, Type methodDeclaringType, boolean isMethodDeclaringTypeInterface) {
//If we're running on Java 6+ We need to inline any JSR instructions because we're computing stack frames.
//otherwise we can save the overhead
super(mv, access, name, desc, methodStaticFieldName, currentTransformMethod, typeBeingWoven,
methodDeclaringType, isMethodDeclaringTypeInterface, false);
}
/**
* We weave instructions before the normal method body. We must be careful not
* to violate the "rules" of Java (e.g. that try blocks cannot intersect, but
* can be nested). We must also not violate the ordering that ASM expects, so
* we must not call visitMaxs, or define labels before a try/catch that uses
* them!
*/
@Override
public final void visitCode()
{
//Notify our parent that the method code is starting. This must happen first
mv.visitCode();
//unwrap for equals if we need to
if(currentTransformMethod.getName().equals("equals") &&
currentTransformMethod.getArgumentTypes().length == 1 &&
currentTransformMethod.getArgumentTypes()[0].equals(OBJECT_TYPE)) {
unwrapEqualsArgument();
}
//Check if we have a dispatcher, if so then we need to dispatch!
loadThis();
getField(typeBeingWoven, DISPATCHER_FIELD, DISPATCHER_TYPE);
ifNonNull(executeDispatch);
}
@Override
public final void visitMaxs(int stack, int locals) {
//Mark this location for continuing execution when a dispatcher is set
mark(executeDispatch);
//Write the dispatcher code in here
writeDispatcher();
mv.visitMaxs(stack, locals);
}
}