[builtins] Inline InternalPromiseThen into it's only caller

There's now only a single caller to InternalPromiseThen left,
which is the Promise.prototype.then implementation, so there's
no need to have a separate helper function.

Bug: v8:7253
Change-Id: I0e1ea674c942f735dd069137182232f34d16a729
Reviewed-on: https://chromium-review.googlesource.com/897762
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51031}
This commit is contained in:
Benedikt Meurer 2018-02-01 14:20:42 +01:00 committed by Commit Bot
parent e64f546140
commit f7bd6a2fd6
3 changed files with 62 additions and 74 deletions

View File

@ -810,7 +810,7 @@ namespace internal {
TFJ(PromiseRejectClosure, 1, kValue) \ TFJ(PromiseRejectClosure, 1, kValue) \
TFJ(PromiseAllResolveElementClosure, 1, kValue) \ TFJ(PromiseAllResolveElementClosure, 1, kValue) \
/* ES #sec-promise.prototype.then */ \ /* ES #sec-promise.prototype.then */ \
TFJ(PromisePrototypeThen, 2, kOnFullfilled, kOnRejected) \ TFJ(PromisePrototypeThen, 2, kOnFulfilled, kOnRejected) \
/* ES #sec-promise.prototype.catch */ \ /* ES #sec-promise.prototype.catch */ \
TFJ(PromisePrototypeCatch, 1, kOnRejected) \ TFJ(PromisePrototypeCatch, 1, kOnRejected) \
/* ES #sec-fulfillpromise */ \ /* ES #sec-fulfillpromise */ \

View File

@ -290,71 +290,6 @@ void PromiseBuiltinsAssembler::AppendPromiseCallback(int offset, Node* promise,
StoreObjectField(promise, offset, new_elements); StoreObjectField(promise, offset, new_elements);
} }
Node* PromiseBuiltinsAssembler::InternalPromiseThen(Node* context,
Node* promise,
Node* on_fulfill,
Node* on_reject) {
// 2. If IsPromise(promise) is false, throw a TypeError exception.
ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE,
"Promise.prototype.then");
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
Label fast_promise_capability(this), slow_constructor(this, Label::kDeferred),
slow_promise_capability(this, Label::kDeferred);
Node* const native_context = LoadNativeContext(context);
Node* const promise_fun =
LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
Node* const promise_prototype =
LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
Node* const promise_map = LoadMap(promise);
GotoIfNot(WordEqual(LoadMapPrototype(promise_map), promise_prototype),
&slow_constructor);
Branch(IsSpeciesProtectorCellInvalid(), &slow_constructor,
&fast_promise_capability);
BIND(&slow_constructor);
Node* const constructor =
SpeciesConstructor(native_context, promise, promise_fun);
Branch(WordEqual(constructor, promise_fun), &fast_promise_capability,
&slow_promise_capability);
// 4. Let resultCapability be ? NewPromiseCapability(C).
Label perform_promise_then(this);
VARIABLE(var_result_promise, MachineRepresentation::kTagged);
VARIABLE(var_result_promise_or_capability, MachineRepresentation::kTagged);
BIND(&fast_promise_capability);
{
Node* const result_promise = AllocateAndInitJSPromise(context, promise);
var_result_promise.Bind(result_promise);
var_result_promise_or_capability.Bind(result_promise);
CSA_ASSERT(this, IsJSPromise(var_result_promise_or_capability.value()));
Goto(&perform_promise_then);
}
BIND(&slow_promise_capability);
{
Node* const capability = NewPromiseCapability(context, constructor);
var_result_promise.Bind(
LoadObjectField(capability, PromiseCapability::kPromiseOffset));
var_result_promise_or_capability.Bind(capability);
CSA_ASSERT(this,
IsPromiseCapability(var_result_promise_or_capability.value()));
Goto(&perform_promise_then);
}
// 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
// resultCapability).
BIND(&perform_promise_then);
CSA_ASSERT(
this,
Word32Or(IsJSPromise(var_result_promise_or_capability.value()),
IsPromiseCapability(var_result_promise_or_capability.value())));
InternalPerformPromiseThen(context, promise, on_fulfill, on_reject,
var_result_promise_or_capability.value());
return var_result_promise.value();
}
void PromiseBuiltinsAssembler::InternalPerformPromiseThen(Node* context, void PromiseBuiltinsAssembler::InternalPerformPromiseThen(Node* context,
Node* promise, Node* promise,
Node* on_fulfilled, Node* on_fulfilled,
@ -1020,13 +955,69 @@ TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) { TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) {
// 1. Let promise be the this value. // 1. Let promise be the this value.
Node* const promise = Parameter(Descriptor::kReceiver); Node* const promise = Parameter(Descriptor::kReceiver);
Node* const on_resolve = Parameter(Descriptor::kOnFullfilled); Node* const on_fulfilled = Parameter(Descriptor::kOnFulfilled);
Node* const on_reject = Parameter(Descriptor::kOnRejected); Node* const on_rejected = Parameter(Descriptor::kOnRejected);
Node* const context = Parameter(Descriptor::kContext); Node* const context = Parameter(Descriptor::kContext);
Node* const result = // 2. If IsPromise(promise) is false, throw a TypeError exception.
InternalPromiseThen(context, promise, on_resolve, on_reject); ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE,
Return(result); "Promise.prototype.then");
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
Label fast_promise_capability(this), slow_constructor(this, Label::kDeferred),
slow_promise_capability(this, Label::kDeferred);
Node* const native_context = LoadNativeContext(context);
Node* const promise_fun =
LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
Node* const promise_prototype =
LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
Node* const promise_map = LoadMap(promise);
GotoIfNot(WordEqual(LoadMapPrototype(promise_map), promise_prototype),
&slow_constructor);
Branch(IsSpeciesProtectorCellInvalid(), &slow_constructor,
&fast_promise_capability);
BIND(&slow_constructor);
Node* const constructor =
SpeciesConstructor(native_context, promise, promise_fun);
Branch(WordEqual(constructor, promise_fun), &fast_promise_capability,
&slow_promise_capability);
// 4. Let resultCapability be ? NewPromiseCapability(C).
Label perform_promise_then(this);
VARIABLE(var_result_promise, MachineRepresentation::kTagged);
VARIABLE(var_result_promise_or_capability, MachineRepresentation::kTagged);
BIND(&fast_promise_capability);
{
Node* const result_promise = AllocateAndInitJSPromise(context, promise);
var_result_promise.Bind(result_promise);
var_result_promise_or_capability.Bind(result_promise);
CSA_ASSERT(this, IsJSPromise(var_result_promise_or_capability.value()));
Goto(&perform_promise_then);
}
BIND(&slow_promise_capability);
{
Node* const capability = NewPromiseCapability(context, constructor);
var_result_promise.Bind(
LoadObjectField(capability, PromiseCapability::kPromiseOffset));
var_result_promise_or_capability.Bind(capability);
CSA_ASSERT(this,
IsPromiseCapability(var_result_promise_or_capability.value()));
Goto(&perform_promise_then);
}
// 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
// resultCapability).
BIND(&perform_promise_then);
CSA_ASSERT(
this,
Word32Or(IsJSPromise(var_result_promise_or_capability.value()),
IsPromiseCapability(var_result_promise_or_capability.value())));
InternalPerformPromiseThen(context, promise, on_fulfilled, on_rejected,
var_result_promise_or_capability.value());
Return(var_result_promise.value());
} }
// ES#sec-promise-resolve-functions // ES#sec-promise-resolve-functions

View File

@ -127,9 +127,6 @@ class PromiseBuiltinsAssembler : public CodeStubAssembler {
void AppendPromiseCallback(int offset, compiler::Node* promise, void AppendPromiseCallback(int offset, compiler::Node* promise,
compiler::Node* value); compiler::Node* value);
Node* InternalPromiseThen(Node* context, Node* promise, Node* on_resolve,
Node* on_reject);
void InternalPerformPromiseThen(Node* context, Node* promise, void InternalPerformPromiseThen(Node* context, Node* promise,
Node* on_fulfill, Node* on_reject, Node* on_fulfill, Node* on_reject,
Node* result); Node* result);