[wasm][eh] Make stack overflows uncatchable
R=jkummerow@chromium.org Change-Id: Ibc772d81765e10331fa8753e8b7dfd3d18509819 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2859864 Commit-Queue: Thibaud Michaud <thibaudm@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#74333}
This commit is contained in:
parent
d6fa333dda
commit
620da72cef
@ -1404,11 +1404,13 @@ Object Isolate::StackOverflow() {
|
||||
MessageFormatter::TemplateString(MessageTemplate::kStackOverflow));
|
||||
Handle<Object> options = factory()->undefined_value();
|
||||
Handle<Object> no_caller;
|
||||
Handle<Object> exception;
|
||||
Handle<JSObject> exception;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
this, exception,
|
||||
ErrorUtils::Construct(this, fun, fun, msg, options, SKIP_NONE, no_caller,
|
||||
ErrorUtils::StackTraceCollection::kSimple));
|
||||
JSObject::AddProperty(this, exception, factory()->wasm_uncatchable_symbol(),
|
||||
factory()->true_value(), NONE);
|
||||
|
||||
Throw(*exception);
|
||||
|
||||
|
@ -574,6 +574,64 @@ WASM_EXEC_TEST(TryCatchTrapRemByZero) {
|
||||
TestTrapNotCaught(code, arraysize(code), execution_tier);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// TODO(cleanup): Define in cctest.h and re-use where appropriate.
|
||||
class IsolateScope {
|
||||
public:
|
||||
IsolateScope() {
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
isolate_ = v8::Isolate::New(create_params);
|
||||
isolate_->Enter();
|
||||
}
|
||||
|
||||
~IsolateScope() {
|
||||
isolate_->Exit();
|
||||
isolate_->Dispose();
|
||||
}
|
||||
|
||||
v8::Isolate* isolate() { return isolate_; }
|
||||
Isolate* i_isolate() { return reinterpret_cast<Isolate*>(isolate_); }
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
UNINITIALIZED_WASM_EXEC_TEST(TestStackOverflowNotCaught) {
|
||||
TestSignatures sigs;
|
||||
EXPERIMENTAL_FLAG_SCOPE(eh);
|
||||
// FLAG_stack_size must be set before isolate initialization.
|
||||
FlagScope<int32_t> stack_size(&v8::internal::FLAG_stack_size, 8);
|
||||
|
||||
IsolateScope isolate_scope;
|
||||
LocalContext context(isolate_scope.isolate());
|
||||
|
||||
WasmRunner<uint32_t> r(execution_tier, nullptr, "main",
|
||||
kRuntimeExceptionSupport, isolate_scope.i_isolate());
|
||||
|
||||
// Build a function that calls itself until stack overflow.
|
||||
WasmFunctionCompiler& stack_overflow = r.NewFunction(sigs.v_v());
|
||||
byte stack_overflow_code[] = {kExprCallFunction,
|
||||
stack_overflow.function_index()};
|
||||
stack_overflow.Build(stack_overflow_code,
|
||||
stack_overflow_code + arraysize(stack_overflow_code));
|
||||
|
||||
// Build the main test function.
|
||||
BUILD(r, WASM_TRY_CATCH_ALL_T(kWasmI32,
|
||||
WASM_STMTS(WASM_I32V(1), kExprCallFunction,
|
||||
stack_overflow.function_index()),
|
||||
WASM_STMTS(WASM_I32V(1))));
|
||||
|
||||
if (execution_tier != TestExecutionTier::kInterpreter) {
|
||||
// Need to call through JS to allow for creation of stack traces.
|
||||
r.CheckCallViaJSTraps();
|
||||
} else {
|
||||
constexpr int stopped = 0;
|
||||
CHECK_EQ(stopped, r.CallInterpreter());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Regress1180457) {
|
||||
TestSignatures sigs;
|
||||
EXPERIMENTAL_FLAG_SCOPE(eh);
|
||||
|
@ -3106,9 +3106,6 @@ class WasmInterpreterInternals {
|
||||
// it to 0 here such that we report the same position as in compiled code.
|
||||
frames_.back().pc = 0;
|
||||
isolate_->StackOverflow();
|
||||
if (FLAG_experimental_wasm_eh) {
|
||||
possible_nondeterminism_ = true;
|
||||
}
|
||||
if (HandleException(isolate_) == WasmInterpreter::HANDLED) {
|
||||
ReloadFromFrameOnException(decoder, target, pc, limit);
|
||||
return true;
|
||||
|
@ -263,6 +263,27 @@ load("test/mjsunit/wasm/exceptions-utils.js");
|
||||
assertInstanceof(caught.__proto__, WebAssembly.RuntimeError);
|
||||
})();
|
||||
|
||||
(function TestStackOverflowNotCaught() {
|
||||
print(arguments.callee.name);
|
||||
function stack_overflow() {
|
||||
%ThrowStackOverflow();
|
||||
}
|
||||
let builder = new WasmModuleBuilder();
|
||||
let sig_v_v = builder.addType(kSig_v_v);
|
||||
let kStackOverflow = builder.addImport('', 'stack_overflow', sig_v_v);
|
||||
builder.addFunction('try_stack_overflow', kSig_v_v)
|
||||
.addBody([
|
||||
kExprTry, kWasmVoid,
|
||||
kExprCallFunction, 0,
|
||||
kExprCatchAll,
|
||||
kExprEnd
|
||||
]).exportFunc();
|
||||
let instance = builder.instantiate({'': {'stack_overflow': stack_overflow}});
|
||||
|
||||
assertThrows(() => instance.exports.try_stack_overflow(),
|
||||
RangeError, 'Maximum call stack size exceeded');
|
||||
})();
|
||||
|
||||
// Test that we can distinguish which exception was thrown by using a cascaded
|
||||
// sequence of nested try blocks with a single catch block each.
|
||||
(function TestCatchComplex1() {
|
||||
|
Loading…
Reference in New Issue
Block a user