Table of Contents

5.4.2.16 On...GoSub Statement

Note

This section describes the implementation of MS-VBAL §5.4.2.16 On...GoSub Statement.

Syntax

AST node Instruction kind Notes
OnGoSubStatementNode GoSubTable Lowering resolves the statement's labels into Instruction.Targets.

An On expression GoSub label, ... statement is represented by OnGoSubStatementNode, and lowers to the InstructionKind GoSubTable (RD-VBAL §3.5.2 Instruction).

OnGoSubStatementNode holds its targets in a Labels list. Each target is an expression naming or numbering a label or line, with no static link to the label node: the same convention as GoSub (RD-VBAL §3.4.2 Simple Statements).

OnGoToStatementNode and OnGoSubStatementNode are separate node types, rather than one shared node with a Kind.

Static Semantics

Lowering resolves each label in the list into Instruction.Targets (RD-VBAL §3.5.3 Lowering Block Statements).

Condition Result
The procedure defines the label. Its Targets entry is the label's offset.
The procedure does not define the label, e.g. Missing in On n GoSub A, Missing. Lowering reports VBC09309 Label not defined for it. Each undefined label in the list is reported on its own.

Runtime Semantics

GoSubTable performs the same selector algorithm as JumpTable (RD-VBAL §5.4.2.13 On...GoTo Statement), and in addition pushes a resumption point on a successful branch:

  1. The selector expression is evaluated once.
  2. The evaluated value is Let-coerced to Integer. Let n be the coerced value.
  3. If n is zero, or greater than the number of labels, execution falls through to the next instruction without branching.
  4. Otherwise, if n is negative or greater than 255, run-time error 5 is raised.
  5. Otherwise, the offset right after the On…GoSub is pushed onto the activation's GoSub Resumption List, and execution branches to the n'th label (1-based) in Instruction.Targets.

The push in step 5 is the same push a bare GoSub performs (RD-VBAL §5.4.2.14 GoSub Statement). A later Return pops it (RD-VBAL §5.4.2.15 Return Statement).

Condition Run-time error
n is negative, or greater than 255 (step 4). 5 — Invalid procedure call or argument

A label with no statement after it, including the end-label of the lexically enclosing procedure declaration, resolves to the offset right past the last instruction. A branch to it completes the activation as if execution had reached the end of the procedure body (RD-VBAL §3.5.1 InstructionList).

Implementation

  • RDCore.Runtime.Execution.ProcedureExecutor dispatches GoSubTable instructions, in the code path it shares with JumpTable.
  • RDCore.Runtime.Execution.JumpTableEvaluator evaluates the selector and Let-coerces it to Integer (steps 1 and 2), by calling VBNumericLetCoercionTypeRuntimeSemantics directly, bypassing the let-coercion provider.
  • The push in step 5 goes through CallStackFrame.PushGoSubReturn.

⏮️ RD-VBAL §5.4.2.15 Return Statement | ⏭️ RD-VBAL §5.4.2.17 Exit Sub Statement