什么是Perl中的`null vK`?
使用Perl,我有两个类似的语法,
if ($a && $b) { exit() } do { exit() } if ($a && $b) 我相信这些应该是同一个东西,但是最上面的一个创建了一个null vK操作码, <1> null vK*/1 ->- null vK的意义是什么?它有什么作用? $perl -MO=Concise -e'if ($a && $b) { exit() }' 8 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 - <1> null vK/1 ->8 6 <|> and(other->7) vK/1 ->8 - <1> null sK/1 ->6 4 <|> and(other->5) sK/1 ->8 - <1> ex-rv2sv sK/1 ->4 3 <#> gvsv[*a] s ->4 - <1> ex-rv2sv sK/1 ->- 5 <#> gvsv[*b] s ->6 - <@> scope vK ->- - <;> ex-nextstate(main 3 -e:1) v ->7 7 <0> exit v* ->8 -e syntax OK 以下是经文, $perl -MO=Concise -e'do { exit() } if ($a && $b)' 8 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 - <1> null vK/1 ->8 6 <|> and(other->7) vK/1 ->8 - <1> null sKP/1 ->6 4 <|> and(other->5) sK/1 ->8 - <1> ex-rv2sv sK/1 ->4 3 <#> gvsv[*a] s ->4 - <1> ex-rv2sv sK/1 ->- 5 <#> gvsv[*b] s ->6 - <1> null vK*/1 ->- - <@> scope vK ->- - <;> ex-nextstate(main 2 -e:1) v ->7 7 <0> exit v* ->8 解决方法
该行开头的“ – ”表示操作不会被执行,也可以使用perl -MO = Concise,-exec来查看.
也就是说,B :: Concise输出中的null vK …或null sK …操作码并不意味着某些操作已经被优化掉了. B :: Concise上的perldoc清楚地表明这种优化由输出中的ex表示:
例如: > perl -MO=Concise -e "$a" 4 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 - **<1> ex-rv2sv vK/1 ->4** 3 <#> gvsv[*a] s ->4 那么这些空值是什么呢? 它们是来自Perl用于解析代码的yacc语法的真正空值,并且它们从一开始就不打算执行. 在你的情况下,多余的null vk直接来自以下的BLOCK语法规则(perly.y): termdo : DO term %prec UNIOP /* do $filename */ { $$= dofile($2,$1);} | DO block %prec '(' /* do { code */ { $$= newUNOP(OP_NULL,OPf_SPECIAL,op_scope($2));} ; 我们可以在这里看到它: >perl -MO=Concise -e "do{}" 4 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 2 -e:1) v:{ ->3 - <1> null vK*/1 ->4 - <@> scope vK ->- 3 <0> stub v ->4 在其他情况下,空值来自yacc操作. 以下是解析布尔表达式产生的null操作示例: >perl -MO=Concise -e "$a||$b" 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 - <1> null vK/1 ->6 4 <|> or(other->5) vK/1 ->6 - <1> ex-rv2sv sK/1 ->4 3 <#> gvsv[*a] s ->4 - <1> ex-rv2sv vK/1 ->- 5 <#> gvsv[*b] s ->6 为什么这里为空?另一个片段有助于说清楚: >perl -MO=Concise -e "!$a&&!$b" 7 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 6 <1> not vK/1 ->7 4 <|> or(other->5) sK/1 ->6 - <1> ex-not sK/1 ->4 - <1> ex-rv2sv sK/1 ->- 3 <#> gvsv[*a] s ->4 - <1> ex-not sK/1 ->6 - <1> ex-rv2sv sK/1 ->- 5 <#> gvsv[*b] s ->6 似乎null vK已经不是vK. 总结一下:由B :: Concise输出中指示的NULL操作码由优化器生成,而由null指示的NULL操作码来自语法解析器.它们都不会被执行,也不会带来任何性能损失. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |