【问题标题】:Falling into a catch clause in CIL陷入 CIL 中的 catch 子句
【发布时间】:2017-11-20 22:14:42
【问题描述】:

对于 CIL 中的 try 块,我知道您可以通过在受保护的块中抛出异常来输入 catch 处理程序,例如:

try {
     newobj Exception
     throw
     leave EX1
} catch {
     pop
     ldstr "catchblock"
     call WriteLine
} finally {
     ldstr "finallyblock"
     call WriteLine
}

EX1: 

throw 语句将控制转移到 catch 子句,它 弹出异常。

我的担忧(/好奇)是这是否可以优化以便执行 不是通过投掷,而是通过增加PC“落入”它来捕获块。像这样的:

try {
     newobj Exception
} catch {
     pop
     ldstr "catchblock"
     call WriteLine
} finally {
     ldstr "finallyblock"
     call WriteLine
}

EX1: 

这是有效的 CIL 吗?是否可以在不使用 throw 语句的情况下到达 catch 处理程序块?

【问题讨论】:

    标签: c# cil


    【解决方案1】:

    不,它明显无效。

    在 ECMA-335 分区 I,第 12.4.2.8.1 节:

    过滤器或处理程序的入口只能通过 CLI 异常系统完成;也就是说,控制落入这样的块是无效的。这意味着过滤器和处理程序不能出现在方法的开头,也不能紧跟在任何可能导致控制流失败的指令之后。

    【讨论】:

    • 这个我的理解是不能掉到handler,但是leave指令可以省略,只是那个控制掉到try块的末尾,对吧?跨度>
    • @TitianCernicova-Dragomir 我不确定这可能吗?最后一条指令不能是规范中定义的分支源规则的分支。所以最后一条指令必须是请假。我认为...
    • 非常感谢布赖恩,这是个好消息
    • @Titan,在规范中引用文本下方的几段,是“无法通过失败退出受保护的块、过滤器或处理程序。”
    • 是的,在 CIL 规范中有一整页内容涉及受保护的块 - 我问这个问题有点让我恼火!
    猜你喜欢
    • 1970-01-01
    • 2014-12-22
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2011-12-17
    相关资源
    最近更新 更多