Skip to content

Commit 7f5a623

Browse files
[js] more accurate handling of a call stack (fixes #13)
1 parent 7e489a8 commit 7f5a623

File tree

3 files changed

+56
-24
lines changed

3 files changed

+56
-24
lines changed

format/js/haxe/CallStack.hx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package haxe;
22

3+
#if js
4+
import jstack.js.JStack;
5+
#end
6+
7+
using StringTools;
8+
39
enum StackItem {
410
CFunction;
511
Module( m : String );
@@ -75,22 +81,35 @@ class CallStack {
7581
return jstack.Format.toString(stack);
7682
}
7783

78-
private static function makeStack(s #if cs : cs.system.diagnostics.StackTrace #elseif hl : hl.NativeArray<hl.Bytes> #end) {
84+
static var rie10 = ~/at (?:([A-Za-z0-9_. ]+)(?:.*?)\()?(.+?):([0-9]+):([0-9]+)(?:\))?$/;
85+
private static function makeStack(s:Dynamic):Array<StackItem> {
7986
if (s == null) {
8087
return [];
8188
} else if ((untyped __js__("typeof"))(s) == "string") {
8289
// Return the raw lines in browsers that don't support prepareStackTrace
8390
var stack : Array<String> = s.split("\n");
8491
if( stack[0] == "Error" ) stack.shift();
8592
var m = [];
86-
var rie10 = ~/^ at ([A-Za-z0-9_. ]+) \(([^)]+):([0-9]+):([0-9]+)\)$/;
8793
for( line in stack ) {
8894
if( rie10.match(line) ) {
89-
var path = rie10.matched(1).split(".");
90-
var meth = path.pop();
95+
var item = null;
96+
var symbol = rie10.matched(1);
97+
if(symbol != null) {
98+
var path = rie10.matched(1).trim().split(".");
99+
var meth = path.pop();
100+
item = meth == "Anonymous function" ? LocalFunction() : meth == "Global code" ? null : Method(path.join("."),meth);
101+
}
91102
var file = rie10.matched(2);
92103
var line = Std.parseInt(rie10.matched(3));
93-
m.push(FilePos( meth == "Anonymous function" ? LocalFunction() : meth == "Global code" ? null : Method(path.join("."),meth), file, line ));
104+
var column = Std.parseInt(rie10.matched(4));
105+
var pos:StackPos = wrapCallSite({
106+
getFileName: function() return file,
107+
getLineNumber: function() return line,
108+
getColumnNumber: function() return column
109+
});
110+
file = pos.getFileName();
111+
line = pos.getLineNumber();
112+
m.push(FilePos( item, file, line ));
94113
} else
95114
m.push(Module(StringTools.trim(line))); // A little weird, but better than nothing
96115
}

src/jstack/Tools.hx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,12 @@ class Tools {
2929
if (Context.defined('display') || !(Context.defined('debug') || Context.defined('JSTACK_FORCE'))) return;
3030
if (!Context.defined('js') && !Context.defined('php7') && !Context.defined('JSTACK_HAXE_DEV')) return;
3131

32-
if (Context.defined('JSTACK_FORMAT')) {
33-
if(Context.defined('js')) {
34-
Compiler.addClassPath(getJstackRootDir() + 'format/js');
35-
} else if(Context.defined('php')) {
36-
Compiler.addClassPath(getJstackRootDir() + 'format/php7');
37-
} else {
38-
throw 'Unexpected behavior';
39-
}
32+
if(Context.defined('js')) {
33+
Compiler.addClassPath(getJstackRootDir() + 'format/js');
34+
} else if(Context.defined('php')) {
35+
Compiler.addClassPath(getJstackRootDir() + 'format/php7');
36+
} else {
37+
throw 'Unexpected behavior';
4038
}
4139

4240
addInjectMetaToEntryPoint();

src/jstack/js/JStack.hx

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ class JStack {
1818
static var mapper : SourceMap;
1919
/** User-defined callback which will be invoked when sourceMap is loaded */
2020
static var onReadyCallback : Void->Void;
21+
/**
22+
* Full name of currently being executed js file.
23+
* If JStack fails to resolve current file name, then `currentFile` will be an empty string.
24+
*/
25+
static var currentFile(get,never):String;
26+
static var _currentFile:String = null;
2127

2228
/** Native stack lines like: at /home/alex/Work/HaXe/jstack/build/js/test.js:729:22 */
2329
static var stackFile = ~/^at (.+?js):([0-9]+):([0-9]+)$/;
@@ -70,7 +76,10 @@ class JStack {
7076
mapper = new SourceMap(sourceMapData);
7177

7278
CallStack.wrapCallSite = function (site) {
73-
var pos = mapper.originalPositionFor(site.getLineNumber(), site.getColumnNumber());
79+
var pos = null;
80+
if(site.getFileName() == currentFile) {
81+
pos = mapper.originalPositionFor(site.getLineNumber(), site.getColumnNumber());
82+
}
7483
return new StackPos(site, pos);
7584
}
7685

@@ -176,7 +185,7 @@ class JStack {
176185
switch (item) {
177186
case Module(line) if (stackFile.match(line)):
178187
var file = stackFile.matched(1);
179-
if (file != currentFile()) return item;
188+
if (file != currentFile) return item;
180189

181190
var line = Std.parseInt(stackFile.matched(2));
182191
var column = Std.parseInt(stackFile.matched(3));
@@ -186,7 +195,7 @@ class JStack {
186195

187196
case Module(line) if (stackFunctionFile.match(line)):
188197
var file = stackFunctionFile.matched(2);
189-
if (file != currentFile()) return item;
198+
if (file != currentFile) return item;
190199

191200
var line = Std.parseInt(stackFunctionFile.matched(3));
192201
var column = Std.parseInt(stackFunctionFile.matched(4));
@@ -206,14 +215,20 @@ class JStack {
206215
}
207216
}
208217

209-
/**
210-
Returns full name of currently being executed js file.
211-
**/
212-
static function currentFile () : Null<String> {
213-
if (isNode()) {
214-
return untyped __js__('__filename');
218+
static function get_currentFile () : String {
219+
if(_currentFile == null) {
220+
if (isNode()) {
221+
_currentFile = untyped __js__('__filename');
222+
} else {
223+
var erFile = ~/\((.+?):([0-9]+):([0-9]+)\)$/;
224+
if(erFile.match(new Error().stack)) {
225+
_currentFile = erFile.matched(1);
226+
} else {
227+
_currentFile = '';
228+
}
229+
}
215230
}
216-
return null;
231+
return _currentFile;
217232
}
218233
}
219234

@@ -234,7 +249,7 @@ class StackPos {
234249
}
235250

236251
public function getFunctionName () return js.getFunctionName();
237-
public function getFileName () return (hx == null || hx.originalLine == null ? js.getFileName() : hx.source);
252+
public function getFileName () return (hx == null || hx.source == null ? js.getFileName() : hx.source);
238253
public function getLineNumber () return (hx == null || hx.originalLine == null ? js.getLineNumber() : hx.originalLine);
239254

240255
}

0 commit comments

Comments
 (0)