📄 basicverifier.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.tree.analysis;
import java.util.List;
import org.drools.asm.Opcodes;
import org.drools.asm.Type;
import org.drools.asm.tree.AbstractInsnNode;
import org.drools.asm.tree.FieldInsnNode;
import org.drools.asm.tree.MethodInsnNode;
/**
* An extended {@link BasicInterpreter} that checks that bytecode instructions
* are correctly used.
*
* @author Eric Bruneton
* @author Bing Ran
*/
public class BasicVerifier extends BasicInterpreter {
public Value copyOperation(final AbstractInsnNode insn,
final Value value) throws AnalyzerException {
Value expected;
switch ( insn.getOpcode() ) {
case ILOAD :
case ISTORE :
expected = BasicValue.INT_VALUE;
break;
case FLOAD :
case FSTORE :
expected = BasicValue.FLOAT_VALUE;
break;
case LLOAD :
case LSTORE :
expected = BasicValue.LONG_VALUE;
break;
case DLOAD :
case DSTORE :
expected = BasicValue.DOUBLE_VALUE;
break;
case ALOAD :
if ( !((BasicValue) value).isReference() ) {
throw new AnalyzerException( null,
"an object reference",
value );
}
return value;
case ASTORE :
if ( !((BasicValue) value).isReference() && value != BasicValue.RETURNADDRESS_VALUE ) {
throw new AnalyzerException( null,
"an object reference or a return address",
value );
}
return value;
default :
return value;
}
// type is necessarily a primitive type here,
// so value must be == to expected value
if ( value != expected ) {
throw new AnalyzerException( null,
expected,
value );
}
return value;
}
public Value unaryOperation(final AbstractInsnNode insn,
final Value value) throws AnalyzerException {
Value expected;
switch ( insn.getOpcode() ) {
case INEG :
case IINC :
case I2F :
case I2L :
case I2D :
case I2B :
case I2C :
case I2S :
case IFEQ :
case IFNE :
case IFLT :
case IFGE :
case IFGT :
case IFLE :
case TABLESWITCH :
case LOOKUPSWITCH :
case IRETURN :
case NEWARRAY :
case ANEWARRAY :
expected = BasicValue.INT_VALUE;
break;
case FNEG :
case F2I :
case F2L :
case F2D :
case FRETURN :
expected = BasicValue.FLOAT_VALUE;
break;
case LNEG :
case L2I :
case L2F :
case L2D :
case LRETURN :
expected = BasicValue.LONG_VALUE;
break;
case DNEG :
case D2I :
case D2F :
case D2L :
case DRETURN :
expected = BasicValue.DOUBLE_VALUE;
break;
case GETFIELD :
expected = newValue( Type.getType( "L" + ((FieldInsnNode) insn).owner + ";" ) );
break;
case CHECKCAST :
if ( !((BasicValue) value).isReference() ) {
throw new AnalyzerException( null,
"an object reference",
value );
}
return super.unaryOperation( insn,
value );
case ARRAYLENGTH :
if ( !isArrayValue( value ) ) {
throw new AnalyzerException( null,
"an array reference",
value );
}
return super.unaryOperation( insn,
value );
case ARETURN :
case ATHROW :
case INSTANCEOF :
case MONITORENTER :
case MONITOREXIT :
case IFNULL :
case IFNONNULL :
if ( !((BasicValue) value).isReference() ) {
throw new AnalyzerException( null,
"an object reference",
value );
}
return super.unaryOperation( insn,
value );
case PUTSTATIC :
expected = newValue( Type.getType( ((FieldInsnNode) insn).desc ) );
break;
default :
throw new RuntimeException( "Internal error." );
}
if ( !isSubTypeOf( value,
expected ) ) {
throw new AnalyzerException( null,
expected,
value );
}
return super.unaryOperation( insn,
value );
}
public Value binaryOperation(final AbstractInsnNode insn,
final Value value1,
final Value value2) throws AnalyzerException {
Value expected1;
Value expected2;
switch ( insn.getOpcode() ) {
case IALOAD :
expected1 = newValue( Type.getType( "[I" ) );
expected2 = BasicValue.INT_VALUE;
break;
case BALOAD :
if ( !isSubTypeOf( value1,
newValue( Type.getType( "[Z" ) ) ) ) {
expected1 = newValue( Type.getType( "[B" ) );
} else {
expected1 = newValue( Type.getType( "[Z" ) );
}
expected2 = BasicValue.INT_VALUE;
break;
case CALOAD :
expected1 = newValue( Type.getType( "[C" ) );
expected2 = BasicValue.INT_VALUE;
break;
case SALOAD :
expected1 = newValue( Type.getType( "[S" ) );
expected2 = BasicValue.INT_VALUE;
break;
case LALOAD :
expected1 = newValue( Type.getType( "[J" ) );
expected2 = BasicValue.INT_VALUE;
break;
case FALOAD :
expected1 = newValue( Type.getType( "[F" ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -