[wasm][eh] Add WebAssembly.Exception traceStack parameter
Context: https://github.com/WebAssembly/exception-handling/pull/197 This change adds the optional {traceStack: <bool>} parameter to the WebAssembly.Exception constructor. When set to true, this captures the stack and sets the `stack` accessor on the exception object. R=jkummerow@chromium.org Bug: v8:8091 Change-Id: I4430b6317b27ec62f11e951fbe95ee480ac72d37 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3688402 Commit-Queue: Thibaud Michaud <thibaudm@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/main@{#81041}
This commit is contained in:
parent
193b82553e
commit
cfea0eb0e8
@ -19,6 +19,7 @@
|
||||
#include "src/execution/execution.h"
|
||||
#include "src/execution/frames-inl.h"
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/execution/messages.h"
|
||||
#include "src/handles/global-handles-inl.h"
|
||||
#include "src/handles/handles.h"
|
||||
#include "src/heap/factory.h"
|
||||
@ -1823,6 +1824,33 @@ void WebAssemblyException(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
tag_object->serialized_signature(), i_isolate);
|
||||
EncodeExceptionValues(isolate, signature, args[1], &thrower, values);
|
||||
if (thrower.error()) return;
|
||||
|
||||
// Third argument: optional ExceptionOption ({traceStack: <bool>}).
|
||||
if (!args[2]->IsNullOrUndefined() && !args[2]->IsObject()) {
|
||||
thrower.TypeError("Argument 2 is not an object");
|
||||
return;
|
||||
}
|
||||
if (args[2]->IsObject()) {
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
Local<Object> trace_stack_obj = Local<Object>::Cast(args[2]);
|
||||
Local<String> trace_stack_key = v8_str(isolate, "traceStack");
|
||||
v8::MaybeLocal<v8::Value> maybe_trace_stack =
|
||||
trace_stack_obj->Get(context, trace_stack_key);
|
||||
v8::Local<Value> trace_stack_value;
|
||||
if (maybe_trace_stack.ToLocal(&trace_stack_value) &&
|
||||
trace_stack_value->BooleanValue(isolate)) {
|
||||
auto caller = Utils::OpenHandle(*args.NewTarget());
|
||||
i_isolate->CaptureAndSetErrorStack(runtime_exception, i::SKIP_NONE,
|
||||
caller);
|
||||
i::Handle<i::AccessorInfo> error_stack =
|
||||
i_isolate->factory()->error_stack_accessor();
|
||||
i::Handle<i::Name> name(i::Name::cast(error_stack->name()), i_isolate);
|
||||
i::JSObject::SetAccessor(runtime_exception, name, error_stack,
|
||||
i::DONT_ENUM)
|
||||
.Assert();
|
||||
}
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(
|
||||
Utils::ToLocal(i::Handle<i::Object>::cast(runtime_exception)));
|
||||
}
|
||||
|
19
test/message/fail/wasm-exception-stack-trace.js
Normal file
19
test/message/fail/wasm-exception-stack-trace.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
let builder = new WasmModuleBuilder();
|
||||
let tag = new WebAssembly.Tag({parameters: []});
|
||||
let import_index = builder.addImport("m", "throw", kSig_v_v);
|
||||
builder.addFunction("throw", kSig_v_v)
|
||||
.addBody([
|
||||
kExprCallFunction, import_index
|
||||
]).exportFunc();
|
||||
function throw_wasm_exn() {
|
||||
let exception = new WebAssembly.Exception(tag, [], {traceStack: true});
|
||||
throw exception;
|
||||
}
|
||||
let instance = builder.instantiate({"m": {"throw": throw_wasm_exn}});
|
||||
instance.exports.throw();
|
7
test/message/fail/wasm-exception-stack-trace.out
Normal file
7
test/message/fail/wasm-exception-stack-trace.out
Normal file
@ -0,0 +1,7 @@
|
||||
*%(basename)s:16: [object WebAssembly.Exception]
|
||||
throw exception;
|
||||
^
|
||||
Error
|
||||
at throw_wasm_exn (*%(basename)s:15:19)
|
||||
at throw (wasm://wasm/f232c786:wasm-function[1]:0x32)
|
||||
at *%(basename)s:19:23
|
@ -99,6 +99,19 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
assertDoesNotThrow(() => new WebAssembly.Exception(tag, [3, 4, 5n, 6, {}]));
|
||||
})();
|
||||
|
||||
(function TestExceptionStackTrace() {
|
||||
print(arguments.callee.name);
|
||||
let tag = new WebAssembly.Tag({parameters: []});
|
||||
let exn = new WebAssembly.Exception(tag, []);
|
||||
assertEquals(undefined, exn.stack);
|
||||
exn = new WebAssembly.Exception(tag, [], {traceStack: false});
|
||||
assertEquals(undefined, exn.stack);
|
||||
exn = new WebAssembly.Exception(tag, [], {traceStack: true});
|
||||
assertTrue(exn.stack.indexOf(arguments.callee.name) > 0);
|
||||
assertThrows(() => new WebAssembly.Exception(tag, [], 0), TypeError,
|
||||
/Argument 2 is not an object/);
|
||||
})();
|
||||
|
||||
(function TestCatchJSException() {
|
||||
print(arguments.callee.name);
|
||||
let builder = new WasmModuleBuilder();
|
||||
|
Loading…
Reference in New Issue
Block a user