コード例 #1
0
 void AddSZArraySig()
 {
     TypeSig = new SZArraySig(TypeSig);
 }
コード例 #2
0
		void WriteArrayValue(SZArraySig arrayType, IList<CAArgument> args) {
			if (arrayType == null) {
				helper.Error("Array type is null");
				return;
			}

			if (args == null)
				writer.Write(uint.MaxValue);
			else {
				writer.Write((uint)args.Count);
				var arrayElementType = FixTypeSig(arrayType.Next);
				for (int i = 0; i < args.Count; i++)
					WriteValue(arrayElementType, args[i]);
			}
		}
コード例 #3
0
        TypeSig ResolveGenericArgs(TypeSig typeSig)
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            if (ReplaceGenericArg(ref typeSig))
            {
                recursionCounter.Decrement();
                return(typeSig);
            }

            TypeSig result;

            switch (typeSig.ElementType)
            {
            case ElementType.Ptr:
                result = new PtrSig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.ByRef:
                result = new ByRefSig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Var:
                result = new GenericVar((typeSig as GenericVar).Number);
                break;

            case ElementType.ValueArray:
                result = new ValueArraySig(ResolveGenericArgs(typeSig.Next), (typeSig as ValueArraySig).Size);
                break;

            case ElementType.SZArray:
                result = new SZArraySig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.MVar:
                result = new GenericMVar((typeSig as GenericMVar).Number);
                break;

            case ElementType.CModReqd:
                result = new CModReqdSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.CModOpt:
                result = new CModOptSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Module:
                result = new ModuleSig((typeSig as ModuleSig).Index, ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Pinned:
                result = new PinnedSig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.FnPtr:
                throw new NotSupportedException("FnPtr is not supported.");

            case ElementType.Array:
                var arraySig = (ArraySig)typeSig;
                var sizes    = new List <uint>(arraySig.Sizes);
                var lbounds  = new List <int>(arraySig.LowerBounds);
                result = new ArraySig(ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds);
                break;

            case ElementType.GenericInst:
                var gis     = (GenericInstSig)typeSig;
                var genArgs = new List <TypeSig>(gis.GenericArguments.Count);
                foreach (TypeSig ga in gis.GenericArguments)
                {
                    genArgs.Add(ResolveGenericArgs(ga));
                }
                result = new GenericInstSig(ResolveGenericArgs(gis.GenericType) as ClassOrValueTypeSig, genArgs);
                break;

            default:
                result = typeSig;
                break;
            }

            recursionCounter.Decrement();

            return(result);
        }
