Commit 31bc17f0 authored by gsathya's avatar gsathya Committed by Commit bot

[promises] cleanup default promise handlers

Use private symbols to mark default promise handler, instead of calling out to default
handlers defined in JS. We check for this symbol in PromiseHandle and perform the
appropriate behavior as the default handlers.

Catch prediction logic is updated to account for a symbol.

BUG=v8:5343

Review-Url: https://codereview.chromium.org/2695593002
Cr-Commit-Position: refs/heads/master@{#43135}
parent 299f8340
......@@ -420,7 +420,6 @@ Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(
Node* context, Node* promise, Node* on_resolve, Node* on_reject,
Node* deferred_promise, Node* deferred_on_resolve,
Node* deferred_on_reject) {
Node* const native_context = LoadNativeContext(context);
Variable var_on_resolve(this, MachineRepresentation::kTagged),
var_on_reject(this, MachineRepresentation::kTagged);
......@@ -432,14 +431,17 @@ Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(
append_callbacks(this);
GotoIf(TaggedIsSmi(on_resolve), &if_onresolvenotcallable);
Isolate* isolate = this->isolate();
Node* const on_resolve_map = LoadMap(on_resolve);
Branch(IsCallableMap(on_resolve_map), &onrejectcheck,
&if_onresolvenotcallable);
Bind(&if_onresolvenotcallable);
{
var_on_resolve.Bind(LoadContextElement(
native_context, Context::PROMISE_ID_RESOLVE_HANDLER_INDEX));
Isolate* isolate = this->isolate();
Node* const default_resolve_handler_symbol = HeapConstant(
isolate->factory()->promise_default_resolve_handler_symbol());
var_on_resolve.Bind(default_resolve_handler_symbol);
Goto(&onrejectcheck);
}
......@@ -454,8 +456,9 @@ Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(
Bind(&if_onrejectnotcallable);
{
var_on_reject.Bind(LoadContextElement(
native_context, Context::PROMISE_ID_REJECT_HANDLER_INDEX));
Node* const default_reject_handler_symbol = HeapConstant(
isolate->factory()->promise_default_reject_handler_symbol());
var_on_reject.Bind(default_reject_handler_symbol);
Goto(&append_callbacks);
}
}
......@@ -1265,25 +1268,55 @@ TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) {
Bind(&run_handler);
{
Callable call_callable = CodeFactory::Call(isolate);
Node* const result =
CallJS(call_callable, context, handler, UndefinedConstant(), value);
Label if_defaulthandler(this), if_callablehandler(this),
if_internalhandler(this), if_customhandler(this, Label::kDeferred);
Variable var_result(this, MachineRepresentation::kTagged);
GotoIfException(result, &if_rejectpromise, &var_reason);
Branch(IsSymbol(handler), &if_defaulthandler, &if_callablehandler);
Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
&if_customhandler);
Bind(&if_defaulthandler);
{
Label if_resolve(this), if_reject(this);
Node* const default_resolve_handler_symbol = HeapConstant(
isolate->factory()->promise_default_resolve_handler_symbol());
Branch(WordEqual(default_resolve_handler_symbol, handler), &if_resolve,
&if_reject);
Bind(&if_resolve);
{
var_result.Bind(value);
Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
&if_customhandler);
}
Bind(&if_reject);
{
var_reason.Bind(value);
Goto(&if_rejectpromise);
}
}
Bind(&if_callablehandler);
{
Callable call_callable = CodeFactory::Call(isolate);
Node* const result =
CallJS(call_callable, context, handler, UndefinedConstant(), value);
var_result.Bind(result);
GotoIfException(result, &if_rejectpromise, &var_reason);
Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
&if_customhandler);
}
Bind(&if_internalhandler);
InternalResolvePromise(context, deferred_promise, result);
InternalResolvePromise(context, deferred_promise, var_result.value());
Goto(&promisehook_after);
Bind(&if_customhandler);
{
Callable call_callable = CodeFactory::Call(isolate);
Node* const maybe_exception =
CallJS(call_callable, context, deferred_on_resolve,
UndefinedConstant(), result);
UndefinedConstant(), var_result.value());
GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
Goto(&promisehook_after);
}
......
......@@ -107,8 +107,6 @@ enum ContextLookupFlags {
V(OBJECT_TO_STRING, JSFunction, object_to_string) \
V(PROMISE_CATCH_INDEX, JSFunction, promise_catch) \
V(PROMISE_FUNCTION_INDEX, JSFunction, promise_function) \
V(PROMISE_ID_RESOLVE_HANDLER_INDEX, JSFunction, promise_id_resolve_handler) \
V(PROMISE_ID_REJECT_HANDLER_INDEX, JSFunction, promise_id_reject_handler) \
V(RANGE_ERROR_FUNCTION_INDEX, JSFunction, range_error_function) \
V(REFERENCE_ERROR_FUNCTION_INDEX, JSFunction, reference_error_function) \
V(SET_ADD_METHOD_INDEX, JSFunction, set_add) \
......
......@@ -207,40 +207,42 @@
V(writable_string, "writable") \
V(year_string, "year")
#define PRIVATE_SYMBOL_LIST(V) \
V(array_iteration_kind_symbol) \
V(array_iterator_next_symbol) \
V(array_iterator_object_symbol) \
V(call_site_frame_array_symbol) \
V(call_site_frame_index_symbol) \
V(class_end_position_symbol) \
V(class_start_position_symbol) \
V(detailed_stack_trace_symbol) \
V(elements_transition_symbol) \
V(error_end_pos_symbol) \
V(error_script_symbol) \
V(error_start_pos_symbol) \
V(frozen_symbol) \
V(hash_code_symbol) \
V(home_object_symbol) \
V(intl_initialized_marker_symbol) \
V(intl_pattern_symbol) \
V(intl_resolved_symbol) \
V(megamorphic_symbol) \
V(native_context_index_symbol) \
V(nonexistent_symbol) \
V(nonextensible_symbol) \
V(normal_ic_symbol) \
V(not_mapped_symbol) \
V(premonomorphic_symbol) \
V(promise_async_stack_id_symbol) \
V(promise_debug_marker_symbol) \
V(promise_forwarding_handler_symbol) \
V(promise_handled_by_symbol) \
V(promise_async_id_symbol) \
V(sealed_symbol) \
V(stack_trace_symbol) \
V(strict_function_transition_symbol) \
#define PRIVATE_SYMBOL_LIST(V) \
V(array_iteration_kind_symbol) \
V(array_iterator_next_symbol) \
V(array_iterator_object_symbol) \
V(call_site_frame_array_symbol) \
V(call_site_frame_index_symbol) \
V(class_end_position_symbol) \
V(class_start_position_symbol) \
V(detailed_stack_trace_symbol) \
V(elements_transition_symbol) \
V(error_end_pos_symbol) \
V(error_script_symbol) \
V(error_start_pos_symbol) \
V(frozen_symbol) \
V(hash_code_symbol) \
V(home_object_symbol) \
V(intl_initialized_marker_symbol) \
V(intl_pattern_symbol) \
V(intl_resolved_symbol) \
V(megamorphic_symbol) \
V(native_context_index_symbol) \
V(nonexistent_symbol) \
V(nonextensible_symbol) \
V(normal_ic_symbol) \
V(not_mapped_symbol) \
V(premonomorphic_symbol) \
V(promise_async_stack_id_symbol) \
V(promise_debug_marker_symbol) \
V(promise_forwarding_handler_symbol) \
V(promise_handled_by_symbol) \
V(promise_async_id_symbol) \
V(promise_default_resolve_handler_symbol) \
V(promise_default_reject_handler_symbol) \
V(sealed_symbol) \
V(stack_trace_symbol) \
V(strict_function_transition_symbol) \
V(uninitialized_symbol)
#define PUBLIC_SYMBOL_LIST(V) \
......
......@@ -1878,6 +1878,11 @@ bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate,
Handle<JSReceiver>::cast(deferred_promise));
}
if (queue->IsSymbol()) {
return InternalPromiseHasUserDefinedRejectHandler(
isolate, Handle<JSPromise>::cast(deferred_promise));
}
Handle<FixedArray> queue_arr = Handle<FixedArray>::cast(queue);
Handle<FixedArray> deferred_promise_arr =
Handle<FixedArray>::cast(deferred_promise);
......
......@@ -18,14 +18,6 @@ var promiseForwardingHandlerSymbol =
utils.ImportNow("promise_forwarding_handler_symbol");
var GlobalPromise = global.Promise;
// -------------------------------------------------------------------
// Core functionality.
function PromiseIdResolveHandler(x) { return x; }
function PromiseIdRejectHandler(r) { %_ReThrow(r); }
SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true);
// -------------------------------------------------------------------
// Define exported functions.
......@@ -137,9 +129,4 @@ utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
"race", PromiseRace,
]);
%InstallToContext([
"promise_id_resolve_handler", PromiseIdResolveHandler,
"promise_id_reject_handler", PromiseIdRejectHandler
]);
})
......@@ -922,10 +922,11 @@ void JSPromise::JSPromiseVerify() {
deferred_on_reject()->IsCallable() ||
deferred_on_reject()->IsFixedArray());
CHECK(fulfill_reactions()->IsUndefined(isolate) ||
fulfill_reactions()->IsCallable() ||
fulfill_reactions()->IsCallable() || fulfill_reactions()->IsSymbol() ||
fulfill_reactions()->IsFixedArray());
CHECK(reject_reactions()->IsUndefined(isolate) ||
reject_reactions()->IsCallable() || reject_reactions()->IsFixedArray());
reject_reactions()->IsSymbol() || reject_reactions()->IsCallable() ||
reject_reactions()->IsFixedArray());
}
void JSRegExp::JSRegExpVerify() {
......@@ -1051,7 +1052,8 @@ void PromiseReactionJobInfo::PromiseReactionJobInfoVerify() {
Isolate* isolate = GetIsolate();
CHECK(IsPromiseReactionJobInfo());
CHECK(value()->IsObject());
CHECK(tasks()->IsFixedArray() || tasks()->IsCallable());
CHECK(tasks()->IsFixedArray() || tasks()->IsCallable() ||
tasks()->IsSymbol());
CHECK(deferred_promise()->IsUndefined(isolate) ||
deferred_promise()->IsJSReceiver() ||
deferred_promise()->IsFixedArray());
......
......@@ -8507,13 +8507,15 @@ class JSPromise : public JSObject {
// 1) Undefined -- This is the zero state when there is no callback
// or deferred fields registered.
//
// 2) Object -- There is a single Callable directly attached to the
// 2) Object -- There is a single callback directly attached to the
// fulfill_reactions, reject_reactions and the deferred fields are
// directly attached to the slots. In this state, deferred_promise
// is a JSReceiver and deferred_on_{resolve, reject} are Callables.
//
// 3) FixedArray -- There is more than one callback and deferred
// fields attached to a FixedArray.
//
// The callback can be a Callable or a Symbol.
DECL_ACCESSORS(deferred_promise, Object)
DECL_ACCESSORS(deferred_on_resolve, Object)
DECL_ACCESSORS(deferred_on_reject, Object)
......
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