Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
3b71d3b0
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,发现更多精彩内容 >>
未验证
提交
3b71d3b0
编写于
11月 15, 2021
作者:
S
Stephen Toub
提交者:
GitHub
11月 15, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Enable SymbolicRegexNode.IsNullableFor fast path to inline (#61605)
上级
2e97ac49
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
83 addition
and
78 deletion
+83
-78
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexNode.cs
...tem/Text/RegularExpressions/Symbolic/SymbolicRegexNode.cs
+83
-78
未找到文件。
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexNode.cs
浏览文件 @
3b71d3b0
...
...
@@ -173,101 +173,106 @@ static void AppendToList(SymbolicRegexNode<S> concat, List<SymbolicRegexNode<S>>
/// <param name="context">kind info for previous and next characters</param>
internal
bool
IsNullableFor
(
uint
context
)
{
if
(
_nullabilityCache
is
null
)
// if _nullabilityCache is null then IsNullable==CanBeNullable
// Observe that if IsNullable==true then CanBeNullable==true.
// but when the node does not start with an anchor
// and IsNullable==false then CanBeNullable==false.
return
_nullabilityCache
is
null
?
_info
.
IsNullable
:
WithCache
(
context
);
// Separated out to enable the common case (no nullability cache) to be inlined
// and to avoid zero-init costs for generally unused state.
bool
WithCache
(
uint
context
)
{
// if _nullabilityCache is null then IsNullable==CanBeNullable
// Observe that if IsNullable==true then CanBeNullable==true.
// but when the node does not start with an anchor
// and IsNullable==false then CanBeNullable==false.
return
_info
.
IsNullable
;
}
if
(!
StackHelper
.
TryEnsureSufficientExecutionStack
())
{
return
StackHelper
.
CallOnEmptyStack
(
IsNullableFor
,
context
);
}
if
(!
StackHelper
.
TryEnsureSufficientExecutionStack
())
{
return
StackHelper
.
CallOnEmptyStack
(
IsNullableFor
,
context
);
}
Debug
.
Assert
(
context
<
CharKind
.
ContextLimit
);
Debug
.
Assert
(
context
<
CharKind
.
ContextLimit
);
// If nullablity has been computed for the given context then return it
byte
b
=
Volatile
.
Read
(
ref
_nullabilityCache
[
context
]);
if
(
b
!=
UndefinedByte
)
{
return
b
==
TrueByte
;
}
// If nullablity has been computed for the given context then return it
byte
b
=
Volatile
.
Read
(
ref
_nullabilityCache
[
context
]);
if
(
b
!=
UndefinedByte
)
{
return
b
==
TrueByte
;
}
// Otherwise compute the nullability recursively for the given context
bool
is_nullable
;
switch
(
_kind
)
{
case
SymbolicRegexKind
.
Loop
:
Debug
.
Assert
(
_left
is
not
null
);
is_nullable
=
_lower
==
0
||
_left
.
IsNullableFor
(
context
);
break
;
// Otherwise compute the nullability recursively for the given context
bool
is_nullable
;
switch
(
_kind
)
{
case
SymbolicRegexKind
.
Loop
:
Debug
.
Assert
(
_left
is
not
null
);
is_nullable
=
_lower
==
0
||
_left
.
IsNullableFor
(
context
);
break
;
case
SymbolicRegexKind
.
Concat
:
Debug
.
Assert
(
_left
is
not
null
&&
_right
is
not
null
);
is_nullable
=
_left
.
IsNullableFor
(
context
)
&&
_right
.
IsNullableFor
(
context
);
break
;
case
SymbolicRegexKind
.
Concat
:
Debug
.
Assert
(
_left
is
not
null
&&
_right
is
not
null
);
is_nullable
=
_left
.
IsNullableFor
(
context
)
&&
_right
.
IsNullableFor
(
context
);
break
;
case
SymbolicRegexKind
.
Or
:
case
SymbolicRegexKind
.
And
:
Debug
.
Assert
(
_alts
is
not
null
);
is_nullable
=
_alts
.
IsNullableFor
(
context
);
break
;
case
SymbolicRegexKind
.
Or
:
case
SymbolicRegexKind
.
And
:
Debug
.
Assert
(
_alts
is
not
null
);
is_nullable
=
_alts
.
IsNullableFor
(
context
);
break
;
case
SymbolicRegexKind
.
Not
:
Debug
.
Assert
(
_left
is
not
null
);
is_nullable
=
!
_left
.
IsNullableFor
(
context
);
break
;
case
SymbolicRegexKind
.
Not
:
Debug
.
Assert
(
_left
is
not
null
);
is_nullable
=
!
_left
.
IsNullableFor
(
context
);
break
;
case
SymbolicRegexKind
.
StartAnchor
:
is_nullable
=
CharKind
.
Prev
(
context
)
==
CharKind
.
StartStop
;
break
;
case
SymbolicRegexKind
.
StartAnchor
:
is_nullable
=
CharKind
.
Prev
(
context
)
==
CharKind
.
StartStop
;
break
;
case
SymbolicRegexKind
.
EndAnchor
:
is_nullable
=
CharKind
.
Next
(
context
)
==
CharKind
.
StartStop
;
break
;
case
SymbolicRegexKind
.
EndAnchor
:
is_nullable
=
CharKind
.
Next
(
context
)
==
CharKind
.
StartStop
;
break
;
case
SymbolicRegexKind
.
BOLAnchor
:
// Beg-Of-Line anchor is nullable when the previous character is Newline or Start
// note: at least one of the bits must be 1, but both could also be 1 in case of very first newline
is_nullable
=
(
CharKind
.
Prev
(
context
)
&
CharKind
.
NewLineS
)
!=
0
;
break
;
case
SymbolicRegexKind
.
BOLAnchor
:
// Beg-Of-Line anchor is nullable when the previous character is Newline or Start
// note: at least one of the bits must be 1, but both could also be 1 in case of very first newline
is_nullable
=
(
CharKind
.
Prev
(
context
)
&
CharKind
.
NewLineS
)
!=
0
;
break
;
case
SymbolicRegexKind
.
EOLAnchor
:
// End-Of-Line anchor is nullable when the next character is Newline or Stop
// note: at least one of the bits must be 1, but both could also be 1 in case of \Z
is_nullable
=
(
CharKind
.
Next
(
context
)
&
CharKind
.
NewLineS
)
!=
0
;
break
;
case
SymbolicRegexKind
.
EOLAnchor
:
// End-Of-Line anchor is nullable when the next character is Newline or Stop
// note: at least one of the bits must be 1, but both could also be 1 in case of \Z
is_nullable
=
(
CharKind
.
Next
(
context
)
&
CharKind
.
NewLineS
)
!=
0
;
break
;
case
SymbolicRegexKind
.
WBAnchor
:
// test that prev char is word letter iff next is not not word letter
is_nullable
=
((
CharKind
.
Prev
(
context
)
&
CharKind
.
WordLetter
)
^
(
CharKind
.
Next
(
context
)
&
CharKind
.
WordLetter
))
!=
0
;
break
;
case
SymbolicRegexKind
.
WBAnchor
:
// test that prev char is word letter iff next is not not word letter
is_nullable
=
((
CharKind
.
Prev
(
context
)
&
CharKind
.
WordLetter
)
^
(
CharKind
.
Next
(
context
)
&
CharKind
.
WordLetter
))
!=
0
;
break
;
case
SymbolicRegexKind
.
NWBAnchor
:
// test that prev char is word letter iff next is word letter
is_nullable
=
((
CharKind
.
Prev
(
context
)
&
CharKind
.
WordLetter
)
^
(
CharKind
.
Next
(
context
)
&
CharKind
.
WordLetter
))
==
0
;
break
;
case
SymbolicRegexKind
.
NWBAnchor
:
// test that prev char is word letter iff next is word letter
is_nullable
=
((
CharKind
.
Prev
(
context
)
&
CharKind
.
WordLetter
)
^
(
CharKind
.
Next
(
context
)
&
CharKind
.
WordLetter
))
==
0
;
break
;
case
SymbolicRegexKind
.
EndAnchorZ
:
// \Z anchor is nullable when the next character is either the last Newline or Stop
// note: CharKind.NewLineS == CharKind.Newline|CharKind.StartStop
is_nullable
=
(
CharKind
.
Next
(
context
)
&
CharKind
.
StartStop
)
!=
0
;
break
;
case
SymbolicRegexKind
.
EndAnchorZ
:
// \Z anchor is nullable when the next character is either the last Newline or Stop
// note: CharKind.NewLineS == CharKind.Newline|CharKind.StartStop
is_nullable
=
(
CharKind
.
Next
(
context
)
&
CharKind
.
StartStop
)
!=
0
;
break
;
default
:
// SymbolicRegexKind.EndAnchorZRev:
// EndAnchorZRev (rev(\Z)) anchor is nullable when the prev character is either the first Newline or Start
// note: CharKind.NewLineS == CharKind.Newline|CharKind.StartStop
Debug
.
Assert
(
_kind
==
SymbolicRegexKind
.
EndAnchorZRev
);
is_nullable
=
(
CharKind
.
Prev
(
context
)
&
CharKind
.
StartStop
)
!=
0
;
break
;
}
default
:
// SymbolicRegexKind.EndAnchorZRev:
// EndAnchorZRev (rev(\Z)) anchor is nullable when the prev character is either the first Newline or Start
// note: CharKind.NewLineS == CharKind.Newline|CharKind.StartStop
Debug
.
Assert
(
_kind
==
SymbolicRegexKind
.
EndAnchorZRev
);
is_nullable
=
(
CharKind
.
Prev
(
context
)
&
CharKind
.
StartStop
)
!=
0
;
break
;
}
Volatile
.
Write
(
ref
_nullabilityCache
[
context
],
is_nullable
?
TrueByte
:
FalseByte
);
Volatile
.
Write
(
ref
_nullabilityCache
[
context
],
is_nullable
?
TrueByte
:
FalseByte
);
return
is_nullable
;
return
is_nullable
;
}
}
/// <summary>Returns true if this is equivalent to .* (the node must be eager also)</summary>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录