コード例 #4
0
ファイル: MethodStack.cs プロジェクト: formylover/de4dot-1
        public static TypeSig GetLoadedType(MethodDef method, IList <Instruction> instructions, int instrIndex, int argIndexFromEnd, out bool wasNewobj)
        {
            wasNewobj = false;
            var pushedArgs = MethodStack.GetPushedArgInstructions(instructions, instrIndex);
            var pushInstr  = pushedArgs.GetEnd(argIndexFromEnd);

            if (pushInstr == null)
            {
                return(null);
            }

            TypeSig type;
            Local   local;
            var     corLibTypes = method.DeclaringType.Module.CorLibTypes;

            switch (pushInstr.OpCode.Code)
            {
            case Code.Ldstr:
                type = corLibTypes.String;
                break;

            case Code.Conv_I:
            case Code.Conv_Ovf_I:
            case Code.Conv_Ovf_I_Un:
                type = corLibTypes.IntPtr;
                break;

            case Code.Conv_U:
            case Code.Conv_Ovf_U:
            case Code.Conv_Ovf_U_Un:
                type = corLibTypes.UIntPtr;
                break;

            case Code.Conv_I8:
            case Code.Conv_Ovf_I8:
            case Code.Conv_Ovf_I8_Un:
                type = corLibTypes.Int64;
                break;

            case Code.Conv_U8:
            case Code.Conv_Ovf_U8:
            case Code.Conv_Ovf_U8_Un:
                type = corLibTypes.UInt64;
                break;

            case Code.Conv_R8:
            case Code.Ldc_R8:
            case Code.Ldelem_R8:
            case Code.Ldind_R8:
                type = corLibTypes.Double;
                break;

            case Code.Call:
            case Code.Calli:
            case Code.Callvirt:
                var calledMethod = pushInstr.Operand as IMethod;
                if (calledMethod == null)
                {
                    return(null);
                }
                type = calledMethod.MethodSig.GetRetType();
                break;

            case Code.Newarr:
                var type2 = pushInstr.Operand as ITypeDefOrRef;
                if (type2 == null)
                {
                    return(null);
                }
                type      = new SZArraySig(type2.ToTypeSig());
                wasNewobj = true;
                break;

            case Code.Newobj:
                var ctor = pushInstr.Operand as IMethod;
                if (ctor == null)
                {
                    return(null);
                }
                type      = ctor.DeclaringType.ToTypeSig();
                wasNewobj = true;
                break;

            case Code.Castclass:
            case Code.Isinst:
            case Code.Unbox_Any:
            case Code.Ldelem:
            case Code.Ldobj:
                type = (pushInstr.Operand as ITypeDefOrRef).ToTypeSig();
                break;

            case Code.Ldarg:
            case Code.Ldarg_S:
            case Code.Ldarg_0:
            case Code.Ldarg_1:
            case Code.Ldarg_2:
            case Code.Ldarg_3:
                type = pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType);
                break;

            case Code.Ldloc:
            case Code.Ldloc_S:
            case Code.Ldloc_0:
            case Code.Ldloc_1:
            case Code.Ldloc_2:
            case Code.Ldloc_3:
                local = pushInstr.GetLocal(method.Body.Variables);
                if (local == null)
                {
                    return(null);
                }
                type = local.Type.RemovePinned();
                break;

            case Code.Ldloca:
            case Code.Ldloca_S:
                local = pushInstr.Operand as Local;
                if (local == null)
                {
                    return(null);
                }
                type = CreateByRefType(local.Type.RemovePinned());
                break;

            case Code.Ldarga:
            case Code.Ldarga_S:
                type = CreateByRefType(pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType));
                break;

            case Code.Ldfld:
            case Code.Ldsfld:
                var field = pushInstr.Operand as IField;
                if (field == null || field.FieldSig == null)
                {
                    return(null);
                }
                type = field.FieldSig.GetFieldType();
                break;

            case Code.Ldflda:
            case Code.Ldsflda:
                var field2 = pushInstr.Operand as IField;
                if (field2 == null || field2.FieldSig == null)
                {
                    return(null);
                }
                type = CreateByRefType(field2.FieldSig.GetFieldType());
                break;

            case Code.Ldelema:
            case Code.Unbox:
                type = CreateByRefType(pushInstr.Operand as ITypeDefOrRef);
                break;

            default:
                return(null);
            }

            return(type);
        }
