Как дженерики (вектор) работают внутри AVM? - PullRequest
14 голосов
/ 16 февраля 2009

Поддержка дженериков (в настоящее время только Vector. <*> , называемая Adobe «параметрами типа постфикса») была добавлена ​​в Flash Player 10, но единственная документация AVM2 не описывать, как эти объекты доступны.

В частности, я заметил новый код операции (0x53) и новый вид с несколькими именами (0x1D), которые кажутся актуальными, но их использование не задокументировано.

NB. Этот вопрос был создан с уже известным ответом, поскольку его легче найти здесь, чем в моем блоге или в базе данных Adobe Bug.

1 Ответ

20 голосов
/ 16 февраля 2009

Работа по реверс-инжинирингу, которую я сделал над этим, не включала объявление ваших собственных универсальных типов, хотя вполне вероятно, что это возможно.

Ссылки на декларируемый (без параметров) универсальный тип (Vector) делаются через обычное квалифицированное имя (хотя это должно делать любое многоименное имя).

Ссылки на типизированный универсальный тип (Vector. в отличие от Vector. <>) Создаются новым многоименовым видом (0x1D), который я называю GenericName. GenericName имеет следующий формат:

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

Где:

  • [TypeDefinition] представляет собой U30 в таблице с несколькими именами
  • [ParamCount] - это U8 (U30?) Количества параметров типа
  • [ParamX] - это U30 в таблице с несколькими именами.

Очевидно, что дженерики, как правило, еще не поддерживаются, поэтому ParamCount всегда будет равен 1 (для Vector. <*>).

Другая интересная вещь - как создаются экземпляры класса. Новый код операции был добавлен во Flash 10 (0x53), который я назову MakeGenericType. MakeGenericType объявлен со следующим стеком:

TypeDefinition, ParameterType1, ParameterTypeN -> GenericType

Он также имеет один параметр, U8 (U30?), Определяющий, сколько параметров в стеке. Как правило, вы увидите, что MakeGenericType используется следующим образом:

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

Так что, если у вас было следующее ...

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

Теперь у вас есть экземпляр Vector.

...