Родитель
1b248ccfd7
Коммит
ad22792139
|
@ -62,9 +62,9 @@ namespace Internal.IL.Stubs
|
|||
// Prepend fnptr argument to the signature
|
||||
TypeDesc[] parameterTypes = new TypeDesc[_targetSignature.Length + 1];
|
||||
|
||||
parameterTypes[0] = Context.GetWellKnownType(WellKnownType.IntPtr);
|
||||
for (int i = 0; i < _targetSignature.Length; i++)
|
||||
parameterTypes[i + 1] = _targetSignature[i];
|
||||
parameterTypes[i] = _targetSignature[i];
|
||||
parameterTypes[parameterTypes.Length - 1] = Context.GetWellKnownType(WellKnownType.IntPtr);
|
||||
|
||||
_signature = new MethodSignature(MethodSignatureFlags.Static, 0, _targetSignature.ReturnType, parameterTypes);
|
||||
}
|
||||
|
@ -80,10 +80,17 @@ namespace Internal.IL.Stubs
|
|||
}
|
||||
}
|
||||
|
||||
public override bool IsPInvoke
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override MethodIL EmitIL()
|
||||
{
|
||||
// TODO
|
||||
throw null;
|
||||
return PInvokeILEmitter.EmitIL(this, default(PInvokeILEmitterConfiguration), _interopStateManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,12 +40,10 @@ namespace Internal.IL.Stubs
|
|||
// targetMethod could be either a PInvoke or a DelegateMarshallingMethodThunk
|
||||
// ForwardNativeFunctionWrapper method thunks are marked as PInvokes, so it is
|
||||
// important to check them first here so that we get the right flags.
|
||||
//
|
||||
DelegateMarshallingMethodThunk delegateThunk = _targetMethod as DelegateMarshallingMethodThunk;
|
||||
|
||||
if (delegateThunk != null)
|
||||
//
|
||||
if (_targetMethod is DelegateMarshallingMethodThunk delegateMethod)
|
||||
{
|
||||
_flags = ((EcmaType)delegateThunk.DelegateType).GetDelegatePInvokeFlags();
|
||||
_flags = ((EcmaType)delegateMethod.DelegateType).GetDelegatePInvokeFlags();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -57,9 +55,21 @@ namespace Internal.IL.Stubs
|
|||
|
||||
private static Marshaller[] InitializeMarshallers(MethodDesc targetMethod, InteropStateManager interopStateManager, PInvokeFlags flags)
|
||||
{
|
||||
bool isDelegate = targetMethod is DelegateMarshallingMethodThunk;
|
||||
MethodSignature methodSig = isDelegate ? ((DelegateMarshallingMethodThunk)targetMethod).DelegateSignature : targetMethod.Signature;
|
||||
MarshalDirection direction = isDelegate ? ((DelegateMarshallingMethodThunk)targetMethod).Direction: MarshalDirection.Forward;
|
||||
MarshalDirection direction = MarshalDirection.Forward;
|
||||
MethodSignature methodSig;
|
||||
switch (targetMethod)
|
||||
{
|
||||
case DelegateMarshallingMethodThunk delegateMethod:
|
||||
methodSig = delegateMethod.DelegateSignature;
|
||||
direction = delegateMethod.Direction;
|
||||
break;
|
||||
case CalliMarshallingMethodThunk calliMethod:
|
||||
methodSig = calliMethod.TargetSignature;
|
||||
break;
|
||||
default:
|
||||
methodSig = targetMethod.Signature;
|
||||
break;
|
||||
}
|
||||
int indexOffset = 0;
|
||||
if (!methodSig.IsStatic && direction == MarshalDirection.Forward)
|
||||
{
|
||||
|
@ -282,6 +292,27 @@ namespace Internal.IL.Stubs
|
|||
}
|
||||
}
|
||||
|
||||
private void EmitCalli(PInvokeILCodeStreams ilCodeStreams, CalliMarshallingMethodThunk calliThunk)
|
||||
{
|
||||
ILEmitter emitter = ilCodeStreams.Emitter;
|
||||
ILCodeStream callsiteSetupCodeStream = ilCodeStreams.CallsiteSetupCodeStream;
|
||||
|
||||
TypeDesc nativeReturnType = _marshallers[0].NativeParameterType;
|
||||
TypeDesc[] nativeParameterTypes = new TypeDesc[_marshallers.Length - 1];
|
||||
|
||||
for (int i = 1; i < _marshallers.Length; i++)
|
||||
{
|
||||
nativeParameterTypes[i - 1] = _marshallers[i].NativeParameterType;
|
||||
}
|
||||
|
||||
MethodSignature nativeSig = new MethodSignature(
|
||||
calliThunk.TargetSignature.Flags, 0, nativeReturnType,
|
||||
nativeParameterTypes);
|
||||
|
||||
callsiteSetupCodeStream.EmitLdArg(calliThunk.TargetSignature.Length);
|
||||
callsiteSetupCodeStream.Emit(ILOpcode.calli, emitter.NewToken(nativeSig));
|
||||
}
|
||||
|
||||
private MethodIL EmitIL()
|
||||
{
|
||||
PInvokeILCodeStreams pInvokeILCodeStreams = new PInvokeILCodeStreams();
|
||||
|
@ -295,20 +326,23 @@ namespace Internal.IL.Stubs
|
|||
}
|
||||
|
||||
// make the call
|
||||
DelegateMarshallingMethodThunk delegateMethod = _targetMethod as DelegateMarshallingMethodThunk;
|
||||
if (delegateMethod != null)
|
||||
switch (_targetMethod)
|
||||
{
|
||||
EmitDelegateCall(delegateMethod, pInvokeILCodeStreams);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitPInvokeCall(pInvokeILCodeStreams);
|
||||
case DelegateMarshallingMethodThunk delegateMethod:
|
||||
EmitDelegateCall(delegateMethod, pInvokeILCodeStreams);
|
||||
break;
|
||||
case CalliMarshallingMethodThunk calliMethod:
|
||||
EmitCalli(pInvokeILCodeStreams, calliMethod);
|
||||
break;
|
||||
default:
|
||||
EmitPInvokeCall(pInvokeILCodeStreams);
|
||||
break;
|
||||
}
|
||||
|
||||
_marshallers[0].LoadReturnValue(unmarshallingCodestream);
|
||||
unmarshallingCodestream.Emit(ILOpcode.ret);
|
||||
|
||||
return new PInvokeILStubMethodIL((ILStubMethodIL)emitter.Link(_targetMethod), IsStubRequired());
|
||||
return new PInvokeILStubMethodIL((ILStubMethodIL)emitter.Link(_targetMethod), IsStubRequired());
|
||||
}
|
||||
|
||||
public static MethodIL EmitIL(MethodDesc method,
|
||||
|
@ -342,11 +376,14 @@ namespace Internal.IL.Stubs
|
|||
return true;
|
||||
}
|
||||
|
||||
if (MarshalHelpers.UseLazyResolution(_targetMethod, _importMetadata.Module,
|
||||
_pInvokeILEmitterConfiguration))
|
||||
if (_pInvokeILEmitterConfiguration != null)
|
||||
{
|
||||
return true;
|
||||
if (MarshalHelpers.UseLazyResolution(_targetMethod, _importMetadata.Module, _pInvokeILEmitterConfiguration))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_flags.SetLastError)
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -760,13 +760,8 @@ namespace Internal.JitInterface
|
|||
result |= CorInfoFlag.CORINFO_FLG_SHAREDINST;
|
||||
|
||||
if (method.IsPInvoke)
|
||||
{
|
||||
result |= CorInfoFlag.CORINFO_FLG_PINVOKE;
|
||||
|
||||
// See comment in pInvokeMarshalingRequired
|
||||
result |= CorInfoFlag.CORINFO_FLG_DONT_INLINE;
|
||||
}
|
||||
|
||||
// TODO: Cache inlining hits
|
||||
// Check for an inlining directive.
|
||||
|
||||
|
@ -1037,23 +1032,34 @@ namespace Internal.JitInterface
|
|||
return (CorInfoUnmanagedCallConv)unmanagedCallConv;
|
||||
}
|
||||
|
||||
private bool IsPInvokeStubRequired(MethodDesc method)
|
||||
{
|
||||
return ((Internal.IL.Stubs.PInvokeILStubMethodIL)_compilation.GetMethodIL(method)).IsStubRequired;
|
||||
}
|
||||
|
||||
private bool pInvokeMarshalingRequired(CORINFO_METHOD_STRUCT_* handle, CORINFO_SIG_INFO* callSiteSig)
|
||||
{
|
||||
// TODO: Support for PInvoke calli with marshalling. For now, assume there is no marshalling required.
|
||||
// calli is covered by convertPInvokeCalliToCall
|
||||
if (handle == null)
|
||||
{
|
||||
#if DEBUG
|
||||
MethodSignature methodSignature = (MethodSignature)HandleToObject((IntPtr)callSiteSig->pSig);
|
||||
|
||||
MethodDesc stub = _compilation.PInvokeILProvider.GetCalliStub(methodSignature);
|
||||
Debug.Assert(!IsPInvokeStubRequired(stub));
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MethodDesc method = HandleToObject(handle);
|
||||
|
||||
if (method.IsRawPInvoke())
|
||||
return false;
|
||||
|
||||
// TODO: Ideally, we would just give back the PInvoke stub IL to the JIT and let it inline it, without
|
||||
// checking whether it is required upfront. Unfortunatelly, RyuJIT is not able to generate PInvoke
|
||||
// transitions in inlined methods today (impCheckForPInvokeCall is not called for inlinees and number of other places
|
||||
// depend on it). To get a decent code with this limitation, we mirror CoreCLR behavior: Check
|
||||
// whether PInvoke stub is required here, and disable inlining of PInvoke methods in getMethodAttribsInternal.
|
||||
return ((Internal.IL.Stubs.PInvokeILStubMethodIL)_compilation.GetMethodIL(method)).IsStubRequired;
|
||||
// We could have given back the PInvoke stub IL to the JIT and let it inline it, without
|
||||
// checking whether there is any stub required. Save the JIT from doing the inlining by checking upfront.
|
||||
return IsPInvokeStubRequired(method);
|
||||
}
|
||||
|
||||
private bool satisfiesMethodConstraints(CORINFO_CLASS_STRUCT_* parent, CORINFO_METHOD_STRUCT_* method)
|
||||
|
@ -3450,8 +3456,30 @@ namespace Internal.JitInterface
|
|||
|
||||
private bool convertPInvokeCalliToCall(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool mustConvert)
|
||||
{
|
||||
Debug.Assert(!mustConvert);
|
||||
return false;
|
||||
var methodIL = (MethodIL)HandleToObject((IntPtr)pResolvedToken.tokenScope);
|
||||
if (methodIL.OwningMethod.IsPInvoke)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MethodSignature signature = (MethodSignature)methodIL.GetObject((int)pResolvedToken.token);
|
||||
|
||||
CorInfoCallConv callConv = (CorInfoCallConv)(signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask);
|
||||
if (callConv != CorInfoCallConv.CORINFO_CALLCONV_C &&
|
||||
callConv != CorInfoCallConv.CORINFO_CALLCONV_STDCALL &&
|
||||
callConv != CorInfoCallConv.CORINFO_CALLCONV_THISCALL &&
|
||||
callConv != CorInfoCallConv.CORINFO_CALLCONV_FASTCALL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MethodDesc stub = _compilation.PInvokeILProvider.GetCalliStub(signature);
|
||||
if (!mustConvert && !IsPInvokeStubRequired(stub))
|
||||
return false;
|
||||
|
||||
pResolvedToken.hMethod = ObjectToHandle(stub);
|
||||
pResolvedToken.hClass = ObjectToHandle(stub.OwningType);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void* getMemoryManager()
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
|
||||
<ItemGroup Condition="'$(XunitTestBinBase)' != ''">
|
||||
|
||||
<!-- Pinvoke calli -->
|
||||
<!-- https://github.com/dotnet/corert/issues/5587 -->
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\Invoke\SEH\_il_dbgcatchfinally_ind\_il_dbgcatchfinally_ind.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\Invoke\SEH\_il_relcatchfinally_ind\_il_relcatchfinally_ind.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\CLR-x86-JIT\V2.0-RTM\b487364\b487364\b487364.*" />
|
||||
|
||||
<!-- Infinite generic expansion -->
|
||||
<!-- https://github.com/dotnet/corert/issues/363 -->
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\inlining\bug505642\test\test.*" />
|
||||
|
@ -266,8 +260,6 @@
|
|||
<ExcludeList Include="$(XunitTestBinBase)\Interop\RefCharArray\RefCharArrayTest\RefCharArrayTest.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\Interop\RefInt\RefIntTest\RefIntTest.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\Interop\StringMarshalling\LPTSTR\LPTSTRTest\LPTSTRTest.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Directed\coverage\oldtests\Desktop\callipinvoke_il_d\callipinvoke_il_d.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Directed\coverage\oldtests\Desktop\callipinvoke_il_r\callipinvoke_il_r.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Directed\IL\PInvokeTail\TailWinApi\TailWinApi.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\Interop\ICastable\Castable\Castable.*" />
|
||||
<ExcludeList Include="$(XunitTestBinBase)\JIT\Generics\pinvoke\instance01\instance01.*" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче