Acme-Perl-VM

 view release on metacpan or  search on metacpan

lib/Acme/Perl/VM/JA.pod  view on Meta::CPAN


これが構文木を解釈する基本的な流れです。プログラムの分岐やサブルーチンの呼び出しなどがあると更に複雑になりますが,一連の流れは同じです。

以下のセクションでは,仮想マシンの実装の中で特に重要なコンポーネントについて説明します。

=head2 The Perl Stack (PL_stack_base)

Perlプログラムの手続きと戻り値のために使われるスタックです。
このスタックは組み込み関数とサブルーチンの両方で使われます。

現在のperl5の実装では,このスタックはCの配列で表現され,必要に応じてC<realloc()>で拡張されます。スタックの先頭はスタックポインタ(C<PL_stack_sp>)として参照できるのですが,ppcode内で...

APVMではこれはPerlの配列で表現され,スタックポインタは配列の最後の添え字です。
ローカルコピーは作りません。

AVPMとの対応:
    perl            APVM

    PL_stack_base   @PL_stack
    PL_stack_sp     $#PL_stack
    dSP             (nothing)
    SP              $#PL_stack
    TOPs            TOP
    PUSHs(sv)       PUSH($sv)
    POPs            POP
    SPAGAIN         (nothing)
    PUTBACK         (nothing)
    EXTEND(SP, n)   (nothing)

See also F<pp.h>.

=head2 The Perl Stack Marker (PL_markstack)

可変長引数を扱うためのスタックのマーカーです。

二項演算子などは引数の数が固定ですが,C<print>のように引数の数が可変長である組み込み関数もあります。可変長引数を扱うためには,引数スタック中で引数が始まる位置を保存するå¿...

lib/Acme/Perl/VM/JA.pod  view on Meta::CPAN

    RETURN;
  }

マクロをいくつか展開すると以下のようになります。

  PP(pp_const)
  {
      dSP;
      EXTEND(SP, 1);
      PUSHs(cSVOPx_sv(PL_op));
      PUTBACK;
      return PL_op->next;
  }

一つひとつを順に追うと以下のようになります。

=over 4

=item C<dSP>

ローカルスタックポインタ変数(SP)を宣言し,グローバルスタックポインタの値で初期化します。

lib/Acme/Perl/VM/JA.pod  view on Meta::CPAN

スタックポインタに値を1つプッシュすることを宣言します。このとき,必要に応じてスタックは拡張されます。

=item C<cSVOPx_sv(PL_op)>

現在実行中のopcodeのsvフィールドを参照します。

=item C<PUSH(sv)>

スタックポインタを通じて引数スタックに値を1つプッシュします。

=item C<PUTBACK>

ローカルスタックポインタをグローバルスタックポインタ変数に戻します。

=item C<< return PL_op->op_next >>

次に実行するopcodeを返します。

OP_CONSTであれば可能性のあるプログラムの経路は常に一つですが,OP_COND_EXPRのような制御を担うopcodeであればC<< PL_op->next >>以外のopcodeを返すことがあります。

=back

lib/Acme/Perl/VM/PP.pm  view on Meta::CPAN

#
#         dSP  (nothing)
#          SP  $#PL_stack
#         *SP  $PL_stack[-1]
#       dMARK  my $mark = POPMARK
#        MARK  $mark
#       *MARK  $PL_stack[$mark]
#   dORIGMARK  my $origmark = $mark
#    ORIGMARK  $origmark
#     SPAGAIN  (nothing)
#     PUTBACK  (nothing)

sub pp_nextstate{
    $PL_curcop = $PL_op;

    $#PL_stack = $PL_cxstack[-1]->oldsp;
    FREETMPS;

    return $PL_op->next;
}



( run in 0.454 second using v1.01-cache-2.11-cpan-4e96b696675 )