GetEnd() приватный Метод

private GetEnd ( ) : int
Результат int
Пример #1
0
			/// <summary>Simulate the local variable and op stack for a super block.</summary>
			/// <remarks>Simulate the local variable and op stack for a super block.</remarks>
			private void ExecuteBlock(SuperBlock work)
			{
				int bc = 0;
				int next = 0;
				for (int bci = work.GetStart(); bci < work.GetEnd(); bci += next)
				{
					bc = this._enclosing.itsCodeBuffer[bci] & unchecked((int)(0xFF));
					next = this.Execute(bci);
					// If we have a branch to some super block, we need to merge
					// the current state of the local table and op stack with what's
					// currently stored as the initial state of the super block. If
					// something actually changed, we need to add it to the work
					// list.
					if (this.IsBranch(bc))
					{
						SuperBlock targetSB = this.GetBranchTarget(bci);
						this.FlowInto(targetSB);
					}
					else
					{
						if (bc == ByteCode.TABLESWITCH)
						{
							int switchStart = bci + 1 + (3 & ~bci);
							// 3 - bci % 4
							int defaultOffset = this.GetOperand(switchStart, 4);
							SuperBlock targetSB = this.GetSuperBlockFromOffset(bci + defaultOffset);
							this.FlowInto(targetSB);
							int low = this.GetOperand(switchStart + 4, 4);
							int high = this.GetOperand(switchStart + 8, 4);
							int numCases = high - low + 1;
							int caseBase = switchStart + 12;
							for (int i = 0; i < numCases; i++)
							{
								int label = bci + this.GetOperand(caseBase + 4 * i, 4);
								targetSB = this.GetSuperBlockFromOffset(label);
								this.FlowInto(targetSB);
							}
						}
					}
					for (int i_1 = 0; i_1 < this._enclosing.itsExceptionTableTop; i_1++)
					{
						ExceptionTableEntry ete = this._enclosing.itsExceptionTable[i_1];
						short startPC = (short)this._enclosing.GetLabelPC(ete.itsStartLabel);
						short endPC = (short)this._enclosing.GetLabelPC(ete.itsEndLabel);
						if (bci < startPC || bci >= endPC)
						{
							continue;
						}
						short handlerPC = (short)this._enclosing.GetLabelPC(ete.itsHandlerLabel);
						SuperBlock sb = this.GetSuperBlockFromOffset(handlerPC);
						int exceptionType;
						if (ete.itsCatchType == 0)
						{
							exceptionType = TypeInfo.OBJECT(this._enclosing.itsConstantPool.AddClass("java/lang/Throwable"));
						}
						else
						{
							exceptionType = TypeInfo.OBJECT(ete.itsCatchType);
						}
						sb.Merge(this.locals, this.localsTop, new int[] { exceptionType }, 1, this._enclosing.itsConstantPool);
						this.AddToWorkList(sb);
					}
				}
				// Check the last instruction to see if it is a true end of a
				// super block (ie., if the instruction is a return). If it
				// isn't, we need to continue processing the next chunk.
				if (!this.IsSuperBlockEnd(bc))
				{
					int nextIndex = work.GetIndex() + 1;
					if (nextIndex < this.superBlocks.Length)
					{
						this.FlowInto(this.superBlocks[nextIndex]);
					}
				}
			}
Пример #2
0
			/// <summary>Replace the contents of a super block with no-ops.</summary>
			/// <remarks>
			/// Replace the contents of a super block with no-ops.
			/// The above description is not strictly true; the last instruction is
			/// an athrow instruction. This technique is borrowed from ASM's
			/// developer guide: http://asm.ow2.org/doc/developer-guide.html#deadcode
			/// The proposed algorithm fills a block with nop, ending it with an
			/// athrow. The stack map generated would be empty locals with an
			/// exception on the stack. In theory, it shouldn't matter what the
			/// locals are, as long as the stack has an exception for the athrow bit.
			/// However, it turns out that if the code being modified falls into an
			/// exception handler, it causes problems. Therefore, if it does, then
			/// we steal the locals from the exception block.
			/// If the block itself is an exception handler, we remove it from the
			/// exception table to simplify block dependencies.
			/// </remarks>
			private void KillSuperBlock(SuperBlock sb)
			{
				int[] locals = new int[0];
				int[] stack = new int[] { TypeInfo.OBJECT("java/lang/Throwable", this._enclosing.itsConstantPool) };
				// If the super block is handled by any exception handler, use its
				// locals as the killed block's locals. Ignore uninitialized
				// handlers, because they will also be killed and removed from the
				// exception table.
				for (int i = 0; i < this._enclosing.itsExceptionTableTop; i++)
				{
					ExceptionTableEntry ete = this._enclosing.itsExceptionTable[i];
					int eteStart = this._enclosing.GetLabelPC(ete.itsStartLabel);
					int eteEnd = this._enclosing.GetLabelPC(ete.itsEndLabel);
					int handlerPC = this._enclosing.GetLabelPC(ete.itsHandlerLabel);
					SuperBlock handlerSB = this.GetSuperBlockFromOffset(handlerPC);
					if ((sb.GetStart() > eteStart && sb.GetStart() < eteEnd) || (eteStart > sb.GetStart() && eteStart < sb.GetEnd()) && handlerSB.IsInitialized())
					{
						locals = handlerSB.GetLocals();
						break;
					}
				}
				// Remove any exception table entry whose handler is the killed
				// block. This removes block dependencies to make stack maps for
				// dead blocks easier to create.
				for (int i_1 = 0; i_1 < this._enclosing.itsExceptionTableTop; i_1++)
				{
					ExceptionTableEntry ete = this._enclosing.itsExceptionTable[i_1];
					int eteStart = this._enclosing.GetLabelPC(ete.itsStartLabel);
					if (eteStart == sb.GetStart())
					{
						for (int j = i_1 + 1; j < this._enclosing.itsExceptionTableTop; j++)
						{
							this._enclosing.itsExceptionTable[j - 1] = this._enclosing.itsExceptionTable[j];
						}
						this._enclosing.itsExceptionTableTop--;
						i_1--;
					}
				}
				sb.Merge(locals, locals.Length, stack, stack.Length, this._enclosing.itsConstantPool);
				int end = sb.GetEnd() - 1;
				this._enclosing.itsCodeBuffer[end] = unchecked((byte)ByteCode.ATHROW);
				for (int bci = sb.GetStart(); bci < end; bci++)
				{
					this._enclosing.itsCodeBuffer[bci] = unchecked((byte)ByteCode.NOP);
				}
			}