示例#1
0
        public override void RewriteConditional(ref BasicBlock block)
        {
            var evaluated = Context.Options.IsFeatureEnabled(Feature);

            Scanner.LogDebug(1, $"REWRITE FEATURE CONDITIONAL: {Feature} {evaluated}");


            if (evaluated)
            {
                BlockList.DeleteBlock(ref block);
                return;
            }

            Context.LogMessage(MessageImportance.High, Environment.NewLine);
            Context.LogMessage(MessageImportance.High, $"Required feature `{Feature}` not available.");
#if FIXME
            Context.Context.Tracer.Dump();
#endif
            Context.LogMessage(MessageImportance.High, Environment.NewLine);

            var pns  = Context.Context.GetType("System.PlatformNotSupportedException");
            var ctor = pns?.Methods.FirstOrDefault(m => m.Name == ".ctor");
            if (ctor == null)
            {
                throw new OptimizerAssertionException($"Can't find `System.PlatformNotSupportedException`.");
            }

            Scanner.LogDebug(1, $"REWRITE FEATURE CONDITIONAL #1: {pns} {ctor}");

            var reference = Method.DeclaringType.Module.ImportReference(ctor);

            BlockList.ReplaceInstructionAt(ref block, 0, Instruction.Create(OpCodes.Newobj, reference));
            BlockList.ReplaceInstructionAt(ref block, 1, Instruction.Create(OpCodes.Throw));
        }
        void RewriteAsIsInst(ref BasicBlock block)
        {
            Scanner.LogDebug(1, $"REWRITE AS ISINST: {block.Count} {block}");

            var reference = Assembly.MainModule.ImportReference(InstanceType);

            int index = 1;

            BlockList.InsertInstructionAt(ref block, index++, Instruction.Create(OpCodes.Isinst, reference));
            BlockList.InsertInstructionAt(ref block, index++, Instruction.Create(OpCodes.Dup));
            BlockList.ReplaceInstructionAt(ref block, index++, Instruction.Create(OpCodes.Stloc, Variable));
            BlockList.RemoveInstructionAt(ref block, index);

            switch (block.BranchType)
            {
            case BranchType.False:
            case BranchType.True:
                break;

            case BranchType.None:
            case BranchType.Return:
                // Convert it into a bool.
                BlockList.InsertInstructionAt(ref block, index++, Instruction.Create(OpCodes.Ldnull));
                BlockList.InsertInstructionAt(ref block, index++, Instruction.Create(OpCodes.Cgt_Un));
                break;

            default:
                throw DebugHelpers.AssertFailUnexpected(Method, block, block.BranchType);
            }
        }