Org.Mozilla.Classfile.ClassFileWriter.StopMethod C# (CSharp) Method

StopMethod() public method

Complete generation of the method.
Complete generation of the method. After this method is called, no more code can be added to the method begun with startMethod.
public StopMethod ( short maxLocals ) : void
maxLocals short /// the maximum number of local variable slots /// (a.k.a. Java registers) used by the method ///
return void
		public virtual void StopMethod(short maxLocals)
		{
			if (itsCurrentMethod == null)
			{
				throw new InvalidOperationException("No method to stop");
			}
			FixLabelGotos();
			itsMaxLocals = maxLocals;
			ClassFileWriter.StackMapTable stackMap = null;
			if (GenerateStackMap)
			{
				FinalizeSuperBlockStarts();
				stackMap = new ClassFileWriter.StackMapTable(this);
				stackMap.Generate();
			}
			int lineNumberTableLength = 0;
			if (itsLineNumberTable != null)
			{
				// 6 bytes for the attribute header
				// 2 bytes for the line number count
				// 4 bytes for each entry
				lineNumberTableLength = 6 + 2 + (itsLineNumberTableTop * 4);
			}
			int variableTableLength = 0;
			if (itsVarDescriptors != null)
			{
				// 6 bytes for the attribute header
				// 2 bytes for the variable count
				// 10 bytes for each entry
				variableTableLength = 6 + 2 + (itsVarDescriptors.Size() * 10);
			}
			int stackMapTableLength = 0;
			if (stackMap != null)
			{
				int stackMapWriteSize = stackMap.ComputeWriteSize();
				if (stackMapWriteSize > 0)
				{
					stackMapTableLength = 6 + stackMapWriteSize;
				}
			}
			int attrLength = 2 + 4 + 2 + 2 + 4 + itsCodeBufferTop + 2 + (itsExceptionTableTop * 8) + 2 + lineNumberTableLength + variableTableLength + stackMapTableLength;
			// attribute_name_index
			// attribute_length
			// max_stack
			// max_locals
			// code_length
			// exception_table_length
			// attributes_count
			if (attrLength > 65536)
			{
				// See http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html,
				// section 4.10, "The amount of code per non-native, non-abstract
				// method is limited to 65536 bytes...
				throw new ClassFileWriter.ClassFileFormatException("generated bytecode for method exceeds 64K limit.");
			}
			byte[] codeAttribute = new byte[attrLength];
			int index = 0;
			int codeAttrIndex = itsConstantPool.AddUtf8("Code");
			index = PutInt16(codeAttrIndex, codeAttribute, index);
			attrLength -= 6;
			// discount the attribute header
			index = PutInt32(attrLength, codeAttribute, index);
			index = PutInt16(itsMaxStack, codeAttribute, index);
			index = PutInt16(itsMaxLocals, codeAttribute, index);
			index = PutInt32(itsCodeBufferTop, codeAttribute, index);
			System.Array.Copy(itsCodeBuffer, 0, codeAttribute, index, itsCodeBufferTop);
			index += itsCodeBufferTop;
			if (itsExceptionTableTop > 0)
			{
				index = PutInt16(itsExceptionTableTop, codeAttribute, index);
				for (int i = 0; i < itsExceptionTableTop; i++)
				{
					ExceptionTableEntry ete = itsExceptionTable[i];
					short startPC = (short)GetLabelPC(ete.itsStartLabel);
					short endPC = (short)GetLabelPC(ete.itsEndLabel);
					short handlerPC = (short)GetLabelPC(ete.itsHandlerLabel);
					short catchType = ete.itsCatchType;
					if (startPC == -1)
					{
						throw new InvalidOperationException("start label not defined");
					}
					if (endPC == -1)
					{
						throw new InvalidOperationException("end label not defined");
					}
					if (handlerPC == -1)
					{
						throw new InvalidOperationException("handler label not defined");
					}
					index = PutInt16(startPC, codeAttribute, index);
					index = PutInt16(endPC, codeAttribute, index);
					index = PutInt16(handlerPC, codeAttribute, index);
					index = PutInt16(catchType, codeAttribute, index);
				}
			}
			else
			{
				// write 0 as exception table length
				index = PutInt16(0, codeAttribute, index);
			}
			int attributeCount = 0;
			if (itsLineNumberTable != null)
			{
				attributeCount++;
			}
			if (itsVarDescriptors != null)
			{
				attributeCount++;
			}
			if (stackMapTableLength > 0)
			{
				attributeCount++;
			}
			index = PutInt16(attributeCount, codeAttribute, index);
			if (itsLineNumberTable != null)
			{
				int lineNumberTableAttrIndex = itsConstantPool.AddUtf8("LineNumberTable");
				index = PutInt16(lineNumberTableAttrIndex, codeAttribute, index);
				int tableAttrLength = 2 + (itsLineNumberTableTop * 4);
				index = PutInt32(tableAttrLength, codeAttribute, index);
				index = PutInt16(itsLineNumberTableTop, codeAttribute, index);
				for (int i = 0; i < itsLineNumberTableTop; i++)
				{
					index = PutInt32(itsLineNumberTable[i], codeAttribute, index);
				}
			}
			if (itsVarDescriptors != null)
			{
				int variableTableAttrIndex = itsConstantPool.AddUtf8("LocalVariableTable");
				index = PutInt16(variableTableAttrIndex, codeAttribute, index);
				int varCount = itsVarDescriptors.Size();
				int tableAttrLength = 2 + (varCount * 10);
				index = PutInt32(tableAttrLength, codeAttribute, index);
				index = PutInt16(varCount, codeAttribute, index);
				for (int i = 0; i < varCount; i++)
				{
					int[] chunk = (int[])itsVarDescriptors.Get(i);
					int nameIndex = chunk[0];
					int descriptorIndex = chunk[1];
					int startPC = chunk[2];
					int register = chunk[3];
					int length = itsCodeBufferTop - startPC;
					index = PutInt16(startPC, codeAttribute, index);
					index = PutInt16(length, codeAttribute, index);
					index = PutInt16(nameIndex, codeAttribute, index);
					index = PutInt16(descriptorIndex, codeAttribute, index);
					index = PutInt16(register, codeAttribute, index);
				}
			}
			if (stackMapTableLength > 0)
			{
				int stackMapTableAttrIndex = itsConstantPool.AddUtf8("StackMapTable");
				int start = index;
				index = PutInt16(stackMapTableAttrIndex, codeAttribute, index);
				index = stackMap.Write(codeAttribute, index);
			}
			itsCurrentMethod.SetCodeAttribute(codeAttribute);
			itsExceptionTable = null;
			itsExceptionTableTop = 0;
			itsLineNumberTableTop = 0;
			itsCodeBufferTop = 0;
			itsCurrentMethod = null;
			itsMaxStack = 0;
			itsStackTop = 0;
			itsLabelTableTop = 0;
			itsFixupTableTop = 0;
			itsVarDescriptors = null;
			itsSuperBlockStarts = null;
			itsSuperBlockStartsTop = 0;
			itsJumpFroms = null;
		}

