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
LocksArray(VBArrayValue)
Whether this activation locks array: a ByRef parameter of it is an element of the array, or a For Each
of it that is running enumerates the array. A locked array is not re-dimensioned, erased or assigned: error 10.
bool LocksArray(VBArrayValue array)
Parameters
arrayVBArrayValueThe array, as the variable that holds it reads.
Returns
Remarks
What MS-VBA locks, recorded in Excel. MS-VBAL §5.4.3.3 says a variable "currently locked by a ByRef formal parameter" cannot be
re-dimensioned, which reads as the whole array passed by reference; MS-VBA does not lock that one - the parameter is another name for the variable,
and sees what a ReDim of either gives it. RD-VBA does what MS-VBA does.
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.
TryGetReferencedType(Symbol, out VBType?)
The declared type of the variable a ByRef parameter of this activation is a second name for, when it is not the parameter's own: a Variant
parameter given a variable of another type (MS-VBAL §5.3.1.11). Such a parameter "is treated as having a declared type of Variant, except when
used as the <l-expression> within Let-assignment or Set-assignment, in which case it is treated as having the declared type of the argument's referenced
variable": it reads as a Variant holding a value of this type, and is assigned as this type.
bool TryGetReferencedType(Symbol symbol, out VBType? declaredType)
Parameters
Returns
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