Add by-ref, and fix pinned CIL extraction

This commit is contained in:
Tamas Vajk
2021-01-11 21:27:11 +01:00
parent f99bf5755c
commit 2804f5cba9
8 changed files with 83 additions and 37 deletions

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Semmle.Extraction.CIL.Entities
{
/// <summary>
/// Types that are passed by reference are not written directly to trap files. Instead, the annotation is stored on
/// the entity.
/// </summary>
internal sealed class ByRefType : Type
{
public ByRefType(Context cx, Type elementType) : base(cx)
{
ElementType = elementType;
}
public override CilTypeKind Kind => throw new NotImplementedException();
public override Namespace? ContainingNamespace => throw new NotImplementedException();
public override Type? ContainingType => throw new NotImplementedException();
public override int ThisTypeParameterCount => throw new NotImplementedException();
public override IEnumerable<Type> TypeParameters => throw new NotImplementedException();
public override Type Construct(IEnumerable<Type> typeArguments) => throw new NotImplementedException();
public override string Name => $"{ElementType.Name}&";
public Type ElementType { get; }
public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException();
public override void WriteId(TextWriter trapFile, bool inContext)
{
ElementType.WriteId(trapFile, inContext);
trapFile.Write('&');
}
}
}

View File

@@ -121,7 +121,12 @@ namespace Semmle.Extraction.CIL.Entities
for (var l = 0; l < this.locals.Length; ++l)
{
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, localVariableTypes[l]));
var t = localVariableTypes[l];
if (t is ByRefType brt)
{
t = brt.ElementType;
}
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t));
yield return this.locals[l];
}
}

View File

@@ -95,6 +95,10 @@ namespace Semmle.Extraction.CIL.Entities
retType = mt.Unmodified;
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
}
if (retType is ByRefType byRefType)
{
retType = byRefType.ElementType;
}
yield return Tuples.cil_function_pointer_return_type(this, retType);
yield return Tuples.cil_function_pointer_calling_conventions(this, signature.Header.CallingConvention);

View File

@@ -103,6 +103,10 @@ namespace Semmle.Extraction.CIL.Entities
t = mt.Unmodified;
yield return Tuples.cil_custom_modifiers(receiver, mt.Modifier, mt.IsRequired);
}
if (t is ByRefType brt)
{
t = brt.ElementType;
}
yield return cx.Populate(new Parameter(cx, parameterizable, i++, t));
}
}
@@ -115,6 +119,10 @@ namespace Semmle.Extraction.CIL.Entities
t = mt.Unmodified;
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
}
if (t is ByRefType brt)
{
t = brt.ElementType;
}
yield return Tuples.cil_method(this, name, declaringType, t);
}
}

View File

@@ -62,6 +62,10 @@ namespace Semmle.Extraction.CIL.Entities
t = mt.Unmodified;
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
}
if (t is ByRefType brt)
{
t = brt.ElementType;
}
yield return Tuples.cil_property(this, type, name, t);
var accessors = pd.GetAccessors();

View File

@@ -41,8 +41,8 @@ namespace Semmle.Extraction.CIL.Entities
public void WriteId(TextWriter trapFile, GenericContext gc)
{
trapFile.Write("ref ");
elementType.WriteId(trapFile, gc);
trapFile.Write('&');
}
}
@@ -173,25 +173,9 @@ namespace Semmle.Extraction.CIL.Entities
return new Modified(unmodifiedType, modifier, isRequired);
}
private class Pinned : ITypeSignature
{
private readonly ITypeSignature elementType;
public Pinned(ITypeSignature elementType)
{
this.elementType = elementType;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
trapFile.Write("pinned ");
elementType.WriteId(trapFile, gc);
}
}
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetPinnedType(ITypeSignature elementType)
{
return new Pinned(elementType);
return elementType;
}
private class PointerType : ITypeSignature

View File

@@ -20,7 +20,7 @@ namespace Semmle.Extraction.CIL.Entities
cx.Populate(new ArrayType(cx, elementType, shape.Rank));
Type IConstructedTypeProvider<Type>.GetByReferenceType(Type elementType) =>
elementType; // ??
new ByRefType(cx, elementType);
Type ISignatureTypeProvider<Type, GenericContext>.GetFunctionPointerType(MethodSignature<Type> signature) =>
cx.Populate(new FunctionPointerType(cx, signature));
@@ -37,8 +37,7 @@ namespace Semmle.Extraction.CIL.Entities
Type ISignatureTypeProvider<Type, GenericContext>.GetModifiedType(Type modifier, Type unmodifiedType, bool isRequired) =>
new ModifiedType(cx, unmodifiedType, modifier, isRequired);
Type ISignatureTypeProvider<Type, GenericContext>.GetPinnedType(Type elementType) =>
cx.Populate(new PointerType(cx, elementType));
Type ISignatureTypeProvider<Type, GenericContext>.GetPinnedType(Type elementType) => elementType;
Type IConstructedTypeProvider<Type>.GetPointerType(Type elementType) =>
cx.Populate(new PointerType(cx, elementType));

View File

@@ -2,28 +2,28 @@ fnptr
| file://:0:0:0:0 | delegate* managed<!0,Int32> | 1 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<A,B> | 1 | file://:0:0:0:0 | B | 0 |
| file://:0:0:0:0 | delegate* managed<B,A> | 1 | file://:0:0:0:0 | A | 0 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 3 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 2 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Int32*,Void*> | 1 | file://:0:0:0:0 | Void* | 0 |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 3 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | 2 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Int32> | 0 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Void*,Int32*> | 1 | file://:0:0:0:0 | Int32* | 0 |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 3 | file://:0:0:0:0 | void | 2 |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 3 | file://:0:0:0:0 | void | 2 |
params
| file://:0:0:0:0 | delegate* managed<!0,Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<!0,Int32> | fnptr.dll:0:0:0:0 | !0 |
| file://:0:0:0:0 | delegate* managed<A,B> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<A,B> | file://:0:0:0:0 | A |
| file://:0:0:0:0 | delegate* managed<B,A> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<B,A> | file://:0:0:0:0 | B |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* managed<Int32*,Void*> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32*,Void*> | file://:0:0:0:0 | Int32* |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32,Object modreq(OutAttribute),Int32> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32,Object modreq(OutAttribute),Int32> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* managed<Void*,Int32*> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Void*,Int32*> | file://:0:0:0:0 | Void* |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | fnptr.dll:0:0:0:0 | !0 |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | fnptr.dll:0:0:0:0 | !0 |
modifiers
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | System.Runtime.InteropServices.InAttribute | modreq |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq |
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | System.Runtime.InteropServices.OutAttribute | modreq |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.InAttribute | modreq |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.OutAttribute | modreq |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | System.Runtime.InteropServices.OutAttribute | modreq |