Interface ICallStackFrame
Represents a single call stack frame: the activation record of one procedure call,
owning the storage for every locally-scoped Symbol it declares — its parameters and
its Dim/procedure-local declarations alike (RD-VBAL §2.3.1.2, the local
stack frame heap tier). A Static local is the one exception: it lives in the
module-level statics heap instead, so it keeps its value between calls.
public interface ICallStackFrame : IStackFrame
- Inherited Members
Remarks
⚠️ A CallStackFrame frame is not immutable: the value retrieved for a
given symbol may be different at a subsequent retrieval, and a frame is torn down (its storage
freed) when it is popped from the ICallStack that owns it.
Properties
Directives
The ModuleDirectives of the module declaring the procedure: what the code of this activation is executed under — its comparison mode, chiefly (MS-VBAL §5.2.1.1).
ModuleDirectives Directives { get; }
Property Value
Remarks
👉 A StaticSymbol identifies a procedure by its name and type alone; it does not say which module it is in.
ErrorHandler
This activation's current ErrorHandlerState (MS-VBAL §5.4.4) — a
single mutable value, like Pc, not per-offset hidden state like
TryGetBlockState(int, out VBTypedValue?)/TryGetForLoopState(int, out ForLoopState)/TryGetForEachState(int, out ForEachState):
an On Error statement changes the activation's policy going forward, it isn't scoped to one
block-opening instruction. Read-only here: only the interpreter's executor (RDCore.Runtime)
updates it, through the concrete frame type it constructs.
ErrorHandlerState ErrorHandler { get; }
Property Value
GoSubDepth
The current depth of this activation's own GoSub Resumption List
(MS-VBAL §5.4.2.14) — how many GoSub/On…GoSub calls are still
awaiting their Return. Read-only here: only the interpreter's executor (RDCore.Runtime)
pushes and pops it, through the concrete frame type it constructs. A Return
(MS-VBAL §5.4.2.15) when this is zero is error 3, "Return without GoSub".
int GoSubDepth { get; }
Property Value
Pc
The offset, into this activation's own InstructionList, of the next instruction to fetch
(RD-VBAL §3.5.1). Read-only here: only the interpreter's executor (RDCore.Runtime)
advances it, through the concrete frame type it constructs.
int Pc { get; }
Property Value
ReturnValue
The current value of this activation's function result variable
(MS-VBAL §5.3.1) — null for an activation of a Sub, a
Property Let, or a Property Set, none of which have one. A bare reference to a
Function/Property Get's own name, from within its own body, reads and writes this
rather than the general symbol table (RD-VBAL §3.5.4). Read-only here: only
RDCore.Runtime ever writes it, through the concrete frame type it constructs.
VBTypedValue? ReturnValue { get; }
Property Value
StaticSymbol
The StaticSymbol identifying the procedure this frame is an activation of.
StaticSymbol StaticSymbol { get; }
Property Value
Target
The object this activation is a call on - the Me of a member of a class module - or null
for a procedure of a standard module. What an Instance symbol, a field of a class, is
resolved against: it is the object's own storage, not the session's.
VBRuntimeObjectId? Target { get; }
Property Value
Methods
GetValue(Symbol)
Gets the IBindingHandle currently held in this frame for the specified locally-scoped Symbol.
IBindingHandle GetValue(Symbol symbol)
Parameters
symbolSymbol
Returns
Exceptions
- KeyNotFoundException
No binding exists yet for
symbolon this frame.
IsByRefParameter(Symbol)
Whether symbol is a ByRef parameter of this activation: a second name for a variable of the caller's, and not a variable of its own
(MS-VBAL §5.3.1.11).
bool IsByRefParameter(Symbol symbol)
Parameters
symbolSymbol
Returns
LocksAddress(MemoryAddress)
Whether a ByRef parameter of this activation is the variable at address - whether this activation locks it
(MS-VBAL §5.4.3.3: a variable "currently locked by a ByRef formal parameter" cannot be re-dimensioned by another name).
bool LocksAddress(MemoryAddress address)
Parameters
addressMemoryAddress
Returns
Push(Symbol, VBTypedValue)
Declares symbol on this frame and reserves storage sized for
value, its initial value — the caller's argument for a parameter, the
declared type's default value for a fresh Dim. MS-VBAL draws no distinction between a
parameter and a Dim local for name-resolution purposes, so both are declared this way.
void Push(Symbol symbol, VBTypedValue value)
Parameters
symbolSymbolvalueVBTypedValue
Exceptions
- InvalidOperationException
symbolis already declared on this frame — a compile-timeDuplicateDeclarationthat should never reach runtime.
TryGetAddress(Symbol, out MemoryAddress)
Gets the MemoryAddress currently reserved for the specified locally-scoped
Symbol on this frame, if any — a ByRef parameter (Push(Symbol, VBTypedValue)ed by
aliasing an existing address rather than allocating one of its own) resolves to the SAME address
its argument does, exactly like an ordinary declared local.
bool TryGetAddress(Symbol symbol, out MemoryAddress address)
Parameters
symbolSymboladdressMemoryAddress
Returns
TryGetBlockState(int, out VBTypedValue?)
Gets the hidden value a block-opening instruction (a With's target, a Select Case's
selector) stashed on this activation, keyed by that instruction's own offset
(RD-VBAL §3.5.4) — however control reached the instruction reading it, a
GoTo included, since the stash lives on the activation rather than on any call stack a
structured walk would otherwise need to unwind.
bool TryGetBlockState(int openerOffset, out VBTypedValue? value)
Parameters
openerOffsetintThe offset of the block-opening instruction that stashed the value.
valueVBTypedValueThe stashed value, if one exists for
openerOffset.
Returns
Remarks
Read-only here: only the interpreter's executor (RDCore.Runtime) stashes a value, through the concrete frame type it constructs.
TryGetForEachState(int, out ForEachState)
Gets the ForEachState a For Each loop's own opener stashed on this
activation, keyed by that instruction's own offset — mirrors TryGetForLoopState(int, out ForLoopState) for
the different per-activation shape a For Each loop's own enumeration cursor needs.
bool TryGetForEachState(int openerOffset, out ForEachState state)
Parameters
openerOffsetintThe offset of the
ForEachOpenerinstruction that stashed the state.stateForEachStateThe stashed state, if one exists for
openerOffset— its absence when aForEachNextinstruction looks it up is MS-VBAL §5.4.2.4 error 92, "For loop not initialized" (aGoTolanded directly on the closer this activation).
Returns
Remarks
Read-only here: only the interpreter's executor (RDCore.Runtime) stashes a value, through the concrete frame type it constructs.
TryGetForLoopState(int, out ForLoopState)
Gets the ForLoopState a For loop's own opener stashed on this activation,
keyed by that instruction's own offset — mirrors TryGetBlockState(int, out VBTypedValue?), but a For
loop's per-activation hidden state is more than the single value that mechanism holds.
bool TryGetForLoopState(int openerOffset, out ForLoopState state)
Parameters
openerOffsetintThe offset of the
ForOpenerinstruction that stashed the state.stateForLoopStateThe stashed state, if one exists for
openerOffset— its absence when aForNextinstruction looks it up is MS-VBAL §5.4.2.3 error 92, "For loop not initialized" (aGoTolanded directly on the closer this activation).
Returns
Remarks
Read-only here: only the interpreter's executor (RDCore.Runtime) stashes a value, through the concrete frame type it constructs.
TryResolve(Symbol, out IBindingHandle?)
Gets the IBindingHandle currently held in this frame for the specified locally-scoped Symbol, if any.
bool TryResolve(Symbol symbol, out IBindingHandle? value)
Parameters
symbolSymbolvalueIBindingHandle