スタック フレーム指定子

あるプロシージャで、それを含むプロシージャのローカル変数を参照する場合は、内側のプロシージャから外側のプロシージャの変数にアクセスできるように、外側のプロシージャのスタック フレームに対する指定子を内側のプロシージャに提供する必要があります。外側のプロシージャのスタック フレームに対するこの指定子が、スタック フレーム指定子です。

外側のプロシージャが再帰的に有効化されている場合を除いて、外側のプロシージャのスタック フレームは 1 つしか存在しません。このスタック フレームは、外側のプロシージャで宣言されている変数を内側のプロシージャで参照する場合に常に使用されるスタック フレームです。

外側のプロシージャが再帰的に有効化されている場合は、内側のプロシージャを呼び出すために使用するエントリ値によって、外側のプロシージャの変数を内側のプロシージャで参照する際に使用されるスタック フレームが決まります。次に例を示します。

A: PROCEDURE RECURSIVE;
   DECLARE X FIXED BINARY(15); 
   DECLARE E ENTRY VARIABLE STATIC; 
   IF FIRST-TIME
      THEN E=B;
      ELSE CALL F;
   CALL G;
.
.
.
B: PROCEDURE; 
      .
      .
      .
      X=5;

この例では、A が G を呼び出し、G が A を呼び出し、次に A が F を呼び出し、F が E によって保持されているエントリ値を呼び出すと想定しています。E には B が代入されているため、E を呼び出すと、B の有効化が行われます。その B の有効化で X を参照する場合、X のインスタンスを含む 2 つのスタック フレームが存在することになります。スタック フレームが 2 つ存在するのは、A の 2 つの呼び出しが有効なままであるためです。ただし、A のこの 2 つの有効化の最初の有効化で B が E に代入されるため、E には A の最初のスタック フレームに対する指定子が格納されています。したがって、B は X の最初のインスタンスに 5 を代入します。A から B を直接呼び出した場合には、B は X を参照する際に常に A の最も新しいスタック フレームを使用することになります。

古いスタック フレームは、エントリ名がエントリ変数に代入される場合、またはエントリ パラメーターに引数として渡される場合にのみ使用されます。エントリ名がこのように渡される、または代入される場合、それを含むブロックの現在のスタック フレームが、その代入によって生成されるエントリ値の 2 つ目のコンポーネントとして代入されます。

代入される、または引数として渡されるプロシージャ名が、その代入または引き渡しを行うブロック内ではなく、外側にあるブロックで宣言されている場合は、前の例で X を見つけるために使用された原理と同じ原理によって、外側にあるブロックのスタック フレームが特定されます。スタック フレームが見つかると、そのスタック フレームに対する指定子がエントリ値の 2 つ目の部分として代入されます。

ブロック A の各スタック フレームには、A を含むブロックのスタック フレームに対する指定子があります。この指定子は、A を有効化するために使用するエントリ値の 2 つ目の部分として提供された指定子です。A の有効化によってエントリ変数またはエントリ パラメーターが呼び出されない限り、また再帰処理が行われない限り、このように指定されたスタック フレームは直前のスタック フレームと同じになります。