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

📄 classfilewriter.java

📁 javascript语言的解释器源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	 * 	 * @param local	 *            number of local register	 */	public void addDStore(int local) {		xop(ByteCode.DSTORE_0, ByteCode.DSTORE, local);	}	/**	 * Store object from stack top into the given local.	 * 	 * @param local	 *            number of local register	 */	public void addAStore(int local) {		xop(ByteCode.ASTORE_0, ByteCode.ASTORE, local);	}	/**	 * Load integer from the given local into stack.	 * 	 * @param local	 *            number of local register	 */	public void addILoad(int local) {		xop(ByteCode.ILOAD_0, ByteCode.ILOAD, local);	}	/**	 * Load long from the given local into stack.	 * 	 * @param local	 *            number of local register	 */	public void addLLoad(int local) {		xop(ByteCode.LLOAD_0, ByteCode.LLOAD, local);	}	/**	 * Load float from the given local into stack.	 * 	 * @param local	 *            number of local register	 */	public void addFLoad(int local) {		xop(ByteCode.FLOAD_0, ByteCode.FLOAD, local);	}	/**	 * Load double from the given local into stack.	 * 	 * @param local	 *            number of local register	 */	public void addDLoad(int local) {		xop(ByteCode.DLOAD_0, ByteCode.DLOAD, local);	}	/**	 * Load object from the given local into stack.	 * 	 * @param local	 *            number of local register	 */	public void addALoad(int local) {		xop(ByteCode.ALOAD_0, ByteCode.ALOAD, local);	}	/**	 * Load "this" into stack.	 */	public void addLoadThis() {		add(ByteCode.ALOAD_0);	}	private void xop(int shortOp, int op, int local) {		switch (local) {		case 0:			add(shortOp);			break;		case 1:			add(shortOp + 1);			break;		case 2:			add(shortOp + 2);			break;		case 3:			add(shortOp + 3);			break;		default:			add(op, local);		}	}	public int addTableSwitch(int low, int high) {		if (DEBUGCODE) {			System.out.println("Add " + bytecodeStr(ByteCode.TABLESWITCH) + " "					+ low + " " + high);		}		if (low > high)			throw new IllegalArgumentException("Bad bounds: " + low + ' '					+ high);		int newStack = itsStackTop + stackChange(ByteCode.TABLESWITCH);		if (newStack < 0 || Short.MAX_VALUE < newStack)			badStack(newStack);		int entryCount = high - low + 1;		int padSize = 3 & ~itsCodeBufferTop; // == 3 - itsCodeBufferTop % 4		int N = addReservedCodeSpace(1 + padSize + 4 * (1 + 2 + entryCount));		int switchStart = N;		itsCodeBuffer[N++] = (byte) ByteCode.TABLESWITCH;		while (padSize != 0) {			itsCodeBuffer[N++] = 0;			--padSize;		}		N += 4; // skip default offset		N = putInt32(low, itsCodeBuffer, N);		putInt32(high, itsCodeBuffer, N);		itsStackTop = (short) newStack;		if (newStack > itsMaxStack)			itsMaxStack = (short) newStack;		if (DEBUGSTACK) {			System.out.println("After " + bytecodeStr(ByteCode.TABLESWITCH)					+ " stack = " + itsStackTop);		}		return switchStart;	}	public final void markTableSwitchDefault(int switchStart) {		setTableSwitchJump(switchStart, -1, itsCodeBufferTop);	}	public final void markTableSwitchCase(int switchStart, int caseIndex) {		setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);	}	public final void markTableSwitchCase(int switchStart, int caseIndex,			int stackTop) {		if (!(0 <= stackTop && stackTop <= itsMaxStack))			throw new IllegalArgumentException("Bad stack index: " + stackTop);		itsStackTop = (short) stackTop;		setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);	}	public void setTableSwitchJump(int switchStart, int caseIndex,			int jumpTarget) {		if (!(0 <= jumpTarget && jumpTarget <= itsCodeBufferTop))			throw new IllegalArgumentException("Bad jump target: " + jumpTarget);		if (!(caseIndex >= -1))			throw new IllegalArgumentException("Bad case index: " + caseIndex);		int padSize = 3 & ~switchStart; // == 3 - switchStart % 4		int caseOffset;		if (caseIndex < 0) {			// default label			caseOffset = switchStart + 1 + padSize;		} else {			caseOffset = switchStart + 1 + padSize + 4 * (3 + caseIndex);		}		if (!(0 <= switchStart && switchStart <= itsCodeBufferTop - 4 * 4				- padSize - 1)) {			throw new IllegalArgumentException(switchStart					+ " is outside a possible range of tableswitch"					+ " in already generated code");		}		if ((0xFF & itsCodeBuffer[switchStart]) != ByteCode.TABLESWITCH) {			throw new IllegalArgumentException(switchStart					+ " is not offset of tableswitch statement");		}		if (!(0 <= caseOffset && caseOffset + 4 <= itsCodeBufferTop)) {			// caseIndex >= -1 does not guarantee that caseOffset >= 0 due			// to a possible overflow.			throw new IllegalArgumentException("Too big case index: "					+ caseIndex);		}		// ALERT: perhaps check against case bounds?		putInt32(jumpTarget - switchStart, itsCodeBuffer, caseOffset);	}	public int acquireLabel() {		int top = itsLabelTableTop;		if (itsLabelTable == null || top == itsLabelTable.length) {			if (itsLabelTable == null) {				itsLabelTable = new int[MIN_LABEL_TABLE_SIZE];			} else {				int[] tmp = new int[itsLabelTable.length * 2];				System.arraycopy(itsLabelTable, 0, tmp, 0, top);				itsLabelTable = tmp;			}		}		itsLabelTableTop = top + 1;		itsLabelTable[top] = -1;		return top | 0x80000000;	}	public void markLabel(int label) {		if (!(label < 0))			throw new IllegalArgumentException("Bad label, no biscuit");		label &= 0x7FFFFFFF;		if (label > itsLabelTableTop)			throw new IllegalArgumentException("Bad label");		if (itsLabelTable[label] != -1) {			throw new IllegalStateException("Can only mark label once");		}		itsLabelTable[label] = itsCodeBufferTop;	}	public void markLabel(int label, short stackTop) {		markLabel(label);		itsStackTop = stackTop;	}	public void markHandler(int theLabel) {		itsStackTop = 1;		markLabel(theLabel);	}	private int getLabelPC(int label) {		if (!(label < 0))			throw new IllegalArgumentException("Bad label, no biscuit");		label &= 0x7FFFFFFF;		if (!(label < itsLabelTableTop))			throw new IllegalArgumentException("Bad label");		return itsLabelTable[label];	}	private void addLabelFixup(int label, int fixupSite) {		if (!(label < 0))			throw new IllegalArgumentException("Bad label, no biscuit");		label &= 0x7FFFFFFF;		if (!(label < itsLabelTableTop))			throw new IllegalArgumentException("Bad label");		int top = itsFixupTableTop;		if (itsFixupTable == null || top == itsFixupTable.length) {			if (itsFixupTable == null) {				itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE];			} else {				long[] tmp = new long[itsFixupTable.length * 2];				System.arraycopy(itsFixupTable, 0, tmp, 0, top);				itsFixupTable = tmp;			}		}		itsFixupTableTop = top + 1;		itsFixupTable[top] = ((long) label << 32) | fixupSite;	}	private void fixLabelGotos() {		byte[] codeBuffer = itsCodeBuffer;		for (int i = 0; i < itsFixupTableTop; i++) {			long fixup = itsFixupTable[i];			int label = (int) (fixup >> 32);			int fixupSite = (int) fixup;			int pc = itsLabelTable[label];			if (pc == -1) {				// Unlocated label				throw new RuntimeException();			}			// -1 to get delta from instruction start			int offset = pc - (fixupSite - 1);			if ((short) offset != offset) {				throw new RuntimeException(						"Program too complex: too big jump offset");			}			codeBuffer[fixupSite] = (byte) (offset >> 8);			codeBuffer[fixupSite + 1] = (byte) offset;		}		itsFixupTableTop = 0;	}	/**	 * Get the current offset into the code of the current method.	 * 	 * @return an integer representing the offset	 */	public int getCurrentCodeOffset() {		return itsCodeBufferTop;	}	public short getStackTop() {		return itsStackTop;	}	public void adjustStackTop(int delta) {		int newStack = itsStackTop + delta;		if (newStack < 0 || Short.MAX_VALUE < newStack)			badStack(newStack);		itsStackTop = (short) newStack;		if (newStack > itsMaxStack)			itsMaxStack = (short) newStack;		if (DEBUGSTACK) {			System.out.println("After " + "adjustStackTop(" + delta + ")"					+ " stack = " + itsStackTop);		}	}	private void addToCodeBuffer(int b) {		int N = addReservedCodeSpace(1);		itsCodeBuffer[N] = (byte) b;	}	private void addToCodeInt16(int value) {		int N = addReservedCodeSpace(2);		putInt16(value, itsCodeBuffer, N);	}	private int addReservedCodeSpace(int size) {		if (itsCurrentMethod == null)			throw new IllegalArgumentException("No method to add to");		int oldTop = itsCodeBufferTop;		int newTop = oldTop + size;		if (newTop > itsCodeBuffer.length) {			int newSize = itsCodeBuffer.length * 2;			if (newTop > newSize) {				newSize = newTop;			}			byte[] tmp = new byte[newSize];			System.arraycopy(itsCodeBuffer, 0, tmp, 0, oldTop);			itsCodeBuffer = tmp;		}		itsCodeBufferTop = newTop;		return oldTop;	}	public void addExceptionHandler(int startLabel, int endLabel,			int handlerLabel, String catchClassName) {		if ((startLabel & 0x80000000) != 0x80000000)			throw new IllegalArgumentException("Bad startLabel");		if ((endLabel & 0x80000000) != 0x80000000)			throw new IllegalArgumentException("Bad endLabel");		if ((handlerLabel & 0x80000000) != 0x80000000)			throw new IllegalArgumentException("Bad handlerLabel");		/*		 * If catchClassName is null, use 0 for the catch_type_index; which		 * means catch everything. (Even when the verifier has let you throw		 * something other than a Throwable.)		 */		short catch_type_index = (catchClassName == null) ? 0 : itsConstantPool				.addClass(catchClassName);		ExceptionTableEntry newEntry = new ExceptionTableEntry(startLabel,				endLabel, handlerLabel, catch_type_index);		int N = itsExceptionTableTop;		if (N == 0) {			itsExceptionTable = new ExceptionTableEntry[ExceptionTableSize];		} else if (N == itsExceptionTable.length) {			ExceptionTableEntry[] tmp = new ExceptionTableEntry[N * 2];			System.arraycopy(itsExceptionTable, 0, tmp, 0, N);			itsExceptionTable = tmp;		}		itsExceptionTable[N] = newEntry;		itsExceptionTableTop = N + 1;	}	public void addLineNumberEntry(short lineNumber) {		if (itsCurrentMethod == null)			throw new IllegalArgumentException("No method to stop");		int N = itsLineNumberTableTop;		if (N == 0) {			itsLineNumberTable = new int[LineNumberTableSize];		} else if (N == itsLineNumberTable.length) {			int[] tmp = new int[N * 2];			System.arraycopy(itsLineNumberTable, 0, tmp, 0, N);			itsLineNumberTable = tmp;		}		itsLineNumberTable[N] = (itsCodeBufferTop << 16) + lineNumber;		itsLineNumberTableTop = N + 1;	}	/**	 * Write the class file to the OutputStream.	 * 	 * @param oStream	 *            the stream to write to	 * @throws IOException	 *             if writing to the stream produces an exception	 */	public void write(OutputStream oStream) throws IOException {		byte[] array = toByteArray();		oStream.write(array);	}	private int getWriteSize() {		int size = 0;		if (itsSourceFileNameIndex != 0) {			itsConstantPool.addUtf8("SourceFile");		}		size += 8; // writeLong(FileHeaderConstant);		size += itsConstantPool.getWriteSize();		size += 2; // writeShort(itsFlags);		size += 2; // writeShort(itsThisClassIndex);		size += 2; // writeShort(itsSuperClassIndex);		size += 2; // writeShort(itsInterfaces.size());		size += 2 * itsInterfaces.size();		size += 2; // writeShort(itsFields.size());		for (int i = 0; i < itsFields.size(); i++) {			size += ((ClassFileField) (itsFields.get(i))).getWriteSize();		}		size += 2; // writeShort(itsMethods.size());		for (int i = 0; i < itsMethods.size(); i++) {			size += ((ClassFileMethod) (itsMethods.get(i))).getWriteSize();		}		if (itsSourceFileNameIndex != 0) {			size += 2; // writeShort(1); attributes count			size += 2; // writeShort(sourceFileAttributeNameIndex);			size += 4; // writeInt(2);			size += 2; // writeShort(itsSourceFileNameIndex);		} else {			size += 2; // out.writeShort(0); no attributes		}		return size;	}	/**	 * Get the class file as array of bytesto the OutputStream.	 */	public byte[] toByteArray() {		int dataSize = getWriteSize();		byte[] data = new byte[dataSize];		int offset = 0;		short sourceFileAttributeNameIndex = 0;		if (itsSourceFileNameIndex != 0) {			sourceFileAttributeNameIndex = itsConstantPool					.addUtf8("SourceFile");		}		offset = putInt64(FileHeaderConstant, data, offset);		offset = itsConstantPool.write(data, offset);		offset = putInt16(itsFlags, data, offset);		offset = putInt16(itsThisClassIndex, data, offset);		offset = putInt16(itsSuperClassIndex, data, offset);		offset = putInt16(itsInterfaces.size(), data, offset);		for (int i = 0; i < itsInterfaces.size(); i++) {			int interfaceIndex = ((Short) (itsInterfaces.get(i))).shortValue();			offset = putInt16(interfaceIndex, data, offset);		}		offset = putInt16(itsFields.size(), data, offset);		for (int i = 0; i < itsFields.size(); i++) {			ClassFileField field = (ClassFileField) itsFields.get(i);			offset = field.write(data, offset);		}		offset = putInt16(itsMethods.size(), data, offset);		for (int i = 0; i < itsMethods.size(); i++) {			ClassFileMethod method = (ClassFileMethod) itsMethods.get(i);			offset = method.write(data, offset);		}		if (itsSourceFileNameIndex != 0) {			offset = putInt16(1, data, offset); // attributes count			offset = putInt16(sourceFileAttributeNameIndex, data, offset);			offset = putInt32(2, data, offset);			offset = putInt16(itsSourceFileNameIndex, data, offset);

⌨️ 快捷键说明

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