Usage Example

コード例 #1
0
ファイル: Codegen.cs プロジェクト: hazzik/Rhino.Net
		private void EmitRegExpInit(ClassFileWriter cfw)
		{
			// precompile all regexp literals
			int totalRegCount = 0;
			for (int i = 0; i != scriptOrFnNodes.Length; ++i)
			{
				totalRegCount += scriptOrFnNodes[i].GetRegexpCount();
			}
			if (totalRegCount == 0)
			{
				return;
			}
			cfw.StartMethod(REGEXP_INIT_METHOD_NAME, REGEXP_INIT_METHOD_SIGNATURE, (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE));
			cfw.AddField("_reInitDone", "Z", (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE | ClassFileWriter.ACC_VOLATILE));
			cfw.Add(ByteCode.GETSTATIC, mainClassName, "_reInitDone", "Z");
			int doInit = cfw.AcquireLabel();
			cfw.Add(ByteCode.IFEQ, doInit);
			cfw.Add(ByteCode.RETURN);
			cfw.MarkLabel(doInit);
			// get regexp proxy and store it in local slot 1
			cfw.AddALoad(0);
			// context
			cfw.AddInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/ScriptRuntime", "checkRegExpProxy", "(Lorg/mozilla/javascript/Context;" + ")Lorg/mozilla/javascript/RegExpProxy;");
			cfw.AddAStore(1);
			// proxy
			// We could apply double-checked locking here but concurrency
			// shouldn't be a problem in practice
			for (int i_1 = 0; i_1 != scriptOrFnNodes.Length; ++i_1)
			{
				ScriptNode n = scriptOrFnNodes[i_1];
				int regCount = n.GetRegexpCount();
				for (int j = 0; j != regCount; ++j)
				{
					string reFieldName = GetCompiledRegexpName(n, j);
					string reFieldType = "Ljava/lang/Object;";
					string reString = n.GetRegexpString(j);
					string reFlags = n.GetRegexpFlags(j);
					cfw.AddField(reFieldName, reFieldType, (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE));
					cfw.AddALoad(1);
					// proxy
					cfw.AddALoad(0);
					// context
					cfw.AddPush(reString);
					if (reFlags == null)
					{
						cfw.Add(ByteCode.ACONST_NULL);
					}
					else
					{
						cfw.AddPush(reFlags);
					}
					cfw.AddInvoke(ByteCode.INVOKEINTERFACE, "org/mozilla/javascript/RegExpProxy", "compileRegExp", "(Lorg/mozilla/javascript/Context;" + "Ljava/lang/String;Ljava/lang/String;" + ")Ljava/lang/Object;");
					cfw.Add(ByteCode.PUTSTATIC, mainClassName, reFieldName, reFieldType);
				}
			}
			cfw.AddPush(1);
			cfw.Add(ByteCode.PUTSTATIC, mainClassName, "_reInitDone", "Z");
			cfw.Add(ByteCode.RETURN);
			cfw.StopMethod((short)2);
		}
All Usage Examples Of Org.Mozilla.Classfile.ClassFileWriter::StopMethod