AVM2での関数呼び出し

ABC(ActionScript3 Bytecode)で、関数をどのように呼び出しているかのメモ。

print("Hello,world!!");

をダンプすると次のバイトコードが得られる。

  6         findpropstrict      print
  8         pushstring          "Hello,world!!"
  10        callproplex         print (1)
  13        pop
  • finpropstrictで呼び出すべきプロパティをプッシュする
  • pushstringで引数をプッシュする
  • callproplexでプロパティを呼び出す
  • popで返り値をポップする

そして、findpropstrictとcallproplexではマルチネーム定数プール内のインデックスによって、呼び出すプロパティの名前を指定している。

プロパティ?メソッド?

確証はないが、プロパティはfunction,method,closureをまとめた呼び方な気がする。

マルチネーム

AVM2では、名前にはいくつかの種類が存在している。

QName
Qualified Name。名前空間+名前
RTQName
Runtime Qualified Name。名前空間が実行時に解決するQName
RTQNameL
Runtime Qualified Name Late。名前も実行時に解決するRTQName
Multiname
Muliple Namespace Name。複数の名前空間+名前
MultinameL
Muliple Namespace Name Late。名前が実行時に解決するMultiname

複数の名前空間が使われるのは、

use namespace a;

foo();

のように、修飾していない名前を用いた場合。

プロパティのロード

findpropstrict
index

のような形をしている。indexはマルチネーム定数プール中のインデックス。一致するプロパティイを現在のスコープから探して、スタックにプッシュする。
似ている命令にfindpropertyがあるが、見つからなかった場合に例外を投げるかどうかが違う。findpropstrictのほうが投げる。

プロパティの呼び出し

メソッドの呼び出しにはいくつかの種類がある。

まず、オブジェクトのメソッドを呼び出すための命令。

call
Function.prototype.callの実装。スタックに関数(?)をロードしておいて、呼び出す
callmethod,callstatic,callsuper
オブジェクトにあるメソッド呼び出し。メソッドはindexによって指定する
callproperty,callproplex
スタック上にプロパティをロードしておいて、それを呼び出す