Move ownership of p/invoke fixup cells (#4353)
The RVA static fields that represent p/invoke lazy fixup cells are currently owned by the same type that owns the p/invoke. This means that if the owning type has a static constructor, accessing the lazy fixup cell with trigger it. The p/invoke should not trigger a beforefieldinit class constructor though. I'm moving the field to be owned by the global type in the compiler-generated pseudo assembly. It doesn't really matter who owns it.
This commit is contained in:
Родитель
5aca61df65
Коммит
61b3a728cf
|
@ -238,8 +238,8 @@ namespace Internal.IL.Stubs
|
|||
_importMetadata.Module,
|
||||
_pInvokeILEmitterConfiguration))
|
||||
{
|
||||
MetadataType lazyHelperType = _targetMethod.Context.GetHelperType("InteropHelpers");
|
||||
FieldDesc lazyDispatchCell = new PInvokeLazyFixupField(_targetMethod);
|
||||
MetadataType lazyHelperType = context.GetHelperType("InteropHelpers");
|
||||
FieldDesc lazyDispatchCell = _interopStateManager.GetPInvokeLazyFixupField(_targetMethod);
|
||||
|
||||
fnptrLoadStream.Emit(ILOpcode.ldsflda, emitter.NewToken(lazyDispatchCell));
|
||||
fnptrLoadStream.Emit(ILOpcode.call, emitter.NewToken(lazyHelperType
|
||||
|
@ -251,7 +251,7 @@ namespace Internal.IL.Stubs
|
|||
_targetMethod.Signature.Flags | unmanagedCallConv, 0, nativeReturnType,
|
||||
nativeParameterTypes);
|
||||
|
||||
ILLocalVariable vNativeFunctionPointer = emitter.NewLocal(_targetMethod.Context
|
||||
ILLocalVariable vNativeFunctionPointer = emitter.NewLocal(context
|
||||
.GetWellKnownType(WellKnownType.IntPtr));
|
||||
|
||||
fnptrLoadStream.EmitStLoc(vNativeFunctionPointer);
|
||||
|
|
|
@ -15,14 +15,24 @@ namespace Internal.IL.Stubs
|
|||
/// </summary>
|
||||
public sealed partial class PInvokeLazyFixupField : FieldDesc
|
||||
{
|
||||
private MethodDesc _targetMethod;
|
||||
private readonly DefType _owningType;
|
||||
private readonly MethodDesc _targetMethod;
|
||||
|
||||
public PInvokeLazyFixupField(MethodDesc targetMethod)
|
||||
public PInvokeLazyFixupField(DefType owningType, MethodDesc targetMethod)
|
||||
{
|
||||
Debug.Assert(targetMethod.IsPInvoke);
|
||||
_owningType = owningType;
|
||||
_targetMethod = targetMethod;
|
||||
}
|
||||
|
||||
public MethodDesc TargetMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
return _targetMethod;
|
||||
}
|
||||
}
|
||||
|
||||
public PInvokeMetadata PInvokeMetadata
|
||||
{
|
||||
get
|
||||
|
@ -91,7 +101,7 @@ namespace Internal.IL.Stubs
|
|||
{
|
||||
get
|
||||
{
|
||||
return (DefType)_targetMethod.OwningType;
|
||||
return _owningType;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace Internal.TypeSystem
|
|||
private readonly ForwardDelegateCreationStubHashtable _forwardDelegateCreationStubHashtable;
|
||||
private readonly PInvokeDelegateWrapperHashtable _pInvokeDelegateWrapperHashtable;
|
||||
private readonly InlineArrayHashTable _inlineArrayHashtable;
|
||||
private readonly PInvokeLazyFixupFieldHashtable _pInvokeLazyFixupFieldHashtable;
|
||||
|
||||
public InteropStateManager(ModuleDesc generatedAssembly)
|
||||
{
|
||||
|
@ -31,6 +32,7 @@ namespace Internal.TypeSystem
|
|||
_forwardDelegateCreationStubHashtable = new ForwardDelegateCreationStubHashtable(this, _generatedAssembly.GetGlobalModuleType());
|
||||
_pInvokeDelegateWrapperHashtable = new PInvokeDelegateWrapperHashtable(this, _generatedAssembly);
|
||||
_inlineArrayHashtable = new InlineArrayHashTable(this, _generatedAssembly);
|
||||
_pInvokeLazyFixupFieldHashtable = new PInvokeLazyFixupFieldHashtable(_generatedAssembly.GetGlobalModuleType());
|
||||
}
|
||||
//
|
||||
// Delegate Marshalling Stubs
|
||||
|
@ -180,6 +182,10 @@ namespace Internal.TypeSystem
|
|||
return _inlineArrayHashtable.GetOrCreateValue(candidate);
|
||||
}
|
||||
|
||||
public FieldDesc GetPInvokeLazyFixupField(MethodDesc method)
|
||||
{
|
||||
return _pInvokeLazyFixupFieldHashtable.GetOrCreateValue(method);
|
||||
}
|
||||
|
||||
private class NativeStructTypeHashtable : LockFreeReaderHashtable<MetadataType, NativeStructType>
|
||||
{
|
||||
|
@ -433,6 +439,39 @@ namespace Internal.TypeSystem
|
|||
}
|
||||
}
|
||||
|
||||
private class PInvokeLazyFixupFieldHashtable : LockFreeReaderHashtable<MethodDesc, PInvokeLazyFixupField>
|
||||
{
|
||||
protected override int GetKeyHashCode(MethodDesc key)
|
||||
{
|
||||
return key.GetHashCode();
|
||||
}
|
||||
|
||||
protected override int GetValueHashCode(PInvokeLazyFixupField value)
|
||||
{
|
||||
return value.TargetMethod.GetHashCode();
|
||||
}
|
||||
|
||||
protected override bool CompareKeyToValue(MethodDesc key, PInvokeLazyFixupField value)
|
||||
{
|
||||
return key == value.TargetMethod;
|
||||
}
|
||||
|
||||
protected override bool CompareValueToValue(PInvokeLazyFixupField value1, PInvokeLazyFixupField value2)
|
||||
{
|
||||
return value1.TargetMethod == value2.TargetMethod;
|
||||
}
|
||||
|
||||
protected override PInvokeLazyFixupField CreateValueFromKey(MethodDesc key)
|
||||
{
|
||||
return new PInvokeLazyFixupField(_owningType, key);
|
||||
}
|
||||
|
||||
private readonly DefType _owningType;
|
||||
|
||||
public PInvokeLazyFixupFieldHashtable(DefType owningType)
|
||||
{
|
||||
_owningType = owningType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче