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); } } } } }
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); }
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); }
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); } }
protected override void VisitCastClass(CastClass node, object data) { state.Stack.Perform_CastClass(node.Type, node.ThrowException, out exc); nextNode = node.Next; }
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); }
public void VisitCast(CastClass cast) { DoAdd(cast.ToType); }
protected internal virtual void VisitCastClass(CastClass node, object data) { throw new NodeNotSupportedException(node); }
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); }