What is initscopedepth in ActionScript bytecode AVM2? Why getlocal_0 and pushscope? - actionscript-3

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 to max_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 between max_scope_depth and init_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.
Figure2-1
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.
All classes extend the Object class by default, as explained in this book.
On method entry, the scope stack is empty and has room for 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.

Related

Why things are so different in a driver class ("static void main") and a class definition?

I know some of the terms I use are confusing. To clarify, a driver class is basically one built on a class definition (starting with public class...) but is a method itself with the header public static void main (String args[]).
The point of this post is to resolve my serious confusion. (I am a beginner in programming)
to me, since a driver class is a method, all it does is to implement itself. But things kinda turn out to be the opposite . For example:
to implement a constructor in a driver class, you simply put down the constructor heading, like public Rectangle(), with its name being the same as that of the class. but in a class definition, to creat a object/ implement a constructor, you also have to write down happen inside that constructor, so you use the expression "type name = new type name ()".
PS: I might have used some terms wrongly, correct me thanks. Or some concept
I'll try to answer this the best way that I can.
Let's look at each of the keywords in a "driver class method" and determine the meaning.
public - this method is publicly callable by a class outside of it
static - this method is callable WITHOUT an instance of the class. In Java, look at the Math class. You don't need to instantiate an instance of the Math class to use the sqrt function (Math m = New Math(); m.sqrt(25);), you can just use Math.sqrt(25).
void - this method returns nothing
main - name of the method
Now that we have that cleared up, let's ask ourselves why these things have to be here for a "driver class"
The Virtual Machine (the program that runs your custom programs) is hard coded to look for a method named main that is public and can also be called WITHOUT CREATING AN INSTANCE OF YOUR CLASS.
So this means that when your program first runs, there is no instance of it.
To counter this, you can either create all of your methods and properties as static (generally considered bad practice) OR you can create an instance of your own class inside of it's own entry method, and begin to call the non-static methods and properties that belong to the instance.
I hope this makes sense.

Which objects to make global, which to make local?

To avoid the moderators who don't like general questions, this is a Visio VBA one but I didn't want to include that in the title as it's a bit niche, and I guess the answer might be generic :-)
My code has the following variables:
Public gappVisio As Visio.Application
Public gdocFile As Visio.Document
Public gpagDiagram As Visio.Page
For those unfamilar with Visio, you create an application object, open the document, then set a reference to a page in the document where you can actually do some drawing.
All vars are global, but actually gdocFile is only used in my initialisation routine.
So my question is, do I need gdocFile as global, or can I just make it local?
I suppose I was worried that if it was local when it went out of scope it might tidy up the Document object, but I still need the page of the document?
Does that make sense?
Don't make a variable or object global unless you absolutely have to, which is almost never. Pass object references as parameters to those procedures that need them -- and only to those. Anything you need from the object before it "runs out of scope", as you say, should be passed to the calling procedure as Function return value (or, more obscurely hence less preferably, Sub ByRef parameter value).
When you say an object is out of scope, it's actually the reference to that object that is out of scope. The object still exists unaltered in memory.
Generally, global is bad and leads to difficult-to-maintain code, but exceptions could be things like universal constants, e.g.
Public Const PI As Double = 3.14159265358979
It's fine to have that as global.
In your case, the document lifetime is controlled by Visio application, the doc will not get cleaned up, no matter how many variables which refer to it you create, or in which scopes they are (global or local). Means, all reference counting (scoping) rules are simply ignored by Visio for documents in fact - the doc is not destroyed, even if there are no more references to it from your code.
You can tell Visio to close the document using document.close. After that call, any attempt to use document's (or page's) methods or properties using any of doc/page variables referring this document/page in this document will result in exception.
A doc may be closed by user. In this case all variables referring to it (or objects inside of it, such as pages or shapes) will become invalid.

AS3 Prototypes - are they just static variables?

