diff options
Diffstat (limited to 'src/ILCompiler.Compiler/src/IL')
6 files changed, 127 insertions, 11 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; } diff --git a/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs b/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs index 4aec04036..7ae483dbc 100644 --- a/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs +++ b/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs @@ -29,5 +29,10 @@ namespace Internal.IL { return PInvokeILEmitter.EmitIL(method, _pInvokeILEmitterConfiguration, _interopStateManager); } + + public MethodDesc GetCalliStub(MethodSignature signature) + { + return _interopStateManager.GetPInvokeCalliStub(signature); + } } } diff --git a/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/AppContextInitializerMethod.Sorting.cs b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/AppContextInitializerMethod.Sorting.cs new file mode 100644 index 000000000..67a2b612c --- /dev/null +++ b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/AppContextInitializerMethod.Sorting.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Internal.TypeSystem; + +using Debug = System.Diagnostics.Debug; + +namespace Internal.IL.Stubs.StartupCode +{ + partial class AppContextInitializerMethod + { + protected override int ClassCode => 15749517; + + protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer) + { + // Should be a singleton + Debug.Assert(this == other); + return 0; + } + } +} diff --git a/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/AppContextInitializerMethod.cs b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/AppContextInitializerMethod.cs new file mode 100644 index 000000000..2c2d3a51a --- /dev/null +++ b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/AppContextInitializerMethod.cs @@ -0,0 +1,83 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; + +using Internal.TypeSystem; + +namespace Internal.IL.Stubs.StartupCode +{ + public sealed partial class AppContextInitializerMethod : ILStubMethod + { + private TypeDesc _owningType; + private MethodSignature _signature; + private IReadOnlyCollection<string> _switches; + + public AppContextInitializerMethod(TypeDesc owningType, IEnumerable<string> switches) + { + _owningType = owningType; + _switches = new List<string>(switches); + } + + public override TypeSystemContext Context + { + get + { + return _owningType.Context; + } + } + + public override TypeDesc OwningType + { + get + { + return _owningType; + } + } + + public override string Name + { + get + { + return "SetAppContextSwitches"; + } + } + + public override MethodIL EmitIL() + { + ILEmitter emitter = new ILEmitter(); + ILCodeStream codeStream = emitter.NewCodeStream(); + + MetadataType appContextType = Context.SystemModule.GetKnownType("System", "AppContext"); + MethodDesc setSwitchMethod = appContextType.GetKnownMethod("SetSwitch", null); + ILToken setSwitchToken = emitter.NewToken(setSwitchMethod); + + foreach (string switchName in _switches) + { + codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(switchName)); + codeStream.EmitLdc(1); + codeStream.Emit(ILOpcode.call, setSwitchToken); + } + + codeStream.Emit(ILOpcode.ret); + + return emitter.Link(this); + } + + public override MethodSignature Signature + { + get + { + if (_signature == null) + { + _signature = new MethodSignature(MethodSignatureFlags.Static, 0, + Context.GetWellKnownType(WellKnownType.Void), + TypeDesc.EmptyTypes); + } + + return _signature; + } + } + } +} diff --git a/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/NativeLibraryStartupMethod.cs b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/NativeLibraryStartupMethod.cs index 80bd691a0..b04e5e988 100644 --- a/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/NativeLibraryStartupMethod.cs +++ b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/NativeLibraryStartupMethod.cs @@ -17,9 +17,9 @@ namespace Internal.IL.Stubs.StartupCode { private TypeDesc _owningType; private MethodSignature _signature; - private IList<MethodDesc> _libraryInitializers; + private IReadOnlyCollection<MethodDesc> _libraryInitializers; - public NativeLibraryStartupMethod(TypeDesc owningType, IList<MethodDesc> libraryInitializers) + public NativeLibraryStartupMethod(TypeDesc owningType, IReadOnlyCollection<MethodDesc> libraryInitializers) { _owningType = owningType; _libraryInitializers = libraryInitializers; diff --git a/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/StartupCodeMainMethod.cs b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/StartupCodeMainMethod.cs index f994a1d0a..fd16383f5 100644 --- a/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/StartupCodeMainMethod.cs +++ b/src/ILCompiler.Compiler/src/IL/Stubs/StartupCode/StartupCodeMainMethod.cs @@ -21,9 +21,9 @@ namespace Internal.IL.Stubs.StartupCode private TypeDesc _owningType; private MainMethodWrapper _mainMethod; private MethodSignature _signature; - private IList<MethodDesc> _libraryInitializers; + private IReadOnlyCollection<MethodDesc> _libraryInitializers; - public StartupCodeMainMethod(TypeDesc owningType, MethodDesc mainMethod, IList<MethodDesc> libraryInitializers) + public StartupCodeMainMethod(TypeDesc owningType, MethodDesc mainMethod, IReadOnlyCollection<MethodDesc> libraryInitializers) { _owningType = owningType; _mainMethod = new MainMethodWrapper(owningType, mainMethod); |