/// <summary> /// Realizes a virtual-call instruction. /// </summary> /// <param name="instruction">The current IL instruction.</param> private void MakeVirtualCall(ILInstruction instruction) { var method = instruction.GetArgumentAs <MethodInfo>(); if (instruction.HasFlags(ILInstructionFlags.Constrained)) { MakeVirtualCall( method, instruction.FlagsContext.Argument as Type); } else { MakeVirtualCall(method, null); } }
private bool TryGenerateCode(ILInstruction instruction) { switch (instruction.InstructionType) { case ILInstructionType.Nop: MakeNop(); return(true); case ILInstructionType.Break: MakeTrap(); return(true); case ILInstructionType.LdToken: MakeLoadToken(instruction.Argument); return(true); case ILInstructionType.Ldarg: { var index = instruction.GetArgumentAs <int>() - LambdaArgumentOffset; if (index >= 0) { LoadVariable( new VariableRef( index, VariableRefType.Argument)); } } return(true); case ILInstructionType.Ldarga: { var index = instruction.GetArgumentAs <int>() - LambdaArgumentOffset; if (index >= 0) { LoadVariableAddress( new VariableRef( index, VariableRefType.Argument)); } } return(true); case ILInstructionType.Starg: { var index = instruction.GetArgumentAs <int>() - LambdaArgumentOffset; if (index >= 0) { StoreVariable( new VariableRef( index, VariableRefType.Argument)); } } return(true); case ILInstructionType.Ldloc: LoadVariable( new VariableRef( instruction.GetArgumentAs <int>(), VariableRefType.Local)); return(true); case ILInstructionType.Ldloca: LoadVariableAddress( new VariableRef( instruction.GetArgumentAs <int>(), VariableRefType.Local)); return(true); case ILInstructionType.Stloc: StoreVariable( new VariableRef( instruction.GetArgumentAs <int>(), VariableRefType.Local)); return(true); case ILInstructionType.LdI4: Load(instruction.GetArgumentAs <int>()); return(true); case ILInstructionType.LdI8: Load(instruction.GetArgumentAs <long>()); return(true); case ILInstructionType.LdR4: Load(instruction.GetArgumentAs <float>()); return(true); case ILInstructionType.LdR8: Load(instruction.GetArgumentAs <double>()); return(true); case ILInstructionType.Ldstr: LoadString(instruction.GetArgumentAs <string>()); return(true); case ILInstructionType.Dup: MakeDup(); return(true); case ILInstructionType.Pop: MakePop(); return(true); case ILInstructionType.Ret: MakeReturn(); return(true); case ILInstructionType.Call: MakeCall(instruction.GetArgumentAs <MethodBase>()); return(true); case ILInstructionType.Callvirt: MakeVirtualCall(instruction); return(true); case ILInstructionType.Calli: MakeCalli(instruction.Argument); return(true); case ILInstructionType.Jmp: MakeJump(instruction.GetArgumentAs <MethodBase>()); return(true); case ILInstructionType.Box: MakeBox(); return(true); case ILInstructionType.Unbox: MakeUnbox(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Br: MakeBranch(); return(true); case ILInstructionType.Brfalse: MakeBranchFalse(); return(true); case ILInstructionType.Brtrue: MakeBranchTrue(); return(true); case ILInstructionType.Beq: MakeBranch(CompareKind.Equal, instruction.Flags); return(true); case ILInstructionType.Bne: MakeBranch(CompareKind.NotEqual, instruction.Flags); return(true); case ILInstructionType.Bge: MakeBranch(CompareKind.GreaterEqual, instruction.Flags); return(true); case ILInstructionType.Bgt: MakeBranch(CompareKind.GreaterThan, instruction.Flags); return(true); case ILInstructionType.Ble: MakeBranch(CompareKind.LessEqual, instruction.Flags); return(true); case ILInstructionType.Blt: MakeBranch(CompareKind.LessThan, instruction.Flags); return(true); case ILInstructionType.Switch: MakeSwitch(instruction.GetArgumentAs <ILInstructionBranchTargets>()); return(true); case ILInstructionType.Add: MakeArithmetic(BinaryArithmeticKind.Add, instruction); return(true); case ILInstructionType.Sub: MakeArithmetic(BinaryArithmeticKind.Sub, instruction); return(true); case ILInstructionType.Mul: MakeArithmetic(BinaryArithmeticKind.Mul, instruction); return(true); case ILInstructionType.Div: MakeArithmetic(BinaryArithmeticKind.Div, instruction); return(true); case ILInstructionType.Rem: MakeArithmetic(BinaryArithmeticKind.Rem, instruction); return(true); case ILInstructionType.And: MakeArithmetic(BinaryArithmeticKind.And, instruction); return(true); case ILInstructionType.Or: MakeArithmetic(BinaryArithmeticKind.Or, instruction); return(true); case ILInstructionType.Xor: MakeArithmetic(BinaryArithmeticKind.Xor, instruction); return(true); case ILInstructionType.Shl: MakeArithmetic(BinaryArithmeticKind.Shl, instruction); return(true); case ILInstructionType.Shr: MakeArithmetic(BinaryArithmeticKind.Shr, instruction); return(true); case ILInstructionType.Neg: MakeArithmetic(UnaryArithmeticKind.Neg); return(true); case ILInstructionType.Not: MakeArithmetic(UnaryArithmeticKind.Not); return(true); case ILInstructionType.Conv: MakeConvert(instruction.GetArgumentAs <Type>(), instruction.Flags); return(true); case ILInstructionType.Initobj: MakeInitObject(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Newobj: MakeNewObject(instruction.GetArgumentAs <MethodBase>()); return(true); case ILInstructionType.Isinst: MakeIsInstance(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Ldfld: MakeLoadField(instruction.GetArgumentAs <FieldInfo>()); return(true); case ILInstructionType.Ldsfld: MakeLoadStaticField(instruction.GetArgumentAs <FieldInfo>()); return(true); case ILInstructionType.Ldflda: MakeLoadFieldAddress(instruction.GetArgumentAs <FieldInfo>()); return(true); case ILInstructionType.Ldsflda: MakeLoadStaticFieldAddress(instruction.GetArgumentAs <FieldInfo>()); return(true); case ILInstructionType.Stfld: MakeStoreField(instruction.GetArgumentAs <FieldInfo>()); return(true); case ILInstructionType.Stsfld: MakeStoreStaticField(instruction.GetArgumentAs <FieldInfo>()); return(true); case ILInstructionType.Ceq: MakeCompare(CompareKind.Equal, instruction.Flags); return(true); case ILInstructionType.Cgt: MakeCompare(CompareKind.GreaterThan, instruction.Flags); return(true); case ILInstructionType.Clt: MakeCompare(CompareKind.LessThan, instruction.Flags); return(true); case ILInstructionType.Ldobj: case ILInstructionType.Ldind: MakeLoadObject(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Stobj: case ILInstructionType.Stind: MakeStoreObject(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Newarr: MakeNewArray(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Ldelem: MakeLoadElement(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Ldelema: MakeLoadElementAddress(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Stelem: MakeStoreElement(instruction.GetArgumentAs <Type>()); return(true); case ILInstructionType.Ldlen: MakeLoadArrayLength(); return(true); default: return(false); } }