?? preverifiermethodnode.java
字號:
/**
* Copyright (c) 2003-2004 Craig Setera
* All Rights Reserved.
* Licensed under the Eclipse Public License - v 1.0
* For more information see http://www.eclipse.org/legal/epl-v10.html
*/
package eclipseme.preverifier.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.analysis.AnalyzerException;
import eclipseme.preverifier.internal.results.ClassNodeErrorInformation;
import eclipseme.preverifier.internal.results.FieldErrorInformation;
import eclipseme.preverifier.internal.results.MethodNodeErrorInformation;
import eclipseme.preverifier.results.PreverificationError;
import eclipseme.preverifier.results.PreverificationErrorLocation;
import eclipseme.preverifier.results.PreverificationErrorLocationType;
import eclipseme.preverifier.results.PreverificationErrorType;
/**
* MethodNode subclass that does preverification of the
* associated method code as well as looking for preverification
* errors.
* <p />
* Copyright (c) 2003-2004 Craig Setera<br>
* All Rights Reserved.<br>
* Licensed under the Eclipse Public License - v 1.0<p/>
* <br>
* $Revision: 1.4 $
* <br>
* $Date: 2005/12/14 01:56:24 $
* <br>
* @author Craig Setera
*/
public class PreverifierMethodNode extends MethodNode {
private PreverificationClassNode classNode;
private int lineNumber;
private List jsrInstructionIndices;
private Map labelIndices;
/**
* Construct a new method node.
*
* @param access
* @param name
* @param desc
* @param exceptions
* @param attrs
*/
public PreverifierMethodNode(
PreverificationClassNode classNode,
int access,
String name,
String desc,
String signature,
String[] exceptions)
{
super(access, name, desc, signature, exceptions);
this.classNode = classNode;
lineNumber = -1;
jsrInstructionIndices = new ArrayList();
labelIndices = new HashMap();
}
/**
* Return the indices of the JSR instruction encountered during visitation.
*
* @return
*/
List getJsrInstructionIndices() {
return jsrInstructionIndices;
}
/**
* Return the map from label instances to their indices within the
* list of instructions.
*
* @return
*/
Map getLabelIndices() {
return labelIndices;
}
/**
* @see org.objectweb.asm.tree.MemberNode#visitEnd()
*/
public void visitEnd() {
boolean hasNoCode =
((access & Opcodes.ACC_NATIVE) != 0) ||
((access & Opcodes.ACC_ABSTRACT) != 0);
if (hasNoCode) {
classNode.methods.add(this);
} else {
MethodRewriter handler = new MethodRewriter(classNode, this);
try {
MethodNode updatedMethod = handler.getUpdatedMethod();
classNode.methods.add(updatedMethod);
} catch (AnalyzerException e) {
throw new RuntimeException("Method " + name + ": " + e.getMessage(), e);
}
}
}
/**
* @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, java.lang.String, java.lang.String, java.lang.String)
*/
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (isDisallowedInstruction(opcode)) {
ClassNodeErrorInformation classInfo = new ClassNodeErrorInformation(classNode);
MethodNodeErrorInformation methodInfo = new MethodNodeErrorInformation(classInfo, this);
FieldErrorInformation fieldInfo = new FieldErrorInformation(name, desc);
PreverificationErrorLocation location = new PreverificationErrorLocation(
PreverificationErrorLocationType.METHOD_FIELD,
classInfo, methodInfo, fieldInfo, lineNumber);
PreverificationError error =
new PreverificationError(PreverificationErrorType.FLOATING_POINT, location, null);
addError(error);
}
super.visitFieldInsn(opcode, owner, name, desc);
}
/**
* @see org.objectweb.asm.MethodVisitor#visitIincInsn(int, int)
*/
public void visitIincInsn(int var, int increment) {
// TODO Fix this...
super.visitIincInsn(var, increment);
}
/**
* @see org.objectweb.asm.MethodVisitor#visitInsn(int)
*/
public void visitInsn(int opcode) {
if (isDisallowedInstruction(opcode)) {
ClassNodeErrorInformation classInfo = new ClassNodeErrorInformation(classNode);
MethodNodeErrorInformation methodInfo = new MethodNodeErrorInformation(classInfo, this);
PreverificationErrorLocation location = new PreverificationErrorLocation(
PreverificationErrorLocationType.METHOD_INSTRUCTION,
classInfo, methodInfo, null, lineNumber);
PreverificationError error =
new PreverificationError(PreverificationErrorType.FLOATING_POINT, location, null);
addError(error);
}
super.visitInsn(opcode);
}
/**
* @see org.objectweb.asm.MethodVisitor#visitIntInsn(int, int)
*/
public void visitIntInsn(int opcode, int operand) {
if (opcode == Opcodes.NEWARRAY) {
if ((operand == Opcodes.T_DOUBLE) || (operand == Opcodes.T_FLOAT)) {
ClassNodeErrorInformation classInfo = new ClassNodeErrorInformation(classNode);
MethodNodeErrorInformation methodInfo = new MethodNodeErrorInformation(classInfo, this);
PreverificationErrorLocation location = new PreverificationErrorLocation(
PreverificationErrorLocationType.METHOD_INSTRUCTION,
classInfo, methodInfo, null, lineNumber);
PreverificationError error =
new PreverificationError(PreverificationErrorType.FLOATING_POINT, location, null);
addError(error);
}
}
super.visitIntInsn(opcode, operand);
}
/**
* @see org.objectweb.asm.CodeVisitor#visitLocalVariable(java.lang.String, java.lang.String, org.objectweb.asm.Label, org.objectweb.asm.Label, int)
*/
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
if (isDisallowedType(desc)) {
ClassNodeErrorInformation classInfo = new ClassNodeErrorInformation(classNode);
MethodNodeErrorInformation methodInfo = new MethodNodeErrorInformation(classInfo, this);
FieldErrorInformation fieldInfo = new FieldErrorInformation(name, desc);
PreverificationErrorLocation location = new PreverificationErrorLocation(
PreverificationErrorLocationType.METHOD_FIELD,
classInfo, methodInfo, fieldInfo, lineNumber);
PreverificationError error =
new PreverificationError(PreverificationErrorType.FLOATING_POINT, location, null);
addError(error);
}
super.visitLocalVariable(name, desc, signature, start, end, index);
}
/**
* @see org.objectweb.asm.CodeVisitor#visitMultiANewArrayInsn(java.lang.String, int)
*/
public void visitMultiANewArrayInsn(String desc, int dims) {
if (isDisallowedType(desc)) {
ClassNodeErrorInformation classInfo = new ClassNodeErrorInformation(classNode);
MethodNodeErrorInformation methodInfo = new MethodNodeErrorInformation(classInfo, this);
PreverificationErrorLocation location = new PreverificationErrorLocation(
PreverificationErrorLocationType.METHOD_INSTRUCTION,
classInfo, methodInfo, null, lineNumber);
PreverificationError error =
new PreverificationError(PreverificationErrorType.FLOATING_POINT, location, null);
addError(error);
}
super.visitMultiANewArrayInsn(desc, dims);
}
/**
* @see org.objectweb.asm.CodeVisitor#visitVarInsn(int, int)
*/
public void visitVarInsn(int opcode, int var) {
// TODO Fix this... addFloatingPointErrorAsNecessary(opcode);
super.visitVarInsn(opcode, var);
}
/**
* @see org.objectweb.asm.CodeVisitor#visitJumpInsn(int, org.objectweb.asm.Label)
*/
public void visitJumpInsn(int opcode, Label label) {
if (isDisallowedInstruction(opcode)) {
ClassNodeErrorInformation classInfo = new ClassNodeErrorInformation(classNode);
MethodNodeErrorInformation methodInfo = new MethodNodeErrorInformation(classInfo, this);
PreverificationErrorLocation location = new PreverificationErrorLocation(
PreverificationErrorLocationType.METHOD_INSTRUCTION,
classInfo, methodInfo, null, lineNumber);
PreverificationError error =
new PreverificationError(PreverificationErrorType.FLOATING_POINT, location, null);
addError(error);
} else if (opcode == Opcodes.JSR) {
// Don't follow JSR's as they will be removed anyway...
jsrInstructionIndices.add(new Integer(instructions.size()));
}
super.visitJumpInsn(opcode, label);
}
/**
* @see org.objectweb.asm.tree.MethodNode#visitLabel(org.objectweb.asm.Label)
*/
public void visitLabel(Label label) {
labelIndices.put(label, new Integer(instructions.size()));
super.visitLabel(label);
}
/**
* @see org.objectweb.asm.CodeVisitor#visitLineNumber(int, org.objectweb.asm.Label)
*/
public void visitLineNumber(int line, Label start) {
lineNumber = line;
super.visitLineNumber(line, start);
}
/**
* Add a new error to the list of errors.
*/
private void addError(PreverificationError error) {
classNode.getErrorList().add(error);
}
/**
* Return a boolean indicating whether the specified opcode is a
* disallowed floating point Opcodes.
*
* @param opcode
* @return
*/
private boolean isDisallowedInstruction(int opcode) {
return
!classNode.getPreverificationPolicy().isFloatingPointAllowed() &&
isFloatingPointOpcode(opcode);
}
/**
* Return a boolean indicating whether the specifie type description is a
* disallowed floating point Opcodes.
*
* @param typeDescription
* @return
*/
private boolean isDisallowedType(String typeDescription) {
Type type = Type.getType(typeDescription);
PreverificationErrorType error = classNode.validateType(type);
return error != PreverificationErrorType.NO_ERROR;
}
/**
* Return a boolean indicating whether the specified opcode is
* a floating point Opcodes.
*
* @param opcode
* @return
*/
private boolean isFloatingPointOpcode(int opcode) {
boolean isFloatingPointOpcode = false;
switch (opcode) {
case Opcodes.FCONST_0:
case Opcodes.FCONST_1:
case Opcodes.FCONST_2:
case Opcodes.DCONST_0:
case Opcodes.DCONST_1:
case Opcodes.FLOAD:
case Opcodes.DLOAD:
case Opcodes.FSTORE:
case Opcodes.DSTORE:
case Opcodes.FALOAD:
case Opcodes.DALOAD:
case Opcodes.FASTORE:
case Opcodes.DASTORE:
case Opcodes.FADD:
case Opcodes.DADD:
case Opcodes.FSUB:
case Opcodes.DSUB:
case Opcodes.FMUL:
case Opcodes.DMUL:
case Opcodes.FDIV:
case Opcodes.DDIV:
case Opcodes.FREM:
case Opcodes.DREM:
case Opcodes.FNEG:
case Opcodes.DNEG:
case Opcodes.FCMPG:
case Opcodes.FCMPL:
case Opcodes.DCMPG:
case Opcodes.DCMPL:
case Opcodes.I2F:
case Opcodes.F2I:
case Opcodes.I2D:
case Opcodes.D2I:
case Opcodes.L2F:
case Opcodes.L2D:
case Opcodes.F2L:
case Opcodes.D2L:
case Opcodes.F2D:
case Opcodes.D2F:
case Opcodes.FRETURN:
case Opcodes.DRETURN:
isFloatingPointOpcode = true;
break;
}
return isFloatingPointOpcode;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -