⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 preverifiermethodnode.java

📁 eclipseme的最新版本的source,欢迎j2me程序员使用
💻 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 + -