I have looked into the AVM2 Overview document (chapter 4.11, page 33) and found the following about init_scope_depth
:
init_scope_depth
The init_scope_depth field defines the minimum scope depth, relative tomax_scope_depth
, that may be accessed within the method.
max_scope_depth
The max_scope_depth field defines the maximum scope depth that may be accessed within the method. The difference betweenmax_scope_depth
andinit_scope_depth
determines the size of the local scope stack.
I have also came across a citation on the ActionScript 3.0 Bible book about the scope chain, which I believe to be related to init_scope_depth
, and says:
The scope chain, shown in figure 2-1, is an internal device that is created to manage variable scope during function execution.
When a variable is referenced, the Flash Player starts with the most recent function called and checks for variable declarations. If the value isn't found in the most local scope, it moves up one level to the parent function that called the function and checks there. This process continues until the scope chain has been checked all the way up to the global scope.
As shown in the figure, we have the scope order being, from top to bottom:
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
Notice also that the scope chain can have more levels depending on class inheritance.
Now here comes my question:
I've been playing with JPEXS Free Flash Decompiler and RABCDAsm, and I have a class called Global
in a package called Data
. The class does not extend any other classes, but implements one interface. Within this class, there are normal methods and static methods. I have noticed that the static methods have initscopedepth
set to 3 and the normal methods have initscopedepth
set to 4. (Note: these values were set by the compiler, as explained in the AVM2 Overview document, chapter 4.11).
My guess is that the initial scope is:
method -> instance of class -> static instance of class (static variables) -> global
But I am not sure and was wondering if anyone could confirm this.
This also leads me to another question. All the methods code
block, both normal and static, start with the code:
getlocal_0
pushscope
(Note: After these 2 instructions comes whatever instruction the method starts with.)
Could it be because, for normal objects it is pushing the this
onto the scope stack, and for static methods it is pushing the static instance of the class onto the scope stack? If so, why is this necessary?
All right, I believe that I've figured out the answer after some more research and thinking. The key to the puzzle was figuring out two more things.
Object
class by default, as explained in this book.max_scope_stack
values, as explained in chapter 3.3.3 of AVM2 Overview.Therefore, the initial scope depth is:
global -> Object class -> MyClass class (static instance)
And thus, the initial scope depth in this case is 3. I have noticed that functions outside classes have initial scope depth of 1 (the global scope only). And methods that are not static have initial scope depth of 4 (they also have MyClass object).
Because the scope stack is empty when we enter a method, and because register 0 holds the this
object (which is the static instance, in the case of static methods, or the class itself if you prefer), we must push this object onto the scope stack so that we can access all the variables and methods on its scope chain. We have of course the scope of the method itself, which makes the max scope depth to be 4.