Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
385fc883
R
runtime
项目概览
dotNET Platform
/
runtime
12 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
385fc883
编写于
2月 17, 2022
作者:
J
Jan Kotas
提交者:
GitHub
2月 17, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix verification of open delegates (#65425)
Fixes #65010
上级
4c2ea7e9
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
157 addition
and
20 deletion
+157
-20
src/coreclr/tools/ILVerification/ILImporter.StackValue.cs
src/coreclr/tools/ILVerification/ILImporter.StackValue.cs
+1
-1
src/coreclr/tools/ILVerification/ILImporter.Verify.cs
src/coreclr/tools/ILVerification/ILImporter.Verify.cs
+88
-16
src/tests/ilverify/ILTests/FtnTests.il
src/tests/ilverify/ILTests/FtnTests.il
+68
-3
未找到文件。
src/coreclr/tools/ILVerification/ILImporter.StackValue.cs
浏览文件 @
385fc883
...
...
@@ -77,7 +77,7 @@ public bool IsMethod
public
bool
IsBoxedValueType
{
get
{
return
Kind
==
StackValueKind
.
ObjRef
&&
Type
.
IsValueType
;
}
get
{
return
Kind
==
StackValueKind
.
ObjRef
&&
Type
!=
null
&&
Type
.
IsValueType
;
}
}
public
StackValue
DereferenceByRef
()
...
...
src/coreclr/tools/ILVerification/ILImporter.Verify.cs
浏览文件 @
385fc883
...
...
@@ -1119,37 +1119,108 @@ void CheckDelegateCreation(StackValue ftn, StackValue obj)
VerificationError
(
VerifierError
.
DelegatePattern
);
}
void
CheckIsDelegateAssignable
(
MethodDesc
ftn
,
TypeDesc
delegateType
)
{
if
(!
IsDelegateAssignable
(
ftn
,
delegateType
))
VerificationError
(
VerifierError
.
DelegateCtor
);
}
bool
IsDelegateAssignable
(
MethodDesc
ftn
,
TypeDesc
delegateType
)
bool
IsDelegateAssignable
(
MethodDesc
targetMethod
,
TypeDesc
delegateType
,
TypeDesc
firstArg
)
{
var
invokeMethod
=
delegateType
.
GetMethod
(
"Invoke"
,
null
);
if
(
invokeMethod
==
null
)
return
false
;
var
ftnSignature
=
ftn
.
Signature
;
var
delegat
eSignature
=
invokeMethod
.
Signature
;
var
targetSignature
=
targetMethod
.
Signature
;
var
invok
eSignature
=
invokeMethod
.
Signature
;
// Compare calling convention ignoring distinction between static and instance
if
((
ftnSignature
.
Flags
&
~
MethodSignatureFlags
.
Static
)
!=
(
delegateSignature
.
Flags
&
~
MethodSignatureFlags
.
Static
))
if
((
targetSignature
.
Flags
&
~
MethodSignatureFlags
.
Static
)
!=
(
invokeSignature
.
Flags
&
~
MethodSignatureFlags
.
Static
))
return
false
;
// Compare return type
if
(!
IsAssignable
(
targetSignature
.
ReturnType
,
invokeSignature
.
ReturnType
))
return
false
;
int
totalTargetArgs
=
targetSignature
.
Length
+
(
targetSignature
.
IsStatic
?
0
:
1
);
// Compare signature parameters
if
(
ftnSignature
.
Length
!=
delegateSignature
.
Length
)
bool
isOpenDelegate
;
if
(
totalTargetArgs
==
invokeSignature
.
Length
)
{
// All arguments provided by invoke, delegate must be open.
isOpenDelegate
=
true
;
}
else
if
(
totalTargetArgs
==
invokeSignature
.
Length
+
1
)
{
// One too few arguments provided by invoke, delegate must be closed.
isOpenDelegate
=
false
;
}
else
{
return
false
;
}
for
(
int
i
=
0
;
i
<
ftnSignature
.
Length
;
i
++)
// An open static delegate which takes no arguments. In that case we're done.
if
(
totalTargetArgs
==
0
)
{
if
(!
IsAssignable
(
delegateSignature
[
i
],
ftnSignature
[
i
]))
Debug
.
Assert
(
isOpenDelegate
);
return
true
;
}
int
consumedArgs
=
0
;
TypeDesc
firstInvokeArg
;
if
(
isOpenDelegate
)
{
// If we're looking at an open delegate but the caller has provided a target it's not a match.
if
(
firstArg
!=
null
)
return
false
;
firstInvokeArg
=
invokeSignature
[
0
];
consumedArgs
++;
}
else
{
// If we're looking at a closed delegate but the caller has not provided a target it's not a match.
if
(
firstArg
==
null
)
return
false
;
// Compare return type
return
IsAssignable
(
ftnSignature
.
ReturnType
,
delegateSignature
.
ReturnType
);
firstInvokeArg
=
firstArg
;
}
TypeDesc
firstTargetArg
;
if
(
targetSignature
.
IsStatic
)
{
// Checked above
Debug
.
Assert
(
targetSignature
.
Length
!=
0
);
// The first argument for a static method is the first fixed arg.
firstTargetArg
=
targetSignature
[
0
];
consumedArgs
--;
}
else
{
// The type of the first argument to an instance method is from the method type.
firstTargetArg
=
targetMethod
.
OwningType
;
// If the delegate is open and the target method is on a value type or primitive then the first argument of the invoke
// method must be a reference to that type. So make the type we got from the reference to a ref. (We don't need to
// do this for the closed instance case because there we got the invocation side type from the first arg passed in, i.e.
// ref was stripped from it implicitly).
if
(
isOpenDelegate
&&
firstTargetArg
.
IsValueType
)
firstTargetArg
=
firstTargetArg
.
MakeByRefType
();
}
if
(!
IsAssignable
(
firstInvokeArg
,
firstTargetArg
))
return
false
;
// We better have same number of remaining args
if
(
invokeSignature
.
Length
-
consumedArgs
!=
targetSignature
.
Length
)
return
false
;
for
(
int
i
=
isOpenDelegate
?
1
:
0
;
i
<
invokeSignature
.
Length
;
i
++)
{
if
(!
IsAssignable
(
invokeSignature
[
i
],
targetSignature
[
i
-
consumedArgs
]))
return
false
;
}
return
true
;
}
ILOpcode
GetOpcodeAt
(
int
instructionOffset
)
...
...
@@ -1525,7 +1596,8 @@ void ImportCall(ILOpcode opcode, int token)
CheckDelegateCreation
(
actualFtn
,
actualObj
);
CheckIsDelegateAssignable
(
actualFtn
.
Method
,
methodType
);
if
(!
IsDelegateAssignable
(
actualFtn
.
Method
,
methodType
,
actualObj
.
Type
))
VerificationError
(
VerifierError
.
DelegateCtor
);
}
else
{
...
...
src/tests/ilverify/ILTests/FtnTests.il
浏览文件 @
385fc883
...
...
@@ -93,6 +93,11 @@
ret
}
.method public hidebysig static void StaticMethodString(string param) cil managed
{
ret
}
.method public hidebysig static int32 StaticIntMethod() cil managed
{
ldc.i4.0
...
...
@@ -167,6 +172,18 @@
.field public static literal valuetype ByteEnum B = uint8(0)
}
.class private auto ansi sealed RefIntDelegate
extends [System.Runtime]System.MulticastDelegate
{
.method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed
{
}
.method public hidebysig newslot virtual instance int32 Invoke(int32& x) runtime managed
{
}
}
.class public auto ansi beforefieldinit FtnTestsType
extends [System.Runtime]System.Object
{
...
...
@@ -264,6 +281,54 @@
ret
}
.method static public hidebysig void LdvirtFtn.InstanceMethodClosed_Valid() cil managed
{
// static void StaticMethodString(this string x)
// var f = new Action("xyz".StaticMethodString);
// f()
ldstr "xyz"
ldftn void TestClass::StaticMethodString(string)
newobj instance void [System.Runtime]System.Action::.ctor(object, native int)
callvirt instance void [System.Runtime]System.Action::Invoke()
ret
}
.method static public hidebysig void LdvirtFtn.InstanceMethodOpen_Valid() cil managed
{
ldnull
ldftn instance class [System.Runtime]System.Type [System.Runtime]System.Object::GetType()
newobj instance void class [System.Runtime]System.Func`2<object, class [System.Runtime]System.Type>::.ctor(object, native int)
ldstr "obj"
callvirt instance !1 class [System.Runtime]System.Func`2<object, class [System.Runtime]System.Type>::Invoke(!0)
pop
ret
}
.method static public hidebysig void LdvirtFtn.InstanceValueTypeMethodOpen_Valid() cil managed
{
.locals init (int32 V_0)
ldnull
ldftn instance int32 [System.Runtime]System.Int32::GetHashCode()
newobj instance void RefIntDelegate::.ctor(object, native int)
ldloca.s V_0
callvirt instance int32 RefIntDelegate::Invoke(int32&)
pop
ret
}
.method static public hidebysig void LdvirtFtn.InstanceValueTypeMethodOpenObjRef_Invalid_DelegateCtor() cil managed
{
ldnull
ldftn instance int32 [System.Runtime]System.Int32::GetHashCode()
newobj instance void class [System.Runtime]System.Func`2<int32, int32>::.ctor(object, native int)
ldc.i4.0
callvirt instance !1 class [System.Runtime]System.Func`2<int32, int32>::Invoke(!0)
pop
ret
}
.method static public hidebysig void LdvirtFtn.StaticMethod_Invalid_LdvirtftnOnStatic() cil managed
{
ldnull
...
...
@@ -274,7 +339,7 @@
ret
}
.method static public hidebysig void LdvirtFtn.ValueTypeNoBox_Invalid_StackObjRef.StackUnexpected.StackUnexpected.DelegateCtorSigO(int32 i) cil managed
.method static public hidebysig void LdvirtFtn.ValueTypeNoBox_Invalid_StackObjRef.StackUnexpected.StackUnexpected.DelegateCtorSigO
.DelegateCtor
(int32 i) cil managed
{
// (int i)
// var f = new System.Func<int, int>(i.CompareTo);
...
...
@@ -290,7 +355,7 @@
ret
}
.method static public hidebysig void LdvirtFtn.ValueTypeWrongBox_Invalid_StackUnexpected.DelegateCtorSigO.DelegatePattern(int32 i) cil managed
.method static public hidebysig void LdvirtFtn.ValueTypeWrongBox_Invalid_StackUnexpected.DelegateCtorSigO.DelegatePattern
.DelegateCtor
(int32 i) cil managed
{
// (int i)
// var f = new System.Func<int, int>(i.CompareTo);
...
...
@@ -307,7 +372,7 @@
ret
}
.method static public hidebysig void LdvirtFtn.ObjectForTestClassInstance_Invalid_StackUnexpected(object c) cil managed
.method static public hidebysig void LdvirtFtn.ObjectForTestClassInstance_Invalid_StackUnexpected
.DelegateCtor
(object c) cil managed
{
// (object c)
// var a = new System.Action(c.InstanceMethod);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录