Exemple #1
0
            protected internal override void VisitLoadElement(LoadElement node, object data)
            {
                StackTypes stack = data as StackTypes;

                Verifier.ProcessLdElem(stack, new TypeEx(node.Type), false);
                AddTask(node.Next, stack);
            }
Exemple #2
0
        protected override void VisitLoadElement(LoadElement downNode, object o)
        {
            StructValue          idx = this.state.Stack.Pop() as StructValue;
            ObjectReferenceValue arr = this.state.Stack.Pop() as ObjectReferenceValue;
            PointerValue         ptr = new PointerToElementValue(arr.Obj as Array, SpecializingVisitor.toInt(idx));

            this.loadVar(downNode, ptr, o);
        }
Exemple #3
0
 protected override void VisitLoadElement(LoadElement node, object data)
 {
     state.Stack.Perform_LoadElement(node.Type, out exc);
     nextNode = node.Next;
 }
Exemple #4
0
 protected internal virtual void VisitLoadElement(LoadElement node, object data)
 {
     throw new NodeNotSupportedException(node);
 }
        static void Main(string[] args)
        {
            //we won't bother with fancy argument parsing here, just look at the buggers directly.
            if (args.Length == 0)
            {
                ShowHelp();
                return;
            }
            else if (args.Length > 0)
            {
                String sUseFile = null;
                if (args.Length > 1)
                {
                    sUseFile = args[1];
                }
                else
                {
                    sUseFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "BASeCamp", "VolumeSlapper", "Quick.xml");
                }
                if (String.Compare(args[0], "save", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    //saves to a given filename.
                    String sTargetFile = sUseFile;
                    Console.WriteLine("Saving session volume data to " + sUseFile);
                    if (sTargetFile.StartsWith("\""))
                    {
                        sTargetFile = sTargetFile.Substring(1);
                    }
                    if (sTargetFile.EndsWith("\""))
                    {
                        sTargetFile = sTargetFile.Substring(0, sTargetFile.Length - 1);
                    }
                    if (File.Exists(sTargetFile))
                    {
                        Console.WriteLine("not overwriting existing file:\"" + sTargetFile + "\"");
                        return;
                    }
                    else
                    {
                        //save volume information to the file, if the process exists, index by the executable path. Otherwise, we index by the retrieved name.
                        XElement  RootNode     = new XElement("Mixer");
                        XDocument VolumeDoc    = new XDocument(RootNode);
                        float     MasterVolume = VolumeUtilities.GetMasterVolume();
                        RootNode.Add(new XAttribute("MasterVolume", MasterVolume));
                        var VolumeData = VolumeUtilities.EnumerateApplications().ToList();
                        foreach (var appinfo in VolumeData)
                        {
                            XElement BuildNode = new XElement("Session", new XAttribute("Name", appinfo.Name), new XAttribute("Volume", appinfo.Volume));
                            RootNode.Add(BuildNode);
                        }
                        String PathPart = Path.GetDirectoryName(sTargetFile);
                        if (!Directory.Exists(PathPart))
                        {
                            Directory.CreateDirectory(PathPart);
                        }
                        using (FileStream ftarget = new FileStream(sTargetFile, FileMode.CreateNew))
                        {
                            VolumeDoc.Save(ftarget);
                        }
                    }
                }
                else if (String.Compare(args[0], "load", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    //loads volume settings from the given file name.
                    String sLoadFile = sUseFile;
                    Console.WriteLine("Loading session volume data from " + sUseFile);
                    if (!File.Exists(sLoadFile))
                    {
                        Console.WriteLine("File not found:" + sLoadFile);
                    }
                    else
                    {
                        XDocument loadDoc = null;
                        using (FileStream fs = new FileStream(sLoadFile, FileMode.Open))
                        {
                            loadDoc = XDocument.Load(fs);
                            XElement MixerNode          = loadDoc.Root;
                            float    MasterVolume       = 0;
                            var      MasterVolumeAttrib = MixerNode.Attribute("MasterVolume");
                            if (MasterVolumeAttrib != null)
                            {
                                MasterVolume = float.Parse(MasterVolumeAttrib.Value);
                            }
                            var ListApps   = VolumeUtilities.EnumerateApplications().ToList();
                            var VolumeInfo = new Dictionary <string, VolumeUtilities.ApplicationVolumeInformation>();
                            foreach (var VolData in ListApps)
                            {
                                if (!VolumeInfo.ContainsKey(VolData.Name))
                                {
                                    VolumeInfo.Add(VolData.Name, VolData);
                                }
                            }
                            VolumeUtilities.SetMasterVolume(MasterVolume);
                            foreach (XElement LoadElement in MixerNode.Elements("Session"))
                            {
                                String     sName = "";
                                float      useVolume = 0;
                                XAttribute Nameattr = null, Volumeattr = null;
                                if ((Nameattr = LoadElement.Attribute("Name")) != null)
                                {
                                    sName = Nameattr.Value;
                                }
                                if ((Volumeattr = LoadElement.Attribute("Volume")) != null)
                                {
                                    float.TryParse(Volumeattr.Value, out useVolume);
                                }


                                try
                                {
                                    VolumeUtilities.SetApplicationVolume(sName, useVolume);
                                }
                                catch (Exception exx)
                                {
                                    Console.WriteLine("Failed Attempting to set volume for " + sName + " To " + useVolume);
                                }
                            }
                        }
                    }
                }
                else if (String.Compare(args[0], "get", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    String VolumeNode = "Master";
                    if (args.Length > 1)
                    {
                        //includes the volume node (program name to get the volume of)
                        VolumeNode = args[1];
                    }
                    //get logic
                    if (VolumeNode.Equals("Master", StringComparison.OrdinalIgnoreCase))
                    {
                        float currvolume = VolumeUtilities.GetMasterVolume();
                        Console.WriteLine(currvolume);
                    }
                    else
                    {
                        var grabAppInfo = VolumeUtilities.GetApplicationVolumeInfo(VolumeNode);
                        if (grabAppInfo == null)
                        {
                            Console.WriteLine("Unable to find Session " + VolumeNode);
                        }
                        else
                        {
                            Console.WriteLine("Current Volume of " + VolumeNode + " is " + grabAppInfo.Volume);
                        }
                    }
                }
                else if (String.Compare(args[0], "set", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    //set logic.
                    float  assignvolume;
                    String sVolume    = "";
                    String VolumeNode = "Master";
                    if (args.Length > 1)
                    {
                        VolumeNode = args[1];
                        sVolume    = args[2];
                    }
                    else
                    {
                        VolumeNode = "Master";
                        sVolume    = args[1];
                    }
                    if (!float.TryParse(sVolume, out assignvolume))
                    {
                        Console.WriteLine("Specified volume level not valid:" + args[1]);
                        Console.WriteLine();
                        ShowHelp();
                        return;
                    }
                    else
                    {
                        if (VolumeNode.Equals("Master", StringComparison.OrdinalIgnoreCase))
                        {
                            VolumeUtilities.SetMasterVolume(assignvolume);
                            Console.WriteLine("Volume Level set to " + assignvolume);
                        }
                        else
                        {
                            var grabinfo = VolumeUtilities.GetApplicationVolumeInfo(VolumeNode);
                            if (grabinfo != null)
                            {
                                grabinfo.Volume = assignvolume;
                                Console.WriteLine("Volume for " + VolumeNode + " Set to " + assignvolume);
                            }
                            else
                            {
                                Console.WriteLine("Unable to find " + VolumeNode);
                            }
                        }
                    }
                }
                else if (String.Compare(args[0], "status", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    Console.WriteLine(" Master Volume is " + VolumeUtilities.GetMasterVolume());
                    foreach (var iterateApp in VolumeUtilities.EnumerateApplications())
                    {
                        var result = iterateApp.Volume;
                        if (result != null)
                        {
                            Console.WriteLine("Session:" + iterateApp.Name);
                            Console.WriteLine("ProcessID:" + iterateApp.ProcessID);
                            Console.WriteLine("Volume:" + result);
                            Console.WriteLine();
                        }
                    }
                }
                else
                {
                    Console.WriteLine("unrecognized parameter:" + args[0]);
                    Console.WriteLine();
                    ShowHelp();
                    return;
                }
            }


            Console.ReadKey();
        }
 public void WriteLoadElement(LoadElement s, ExpressionUsage u)
 {
     WriteLoadElement(s.Source, s.ReturnType, s.Array, s.Index, u);
 }
Exemple #7
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);
        }