📄 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.objectweb.asm.tree.analysis;
import java.util.List;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.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.getObjectType(((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 Error("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"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -