Skip to content

Commit bf3765c

Browse files
committed
Scopes: initial draft of the algorithm for computing original stack frames
1 parent f15b006 commit bf3765c

File tree

1 file changed

+315
-0
lines changed

1 file changed

+315
-0
lines changed

spec.emu

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,321 @@ return lastURL;</code></pre>
25322532
</emu-clause>
25332533
</emu-clause>
25342534

2535+
<emu-clause id="sec-computing-original-stack-frames">
2536+
<h1>Computing original stack frames</h1>
2537+
<p></p>
2538+
2539+
<emu-clause id="sec-debugger-position-record-type">
2540+
<h1>Debugger Position Record</h1>
2541+
<p>A <dfn id="debugger-position-record">Debugger Position Record</dfn> is a tuple of a source URL and non-negative line and column numbers.</p>
2542+
<emu-table id="table-debugger-position-record-fields">
2543+
<thead>
2544+
<tr>
2545+
<th>Field Name</th>
2546+
<th>Value Type</th>
2547+
</tr>
2548+
</thead>
2549+
<tbody>
2550+
<tr>
2551+
<td>[[URL]]</td>
2552+
<td>a URL or *null*</td>
2553+
</tr>
2554+
<tr>
2555+
<td>[[Line]]</td>
2556+
<td>a non-negative integral Number</td>
2557+
</tr>
2558+
<tr>
2559+
<td>[[Column]]</td>
2560+
<td>a non-negative integral Number</td>
2561+
</tr>
2562+
</tbody>
2563+
</emu-table>
2564+
</emu-clause>
2565+
2566+
<emu-clause id="sec-debugger-bindings-record-type">
2567+
<h1>Debugger Bindings Records</h1>
2568+
<p>A <dfn id="debugger-bindings-record">Debugger Bindings Record</dfn> associates variable names to implementation-defined representations of javascript values in the debuggee or to ~unavailable~.</p>
2569+
</emu-clause>
2570+
2571+
<emu-clause id="sec-debugger-scope-record-type">
2572+
<h1>Debugger Scope Record</h1>
2573+
<p>A <dfn id="debugger-scope-record" variants="Debugger Scope Records">Debugger Scope Record</dfn> is a tuple of start and end positions and a Debugger Bindings Record.</p>
2574+
<emu-table id="table-debugger-scope-record-fields">
2575+
<thead>
2576+
<tr>
2577+
<th>Field Name</th>
2578+
<th>Value</th>
2579+
<th>Meaning</th>
2580+
</tr>
2581+
</thead>
2582+
<tbody>
2583+
<tr>
2584+
<td>[[Start]]</td>
2585+
<td>A Debugger Position Record</td>
2586+
<td>The line and column (inclusive) where the scope starts.</td>
2587+
</tr>
2588+
<tr>
2589+
<td>[[End]]</td>
2590+
<td>A Debugger Position Record</td>
2591+
<td>The line and column (exclusive) where the scope ends.</td>
2592+
</tr>
2593+
<tr>
2594+
<td>[[Bindings]]</td>
2595+
<td>A Debugger Bindings Record</td>
2596+
<td>The bindings of the scope.</td>
2597+
</tr>
2598+
</tbody>
2599+
</emu-table>
2600+
</emu-clause>
2601+
2602+
<emu-clause id="sec-debugger-frame-record-type">
2603+
<h1>Debugger Frame Record</h1>
2604+
<p>A <dfn id="debugger-frame-record" variants="Debugger Frame Records">Debugger Frame Record</dfn> is a tuple of a position, a list of scopes and an optional name.</p>
2605+
<emu-table id="table-debugger-frame-record-fields">
2606+
<thead>
2607+
<tr>
2608+
<th>Field Name</th>
2609+
<th>Value</th>
2610+
<th>Meaning</th>
2611+
</tr>
2612+
</thead>
2613+
<tbody>
2614+
<tr>
2615+
<td>[[Position]]</td>
2616+
<td>A Debugger Position Record</td>
2617+
<td>The position where execution was paused.</td>
2618+
</tr>
2619+
<tr>
2620+
<td>[[Scopes]]</td>
2621+
<td>A List of Debugger Scope Records</td>
2622+
<td>The scopes of the frame, starting with the innermost scope.</td>
2623+
</tr>
2624+
<tr>
2625+
<td>[[Name]]</td>
2626+
<td>A String or *null*</td>
2627+
<td>The name of the frame.</td>
2628+
</tr>
2629+
</tbody>
2630+
</emu-table>
2631+
</emu-clause>
2632+
2633+
<emu-clause id="sec-EvaluateWithBindings" type="abstract operation">
2634+
<h1>
2635+
EvaluateWithBindings (
2636+
_bindings_: a Debugger Bindings Record,
2637+
_expression_: a String,
2638+
)
2639+
</h1>
2640+
<dl class="header">
2641+
<dt>description</dt>
2642+
<dd>The debugger must provide an operation for evaluating an expression in the global scope with the given bindings.</dd>
2643+
</dl>
2644+
</emu-clause>
2645+
2646+
<emu-clause id="sec-MergeBindings" type="abstract operation">
2647+
<h1>
2648+
MergeBindings (
2649+
_scopes_: a List of Debugger Scope Records,
2650+
): a Debugger Bindings Record
2651+
</h1>
2652+
<dl class="header"></dl>
2653+
<emu-alg>
2654+
1. Let _bindings_ be a new empty Debugger Bindings Record.
2655+
1. For each Debugger Scope Record _scope_ of _scopes_, in reverse List order, do
2656+
1. For each variable name _variable_ of _scope_.[[Bindings]], do
2657+
1. Let _value_ be the value associated with _variable_ in _scope_.[[Bindings]].
2658+
1. Set the value of _variable_ in _bindings_ to _value_.
2659+
1. Return _bindings_.
2660+
</emu-alg>
2661+
</emu-clause>
2662+
2663+
<emu-clause id="sec-FindInnermostGeneratedRange" type="abstract operation">
2664+
<h1>
2665+
FindInnermostGeneratedRange (
2666+
_ranges_: a List of Generated Range Records,
2667+
_position_: a Debugger Position Record,
2668+
): a Generated Range Record or *null*
2669+
</h1>
2670+
<dl class="header"></dl>
2671+
<emu-alg>
2672+
1. For each Generated Range Record _range_ of _ranges_, do
2673+
1. If ComparePositions(_range_.[[Start]], _position_) is not ~greater~ and ComparePositions(_range_.[[End]], _position_) is ~greater~, then
2674+
1. Let _descendantRange_ be FindInnermostGeneratedRange(_range_.[[Children]], _position_).
2675+
1. If _descendantRange_ is not *null*, then
2676+
1. Return _descendantRange_.
2677+
1. Else,
2678+
1. return _range_.
2679+
1. Return *null*.
2680+
</emu-alg>
2681+
</emu-clause>
2682+
2683+
<emu-clause id="sec-FindInnermostOriginalScope" type="abstract operation">
2684+
<h1>
2685+
FindInnermostOriginalScope (
2686+
_scope_: an Original Scope Record,
2687+
_position_: a Debugger Position Record,
2688+
): an Original Scope Record
2689+
</h1>
2690+
<dl class="header"></dl>
2691+
<emu-alg>
2692+
1. For each Original Scope Record _childScope_ of _scope_.[[Children]], do
2693+
1. If ComparePositions(_childScope_.[[Start]], _position_) is not ~greater~ and ComparePositions(_childScope_.[[End]], _position_) is ~greater~, then
2694+
1. return FindInnermostOriginalScope(_childScope_, _position_).
2695+
1. Return _scope_.
2696+
</emu-alg>
2697+
</emu-clause>
2698+
2699+
<emu-clause id="sec-FindSourceForURL" type="abstract operation">
2700+
<h1>
2701+
FindSourceForURL (
2702+
_sources_: a List of Decoded Source Records,
2703+
_URL_: a URL,
2704+
): a Decoded Source Record or *null*
2705+
</h1>
2706+
<dl class="header"></dl>
2707+
<emu-alg>
2708+
1. For each Decoded Source Record _source_ of _sources_, do
2709+
1. If _source_.[[URL]] is _URL_, then
2710+
1. Return _source_.
2711+
1. Return *null*.
2712+
</emu-alg>
2713+
</emu-clause>
2714+
2715+
<emu-clause id="sec-FindAncestorRangeForDefinition" type="abstract operation">
2716+
<h1>
2717+
FindAncestorRangeForDefinition (
2718+
_range_: a Generated Range Record,
2719+
_definition_: an Original Scope Record,
2720+
): a Generated Range Record or *null*
2721+
</h1>
2722+
<dl class="header"></dl>
2723+
<emu-alg>
2724+
1. Repeat, while _range_ is not *null*,
2725+
1. If _range_.[[Definition]] is _definition_, then
2726+
1. Return _range_.
2727+
1. Set _range_ to its parent or *null* if it has no parent.
2728+
1. Return *null*.
2729+
</emu-alg>
2730+
</emu-clause>
2731+
2732+
<emu-clause id="sec-FindFunctionName" type="abstract operation">
2733+
<h1>
2734+
FindFunctionName (
2735+
_scope_: an Original Scope Record,
2736+
): String or *null*
2737+
</h1>
2738+
<dl class="header"></dl>
2739+
<emu-alg>
2740+
1. If _scope_.[[IsStackFrame]], then
2741+
1. Return _scope_.[[Name]].
2742+
1. Let _parentScope_ be the parent of _scope_ or *null* if it has no parent.
2743+
1. If _parentScope_ is not *null*, then
2744+
1. Return FindFunctionName(_parentScope_).
2745+
1. Return *null*.
2746+
</emu-alg>
2747+
</emu-clause>
2748+
2749+
<emu-clause id="sec-FilterEnclosingScopes" type="abstract operation">
2750+
<h1>
2751+
FilterEnclosingScopes (
2752+
_debuggerScopes_: a List of Debugger Scope Records,
2753+
_start_: a Debugger Position Record,
2754+
_end_: a Debugger Position Record,
2755+
): a List of Debugger Scope Records
2756+
</h1>
2757+
<dl class="header"></dl>
2758+
<emu-alg>
2759+
1. Let _enclosingScopes_ be a new empty List.
2760+
1. For each Debugger Scope Record _scope_ in _debuggerScopes_, do
2761+
1. If ComparePositions(_scope_.[[Start]], _start_) is not ~greater~ and ComparePositions(_scope_..[[End]], _end_) is not ~less~, then
2762+
1. Append _scope_ to _enclosingScopes_.
2763+
1. Return _enclosingScopes_.
2764+
</emu-alg>
2765+
</emu-clause>
2766+
2767+
<emu-clause id="sec-FindBindingRecord" type="abstract operation">
2768+
<h1>
2769+
FindBindingRecord (
2770+
_subRangeBindings_: a List of Binding Records,
2771+
_position_: a Debugger Position Record,
2772+
): a Binding Record or *null*
2773+
</h1>
2774+
<emu-alg>
2775+
1. For each Binding Record _subRangeBinding_ in _subRangeBindings_, in reverse List order, do
2776+
1. If ComparePositions(_subRangeBinding_.[[From]], _position_) is not ~greater~, then
2777+
1. Return _subRangeBinding_.
2778+
1. Return *null*.
2779+
</emu-alg>
2780+
</emu-clause>
2781+
2782+
<emu-clause id="sec-ComputeOriginalFrames" type="abstract operation">
2783+
<h1>
2784+
ComputeOriginalFrames (
2785+
_sourceMap_: a Decoded Source Map Record,
2786+
_frames_: a List of Debugger Frame Records,
2787+
): a List of Debugger Frame Records
2788+
</h1>
2789+
<dl class="header"></dl>
2790+
<emu-alg>
2791+
1. Let _originalFrames_ be a new empty List.
2792+
1. For each Debugger Frame Record _frame_ of _frames_, do
2793+
1. Let _generatedPosition_ be _frame_.[[Position]].
2794+
1. Let _mapping_ be GetOriginalPosition(_sourceMap_, _generatedPosition_).
2795+
1. Assert: _mapping_ is not *null*.
2796+
1. Append ComputeOriginalFrame(_sourceMap_, _frame_.[[Scopes]], _generatedPosition_, _mapping_.[[OriginalPosition]]) to _originalFrames_.
2797+
1. Let _generatedRange_ be FindInnermostGeneratedRange(_sourceMap_, _generatedPosition_).
2798+
1. Repeat, while _generatedRange_ is not *null* and _generatedRange_.[[StackFrameType]] is ~none~,
2799+
1. If _generatedRange_.[[CallSite]] is not *null*, then
2800+
1. Append ComputeOriginalFrame(_sourceMap_, _frame_.[[Scopes]], _generatedPosition_, _generatedRange_.[[CallSite]]) to _originalFrames_.
2801+
1. Set _generatedRange_ to its parent or *null* if it has no parent.
2802+
1. Return _originalFrames_.
2803+
</emu-alg>
2804+
</emu-clause>
2805+
2806+
<emu-clause id="sec-ComputeOriginalFrame" type="abstract operation">
2807+
<h1>
2808+
ComputeOriginalFrame (
2809+
_sourceMap_: a Decoded Source Map Record,
2810+
_debuggerScopes_: a List of Debugger Scope Records,
2811+
_generatedPosition_: a Debugger Position Record,
2812+
_originalPosition_: a Debugger Position Record,
2813+
): a Debugger Frame Record
2814+
</h1>
2815+
<dl class="header"></dl>
2816+
<emu-alg>
2817+
1. Let _innermostGeneratedRange_ be FindInnermostGeneratedRange(_sourceMap_.[[Ranges]], _generatedPosition_).
2818+
1. Assert: _innermostGeneratedRange_ is not *null*.
2819+
1. Let _originalSource_ be FindSourceForURL(_sourceMap_.[[Sources]], _originalPosition_.[[URL]]).
2820+
1. Assert: _originalSource_ is not *null*.
2821+
1. Let _originalScope_ be FindInnermostOriginalScope(_originalSource_.[[Scope]], _originalPosition_).
2822+
1. Let _name_ be FindFunctionName(_originalScope_).
2823+
1. Let _originalDebuggerScopes_ be a new empty List.
2824+
1. Repeat, while _originalScope_ is not *null*,
2825+
1. Let _generatedRange_ be FindAncestorRangeForDefinition(_innermostGeneratedRange_, _originalScope_).
2826+
1. Let _originalBindings_ be a new empty Debugger Bindings Record.
2827+
1. If _generatedRange_ is not *null*, then
2828+
1. Assert: The length of _originalScope_.[[Variables]] is equal to the length of _generatedRange_.[[Bindings]].
2829+
1. Let _activeDebuggerScopes_ be FilterEnclosingScopes(_debuggerScopes_, _generatedRange_.[[Start]], _generatedRange_.[[End]]).
2830+
1. Let _activeBindings_ be MergeBindings(_activeDebuggerScopes_).
2831+
1. Let i = 0.
2832+
1. Repeat, while i is smaller than the length of _originalScope_.[[Variables]],
2833+
1. Let _variable_ be _originalScope_.[[Variables]][i].
2834+
1. Let _binding_ be FindBindingRecord(_generatedRange_.[[Bindings]][i], _generatedPosition_).
2835+
1. Assert: _binding_ is not *null*.
2836+
1. Let _value_ be ~unavailable~.
2837+
1. If _binding_.[[Binding]] is not *null*, then
2838+
1. Set _value_ to EvaluateWithBindings(_activeBindings_, __binding_.[[Binding]]).
2839+
1. Set the value of _variable_ in _originalBindings_ to _value_.
2840+
1. Set i to i + 1.
2841+
1. Else,
2842+
1. For each String _variable_ of _originalScope_.[[Variables]], do
2843+
1. Set the value of _variable_ in _originalBindings_ to ~unavailable~.
2844+
1. Append { [[Start]]: _originalScope_.[[Start]], [[End]]: _originalScope_.[[End]], [[Bindings]]: _originalBindings_ } to _originalDebuggerScopes_.
2845+
1. Return { [[Position]]: _originalPosition_, [[Scopes]]: _originalDebuggerScopes_, [[Name]]: _name_ }.
2846+
</emu-alg>
2847+
</emu-clause>
2848+
</emu-clause>
2849+
25352850
<emu-annex id="sec-conventions">
25362851
<h1>Conventions</h1>
25372852

0 commit comments

Comments
 (0)