Avoid calling out to JS during stack overflow

If an exception is thrown when there is a Promise being created, the Promise
catch prediction code would call into a part implemented in JavaScript to see if
the Promise has a catch handler. If it is not possible to call back into JS,
e.g., due to a stack overflow, then this would lead to a crash. This patch
"speculates" that, if it's impossible to call back into JavaScript, then the
error is unhandled, avoding the issue. In a future patch, the catch prediction
logic should be entirely written in C++, but this patch adds a minimal fix to
be more friendly to backports.

BUG=chromium:662935
R=jgruber

Review-Url: https://codereview.chromium.org/2487833002
Cr-Commit-Position: refs/heads/master@{#40851}
This commit is contained in:
littledan 2016-11-08 23:52:44 -08:00 committed by Commit bot
parent 3f2db58c89
commit 5975c47a6a
2 changed files with 19 additions and 0 deletions

View File

@ -1775,6 +1775,9 @@ void Isolate::PopPromise() {
bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<Object> promise) {
Handle<JSFunction> fun = promise_has_user_defined_reject_handler();
Handle<Object> has_reject_handler;
// If we are, e.g., overflowing the stack, don't try to call out to JS
if (!AllowJavascriptExecution::IsAllowed(this)) return false;
// Call the registered function to check for a handler
if (Execution::TryCall(this, fun, promise, 0, NULL)
.ToHandle(&has_reject_handler)) {
return has_reject_handler->IsTrue(this);

View File

@ -0,0 +1,16 @@
// Copyright 2016 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-debug-as debug
Debug = debug.Debug
function overflow() {
return new Promise(function foo() { foo() });
}
function listener(event, exec_state, event_data, data) { }
Debug.setListener(listener);
assertEquals(Promise, overflow().constructor);