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

📄 classfilewriter.java

📁 javascript语言的解释器源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
			break;		case ByteCode.BIPUSH:			if ((byte) theOperand != theOperand)				throw new IllegalArgumentException("out of range byte");			addToCodeBuffer(theOpCode);			addToCodeBuffer((byte) theOperand);			break;		case ByteCode.SIPUSH:			if ((short) theOperand != theOperand)				throw new IllegalArgumentException("out of range short");			addToCodeBuffer(theOpCode);			addToCodeInt16(theOperand);			break;		case ByteCode.NEWARRAY:			if (!(0 <= theOperand && theOperand < 256))				throw new IllegalArgumentException("out of range index");			addToCodeBuffer(theOpCode);			addToCodeBuffer(theOperand);			break;		case ByteCode.GETFIELD:		case ByteCode.PUTFIELD:			if (!(0 <= theOperand && theOperand < 65536))				throw new IllegalArgumentException("out of range field");			addToCodeBuffer(theOpCode);			addToCodeInt16(theOperand);			break;		case ByteCode.LDC:		case ByteCode.LDC_W:		case ByteCode.LDC2_W:			if (!(0 <= theOperand && theOperand < 65536))				throw new IllegalArgumentException("out of range index");			if (theOperand >= 256 || theOpCode == ByteCode.LDC_W					|| theOpCode == ByteCode.LDC2_W) {				if (theOpCode == ByteCode.LDC) {					addToCodeBuffer(ByteCode.LDC_W);				} else {					addToCodeBuffer(theOpCode);				}				addToCodeInt16(theOperand);			} else {				addToCodeBuffer(theOpCode);				addToCodeBuffer(theOperand);			}			break;		case ByteCode.RET:		case ByteCode.ILOAD:		case ByteCode.LLOAD:		case ByteCode.FLOAD:		case ByteCode.DLOAD:		case ByteCode.ALOAD:		case ByteCode.ISTORE:		case ByteCode.LSTORE:		case ByteCode.FSTORE:		case ByteCode.DSTORE:		case ByteCode.ASTORE:			if (!(0 <= theOperand && theOperand < 65536))				throw new IllegalArgumentException("out of range variable");			if (theOperand >= 256) {				addToCodeBuffer(ByteCode.WIDE);				addToCodeBuffer(theOpCode);				addToCodeInt16(theOperand);			} else {				addToCodeBuffer(theOpCode);				addToCodeBuffer(theOperand);			}			break;		default:			throw new IllegalArgumentException(					"Unexpected opcode for 1 operand");		}		itsStackTop = (short) newStack;		if (newStack > itsMaxStack)			itsMaxStack = (short) newStack;		if (DEBUGSTACK) {			System.out.println("After " + bytecodeStr(theOpCode) + " stack = "					+ itsStackTop);		}	}	/**	 * Generate the load constant bytecode for the given integer.	 * 	 * @param k	 *            the constant	 */	public void addLoadConstant(int k) {		add(ByteCode.LDC, itsConstantPool.addConstant(k));	}	/**	 * Generate the load constant bytecode for the given long.	 * 	 * @param k	 *            the constant	 */	public void addLoadConstant(long k) {		add(ByteCode.LDC2_W, itsConstantPool.addConstant(k));	}	/**	 * Generate the load constant bytecode for the given float.	 * 	 * @param k	 *            the constant	 */	public void addLoadConstant(float k) {		add(ByteCode.LDC, itsConstantPool.addConstant(k));	}	/**	 * Generate the load constant bytecode for the given double.	 * 	 * @param k	 *            the constant	 */	public void addLoadConstant(double k) {		add(ByteCode.LDC2_W, itsConstantPool.addConstant(k));	}	/**	 * Generate the load constant bytecode for the given string.	 * 	 * @param k	 *            the constant	 */	public void addLoadConstant(String k) {		add(ByteCode.LDC, itsConstantPool.addConstant(k));	}	/**	 * Add the given two-operand bytecode to the current method.	 * 	 * @param theOpCode	 *            the opcode of the bytecode	 * @param theOperand1	 *            the first operand of the bytecode	 * @param theOperand2	 *            the second operand of the bytecode	 */	public void add(int theOpCode, int theOperand1, int theOperand2) {		if (DEBUGCODE) {			System.out.println("Add " + bytecodeStr(theOpCode) + ", "					+ Integer.toHexString(theOperand1) + ", "					+ Integer.toHexString(theOperand2));		}		int newStack = itsStackTop + stackChange(theOpCode);		if (newStack < 0 || Short.MAX_VALUE < newStack)			badStack(newStack);		if (theOpCode == ByteCode.IINC) {			if (!(0 <= theOperand1 && theOperand1 < 65536))				throw new IllegalArgumentException("out of range variable");			if (!(0 <= theOperand2 && theOperand2 < 65536))				throw new IllegalArgumentException("out of range increment");			if (theOperand1 > 255 || theOperand2 < -128 || theOperand2 > 127) {				addToCodeBuffer(ByteCode.WIDE);				addToCodeBuffer(ByteCode.IINC);				addToCodeInt16(theOperand1);				addToCodeInt16(theOperand2);			} else {				addToCodeBuffer(ByteCode.WIDE);				addToCodeBuffer(ByteCode.IINC);				addToCodeBuffer(theOperand1);				addToCodeBuffer(theOperand2);			}		} else if (theOpCode == ByteCode.MULTIANEWARRAY) {			if (!(0 <= theOperand1 && theOperand1 < 65536))				throw new IllegalArgumentException("out of range index");			if (!(0 <= theOperand2 && theOperand2 < 256))				throw new IllegalArgumentException("out of range dimensions");			addToCodeBuffer(ByteCode.MULTIANEWARRAY);			addToCodeInt16(theOperand1);			addToCodeBuffer(theOperand2);		} else {			throw new IllegalArgumentException(					"Unexpected opcode for 2 operands");		}		itsStackTop = (short) newStack;		if (newStack > itsMaxStack)			itsMaxStack = (short) newStack;		if (DEBUGSTACK) {			System.out.println("After " + bytecodeStr(theOpCode) + " stack = "					+ itsStackTop);		}	}	public void add(int theOpCode, String className) {		if (DEBUGCODE) {			System.out.println("Add " + bytecodeStr(theOpCode) + ", "					+ className);		}		int newStack = itsStackTop + stackChange(theOpCode);		if (newStack < 0 || Short.MAX_VALUE < newStack)			badStack(newStack);		switch (theOpCode) {		case ByteCode.NEW:		case ByteCode.ANEWARRAY:		case ByteCode.CHECKCAST:		case ByteCode.INSTANCEOF: {			short classIndex = itsConstantPool.addClass(className);			addToCodeBuffer(theOpCode);			addToCodeInt16(classIndex);		}			break;		default:			throw new IllegalArgumentException("bad opcode for class reference");		}		itsStackTop = (short) newStack;		if (newStack > itsMaxStack)			itsMaxStack = (short) newStack;		if (DEBUGSTACK) {			System.out.println("After " + bytecodeStr(theOpCode) + " stack = "					+ itsStackTop);		}	}	public void add(int theOpCode, String className, String fieldName,			String fieldType) {		if (DEBUGCODE) {			System.out.println("Add " + bytecodeStr(theOpCode) + ", "					+ className + ", " + fieldName + ", " + fieldType);		}		int newStack = itsStackTop + stackChange(theOpCode);		char fieldTypeChar = fieldType.charAt(0);		int fieldSize = (fieldTypeChar == 'J' || fieldTypeChar == 'D') ? 2 : 1;		switch (theOpCode) {		case ByteCode.GETFIELD:		case ByteCode.GETSTATIC:			newStack += fieldSize;			break;		case ByteCode.PUTSTATIC:		case ByteCode.PUTFIELD:			newStack -= fieldSize;			break;		default:			throw new IllegalArgumentException("bad opcode for field reference");		}		if (newStack < 0 || Short.MAX_VALUE < newStack)			badStack(newStack);		short fieldRefIndex = itsConstantPool.addFieldRef(className, fieldName,				fieldType);		addToCodeBuffer(theOpCode);		addToCodeInt16(fieldRefIndex);		itsStackTop = (short) newStack;		if (newStack > itsMaxStack)			itsMaxStack = (short) newStack;		if (DEBUGSTACK) {			System.out.println("After " + bytecodeStr(theOpCode) + " stack = "					+ itsStackTop);		}	}	public void addInvoke(int theOpCode, String className, String methodName,			String methodType) {		if (DEBUGCODE) {			System.out.println("Add " + bytecodeStr(theOpCode) + ", "					+ className + ", " + methodName + ", " + methodType);		}		int parameterInfo = sizeOfParameters(methodType);		int parameterCount = parameterInfo >>> 16;		int stackDiff = (short) parameterInfo;		int newStack = itsStackTop + stackDiff;		newStack += stackChange(theOpCode); // adjusts for 'this'		if (newStack < 0 || Short.MAX_VALUE < newStack)			badStack(newStack);		switch (theOpCode) {		case ByteCode.INVOKEVIRTUAL:		case ByteCode.INVOKESPECIAL:		case ByteCode.INVOKESTATIC:		case ByteCode.INVOKEINTERFACE: {			addToCodeBuffer(theOpCode);			if (theOpCode == ByteCode.INVOKEINTERFACE) {				short ifMethodRefIndex = itsConstantPool.addInterfaceMethodRef(						className, methodName, methodType);				addToCodeInt16(ifMethodRefIndex);				addToCodeBuffer(parameterCount + 1);				addToCodeBuffer(0);			} else {				short methodRefIndex = itsConstantPool.addMethodRef(className,						methodName, methodType);				addToCodeInt16(methodRefIndex);			}		}			break;		default:			throw new IllegalArgumentException(					"bad opcode for method reference");		}		itsStackTop = (short) newStack;		if (newStack > itsMaxStack)			itsMaxStack = (short) newStack;		if (DEBUGSTACK) {			System.out.println("After " + bytecodeStr(theOpCode) + " stack = "					+ itsStackTop);		}	}	/**	 * Generate code to load the given integer on stack.	 * 	 * @param k	 *            the constant	 */	public void addPush(int k) {		if ((byte) k == k) {			if (k == -1) {				add(ByteCode.ICONST_M1);			} else if (0 <= k && k <= 5) {				add((byte) (ByteCode.ICONST_0 + k));			} else {				add(ByteCode.BIPUSH, (byte) k);			}		} else if ((short) k == k) {			add(ByteCode.SIPUSH, (short) k);		} else {			addLoadConstant(k);		}	}	public void addPush(boolean k) {		add(k ? ByteCode.ICONST_1 : ByteCode.ICONST_0);	}	/**	 * Generate code to load the given long on stack.	 * 	 * @param k	 *            the constant	 */	public void addPush(long k) {		int ik = (int) k;		if (ik == k) {			addPush(ik);			add(ByteCode.I2L);		} else {			addLoadConstant(k);		}	}	/**	 * Generate code to load the given double on stack.	 * 	 * @param k	 *            the constant	 */	public void addPush(double k) {		if (k == 0.0) {			// zero			add(ByteCode.DCONST_0);			if (1.0 / k < 0) {				// Negative zero				add(ByteCode.DNEG);			}		} else if (k == 1.0 || k == -1.0) {			add(ByteCode.DCONST_1);			if (k < 0) {				add(ByteCode.DNEG);			}		} else {			addLoadConstant(k);		}	}	/**	 * Generate the code to leave on stack the given string even if the string	 * encoding exeeds the class file limit for single string constant	 * 	 * @param k	 *            the constant	 */	public void addPush(String k) {		int length = k.length();		int limit = itsConstantPool.getUtfEncodingLimit(k, 0, length);		if (limit == length) {			addLoadConstant(k);			return;		}		// Split string into picies fitting the UTF limit and generate code for		// StringBuffer sb = new StringBuffer(length);		// sb.append(loadConstant(piece_1));		// ...		// sb.append(loadConstant(piece_N));		// sb.toString();		final String SB = "java/lang/StringBuffer";		add(ByteCode.NEW, SB);		add(ByteCode.DUP);		addPush(length);		addInvoke(ByteCode.INVOKESPECIAL, SB, "<init>", "(I)V");		int cursor = 0;		for (;;) {			add(ByteCode.DUP);			String s = k.substring(cursor, limit);			addLoadConstant(s);			addInvoke(ByteCode.INVOKEVIRTUAL, SB, "append",					"(Ljava/lang/String;)Ljava/lang/StringBuffer;");			add(ByteCode.POP);			if (limit == length) {				break;			}			cursor = limit;			limit = itsConstantPool.getUtfEncodingLimit(k, limit, length);		}		addInvoke(ByteCode.INVOKEVIRTUAL, SB, "toString",				"()Ljava/lang/String;");	}	/**	 * Check if k fits limit on string constant size imposed by class file	 * format.	 * 	 * @param k	 *            the string constant	 */	public boolean isUnderStringSizeLimit(String k) {		return itsConstantPool.isUnderUtfEncodingLimit(k);	}	/**	 * Store integer from stack top into the given local.	 * 	 * @param local	 *            number of local register	 */	public void addIStore(int local) {		xop(ByteCode.ISTORE_0, ByteCode.ISTORE, local);	}	/**	 * Store long from stack top into the given local.	 * 	 * @param local	 *            number of local register	 */	public void addLStore(int local) {		xop(ByteCode.LSTORE_0, ByteCode.LSTORE, local);	}	/**	 * Store float from stack top into the given local.	 * 	 * @param local	 *            number of local register	 */	public void addFStore(int local) {		xop(ByteCode.FSTORE_0, ByteCode.FSTORE, local);	}	/**	 * Store double from stack top into the given local.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -