+ Computing original stack frames
+
+
+
+ Source Maps Record
+ A Source Maps Record associates source URLs to Decoded Source Map Records.
+
+
+
+ Debugger Position Record
+ A Debugger Position Record is a tuple of a source URL and non-negative line and column numbers.
+
+
+
+
+ | Field Name |
+ Value Type |
+
+
+
+ | [[URL]] |
+ a URL or *null* |
+
+
+ | [[Line]] |
+ a non-negative integral Number |
+
+
+ | [[Column]] |
+ a non-negative integral Number |
+
+
+
+
+
+
+ Debugger Bindings Record
+ A Debugger Bindings Record associates variable names to implementation-defined representations of javascript values in the debuggee or to ~unavailable~.
+
+
+
+ Debugger Scope Record
+ A Debugger Scope Record is a tuple of start and end positions and a Debugger Bindings Record.
+
+
+
+
+ | Field Name |
+ Value |
+ Meaning |
+
+
+
+ | [[Start]] |
+ A Debugger Position Record |
+ The line and column (inclusive) where the scope starts. |
+
+
+ | [[End]] |
+ A Debugger Position Record |
+ The line and column (exclusive) where the scope ends. |
+
+
+ | [[Bindings]] |
+ A Debugger Bindings Record |
+ The bindings of the scope. |
+
+
+
+
+
+
+ Debugger Frame Record
+ A Debugger Frame Record is a tuple of a position, a list of scopes and an optional name.
+
+
+
+
+ | Field Name |
+ Value |
+ Meaning |
+
+
+
+ | [[Position]] |
+ A Debugger Position Record |
+ The position where execution was paused. |
+
+
+ | [[Scopes]] |
+ A List of Debugger Scope Records |
+ The scopes of the frame, starting with the innermost scope. |
+
+
+ | [[Name]] |
+ A String or *null* |
+ The name of the frame. |
+
+
+
+
+
+
+ SourceMapped Frame Record
+ A SourceMapped Frame Record contains the name and position of an original frame and the index of its corresponding generated frame.
+
+
+
+
+ | Field Name |
+ Value |
+ Meaning |
+
+
+
+ | [[Name]] |
+ A String or *null* |
+ The name of the original frame. |
+
+
+ | [[OriginalPosition]] |
+ A Debugger Position Record |
+ The position of the original frame. |
+
+
+ | [[GeneratedFrameIndex]] |
+ a non-negative integral Number |
+ The index of the corresponding generated frame. |
+
+
+ | [[HideCaller]] |
+ a Boolean |
+ |
+
+
+
+
+
+
+
+ EvaluateInScope (
+ _frameIndex_: a non-negative integral Number,
+ _scopeIndex_: a non-negative integral Number,
+ _expression_: a String,
+ )
+
+
+
+
+
+
+ FindInnermostGeneratedRange (
+ _ranges_: a List of Generated Range Records,
+ _position_: a Debugger Position Record,
+ ): a Generated Range Record or *null*
+
+
+
+ 1. For each Generated Range Record _range_ of _ranges_, do
+ 1. If ComparePositions(_range_.[[Start]], _position_) is not ~greater~ and ComparePositions(_range_.[[End]], _position_) is ~greater~, then
+ 1. Let _descendantRange_ be FindInnermostGeneratedRange(_range_.[[Children]], _position_).
+ 1. If _descendantRange_ is not *null*, then
+ 1. Return _descendantRange_.
+ 1. Else,
+ 1. return _range_.
+ 1. Return *null*.
+
+
+
+
+
+ FindInnermostOriginalScope (
+ _scope_: an Original Scope Record,
+ _position_: a Debugger Position Record,
+ ): an Original Scope Record
+
+
+
+ 1. For each Original Scope Record _childScope_ of _scope_.[[Children]], do
+ 1. If ComparePositions(_childScope_.[[Start]], _position_) is not ~greater~ and ComparePositions(_childScope_.[[End]], _position_) is ~greater~, then
+ 1. return FindInnermostOriginalScope(_childScope_, _position_).
+ 1. Return _scope_.
+
+
+
+
+
+ FindSourceForURL (
+ _sources_: a List of Decoded Source Records,
+ _URL_: a URL,
+ ): a Decoded Source Record or *null*
+
+
+
+ 1. For each Decoded Source Record _source_ of _sources_, do
+ 1. If _source_.[[URL]] is _URL_, then
+ 1. Return _source_.
+ 1. Return *null*.
+
+
+
+
+
+ FindAncestorRangeForDefinition (
+ _range_: a Generated Range Record,
+ _definition_: an Original Scope Record,
+ ): a Generated Range Record or *null*
+
+
+
+ 1. Repeat, while _range_ is not *null*,
+ 1. If _range_.[[Definition]] is _definition_, then
+ 1. Return _range_.
+ 1. Set _range_ to its parent or *null* if it has no parent.
+ 1. Return *null*.
+
+
+
+
+
+ FindFunctionName (
+ _scope_: an Original Scope Record,
+ ): String or *null*
+
+
+
+ 1. If _scope_.[[IsStackFrame]], then
+ 1. Return _scope_.[[Name]].
+ 1. Let _parentScope_ be the parent of _scope_ or *null* if it has no parent.
+ 1. If _parentScope_ is not *null*, then
+ 1. Return FindFunctionName(_parentScope_).
+ 1. Return *null*.
+
+
+
+
+
+ FindDebuggerScopeIndexForRange (
+ _debuggerScopes_: a List of Debugger Scope Records,
+ _start_: a Debugger Position Record,
+ _end_: a Debugger Position Record,
+ ): a non-negative integral Number or *null*
+
+
+
+ 1. Let _index_ be 0.
+ 1. Repeat, while _index_ is smaller than the length of _debuggerScopes_,
+ 1. Let _scope_ be _debuggerScopes_[_index_].
+ 1. If ComparePositions(_scope_.[[Start]], _start_) is not ~greater~ and ComparePositions(_scope_.[[End]], _end_) is not ~less~, then
+ 1. Return _index_.
+ 1. Set _index_ to _index_ + 1.
+ 1. Return *null*.
+
+
+
+
+
+ FindBindingRecord (
+ _subRangeBindings_: a List of Binding Records,
+ _position_: a Debugger Position Record,
+ ): a Binding Record or *null*
+
+
+
+ 1. For each Binding Record _subRangeBinding_ in _subRangeBindings_, in reverse List order, do
+ 1. If ComparePositions(_subRangeBinding_.[[From]], _position_) is not ~greater~, then
+ 1. Return _subRangeBinding_.
+ 1. Return *null*.
+
+
+
+
+
+ ComputeOriginalFrames (
+ _sourceMap_: a Decoded Source Map Record,
+ _generatedFrames_: a List of Debugger Frame Records,
+ ): a List of Debugger Frame Records
+
+
+
+ 1. Let _framePositions_ be a new empty List.
+ 1. For each Debugger Frame Record _frame_ of _generatedFrames_, do
+ 1. Append _frame_.[[Position]] to _framePositions_.
+ 1. Let _sourceMappedFrames_ be MapStackTrace(_sourceMap_, _framePositions_).
+ 1. Let _originalFrames_ be a new empty List.
+ 1. For each SourceMapped Frame Record _sourceMappedFrame_ of _sourceMappedFrames_, do
+ 1. Let _generatedFrameIndex_ be _sourceMappedFrame_.[[GeneratedFrameIndex]].
+ 1. Let _generatedFrame_ be _generatedFrames_[_generatedFrameIndex_].
+ 1. Let _originalPosition_ be _sourceMappedFrame_.[[OriginalPosition]].
+ 1. Let _originalScopes_ be BuildScopeChain(_sourceMap_, _generatedFrame_.[[Scopes]], _generatedFrame_.[[Position]], _generatedFrameIndex_, _originalPosition_).
+ 1. Append { [[Position]]: _originalPosition_, [[Scopes]]: _originalScopes_, [[Name]]: _sourceMappedFrame_.[[Name]] } to _originalFrames_.
+ 1. Return _originalFrames_.
+
+
+
+
+
+ MapStackTrace (
+ _sourceMaps_: a Source Maps Record,
+ _framePositions_: a List of Debugger Position Records,
+ ): a List of SourceMapped Frame Records
+
+
+
+ 1. Let _sourceMappedFrames_ be a new empty List.
+ 1. Let _i_ be 0.
+ 1. Let _hideNextFrame_ be *false*.
+ 1. Repeat, while _i_ is smaller than the length of _framePositions_,
+ 1. Let _sourceMap_ be the Decoded Source Map Record associated with _framePositions_[_i_][[URL]] in _sourceMaps_.
+ 1. Let _currentSourceMappedFrames_ be MapStackFrame(_sourceMap_, _framePositions_[_i_]).
+ 1. Let _j_ be 0.
+ 1. Repeat, while _j_ is smaller than the length of _currentSourceMappedFrames_,
+ 1. If _hideNextFrame_ is *false*,
+ 1. Set _currentSourceMappedFrames_[j].[[GeneratedFrameIndex]] to _i_.
+ 1. Append _currentSourceMappedFrames_[j] to _sourceMappedFrames_.
+ 1. Set _hideNextFrame_ to _currentSourceMappedFrames_[j].[[HideCaller]].
+ 1. Set _j_ to _j_ + 1.
+ 1. Set _i_ to _i_ + 1.
+ 1. Return _sourceMappedFrames_.
+
+
+
+
+
+ MapStackFrame (
+ _sourceMap_: a Decoded Source Map Record,
+ _framePosition_: a Debugger Position Record,
+ ): a List of SourceMapped Frame Records
+
+
+
+ 1. Let _sourceMappedFrames_ be a new empty List.
+ 1. Let _originalPositions_ be GetOriginalPositions(_sourceMap_, _framePosition_).
+ 1. Assert: _originalPositions_ is not empty.
+ 1. Let _originalPosition_ be _originalPositions_[0].
+ 1. Let _originalSource_ be FindSourceForURL(_sourceMap_.[[Sources]], _originalPosition_.[[URL]]).
+ 1. Assert: _originalSource_ is not *null*.
+ 1. Let _originalScope_ be FindInnermostOriginalScope(_originalSource_.[[Scope]], _originalPosition_).
+ 1. Let _name_ be FindFunctionName(_originalScope_).
+ 1. Append { [[Name]]: _name_, [[OriginalPosition]]: _originalPosition_, [[GeneratedFrameIndex]]: 0, [[HideCaller]]: *false* } to _sourceMappedFrames_.
+ 1. Let _generatedRange_ be FindInnermostGeneratedRange(_sourceMap_, _framePosition_).
+ 1. Repeat, while _generatedRange_ is not *null* and _generatedRange_.[[StackFrameType]] is ~none~,
+ 1. Let _callSite_ be _generatedRange_.[[CallSite]].
+ 1. If _callSite_ is not *null*, then
+ 1. Let _callSiteSource_ be _callSite_.[[Source]].
+ 1. Let _callSiteScope_ be FindInnermostOriginalScope(_callSiteSource_.[[Scope]], _callSite_).
+ 1. Let _callSiteName_ be FindFunctionName(_callSiteScope_).
+ 1. Append { [[Name]]: _callSiteName_, [[OriginalPosition]]: _callSite_, [[GeneratedFrameIndex]]: 0, [[HideCaller]]: *false* } to _sourceMappedFrames_.
+ 1. Set _generatedRange_ to its parent or *null* if it has no parent.
+ 1. If _generatedRange_ is not *null* and _generatedRange_.[[StackFrameType]] is ~hidden~, then
+ 1. Let _lastFrame_ be the last element of _sourceMappedFrames_.
+ 1. Set _lastFrame_.[[HideCaller]] to *true*.
+ 1. Return _sourceMappedFrames_.
+
+
+
+
+
+ BuildScopeChain (
+ _sourceMap_: a Decoded Source Map Record,
+ _debuggerScopes_: a List of Debugger Scope Records,
+ _generatedPosition_: a Debugger Position Record,
+ _generatedFrameIndex_: a non-negative integral Number,
+ _originalPosition_: a Debugger Position Record,
+ ): a List of Debugger Scope Records
+
+
+
+ 1. Let _innermostGeneratedRange_ be FindInnermostGeneratedRange(_sourceMap_.[[Ranges]], _generatedPosition_).
+ 1. Assert: _innermostGeneratedRange_ is not *null*.
+ 1. Let _originalSource_ be FindSourceForURL(_sourceMap_.[[Sources]], _originalPosition_.[[URL]]).
+ 1. Assert: _originalSource_ is not *null*.
+ 1. Let _originalScope_ be FindInnermostOriginalScope(_originalSource_.[[Scope]], _originalPosition_).
+ 1. Let _originalDebuggerScopes_ be a new empty List.
+ 1. Repeat, while _originalScope_ is not *null*,
+ 1. Let _generatedRange_ be FindAncestorRangeForDefinition(_innermostGeneratedRange_, _originalScope_).
+ 1. Let _originalBindings_ be a new empty Debugger Bindings Record.
+ 1. If _generatedRange_ is not *null*, then
+ 1. Assert: The length of _originalScope_.[[Variables]] is equal to the length of _generatedRange_.[[Bindings]].
+ 1. Let _scopeIndex_ be FindDebuggerScopeIndexForRange(_debuggerScopes_, _generatedRange_.[[Start]], _generatedRange_.[[End]]).
+ 1. Let _i_ be 0.
+ 1. Repeat, while _i_ is smaller than the length of _originalScope_.[[Variables]],
+ 1. Let _variable_ be _originalScope_.[[Variables]][i].
+ 1. Let _binding_ be FindBindingRecord(_generatedRange_.[[Bindings]][i], _generatedPosition_).
+ 1. Assert: _binding_ is not *null*.
+ 1. Let _value_ be ~unavailable~.
+ 1. If _binding_.[[Binding]] is not *null*, then
+ 1. Set _value_ to EvaluateInScope(_generatedFrameIndex_, _scopeIndex_, __binding_.[[Binding]]).
+ 1. Set the value of _variable_ in _originalBindings_ to _value_.
+ 1. Set _i_ to _i_ + 1.
+ 1. Else,
+ 1. For each String _variable_ of _originalScope_.[[Variables]], do
+ 1. Set the value of _variable_ in _originalBindings_ to ~unavailable~.
+ 1. Append { [[Start]]: _originalScope_.[[Start]], [[End]]: _originalScope_.[[End]], [[Bindings]]: _originalBindings_ } to _originalDebuggerScopes_.
+ 1. Set _originalScope_ to its parent or *null* if it has no parent.
+ 1. Return _originalDebuggerScopes_.
+
+
+
+