【问题标题】:How can I decompile Perl 6?如何反编译 Perl 6?
【发布时间】:2017-07-04 01:17:14
【问题描述】:

我们应该能够以某种方式做到这一点。我想我在哪里见过它,但我找不到我认为我记得的东西。主要是想看看编译器是如何解释代码的。

除了反编译之外,有没有办法在编译时观察它正在做什么?我认为查看它正在尝试做什么以及在哪里可能比尝试理解它的一些错误消息更容易。而且,反编译程序可以消除所有用于阐明实际发生的事情的速记和聪明之处。

【问题讨论】:

    标签: raku


    【解决方案1】:

    我不确定您为什么要这样做。此外,编译结果取决于后端,并且您没有指定后端。无论如何,使用--target= 参数,您可以获得中间结果。最有用的是:

    $ perl6 --target=parse -e 'say "foo"'
    - statementlist: say "foo"
      - statement: 1 matches
        - EXPR: say "foo"
          - args:  "foo"
            - arglist: "foo"
              - EXPR: "foo"
                - value: "foo"
                  - quote: "foo"
                    - nibble: foo
          - longname: say
            - name: say
              - identifier: say
              - morename:  isa NQPArray
            - colonpair:  isa NQPArray
    

    --target=parse 显示解析的即时结果。

    $ perl6 --target=ast -e 'say "foo"'
    - QAST::CompUnit  :W<?> :UNIT<?>
      [pre_deserialize]
        - QAST::Stmt 
          - QAST::Stmt 
            - QAST::Op(loadbytecode)
              - QAST::VM 
                [jvm]
                  - QAST::SVal(ModuleLoader.class) 
                [moar]
                  - QAST::SVal(ModuleLoader.moarvm) 
            - QAST::Op(callmethod load_module) 
    *snip*
    

    --target=ast 显示抽象语法树。

    $ perl6 --target=mast -e 'say "foo"'
    MAST::Frame name<<unit-outer>>, cuuid<2>
      Local types: 0<obj>, 1<obj>, 2<obj>, 3<obj>, 
      Outer: <none>
      Instructions:
      [0] MAST::Op getcode
        MAST::Local index<3>
        MAST::Frame name<<unit>>, cuuid<1>
      [1] MAST::Op capturelex
        MAST::Local index<3>
      [2] MAST::Op getcode
        MAST::Local index<1>
        MAST::Frame name<<unit>>, cuuid<1>
      [3] MAST::Op takeclosure
    *snip*
    

    --target=mast 显示正在生成的实际字节码,在本例中是针对 MoarVM 后端。

    【讨论】:

    • --target=ast 是否显示简化/静态优化之前或之后的状态?是否有更易读的优化后状态形式?我将这个问题理解为询问是否有类似 Perl 5 的 B::Deparse 的东西,它将优化的“字节码”序列化回 Perl 代码,让您了解编译器如何“理解”您编写的内容,以及是否存在例如编译器认为两种语法相同。 (我也很想在 Perl 6 中看到类似的东西)。
    • 例如,它可以很容易地检查在没有空格的打高尔夫球的表达式中如何解决优先级;以及if $a == 1|2 { ... }是否编译成if $a == 1 || $a == 2 { ... };等
    • @smls, --target=ast 显示在静态优化器之前。使用--target=optimize 查看之后。您还可以使用 RAKUDO_OPTIMIZER_DEBUG=1 env var 打印一堆关于优化器正在做什么以及之前、之后和中间的所有步骤的信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 2011-09-11
    • 2010-11-27
    相关资源
    最近更新 更多