コード例 #5
0
        public static void WriteTo(this TypeSig type, ITextOutput writer, ILNameSyntax syntax, int depth)
        {
            if (depth++ > MAX_CONVERTTYPE_DEPTH)
            {
                return;
            }
            ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;

            if (type is PinnedSig)
            {
                ((PinnedSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.WriteSpace();
                writer.Write("pinned", TextTokenType.Keyword);
            }
            else if (type is ArraySig)
            {
                ArraySig at = (ArraySig)type;
                at.Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('[', TextTokenType.Operator);
                for (int i = 0; i < at.Rank; i++)
                {
                    if (i != 0)
                    {
                        writer.Write(',', TextTokenType.Operator);
                        writer.WriteSpace();
                    }
                    int? lower = i < at.LowerBounds.Count ? at.LowerBounds[i] : (int?)null;
                    uint?size  = i < at.Sizes.Count ? at.Sizes[i] : (uint?)null;
                    if (lower != null)
                    {
                        writer.Write(lower.ToString(), TextTokenType.Number);
                        if (size != null)
                        {
                            writer.Write("..", TextTokenType.Operator);
                            writer.Write((lower.Value + (int)size.Value - 1).ToString(), TextTokenType.Number);
                        }
                        else
                        {
                            writer.Write("...", TextTokenType.Operator);
                        }
                    }
                }
                writer.Write(']', TextTokenType.Operator);
            }
            else if (type is SZArraySig)
            {
                SZArraySig at = (SZArraySig)type;
                at.Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write("[]", TextTokenType.Operator);
            }
            else if (type is GenericSig)
            {
                if (((GenericSig)type).IsMethodVar)
                {
                    writer.Write("!!", TextTokenType.Operator);
                }
                else
                {
                    writer.Write("!", TextTokenType.Operator);
                }
                string typeName = type.TypeName;
                if (string.IsNullOrEmpty(typeName) || typeName[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
                {
                    writer.Write(((GenericSig)type).Number.ToString(), TextTokenType.Number);
                }
                else
                {
                    writer.Write(Escape(typeName), TextTokenHelper.GetTextTokenType(type));
                }
            }
            else if (type is ByRefSig)
            {
                ((ByRefSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('&', TextTokenType.Operator);
            }
            else if (type is PtrSig)
            {
                ((PtrSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('*', TextTokenType.Operator);
            }
            else if (type is GenericInstSig)
            {
                ((GenericInstSig)type).GenericType.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('<', TextTokenType.Operator);
                var arguments = ((GenericInstSig)type).GenericArguments;
                for (int i = 0; i < arguments.Count; i++)
                {
                    if (i > 0)
                    {
                        writer.Write(',', TextTokenType.Operator);
                        writer.WriteSpace();
                    }
                    arguments[i].WriteTo(writer, syntaxForElementTypes, depth);
                }
                writer.Write('>', TextTokenType.Operator);
            }
            else if (type is CModOptSig)
            {
                ((ModifierSig)type).Next.WriteTo(writer, syntax, depth);
                writer.WriteSpace();
                writer.Write("modopt", TextTokenType.Keyword);
                writer.Write('(', TextTokenType.Operator);
                ((ModifierSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName, depth);
                writer.Write(')', TextTokenType.Operator);
                writer.WriteSpace();
            }
            else if (type is CModReqdSig)
            {
                ((ModifierSig)type).Next.WriteTo(writer, syntax, depth);
                writer.WriteSpace();
                writer.Write("modreq", TextTokenType.Keyword);
                writer.Write('(', TextTokenType.Operator);
                ((ModifierSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName, depth);
                writer.Write(')', TextTokenType.Operator);
                writer.WriteSpace();
            }
            else if (type is TypeDefOrRefSig)
            {
                WriteTo(((TypeDefOrRefSig)type).TypeDefOrRef, writer, syntax, depth);
            }
            else if (type is FnPtrSig)
            {
                WriteTo(type.ToTypeDefOrRef(), writer, syntax, depth);
            }
            //TODO: SentinelSig
        }
コード例 #6
0
        TypeSig?ResolveGenericArgs(TypeSig typeSig)
        {
            if (typeSig is null)
            {
                return(null);
            }
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            if (ReplaceGenericArg(ref typeSig))
            {
                recursionCounter.Decrement();
                return(typeSig);
            }

            TypeSig result;

            switch (typeSig.ElementType)
            {
            case ElementType.Ptr:
                result = new PtrSig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.ByRef:
                result = new ByRefSig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Var:
                result = new GenericVar(((GenericVar)typeSig).Number, ((GenericVar)typeSig).OwnerType);
                break;

            case ElementType.ValueArray:
                result = new ValueArraySig(ResolveGenericArgs(typeSig.Next), ((ValueArraySig)typeSig).Size);
                break;

            case ElementType.SZArray:
                result = new SZArraySig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.MVar:
                result = new GenericMVar(((GenericMVar)typeSig).Number, ((GenericMVar)typeSig).OwnerMethod);
                break;

            case ElementType.CModReqd:
                result = new CModReqdSig(((ModifierSig)typeSig).Modifier, ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.CModOpt:
                result = new CModOptSig(((ModifierSig)typeSig).Modifier, ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Module:
                result = new ModuleSig(((ModuleSig)typeSig).Index, ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.Pinned:
                result = new PinnedSig(ResolveGenericArgs(typeSig.Next));
                break;

            case ElementType.FnPtr:
                result = new FnPtrSig(ResolveGenericArgs(((FnPtrSig)typeSig).MethodSig));
                break;

            case ElementType.Array:
                ArraySig    arraySig = (ArraySig)typeSig;
                List <uint> sizes    = new List <uint>(arraySig.Sizes);
                List <int>  lbounds  = new List <int>(arraySig.LowerBounds);
                result = new ArraySig(ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds);
                break;

            case ElementType.GenericInst:
                GenericInstSig  gis     = (GenericInstSig)typeSig;
                List <TypeSig?> genArgs = new List <TypeSig?>(gis.GenericArguments.Count);
                foreach (TypeSig ga in gis.GenericArguments)
                {
                    genArgs.Add(ResolveGenericArgs(ga));
                }
                result = new GenericInstSig(ResolveGenericArgs(gis.GenericType as TypeSig) as ClassOrValueTypeSig, genArgs);
                break;

            default:
                result = typeSig;
                break;
            }

            recursionCounter.Decrement();

            return(result);
        }
コード例 #7
0
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            SZArraySig arrayType = type as SZArraySig;              // TODO: multi-dimensional array

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append("[]");
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef  = type.ToTypeDefOrRef();
                var declType = Decompiler.DnlibExtensions.GetDeclaringType(typeRef);
                if (declType != null)
                {
                    AppendTypeName(b, declType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    b.Append(type.FullName);
                }
            }
        }
コード例 #8
0
        // TODO: multi-dimensional array

        #region Array Initializers
        bool TransformArrayInitializers(List <ILNode> body, ILExpression expr, int pos)
        {
            ILVariable    v, v3;
            ILExpression  newarrExpr;
            ITypeDefOrRef elementType;
            ILExpression  lengthExpr;
            int           arrayLength;

            if (expr.Match(ILCode.Stloc, out v, out newarrExpr) &&
                newarrExpr.Match(ILCode.Newarr, out elementType, out lengthExpr) &&
                lengthExpr.Match(ILCode.Ldc_I4, out arrayLength) &&
                arrayLength > 0)
            {
                ILExpression[] newArr;
                int            initArrayPos;
                if (ForwardScanInitializeArrayRuntimeHelper(body, pos + 1, v, elementType.ToTypeSig(), arrayLength, out newArr, out initArrayPos))
                {
                    var arrayType = new SZArraySig(elementType.ToTypeSig());
                    //arrayType.Dimensions[0] = new ArrayDimension(0, arrayLength);
                    body[pos] = new ILExpression(ILCode.Stloc, v, new ILExpression(ILCode.InitArray, arrayType, newArr));
                    body.RemoveAt(initArrayPos);
                }
                // Put in a limit so that we don't consume too much memory if the code allocates a huge array
                // and populates it extremely sparsly. However, 255 "null" elements in a row actually occur in the Mono C# compiler!
                const int           maxConsecutiveDefaultValueExpressions = 300;
                List <ILExpression> operands     = new List <ILExpression>();
                int numberOfInstructionsToRemove = 0;
                for (int j = pos + 1; j < body.Count; j++)
                {
                    ILExpression nextExpr = body[j] as ILExpression;
                    int          arrayPos;
                    if (nextExpr != null &&
                        nextExpr.Code.IsStoreToArray() &&
                        nextExpr.Arguments[0].Match(ILCode.Ldloc, out v3) &&
                        v == v3 &&
                        nextExpr.Arguments[1].Match(ILCode.Ldc_I4, out arrayPos) &&
                        arrayPos >= operands.Count &&
                        arrayPos <= operands.Count + maxConsecutiveDefaultValueExpressions &&
                        !nextExpr.Arguments[2].ContainsReferenceTo(v3))
                    {
                        while (operands.Count < arrayPos)
                        {
                            operands.Add(new ILExpression(ILCode.DefaultValue, elementType));
                        }
                        operands.Add(nextExpr.Arguments[2]);
                        numberOfInstructionsToRemove++;
                    }
                    else
                    {
                        break;
                    }
                }
                if (operands.Count == arrayLength)
                {
                    var arrayType = new SZArraySig(elementType.ToTypeSig());
                    //arrayType.Dimensions[0] = new ArrayDimension(0, arrayLength);
                    expr.Arguments[0] = new ILExpression(ILCode.InitArray, arrayType.ToTypeDefOrRef(), operands);
                    body.RemoveRange(pos + 1, numberOfInstructionsToRemove);

                    new ILInlining(method).InlineIfPossible(body, ref pos);
                    return(true);
                }
            }
            return(false);
        }
コード例 #9
0
 void AddSZArraySig() => TypeSig = new SZArraySig(TypeSig);
コード例 #10
0
        TypeSig Create2(TypeSig type)
        {
            if (type == null)
            {
                return(type);
            }
            TypeSig result;

            GenericSig varSig;

            switch (type.ElementType)
            {
            case ElementType.Void:
            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.U1:
            case ElementType.I2:
            case ElementType.U2:
            case ElementType.I4:
            case ElementType.U4:
            case ElementType.I8:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.String:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.Object:
                result = type;
                break;

            case ElementType.Ptr:
                result = new PtrSig(Create2(type.Next));
                break;

            case ElementType.ByRef:
                result = new ByRefSig(Create2(type.Next));
                break;

            case ElementType.Array:
                var ary = (ArraySig)type;
                result = new ArraySig(ary.Next, ary.Rank, ary.Sizes, ary.LowerBounds);
                break;

            case ElementType.SZArray:
                result = new SZArraySig(Create2(type.Next));
                break;

            case ElementType.Pinned:
                result = new PinnedSig(Create2(type.Next));
                break;

            case ElementType.ValueType:
            case ElementType.Class:
                result = type;
                break;

            case ElementType.Var:
                varSig = (GenericSig)type;
                if (genericArgs != null && varSig.Number < (uint)genericArgs.Count)
                {
                    result  = genericArgs[(int)varSig.Number];
                    updated = true;
                }
                else
                {
                    result = type;
                }
                break;

            case ElementType.MVar:
                varSig = (GenericSig)type;
                if (genericMethodArgs != null && varSig.Number < (uint)genericMethodArgs.Count)
                {
                    result  = genericMethodArgs[(int)varSig.Number];
                    updated = true;
                }
                else
                {
                    result = type;
                }
                break;

            case ElementType.GenericInst:
                var gis    = (GenericInstSig)type;
                var newGis = new GenericInstSig(Create2(gis.GenericType) as ClassOrValueTypeSig, gis.GenericArguments.Count);
                for (int i = 0; i < gis.GenericArguments.Count; i++)
                {
                    newGis.GenericArguments.Add(Create2(gis.GenericArguments[i]));
                }
                result = newGis;
                break;

            case ElementType.ValueArray:
                result = new ValueArraySig(type.Next, ((ValueArraySig)type).Size);
                break;

            case ElementType.Module:
                result = new ModuleSig(((ModuleSig)type).Index, type.Next);
                break;

            case ElementType.CModReqd:
                result = new CModReqdSig(((ModifierSig)type).Modifier, type.Next);
                break;

            case ElementType.CModOpt:
                result = new CModOptSig(((ModifierSig)type).Modifier, type.Next);
                break;

            case ElementType.FnPtr:
                result = new FnPtrSig(Create(((FnPtrSig)type).MethodSig));
                break;

            case ElementType.End:
            case ElementType.R:
            case ElementType.Sentinel:
            case ElementType.Internal:
            default:
                result = type;
                break;
            }

            return(result);
        }
コード例 #11
0
        private MosaInstruction ResolveInstruction(MethodDef methodDef, CilBody body, int index, GenericArgumentResolver resolver)
        {
            var instruction = body.Instructions[index];
            int?prev        = index == 0 ? null : (int?)body.Instructions[index - 1].Offset;
            int?next        = index == body.Instructions.Count - 1 ? null : (int?)body.Instructions[index + 1].Offset;

            object operand = instruction.Operand;

            // Special case: newarr instructions need to have their operand changed now so that the type is a SZArray
            if (instruction.OpCode == OpCodes.Newarr)
            {
                var typeSig    = resolver.Resolve(((ITypeDefOrRef)instruction.Operand).ToTypeSig());
                var szArraySig = new SZArraySig(typeSig);
                operand = metadata.Loader.GetType(szArraySig);
            }
            else if (instruction.Operand is ITypeDefOrRef)
            {
                operand = ResolveTypeOperand((ITypeDefOrRef)instruction.Operand, resolver);
            }
            else if (instruction.Operand is MemberRef memberRef)
            {
                if (memberRef.IsFieldRef)
                {
                    operand = ResolveFieldOperand(memberRef, resolver);
                }
                else
                {
                    operand = ResolveMethodOperand(memberRef, resolver);
                }
            }
            else if (instruction.Operand is IField)
            {
                operand = ResolveFieldOperand((IField)instruction.Operand, resolver);
            }
            else if (instruction.Operand is IMethod)
            {
                operand = ResolveMethodOperand((IMethod)instruction.Operand, resolver);
            }
            else if (instruction.Operand is Local)
            {
                operand = ((Local)instruction.Operand).Index;
            }
            else if (instruction.Operand is Parameter)
            {
                operand = ((Parameter)instruction.Operand).Index;
            }
            else if (instruction.Operand is Instruction)
            {
                operand = (int)((Instruction)instruction.Operand).Offset;
            }
            else if (instruction.Operand is Instruction[] targets)
            {
                var offsets = new int[targets.Length];
                for (int i = 0; i < offsets.Length; i++)
                {
                    offsets[i] = (int)targets[i].Offset;
                }

                operand = offsets;
            }
            else if (instruction.Operand is string)
            {
                operand = metadata.Cache.GetStringId((string)instruction.Operand);
            }

            ushort code = (ushort)instruction.OpCode.Code;

            if (code > 0xff)                // To match compiler's opcode values
            {
                code = (ushort)(0x100 + (code & 0xff));
            }

            return(new MosaInstruction()
            {
                Offset = (int)instruction.Offset,
                OpCode = code,
                Operand = operand,
                Previous = prev,
                Next = next,
                Document = instruction.SequencePoint?.Document.Url,
                StartLine = instruction.SequencePoint?.StartLine ?? 0,
                StartColumn = instruction.SequencePoint?.StartColumn ?? 0,
                EndLine = instruction.SequencePoint?.EndLine ?? 0,
                EndColumn = instruction.SequencePoint?.EndColumn ?? 0,
            });
        }
コード例 #12
0
        private static void Transform(ILASTExpression expr, ModuleDef module)
        {
            switch (expr.ILCode)
            {
            case Code.Ldlen:
            {
                expr.ILCode = Code.Call;
                var array     = module.CorLibTypes.GetTypeRef("System", "Array");
                var lenSig    = MethodSig.CreateInstance(module.CorLibTypes.Int32);
                var methodRef = new MemberRefUser(module, "get_Length", lenSig, array);
                expr.Operand = methodRef;
                break;
            }

            case Code.Newarr:
            {
                expr.ILCode = Code.Newobj;
                var array   = new SZArraySig(((ITypeDefOrRef)expr.Operand).ToTypeSig()).ToTypeDefOrRef();
                var ctorSig = MethodSig.CreateInstance(module.CorLibTypes.Void, module.CorLibTypes.Int32);
                var ctorRef = new MemberRefUser(module, ".ctor", ctorSig, array);
                expr.Operand = ctorRef;
                break;
            }

            case Code.Ldelema:
            {
                expr.ILCode = Code.Call;
                var elemType = ((ITypeDefOrRef)expr.Operand).ToTypeSig();
                var array    = new SZArraySig(elemType).ToTypeDefOrRef();
                var addrSig  = MethodSig.CreateInstance(new ByRefSig(elemType), module.CorLibTypes.Int32);
                var addrRef  = new MemberRefUser(module, "Address", addrSig, array);
                expr.Operand = addrRef;
                break;
            }

            case Code.Ldelem:
                TransformLDELEM(expr, module, (ITypeDefOrRef)expr.Operand);
                break;

            case Code.Ldelem_I1:
                TransformLDELEM(expr, module, module.CorLibTypes.SByte.ToTypeDefOrRef());
                break;

            case Code.Ldelem_U1:
                TransformLDELEM(expr, module, module.CorLibTypes.Byte.ToTypeDefOrRef());
                break;

            case Code.Ldelem_I2:
                TransformLDELEM(expr, module, module.CorLibTypes.Int16.ToTypeDefOrRef());
                break;

            case Code.Ldelem_U2:
                TransformLDELEM(expr, module, module.CorLibTypes.UInt16.ToTypeDefOrRef());
                break;

            case Code.Ldelem_I4:
                TransformLDELEM(expr, module, module.CorLibTypes.Int32.ToTypeDefOrRef());
                break;

            case Code.Ldelem_U4:
                TransformLDELEM(expr, module, module.CorLibTypes.UInt32.ToTypeDefOrRef());
                break;

            case Code.Ldelem_I8:
                TransformLDELEM(expr, module, module.CorLibTypes.Int64.ToTypeDefOrRef());
                break;

            case Code.Ldelem_R4:
                TransformLDELEM(expr, module, module.CorLibTypes.Single.ToTypeDefOrRef());
                break;

            case Code.Ldelem_R8:
                TransformLDELEM(expr, module, module.CorLibTypes.Double.ToTypeDefOrRef());
                break;

            case Code.Ldelem_I:
                TransformLDELEM(expr, module, module.CorLibTypes.IntPtr.ToTypeDefOrRef());
                break;

            case Code.Ldelem_Ref:
                TransformLDELEM(expr, module, module.CorLibTypes.Object.ToTypeDefOrRef());
                break;
            }
        }
コード例 #13
0
        /// <summary>
        /// Reads the next type
        /// </summary>
        /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns>
        private TypeSig ReadType()
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            uint    num;
            TypeSig nextType, result = null;

            switch ((ElementType)reader.ReadByte())
            {
            case ElementType.Void: result = corLibTypes.Void; break;

            case ElementType.Boolean: result = corLibTypes.Boolean; break;

            case ElementType.Char: result = corLibTypes.Char; break;

            case ElementType.I1: result = corLibTypes.SByte; break;

            case ElementType.U1: result = corLibTypes.Byte; break;

            case ElementType.I2: result = corLibTypes.Int16; break;

            case ElementType.U2: result = corLibTypes.UInt16; break;

            case ElementType.I4: result = corLibTypes.Int32; break;

            case ElementType.U4: result = corLibTypes.UInt32; break;

            case ElementType.I8: result = corLibTypes.Int64; break;

            case ElementType.U8: result = corLibTypes.UInt64; break;

            case ElementType.R4: result = corLibTypes.Single; break;

            case ElementType.R8: result = corLibTypes.Double; break;

            case ElementType.String: result = corLibTypes.String; break;

            case ElementType.TypedByRef: result = corLibTypes.TypedReference; break;

            case ElementType.I: result = corLibTypes.IntPtr; break;

            case ElementType.U: result = corLibTypes.UIntPtr; break;

            case ElementType.Object: result = corLibTypes.Object; break;

            case ElementType.Ptr: result = new PtrSig(ReadType()); break;

            case ElementType.ByRef: result = new ByRefSig(ReadType()); break;

            case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef()); break;

            case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef()); break;

            case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break;

            case ElementType.SZArray: result = new SZArraySig(ReadType()); break;

            case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.Sentinel: result = new SentinelSig(); break;

            case ElementType.Pinned: result = new PinnedSig(ReadType()); break;

            case ElementType.Var:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericVar(num, gpContext.Type);
                break;

            case ElementType.MVar:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericMVar(num, gpContext.Method);
                break;

            case ElementType.ValueArray:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ValueArraySig(nextType, num);
                break;

            case ElementType.Module:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ModuleSig(num, ReadType());
                break;

            case ElementType.GenericInst:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num);
                var args           = genericInstSig.GenericArguments;
                for (uint i = 0; i < num; i++)
                {
                    args.Add(ReadType());
                }
                result = genericInstSig;
                break;

            case ElementType.Array:
                nextType = ReadType();
                uint rank;
                if (!reader.ReadCompressedUInt32(out rank))
                {
                    break;
                }
                if (rank == 0)
                {
                    result = new ArraySig(nextType, rank);
                    break;
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var sizes = new List <uint>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    uint size;
                    if (!reader.ReadCompressedUInt32(out size))
                    {
                        goto exit;
                    }
                    sizes.Add(size);
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var lowerBounds = new List <int>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    int size;
                    if (!reader.ReadCompressedInt32(out size))
                    {
                        goto exit;
                    }
                    lowerBounds.Add(size);
                }
                result = new ArraySig(nextType, rank, sizes, lowerBounds);
                break;

            case ElementType.Internal:
                IntPtr address;
                if (IntPtr.Size == 4)
                {
                    address = new IntPtr(reader.ReadInt32());
                }
                else
                {
                    address = new IntPtr(reader.ReadInt64());
                }
                result = helper.ConvertRTInternalAddress(address);
                break;

            case ElementType.End:
            case ElementType.R:
            default:
                result = null;
                break;
            }
exit:
            recursionCounter.Decrement();
            return(result);
        }