Example #1
0
        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;
                }
            }
        }
Example #2
0
 private void ImportFallthrough(BasicBlock next)
 {
     MarkBasicBlock(next);
 }
Example #3
0
        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");
            }
        }
Example #4
0
 private void ImportLeave(BasicBlock target)
 {
     ImportFallthrough(target);
 }
Example #5
0
 private void EndImportingBasicBlock(BasicBlock basicBlock)
 {
 }