Ejemplo n.º 1
0
        public static IsTypeAvailableConditional Create(BasicBlockScanner scanner, ref BasicBlock bb, ref int index)
        {
            if (bb.Instructions.Count == 1)
            {
                throw new OptimizerAssertionException();
            }
            if (index + 1 >= scanner.Method.Body.Instructions.Count)
            {
                throw new OptimizerAssertionException();
            }

            /*
             * `bool MonoLinkerSupport.IsTypeAvailable (string)`
             *
             */

            if (bb.Instructions.Count > 2)
            {
                scanner.BlockList.SplitBlockAt(ref bb, bb.Instructions.Count - 2);
            }

            if (bb.FirstInstruction.OpCode.Code != Code.Ldstr)
            {
                throw new OptimizerAssertionException($"Invalid argument `{bb.FirstInstruction}` used in `MonoLinkerSupport.IsTypeAvailable(string)` conditional.");
            }

            var instance = new IsTypeAvailableConditional(scanner, (string)bb.FirstInstruction.Operand);

            bb.LinkerConditional = instance;

            LookAheadAfterConditional(scanner.BlockList, ref bb, ref index);

            return(instance);
        }
Ejemplo n.º 2
0
        public static IsTypeAvailableConditional Create(BasicBlockScanner scanner, ref BasicBlock bb, ref int index, TypeDefinition type)
        {
            if (index + 1 >= scanner.Method.Body.Instructions.Count)
            {
                throw new OptimizerAssertionException();
            }

            /*
             * `bool MonoLinkerSupport.IsTypeAvailable<T> ()`
             *
             */

            if (bb.Instructions.Count > 1)
            {
                scanner.BlockList.SplitBlockAt(ref bb, bb.Instructions.Count - 1);
            }

            var instance = new IsTypeAvailableConditional(scanner, type);

            bb.LinkerConditional = instance;

            LookAheadAfterConditional(scanner.BlockList, ref bb, ref index);

            return(instance);
        }
Ejemplo n.º 3
0
        public static bool Scan(BasicBlockScanner scanner, ref BasicBlock bb, ref int index, Instruction instruction)
        {
            var reference = (MethodReference)instruction.Operand;

            if (!scanner.Context.TryFastResolve(reference, out var target))
            {
                return(false);
            }

            if (target == null)
            {
                if (reference.DeclaringType.Name.Contains("..."))
                {
                    // FIXME: we don't support Ranges yet.
                    return(false);
                }
                scanner.Context.LogMessage(MessageImportance.High, $"Cannot resolve call target: {CecilHelper.Format (instruction)}");
                if (scanner.Context.Options.IgnoreResolutionErrors)
                {
                    return(false);
                }
                throw new ResolutionException(reference);
            }
            scanner.LogDebug(2, $"    CALL: {target}");

            if (instruction.Operand is GenericInstanceMethod genericInstance)
            {
                if (scanner.Context.IsWeakInstanceOfMethod(target))
                {
                    var conditionalType = genericInstance.GenericArguments [0].Resolve();
                    if (conditionalType == null)
                    {
                        throw new ResolutionException(genericInstance.GenericArguments [0]);
                    }
                    IsWeakInstanceOfConditional.Create(scanner, ref bb, ref index, conditionalType);
                    return(true);
                }
                else if (scanner.Context.AsWeakInstanceOfMethod(target))
                {
                    var conditionalType = genericInstance.GenericArguments [0].Resolve();
                    if (conditionalType == null)
                    {
                        throw new ResolutionException(genericInstance.GenericArguments [0]);
                    }
                    AsWeakInstanceOfConditional.Create(scanner, ref bb, ref index, conditionalType);
                    return(true);
                }
                else if (scanner.Context.IsTypeAvailableMethod(target))
                {
                    var conditionalType = genericInstance.GenericArguments [0].Resolve();
                    if (conditionalType == null)
                    {
                        throw new ResolutionException(genericInstance.GenericArguments [0]);
                    }
                    IsTypeAvailableConditional.Create(scanner, ref bb, ref index, conditionalType);
                    return(true);
                }
                return(false);
            }

            if (scanner.Context.IsFeatureSupportedMethod(target))
            {
                IsFeatureSupportedConditional.Create(scanner, ref bb, ref index);
                return(true);
            }

            if (scanner.Context.IsTypeNameAvailableMethod(target))
            {
                IsTypeAvailableConditional.Create(scanner, ref bb, ref index);
                return(true);
            }


            if (scanner.Context.IsRequireFeatureMethod(target))
            {
                RequireFeatureConditional.Create(scanner, ref bb, ref index);
                return(true);
            }

            if (scanner.Context.TryGetConstantMethod(target, out var constant))
            {
                ConstantCallConditional.Create(scanner, ref bb, ref index, target, constant);
                return(true);
            }

            return(false);
        }