Opcodeのトレース
Perlを-DDEBUGGINGつきでビルドするとPerl本体にOpcodeトレース機能が付く。
$ perl -Dts -e 'print "Hello, $ARGV[0] world\n"' Perl EXECUTING... => (-e:0) enter => (-e:0) nextstate => (-e:1) pushmark => * (-e:1) const(PV("Hello, "\0)) => * PV("Hello, "\0) (-e:1) aelemfast => * PV("Hello, "\0) PV("Perl"\0) (-e:1) concat => * PV("Hello, Perl"\0) (-e:1) const(PV(" world\n"\0)) => * PV("Hello, Perl"\0) PV(" world\n"\0) (-e:1) concat => * PV("Hello, Perl world\n"\0) (-e:1) print Hello, Perl world => SV_YES (-e:1) leave
perl -Dtsでopcodeトレースとスタック(PL_stack_base)の中身を出力してくれるのでとても面白いのだが,情報量が少なすぎる。せめてB::Concise並みの情報がほしい。
そこで,Acme::Perl::VMのトレースモードを強化してみた。
$ APVM_DEBUG=stack perl -MAcme::Perl::VM::Run -e 'print "Hello, $ARGV[0] world\n"' APVM .enter () .nextstate(main -e:1) VOID () .pushmark SCALAR () .const("Hello, ") SCALAR ("Hello, ") .aelemfast[@ARGV[0]] SCALAR ("Hello, ","APVM") .concat SCALAR KIDS ("Hello, APVM") .const(" world\n") SCALAR ("Hello, APVM"," world\n") .concat SCALAR KIDS STACKED ("Hello, APVM world\n") .print VOID KIDS Hello, APVM world (sv_yes) .leave VOID KIDS PARENS ()
見ての通り,格段にわかりやすい。これをベースにOpcodeトレース用のモジュールでも作ってみようかと思ったが,コンセプトがid:yappo氏のDevel::RunOpsAnalizeと丸被りなのだった。
まあいいか。