Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
24bbfbfb
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,发现更多精彩内容 >>
未验证
提交
24bbfbfb
编写于
6月 15, 2022
作者:
T
Tlakaelel Axayakatl Ceja
提交者:
GitHub
6月 16, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add SubstitutionParser that uses XPath Navigator into NativeAOT (#64671)
上级
a7052ac7
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
258 addition
and
166 deletion
+258
-166
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitution.cs
...ools/aot/ILCompiler.Compiler/Compiler/BodySubstitution.cs
+56
-0
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitutionParser.cs
...ot/ILCompiler.Compiler/Compiler/BodySubstitutionParser.cs
+172
-0
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs
.../aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs
+1
-164
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs
.../aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs
+27
-2
src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
.../tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
+2
-0
未找到文件。
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitution.cs
0 → 100644
浏览文件 @
24bbfbfb
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using
System.Diagnostics
;
using
Internal.IL
;
using
Internal.IL.Stubs
;
using
Internal.TypeSystem
;
namespace
ILCompiler
{
internal
sealed
class
BodySubstitution
{
private
object
_value
;
private
readonly
static
object
Throw
=
new
object
();
public
readonly
static
BodySubstitution
ThrowingBody
=
new
BodySubstitution
(
Throw
);
public
readonly
static
BodySubstitution
EmptyBody
=
new
BodySubstitution
(
null
);
public
object
Value
{
get
{
Debug
.
Assert
(
_value
!=
Throw
);
return
_value
;
}
}
private
BodySubstitution
(
object
value
)
=>
_value
=
value
;
public
static
BodySubstitution
Create
(
object
value
)
=>
new
BodySubstitution
(
value
);
public
MethodIL
EmitIL
(
MethodDesc
method
)
{
ILEmitter
emit
=
new
ILEmitter
();
ILCodeStream
codestream
=
emit
.
NewCodeStream
();
if
(
_value
==
Throw
)
{
codestream
.
EmitCallThrowHelper
(
emit
,
method
.
Context
.
GetHelperEntryPoint
(
"ThrowHelpers"
,
"ThrowFeatureBodyRemoved"
));
}
else
if
(
_value
==
null
)
{
Debug
.
Assert
(
method
.
Signature
.
ReturnType
.
IsVoid
);
codestream
.
Emit
(
ILOpcode
.
ret
);
}
else
{
Debug
.
Assert
(
_value
is
int
);
codestream
.
EmitLdc
((
int
)
_value
);
codestream
.
Emit
(
ILOpcode
.
ret
);
}
return
emit
.
Link
(
method
);
}
}
}
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitutionParser.cs
0 → 100644
浏览文件 @
24bbfbfb
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using
System
;
using
System.Collections.Generic
;
using
System.Diagnostics
;
using
System.IO
;
using
System.Reflection.Metadata
;
using
Internal.TypeSystem
;
using
System.Xml.XPath
;
using
System.Globalization
;
using
System.Linq
;
namespace
ILCompiler
{
internal
sealed
class
BodySubstitutionsParser
:
ProcessLinkerXmlBase
{
private
readonly
Dictionary
<
MethodDesc
,
BodySubstitution
>
_methodSubstitutions
;
private
readonly
Dictionary
<
FieldDesc
,
object
>
_fieldSubstitutions
;
private
BodySubstitutionsParser
(
TypeSystemContext
context
,
Stream
documentStream
,
ManifestResource
resource
,
ModuleDesc
resourceAssembly
,
string
xmlDocumentLocation
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
:
base
(
context
,
documentStream
,
resource
,
resourceAssembly
,
xmlDocumentLocation
,
featureSwitchValues
)
{
_methodSubstitutions
=
new
Dictionary
<
MethodDesc
,
BodySubstitution
>();
_fieldSubstitutions
=
new
Dictionary
<
FieldDesc
,
object
>();
}
protected
override
void
ProcessAssembly
(
ModuleDesc
assembly
,
XPathNavigator
nav
,
bool
warnOnUnresolvedTypes
)
{
ProcessTypes
(
assembly
,
nav
,
warnOnUnresolvedTypes
);
}
// protected override TypeDesc? ProcessExportedType(ExportedType exported, ModuleDesc assembly, XPathNavigator nav) => null;
protected
override
bool
ProcessTypePattern
(
string
fullname
,
ModuleDesc
assembly
,
XPathNavigator
nav
)
=>
false
;
protected
override
void
ProcessType
(
TypeDesc
type
,
XPathNavigator
nav
)
{
Debug
.
Assert
(
ShouldProcessElement
(
nav
));
ProcessTypeChildren
(
type
,
nav
);
}
protected
override
void
ProcessMethod
(
TypeDesc
type
,
XPathNavigator
methodNav
,
object
customData
)
{
string
signature
=
GetSignature
(
methodNav
);
if
(
string
.
IsNullOrEmpty
(
signature
))
return
;
MethodDesc
method
=
FindMethod
(
type
,
signature
);
if
(
method
==
null
)
{
// LogWarning(methodNav, DiagnosticId.XmlCouldNotFindMethodOnType, signature, type.GetDisplayName());
return
;
}
string
action
=
GetAttribute
(
methodNav
,
"body"
);
switch
(
action
)
{
case
"remove"
:
_methodSubstitutions
.
Add
(
method
,
BodySubstitution
.
ThrowingBody
);
break
;
case
"stub"
:
BodySubstitution
stubBody
;
if
(
method
.
Signature
.
ReturnType
.
IsVoid
)
stubBody
=
BodySubstitution
.
EmptyBody
;
else
stubBody
=
BodySubstitution
.
Create
(
TryCreateSubstitution
(
method
.
Signature
.
ReturnType
,
GetAttribute
(
methodNav
,
"value"
)));
if
(
stubBody
!=
null
)
{
_methodSubstitutions
[
method
]
=
stubBody
;
}
else
{
// Context.LogWarning ($"Invalid value for '{method.GetDisplayName ()}' stub", 2010, _xmlDocumentLocation);
}
break
;
default
:
//Context.LogWarning($"Unknown body modification '{action}' for '{method.GetDisplayName()}'", 2011, _xmlDocumentLocation);
break
;
}
}
protected
override
void
ProcessField
(
TypeDesc
type
,
XPathNavigator
fieldNav
)
{
string
name
=
GetAttribute
(
fieldNav
,
"name"
);
if
(
string
.
IsNullOrEmpty
(
name
))
return
;
var
field
=
type
.
GetFields
().
FirstOrDefault
(
f
=>
f
.
Name
==
name
);
if
(
field
==
null
)
{
// LogWarning(fieldNav, DiagnosticId.XmlCouldNotFindFieldOnType, name, type.GetDisplayName());
return
;
}
if
(!
field
.
IsStatic
||
field
.
IsLiteral
)
{
// LogWarning(fieldNav, DiagnosticId.XmlSubstitutedFieldNeedsToBeStatic, field.GetDisplayName());
return
;
}
string
value
=
GetAttribute
(
fieldNav
,
"value"
);
if
(
string
.
IsNullOrEmpty
(
value
))
{
//Context.LogWarning($"Missing 'value' attribute for field '{field.GetDisplayName()}'.", 2014, _xmlDocumentLocation);
return
;
}
object
substitution
=
TryCreateSubstitution
(
field
.
FieldType
,
value
);
if
(
substitution
==
null
)
{
//Context.LogWarning($"Invalid value '{value}' for '{field.GetDisplayName()}'.", 2015, _xmlDocumentLocation);
return
;
}
if
(
String
.
Equals
(
GetAttribute
(
fieldNav
,
"initialize"
),
"true"
,
StringComparison
.
InvariantCultureIgnoreCase
))
{
// We would need to also mess with the cctor of the type to set the field to this value:
//
// * Linker will remove all stsfld instructions referencing this field from the cctor
// * It will place an explicit stsfld in front of the last "ret" instruction in the cctor
//
// This approach... has issues.
throw
new
NotSupportedException
();
}
_fieldSubstitutions
[
field
]
=
substitution
;
}
static
MethodDesc
FindMethod
(
TypeDesc
type
,
string
signature
)
{
foreach
(
MethodDesc
meth
in
type
.
GetMethods
())
if
(
signature
==
GetMethodSignature
(
meth
,
includeGenericParameters
:
true
))
return
meth
;
return
null
;
}
private
object
TryCreateSubstitution
(
TypeDesc
type
,
string
value
)
{
switch
(
type
.
UnderlyingType
.
Category
)
{
case
TypeFlags
.
Int32
:
if
(
string
.
IsNullOrEmpty
(
value
))
return
0
;
else
if
(
int
.
TryParse
(
value
,
NumberStyles
.
Integer
,
CultureInfo
.
InvariantCulture
,
out
int
iresult
))
return
iresult
;
break
;
case
TypeFlags
.
Boolean
:
if
(
String
.
IsNullOrEmpty
(
value
))
return
0
;
else
if
(
bool
.
TryParse
(
value
,
out
bool
bvalue
))
return
bvalue
?
1
:
0
;
else
goto
case
TypeFlags
.
Int32
;
default
:
throw
new
NotSupportedException
(
type
.
ToString
());
}
return
null
;
}
public
static
(
Dictionary
<
MethodDesc
,
BodySubstitution
>,
Dictionary
<
FieldDesc
,
object
>)
GetSubstitutions
(
TypeSystemContext
context
,
UnmanagedMemoryStream
documentStream
,
ManifestResource
resource
,
ModuleDesc
resourceAssembly
,
string
xmlDocumentLocation
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
{
var
rdr
=
new
BodySubstitutionsParser
(
context
,
documentStream
,
resource
,
resourceAssembly
,
xmlDocumentLocation
,
featureSwitchValues
);
rdr
.
ProcessXml
(
false
);
return
(
rdr
.
_methodSubstitutions
,
rdr
.
_fieldSubstitutions
);
}
}
}
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs
浏览文件 @
24bbfbfb
...
...
@@ -8,7 +8,6 @@
using
System.Reflection.Metadata
;
using
System.Reflection.PortableExecutable
;
using
System.Xml
;
using
Internal.IL
;
using
Internal.IL.Stubs
;
using
Internal.TypeSystem
;
...
...
@@ -740,172 +739,10 @@ public AssemblyFeatureInfo(EcmaModule module, IReadOnlyDictionary<string, bool>
ms
=
new
UnmanagedMemoryStream
(
reader
.
CurrentPointer
,
length
);
}
(
BodySubstitutions
,
FieldSubstitutions
)
=
SubstitutionsReader
.
GetSubstitutions
(
module
.
Context
,
XmlReader
.
Create
(
ms
),
module
,
featureSwitchValues
);
(
BodySubstitutions
,
FieldSubstitutions
)
=
BodySubstitutionsParser
.
GetSubstitutions
(
module
.
Context
,
ms
,
resource
,
module
,
"name"
,
featureSwitchValues
);
}
}
}
}
private
class
BodySubstitution
{
private
object
_value
;
private
readonly
static
object
Throw
=
new
object
();
public
readonly
static
BodySubstitution
ThrowingBody
=
new
BodySubstitution
(
Throw
);
public
readonly
static
BodySubstitution
EmptyBody
=
new
BodySubstitution
(
null
);
public
object
Value
{
get
{
Debug
.
Assert
(
_value
!=
Throw
);
return
_value
;
}
}
private
BodySubstitution
(
object
value
)
=>
_value
=
value
;
public
static
BodySubstitution
Create
(
object
value
)
=>
new
BodySubstitution
(
value
);
public
MethodIL
EmitIL
(
MethodDesc
method
)
{
ILEmitter
emit
=
new
ILEmitter
();
ILCodeStream
codestream
=
emit
.
NewCodeStream
();
if
(
_value
==
Throw
)
{
codestream
.
EmitCallThrowHelper
(
emit
,
method
.
Context
.
GetHelperEntryPoint
(
"ThrowHelpers"
,
"ThrowFeatureBodyRemoved"
));
}
else
if
(
_value
==
null
)
{
Debug
.
Assert
(
method
.
Signature
.
ReturnType
.
IsVoid
);
codestream
.
Emit
(
ILOpcode
.
ret
);
}
else
{
Debug
.
Assert
(
_value
is
int
);
codestream
.
EmitLdc
((
int
)
_value
);
codestream
.
Emit
(
ILOpcode
.
ret
);
}
return
emit
.
Link
(
method
);
}
}
private
class
SubstitutionsReader
:
ProcessXmlBase
{
private
readonly
Dictionary
<
MethodDesc
,
BodySubstitution
>
_methodSubstitutions
;
private
readonly
Dictionary
<
FieldDesc
,
object
>
_fieldSubstitutions
;
private
SubstitutionsReader
(
TypeSystemContext
context
,
XmlReader
reader
,
ModuleDesc
module
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
:
base
(
context
,
reader
,
module
,
featureSwitchValues
)
{
_methodSubstitutions
=
new
Dictionary
<
MethodDesc
,
BodySubstitution
>();
_fieldSubstitutions
=
new
Dictionary
<
FieldDesc
,
object
>();
}
protected
override
void
ProcessMethod
(
MethodDesc
method
)
{
string
action
=
GetAttribute
(
"body"
);
if
(!
String
.
IsNullOrEmpty
(
action
))
{
switch
(
action
)
{
case
"remove"
:
_methodSubstitutions
.
Add
(
method
,
BodySubstitution
.
ThrowingBody
);
break
;
case
"stub"
:
BodySubstitution
stubBody
;
if
(
method
.
Signature
.
ReturnType
.
IsVoid
)
stubBody
=
BodySubstitution
.
EmptyBody
;
else
stubBody
=
BodySubstitution
.
Create
(
TryCreateSubstitution
(
method
.
Signature
.
ReturnType
,
GetAttribute
(
"value"
)));
if
(
stubBody
!=
null
)
{
_methodSubstitutions
[
method
]
=
stubBody
;
}
else
{
// Context.LogWarning ($"Invalid value for '{method.GetDisplayName ()}' stub", 2010, _xmlDocumentLocation);
}
break
;
default
:
//Context.LogWarning($"Unknown body modification '{action}' for '{method.GetDisplayName()}'", 2011, _xmlDocumentLocation);
break
;
}
}
}
protected
override
void
ProcessField
(
FieldDesc
field
)
{
if
(!
field
.
IsStatic
||
field
.
IsLiteral
)
{
// Context.LogWarning ($"Substituted field '{field.GetDisplayName ()}' needs to be static field.", 2013, _xmlDocumentLocation);
return
;
}
string
value
=
GetAttribute
(
"value"
);
if
(
string
.
IsNullOrEmpty
(
value
))
{
//Context.LogWarning($"Missing 'value' attribute for field '{field.GetDisplayName()}'.", 2014, _xmlDocumentLocation);
return
;
}
object
substitution
=
TryCreateSubstitution
(
field
.
FieldType
,
value
);
if
(
substitution
==
null
)
{
//Context.LogWarning($"Invalid value '{value}' for '{field.GetDisplayName()}'.", 2015, _xmlDocumentLocation);
return
;
}
if
(
String
.
Equals
(
GetAttribute
(
"initialize"
),
"true"
,
StringComparison
.
InvariantCultureIgnoreCase
))
{
// We would need to also mess with the cctor of the type to set the field to this value:
//
// * Linker will remove all stsfld instructions referencing this field from the cctor
// * It will place an explicit stsfld in front of the last "ret" instruction in the cctor
//
// This approach... has issues.
throw
new
NotSupportedException
();
}
_fieldSubstitutions
[
field
]
=
substitution
;
}
private
object
TryCreateSubstitution
(
TypeDesc
type
,
string
value
)
{
switch
(
type
.
UnderlyingType
.
Category
)
{
case
TypeFlags
.
Int32
:
if
(
string
.
IsNullOrEmpty
(
value
))
return
0
;
else
if
(
int
.
TryParse
(
value
,
NumberStyles
.
Integer
,
CultureInfo
.
InvariantCulture
,
out
int
iresult
))
return
iresult
;
break
;
case
TypeFlags
.
Boolean
:
if
(
String
.
IsNullOrEmpty
(
value
))
return
0
;
else
if
(
bool
.
TryParse
(
value
,
out
bool
bvalue
))
return
bvalue
?
1
:
0
;
else
goto
case
TypeFlags
.
Int32
;
default
:
throw
new
NotSupportedException
(
type
.
ToString
());
}
return
null
;
}
public
static
(
Dictionary
<
MethodDesc
,
BodySubstitution
>,
Dictionary
<
FieldDesc
,
object
>)
GetSubstitutions
(
TypeSystemContext
context
,
XmlReader
reader
,
ModuleDesc
module
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
{
var
rdr
=
new
SubstitutionsReader
(
context
,
reader
,
module
,
featureSwitchValues
);
rdr
.
ProcessXml
();
return
(
rdr
.
_methodSubstitutions
,
rdr
.
_fieldSubstitutions
);
}
}
}
}
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs
浏览文件 @
24bbfbfb
...
...
@@ -50,7 +50,7 @@ public abstract class ProcessLinkerXmlBase
private
readonly
IReadOnlyDictionary
<
string
,
bool
>
_featureSwitchValues
;
protected
readonly
TypeSystemContext
_context
;
protected
ProcessLinkerXmlBase
(
TypeSystemContext
context
,
UnmanagedMemory
Stream
documentStream
,
string
xmlDocumentLocation
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
protected
ProcessLinkerXmlBase
(
TypeSystemContext
context
,
Stream
documentStream
,
string
xmlDocumentLocation
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
{
_context
=
context
;
using
(
documentStream
)
...
...
@@ -61,7 +61,7 @@ protected ProcessLinkerXmlBase(TypeSystemContext context, UnmanagedMemoryStream
_featureSwitchValues
=
featureSwitchValues
;
}
protected
ProcessLinkerXmlBase
(
TypeSystemContext
context
,
UnmanagedMemory
Stream
documentStream
,
ManifestResource
resource
,
ModuleDesc
resourceAssembly
,
string
xmlDocumentLocation
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
protected
ProcessLinkerXmlBase
(
TypeSystemContext
context
,
Stream
documentStream
,
ManifestResource
resource
,
ModuleDesc
resourceAssembly
,
string
xmlDocumentLocation
,
IReadOnlyDictionary
<
string
,
bool
>
featureSwitchValues
)
:
this
(
context
,
documentStream
,
xmlDocumentLocation
,
featureSwitchValues
)
{
_owningModule
=
resourceAssembly
??
throw
new
ArgumentNullException
(
nameof
(
resourceAssembly
));
...
...
@@ -489,6 +489,31 @@ protected static string GetAttribute(XPathNavigator nav, string attribute)
return
nav
.
GetAttribute
(
attribute
,
XmlNamespace
);
}
public
static
string
GetMethodSignature
(
MethodDesc
meth
,
bool
includeGenericParameters
)
{
StringBuilder
sb
=
new
StringBuilder
();
CecilTypeNameFormatter
.
Instance
.
AppendName
(
sb
,
meth
.
Signature
.
ReturnType
);
sb
.
Append
(
' '
);
sb
.
Append
(
meth
.
Name
);
if
(
includeGenericParameters
&&
meth
.
HasInstantiation
)
{
sb
.
Append
(
'`'
);
sb
.
Append
(
meth
.
Instantiation
.
Length
);
}
sb
.
Append
(
'('
);
for
(
int
i
=
0
;
i
<
meth
.
Signature
.
Length
;
i
++)
{
if
(
i
>
0
)
sb
.
Append
(
','
);
CecilTypeNameFormatter
.
Instance
.
AppendName
(
sb
,
meth
.
Signature
[
i
]);
}
sb
.
Append
(
')'
);
return
sb
.
ToString
();
}
#if false
protected
MessageOrigin
GetMessageOriginForPosition
(
XPathNavigator
position
)
{
...
...
src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
浏览文件 @
24bbfbfb
...
...
@@ -300,6 +300,8 @@
<Compile Include="Compiler\AnalysisBasedInteropStubManager.cs" />
<Compile Include="Compiler\AnalysisBasedMetadataManager.cs" />
<Compile Include="Compiler\BlockedInternalsBlockingPolicy.cs" />
<Compile Include="Compiler\BodySubstitution.cs" />
<Compile Include="Compiler\BodySubstitutionParser.cs" />
<Compile Include="Compiler\CompilationBuilder.Aot.cs" />
<Compile Include="Compiler\CompilationModuleGroup.Aot.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.Aot.cs" />
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录