A reference to the prototype object of a class or function object. The
prototype property is automatically created and attached to any class
or function object that you create. This property is static in that it
is specific to the class or function that you create. For example, if
you create a class, the value of the prototype property is shared by
all instances of the class and is accessible only as a class property.
Instances of your class cannot directly access the prototype property.
A class’s prototype object is a special instance of that class that
provides a mechanism for sharing state across all instances of a
class. At run time, when a property is not found on a class instance,
the delegate, which is the class prototype object, is checked for that
property. If the prototype object does not contain the property, the
process continues with the prototype object’s delegate checking in
consecutively higher levels in the hierarchy until Flash Player or the
Adobe Integrated Runtime finds the property.
Note: In ActionScript 3.0, prototype inheritance is not the primary
mechanism for inheritance. Class inheritance, which drives the
inheritance of fixed properties in class definitions, is the primary
inheritance mechanism in ActionScript 3.0.
So, from this I get the impression that prototypes are just static variables.. am I right?
Not exactly, a function implemented as a prototype is still executed as instance method. In a static function you don't have access to this.
Also it doesn't mean setting a prototype value to something is setting the value for every instance. It's only the fallback value, if an object of that class isn't setting it explicitly.
var o1:Object= {};
var o2:Object= {};
Object.prototype.foo = "foo";
o1.foo = "bar"
trace(o1.foo) // bar
trace(o2.foo) // foo

Is there a way to access entry point class object from other classes of the app?

Just wonder if I can reference entry point object from any place in the app? Is it maybe assigned to some global object, like stage is for example?
Currently I use static methods and variables, but this breaks encapsulation.
If someObject is in display list, then you have a someObject.root reference which is what you are looking for. If you remove someObject from display list, you loose that reference.
My answer is no, there is no direct way to access entry object, and there shouldn't be: that's what incapsulation is about. Accessing something globally is pretty much AS1 way. When you access main instance by implicitly referencing MainClass, you make parts of your application tightly coupled, which is generally bad.
However, if you do need to have it, you may choose from several options.
Use static var: MainClass.instance
Use singletone-like access through MainClass.getInstance()
Create a package-level variable or a package level getter method
I would choose the latter.
package com.smth.application
{
public var mainObject:MainClass;
}
// in main app
package com.smth.application
{
public function MainClass()
{
mainObject = this;
}
}
It may look somewhat similar to static acces, but I think this way your code will retain some flexibility.
stage is a reference to the top level of your application, which you can access though any display object that is on the display tree as myDisplayObject.stage. When using a custom document class, it will be the first child (index 0) of stage, unless you manually force something else into the 0 index as Bakapii says.

Whats the difference between C# delegates, Dynamic Proxy, Closures and function pointers?

What are useful definitions for the common methods of passing a method or function as data, such as:
Delegates
Closures
Function pointers
Invocation by dynamic proxy and
First class methods?
Function pointers lets you pass functions around like variables. Function pointer is basically legacy method to pass function around in languages that don't support first-class methods, such as C/C++.
First class methods Basically means you can pass functions around like variables. Methods (loosely) mean functions. So this basically means first class functions. In simplest terms, it means functions are treated as "first class citizens", like variables. In the old days (C/C++), because we can't directly pass a function around, and we had to resort to workarounds like function pointers, we said functions weren't first-class citizens.
Delegates is C#'s answer to first-class methods. Delegates are somewhat more powerful because it involves closures, consider the following code snippet:
void foo( int a )
{
void bar() { writefln( a ); }
call( &bar );
}
void call( void delegate() dg ) { dg(); }
int main( char[][] args ) {
foo( 100 );
}
Notice that bar can reference the local variable a because delegates can use closures.
Closures can be very confusing at first. But the lazy-man's definition can be really simple. It basically means a variable can be available in the human-expected way. Put in other words, a variable can be referenced in places where they look like they would be present, by reading the structure of the source code. For example, looking at the code fragment above. If we didn't have closure, bar would not be able to reference a because a was only local to foo, but not bar, which is another function.
Dynamic Proxy is the odd one out. It doesn't belong to these items. Explaining it requires some very long text. It stems from the famous Proxy Pattern. The problem with Proxy Pattern was that the Proxy class needs to be implementing the same interface as the Subject. Dynamic Proxy basically means using reflective approach to discover the Subject's method so that the ProxyPattern can be freed from being tied to the Subject's interface.
just the ones i know about:
Function pointers: just that, a pointer to a piece of code. you jump to it, it executes. typed languages can enforce some parameter passing convention (i.e. C declarations)
Closures: a function with some state paired. most naturally written in lexically scoped languages (i.e. Scheme, JavaScript, Lua). several closures can share the same state (or part of it), making it an easy way to implement OOP.
First class methods: a closure created from an object instance and a method. some languages with both closures and a native OOP (Python, JavaScript) can create closures automatically.
Closure is a programming language concept. Delegate is its realization in MS.NET.
A Delegate in MS.NET is a strongly typed pointer to an object's method (a delegate instance points to both - an object and its method). There is also a way to combine several void delegate instances into one.