首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ActionScript字节码AVM2中的内部深度是多少?为什么是getlocal_0和推广器?

ActionScript字节码AVM2中的内部深度是多少?为什么是getlocal_0和推广器?
EN

Stack Overflow用户
提问于 2020-06-30 19:53:33
回答 1查看 172关注 0票数 2

我查看了AVM2概述文件 (第4.11章,第33页),发现了关于init_scope_depth的如下内容

init_scope_depth init_scope_depth字段定义可在方法中访问的相对于max_scope_depth的最小范围深度。 max_scope_depth max_scope_depth字段定义了可在方法中访问的最大范围深度。max_scope_depthinit_scope_depth之间的差异决定了本地作用域堆栈的大小。

我还在ActionScript 3.0圣经书上遇到了一个关于范围链的引文,我认为它与init_scope_depth有关,并说:

范围链,如图2-1所示,是一个内部设备,用于在函数执行期间管理变量范围。 当引用变量时,Flash以最近调用的函数开始,并检查变量声明。如果在大多数本地作用域中找不到该值,它会将一个级别移到调用该函数的父函数上,并在那里进行检查。此过程一直持续到范围链一直被检查到全局范围为止。

图2-1

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

function scope -> parent function(s) scope (if any) -> instance of the class calling the function -> static instance of the class calling the function -> global scope

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

现在我的问题来了:

我一直在使用和RABCDAsm,在一个名为Data的包中有一个名为Global的类。该类不扩展任何其他类,而是实现一个接口。在这个类中,有普通的方法和静态的方法。我注意到静态方法将initscopedepth设置为3,而普通方法将initscopedepth设置为4。(注意:这些值由编译器设置,如AVM2概述文件第4.11章所解释)。

我的猜测是,最初的范围是:

method -> instance of class -> static instance of class (static variables) -> global

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

这也给我带来了另一个问题。所有方法code块,包括普通方法和静态方法,都从代码开始:

代码语言:javascript
复制
getlocal_0
pushscope

(注意:在这2条指令之后,不管方法是以什么方式开始的。)这是否是因为,对于普通对象,它是将this推到范围堆栈上,而对于静态方法,则是将类的静态实例推到范围堆栈上?若然,为甚麽要这样做呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-05 17:52:37

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

  1. 默认情况下,所有类都扩展Object类,如这本书中所解释的那样。
  2. 在方法条目中,范围堆栈是空的,并且有用于max_scope_stack值的空间,如AVM2概述的第3.3.3章所解释的那样。

因此,初始作用域深度为:global -> Object class -> MyClass class (static instance)

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62665206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档