|
17 | 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
18 | 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
19 | 19 | // IN THE SOFTWARE.
|
20 |
| -'use strict'; |
21 | 20 |
|
| 21 | +/* eslint-disable strict */ |
22 | 22 | (function(keepAlive) {
|
23 | 23 | // Save original builtIns
|
24 | 24 | var
|
|
42 | 42 | var global = this;
|
43 | 43 |
|
44 | 44 | // Simulate V8 JavaScript stack trace API
|
45 |
| - function StackFrame(funcName, fileName, lineNumber, columnNumber) { |
| 45 | + function StackFrame(func, funcName, fileName, lineNumber, columnNumber) { |
46 | 46 | this.column = columnNumber;
|
47 | 47 | this.lineNumber = lineNumber;
|
48 | 48 | this.scriptName = fileName;
|
49 | 49 | this.functionName = funcName;
|
| 50 | + this.function = func; |
50 | 51 | }
|
51 | 52 |
|
| 53 | + StackFrame.prototype.getFunction = function() { |
| 54 | + // TODO: Fix if .stack is called from different callsite |
| 55 | + // from where Error() or Error.captureStackTrace was called |
| 56 | + return this.function; |
| 57 | + }; |
| 58 | + |
| 59 | + StackFrame.prototype.getTypeName = function() { |
| 60 | + //TODO : Fix this |
| 61 | + return this.functionName; |
| 62 | + }; |
| 63 | + |
| 64 | + StackFrame.prototype.getMethodName = function() { |
| 65 | + return this.functionName; |
| 66 | + }; |
| 67 | + |
52 | 68 | StackFrame.prototype.getFunctionName = function() {
|
53 | 69 | return this.functionName;
|
54 | 70 | };
|
|
70 | 86 | return false;
|
71 | 87 | };
|
72 | 88 |
|
| 89 | + StackFrame.prototype.isToplevel = function() { |
| 90 | + // TODO |
| 91 | + return false; |
| 92 | + }; |
| 93 | + |
| 94 | + StackFrame.prototype.isNative = function() { |
| 95 | + // TODO |
| 96 | + return false; |
| 97 | + }; |
| 98 | + |
| 99 | + StackFrame.prototype.isConstructor = function() { |
| 100 | + // TODO |
| 101 | + return false; |
| 102 | + }; |
| 103 | + |
73 | 104 | StackFrame.prototype.toString = function() {
|
74 | 105 | return (this.functionName || 'Anonymous function') + ' (' +
|
75 | 106 | this.scriptName + ':' + this.lineNumber + ':' + this.column + ')';
|
|
89 | 120 | // Parse 'stack' string into StackTrace frames. Skip top 'skipDepth' frames,
|
90 | 121 | // and optionally skip top to 'startName' function frames.
|
91 | 122 | function parseStack(stack, skipDepth, startName) {
|
92 |
| - var splittedStack = stack.split('\n'); |
93 |
| - splittedStack.splice(0, skipDepth + 1); // also skip top name/message line |
| 123 | + var stackSplitter = /\)\s*at/; |
| 124 | + var reStackDetails = /\s(?:at\s)?(.*)\s\((.*)/; |
| 125 | + var fileDetailsSplitter = /:(\d+)/; |
| 126 | + |
| 127 | + var curr = parseStack; |
| 128 | + var splittedStack = stack.split(stackSplitter); |
94 | 129 | var errstack = [];
|
95 | 130 |
|
96 | 131 | for (var i = 0; i < splittedStack.length; i++) {
|
97 |
| - var parens = /\(/.exec(splittedStack[i]); |
98 |
| - var funcName = splittedStack[i].substr(6, parens.index - 7); |
| 132 | + // parseStack has 1 frame lesser than skipDepth. So skip calling .caller |
| 133 | + // once. After that, continue calling .caller |
| 134 | + if (skipDepth != 1 && curr) { |
| 135 | + try { |
| 136 | + curr = curr.caller; |
| 137 | + } catch (e) { |
| 138 | + curr = undefined; // .caller might not be allowed in curr's context |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + if (skipDepth-- > 0) { |
| 143 | + continue; |
| 144 | + } |
| 145 | + |
| 146 | + var func = curr; |
| 147 | + var stackDetails = reStackDetails.exec(splittedStack[i]); |
| 148 | + var funcName = stackDetails[1]; |
99 | 149 |
|
100 | 150 | if (startName) {
|
101 | 151 | if (funcName === startName) {
|
|
107 | 157 | funcName = null;
|
108 | 158 | }
|
109 | 159 |
|
110 |
| - var location = splittedStack[i].substr(parens.index + 1, |
111 |
| - splittedStack[i].length - parens.index - 2); |
| 160 | + var fileDetails = stackDetails[2].split(fileDetailsSplitter); |
112 | 161 |
|
113 |
| - var fileName = location; |
114 |
| - var lineNumber = 0; |
115 |
| - var columnNumber = 0; |
| 162 | + var fileName = fileDetails[0]; |
| 163 | + var lineNumber = fileDetails[1] ? fileDetails[1] : 0; |
| 164 | + var columnNumber = fileDetails[3] ? fileDetails[3] : 0; |
116 | 165 |
|
117 |
| - var colonPattern = /:[0-9]+/g; |
118 |
| - var firstColon = colonPattern.exec(location); |
119 |
| - if (firstColon) { |
120 |
| - fileName = location.substr(0, firstColon.index); |
121 |
| - |
122 |
| - var secondColon = colonPattern.exec(location); |
123 |
| - if (secondColon) { |
124 |
| - lineNumber = parseInt(location.substr(firstColon.index + 1, |
125 |
| - secondColon.index - firstColon.index - 1), 10); |
126 |
| - columnNumber = parseInt(location.substr(secondColon.index + 1, |
127 |
| - location.length - secondColon.index), 10); |
128 |
| - } |
129 |
| - } |
130 | 166 | errstack.push(
|
131 |
| - new StackFrame(funcName, fileName, lineNumber, columnNumber)); |
| 167 | + new StackFrame(func, funcName, fileName, lineNumber, columnNumber)); |
132 | 168 | }
|
133 | 169 | return errstack;
|
134 | 170 | }
|
|
190 | 226 |
|
191 | 227 | var funcSkipDepth = findFuncDepth(func);
|
192 | 228 | var startFuncName = (func && funcSkipDepth < 0) ? func.name : undefined;
|
193 |
| - skipDepth += Math.max(funcSkipDepth, 0); |
| 229 | + skipDepth += Math.max(funcSkipDepth - 1, 0); |
194 | 230 |
|
195 | 231 | var currentStackTrace;
|
196 | 232 | function ensureStackTrace() {
|
|
216 | 252 | // this Chakra runtime would reset stack at throw time.
|
217 | 253 | Reflect_apply(oldStackDesc.set, e, [value]);
|
218 | 254 | }
|
| 255 | + |
| 256 | + // To retain overriden stackAccessors below,notify Chakra runtime to not |
| 257 | + // reset stack for this error object. |
| 258 | + if (e !== err) { |
| 259 | + Reflect_apply(oldStackDesc.set, err, ['']); |
| 260 | + } |
| 261 | + |
219 | 262 | Object_defineProperty(err, 'stack', {
|
220 | 263 | get: stackGetter, set: stackSetter, configurable: true, enumerable: false
|
221 | 264 | });
|
|
0 commit comments