The article directories

$ESTACK variable

Contains the number of context frames saved on the call stack from user-defined points.

The outline

$ESTACK
$ES
Copy the code

describe

$ESTACK contains the number of context frames saved on the call stack for the JOB from the user-defined point. You can specify this by creating a new copy of $ESTACK using the new command.

The $ESTACK special is similar to the $STACK special. Both contain the number of context frames currently stored in the JOB or program’s call stack. When the context changes, the Cache increments and restores both. The main difference is that you can reset the $ESTACK count to zero at any time using the NEW command. Unable to reset $STACK count.

Context framework and call stack

When the Cache image is started, the values of $ESTACK and $STACK are zero before any context is saved to the call STACK. Each time a routine calls another routine using DO, the system saves the context of the currently executing routine in the call STACK, incrementing $ESTACK and $STACK, and starts executing the called routine in the newly created context. The invoked routine can call another routine in turn, and so on. Each time another routine is called, the Cache increments $ESTACK and $STACK and places more saved context on the call STACK.

Issuing DO commands, EXECUTE commands, or calls to user-defined functions creates a new execution context. No GOTO command will be issued.

When a DO command, XECUTE command, or user-defined function reference creates a new context, the Cache increases the value of $STACK and $ESTACK. When the QUIT command causes the context to exit, the Cache restores the previous context from the call STACK and decreases the $STACK and $ESTACK values.

The $ESTACK and $STACK special variables cannot be modified using the SET command. Attempting to do so results in a

error.

create$ESTACK

You can use the NEW command to create a NEW copy of $ESTACK in any context. Cache takes the following actions:

  • save$ESTACKAn old copy of.
  • Create a new$ESTACKA copy with a value of zero (0).

In this way, a specific context can be set up as a $ESTACK level 0 context. When a new context is created using DO, XECUTE, or user-defined functions, the Cache increments this $ESTACK value. However, when the context in which a new $ESTACK was created exits ($ESTACK is at level 0), the Cache restores the value of the previous copy of $ESTACK.

The sample

The following example shows the NEW command on $ESTACK in action. The example MainRoutine here shows the initial values for $STACK and $ESTACK (they are the same values). It then calls Sub1. This call will increment $STACK and $ESTACK. The NEW command creates a $ESTACK with a value of 0. Sub1 calls Sub2, incrementing $STACK and $ESTACK. Returning MainRoutine will restore the initial values of $STACK and $ESTACK:

/// d ##class(PHA.TEST.SpecialVariables).ESTACK()
ClassMethod ESTACK(a)
{ Main WRITE ! ."Initial: $STACK=",$STACK," $ESTACK=",$ESTACK DO Sub1 WRITE ! ."Return: $STACK=",$STACK," $ESTACK=",$ESTACK QUIT Sub1 WRITE ! ."Sub1Call: $STACK=",$STACK," $ESTACK=",$ESTACK NEW $ESTACK WRITE ! ."Sub1NEW: $STACK=",$STACK," $ESTACK=",$ESTACK DO Sub2 QUIT Sub2 WRITE ! ."Sub2Call: $STACK=",$STACK," $ESTACK=",$ESTACK
	QUIT
}
Copy the code
DHC-APP>d ##class(PHA.TEST.SpecialVariables).ESTACK(a)Initial: $STACK=1 $ESTACK=1
Sub1Call: $STACK=2 $ESTACK=2
Sub1NEW: $STACK=2 $ESTACK=0
Sub2Call: $STACK=3 $ESTACK=1
Return: $STACK=1 $ESTACK=1
Copy the code

The following example demonstrates how to increase the value of $ESTACK when you create new contexts by issuing the DO and XECUTE commands and decrease the value when you exit those contexts. It also shows that the GOTO command does not create a new context or increment $ESTACK:

/// d ##class(PHA.TEST.SpecialVariables).ESTACK1()
ClassMethod ESTACK1(a)
{ Main NEW $ESTACK WRITE ! ."Initial Main: $ESTACK=",$ESTACK   / / 0DO Sub1 WRITE ! ."Return Main: $ESTACK=",$ESTACK   / / 0QUIT Sub1 WRITE ! ."Sub1 via DO: $ESTACK=",$ESTACK  / / 1
	XECUTE "WRITE ! ,""Sub1 XECUTE: $ESTACK="",$ESTACK"   / / 2WRITE ! ."Sub1 post-XECUTE: $ESTACK=",$ESTACK   / / 1GOTO Sub2 Sub1Return WRITE ! ."Sub1 after GOTO: $ESTACK=",$ESTACK  / / 1QUIT Sub2 WRITE ! ."Sub2 via GOTO: $ESTACK=",$ESTACK   / / 1
	GOTO Sub1Return
}
Copy the code
DHC-APP>d ##class(PHA.TEST.SpecialVariables).ESTACK1(a)Initial Main: $ESTACK=0
Sub1 via DO: $ESTACK=1
Sub1 XECUTE: $ESTACK=2
Sub1 post-XECUTE: $ESTACK=1
Sub2 via GOTO: $ESTACK=1
Sub1 after GOTO: $ESTACK=1
Return Main: $ESTACK=0
Copy the code

Pay attention to

The context level of the terminal prompt

The routine called from the program starts at a different context level than the routine called at terminal prompt using the DO command. When you type the DO command at the terminal prompt, a new context is created for the routine.

The invoked routine can compensate by setting up a $ESTACK Level 0 context and then using $ESTACK for all context-level references.

Consider the following routine:

/// d ##class(PHA.TEST.SpecialVariables).ESTACK2()
ClassMethod ESTACK2(a)
{ START ; Establish $ESTACK0Level context NEW $ESTACK; Display $STACK context level WRITE! ."$STACK level in routine START is ",$STACK ; Display the $ESTACK context level and exit WRITE! ."$ESTACK level in routine START is ",$ESTACK
	QUIT
}
Copy the code

When you run Start from the program, you should see the following display:

$STACK level in routine START is 0
$ESTACK level in routine START is 0
Copy the code

When you run start by issuing the do^start command at the terminal prompt, you will see the following:

DHC-APP>d ##class(PHA.TEST.SpecialVariables).ESTACK2(a) $STACK level in routine START is 1
$ESTACK level in routine START is 0
Copy the code

$ESTACKAnd error handling

$ESTACK is particularly useful during error handling when the error handler must expand the call stack to a particular context level.