AVM1 is the virtual machine of ActionScript 1.0 and 2.0: a stack machine that runs lists of actions. Every action is a one-byte code, and actions from 0x80 up carry operands. This page covers every action a SWF 6 and later movie can hold, including those SWF 6 and 7 added for ActionScript 2.0. Strings in actions are UTF-8. In a movie whose FileAttributes sets the ActionScript3 flag, the player ignores all of these and runs the ABC code instead.
Where action lists are
- DoAction – frame scripts, on the main timeline and in sprites
- DoInitAction –
#initclipblocks, and compiled ActionScript 2.0 classes - DefineButton – one list after the button records, run on release
- DefineButton2 – a list in each condition action
- PlaceObject2 and PlaceObject3 – a list in each clip action record
Every list ends with an End action, 0x00.
DoAction (12, SWF 3)
| Type | Name | Meaning |
|---|---|---|
| ACTIONRECORD[] | Actions | The frame’s actions, ending with End |
The actions run when the frame they belong to is complete.
DoInitAction (59, SWF 6)
| Type | Name | Meaning |
|---|---|---|
| UI16 | SpriteID | The sprite the actions belong to |
| ACTIONRECORD[] | Actions | The actions, ending with End |
Run once, before the sprite is first used. Flash
writes #initclip code here, and each ActionScript 2.0 class: an empty
sprite exported as __Packages. and the class name, whose DoInitAction
builds the class under _global. See
ActionScript in SWF.
The action record
| Type | Name | Meaning |
|---|---|---|
| UI8 | ActionCode | The action |
| UI16 | Length | Only if ActionCode is 0x80 or more: the bytes of operands that follow |
| bytes | operands | Length bytes |
Actions below 0x80 have no operands and no length. So an action a reader does not know can always be stepped over.
Branches
ActionJump and ActionIf hold an SI16 BranchOffset, counted in bytes from the start of the next action, the end of the branch action itself. ActionWaitForFrame and ActionWaitForFrame2 skip a number of actions, not bytes.
Owned blocks
ActionDefineFunction and ActionDefineFunction2 end with a UI16 codeSize: the function’s body is the next codeSize bytes of actions after the record. ActionWith’s Size and ActionTry’s TrySize, CatchSize and FinallySize count the blocks after the record in the same way. These bodies have no End action of their own.
Registers
There are four global registers, 0 to 3, for ActionStoreRegister and push type 4. Inside an ActionDefineFunction2 body there are up to 255 local registers, as many as its RegisterCount.
ActionPush (0x96, SWF 4)
Pushes one or more values. Each is a UI8 type, then the value:
| Type | Value | SWF |
|---|---|---|
| 0 | STRING | 4 |
| 1 | FLOAT, 32-bit | 4 |
| 2 | null (no bytes) | 5 |
| 3 | undefined (no bytes) | 5 |
| 4 | UI8 register number | 5 |
| 5 | UI8 boolean | 5 |
| 6 | DOUBLE: the high 32 bits first, each half little-endian | 5 |
| 7 | UI32 integer, used as signed | 5 |
| 8 | UI8 constant pool index | 5 |
| 9 | UI16 constant pool index | 5 |
ActionConstantPool (0x88, SWF 5)
UI16 Count, then Count STRINGs. Push types 8 and 9 index the pool most recently set by an ActionConstantPool that has run. Compilers put one at the start of each action list, so that repeated names are stored once.
ActionDefineFunction (0x9B, SWF 5)
| Type | Name | Meaning |
|---|---|---|
| STRING | FunctionName | Empty for an anonymous function, which is then pushed |
| UI16 | NumParams | The number of parameters |
| STRING × NumParams | param | Their names |
| UI16 | codeSize | The bytes of the body after this record |
ActionDefineFunction2 (0x8E, SWF 7)
| Type | Name | Meaning |
|---|---|---|
| STRING | FunctionName | Empty for an anonymous function |
| UI16 | NumParams | The number of parameters |
| UI8 | RegisterCount | The local registers the function uses |
| UB[1] × 8 | first flags byte | PreloadParentFlag, PreloadRootFlag, SuppressSuperFlag, PreloadSuperFlag, SuppressArgumentsFlag, PreloadArgumentsFlag, SuppressThisFlag, PreloadThisFlag |
| UB[7], UB[1] | second flags byte | Reserved, PreloadGlobalFlag |
| REGISTERPARAM × NumParams | Parameters | UI8 Register (0 for an ordinary named variable), STRING ParamName |
| UI16 | codeSize | The bytes of the body after this record |
The preloaded values take registers from 1, in this order, each only if its Preload
flag is set: this, arguments, super,
_root, _parent, _global. Suppress means the
value is not created at all. Flash MX 2004 and later compile functions this way when
they target SWF 7 or later, so registers replace named locals.
ActionTry (0x8F, SWF 7)
| Type | Name | Meaning |
|---|---|---|
| UB[5] | Reserved | 0 |
| UB[1] | CatchInRegisterFlag | The caught value goes in a register |
| UB[1] | FinallyBlockFlag | There is a finally block |
| UB[1] | CatchBlockFlag | There is a catch block |
| UI16 | TrySize | Bytes of the try block |
| UI16 | CatchSize | Bytes of the catch block |
| UI16 | FinallySize | Bytes of the finally block |
| STRING or UI8 | CatchName or CatchRegister | Where the caught value goes |
The try, catch and finally blocks follow the record, in that order.
ActionWith (0x94, SWF 5)
UI16 Size, then a block of Size bytes, run with the popped object added to the scope chain.
ActionGetURL2 (0x9A, SWF 4)
One byte of flags: UB[2] SendVarsMethod (0 none, 1 GET, 2 POST), UB[4] Reserved, UB[1] LoadTargetFlag (0 a browser window, 1 a sprite path), UB[1] LoadVariablesFlag. The URL and the target are popped from the stack.
ActionGotoFrame2 (0x9F, SWF 4)
UB[6] Reserved, UB[1] SceneBiasFlag, UB[1] PlayFlag, then UI16 SceneBias if the flag is set. The frame, a number or a label, is popped from the stack.
Property indexes
ActionGetProperty and ActionSetProperty take a property by number:
| Index | Property | Index | Property |
|---|---|---|---|
| 0 | _x | 11 | _target |
| 1 | _y | 12 | _framesloaded |
| 2 | _xscale | 13 | _name |
| 3 | _yscale | 14 | _droptarget |
| 4 | _currentframe | 15 | _url |
| 5 | _totalframes | 16 | _highquality |
| 6 | _alpha | 17 | _focusrect |
| 7 | _visible | 18 | _soundbuftime |
| 8 | _width | 19 | _quality |
| 9 | _height | 20 | _xmouse |
| 10 | _rotation | 21 | _ymouse |
All actions
The SWF column is the version the specification gives. Its “SWF 3” actions were in SWF 1 and 2 buttons already, which is an inference from DefineButton being SWF 1. For two-operand actions, A is the value popped first, from the top of the stack, and B the one below it.
| Code | Name | SWF | Operands and stack |
|---|---|---|---|
| 0x00 | End | 1 | Ends the action list |
| 0x04 | ActionNextFrame | 3 | Goes to the next frame |
| 0x05 | ActionPreviousFrame | 3 | Goes to the previous frame |
| 0x06 | ActionPlay | 3 | Starts playing |
| 0x07 | ActionStop | 3 | Stops playing |
| 0x08 | ActionToggleQuality | 3 | Switches between high and low quality |
| 0x09 | ActionStopSounds | 3 | Stops all sounds |
| 0x0A | ActionAdd | 4 | Pops A and B, pushes B + A as numbers |
| 0x0B | ActionSubtract | 4 | Pushes B − A |
| 0x0C | ActionMultiply | 4 | Pushes B × A |
| 0x0D | ActionDivide | 4 | Pushes B ÷ A |
| 0x0E | ActionEquals | 4 | Numeric equality |
| 0x0F | ActionLess | 4 | Pushes B < A |
| 0x10 | ActionAnd | 4 | Logical and |
| 0x11 | ActionOr | 4 | Logical or |
| 0x12 | ActionNot | 4 | Logical not |
| 0x13 | ActionStringEquals | 4 | Pops two strings, pushes whether they are equal |
| 0x14 | ActionStringLength | 4 | Pops a string, pushes its length |
| 0x15 | ActionStringExtract | 4 | Pops count, index and string; pushes the substring |
| 0x17 | ActionPop | 4 | Discards the top value |
| 0x18 | ActionToInteger | 4 | Converts the top value to an integer |
| 0x1C | ActionGetVariable | 4 | Pops a name, pushes the variable’s value |
| 0x1D | ActionSetVariable | 4 | Pops a value and a name, sets the variable |
| 0x20 | ActionSetTarget2 | 4 | Pops a target path and makes it the current target |
| 0x21 | ActionStringAdd | 4 | Pops two strings, pushes them joined |
| 0x22 | ActionGetProperty | 4 | Pops an index and a target, pushes the property |
| 0x23 | ActionSetProperty | 4 | Pops a value, an index and a target, sets the property |
| 0x24 | ActionCloneSprite | 4 | Pops depth, target and source; duplicates a movie clip |
| 0x25 | ActionRemoveSprite | 4 | Pops a target, removes the duplicated clip |
| 0x26 | ActionTrace | 4 | Pops a value, sends it to the debugger |
| 0x27 | ActionStartDrag | 4 | Pops target, lock and constrain (and a rectangle if constrained); starts dragging |
| 0x28 | ActionEndDrag | 4 | Stops dragging |
| 0x29 | ActionStringLess | 4 | Pops two strings, pushes whether B sorts before A |
| 0x2A | ActionThrow | 7 | Pops a value and throws it |
| 0x2B | ActionCastOp | 7 | Pops an object and a constructor; pushes the object if it is an instance, else null |
| 0x2C | ActionImplementsOp | 7 | Pops a constructor, a count and the interfaces it implements |
| 0x2D | ActionFSCommand2 | Flash Lite | An fscommand2 call; not in the SWF specification |
| 0x30 | ActionRandomNumber | 4 | Pops a maximum, pushes a random integer below it |
| 0x31 | ActionMBStringLength | 4 | String length in characters, for multibyte text |
| 0x32 | ActionCharToAscii | 4 | Pops a string, pushes the code of its first character |
| 0x33 | ActionAsciiToChar | 4 | Pops a code, pushes the character |
| 0x34 | ActionGetTime | 4 | Pushes the milliseconds since the movie started |
| 0x35 | ActionMBStringExtract | 4 | Substring in characters, for multibyte text |
| 0x36 | ActionMBCharToAscii | 4 | Character code, for multibyte text |
| 0x37 | ActionMBAsciiToChar | 4 | Character from a code, for multibyte text |
| 0x3A | ActionDelete | 5 | Pops a name and an object, deletes the property |
| 0x3B | ActionDelete2 | 5 | Pops a name, deletes the variable |
| 0x3C | ActionDefineLocal | 5 | Pops a value and a name, defines a local variable |
| 0x3D | ActionCallFunction | 5 | Pops a name, a count and the arguments; calls the function, pushes the result |
| 0x3E | ActionReturn | 5 | Returns from the function with the top value |
| 0x3F | ActionModulo | 5 | Pushes B mod A |
| 0x40 | ActionNewObject | 5 | Pops a name, a count and the arguments; constructs an object |
| 0x41 | ActionDefineLocal2 | 5 | Pops a name, defines an undefined local variable |
| 0x42 | ActionInitArray | 5 | Pops a count and the elements, pushes an array |
| 0x43 | ActionInitObject | 5 | Pops a count and name–value pairs, pushes an object |
| 0x44 | ActionTypeOf | 5 | Pops a value, pushes its type name |
| 0x45 | ActionTargetPath | 5 | Pops a movie clip, pushes its target path |
| 0x46 | ActionEnumerate | 5 | Pops a variable name, pushes null and then its property names |
| 0x47 | ActionAdd2 | 5 | ECMA-262 addition: numbers, or strings joined |
| 0x48 | ActionLess2 | 5 | ECMA-262 less-than |
| 0x49 | ActionEquals2 | 5 | ECMA-262 equality |
| 0x4A | ActionToNumber | 5 | Converts the top value to a number |
| 0x4B | ActionToString | 5 | Converts the top value to a string |
| 0x4C | ActionPushDuplicate | 5 | Pushes a copy of the top value |
| 0x4D | ActionStackSwap | 5 | Swaps the top two values |
| 0x4E | ActionGetMember | 5 | Pops a name and an object, pushes the property |
| 0x4F | ActionSetMember | 5 | Pops a value, a name and an object, sets the property |
| 0x50 | ActionIncrement | 5 | Adds 1 to the top value |
| 0x51 | ActionDecrement | 5 | Subtracts 1 from the top value |
| 0x52 | ActionCallMethod | 5 | Pops a name, an object, a count and the arguments; calls the method |
| 0x53 | ActionNewMethod | 5 | Pops a name, an object, a count and the arguments; constructs with the method |
| 0x54 | ActionInstanceOf | 6 | Pops a constructor and an object, pushes whether it is an instance |
| 0x55 | ActionEnumerate2 | 6 | Pops an object, pushes null and then its property names |
| 0x60 | ActionBitAnd | 5 | Bitwise and of two 32-bit integers |
| 0x61 | ActionBitOr | 5 | Bitwise or |
| 0x62 | ActionBitXor | 5 | Bitwise exclusive or |
| 0x63 | ActionBitLShift | 5 | Shift left |
| 0x64 | ActionBitRShift | 5 | Signed shift right |
| 0x65 | ActionBitURShift | 5 | Unsigned shift right |
| 0x66 | ActionStrictEquals | 6 | Equality without type conversion (===) |
| 0x67 | ActionGreater | 6 | ECMA-262 greater-than |
| 0x68 | ActionStringGreater | 6 | Pops two strings, pushes whether B sorts after A |
| 0x69 | ActionExtends | 7 | Pops a superclass and a subclass constructor, sets up inheritance |
| 0x81 | ActionGotoFrame | 3 | UI16 Frame, counted from 0 |
| 0x83 | ActionGetURL | 3 | STRING UrlString, STRING TargetString |
| 0x87 | ActionStoreRegister | 5 | UI8 RegisterNumber: copies the top value into the register |
| 0x88 | ActionConstantPool | 5 | UI16 Count, STRING × Count |
| 0x89 | ActionStrictMode † | – | UI8 mode; undocumented, the name JPEXS uses |
| 0x8A | ActionWaitForFrame | 3 | UI16 Frame, UI8 SkipCount: if the frame is not loaded, skip that many actions |
| 0x8B | ActionSetTarget | 3 | STRING TargetName: makes a named movie clip the current target |
| 0x8C | ActionGoToLabel | 3 | STRING Label: goes to the labelled frame |
| 0x8D | ActionWaitForFrame2 | 4 | UI8 SkipCount; the frame is popped |
| 0x8E | ActionDefineFunction2 | 7 | Name, parameters in registers, flags, codeSize |
| 0x8F | ActionTry | 7 | Flags, block sizes, catch name or register |
| 0x94 | ActionWith | 5 | UI16 Size; pops an object |
| 0x96 | ActionPush | 4 | Typed values |
| 0x99 | ActionJump | 4 | SI16 BranchOffset |
| 0x9A | ActionGetURL2 | 4 | Flags; pops URL and target |
| 0x9B | ActionDefineFunction | 5 | Name, parameter names, codeSize |
| 0x9D | ActionIf | 4 | SI16 BranchOffset; pops a condition and branches if it is true |
| 0x9E | ActionCall | 4 | Pops a frame and runs that frame’s actions |
| 0x9F | ActionGotoFrame2 | 4 | Flags, UI16 SceneBias; pops the frame |
Any other code is not defined. The explorer shows it as an unknown action and steps over it by its length.
A worked example
From the DoAction of a SWF 6 movie. It begins with a constant pool of 84 strings:
00000020 88 E4 01 54 00 74 68 69 73 00 6E 6F 72 6D 61 6C
00000030 00 70 6F 69 6E 74 00 41 72 72 61 79 00 …
Further on, a function:
00000207 9B 0C 00 50 6F 6C 79 67 6F 6E 00 00 00 25 00
00000216 96 02 00 08 00 1C 96 03 00 08 01 02 4F
00000223 96 02 00 08 00 1C 96 0D 00 08 02 06 00 00 00 00
00000233 00 00 00 00 08 03 40 4F
9B 0C 00: ActionDefineFunction, 12 bytes of operands: the name “Polygon”,00 00no parameters,25 00a body of 37 bytes.96 02 00 08 00: push constant 0, “this”;1C: get the variablethis.96 03 00 08 01 02: push constant 1, “normal”, and null;4F: set the member, sothis.normal = null.96 02 00 08 00 1Cagain givesthis; then96 0D 00pushes constant 2, “point”, the double 0 (type 6, eight zero bytes) and constant 3, “Array”.40, ActionNewObject, pops the name “Array” and the count 0 and pushes a new array;4Fsetsthis.pointto it.
function Polygon() {
this.normal = null;
this.point = new Array();
}