Ejemplo n.º 1
0
        public void VisitCast(CastClass cast)
        {
            if (m_needsCheck && !m_foundTypeCheck)
            {
                // If the method has a isinst check we'll assume that it isn't
                // completely silly.
                if (cast.Untyped.OpCode.Code == Code.Isinst)
                {
                    if (cast.ToType.FullName == m_info.Method.DeclaringType.FullName)
                    {
                        if (m_tracker.GetStack(cast.Index, 0) == -33)
                        {
                            m_foundTypeCheck = true;
                            Log.DebugLine(this, "found isinst call at {0:X2}", cast.Untyped.Offset);
                        }
                    }
                }

                // If we find a cast to our class type, and it's using our argument,
                // then we have a problem.
                else if (m_offset < 0)
                {
                    if (cast.ToType.FullName == m_info.Method.DeclaringType.FullName)
                    {
                        if (m_tracker.GetStack(cast.Index, 0) == -33)
                        {
                            m_offset = cast.Untyped.Offset;
                            Log.DebugLine(this, "found cast at {0:X2}", m_offset);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
            protected internal override void VisitCastClass(CastClass node, object data)
            {
                StackTypes stack = data as StackTypes;

                Verifier.ProcessCastClass(stack, new TypeEx(node.Type, true));
                AddTask(node.Next, stack);
            }
Ejemplo n.º 3
0
 public void VisitCast(CastClass cast)
 {
     if (m_needsCheck && !m_foundEarlyReturn && m_offset < 0)
     {
         if (cast.Untyped.OpCode.Code == Code.Isinst)
         {
             if (m_info.Instructions[cast.Index + 1].Untyped.OpCode.Code == Code.Brfalse ||
                 m_info.Instructions[cast.Index + 1].Untyped.OpCode.Code == Code.Brfalse_S)
             {
                 m_foundEarlyReturn = true;
                 Log.DebugLine(this, "isinst check {0:X2}", cast.Untyped.Offset);
             }
         }
     }
 }
        private int EmulateInstruction(Instruction instruction, int i)
        {
            switch (instruction.OpCode.Code)
            {
            case Code.UNKNOWN1:
                throw new NotSupportedException();

            case Code.UNKNOWN2:
                throw new NotSupportedException();

            case Code.Add:
                Add.Emulate(ValueStack);
                break;

            case Code.Add_Ovf:
            case Code.Add_Ovf_Un:
                Add.Emulate_Ovf(ValueStack);
                break;

            case Code.And:
                And.Emulate(ValueStack);
                break;

            case Code.Arglist:
                throw new NotSupportedException();

            case Code.Beq:
            case Code.Beq_S:
                var beqResult = Beq.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(beqResult == -1 ? i : beqResult);

            case Code.Bge:
            case Code.Bge_S:
            case Code.Bge_Un:
            case Code.Bge_Un_S:
                var bgeResult = Bge.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(bgeResult == -1 ? i : bgeResult);

            case Code.Bgt:
            case Code.Bgt_S:
            case Code.Bgt_Un:
            case Code.Bgt_Un_S:
                var bgtResult = Bgt.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(bgtResult == -1 ? i : bgtResult);

            case Code.Ble:
            case Code.Ble_S:
            case Code.Ble_Un:
            case Code.Ble_Un_S:
                var bleResult = Ble.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(bleResult == -1 ? i : bleResult);

            case Code.Blt:
            case Code.Blt_S:
            case Code.Blt_Un:
            case Code.Blt_Un_S:
                var bltResult = Blt.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(bltResult == -1 ? i : bltResult);

            case Code.Bne_Un:
            case Code.Bne_Un_S:
                var bneResult = Bne.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(bneResult == -1 ? i : bneResult);

            case Code.Box:
                Box.Emulate_Box(ValueStack, instruction);
                break;

            case Code.Br:
            case Code.Br_S:
                return(Br.Emulate(ValueStack, instruction, _instructionsToEmulate));

            case Code.Break:
                break;

            case Code.Brfalse:
            case Code.Brfalse_S:
                var bFalseResult = BrFalse.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(bFalseResult == -1 ? i : bFalseResult);

            case Code.Brtrue:
            case Code.Brtrue_S:
                var bTrueResult = BrTrue.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(bTrueResult == -1 ? i : bTrueResult);

            case Code.Call:
                Call.Emulate(ValueStack, instruction, _method);
                break;

            case Code.Calli:
                throw new NotSupportedException();

            case Code.Callvirt:
                CallVirt.Emulate(ValueStack, instruction, _method);
                break;

            case Code.Castclass:
                CastClass.Emulate(ValueStack, instruction);
                break;

            case Code.Ceq:
                Ceq.Emulate(ValueStack);
                break;

            case Code.Cgt:
            case Code.Cgt_Un:
                Ceq.Emulate(ValueStack);
                break;

            case Code.Ckfinite:
                throw new NotSupportedException();

            case Code.Clt:
            case Code.Clt_Un:
                Clt.Emulate(ValueStack);
                break;

            case Code.Constrained:
                throw new NotSupportedException();

            case Code.Conv_I:
                ConvI.Emulation(ValueStack);
                break;

            case Code.Conv_I1:
                throw new NotSupportedException();

            case Code.Conv_I2:
                ConvI2.Emulation(ValueStack);
                break;

            case Code.Conv_I4:
                ConvI4.Emulation(ValueStack);
                break;

            case Code.Conv_I8:
                ConvI8.Emulation(ValueStack);
                break;

            case Code.Conv_Ovf_I:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I1:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I1_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I2:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I2_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I4:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I4_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I8:
                throw new NotSupportedException();

            case Code.Conv_Ovf_I8_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U1:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U1_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U2:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U2_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U4:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U4_Un:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U8:
                throw new NotSupportedException();

            case Code.Conv_Ovf_U8_Un:
                throw new NotSupportedException();

            case Code.Conv_R_Un:
                throw new NotSupportedException();

            case Code.Conv_R4:
                throw new NotSupportedException();

            case Code.Conv_R8:
                throw new NotSupportedException();

            case Code.Conv_U:
                ConvI.UEmulation(ValueStack);
                break;

            case Code.Conv_U1:
                ConvI1.UEmulation(ValueStack);
                break;

            case Code.Conv_U2:
                ConvI2.UEmulation(ValueStack);
                break;

            case Code.Conv_U4:
                ConvI4.UEmulation(ValueStack);
                break;

            case Code.Conv_U8:
                ConvI8.UEmulation(ValueStack);
                break;

            case Code.Cpblk:
                throw new NotSupportedException();

            case Code.Cpobj:
                throw new NotSupportedException();

            case Code.Div:
                Div.Emulate(ValueStack);
                break;

            case Code.Div_Un:
                Div.Emulate_Un(ValueStack);
                break;

            case Code.Dup:
                ValueStack.CallStack.Push(ValueStack.CallStack.Peek());
                break;

            case Code.Endfilter:
                throw new NotSupportedException();

            case Code.Endfinally:
                throw new NotSupportedException();

            case Code.Initblk:
                throw new NotSupportedException();

            case Code.Initobj:
                ValueStack.CallStack.Pop();
                break;

            case Code.Isinst:
                IsInst.Emulate_Box(ValueStack, instruction);
                break;

            case Code.Jmp:
                throw new NotSupportedException();

            case Code.Ldarg:
            case Code.Ldarg_0:
            case Code.Ldarg_1:
            case Code.Ldarg_2:
            case Code.Ldarg_3:
            case Code.Ldarg_S:
                Ldarg.Emulate(ValueStack, instruction, _method);
                break;

            case Code.Ldarga:
                throw new NotSupportedException();

            case Code.Ldarga_S:
                throw new NotSupportedException();

            case Code.Ldc_I4:
            case Code.Ldc_I4_0:
            case Code.Ldc_I4_1:
            case Code.Ldc_I4_2:
            case Code.Ldc_I4_3:
            case Code.Ldc_I4_4:
            case Code.Ldc_I4_5:
            case Code.Ldc_I4_6:
            case Code.Ldc_I4_7:
            case Code.Ldc_I4_8:
                ValueStack.CallStack.Push(instruction.GetLdcI4Value());
                break;

            case Code.Ldc_I4_M1:
                ValueStack.CallStack.Push(-1);
                break;

            case Code.Ldc_I4_S:
                ValueStack.CallStack.Push((sbyte)instruction.GetLdcI4Value());
                break;

            case Code.Ldc_I8:
                ValueStack.CallStack.Push((long)instruction.Operand);
                break;

            case Code.Ldc_R4:
                ValueStack.CallStack.Push((float)instruction.GetOperand());
                break;

            case Code.Ldc_R8:
                ValueStack.CallStack.Push((double)instruction.GetOperand());
                break;

            case Code.Ldelem:
                throw new NotSupportedException();

            case Code.Ldelem_I:
                throw new NotSupportedException();

            case Code.Ldelem_I1:
                throw new NotSupportedException();

            case Code.Ldelem_I2:
                throw new NotSupportedException();

            case Code.Ldelem_I4:
                throw new NotSupportedException();

            case Code.Ldelem_I8:
                throw new NotSupportedException();

            case Code.Ldelem_R4:
                throw new NotSupportedException();

            case Code.Ldelem_R8:
                throw new NotSupportedException();

            case Code.Ldelem_Ref:
                LdelemRef.Emulate(ValueStack);
                break;

            case Code.Ldelem_U1:
                LdelemI1.UEmulate(ValueStack);
                break;

            case Code.Ldelem_U2:
                throw new NotSupportedException();

            case Code.Ldelem_U4:
                LdelemI4.UEmulate(ValueStack);
                break;

            case Code.Ldelema:
                Ldelema.Emulate(ValueStack);
                break;

            case Code.Ldfld:
                throw new NotSupportedException();

            case Code.Ldflda:
                throw new NotSupportedException();

            case Code.Ldftn:
                throw new NotSupportedException();

            case Code.Ldind_I:
                throw new NotSupportedException();

            case Code.Ldind_I1:
                throw new NotSupportedException();

            case Code.Ldind_I2:
                throw new NotSupportedException();

            case Code.Ldind_I4:
                LdindI4.Emulate(ValueStack);
                break;

            case Code.Ldind_I8:
                throw new NotSupportedException();

            case Code.Ldind_R4:
                throw new NotSupportedException();

            case Code.Ldind_R8:
                throw new NotSupportedException();

            case Code.Ldind_Ref:
                throw new NotSupportedException();

            case Code.Ldind_U1:
                LdindI1.UEmulate(ValueStack);
                break;

            case Code.Ldind_U2:
                LdindI2.UEmulate(ValueStack);
                break;

            case Code.Ldind_U4:
                LdindI4.UEmulate(ValueStack);
                break;

            case Code.Ldlen:
                Ldlen.Emulate(ValueStack);
                break;

            case Code.Ldloc:
            case Code.Ldloc_0:
            case Code.Ldloc_1:
            case Code.Ldloc_2:
            case Code.Ldloc_3:
            case Code.Ldloc_S:

                Ldloc.Emulate(ValueStack, instruction, _method);
                break;

            case Code.Ldloca:
            case Code.Ldloca_S:
                Ldloc.EmulateLdloca(ValueStack, instruction, _method);
                break;

            case Code.Ldnull:
                ValueStack.CallStack.Push(null);
                break;

            case Code.Ldobj:
                Ldobj.Emulate(ValueStack, instruction);
                break;

            case Code.Ldsfld:
                Ldsfld.Emulate(ValueStack, instruction);
                break;

            case Code.Ldsflda:
                throw new NotSupportedException();

            case Code.Ldstr:
                ValueStack.CallStack.Push(instruction.Operand.ToString());
                break;

            case Code.Ldtoken:
                Ldtoken.Emulate(ValueStack, instruction);
                break;

            case Code.Ldvirtftn:
                throw new NotSupportedException();

            case Code.Leave:

            case Code.Leave_S:
                return(LEave.Emulate(ValueStack, instruction, _instructionsToEmulate));

            case Code.Localloc:
                Localloc.Emulate(ValueStack);
                break;

            case Code.Mkrefany:
                throw new NotSupportedException();

            case Code.Mul:
            case Code.Mul_Ovf:
            case Code.Mul_Ovf_Un:
                Mul.Emulate(ValueStack);
                break;

            case Code.Neg:
                ValueStack.CallStack.Push(-ValueStack.CallStack.Pop());
                break;

            case Code.Newarr:
                NewArr.Emulate(ValueStack, instruction);
                break;

            case Code.Newobj:
                throw new NotSupportedException();

            case Code.Nop:
                break;

            case Code.Not:
                Not.Emulate(ValueStack);
                break;

            case Code.Or:
                Or.Emulate(ValueStack);
                break;

            case Code.Pop:
                ValueStack.CallStack.Pop();
                break;

            case Code.Prefix1:
                throw new NotSupportedException();

            case Code.Prefix2:
                throw new NotSupportedException();

            case Code.Prefix3:
                throw new NotSupportedException();

            case Code.Prefix4:
                throw new NotSupportedException();

            case Code.Prefix5:
                throw new NotSupportedException();

            case Code.Prefix6:
                throw new NotSupportedException();

            case Code.Prefix7:
                throw new NotSupportedException();

            case Code.Prefixref:
                throw new NotSupportedException();

            case Code.Readonly:
                throw new NotSupportedException();

            case Code.Refanytype:
                throw new NotSupportedException();

            case Code.Refanyval:
                throw new NotSupportedException();

            case Code.Rem:
                Rem.Emulate(ValueStack);
                break;

            case Code.Rem_Un:
                Rem.Emulate_Un(ValueStack);
                break;

            case Code.Ret:
                break;

            case Code.Rethrow:
                throw new NotSupportedException();

            case Code.Shl:
                Shl.Emulate(ValueStack);
                break;

            case Code.Shr:
                Shr.Emulate(ValueStack);
                break;

            case Code.Shr_Un:
                Shr.Emulate_Un(ValueStack);
                break;

            case Code.Sizeof:
                throw new NotSupportedException();

            case Code.Starg:
            case Code.Starg_S:
                Starg.Emulate(ValueStack, instruction, _method);
                break;

            case Code.Stelem:
                throw new NotSupportedException();

            case Code.Stelem_I:

                throw new NotSupportedException();

            case Code.Stelem_I1:
                StelemI1.Emulate(ValueStack);
                break;

            case Code.Stelem_I2:
                break;

            case Code.Stelem_I4:
                Stelem_I4.Emulate(ValueStack);
                break;

            case Code.Stelem_I8:
                throw new NotSupportedException();

            case Code.Stelem_R4:
                throw new NotSupportedException();

            case Code.Stelem_R8:
                throw new NotSupportedException();

            case Code.Stelem_Ref:
                throw new NotSupportedException();

            case Code.Stfld:
                throw new NotSupportedException();

            case Code.Stind_I:
                throw new NotSupportedException();

            case Code.Stind_I1:
                StindI1.Emulate(ValueStack);
                break;

            case Code.Stind_I2:
                throw new NotSupportedException();

            case Code.Stind_I4:
                StindI4.Emulate(ValueStack);
                break;

            case Code.Stind_I8:
                throw new NotSupportedException();

            case Code.Stind_R4:
                throw new NotSupportedException();

            case Code.Stind_R8:
                throw new NotSupportedException();

            case Code.Stind_Ref:
                throw new NotSupportedException();

            case Code.Stloc:
            case Code.Stloc_0:
            case Code.Stloc_1:
            case Code.Stloc_2:
            case Code.Stloc_3:
            case Code.Stloc_S:
                Stloc.Emulate(ValueStack, instruction, _method);
                break;

            case Code.Stobj:
                Stobj.Emulate(ValueStack, instruction);
                break;

            case Code.Stsfld:
                Stsfld.Emulate(ValueStack, instruction);
                break;

            case Code.Sub:
                Sub.Emulate(ValueStack);
                break;

            case Code.Sub_Ovf:
            case Code.Sub_Ovf_Un:
                Sub.Emulate_Ovf(ValueStack);
                break;

            case Code.Switch:
                var switchResult = Switch.Emulate(ValueStack, instruction, _instructionsToEmulate);
                return(switchResult == -1 ? i : switchResult);

            case Code.Tailcall:
                throw new NotSupportedException();

            case Code.Throw:
                throw new NotSupportedException();

            case Code.Unaligned:
                throw new NotSupportedException();

            case Code.Unbox:
                throw new NotSupportedException();

            case Code.Unbox_Any:
                //     Box.Emulate_UnBox_Any(ValueStack,instruction);
                break;

            case Code.Volatile:
                throw new NotSupportedException();

            case Code.Xor:
                Xor.Emulate(ValueStack);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(i);
        }
Ejemplo n.º 5
0
		void OnApplicationConnectionResult(CastClass.IApplicationConnectionResult result)
		{
			Console.WriteLine("ApplicationConnectionResultCallback - {0}", result.Status.StatusCode);
			if (result.Status.IsSuccess)
			{
				Console.WriteLine("application name: {0}, status: {1}, sessionId: {2}, wasLaunched: {3}",
					result.ApplicationMetadata.Name,
					result.ApplicationStatus,
					result.SessionId,
					result.WasLaunched);
				
				_applicationStarted = true;

				// Create the custom message
				// channel
				_channel = new MyChannel(_apiClient) { MessageReceived = OnMessageReceived };
					
				try {
					CastClass.CastApi.SetMessageReceivedCallbacks(
						_apiClient,
						MyChannel.CastNamespace,
						_channel);
				}
				catch (Exception e)
				{
					Console.WriteLine ("Exception while creating channel - {0}", e);
				}

				UpdateEnabledStates();
				_textName.RequestFocus ();
			}
			else
			{
				Console.WriteLine ("application could not launch");
				Teardown(true);
			}
		}
Ejemplo n.º 6
0
 protected override void VisitCastClass(CastClass node, object data)
 {
     state.Stack.Perform_CastClass(node.Type, node.ThrowException, out exc);
     nextNode = node.Next;
 }
Ejemplo n.º 7
0
        static ILInstruction GetRef(ILVariable v, string Name)
        {
            var ty = TypeInference.GetVariableType(v);

            if (ty == null)
            {
                // happens on ldNull;
                return(null);
            }
            var isPointer = false;

            if (ty.Kind == TypeKind.Pointer)
            {
                ty        = ((ICSharpCode.Decompiler.TypeSystem.PointerType)ty).ElementType;
                isPointer = true;
            }

            IType         etype;
            ILInstruction loadInst;

            if (ty.IsReferenceType.Value)
            {
                etype = GetETypeBase(ty);
                if (isPointer)
                {
                    loadInst = new LdObj(new LdLoc(v), ty);
                }
                else
                {
                    loadInst = new LdLoc(v);
                }



                if (etype == null && !ty.FullName.StartsWith("System."))
                {
                    Debug.Assert(false, "Type is broken??");
                }

                // only do ref counting for our own types
                if (etype == null)
                {
                    return(null);
                }

                // avoid compiler warnings
                loadInst = new CastClass(loadInst, etype);
            }
            else                 // value type
            {
                etype = ty;

                if (v.StackType == StackType.O)
                {
                    loadInst = new Conv(new LdLoca(v), PrimitiveType.I, false, Sign.None);
                }
                else
                {
                    loadInst = new Conv(new LdLoc(v), PrimitiveType.I, false, Sign.None);
                }
            }


            // make sure we don't end up with crazy unintended names
            //v.HasGeneratedName = false;

            //var test = (DefaultResolvedTypeDefinition)ty;

            var m    = etype.GetMethods().First(x => x.Name.EndsWith(Name + "Ref"));
            var inst = new Call(m);

            inst.Arguments.Add(loadInst);

            return(inst);
        }
Ejemplo n.º 8
0
 public void VisitCast(CastClass cast)
 {
     DoAdd(cast.ToType);
 }
Ejemplo n.º 9
0
 protected internal virtual void VisitCastClass(CastClass node, object data)
 {
     throw new NodeNotSupportedException(node);
 }
Ejemplo n.º 10
0
        public static MethodBodyBlock Convert(MethodEx method)
        {
            if (!method.IsVerified)
            {
                throw new ConvertionException();
            }
            MethodInfoExtention _method_  = new MethodInfoExtention(method.Method);
            MethodBodyBlock     mainBlock = new MethodBodyBlock(_method_.GetReturnType().type);

            mainBlock.Options["StackTypes"] = new StackTypes();
            Block currentBlock = mainBlock;

            Node[] heads = new Node[method.Count];
            Node[] tails = new Node[method.Count];
            Node   head = null;
            Node   tail = null;
            Node   firstBlock = null;
            Node   lastBlock = null;
            int    iNum, iNumNext;

            Variable[]    locals        = new Variable[method.Locals.Count];
            Variable[]    args          = new Variable[_method_.ArgCount];
            VariablesList methodVarList = mainBlock.Variables;

            for (int i = 0; i < args.Length; i++)
            {
                args[i]      = methodVarList.CreateVar(_method_.GetArgType(i).type, VariableKind.Parameter);
                args[i].Name = "Arg" + i;
//				methodVarList.Add(args[i]);
            }
            for (int i = 0; i < locals.Length; i++)
            {
                locals[i]      = methodVarList.CreateVar(method.Locals[i], VariableKind.Local);
                locals[i].Name = "Loc" + i;
//				methodVarList.Add(locals[i]);
            }

            BlockType nextBlockType;
            int       nextBlockStart = -1;
            int       nextBlockEnd   = 1 << 30;
            int       nextBlockIndex;
            Type      nextCatchBlockType;
            Hashtable tryBlocks    = new Hashtable();
            Hashtable filterBlocks = new Hashtable();
            Stack     blockEnds    = new Stack();

            blockEnds.Push(method.Count);
            FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex);

            //Nodes and blocks creation, blocks linkage
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                while (iNum == (int)blockEnds.Peek())
                {
                    currentBlock = currentBlock.Parent;
                    blockEnds.Pop();
                }

                firstBlock = null;
                lastBlock  = null;
                Node thisBlock = null;
                while (iNum == nextBlockStart)
                {
                    Block currentBlockOld = currentBlock;

                    switch (nextBlockType)
                    {
                    case BlockType.Try:
                        currentBlock = new ProtectedBlock();
                        break;

                    case BlockType.Catch:
                        currentBlock = new CatchBlock(nextCatchBlockType);
                        break;

                    case BlockType.Finally:
                        currentBlock = new FinallyBlock(false);
                        break;

                    case BlockType.Filter:
                        currentBlock = new FilterBlock();
                        break;

                    case BlockType.FilteredCatch:
                        currentBlock = new UserFilteredBlock();
                        break;
                    }

                    currentBlock.setParent(currentBlockOld);

                    blockEnds.Push(nextBlockEnd);
                    if (thisBlock == null)
                    {
                        thisBlock = firstBlock = currentBlock;
                    }
                    else
                    {
                        thisBlock.Next = currentBlock;
                        thisBlock      = currentBlock;
                    }
                    switch (nextBlockType)
                    {
                    case BlockType.Try:
                        tryBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock);
                        break;

                    case BlockType.Filter:
                        filterBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock);
                        break;

                    case BlockType.Finally:
                    case BlockType.Catch:
                    {
                        Segment        tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex);
                        ProtectedBlock tryBlock    = tryBlocks[tryBlockKey] as ProtectedBlock;
                        tryBlock.AddHandler(thisBlock as EHBlock);
                    }       break;

                    case BlockType.FilteredCatch:
                    {
                        Segment        tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex);
                        ProtectedBlock tryBlock    = tryBlocks[tryBlockKey] as ProtectedBlock;
                        tryBlock.AddHandler(thisBlock as EHBlock);

                        Segment     filterKey   = FindFilterBlock(method.EHClauses, nextBlockIndex);
                        FilterBlock filterBlock = filterBlocks[filterKey] as FilterBlock;
                        (thisBlock as UserFilteredBlock).Filter = filterBlock;
                    }       break;
                    }
                    FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex);
                }
                lastBlock = thisBlock;

                Instruction i = method[iNum];
                switch (i.Code)
                {
                case InstructionCode.NEG:
                case InstructionCode.NOT:
                {
                    head = tail = new UnaryOp(UnaryOpFromCode(i.Code));
                    /*!*/ head.setParent(currentBlock);
                } break;

                case InstructionCode.ADD:
                case InstructionCode.AND:
                case InstructionCode.CEQ:
                case InstructionCode.CGT:
                case InstructionCode.CLT:
                case InstructionCode.DIV:
                case InstructionCode.MUL:
                case InstructionCode.OR:
                case InstructionCode.REM:
                case InstructionCode.SHL:
                case InstructionCode.SHR:
                case InstructionCode.SUB:
                case InstructionCode.XOR:
                {
                    head = tail = new BinaryOp(BinaryOpFromCode(i.Code), i.OverflowFlag, i.UnsignedFlag);
                    /*!*/ head.setParent(currentBlock);
                } break;

                case InstructionCode.LDC:
                    head = tail = new LoadConst(i.Param);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDARG:
                    head = tail = new LoadVar(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLOC:
                    head = tail = new LoadVar(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDARGA:
                    head = tail = new LoadVarAddr(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLOCA:
                    head = tail = new LoadVarAddr(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDIND:
                    head = tail = new LoadIndirect(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDFLD:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new RemoveStackTop();
                        /*!*/ head.setParent(currentBlock);
                        //remove the object instance when accessing the static field with LDFLD
                        tail = new LoadField(field);
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new LoadField(field);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.LDFLDA:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new RemoveStackTop();
                        /*!*/ head.setParent(currentBlock);
                        tail = new LoadFieldAddr(field);
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new LoadFieldAddr(field);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.LDSFLD:
                    head = tail = new LoadField(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDSFLDA:
                    head = tail = new LoadFieldAddr(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDELEM:
                    head = tail = new LoadElement(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDELEMA:
                    head = tail = new LoadElementAddr(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDOBJ:
                    head = tail = new LoadIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.SIZEOF:
                    head = tail = new LoadSizeOfValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDLEN:
                    head = tail = new LoadLength();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDTOKEN:
                    if (i.Param is Type)
                    {
                        head = tail = new LoadConst((i.Param as Type).TypeHandle);
                    }
                    else if (i.Param is MethodBase)
                    {
                        head = tail = new LoadConst((i.Param as MethodBase).MethodHandle);
                    }
                    else if (i.Param is FieldInfo)
                    {
                        head = tail = new LoadConst((i.Param as FieldInfo).FieldHandle);
                    }
                    else
                    {
                        throw new ConvertionException();
                    }
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDNULL:
                    head = tail = new LoadConst(null);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.LDSTR:
                    head = tail = new LoadConst(i.Param);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STARG:
                    head = tail = new StoreVar(args[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STLOC:
                    head = tail = new StoreVar(locals[(int)(i.Param)]);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STIND:
                    head = tail = new StoreIndirect(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STFLD:
                {
                    FieldInfo field = i.Param as FieldInfo;
                    if (field.IsStatic)
                    {
                        head = new StoreField(field);
                        /*!*/ head.setParent(currentBlock);
                        tail = new RemoveStackTop();
                        /*!*/ tail.setParent(currentBlock);
                        head.Next = tail;
                    }
                    else
                    {
                        head = tail = new StoreField(i.Param as FieldInfo);
                        /*!*/ head.setParent(currentBlock);
                    }
                }       break;

                case InstructionCode.STSFLD:
                    head = tail = new StoreField(i.Param as FieldInfo);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STELEM:
                    head = tail = new StoreElement(i.TypeBySuffixOrParam());
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.STOBJ:
                    head = tail = new StoreIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CPOBJ:
                    head = new LoadIndirect(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    tail = new StoreIndirect(i.Param as Type);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.DUP:
                    head = tail = new DuplicateStackTop();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CALL:
                    head = tail = new CallMethod(i.Param as MethodBase, false, i.HasTail);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CALLVIRT:
                    MethodInfo callee = i.Param as MethodInfo;
                    head = tail = new CallMethod(callee, callee.IsVirtual, i.HasTail);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.NEWOBJ:
                { ConstructorInfo ctor = i.Param as ConstructorInfo;
                  if (Verifier.IsDelegate(ctor.DeclaringType))
                  {
                      if (Verifier.IsInstanceDispatch(method, iNum))
                      {
                          heads[iNum - 1] = tails[iNum - 1] = null;
                          head            = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, false);
                      }
                      else if (Verifier.IsVirtualDispatch(method, iNum))
                      {
                          heads[iNum - 2] = tails[iNum - 2] = null;
                          heads[iNum - 1] = tails[iNum - 1] = null;
                          head            = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, true);
                      }
                  }
                  else
                  {
                      head = tail = new NewObject(ctor);
                  }
                  /*!*/ head.setParent(currentBlock); }       break;

                case InstructionCode.NEWARR:
                    head = tail = new NewArray(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.INITOBJ:
                    head = tail = new InitValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.ISINST:
                    head = tail = new CastClass(i.Param as Type, false);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CASTCLASS:
                    head = tail = new CastClass(i.Param as Type, true);
                    /*!*/ head.setParent(currentBlock);
                    break;


                case InstructionCode.BOX:
                    head = tail = new BoxValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.UNBOX:
                    head = tail = new UnboxValue(i.Param as Type);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.CONV:
                    head = tail = new ConvertValue(i.TypeBySuffixOrParam(), i.OverflowFlag, i.UnsignedFlag);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.POP:
                    head = tail = new RemoveStackTop();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BEQ:
                    head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false);
                    /*!*/ head.setParent(currentBlock);
                    tail = new Branch();
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BNE:
                    head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false);
                    /*!*/ head.setParent(currentBlock);
                    tail = new Branch();
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BGE:
                    if (TypeFixer.IsFloatOrCompatible(i.Stack.Top()))
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CLT, false, !i.UnsignedFlag);
                    }
                    else
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag);
                    }
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BGT:
                    head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag);
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BLE:
                    if (TypeFixer.IsFloatOrCompatible(i.Stack.Top()))
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CGT, false, !i.UnsignedFlag);
                    }
                    else
                    {
                        head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag);
                    }
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BLT:
                    head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag);
                    tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    /*!*/ tail.setParent(currentBlock);
                    head.Next = tail;
                    break;

                case InstructionCode.BRTRUE:
                    head = tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BRFALSE:
                    head = tail = new Branch();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.SWITCH:
                    head = tail = new Switch((i.Param as int[]).Length);
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.BR:
                case InstructionCode.NOP:
                case InstructionCode.BREAK:
                case InstructionCode.LDFTN:                             // Expecting further delegate construction...
                case InstructionCode.LDVIRTFTN:                         //
                    head = tail = new DummyNode();
                    /*!*/ head.setParent(currentBlock);
                    break;

                case InstructionCode.THROW:
                    head = tail = new ThrowException();
                    /*!*/ head.setParent(currentBlock);
                    break;


                case InstructionCode.RET:
                case InstructionCode.ENDFINALLY:
                case InstructionCode.ENDFILTER:
                case InstructionCode.LEAVE:
                    head = tail = new Leave();
                    /*!*/ head.setParent(currentBlock);
                    break;

                default:
                    throw new ConvertionException();
                }
                if (head != null)
                {
                    head.Options["StackTypes"] = i.Stack.Clone() as StackTypes;
                }
                if (head != tail)                //=>   head :: BinaryOp, tail :: Branch
                //||   head :: LoadIndirect, tail :: StoreIndirect
                {
                    if (head is BinaryOp && tail is Branch)
                    {
                        StackTypes stack = i.Stack.Clone() as StackTypes;
                        stack.Pop();
                        stack.Pop();
                        stack.Push(typeof(int));
                        tail.Options["StackTypes"] = stack;
                    }
                    else if (head is LoadIndirect && tail is StoreIndirect)
                    {
                        StackTypes stack = i.Stack.Clone() as StackTypes;
                        TypeEx     type  = stack.Pop();                    //type == S&
                        stack.Push(type.type.GetElementType());
                        tail.Options["StackTypes"] = stack;
                    }
                }
                if (firstBlock != null)
                {
                    lastBlock.Next = head;
                    for (Node n = firstBlock; n != head; n = n.Next)
                    {
                        n.Options["StackTypes"] = i.Stack.Clone() as StackTypes;
                    }
                    head = firstBlock;
                    if (tail == null)
                    {
                        tail = lastBlock;                         //This may occure what the NOP instruction starts some block
                    }
                }
                heads[iNum] = head;
                tails[iNum] = tail;
            }            //for
            mainBlock.Next = heads[0];
            //Control flow linkage
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                if (heads[iNum] == null)
                {
                    throw new ConvertionException();                     //impossible :)
                }
                Instruction i = method[iNum];

                switch (i.Code)
                {
                case InstructionCode.BR:
                case InstructionCode.LEAVE:
                    tails[iNum].Next = heads[(int)i.Param];
                    break;

                case InstructionCode.RET:
                case InstructionCode.ENDFINALLY:
                case InstructionCode.ENDFILTER:
                case InstructionCode.THROW:
                case InstructionCode.RETHROW:
                    break;

                case InstructionCode.BRFALSE:                     //false
                case InstructionCode.BGE:                         //false
                case InstructionCode.BLE:                         //false
                case InstructionCode.BNE:                         //false
                    tails[iNum].Next            = heads[(int)i.Param];
                    (tails[iNum] as Branch).Alt = heads[iNum + 1];
                    break;

                case InstructionCode.BRTRUE:                      //true
                case InstructionCode.BEQ:                         //true
                case InstructionCode.BGT:                         //true
                case InstructionCode.BLT:                         //true
                    tails[iNum].Next            = heads[iNum + 1];
                    (tails[iNum] as Branch).Alt = heads[(int)i.Param];
                    break;

                case InstructionCode.SWITCH:
                    tails[iNum].Next = heads[iNum + 1];
                    Switch node = tails[iNum] as Switch;
                    int[]  alt  = i.Param as int[];
                    for (int j = 0; j < node.Count; j++)
                    {
                        node[j] = heads[alt[j]];
                    }
                    break;

                default:
                    tails[iNum].Next = heads[iNum + 1];
                    break;
                }
            }

            //Removing DummyNodes
            for (iNum = 0; iNum < method.Count; iNum++)
            {
                if (heads[iNum] is DummyNode)
                {
                    Node   dummy = heads[iNum];
                    Node[] prev  = new Node[dummy.PrevArray.Count];
                    for (int j = 0; j < prev.Length; j++)
                    {
                        prev[j] = dummy.PrevArray[j];
                    }
                    for (int j = 0; j < prev.Length; j++)
                    {
                        prev[j].NextArray[prev[j].NextArray.IndexOf(dummy)] = dummy.Next;
                    }
                    dummy.RemoveFromGraph();
                }
            }


            return(mainBlock);
        }