Defining Classes in Flash
Working with ActionScript bytecode can be an interesting adventure. Although Macromedia defines the format of 99% of the ActionScript and SWF tags, they don't do such a good job when it comes to how the Flash player deals with the tags themselves. Until now, this knowledge has been kept secret by the SWF decompiler guys and Macromedia (I know of zero articles or references on this, and believe me, I've looked far and wide), but I'm going to start making this info publicly available as I dig deep into the SWF 7 file format with SWFSource.NET (note that classes were really introduced in MX/Flash 6, so doing this stuff will require Flash Player 6 or higher).
The first thing to keep in mind is that the DefineMethod SWF tag can be written with an empty function name to indicate that Flash should simply define the function and place it on the stack. This is very important, because classes don't actually exist in the bytecode. Also, for every class, you should define a movie clip (even if that movie clip is empty) and place your actions in the new DoActionInit tag. This will allow you to export your class as a component.
In order to define a class, the first thing you need to do after creating the movie clip is set the variable “_global.yourClassName” equal to the results of your constructor's DefineMethod action. Note that you don't pass a name, because the name gets set by creating the global variable.
The next step is to add your methods. Define your method the same way that you defined your constructor (with an empty name), but this time, set the variable “_global.yourClassName.prototype.yourMethodName” equal to the results of your DefineFunction action. Registers come in handy here, because you can store the results of your constructor's DefineFunction call in a register so that you only have to execute one action to retrieve the class prototype variable.
That is the basic way things work. However, there are a few “extra” pieces that you will need to do:
1) Define a constant pool as the first action in your movie with (at the very least) “_global”, “prototype”, and each of the method names in your class.
2) Wrap your class definition with bytecode equivalent to the following:
push “_global“
getVariable
push “yourTypeName“
getMember
not
not
branchIfTrue afterClassLabel
// class def here
afterClassLabel:
pop
There are some extra things you can do in there, like using “extends” to set the base class, but this is the general way things work.