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); } }