仿制药(Vector)如何在AVM中工作?

Ric*_*lay 14 apache-flex generics vector avm2

Flash Player 10中添加了对泛型的支持(目前只有Vector.<*>,并称为Adobe的'postfix类型参数'),但唯一的AVM2文档没有描述如何访问这些对象.

具体来说,我注意到一个新的操作码(0x53)和一个看似相关的新的多种类型(0x1D),但它们的用法没有记录.

注意:这个问题是用已经知道的答案创建的,因为它比我的博客或Adobe Bug DB更容易找到.

Ric*_*lay 20

我在这方面所做的逆向工程工作并没有包括声明你自己的泛型类型,尽管它很有可能.

对声明(无参数)泛型类型(Vector)的引用是通过常规限定名称进行的(尽管任何多重名称都应该这样做).

对类型泛型类型(Vector.<int>而不是Vector.<>)的引用是由一个新的多头类型(0x1D)引起的,我称之为GenericName.GenericName的格式如下:

[Kind] [TypeDefinition] [ParamCount] [Param1] [Param2] [ParamN]
Run Code Online (Sandbox Code Playgroud)

哪里:

  • [TypeDefinition]是进入多重名称表的U30
  • [ParamCount]是一个U8(U30?),它有多少个类型参数
  • [ParamX]是一个U30进入多重名称表.

显然通常不支持泛型,因此ParamCount将始终为1(对于Vector.<*>).

另一个有趣的事情是如何创建类的实例.在Flash 10(0x53)中添加了一个新操作码,我将其称为MakeGenericType.MakeGenericType使用以下堆栈声明:

TypeDefinition, ParameterType1, ParameterTypeN -> GenericType
Run Code Online (Sandbox Code Playgroud)

它还有一个参数,一个U8(U30?),指定堆栈中有多少参数.您通常会看到MakeGenericType的使用方式如下:

GetLex [TypeDefinitionMultiname]
GetLex [ParameterTypeMultiname]
MakeGeneric [ParamCount]
Coerce [GenericNameMultiname]
Construct [ConstructorParamCount]
Run Code Online (Sandbox Code Playgroud)

所以如果你有以下......

GetLex __AS3__.vec::Vector
GetLex int
MakeGeneric 1
Coerce __AS3__.vec::Vector.<int>
Construct 0
Run Code Online (Sandbox Code Playgroud)

您现在将拥有Vector.<int>的实例

  • 我非常喜欢了解as3/avm2的内部结构.谢谢你分享这个! (2认同)