Как дженерики (вектор) работают внутри AVM?

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

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

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

Ответы

Ответ 1

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

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

Ссылки на типизированный типичный тип (Vector. <int> в отличие от 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. <int>