diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-03-12 17:51:59 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-03-12 17:51:59 -0400 |
commit | a6ed67a9f763b5efab58589776e8eaa31a4f2dbc (patch) | |
tree | a9ce5d5f9194aa24ce4f41c2099c18c437441083 /src | |
parent | a12bcf3b7845b7c4541ca7539a4810a81b87e3ce (diff) | |
download | SMAPI-a6ed67a9f763b5efab58589776e8eaa31a4f2dbc.tar.gz SMAPI-a6ed67a9f763b5efab58589776e8eaa31a4f2dbc.tar.bz2 SMAPI-a6ed67a9f763b5efab58589776e8eaa31a4f2dbc.zip |
simplify & optimise instruction searching a bit (#247)
Diffstat (limited to 'src')
-rw-r--r-- | src/StardewModdingAPI/Framework/AssemblyLoader.cs | 41 |
1 files changed, 12 insertions, 29 deletions
diff --git a/src/StardewModdingAPI/Framework/AssemblyLoader.cs b/src/StardewModdingAPI/Framework/AssemblyLoader.cs index dfe0d03f..bc56de01 100644 --- a/src/StardewModdingAPI/Framework/AssemblyLoader.cs +++ b/src/StardewModdingAPI/Framework/AssemblyLoader.cs @@ -191,46 +191,29 @@ namespace StardewModdingAPI.Framework this.ChangeTypeScope(type); } - // throw exception if assembly contains incompatible instructions can't be rewritten - { - IInstructionFinder[] finders = Constants.GetIncompatibilityFinders().ToArray(); - foreach (MethodDefinition method in this.GetMethods(module)) - { - foreach (Instruction instruction in method.Body.Instructions) - { - foreach (IInstructionFinder finder in finders) - { - if (finder.IsMatch(instruction, platformChanged)) - throw new IncompatibleInstructionException(finder.NounPhrase, $"Found an incompatible CIL instruction ({finder.NounPhrase}) while loading assembly {assembly.Name.Name}."); - } - } - } - } - - // rewrite incompatible instructions + // find incompatible instructions bool anyRewritten = false; + IInstructionFinder[] finders = Constants.GetIncompatibilityFinders().ToArray(); IInstructionRewriter[] rewriters = Constants.GetRewriters().ToArray(); foreach (MethodDefinition method in this.GetMethods(module)) { - // skip methods with no rewritable instructions - bool canRewrite = method.Body.Instructions.Any(op => rewriters.Any(rewriter => rewriter.IsMatch(op, platformChanged))); - if (!canRewrite) - continue; - - // rewrite instructions ILProcessor cil = method.Body.GetILProcessor(); - foreach (Instruction op in cil.Body.Instructions.ToArray()) + foreach (Instruction instruction in cil.Body.Instructions.ToArray()) { - IInstructionRewriter rewriter = rewriters.FirstOrDefault(p => p.IsMatch(op, platformChanged)); + // throw exception if instruction is incompatible but can't be rewritten + IInstructionFinder finder = finders.FirstOrDefault(p => p.IsMatch(instruction, platformChanged)); + if (finder != null) + throw new IncompatibleInstructionException(finder.NounPhrase, $"Found an incompatible CIL instruction ({finder.NounPhrase}) while loading assembly {assembly.Name.Name}."); + + // rewrite instruction if needed + IInstructionRewriter rewriter = rewriters.FirstOrDefault(p => p.IsMatch(instruction, platformChanged)); if (rewriter != null) { this.LogOnce(this.Monitor, loggedRewrites, $"Rewriting {assembly.Name.Name} to fix {rewriter.NounPhrase}..."); - rewriter.Rewrite(module, cil, op, this.AssemblyMap); + rewriter.Rewrite(module, cil, instruction, this.AssemblyMap); + anyRewritten = true; } } - - // finalise method - anyRewritten = true; } return platformChanged || anyRewritten; |