Commit dd40b333 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Fix crash during exception stack unwinding.

This fixes a crash with a predicate used during stack unwinding of
WebAssembly frames during exception handling. The predicate caused an
observable side-effect in JavaScript during unwinding, code that is
inherently unhandlified and is not allowed to be observable.

The fix actually just removes the entire predicate. This is because the
updated proposal causes all JavaScript exceptions to participate in
WebAssembly exception handling, allowing modelling of "finally" language
constructs to perform cleanup independent of the embedders exception
details.

R=ahaas@chromium.org
TEST=mjsunit/regress/wasm/regress-8095
BUG=v8:8095

Change-Id: Ic03bc45e7b7f4562a431ccf910ee9ddcf558aa48
Reviewed-on: https://chromium-review.googlesource.com/1193445Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55457}
parent e36b49bd
......@@ -1124,19 +1124,6 @@ void ReportBootstrappingException(Handle<Object> exception,
#endif
}
bool Isolate::is_catchable_by_wasm(Object* exception) {
// TODO(titzer): thread WASM features here, or just remove this check?
if (!FLAG_experimental_wasm_eh) return false;
if (!is_catchable_by_javascript(exception) || !exception->IsJSError())
return false;
HandleScope scope(this);
Handle<Object> exception_handle(exception, this);
return JSReceiver::HasProperty(Handle<JSReceiver>::cast(exception_handle),
factory()->InternalizeUtf8String(
wasm::WasmException::kRuntimeIdStr))
.IsJust();
}
Object* Isolate::Throw(Object* raw_exception, MessageLocation* location) {
DCHECK(!has_pending_exception());
......@@ -1310,11 +1297,10 @@ Object* Isolate::UnwindAndFindHandler() {
trap_handler::ClearThreadInWasm();
}
if (!is_catchable_by_wasm(exception)) {
break;
}
int stack_slots = 0; // Will contain stack slot count of frame.
// For WebAssembly frames we perform a lookup in the handler table.
if (!catchable_by_js) break;
WasmCompiledFrame* wasm_frame = static_cast<WasmCompiledFrame*>(frame);
int stack_slots = 0; // Will contain stack slot count of frame.
int offset = wasm_frame->LookupExceptionHandlerInTable(&stack_slots);
if (offset < 0) break;
// Compute the stack pointer from the frame pointer. This ensures that
......@@ -1324,7 +1310,7 @@ Object* Isolate::UnwindAndFindHandler() {
stack_slots * kPointerSize;
// This is going to be handled by Wasm, so we need to set the TLS flag
// again.
// again. It was cleared above assuming the frame would be unwound.
trap_handler::SetThreadInWasm();
set_wasm_caught_exception(exception);
......
......@@ -757,7 +757,6 @@ class Isolate : private HiddenFactory {
bool IsExternalHandlerOnTop(Object* exception);
inline bool is_catchable_by_javascript(Object* exception);
bool is_catchable_by_wasm(Object* exception);
// JS execution stack (see frames.h).
static Address c_entry_fp(ThreadLocalTop* thread) {
......
// Copyright 2018 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.
// Flags: --expose-wasm --experimental-wasm-eh
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
// Prepare a special error object to throw.
var error = new Error("my error");
error.__proto__ = new Proxy(new Error(), {
has(target, property, receiver) {
assertUnreachable();
}
});
// Throw it through a WebAssembly module.
var builder = new WasmModuleBuilder();
builder.addImport('mod', 'fun', kSig_v_v);
builder.addFunction("funnel", kSig_v_v)
.addBody([kExprCallFunction, 0])
.exportFunc();
var instance = builder.instantiate({ mod: {fun: function() { throw error }}});
assertThrows(instance.exports.funnel, Error);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment