Skip to content

Commit c48ae2d

Browse files
bcoeCommit Bot
authored andcommitted
stack-trace-api: implement getEnclosingLine/Column
Introduces getEnclosingColumn and getEnclosingLine on CallSite so that the position can be used to lookup the original symbol for function when source maps are used. BUG=v8:11157 Change-Id: I06c4c374d172d206579abb170c7b7a2bd3bb159f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2547218 Reviewed-by: Jakob Kummerow <[email protected]> Commit-Queue: Benjamin Coe <[email protected]> Cr-Commit-Position: refs/heads/master@{#71343}
1 parent a48fcd6 commit c48ae2d

7 files changed

Lines changed: 114 additions & 0 deletions

File tree

src/builtins/builtins-callsite.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,22 @@ BUILTIN(CallSitePrototypeGetColumnNumber) {
5353
return PositiveNumberOrNull(it.Frame()->GetColumnNumber(), isolate);
5454
}
5555

56+
BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) {
57+
HandleScope scope(isolate);
58+
CHECK_CALLSITE(recv, "getEnclosingColumnNumber");
59+
FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
60+
GetFrameIndex(isolate, recv));
61+
return PositiveNumberOrNull(it.Frame()->GetEnclosingColumnNumber(), isolate);
62+
}
63+
64+
BUILTIN(CallSitePrototypeGetEnclosingLineNumber) {
65+
HandleScope scope(isolate);
66+
CHECK_CALLSITE(recv, "getEnclosingLineNumber");
67+
FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
68+
GetFrameIndex(isolate, recv));
69+
return PositiveNumberOrNull(it.Frame()->GetEnclosingLineNumber(), isolate);
70+
}
71+
5672
BUILTIN(CallSitePrototypeGetEvalOrigin) {
5773
HandleScope scope(isolate);
5874
CHECK_CALLSITE(recv, "getEvalOrigin");

src/builtins/builtins-definitions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ namespace internal {
367367
\
368368
/* CallSite */ \
369369
CPP(CallSitePrototypeGetColumnNumber) \
370+
CPP(CallSitePrototypeGetEnclosingColumnNumber) \
371+
CPP(CallSitePrototypeGetEnclosingLineNumber) \
370372
CPP(CallSitePrototypeGetEvalOrigin) \
371373
CPP(CallSitePrototypeGetFileName) \
372374
CPP(CallSitePrototypeGetFunction) \

src/execution/messages.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,26 @@ int JSStackFrame::GetColumnNumber() {
514514
return kNone;
515515
}
516516

517+
int JSStackFrame::GetEnclosingLineNumber() {
518+
if (HasScript()) {
519+
Handle<SharedFunctionInfo> shared = handle(function_->shared(), isolate_);
520+
return Script::GetLineNumber(GetScript(),
521+
shared->function_token_position()) + 1;
522+
} else {
523+
return kNone;
524+
}
525+
}
526+
527+
int JSStackFrame::GetEnclosingColumnNumber() {
528+
if (HasScript()) {
529+
Handle<SharedFunctionInfo> shared = handle(function_->shared(), isolate_);
530+
return Script::GetColumnNumber(GetScript(),
531+
shared->function_token_position()) + 1;
532+
} else {
533+
return kNone;
534+
}
535+
}
536+
517537
int JSStackFrame::GetPromiseIndex() const {
518538
return (is_promise_all_ || is_promise_any_) ? offset_ : kNone;
519539
}
@@ -602,6 +622,12 @@ int WasmStackFrame::GetPosition() const {
602622

603623
int WasmStackFrame::GetColumnNumber() { return GetModuleOffset(); }
604624

625+
int WasmStackFrame::GetEnclosingColumnNumber() {
626+
const int function_offset =
627+
GetWasmFunctionOffset(wasm_instance_->module(), wasm_func_index_);
628+
return function_offset;
629+
}
630+
605631
int WasmStackFrame::GetModuleOffset() const {
606632
const int function_offset =
607633
GetWasmFunctionOffset(wasm_instance_->module(), wasm_func_index_);
@@ -672,6 +698,26 @@ int AsmJsWasmStackFrame::GetColumnNumber() {
672698
return Script::GetColumnNumber(script, GetPosition()) + 1;
673699
}
674700

701+
int AsmJsWasmStackFrame::GetEnclosingLineNumber() {
702+
DCHECK_LE(0, GetPosition());
703+
Handle<Script> script(wasm_instance_->module_object().script(), isolate_);
704+
DCHECK(script->IsUserJavaScript());
705+
int byte_offset = GetSourcePosition(wasm_instance_->module(),
706+
wasm_func_index_, 0,
707+
is_at_number_conversion_);
708+
return Script::GetLineNumber(script, byte_offset) + 1;
709+
}
710+
711+
int AsmJsWasmStackFrame::GetEnclosingColumnNumber() {
712+
DCHECK_LE(0, GetPosition());
713+
Handle<Script> script(wasm_instance_->module_object().script(), isolate_);
714+
DCHECK(script->IsUserJavaScript());
715+
int byte_offset = GetSourcePosition(wasm_instance_->module(),
716+
wasm_func_index_, 0,
717+
is_at_number_conversion_);
718+
return Script::GetColumnNumber(script, byte_offset) + 1;
719+
}
720+
675721
FrameArrayIterator::FrameArrayIterator(Isolate* isolate,
676722
Handle<FrameArray> array, int frame_ix)
677723
: isolate_(isolate), array_(array), frame_ix_(frame_ix) {}

src/execution/messages.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ class StackFrameBase {
8787
// Return 0-based Wasm function index. Returns -1 for non-Wasm frames.
8888
virtual int GetWasmFunctionIndex();
8989

90+
virtual int GetEnclosingColumnNumber() = 0;
91+
virtual int GetEnclosingLineNumber() = 0;
92+
9093
// Returns the index of the rejected promise in the Promise combinator input,
9194
// or -1 if this frame is not a Promise combinator frame.
9295
virtual int GetPromiseIndex() const = 0;
@@ -133,6 +136,9 @@ class JSStackFrame : public StackFrameBase {
133136
int GetLineNumber() override;
134137
int GetColumnNumber() override;
135138

139+
int GetEnclosingColumnNumber() override;
140+
int GetEnclosingLineNumber() override;
141+
136142
int GetPromiseIndex() const override;
137143

138144
bool IsNative() override;
@@ -183,6 +189,8 @@ class WasmStackFrame : public StackFrameBase {
183189
int GetPosition() const override;
184190
int GetLineNumber() override { return 0; }
185191
int GetColumnNumber() override;
192+
int GetEnclosingColumnNumber() override;
193+
int GetEnclosingLineNumber() override { return 0; }
186194
int GetWasmFunctionIndex() override { return wasm_func_index_; }
187195

188196
int GetPromiseIndex() const override { return GetPosition(); }
@@ -231,6 +239,9 @@ class AsmJsWasmStackFrame : public WasmStackFrame {
231239
int GetLineNumber() override;
232240
int GetColumnNumber() override;
233241

242+
int GetEnclosingColumnNumber() override;
243+
int GetEnclosingLineNumber() override;
244+
234245
private:
235246
friend class FrameArrayIterator;
236247
AsmJsWasmStackFrame() = default;

src/init/bootstrapper.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4202,6 +4202,10 @@ void Genesis::InitializeCallSiteBuiltins() {
42024202

42034203
FunctionInfo infos[] = {
42044204
{"getColumnNumber", Builtins::kCallSitePrototypeGetColumnNumber},
4205+
{"getEnclosingColumnNumber",
4206+
Builtins::kCallSitePrototypeGetEnclosingColumnNumber},
4207+
{"getEnclosingLineNumber",
4208+
Builtins::kCallSitePrototypeGetEnclosingLineNumber},
42054209
{"getEvalOrigin", Builtins::kCallSitePrototypeGetEvalOrigin},
42064210
{"getFileName", Builtins::kCallSitePrototypeGetFileName},
42074211
{"getFunction", Builtins::kCallSitePrototypeGetFunction},

test/mjsunit/stack-traces.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,23 @@ var constructor = new Error().stack[0].constructor;
439439
assertThrows(() => constructor.call());
440440
assertThrows(() => constructor.call(
441441
null, {}, () => undefined, {valueOf() { return 0 }}, false));
442+
443+
// Test stack frames populated with line/column information for both call site
444+
// and enclosing function:
445+
Error.prepareStackTrace = function(e, frames) {
446+
assertMatches(/stack-traces\.js/, frames[0].getFileName());
447+
assertEquals(3, frames[0].getEnclosingColumnNumber());
448+
assertEquals(11, frames[0].getColumnNumber());
449+
assertTrue(frames[0].getEnclosingLineNumber() < frames[0].getLineNumber());
450+
}
451+
try {
452+
function a() {
453+
b();
454+
}
455+
function b() {
456+
throw Error('hello world');
457+
}
458+
a();
459+
} catch (err) {
460+
err.stack;
461+
}

test/mjsunit/wasm/asm-wasm-stack.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,18 @@ function generateOverflowWasmFromAsmJs() {
154154
['f', 135, 12] // --
155155
]);
156156
})();
157+
158+
(function EnclosingFunctionOffsets() {
159+
const fun = generateWasmFromAsmJs(this, {throwFunc: throwException});
160+
assertTrue(%IsWasmCode(fun));
161+
let e = null;
162+
try {
163+
fun(0);
164+
} catch (ex) {
165+
e = ex;
166+
}
167+
assertEquals(68, e.stack[2].getLineNumber());
168+
assertEquals(15, e.stack[2].getColumnNumber());
169+
assertEquals(65, e.stack[2].getEnclosingLineNumber());
170+
assertEquals(3, e.stack[2].getEnclosingColumnNumber());
171+
})();

0 commit comments

Comments
 (0)