Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do generics (Vector) work inside the AVM?

Support for generics (currently only Vector.<*>, and called 'postfix type parameters' by Adobe) was added in Flash Player 10, but the only AVM2 documentation does not describe how these objects are accessed.

Specifically, I noticed a new opcode (0x53) and a new multiname kind (0x1D) that seem relevant, but their usage is not documented.

NB: This question was created with the answer already known as it is more easily found here than on my blog or the Adobe Bug DB.

like image 931
Richard Szalay Avatar asked Feb 16 '09 14:02

Richard Szalay


1 Answers

The reverse engineering work I did on this did not include declaring your own generic types, though it's very likely possible.

References to the declaring (parameterless) generic type (Vector) are made through a regular qualified name (though any multiname should do).

References to a typed generic type (Vector.<int> as opposed to Vector.<>) are made by a new multiname kind (0x1D), which I call GenericName. GenericName has a format like so:

[Kind] [TypeDefinition] [ParamCount] [Param1] [Param2] [ParamN]

Where:

  • [TypeDefinition] is a U30 into the multiname table
  • [ParamCount] is a U8 (U30?) of how many type parameters there are
  • [ParamX] is a U30 into the multiname table.

Obviously generics are not generally supported yet, so ParamCount will always be 1 (for Vector.<*>).

The other interesting thing is how instances of the class are created. A new opcode was added in Flash 10 (0x53), which I will call MakeGenericType. MakeGenericType is declared with the following stack:

TypeDefinition, ParameterType1, ParameterTypeN -> GenericType

It also has one parameter, a U8 (U30?) specifying how many parameters are on the stack. You will generally see MakeGenericType being used like this:

GetLex [TypeDefinitionMultiname]
GetLex [ParameterTypeMultiname]
MakeGeneric [ParamCount]
Coerce [GenericNameMultiname]
Construct [ConstructorParamCount]

So if you had the following...

GetLex __AS3__.vec::Vector
GetLex int
MakeGeneric 1
Coerce __AS3__.vec::Vector.<int>
Construct 0

You would now have an instance of Vector.<int>

like image 179
Richard Szalay Avatar answered Oct 12 '22 16:10

Richard Szalay