Commit 3b54f89f authored by yangguo@chromium.org's avatar yangguo@chromium.org

Trigger exception debug events on Promise reject.

R=rossberg@chromium.org, aandrey@chromium.org
BUG=393913
LOG=Y

Review URL: https://codereview.chromium.org/440773004

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22913 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ef17fe76
......@@ -855,8 +855,8 @@ void Debug::Unload() {
ClearAllBreakPoints();
ClearStepping();
// Match unmatched PromiseHandlePrologue calls.
while (thread_local_.promise_on_stack_) PromiseHandleEpilogue();
// Match unmatched PopPromise calls.
while (thread_local_.promise_on_stack_) PopPromise();
// Return debugger is not loaded.
if (!is_loaded()) return;
......@@ -1272,30 +1272,29 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) {
}
PromiseOnStack::PromiseOnStack(Isolate* isolate,
PromiseOnStack* prev,
Handle<JSFunction> getter)
PromiseOnStack::PromiseOnStack(Isolate* isolate, PromiseOnStack* prev,
Handle<JSObject> promise)
: isolate_(isolate), prev_(prev) {
handler_ = StackHandler::FromAddress(
Isolate::handler(isolate->thread_local_top()));
getter_ = Handle<JSFunction>::cast(
isolate->global_handles()->Create(*getter));
promise_ =
Handle<JSObject>::cast(isolate->global_handles()->Create(*promise));
}
PromiseOnStack::~PromiseOnStack() {
isolate_->global_handles()->Destroy(Handle<Object>::cast(getter_).location());
isolate_->global_handles()->Destroy(
Handle<Object>::cast(promise_).location());
}
void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) {
void Debug::PushPromise(Handle<JSObject> promise) {
PromiseOnStack* prev = thread_local_.promise_on_stack_;
thread_local_.promise_on_stack_ =
new PromiseOnStack(isolate_, prev, promise_getter);
thread_local_.promise_on_stack_ = new PromiseOnStack(isolate_, prev, promise);
}
void Debug::PromiseHandleEpilogue() {
void Debug::PopPromise() {
if (thread_local_.promise_on_stack_ == NULL) return;
PromiseOnStack* prev = thread_local_.promise_on_stack_->prev();
delete thread_local_.promise_on_stack_;
......@@ -1303,35 +1302,40 @@ void Debug::PromiseHandleEpilogue() {
}
Handle<Object> Debug::GetPromiseForUncaughtException() {
Handle<Object> Debug::GetPromiseOnStackOnThrow() {
Handle<Object> undefined = isolate_->factory()->undefined_value();
if (thread_local_.promise_on_stack_ == NULL) return undefined;
Handle<JSFunction> promise_getter = thread_local_.promise_on_stack_->getter();
StackHandler* promise_catch = thread_local_.promise_on_stack_->handler();
StackHandler* promise_try = thread_local_.promise_on_stack_->handler();
// Find the top-most try-catch handler.
StackHandler* handler = StackHandler::FromAddress(
Isolate::handler(isolate_->thread_local_top()));
while (handler != NULL && !handler->is_catch()) {
handler = handler->next();
}
#ifdef DEBUG
// Make sure that our promise catch handler is in the list of handlers,
// even if it's not the top-most try-catch handler.
StackHandler* temp = handler;
while (temp != promise_catch && !temp->is_catch()) {
temp = temp->next();
CHECK(temp != NULL);
}
#endif // DEBUG
if (handler == promise_catch) {
return Execution::Call(
isolate_, promise_getter, undefined, 0, NULL).ToHandleChecked();
do {
if (handler == promise_try) {
// Mark the pushed try-catch handler to prevent a later duplicate event
// triggered with the following reject.
return thread_local_.promise_on_stack_->promise();
}
handler = handler->next();
// There must be a try-catch handler if a promise is on stack.
DCHECK_NE(NULL, handler);
// Throwing inside a Promise can be intercepted by an inner try-catch, so
// we stop at the first try-catch handler.
} while (!handler->is_catch());
return undefined;
}
bool Debug::PromiseHasRejectHandler(Handle<JSObject> promise) {
Handle<JSFunction> fun = Handle<JSFunction>::cast(
JSObject::GetDataProperty(isolate_->js_builtins_object(),
isolate_->factory()->NewStringFromStaticAscii(
"PromiseHasRejectHandler")));
Handle<Object> result =
Execution::Call(isolate_, fun, promise, 0, NULL).ToHandleChecked();
return result->IsTrue();
}
void Debug::PrepareStep(StepAction step_action,
int step_count,
StackFrame::Id frame_id) {
......@@ -2562,13 +2566,25 @@ MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
}
void Debug::OnException(Handle<Object> exception, bool uncaught) {
void Debug::OnThrow(Handle<Object> exception, bool uncaught) {
if (in_debug_scope() || ignore_events()) return;
HandleScope scope(isolate_);
OnException(exception, uncaught, GetPromiseOnStackOnThrow());
}
void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) {
if (in_debug_scope() || ignore_events()) return;
HandleScope scope(isolate_);
Handle<Object> promise = GetPromiseForUncaughtException();
uncaught |= !promise->IsUndefined();
OnException(value, false, promise);
}
void Debug::OnException(Handle<Object> exception, bool uncaught,
Handle<Object> promise) {
if (promise->IsJSObject()) {
uncaught |= !PromiseHasRejectHandler(Handle<JSObject>::cast(promise));
}
// Bail out if exception breaks are not active
if (uncaught) {
// Uncaught exceptions are reported by either flags.
......
......@@ -335,17 +335,16 @@ class LockingCommandMessageQueue BASE_EMBEDDED {
class PromiseOnStack {
public:
PromiseOnStack(Isolate* isolate,
PromiseOnStack* prev,
Handle<JSFunction> getter);
PromiseOnStack(Isolate* isolate, PromiseOnStack* prev,
Handle<JSObject> getter);
~PromiseOnStack();
StackHandler* handler() { return handler_; }
Handle<JSFunction> getter() { return getter_; }
Handle<JSObject> promise() { return promise_; }
PromiseOnStack* prev() { return prev_; }
private:
Isolate* isolate_;
StackHandler* handler_;
Handle<JSFunction> getter_;
Handle<JSObject> promise_;
PromiseOnStack* prev_;
};
......@@ -361,7 +360,9 @@ class Debug {
public:
// Debug event triggers.
void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
void OnException(Handle<Object> exception, bool uncaught);
void OnThrow(Handle<Object> exception, bool uncaught);
void OnPromiseReject(Handle<JSObject> promise, Handle<Object> value);
void OnCompileError(Handle<Script> script);
void OnBeforeCompile(Handle<Script> script);
void OnAfterCompile(Handle<Script> script);
......@@ -452,8 +453,9 @@ class Debug {
bool IsBreakAtReturn(JavaScriptFrame* frame);
// Promise handling.
void PromiseHandlePrologue(Handle<JSFunction> promise_getter);
void PromiseHandleEpilogue();
// Push and pop a promise and the current try-catch handler.
void PushPromise(Handle<JSObject> promise);
void PopPromise();
// Support for LiveEdit
void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
......@@ -523,6 +525,9 @@ class Debug {
inline bool has_commands() const { return !command_queue_.IsEmpty(); }
inline bool ignore_events() const { return is_suppressed_ || !is_active_; }
void OnException(Handle<Object> exception, bool uncaught,
Handle<Object> promise);
// Constructors for debug event objects.
MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
const char* constructor_name,
......@@ -545,8 +550,9 @@ class Debug {
// Mirror cache handling.
void ClearMirrorCache();
// Returns a promise if it does not have a reject handler.
Handle<Object> GetPromiseForUncaughtException();
// Returns a promise if the pushed try-catch handler matches the current one.
Handle<Object> GetPromiseOnStackOnThrow();
bool PromiseHasRejectHandler(Handle<JSObject> promise);
void CallEventCallback(v8::DebugEvent event,
Handle<Object> exec_state,
......
......@@ -1026,7 +1026,7 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
// Notify debugger of exception.
if (catchable_by_javascript) {
debug()->OnException(exception_handle, report_exception);
debug()->OnThrow(exception_handle, report_exception);
}
// Generate the message if required.
......
......@@ -18,6 +18,7 @@ var PromiseReject;
var PromiseChain;
var PromiseCatch;
var PromiseThen;
var PromiseHasRejectHandler;
// mirror-debugger.js currently uses builtins.promiseStatus. It would be nice
// if we could move these property names into the closure below.
......@@ -29,6 +30,7 @@ var promiseValue = GLOBAL_PRIVATE("Promise#value");
var promiseOnResolve = GLOBAL_PRIVATE("Promise#onResolve");
var promiseOnReject = GLOBAL_PRIVATE("Promise#onReject");
var promiseRaw = GLOBAL_PRIVATE("Promise#raw");
var promiseDebug = GLOBAL_PRIVATE("Promise#debug");
var lastMicrotaskId = 0;
(function() {
......@@ -40,13 +42,13 @@ var lastMicrotaskId = 0;
throw MakeTypeError('resolver_not_a_function', [resolver]);
var promise = PromiseInit(this);
try {
%DebugPromiseHandlePrologue(function() { return promise });
%DebugPushPromise(promise);
resolver(function(x) { PromiseResolve(promise, x) },
function(r) { PromiseReject(promise, r) });
} catch (e) {
PromiseReject(promise, e);
} finally {
%DebugPromiseHandleEpilogue();
%DebugPopPromise();
}
}
......@@ -98,11 +100,7 @@ var lastMicrotaskId = 0;
function PromiseHandle(value, handler, deferred) {
try {
%DebugPromiseHandlePrologue(
function() {
var queue = GET_PRIVATE(deferred.promise, promiseOnReject);
return (queue && queue.length == 0) ? deferred.promise : UNDEFINED;
});
%DebugPushPromise(deferred.promise);
var result = handler(value);
if (result === deferred.promise)
throw MakeTypeError('promise_cyclic', [result]);
......@@ -111,14 +109,9 @@ var lastMicrotaskId = 0;
else
deferred.resolve(result);
} catch (exception) {
try {
%DebugPromiseHandlePrologue(function() { return deferred.promise });
deferred.reject(exception);
} catch (e) { } finally {
%DebugPromiseHandleEpilogue();
}
try { deferred.reject(exception); } catch (e) { }
} finally {
%DebugPromiseHandleEpilogue();
%DebugPopPromise();
}
}
......@@ -165,6 +158,13 @@ var lastMicrotaskId = 0;
}
PromiseReject = function PromiseReject(promise, r) {
// Check promise status to confirm that this reject has an effect.
// Check promiseDebug property to avoid duplicate event.
if (DEBUG_IS_ACTIVE &&
GET_PRIVATE(promise, promiseStatus) == 0 &&
!HAS_PRIVATE(promise, promiseDebug)) {
%DebugPromiseRejectEvent(promise, r);
}
PromiseDone(promise, -1, r, promiseOnReject)
}
......@@ -322,6 +322,16 @@ var lastMicrotaskId = 0;
return deferred.promise;
}
// Utility for debugger
PromiseHasRejectHandler = function PromiseHasRejectHandler() {
// Mark promise as already having triggered a reject event.
SET_PRIVATE(this, promiseDebug, true);
var queue = GET_PRIVATE(this, promiseOnReject);
return !IS_UNDEFINED(queue) && queue.length > 0;
};
// -------------------------------------------------------------------
// Install exported functions.
......
......@@ -5465,22 +5465,19 @@ RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
}
// The argument is a closure that is kept until the epilogue is called.
// On exception, the closure is called, which returns the promise if the
// exception is considered uncaught, or undefined otherwise.
RUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
DCHECK(args.length() == 1);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
isolate->debug()->PromiseHandlePrologue(promise_getter);
CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
isolate->debug()->PushPromise(promise);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
DCHECK(args.length() == 0);
SealHandleScope shs(isolate);
isolate->debug()->PromiseHandleEpilogue();
isolate->debug()->PopPromise();
return isolate->heap()->undefined_value();
}
......@@ -5494,6 +5491,16 @@ RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
}
RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
DCHECK(args.length() == 2);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
isolate->debug()->OnPromiseReject(promise, value);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
DCHECK(args.length() == 1);
HandleScope scope(isolate);
......
......@@ -76,9 +76,10 @@ namespace internal {
F(SetInlineBuiltinFlag, 1, 1) \
F(StoreArrayLiteralElement, 5, 1) \
F(DebugPrepareStepInIfStepping, 1, 1) \
F(DebugPromiseHandlePrologue, 1, 1) \
F(DebugPromiseHandleEpilogue, 0, 1) \
F(DebugPushPromise, 1, 1) \
F(DebugPopPromise, 0, 1) \
F(DebugPromiseEvent, 1, 1) \
F(DebugPromiseRejectEvent, 2, 1) \
F(DebugAsyncTaskEvent, 1, 1) \
F(FlattenString, 1, 1) \
F(LoadMutableDouble, 2, 1) \
......
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when we listen to uncaught exceptions and
// the Promise is rejected in a chained closure after it has been resolved.
// We expect no Exception debug event to be triggered.
Debug = debug.Debug;
var log = [];
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve(reject);
});
var q = p.chain(
function(value) {
assertEquals(["resolve", "end main"], log);
value(new Error("reject"));
});
function listener(event, exec_state, event_data, data) {
try {
assertTrue(event != Debug.DebugEvent.Exception);
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnException();
Debug.setListener(listener);
log.push("end main");
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when we listen to all exceptions and
// there is a catch handler for the to-be-rejected Promise.
// We expect a normal Exception debug event to be triggered.
Debug = debug.Debug;
var log = [];
var expected_events = 1;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve();
});
var q = p.chain(
function(value) {
log.push("reject");
return Promise.reject(new Error("reject"));
});
q.catch(
function(e) {
assertEquals("reject", e.message);
});
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("reject", event_data.exception().message);
assertEquals(q, event_data.promise());
assertFalse(event_data.uncaught());
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "end main", "reject"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions, the Promise
// is rejected, and a catch handler is installed right before the rejection.
// We expect no debug event to be triggered.
Debug = debug.Debug;
var p = new Promise(function(resolve, reject) {
resolve();
});
var q = p.chain(
function() {
q.catch(function(e) {
assertEquals("caught", e.message);
});
return Promise.reject(Error("caught"));
});
function listener(event, exec_state, event_data, data) {
try {
assertTrue(event != Debug.DebugEvent.Exception);
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the to-be-rejected Promise.
// We expect no debug event to be triggered.
Debug = debug.Debug;
var p = new Promise(function(resolve, reject) {
resolve();
});
var q = p.chain(
function() {
return Promise.reject(Error("caught reject"));
});
q.catch(
function(e) {
assertEquals("caught reject", e.message);
});
function listener(event, exec_state, event_data, data) {
try {
assertTrue(event != Debug.DebugEvent.Exception);
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
// Copyright 2014 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
// Test debug events when we only listen to uncaught exceptions and
// the Promise is rejected in the Promise constructor.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
var steps = 0;
var exception = null;
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
steps++;
assertEquals("uncaught", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
}
} catch (e) {
exception = e;
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
var p = new Promise(function(resolve, reject) {
reject(new Error("uncaught")); // event
});
assertEquals(1, steps);
assertNull(exception);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when we listen to all exceptions and
// there is a catch handler for the to-be-rejected Promise.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve();
});
var q = p.chain(
function() {
log.push("reject");
return Promise.reject(new Error("uncaught reject"));
});
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("uncaught reject", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertEquals(q, event_data.promise());
assertTrue(event_data.uncaught());
// All of the frames on the stack are from native Javascript.
assertEquals(0, exec_state.frameCount());
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "end main", "reject"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the to-be-rejected Promise.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var reject_closure;
var p = new Promise(function(resolve, reject) {
log.push("postpone p");
reject_closure = reject;
});
var q = new Promise(function(resolve, reject) {
log.push("resolve q");
resolve();
});
q.then(function() {
log.push("reject p");
reject_closure(new Error("uncaught reject p")); // event
})
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("uncaught reject p", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertEquals(p, event_data.promise());
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["postpone p", "resolve q", "end main", "reject p"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions and
// there is no catch handler for the to-be-rejected Promise.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve();
});
var q = p.chain(
function() {
log.push("reject");
return Promise.reject(Error("uncaught reject")); // event
});
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("uncaught reject", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertEquals(q, event_data.promise());
assertTrue(event_data.uncaught());
// All of the frames on the stack are from native Javascript.
assertEquals(0, exec_state.frameCount());
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "end main", "reject"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when a Promise is rejected, which is caught by a custom
// promise, which has a number for reject closure. We expect an Exception debug
// events trying to call the invalid reject closure.
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve();
});
function MyPromise(resolver) {
var reject = 1;
var resolve = function() { };
log.push("construct");
resolver(resolve, reject);
};
MyPromise.prototype = new Promise(function() {});
p.constructor = MyPromise;
var q = p.chain(
function() {
log.push("reject caught");
return Promise.reject(new Error("caught"));
});
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("number is not a function", event_data.exception().message);
// All of the frames on the stack are from native Javascript.
assertEquals(0, exec_state.frameCount());
assertEquals(q, event_data.promise());
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "construct", "end main", "reject caught"],
log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
log.push("end main");
......@@ -2,16 +2,18 @@
// 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
// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when an exception is thrown inside a Promise, which is
// caught by a custom promise, which throws a new exception in its reject
// handler. We expect an Exception debug event with a promise to be triggered.
// Test debug events when a Promise is rejected, which is caught by a
// custom promise, which throws a new exception in its reject handler.
// We expect two Exception debug events:
// 1) when promise q is rejected.
// 2) when the custom reject closure in MyPromise throws an exception.
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var step = 0;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
......@@ -20,7 +22,7 @@ var p = new Promise(function(resolve, reject) {
function MyPromise(resolver) {
var reject = function() {
log.push("throw reject");
log.push("throw in reject");
throw new Error("reject"); // event
};
var resolve = function() { };
......@@ -28,23 +30,24 @@ function MyPromise(resolver) {
resolver(resolve, reject);
};
MyPromise.prototype = p;
MyPromise.prototype = new Promise(function() {});
p.constructor = MyPromise;
var q = p.chain(
function() {
log.push("throw caught");
throw new Error("caught");
log.push("reject caught");
return Promise.reject(new Error("caught"));
});
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
assertEquals(["resolve", "construct", "end main",
"throw caught", "throw reject"], log);
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("reject", event_data.exception().message);
assertEquals(q, event_data.promise());
assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
// Assert that the debug event is triggered at the throw site.
assertTrue(
exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
}
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
......@@ -59,3 +62,26 @@ Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "construct", "end main",
"reject caught", "throw in reject"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when a Promise is rejected, which is caught by a custom
// promise, which has undefined for reject closure. We expect an Exception
// debug even calling the (undefined) custom rejected closure.
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve();
});
function MyPromise(resolver) {
var reject = undefined;
var resolve = function() { };
log.push("construct");
resolver(resolve, reject);
};
MyPromise.prototype = new Promise(function() {});
p.constructor = MyPromise;
var q = p.chain(
function() {
log.push("reject caught");
return Promise.reject(new Error("caught"));
});
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("caught", event_data.exception().message);
// All of the frames on the stack are from native Javascript.
assertEquals(0, exec_state.frameCount());
assertEquals(q, event_data.promise());
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "construct", "end main", "reject caught"],
log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
log.push("end main");
......@@ -2,7 +2,7 @@
// 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
// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we listen to all exceptions and
// there is a catch handler for the exception thrown in a Promise.
......@@ -10,8 +10,8 @@
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var step = 0;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
......@@ -30,23 +30,16 @@ q.catch(
});
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.AsyncTaskEvent) return;
try {
// Ignore exceptions during startup in stress runs.
if (step >= 1) return;
assertEquals(["resolve", "end main", "throw"], log);
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("caught", event_data.exception().message);
assertEquals(undefined, event_data.promise());
assertEquals(q, event_data.promise());
assertFalse(event_data.uncaught());
step++;
}
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
// debugger swallows exceptions and we expect the chained function
// and this listener to be executed after the main script is finished.
print("Unexpected exception: " + e + "\n" + e.stack);
quit(1);
%AbortJS(e + "\n" + e.stack);
}
}
......@@ -54,3 +47,25 @@ Debug.setBreakOnException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "end main", "throw"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
......@@ -2,7 +2,7 @@
// 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
// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions, the Promise
// throws, and a catch handler is installed right before throwing.
......@@ -26,11 +26,7 @@ function listener(event, exec_state, event_data, data) {
try {
assertTrue(event != Debug.DebugEvent.Exception);
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
// debugger swallows exceptions and we expect the chained function
// and this listener to be executed after the main script is finished.
print("Unexpected exception: " + e + "\n" + e.stack);
quit(1);
%AbortJS(e + "\n" + e.stack);
}
}
......
......@@ -2,7 +2,7 @@
// 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
// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the exception thrown in a Promise.
......@@ -16,23 +16,19 @@ var p = new Promise(function(resolve, reject) {
var q = p.chain(
function() {
throw new Error("caught");
throw new Error("caught throw");
});
q.catch(
function(e) {
assertEquals("caught", e.message);
assertEquals("caught throw", e.message);
});
function listener(event, exec_state, event_data, data) {
try {
assertTrue(event != Debug.DebugEvent.Exception);
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
// debugger swallows exceptions and we expect the chained function
// and this listener to be executed after the main script is finished.
print("Unexpected exception: " + e + "\n" + e.stack);
quit(1);
%AbortJS(e + "\n" + e.stack);
}
}
......
......@@ -5,7 +5,7 @@
// Flags: --expose-debug-as debug
// Test debug events when we only listen to uncaught exceptions and
// an exception is thrown in the the Promise constructor.
// an exception is thrown in the Promise constructor.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
......@@ -15,8 +15,6 @@ var exception = null;
function listener(event, exec_state, event_data, data) {
try {
// Ignore exceptions during startup in stress runs.
if (step >= 1) return;
if (event == Debug.DebugEvent.Exception) {
assertEquals(0, step);
assertEquals("uncaught", event_data.exception().message);
......@@ -27,10 +25,6 @@ function listener(event, exec_state, event_data, data) {
step++;
}
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
// debugger swallows exceptions and we expect the chained function
// and this listener to be executed after the main script is finished.
print("Unexpected exception: " + e + "\n" + e.stack);
exception = e;
}
}
......
......@@ -2,17 +2,16 @@
// 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
// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we listen to all exceptions and
// there is a catch handler for the exception thrown in a Promise.
// there is no catch handler for the exception thrown in a Promise.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var step = 0;
var exception = undefined;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
......@@ -26,27 +25,20 @@ var q = p.chain(
});
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.AsyncTaskEvent) return;
try {
// Ignore exceptions during startup in stress runs.
if (step >= 1) return;
assertEquals(["resolve", "end main", "throw"], log);
if (event == Debug.DebugEvent.Exception) {
assertEquals(0, step);
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("uncaught", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertEquals(q, event_data.promise());
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
step++;
}
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
// debugger swallows exceptions and we expect the chained function
// and this listener to be executed after the main script is finished.
print("Unexpected exception: " + e + "\n" + e.stack);
quit(1);
%AbortJS(e + "\n" + e.stack);
}
}
......@@ -54,3 +46,25 @@ Debug.setBreakOnException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "end main", "throw"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Rerun testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
......@@ -2,7 +2,7 @@
// 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
// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the exception thrown in a Promise.
......@@ -10,8 +10,8 @@
Debug = debug.Debug;
var expected_events = 1;
var log = [];
var step = 0;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
......@@ -27,25 +27,18 @@ var q = p.chain(
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.AsyncTaskEvent) return;
try {
// Ignore exceptions during startup in stress runs.
if (step >= 1) return;
assertEquals(["resolve", "end main", "throw"], log);
if (event == Debug.DebugEvent.Exception) {
assertEquals(0, step);
expected_events--;
assertTrue(expected_events >= 0);
assertEquals("uncaught", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertEquals(q, event_data.promise());
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
step++;
}
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
// debugger swallows exceptions and we expect the chained function
// and this listener to be executed after the main script is finished.
print("Unexpected exception: " + e + "\n" + e.stack);
quit(1);
%AbortJS(e + "\n" + e.stack);
}
}
......@@ -53,3 +46,25 @@ Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "end main", "throw"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
// Copyright 2014 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 --allow-natives-syntax
// Test debug events when an exception is thrown inside a Promise, which is
// caught by a custom promise, which throws a new exception in its reject
// handler. We expect two Exception debug events:
// 1) when the exception is thrown in the promise q.
// 2) when the custom reject closure in MyPromise throws an exception.
Debug = debug.Debug;
var expected_events = 2;
var log = [];
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve();
});
function MyPromise(resolver) {
var reject = function() {
log.push("throw in reject");
throw new Error("reject"); // event
};
var resolve = function() { };
log.push("construct");
resolver(resolve, reject);
};
MyPromise.prototype = new Promise(function() {});
p.constructor = MyPromise;
var q = p.chain(
function() {
log.push("throw caught");
throw new Error("caught"); // event
});
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
expected_events--;
assertTrue(expected_events >= 0);
if (expected_events == 1) {
assertEquals(["resolve", "construct", "end main",
"throw caught"], log);
assertEquals("caught", event_data.exception().message);
} else if (expected_events == 0) {
assertEquals("reject", event_data.exception().message);
} else {
assertUnreachable();
}
assertEquals(q, event_data.promise());
assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "construct", "end main",
"throw caught", "throw in reject"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
......@@ -2,16 +2,18 @@
// 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
// Flags: --expose-debug-as debug --allow-natives-syntax
// Test debug events when an exception is thrown inside a Promise, which is
// caught by a custom promise, which has no reject handler.
// We expect an Exception event with a promise to be triggered.
// We expect two Exception debug events:
// 1) when the exception is thrown in the promise q.
// 2) when calling the undefined custom reject closure in MyPromise throws.
Debug = debug.Debug;
var expected_events = 2;
var log = [];
var step = 0;
var p = new Promise(function(resolve, reject) {
log.push("resolve");
......@@ -25,7 +27,7 @@ function MyPromise(resolver) {
resolver(resolve, reject);
};
MyPromise.prototype = p;
MyPromise.prototype = new Promise(function() {});
p.constructor = MyPromise;
var q = p.chain(
......@@ -37,17 +39,24 @@ var q = p.chain(
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
assertEquals(["resolve", "construct", "end main", "throw caught"], log);
expected_events--;
assertTrue(expected_events >= 0);
if (expected_events == 1) {
assertTrue(
exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
assertEquals("caught", event_data.exception().message);
} else if (expected_events == 0) {
// All of the frames on the stack are from native Javascript.
assertEquals(0, exec_state.frameCount());
assertEquals("undefined is not a function",
event_data.exception().message);
} else {
assertUnreachable();
}
assertEquals(q, event_data.promise());
}
} catch (e) {
// Signal a failure with exit code 1. This is necessary since the
// debugger swallows exceptions and we expect the chained function
// and this listener to be executed after the main script is finished.
print("Unexpected exception: " + e + "\n" + e.stack);
quit(1);
%AbortJS(e + "\n" + e.stack);
}
}
......@@ -55,3 +64,25 @@ Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
log.push("end main");
function testDone(iteration) {
function checkResult() {
try {
assertTrue(iteration < 10);
if (expected_events === 0) {
assertEquals(["resolve", "construct", "end main", "throw caught"], log);
} else {
testDone(iteration + 1);
}
} catch (e) {
%AbortJS(e + "\n" + e.stack);
}
}
// Run testDone through the Object.observe processing loop.
var dummy = {};
Object.observe(dummy, checkResult);
dummy.dummy = dummy;
}
testDone(0);
// Copyright 2014 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
// Test debug events when we only listen to uncaught exceptions and
// the Promise is rejected within a try-catch in the Promise constructor.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
var step = 0;
var exception = null;
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
assertEquals(0, step);
assertEquals("uncaught", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
step++;
}
} catch (e) {
exception = e;
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
var p = new Promise(function(resolve, reject) {
try { // This try-catch must not prevent this uncaught reject event.
reject(new Error("uncaught")); // event
} catch (e) { }
});
assertEquals(1, step);
assertNull(exception);
// Copyright 2014 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
// Test debug events when we only listen to uncaught exceptions and
// an exception is thrown in the Promise constructor, but caught in an
// inner try-catch. The Promise is rejected afterwards.
// We expect an Exception debug event with a promise to be triggered.
Debug = debug.Debug;
var step = 0;
var exception = null;
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Exception) {
assertEquals(0, step);
assertEquals("uncaught", event_data.exception().message);
assertTrue(event_data.promise() instanceof Promise);
assertTrue(event_data.uncaught());
// Assert that the debug event is triggered at the throw site.
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
step++;
}
} catch (e) {
exception = e;
}
}
Debug.setBreakOnUncaughtException();
Debug.setListener(listener);
var p = new Promise(function(resolve, reject) {
try { // This try-catch must not prevent this uncaught reject event.
throw new Error("caught");
} catch (e) { }
reject(new Error("uncaught")); // event
});
assertEquals(1, step);
assertNull(exception);
......@@ -127,10 +127,14 @@
'debug-stepout-scope-part3': [PASS, NO_VARIANTS],
'debug-stepout-scope-part7': [PASS, NO_VARIANTS],
'debug-stepout-to-builtin': [PASS, NO_VARIANTS],
'es6/debug-promises-throw-in-constructor': [PASS, NO_VARIANTS],
'es6/debug-promises-throw-in-reject': [PASS, NO_VARIANTS],
'es6/debug-promises-uncaught-all': [PASS, NO_VARIANTS],
'es6/debug-promises-uncaught-uncaught': [PASS, NO_VARIANTS],
'es6/debug-promises/throw-in-constructor': [PASS, NO_VARIANTS],
'es6/debug-promises/reject-in-constructor': [PASS, NO_VARIANTS],
'es6/debug-promises/throw-with-undefined-reject': [PASS, NO_VARIANTS],
'es6/debug-promises/throw-with-throw-in-reject': [PASS, NO_VARIANTS],
'es6/debug-promises/reject-with-throw-in-reject': [PASS, NO_VARIANTS],
'es6/debug-promises/throw-uncaught-all': [PASS, NO_VARIANTS],
'es6/debug-promises/throw-uncaught-uncaught': [PASS, NO_VARIANTS],
'es6/debug-promises/reject-uncaught-late': [PASS, NO_VARIANTS],
'harmony/debug-blockscopes': [PASS, NO_VARIANTS],
'harmony/generators-debug-scopes': [PASS, NO_VARIANTS],
'regress/regress-1081309': [PASS, NO_VARIANTS],
......
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
%DebugPromiseHandleEpilogue();
%DebugPopPromise();
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _promise = new Object();
var _value = new Object();
%DebugPromiseRejectEvent(_promise, _value);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _promise_getter = function() {};
%DebugPromiseHandlePrologue(_promise_getter);
var _promise = new Object();
%DebugPushPromise(_promise);
......@@ -47,8 +47,8 @@ EXPAND_MACROS = [
# that the parser doesn't bit-rot. Change the values as needed when you add,
# remove or change runtime functions, but make sure we don't lose our ability
# to parse them!
EXPECTED_FUNCTION_COUNT = 425
EXPECTED_FUZZABLE_COUNT = 328
EXPECTED_FUNCTION_COUNT = 426
EXPECTED_FUZZABLE_COUNT = 329
EXPECTED_CCTEST_COUNT = 7
EXPECTED_UNKNOWN_COUNT = 16
EXPECTED_BUILTINS_COUNT = 813
......
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