private void ImportBasicBlock(BasicBlock basicBlock) { _currentBasicBlock = basicBlock; _currentOffset = basicBlock.StartOffset; for (;;) { StartImportingInstruction(); ILOpcode opCode = (ILOpcode)ReadILByte(); again: switch (opCode) { case ILOpcode.nop: ImportNop(); break; case ILOpcode.break_: ImportBreak(); break; case ILOpcode.ldarg_0: case ILOpcode.ldarg_1: case ILOpcode.ldarg_2: case ILOpcode.ldarg_3: ImportLoadVar(opCode - ILOpcode.ldarg_0, true); break; case ILOpcode.ldloc_0: case ILOpcode.ldloc_1: case ILOpcode.ldloc_2: case ILOpcode.ldloc_3: ImportLoadVar(opCode - ILOpcode.ldloc_0, false); break; case ILOpcode.stloc_0: case ILOpcode.stloc_1: case ILOpcode.stloc_2: case ILOpcode.stloc_3: ImportStoreVar(opCode - ILOpcode.stloc_0, false); break; case ILOpcode.ldarg_s: ImportLoadVar(ReadILByte(), true); break; case ILOpcode.ldarga_s: ImportAddressOfVar(ReadILByte(), true); break; case ILOpcode.starg_s: ImportStoreVar(ReadILByte(), true); break; case ILOpcode.ldloc_s: ImportLoadVar(ReadILByte(), false); break; case ILOpcode.ldloca_s: ImportAddressOfVar(ReadILByte(), false); break; case ILOpcode.stloc_s: ImportStoreVar(ReadILByte(), false); break; case ILOpcode.ldnull: ImportLoadNull(); break; case ILOpcode.ldc_i4_m1: ImportLoadInt(-1, StackValueKind.Int32); break; case ILOpcode.ldc_i4_0: case ILOpcode.ldc_i4_1: case ILOpcode.ldc_i4_2: case ILOpcode.ldc_i4_3: case ILOpcode.ldc_i4_4: case ILOpcode.ldc_i4_5: case ILOpcode.ldc_i4_6: case ILOpcode.ldc_i4_7: case ILOpcode.ldc_i4_8: ImportLoadInt(opCode - ILOpcode.ldc_i4_0, StackValueKind.Int32); break; case ILOpcode.ldc_i4_s: ImportLoadInt((sbyte)ReadILByte(), StackValueKind.Int32); break; case ILOpcode.ldc_i4: ImportLoadInt((int)ReadILUInt32(), StackValueKind.Int32); break; case ILOpcode.ldc_i8: ImportLoadInt((long)ReadILUInt64(), StackValueKind.Int64); break; case ILOpcode.ldc_r4: ImportLoadFloat(ReadILFloat()); break; case ILOpcode.ldc_r8: ImportLoadFloat(ReadILDouble()); break; case ILOpcode.dup: ImportDup(); break; case ILOpcode.pop: ImportPop(); break; case ILOpcode.jmp: ImportJmp(ReadILToken()); EndImportingInstruction(); return; case ILOpcode.call: ImportCall(opCode, ReadILToken()); break; case ILOpcode.calli: ImportCalli(ReadILToken()); break; case ILOpcode.ret: ImportReturn(); EndImportingInstruction(); return; case ILOpcode.br_s: case ILOpcode.brfalse_s: case ILOpcode.brtrue_s: case ILOpcode.beq_s: case ILOpcode.bge_s: case ILOpcode.bgt_s: case ILOpcode.ble_s: case ILOpcode.blt_s: case ILOpcode.bne_un_s: case ILOpcode.bge_un_s: case ILOpcode.bgt_un_s: case ILOpcode.ble_un_s: case ILOpcode.blt_un_s: { int delta = (sbyte)ReadILByte(); ImportBranch(opCode + (ILOpcode.br - ILOpcode.br_s), _basicBlocks[_currentOffset + delta], (opCode != ILOpcode.br_s) ? _basicBlocks[_currentOffset] : null); } EndImportingInstruction(); return; case ILOpcode.br: case ILOpcode.brfalse: case ILOpcode.brtrue: case ILOpcode.beq: case ILOpcode.bge: case ILOpcode.bgt: case ILOpcode.ble: case ILOpcode.blt: case ILOpcode.bne_un: case ILOpcode.bge_un: case ILOpcode.bgt_un: case ILOpcode.ble_un: case ILOpcode.blt_un: { int delta = (int)ReadILUInt32(); ImportBranch(opCode, _basicBlocks[_currentOffset + delta], (opCode != ILOpcode.br) ? _basicBlocks[_currentOffset] : null); } EndImportingInstruction(); return; case ILOpcode.switch_: { uint count = ReadILUInt32(); int jmpBase = _currentOffset + (int)(4 * count); int[] jmpDelta = new int[count]; for (uint i = 0; i < count; i++) { jmpDelta[i] = (int)ReadILUInt32(); } ImportSwitchJump(jmpBase, jmpDelta, _basicBlocks[_currentOffset]); } EndImportingInstruction(); return; case ILOpcode.ldind_i1: ImportLoadIndirect(WellKnownType.SByte); break; case ILOpcode.ldind_u1: ImportLoadIndirect(WellKnownType.Byte); break; case ILOpcode.ldind_i2: ImportLoadIndirect(WellKnownType.Int16); break; case ILOpcode.ldind_u2: ImportLoadIndirect(WellKnownType.UInt16); break; case ILOpcode.ldind_i4: ImportLoadIndirect(WellKnownType.Int32); break; case ILOpcode.ldind_u4: ImportLoadIndirect(WellKnownType.UInt32); break; case ILOpcode.ldind_i8: ImportLoadIndirect(WellKnownType.Int64); break; case ILOpcode.ldind_i: ImportLoadIndirect(WellKnownType.IntPtr); break; case ILOpcode.ldind_r4: ImportLoadIndirect(WellKnownType.Single); break; case ILOpcode.ldind_r8: ImportLoadIndirect(WellKnownType.Double); break; case ILOpcode.ldind_ref: ImportLoadIndirect(null); break; case ILOpcode.stind_ref: ImportStoreIndirect(null); break; case ILOpcode.stind_i1: ImportStoreIndirect(WellKnownType.SByte); break; case ILOpcode.stind_i2: ImportStoreIndirect(WellKnownType.Int16); break; case ILOpcode.stind_i4: ImportStoreIndirect(WellKnownType.Int32); break; case ILOpcode.stind_i8: ImportStoreIndirect(WellKnownType.Int64); break; case ILOpcode.stind_r4: ImportStoreIndirect(WellKnownType.Single); break; case ILOpcode.stind_r8: ImportStoreIndirect(WellKnownType.Double); break; case ILOpcode.add: case ILOpcode.sub: case ILOpcode.mul: case ILOpcode.div: case ILOpcode.div_un: case ILOpcode.rem: case ILOpcode.rem_un: case ILOpcode.and: case ILOpcode.or: case ILOpcode.xor: ImportBinaryOperation(opCode); break; case ILOpcode.shl: case ILOpcode.shr: case ILOpcode.shr_un: ImportShiftOperation(opCode); break; case ILOpcode.neg: case ILOpcode.not: ImportUnaryOperation(opCode); break; case ILOpcode.conv_i1: ImportConvert(WellKnownType.SByte, false, false); break; case ILOpcode.conv_i2: ImportConvert(WellKnownType.Int16, false, false); break; case ILOpcode.conv_i4: ImportConvert(WellKnownType.Int32, false, false); break; case ILOpcode.conv_i8: ImportConvert(WellKnownType.Int64, false, false); break; case ILOpcode.conv_r4: ImportConvert(WellKnownType.Single, false, false); break; case ILOpcode.conv_r8: ImportConvert(WellKnownType.Double, false, false); break; case ILOpcode.conv_u4: ImportConvert(WellKnownType.UInt32, false, false); break; case ILOpcode.conv_u8: ImportConvert(WellKnownType.UInt64, false, false); break; case ILOpcode.callvirt: ImportCall(opCode, ReadILToken()); break; case ILOpcode.cpobj: ImportCpOpj(ReadILToken()); break; case ILOpcode.ldobj: ImportLoadIndirect(ReadILToken()); break; case ILOpcode.ldstr: ImportLoadString(ReadILToken()); break; case ILOpcode.newobj: ImportCall(opCode, ReadILToken()); break; case ILOpcode.castclass: case ILOpcode.isinst: ImportCasting(opCode, ReadILToken()); break; case ILOpcode.conv_r_un: ImportConvert(WellKnownType.Double, false, true); break; case ILOpcode.unbox: ImportUnbox(ReadILToken(), opCode); break; case ILOpcode.throw_: ImportThrow(); EndImportingInstruction(); return; case ILOpcode.ldfld: ImportLoadField(ReadILToken(), false); break; case ILOpcode.ldflda: ImportAddressOfField(ReadILToken(), false); break; case ILOpcode.stfld: ImportStoreField(ReadILToken(), false); break; case ILOpcode.ldsfld: ImportLoadField(ReadILToken(), true); break; case ILOpcode.ldsflda: ImportAddressOfField(ReadILToken(), true); break; case ILOpcode.stsfld: ImportStoreField(ReadILToken(), true); break; case ILOpcode.stobj: ImportStoreIndirect(ReadILToken()); break; case ILOpcode.conv_ovf_i1_un: ImportConvert(WellKnownType.SByte, true, true); break; case ILOpcode.conv_ovf_i2_un: ImportConvert(WellKnownType.Int16, true, true); break; case ILOpcode.conv_ovf_i4_un: ImportConvert(WellKnownType.Int32, true, true); break; case ILOpcode.conv_ovf_i8_un: ImportConvert(WellKnownType.Int64, true, true); break; case ILOpcode.conv_ovf_u1_un: ImportConvert(WellKnownType.Byte, true, true); break; case ILOpcode.conv_ovf_u2_un: ImportConvert(WellKnownType.UInt16, true, true); break; case ILOpcode.conv_ovf_u4_un: ImportConvert(WellKnownType.UInt32, true, true); break; case ILOpcode.conv_ovf_u8_un: ImportConvert(WellKnownType.UInt64, true, true); break; case ILOpcode.conv_ovf_i_un: ImportConvert(WellKnownType.IntPtr, true, true); break; case ILOpcode.conv_ovf_u_un: ImportConvert(WellKnownType.UIntPtr, true, true); break; case ILOpcode.box: ImportBox(ReadILToken()); break; case ILOpcode.newarr: ImportNewArray(ReadILToken()); break; case ILOpcode.ldlen: ImportLoadLength(); break; case ILOpcode.ldelema: ImportAddressOfElement(ReadILToken()); break; case ILOpcode.ldelem_i1: ImportLoadElement(WellKnownType.SByte); break; case ILOpcode.ldelem_u1: ImportLoadElement(WellKnownType.Byte); break; case ILOpcode.ldelem_i2: ImportLoadElement(WellKnownType.Int16); break; case ILOpcode.ldelem_u2: ImportLoadElement(WellKnownType.UInt16); break; case ILOpcode.ldelem_i4: ImportLoadElement(WellKnownType.Int32); break; case ILOpcode.ldelem_u4: ImportLoadElement(WellKnownType.UInt32); break; case ILOpcode.ldelem_i8: ImportLoadElement(WellKnownType.Int64); break; case ILOpcode.ldelem_i: ImportLoadElement(WellKnownType.IntPtr); break; case ILOpcode.ldelem_r4: ImportLoadElement(WellKnownType.Single); break; case ILOpcode.ldelem_r8: ImportLoadElement(WellKnownType.Double); break; case ILOpcode.ldelem_ref: ImportLoadElement(null); break; case ILOpcode.stelem_i: ImportStoreElement(WellKnownType.IntPtr); break; case ILOpcode.stelem_i1: ImportStoreElement(WellKnownType.SByte); break; case ILOpcode.stelem_i2: ImportStoreElement(WellKnownType.Int16); break; case ILOpcode.stelem_i4: ImportStoreElement(WellKnownType.Int32); break; case ILOpcode.stelem_i8: ImportStoreElement(WellKnownType.Int64); break; case ILOpcode.stelem_r4: ImportStoreElement(WellKnownType.Single); break; case ILOpcode.stelem_r8: ImportStoreElement(WellKnownType.Double); break; case ILOpcode.stelem_ref: ImportStoreElement(null); break; case ILOpcode.ldelem: ImportLoadElement(ReadILToken()); break; case ILOpcode.stelem: ImportStoreElement(ReadILToken()); break; case ILOpcode.unbox_any: ImportUnbox(ReadILToken(), opCode); break; case ILOpcode.conv_ovf_i1: ImportConvert(WellKnownType.SByte, true, false); break; case ILOpcode.conv_ovf_u1: ImportConvert(WellKnownType.Byte, true, false); break; case ILOpcode.conv_ovf_i2: ImportConvert(WellKnownType.Int16, true, false); break; case ILOpcode.conv_ovf_u2: ImportConvert(WellKnownType.UInt16, true, false); break; case ILOpcode.conv_ovf_i4: ImportConvert(WellKnownType.Int32, true, false); break; case ILOpcode.conv_ovf_u4: ImportConvert(WellKnownType.UInt32, true, false); break; case ILOpcode.conv_ovf_i8: ImportConvert(WellKnownType.Int64, true, false); break; case ILOpcode.conv_ovf_u8: ImportConvert(WellKnownType.UInt64, true, false); break; case ILOpcode.refanyval: ImportRefAnyVal(ReadILToken()); break; case ILOpcode.ckfinite: ImportCkFinite(); break; case ILOpcode.mkrefany: ImportMkRefAny(ReadILToken()); break; case ILOpcode.ldtoken: ImportLdToken(ReadILToken()); break; case ILOpcode.conv_u2: ImportConvert(WellKnownType.UInt16, false, false); break; case ILOpcode.conv_u1: ImportConvert(WellKnownType.Byte, false, false); break; case ILOpcode.conv_i: ImportConvert(WellKnownType.IntPtr, false, false); break; case ILOpcode.conv_ovf_i: ImportConvert(WellKnownType.IntPtr, true, false); break; case ILOpcode.conv_ovf_u: ImportConvert(WellKnownType.UIntPtr, true, false); break; case ILOpcode.add_ovf: case ILOpcode.add_ovf_un: case ILOpcode.mul_ovf: case ILOpcode.mul_ovf_un: case ILOpcode.sub_ovf: case ILOpcode.sub_ovf_un: ImportBinaryOperation(opCode); break; case ILOpcode.endfinally: //both endfinally and endfault ImportEndFinally(); EndImportingInstruction(); return; case ILOpcode.leave: { int delta = (int)ReadILUInt32(); ImportLeave(_basicBlocks[_currentOffset + delta]); } EndImportingInstruction(); return; case ILOpcode.leave_s: { int delta = (sbyte)ReadILByte(); ImportLeave(_basicBlocks[_currentOffset + delta]); } EndImportingInstruction(); return; case ILOpcode.stind_i: ImportStoreIndirect(WellKnownType.IntPtr); break; case ILOpcode.conv_u: ImportConvert(WellKnownType.UIntPtr, false, false); break; case ILOpcode.prefix1: opCode = (ILOpcode)(0x100 + ReadILByte()); goto again; case ILOpcode.arglist: ImportArgList(); break; case ILOpcode.ceq: case ILOpcode.cgt: case ILOpcode.cgt_un: case ILOpcode.clt: case ILOpcode.clt_un: ImportCompareOperation(opCode); break; case ILOpcode.ldftn: case ILOpcode.ldvirtftn: ImportLdFtn(ReadILToken(), opCode); break; case ILOpcode.ldarg: ImportLoadVar(ReadILUInt16(), true); break; case ILOpcode.ldarga: ImportAddressOfVar(ReadILUInt16(), true); break; case ILOpcode.starg: ImportStoreVar(ReadILUInt16(), true); break; case ILOpcode.ldloc: ImportLoadVar(ReadILUInt16(), false); break; case ILOpcode.ldloca: ImportAddressOfVar(ReadILUInt16(), false); break; case ILOpcode.stloc: ImportStoreVar(ReadILUInt16(), false); break; case ILOpcode.localloc: ImportLocalAlloc(); break; case ILOpcode.endfilter: ImportEndFilter(); EndImportingInstruction(); return; case ILOpcode.unaligned: ImportUnalignedPrefix(ReadILByte()); continue; case ILOpcode.volatile_: ImportVolatilePrefix(); continue; case ILOpcode.tail: ImportTailPrefix(); continue; case ILOpcode.initobj: ImportInitObj(ReadILToken()); break; case ILOpcode.constrained: ImportConstrainedPrefix(ReadILToken()); continue; case ILOpcode.cpblk: ImportCpBlk(); break; case ILOpcode.initblk: ImportInitBlk(); break; case ILOpcode.no: ImportNoPrefix(ReadILByte()); continue; case ILOpcode.rethrow: ImportRethrow(); EndImportingInstruction(); return; case ILOpcode.sizeof_: ImportSizeOf(ReadILToken()); break; case ILOpcode.refanytype: ImportRefAnyType(); break; case ILOpcode.readonly_: ImportReadOnlyPrefix(); continue; default: ReportInvalidInstruction(opCode); EndImportingInstruction(); return; } EndImportingInstruction(); // Check if control falls through the end of method. if (_currentOffset == _basicBlocks.Length) { ReportFallthroughAtEndOfMethod(); return; } BasicBlock nextBasicBlock = _basicBlocks[_currentOffset]; if (nextBasicBlock != null) { ImportFallthrough(nextBasicBlock); return; } } }
private void ImportFallthrough(BasicBlock next) { MarkBasicBlock(next); }
private void ImportLdToken(int token) { object obj = _methodIL.GetObject(token); if (obj is TypeDesc) { var type = (TypeDesc)obj; if (type.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, type), "ldtoken"); } else { if (ConstructedEETypeNode.CreationAllowed(type)) { _dependencies.Add(_factory.ConstructedTypeSymbol(type), "ldtoken"); } else { _dependencies.Add(_factory.NecessaryTypeSymbol(type), "ldtoken"); } } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeTypeHandle), "ldtoken"); } else if (obj is MethodDesc) { var method = (MethodDesc)obj; if (method.IsRuntimeDeterminedExactMethod) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodHandle, method), "ldtoken"); } else { _dependencies.Add(_factory.RuntimeMethodHandle(method), "ldtoken"); } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeMethodHandle), "ldtoken"); } else { Debug.Assert(obj is FieldDesc); // First check if this is a ldtoken Field / InitializeArray sequence. BasicBlock nextBasicBlock = _basicBlocks[_currentOffset]; if (nextBasicBlock == null) { if ((ILOpcode)_ilBytes[_currentOffset] == ILOpcode.call) { int methodToken = ReadILTokenAt(_currentOffset + 1); var method = (MethodDesc)_methodIL.GetObject(methodToken); if (IsRuntimeHelpersInitializeArray(method)) { // Codegen expands this and doesn't do the normal ldtoken. return; } } } var field = (FieldDesc)obj; if (field.OwningType.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.FieldHandle, field), "ldtoken"); } else { _dependencies.Add(_factory.RuntimeFieldHandle(field), "ldtoken"); } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeFieldHandle), "ldtoken"); } }
private void ImportLeave(BasicBlock target) { ImportFallthrough(target); }
private void EndImportingBasicBlock(BasicBlock basicBlock) { }