* Native COM clients have not been running since we switched over to SDK projects.
* Stop IL generators from passing GC types to unmanaged function calls.
Update crossgen2 IL stub generators.
Update Dynamic runtime stub generator.
Add assert for GC types in unmanaged function calls.
assert(thisPtr->TypeGet() == TYP_I_IMPL || thisPtr->TypeGet() == TYP_BYREF);
}
- for (GenTreeCall::Use& use : GenTreeCall::UseList(args))
+ for (GenTreeCall::Use& argUse : GenTreeCall::UseList(args))
{
- call->gtFlags |= use.GetNode()->gtFlags & GTF_GLOB_EFFECT;
+ // We should not be passing gc typed args to an unmanaged call.
+ GenTree* arg = argUse.GetNode();
+ if (varTypeIsGC(arg->TypeGet()))
+ {
+ assert(!"*** invalid IL: gc type passed to unmanaged call");
+ }
+
+ call->gtFlags |= arg->gtFlags & GTF_GLOB_EFFECT;
}
}
protected void LoadNativeArg(ILCodeStream stream)
{
if (IsNativeByRef)
+ {
_nativeHome.LoadAddr(stream);
+ stream.Emit(ILOpcode.conv_i);
+ }
else
+ {
_nativeHome.LoadValue(stream);
+ }
}
protected void LoadNativeAddr(ILCodeStream stream)
locDescInnerPtr.MakeByRef();
pcsDispatch->SetStubTargetArgType(&locDescInnerPtr, false);
pcsDispatch->EmitLDLOCA(dwInnerIInspectableLocalNum);
+ pcsDispatch->EmitCONV_I();
}
// pass pointer to the local to the factory method (last argument)
locDescFactoryRetVal.MakeByRef();
pcsDispatch->SetStubTargetArgType(&locDescFactoryRetVal, false);
pcsDispatch->EmitLDLOCA(dwFactoryRetValLocalNum);
+ pcsDispatch->EmitCONV_I();
/*
* UNMARSHAL
}
// Leave the address of the native handle local as the argument to the native method.
- pslILDispatch->EmitLDLOCA(dwNativeHandleLocal);
+ EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwNativeHandleLocal);
// On the output side we only backpropagate the native handle into the output SafeHandle and the output SafeHandle
// to the caller if the native handle actually changed (otherwise we can end up with two SafeHandles wrapping the
pslIL->SetStubTargetArgType(&locDescReturnHandle, false); // extra arg is a byref IntPtr
// 5) [byref] pass address of local as last arg
- pslILDispatch->EmitLDLOCA(dwReturnNativeHandleLocal);
+ EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwReturnNativeHandleLocal);
// We will use cleanup stream to avoid leaking the handle on thread abort.
psl->EmitSetArgMarshalIndex(pslIL, NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL);
}
// Leave the address of the native handle local as the argument to the native method.
- pslILDispatch->EmitLDLOCA(dwNativeHandleLocal);
+ EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwNativeHandleLocal);
if (fin)
{
pslIL->SetStubTargetArgType(&locDescReturnHandle, false); // extra arg is a byref IntPtr
// 5) [byref] pass address of local as last arg
- pslILDispatch->EmitLDLOCA(dwReturnNativeHandleLocal);
+ EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwReturnNativeHandleLocal);
// We will use cleanup stream to avoid leaking the handle on thread abort.
psl->EmitSetArgMarshalIndex(pslIL, NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL);
pslILDispatch->EmitLDLOC(dwNewValueTypeLocal); // we load the local directly
#else
pslIL->SetStubTargetArgType(ELEMENT_TYPE_I); // native type is a pointer
- pslILDispatch->EmitLDLOCA(dwNewValueTypeLocal);
+ EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwNewValueTypeLocal);
#endif
return OVERRIDDEN;
return (0 != (dwMarshalFlags & MARSHAL_FLAG_FIELD));
}
+ static void EmitLoadNativeLocalAddrForByRefDispatch(ILCodeStream* pslILEmit, DWORD local)
+ {
+ WRAPPER_NO_CONTRACT;
+ pslILEmit->EmitLDLOCA(local);
+
+ // Convert the loaded local containing a native address
+ // into a non-GC type for the byref case.
+ pslILEmit->EmitCONV_I();
+ }
+
void EmitLoadManagedValue(ILCodeStream* pslILEmit)
{
WRAPPER_NO_CONTRACT;
m_nativeHome.EmitLoadHomeAddr(pslILEmit);
}
+ void EmitLoadNativeHomeAddrForByRefDispatch(ILCodeStream* pslILEmit)
+ {
+ WRAPPER_NO_CONTRACT;
+ EmitLoadNativeHomeAddr(pslILEmit);
+
+ // Convert the loaded value containing a native address
+ // into a non-GC type for the byref case.
+ pslILEmit->EmitCONV_I();
+ }
+
void EmitStoreManagedValue(ILCodeStream* pslILEmit)
{
WRAPPER_NO_CONTRACT;
void EmitLogNativeArgument(ILCodeStream* pslILEmit, DWORD dwPinnedLocal)
{
+ WRAPPER_NO_CONTRACT;
if (g_pConfig->InteropLogArguments())
{
m_pslNDirect->EmitLogNativeArgument(pslILEmit, dwPinnedLocal);
{
if (IsNativePassedByRef())
{
- EmitLoadNativeHomeAddr(pslILEmit);
+ EmitLoadNativeHomeAddrForByRefDispatch(pslILEmit);
}
else
{
if (IsHresultSwap(dwMarshalFlags) || byrefNativeReturn)
{
EmitReInitNative(m_pcsMarshal);
- EmitLoadNativeHomeAddr(pcsDispatch); // load up the byref native type as an extra arg
+ EmitLoadNativeHomeAddrForByRefDispatch(pcsDispatch); // load up the byref native type as an extra arg
}
else
{
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
+ <OutputType>Exe</OutputType>
<IgnoreCoreCLRTestLibraryDependency>true</IgnoreCoreCLRTestLibraryDependency>
<CLRTestScriptLocalCoreShim>true</CLRTestScriptLocalCoreShim>
<RequiresMockHostPolicy>true</RequiresMockHostPolicy>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
+ <OutputType>Exe</OutputType>
<IgnoreCoreCLRTestLibraryDependency>true</IgnoreCoreCLRTestLibraryDependency>
<CLRTestScriptLocalCoreShim>true</CLRTestScriptLocalCoreShim>
<RequiresMockHostPolicy>true</RequiresMockHostPolicy>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
+ <OutputType>Exe</OutputType>
<IgnoreCoreCLRTestLibraryDependency>true</IgnoreCoreCLRTestLibraryDependency>
<CLRTestScriptLocalCoreShim>true</CLRTestScriptLocalCoreShim>
<RequiresMockHostPolicy>true</RequiresMockHostPolicy>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
+ <OutputType>Exe</OutputType>
<IgnoreCoreCLRTestLibraryDependency>true</IgnoreCoreCLRTestLibraryDependency>
<CLRTestScriptLocalCoreShim>true</CLRTestScriptLocalCoreShim>
<RequiresMockHostPolicy>true</RequiresMockHostPolicy>
EmitLoadArg(method, flagsIndex);
EmitLoadArg(method, dispParamsIndex);
+ method.Emit(OpCodes.Conv_I);
if (returnResult)
{
EmitLoadArg(method, resultIndex);
+ method.Emit(OpCodes.Conv_I);
}
else
{
method.Emit(OpCodes.Ldsfld, typeof(IntPtr).GetField(nameof(IntPtr.Zero)));
}
EmitLoadArg(method, exceptInfoIndex);
+ method.Emit(OpCodes.Conv_I);
EmitLoadArg(method, argErrIndex);
+ method.Emit(OpCodes.Conv_I);
// functionPtr = *(IntPtr*)(*(dispatchPointer) + VTABLE_OFFSET)
int idispatchInvokeOffset = ((int)IDispatchMethodIndices.IDispatch_Invoke) * Marshal.SizeOf(typeof(IntPtr));