Actionscript 3 ActionScript字节码AVM2中的initscopedepth是什么?为什么使用getlocal_0和pushscope?

Actionscript 3 ActionScript字节码AVM2中的initscopedepth是什么?为什么使用getlocal_0和pushscope?,actionscript-3,bytecode,avm2,Actionscript 3,Bytecode,Avm2,我查阅了(第4.11章,第33页)并发现了以下关于init\u scope\u depth: init\u scope\u depth init_scope_depth字段定义了可在方法中访问的相对于max_scope_depth的最小作用域深度。 max\u scope\u depth max_scope_depth字段定义可在方法中访问的最大作用域深度。max\u scope\u depth和init\u scope\u depth之间的差异决定了本地作用域堆栈的大小 我在《关于范围链》(a

我查阅了(第4.11章,第33页)并发现了以下关于
init\u scope\u depth

init\u scope\u depth

init_scope_depth字段定义了可在方法中访问的相对于
max_scope_depth
的最小作用域深度。
max\u scope\u depth

max_scope_depth字段定义可在方法中访问的最大作用域深度。
max\u scope\u depth
init\u scope\u depth
之间的差异决定了本地作用域堆栈的大小

我在《关于范围链》(about the scope chain)一文中也看到了一条引文,我认为这条引文与
init\u scope\u depth
有关,并说:

范围链(如图2-1所示)是一个内部设备,用于在函数执行期间管理变量范围。
当引用变量时,Flash Player将从调用的最新函数开始,并检查变量声明。如果在most局部作用域中找不到该值,它将向上移动一级到调用该函数的父函数并在那里进行检查。此过程将继续,直到范围链一直检查到全局范围为止

如图所示,我们的范围顺序是,从上到下:

函数范围->父函数范围(如果有)->调用函数的类的实例->调用函数的类的静态实例->全局范围

还要注意,范围链可以有更多的级别,这取决于类继承

现在我的问题来了:

我一直在玩JPEXS免费Flash反编译程序和RABCDAsm,在一个名为
Data
的包中有一个名为
Global
的类。该类不扩展任何其他类,而是实现一个接口。在这个类中,有普通方法和静态方法。我注意到静态方法将
initscopedepth
设置为3,而常规方法将
initscopedepth
设置为4。(注:这些值由编译器设置,如第4.11章中所述)

我猜最初的范围是:

method->instance of class->static instance of class(静态变量)->global

但我不确定,不知道是否有人能证实这一点

这也引出了另一个问题。所有方法
code
块(正常和静态)都从代码开始:

getlocal_0
pushscope
(注意:在这两条指令之后是方法开始的任何指令。)
这可能是因为,对于普通对象,它将
this
推到作用域堆栈上,而对于静态方法,它将类的静态实例推到作用域堆栈上?如果是这样的话,为什么有必要这样做呢?

好吧,我相信经过进一步的研究和思考,我已经找到了答案。谜题的关键是找出另外两件事

  • 默认情况下,所有类都扩展
    对象
    类,如中所述
  • 在方法输入时,范围堆栈为空,并且有空间容纳
    max\u scope\u stack
    值,如AVM2概述第3.3.3章所述
  • 因此,初始范围深度为:
    global->Object class->MyClass类(静态实例)

    因此,这种情况下的初始范围深度是3。我注意到类之外的函数的初始作用域深度为1(仅全局作用域)。非静态方法的初始作用域深度为4(它们也有MyClass对象)


    因为当我们输入一个方法时,作用域堆栈是空的,并且因为寄存器0保存了
    这个
    对象(对于静态方法,它是静态实例,或者如果您愿意,它是类本身),所以我们必须将这个对象推到作用域堆栈上,以便我们可以访问其作用域链上的所有变量和方法。当然,我们有方法本身的作用域,这使得最大作用域深度为4。

    (1)“我注意到静态方法将
    initscopedepth
    设置为3,而普通方法将
    initscopedepth
    设置为4。”可能JPEXS本身就是这样做的,作为输出特性。可能需要使反编译代码正常工作。(2) 您的
    getlocal\u 0
    pushscope
    是否后跟
    pushnull
    newfunction
    ?我认为这也是JPEXS在设置反编译字节码时所做的标准操作。也许其他人可以解释为什么。。。您需要解决的问题是什么?@VC.One(1)这不是JPEXS的工作。这些值由编译器创建,是方法体字节码的一部分,如AVM2概述文档(第4.11章)所示。RABCDAsm中会出现相同的值。另外,在使用JPEXS“Add trait”选项创建新方法时,它将
    initscopedepth
    设置为1,将
    maxscopedepth
    设置为1,尽管它会自动添加
    getlocal\u 0
    pushscope
    ,因此显然不知道它在做什么。(2) 不。它后面跟着函数开头的任何指令。(3) 问题是我想知道作用域链在这里是如何工作的。好吧,我以为你有一个运行时问题要解决。如果你想了解“作用域链在这里是如何工作的”,那么也可以询问at,因为那里的管理员(@Zwetan)喜欢讨论AVM2的工作原理。你可能会得到一个更快的答案。在这里,它可能对未来的读者没有用处(例如:最终答案如何帮助他人修复一个不工作的应用程序?@VC.One如果我想编辑一个SWF文件,而我没有访问源代码,这个问题很有用。我已经在as3lang.org上提出了这个问题,谢谢。