diff --git a/common.gypi b/common.gypi index 8bc115b1d6bfbd..77ffb7e4867ca6 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.19', + 'v8_embedder_string': '-node.20', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/builtins/builtins-callsite.cc b/deps/v8/src/builtins/builtins-callsite.cc index 5b7807ed4a9e50..63e4d7a572e53b 100644 --- a/deps/v8/src/builtins/builtins-callsite.cc +++ b/deps/v8/src/builtins/builtins-callsite.cc @@ -53,6 +53,22 @@ BUILTIN(CallSitePrototypeGetColumnNumber) { return PositiveNumberOrNull(it.Frame()->GetColumnNumber(), isolate); } +BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) { + HandleScope scope(isolate); + CHECK_CALLSITE(recv, "getEnclosingColumnNumber"); + FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), + GetFrameIndex(isolate, recv)); + return PositiveNumberOrNull(it.Frame()->GetEnclosingColumnNumber(), isolate); +} + +BUILTIN(CallSitePrototypeGetEnclosingLineNumber) { + HandleScope scope(isolate); + CHECK_CALLSITE(recv, "getEnclosingLineNumber"); + FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), + GetFrameIndex(isolate, recv)); + return PositiveNumberOrNull(it.Frame()->GetEnclosingLineNumber(), isolate); +} + BUILTIN(CallSitePrototypeGetEvalOrigin) { HandleScope scope(isolate); CHECK_CALLSITE(recv, "getEvalOrigin"); diff --git a/deps/v8/src/builtins/builtins-definitions.h b/deps/v8/src/builtins/builtins-definitions.h index 511e748acdaa2c..10bbd12f8a1125 100644 --- a/deps/v8/src/builtins/builtins-definitions.h +++ b/deps/v8/src/builtins/builtins-definitions.h @@ -364,6 +364,8 @@ namespace internal { \ /* CallSite */ \ CPP(CallSitePrototypeGetColumnNumber) \ + CPP(CallSitePrototypeGetEnclosingColumnNumber) \ + CPP(CallSitePrototypeGetEnclosingLineNumber) \ CPP(CallSitePrototypeGetEvalOrigin) \ CPP(CallSitePrototypeGetFileName) \ CPP(CallSitePrototypeGetFunction) \ diff --git a/deps/v8/src/execution/messages.cc b/deps/v8/src/execution/messages.cc index 86e3d48882d601..ab6c6bc3926191 100644 --- a/deps/v8/src/execution/messages.cc +++ b/deps/v8/src/execution/messages.cc @@ -514,6 +514,26 @@ int JSStackFrame::GetColumnNumber() { return kNone; } +int JSStackFrame::GetEnclosingLineNumber() { + if (HasScript()) { + Handle<SharedFunctionInfo> shared = handle(function_->shared(), isolate_); + return Script::GetLineNumber(GetScript(), + shared->function_token_position()) + 1; + } else { + return kNone; + } +} + +int JSStackFrame::GetEnclosingColumnNumber() { + if (HasScript()) { + Handle<SharedFunctionInfo> shared = handle(function_->shared(), isolate_); + return Script::GetColumnNumber(GetScript(), + shared->function_token_position()) + 1; + } else { + return kNone; + } +} + int JSStackFrame::GetPromiseIndex() const { return (is_promise_all_ || is_promise_any_) ? offset_ : kNone; } @@ -602,6 +622,12 @@ int WasmStackFrame::GetPosition() const { int WasmStackFrame::GetColumnNumber() { return GetModuleOffset(); } +int WasmStackFrame::GetEnclosingColumnNumber() { + const int function_offset = + GetWasmFunctionOffset(wasm_instance_->module(), wasm_func_index_); + return function_offset; +} + int WasmStackFrame::GetModuleOffset() const { const int function_offset = GetWasmFunctionOffset(wasm_instance_->module(), wasm_func_index_); @@ -672,6 +698,26 @@ int AsmJsWasmStackFrame::GetColumnNumber() { return Script::GetColumnNumber(script, GetPosition()) + 1; } +int AsmJsWasmStackFrame::GetEnclosingLineNumber() { + DCHECK_LE(0, GetPosition()); + Handle<Script> script(wasm_instance_->module_object().script(), isolate_); + DCHECK(script->IsUserJavaScript()); + int byte_offset = GetSourcePosition(wasm_instance_->module(), + wasm_func_index_, 0, + is_at_number_conversion_); + return Script::GetLineNumber(script, byte_offset) + 1; +} + +int AsmJsWasmStackFrame::GetEnclosingColumnNumber() { + DCHECK_LE(0, GetPosition()); + Handle<Script> script(wasm_instance_->module_object().script(), isolate_); + DCHECK(script->IsUserJavaScript()); + int byte_offset = GetSourcePosition(wasm_instance_->module(), + wasm_func_index_, 0, + is_at_number_conversion_); + return Script::GetColumnNumber(script, byte_offset) + 1; +} + FrameArrayIterator::FrameArrayIterator(Isolate* isolate, Handle<FrameArray> array, int frame_ix) : isolate_(isolate), array_(array), frame_ix_(frame_ix) {} diff --git a/deps/v8/src/execution/messages.h b/deps/v8/src/execution/messages.h index 16ddd034699ad1..ad72d762d274d4 100644 --- a/deps/v8/src/execution/messages.h +++ b/deps/v8/src/execution/messages.h @@ -87,6 +87,9 @@ class StackFrameBase { // Return 0-based Wasm function index. Returns -1 for non-Wasm frames. virtual int GetWasmFunctionIndex(); + virtual int GetEnclosingColumnNumber() = 0; + virtual int GetEnclosingLineNumber() = 0; + // Returns the index of the rejected promise in the Promise combinator input, // or -1 if this frame is not a Promise combinator frame. virtual int GetPromiseIndex() const = 0; @@ -133,6 +136,9 @@ class JSStackFrame : public StackFrameBase { int GetLineNumber() override; int GetColumnNumber() override; + int GetEnclosingColumnNumber() override; + int GetEnclosingLineNumber() override; + int GetPromiseIndex() const override; bool IsNative() override; @@ -183,6 +189,8 @@ class WasmStackFrame : public StackFrameBase { int GetPosition() const override; int GetLineNumber() override { return 0; } int GetColumnNumber() override; + int GetEnclosingColumnNumber() override; + int GetEnclosingLineNumber() override { return 0; } int GetWasmFunctionIndex() override { return wasm_func_index_; } int GetPromiseIndex() const override { return GetPosition(); } @@ -231,6 +239,9 @@ class AsmJsWasmStackFrame : public WasmStackFrame { int GetLineNumber() override; int GetColumnNumber() override; + int GetEnclosingColumnNumber() override; + int GetEnclosingLineNumber() override; + private: friend class FrameArrayIterator; AsmJsWasmStackFrame() = default; diff --git a/deps/v8/src/init/bootstrapper.cc b/deps/v8/src/init/bootstrapper.cc index c5cfceb0696874..990a7804fda7a7 100644 --- a/deps/v8/src/init/bootstrapper.cc +++ b/deps/v8/src/init/bootstrapper.cc @@ -4090,6 +4090,10 @@ void Genesis::InitializeCallSiteBuiltins() { FunctionInfo infos[] = { {"getColumnNumber", Builtins::kCallSitePrototypeGetColumnNumber}, + {"getEnclosingColumnNumber", + Builtins::kCallSitePrototypeGetEnclosingColumnNumber}, + {"getEnclosingLineNumber", + Builtins::kCallSitePrototypeGetEnclosingLineNumber}, {"getEvalOrigin", Builtins::kCallSitePrototypeGetEvalOrigin}, {"getFileName", Builtins::kCallSitePrototypeGetFileName}, {"getFunction", Builtins::kCallSitePrototypeGetFunction}, diff --git a/deps/v8/test/mjsunit/stack-traces.js b/deps/v8/test/mjsunit/stack-traces.js index a46b2b3940bf22..949d8390b49f13 100644 --- a/deps/v8/test/mjsunit/stack-traces.js +++ b/deps/v8/test/mjsunit/stack-traces.js @@ -439,3 +439,23 @@ var constructor = new Error().stack[0].constructor; assertThrows(() => constructor.call()); assertThrows(() => constructor.call( null, {}, () => undefined, {valueOf() { return 0 }}, false)); + +// Test stack frames populated with line/column information for both call site +// and enclosing function: +Error.prepareStackTrace = function(e, frames) { + assertMatches(/stack-traces\.js/, frames[0].getFileName()); + assertEquals(3, frames[0].getEnclosingColumnNumber()); + assertEquals(11, frames[0].getColumnNumber()); + assertTrue(frames[0].getEnclosingLineNumber() < frames[0].getLineNumber()); +} +try { + function a() { + b(); + } + function b() { + throw Error('hello world'); + } + a(); +} catch (err) { + err.stack; +} diff --git a/deps/v8/test/mjsunit/wasm/asm-wasm-stack.js b/deps/v8/test/mjsunit/wasm/asm-wasm-stack.js index b416aaa141eb3d..9e09419d06a982 100644 --- a/deps/v8/test/mjsunit/wasm/asm-wasm-stack.js +++ b/deps/v8/test/mjsunit/wasm/asm-wasm-stack.js @@ -154,3 +154,18 @@ function generateOverflowWasmFromAsmJs() { ['f', 135, 12] // -- ]); })(); + +(function EnclosingFunctionOffsets() { + const fun = generateWasmFromAsmJs(this, {throwFunc: throwException}); + assertTrue(%IsWasmCode(fun)); + let e = null; + try { + fun(0); + } catch (ex) { + e = ex; + } + assertEquals(68, e.stack[2].getLineNumber()); + assertEquals(15, e.stack[2].getColumnNumber()); + assertEquals(65, e.stack[2].getEnclosingLineNumber()); + assertEquals(3, e.stack[2].getEnclosingColumnNumber()); +})();