📄 adviceadapter.java
字号:
/***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2005 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.drools.asm.commons;
import java.util.ArrayList;
import java.util.HashMap;
import org.drools.asm.Label;
import org.drools.asm.MethodVisitor;
import org.drools.asm.Opcodes;
import org.drools.asm.Type;
/**
* A <code>MethodAdapter</code> to dispatch method body instruction
* <p>
* The behavior is like this:
* <ol>
*
* <li>as long as the INVOKESPECIAL for the object initialization has not been
* reached, every bytecode instruction is dispatched in the ctor code visitor</li>
*
* <li>when this one is reached, it is only added in the ctor code visitor and
* a JP invoke is added</li>
* <li>after that, only the other code visitor receives the instructions</li>
*
* </ol>
*
* @author Eugene Kuleshov
* @author Eric Bruneton
*/
public abstract class AdviceAdapter extends GeneratorAdapter
implements
Opcodes {
private static final Object THIS = new Object();
private static final Object OTHER = new Object();
protected int methodAccess;
protected String methodDesc;
private boolean constructor;
private boolean superInitialized;
private ArrayList stackFrame;
private HashMap branches;
/**
* Creates a new {@link AdviceAdapter}.
*
* @param mv the method visitor to which this adapter delegates calls.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}).
*/
public AdviceAdapter(final MethodVisitor mv,
final int access,
final String name,
final String desc) {
super( mv,
access,
name,
desc );
this.methodAccess = access;
this.methodDesc = desc;
this.constructor = "<init>".equals( name );
if ( !this.constructor ) {
this.superInitialized = true;
onMethodEnter();
} else {
this.stackFrame = new ArrayList();
this.branches = new HashMap();
}
}
public void visitLabel(final Label label) {
this.mv.visitLabel( label );
if ( this.constructor && this.branches != null ) {
final ArrayList frame = (ArrayList) this.branches.get( label );
if ( frame != null ) {
this.stackFrame = frame;
this.branches.remove( label );
}
}
}
public void visitInsn(final int opcode) {
if ( this.constructor ) {
switch ( opcode ) {
case RETURN : // empty stack
onMethodExit( opcode );
break;
case IRETURN : // 1 before n/a after
case FRETURN : // 1 before n/a after
case ARETURN : // 1 before n/a after
case ATHROW : // 1 before n/a after
popValue();
popValue();
onMethodExit( opcode );
break;
case LRETURN : // 2 before n/a after
case DRETURN : // 2 before n/a after
popValue();
popValue();
onMethodExit( opcode );
break;
case NOP :
case LALOAD : // remove 2 add 2
case DALOAD : // remove 2 add 2
case LNEG :
case DNEG :
case FNEG :
case INEG :
case L2D :
case D2L :
case F2I :
case I2B :
case I2C :
case I2S :
case I2F :
case Opcodes.ARRAYLENGTH :
break;
case ACONST_NULL :
case ICONST_M1 :
case ICONST_0 :
case ICONST_1 :
case ICONST_2 :
case ICONST_3 :
case ICONST_4 :
case ICONST_5 :
case FCONST_0 :
case FCONST_1 :
case FCONST_2 :
case F2L : // 1 before 2 after
case F2D :
case I2L :
case I2D :
pushValue( AdviceAdapter.OTHER );
break;
case LCONST_0 :
case LCONST_1 :
case DCONST_0 :
case DCONST_1 :
pushValue( AdviceAdapter.OTHER );
pushValue( AdviceAdapter.OTHER );
break;
case IALOAD : // remove 2 add 1
case FALOAD : // remove 2 add 1
case AALOAD : // remove 2 add 1
case BALOAD : // remove 2 add 1
case CALOAD : // remove 2 add 1
case SALOAD : // remove 2 add 1
case POP :
case IADD :
case FADD :
case ISUB :
case LSHL : // 3 before 2 after
case LSHR : // 3 before 2 after
case LUSHR : // 3 before 2 after
case L2I : // 2 before 1 after
case L2F : // 2 before 1 after
case D2I : // 2 before 1 after
case D2F : // 2 before 1 after
case FSUB :
case FMUL :
case FDIV :
case FREM :
case FCMPL : // 2 before 1 after
case FCMPG : // 2 before 1 after
case IMUL :
case IDIV :
case IREM :
case ISHL :
case ISHR :
case IUSHR :
case IAND :
case IOR :
case IXOR :
case MONITORENTER :
case MONITOREXIT :
popValue();
break;
case POP2 :
case LSUB :
case LMUL :
case LDIV :
case LREM :
case LADD :
case LAND :
case LOR :
case LXOR :
case DADD :
case DMUL :
case DSUB :
case DDIV :
case DREM :
popValue();
popValue();
break;
case IASTORE :
case FASTORE :
case AASTORE :
case BASTORE :
case CASTORE :
case SASTORE :
case LCMP : // 4 before 1 after
case DCMPL :
case DCMPG :
popValue();
popValue();
popValue();
break;
case LASTORE :
case DASTORE :
popValue();
popValue();
popValue();
popValue();
break;
case DUP :
pushValue( peekValue() );
break;
case DUP_X1 :
// TODO optimize this
{
final Object o1 = popValue();
final Object o2 = popValue();
pushValue( o1 );
pushValue( o2 );
pushValue( o1 );
}
break;
case DUP_X2 :
// TODO optimize this
{
final Object o1 = popValue();
final Object o2 = popValue();
final Object o3 = popValue();
pushValue( o1 );
pushValue( o3 );
pushValue( o2 );
pushValue( o1 );
}
break;
case DUP2 :
// TODO optimize this
{
final Object o1 = popValue();
final Object o2 = popValue();
pushValue( o2 );
pushValue( o1 );
pushValue( o2 );
pushValue( o1 );
}
break;
case DUP2_X1 :
// TODO optimize this
{
final Object o1 = popValue();
final Object o2 = popValue();
final Object o3 = popValue();
pushValue( o2 );
pushValue( o1 );
pushValue( o3 );
pushValue( o2 );
pushValue( o1 );
}
break;
case DUP2_X2 :
// TODO optimize this
{
final Object o1 = popValue();
final Object o2 = popValue();
final Object o3 = popValue();
final Object o4 = popValue();
pushValue( o2 );
pushValue( o1 );
pushValue( o4 );
pushValue( o3 );
pushValue( o2 );
pushValue( o1 );
}
break;
case SWAP : {
final Object o1 = popValue();
final Object o2 = popValue();
pushValue( o1 );
pushValue( o2 );
}
break;
}
} else {
switch ( opcode ) {
case RETURN :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -