diff options
Diffstat (limited to 'src/ILCompiler.Compiler/src/IL/ILImporter.Scanner.cs')
-rw-r--r-- | src/ILCompiler.Compiler/src/IL/ILImporter.Scanner.cs | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/ILCompiler.Compiler/src/IL/ILImporter.Scanner.cs b/src/ILCompiler.Compiler/src/IL/ILImporter.Scanner.cs index 009dc068b..9468e25f1 100644 --- a/src/ILCompiler.Compiler/src/IL/ILImporter.Scanner.cs +++ b/src/ILCompiler.Compiler/src/IL/ILImporter.Scanner.cs @@ -19,6 +19,7 @@ namespace Internal.IL partial class ILImporter { private readonly MethodIL _methodIL; + private readonly MethodIL _canonMethodIL; private readonly ILScanner _compilation; private readonly ILScanNodeFactory _factory; @@ -84,6 +85,8 @@ namespace Internal.IL _ilBytes = methodIL.GetILBytes(); + _canonMethodIL = methodIL; + // Get the runtime determined method IL so that this works right in shared code // and tokens in shared code resolve to runtime determined types. MethodIL uninstantiatiedMethodIL = methodIL.GetMethodILDefinition(); @@ -266,11 +269,10 @@ namespace Internal.IL private void ImportCall(ILOpcode opcode, int token) { - // Strip runtime determined characteristics off of the method (because that's how RyuJIT operates) + // We get both the canonical and runtime determined form - JitInterface mostly operates + // on the canonical form. var runtimeDeterminedMethod = (MethodDesc)_methodIL.GetObject(token); - MethodDesc method = runtimeDeterminedMethod; - if (runtimeDeterminedMethod.IsRuntimeDeterminedExactMethod) - method = runtimeDeterminedMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); + var method = (MethodDesc)_canonMethodIL.GetObject(token); if (method.IsRawPInvoke()) { @@ -354,10 +356,14 @@ namespace Internal.IL } } - if (method.OwningType.IsDelegate && method.Name == "Invoke") + if (method.OwningType.IsDelegate && method.Name == "Invoke" && + opcode != ILOpcode.ldftn && opcode != ILOpcode.ldvirtftn) { - // TODO: might not want to do this if scanning for reflection. - // This is expanded as an intrinsic, not a function call. + // This call is expanded as an intrinsic; it's not an actual function call. + // Before codegen realizes this is an intrinsic, it might still ask questions about + // the vtable of this virtual method, so let's make sure it's marked in the scanner's + // dependency graph. + _dependencies.Add(_factory.VTable(method.OwningType), reason); return; } |