| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/builtins/builtins-promise.h" | 5 #include "src/builtins/builtins-promise.h" |
| 6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 #include "src/builtins/builtins.h" | 7 #include "src/builtins/builtins.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stub-assembler.h" | 9 #include "src/code-stub-assembler.h" |
| 10 #include "src/promise-utils.h" | 10 #include "src/promise-utils.h" |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 var_on_reject.Bind(LoadContextElement( | 223 var_on_reject.Bind(LoadContextElement( |
| 224 native_context, Context::PROMISE_ID_REJECT_HANDLER_INDEX)); | 224 native_context, Context::PROMISE_ID_REJECT_HANDLER_INDEX)); |
| 225 Goto(&append_callbacks); | 225 Goto(&append_callbacks); |
| 226 } | 226 } |
| 227 } | 227 } |
| 228 | 228 |
| 229 Bind(&append_callbacks); | 229 Bind(&append_callbacks); |
| 230 { | 230 { |
| 231 Label fulfilled_check(this); | 231 Label fulfilled_check(this); |
| 232 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset); | 232 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset); |
| 233 GotoUnless(SmiEqual(status, SmiConstant(kPromisePending)), | 233 GotoUnless(SmiEqual(status, SmiConstant(v8::Promise::kPending)), |
| 234 &fulfilled_check); | 234 &fulfilled_check); |
| 235 | 235 |
| 236 Node* const existing_deferred = | 236 Node* const existing_deferred = |
| 237 LoadObjectField(promise, JSPromise::kDeferredOffset); | 237 LoadObjectField(promise, JSPromise::kDeferredOffset); |
| 238 | 238 |
| 239 Label if_noexistingcallbacks(this), if_existingcallbacks(this); | 239 Label if_noexistingcallbacks(this), if_existingcallbacks(this); |
| 240 Branch(IsUndefined(existing_deferred), &if_noexistingcallbacks, | 240 Branch(IsUndefined(existing_deferred), &if_noexistingcallbacks, |
| 241 &if_existingcallbacks); | 241 &if_existingcallbacks); |
| 242 | 242 |
| 243 Bind(&if_noexistingcallbacks); | 243 Bind(&if_noexistingcallbacks); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise, | 297 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise, |
| 298 var_on_reject.value()); | 298 var_on_reject.value()); |
| 299 Goto(&out); | 299 Goto(&out); |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 | 302 |
| 303 Bind(&fulfilled_check); | 303 Bind(&fulfilled_check); |
| 304 { | 304 { |
| 305 Label reject(this); | 305 Label reject(this); |
| 306 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset); | 306 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset); |
| 307 GotoUnless(WordEqual(status, SmiConstant(kPromiseFulfilled)), &reject); | 307 GotoUnless(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)), |
| 308 &reject); |
| 308 | 309 |
| 309 // TODO(gsathya): Move this to TF. | 310 // TODO(gsathya): Move this to TF. |
| 310 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, result, | 311 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, result, |
| 311 var_on_resolve.value(), deferred, | 312 var_on_resolve.value(), deferred, |
| 312 SmiConstant(kPromiseFulfilled)); | 313 SmiConstant(v8::Promise::kFulfilled)); |
| 313 Goto(&out); | 314 Goto(&out); |
| 314 | 315 |
| 315 Bind(&reject); | 316 Bind(&reject); |
| 316 { | 317 { |
| 317 Node* const has_handler = PromiseHasHandler(promise); | 318 Node* const has_handler = PromiseHasHandler(promise); |
| 318 Label enqueue(this); | 319 Label enqueue(this); |
| 319 | 320 |
| 320 // TODO(gsathya): Fold these runtime calls and move to TF. | 321 // TODO(gsathya): Fold these runtime calls and move to TF. |
| 321 GotoIf(has_handler, &enqueue); | 322 GotoIf(has_handler, &enqueue); |
| 322 CallRuntime(Runtime::kPromiseRevokeReject, context, promise); | 323 CallRuntime(Runtime::kPromiseRevokeReject, context, promise); |
| 323 Goto(&enqueue); | 324 Goto(&enqueue); |
| 324 | 325 |
| 325 Bind(&enqueue); | 326 Bind(&enqueue); |
| 326 { | 327 { |
| 327 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, | 328 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, |
| 328 result, var_on_reject.value(), deferred, | 329 result, var_on_reject.value(), deferred, |
| 329 SmiConstant(kPromiseRejected)); | 330 SmiConstant(v8::Promise::kRejected)); |
| 330 | 331 |
| 331 Goto(&out); | 332 Goto(&out); |
| 332 } | 333 } |
| 333 } | 334 } |
| 334 } | 335 } |
| 335 } | 336 } |
| 336 | 337 |
| 337 Bind(&out); | 338 Bind(&out); |
| 338 PromiseSetHasHandler(promise); | 339 PromiseSetHasHandler(promise); |
| 339 | 340 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 // rejected, shortcircuit the resolution procedure by directly | 409 // rejected, shortcircuit the resolution procedure by directly |
| 409 // reusing the value from the promise. | 410 // reusing the value from the promise. |
| 410 Bind(&if_nativepromise); | 411 Bind(&if_nativepromise); |
| 411 { | 412 { |
| 412 Node* const thenable_status = | 413 Node* const thenable_status = |
| 413 LoadObjectField(result, JSPromise::kStatusOffset); | 414 LoadObjectField(result, JSPromise::kStatusOffset); |
| 414 Node* const thenable_value = | 415 Node* const thenable_value = |
| 415 LoadObjectField(result, JSPromise::kResultOffset); | 416 LoadObjectField(result, JSPromise::kResultOffset); |
| 416 | 417 |
| 417 Label if_isnotpending(this); | 418 Label if_isnotpending(this); |
| 418 GotoUnless(SmiEqual(SmiConstant(kPromisePending), thenable_status), | 419 GotoUnless(SmiEqual(SmiConstant(v8::Promise::kPending), thenable_status), |
| 419 &if_isnotpending); | 420 &if_isnotpending); |
| 420 | 421 |
| 421 // TODO(gsathya): Use a marker here instead of the actual then | 422 // TODO(gsathya): Use a marker here instead of the actual then |
| 422 // callback, and check for the marker in PromiseResolveThenableJob | 423 // callback, and check for the marker in PromiseResolveThenableJob |
| 423 // and perform PromiseThen. | 424 // and perform PromiseThen. |
| 424 Node* const native_context = LoadNativeContext(context); | 425 Node* const native_context = LoadNativeContext(context); |
| 425 Node* const then = | 426 Node* const then = |
| 426 LoadContextElement(native_context, Context::PROMISE_THEN_INDEX); | 427 LoadContextElement(native_context, Context::PROMISE_THEN_INDEX); |
| 427 var_then.Bind(then); | 428 var_then.Bind(then); |
| 428 Goto(&do_enqueue); | 429 Goto(&do_enqueue); |
| 429 | 430 |
| 430 Bind(&if_isnotpending); | 431 Bind(&if_isnotpending); |
| 431 { | 432 { |
| 432 Label if_fulfilled(this), if_rejected(this); | 433 Label if_fulfilled(this), if_rejected(this); |
| 433 Branch(SmiEqual(SmiConstant(kPromiseFulfilled), thenable_status), | 434 Branch(SmiEqual(SmiConstant(v8::Promise::kFulfilled), thenable_status), |
| 434 &if_fulfilled, &if_rejected); | 435 &if_fulfilled, &if_rejected); |
| 435 | 436 |
| 436 Bind(&if_fulfilled); | 437 Bind(&if_fulfilled); |
| 437 { | 438 { |
| 438 CallRuntime(Runtime::kPromiseFulfill, context, promise, | 439 CallRuntime(Runtime::kPromiseFulfill, context, promise, |
| 439 SmiConstant(kPromiseFulfilled), thenable_value); | 440 SmiConstant(v8::Promise::kFulfilled), thenable_value); |
| 440 PromiseSetHasHandler(promise); | 441 PromiseSetHasHandler(promise); |
| 441 Goto(out); | 442 Goto(out); |
| 442 } | 443 } |
| 443 | 444 |
| 444 Bind(&if_rejected); | 445 Bind(&if_rejected); |
| 445 { | 446 { |
| 446 Label reject(this); | 447 Label reject(this); |
| 447 Node* const has_handler = PromiseHasHandler(result); | 448 Node* const has_handler = PromiseHasHandler(result); |
| 448 | 449 |
| 449 // Promise has already been rejected, but had no handler. | 450 // Promise has already been rejected, but had no handler. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 Bind(&enqueue); | 501 Bind(&enqueue); |
| 501 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise, | 502 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise, |
| 502 result, var_then.value()); | 503 result, var_then.value()); |
| 503 Goto(out); | 504 Goto(out); |
| 504 } | 505 } |
| 505 | 506 |
| 506 // 7.b Return FulfillPromise(promise, resolution). | 507 // 7.b Return FulfillPromise(promise, resolution). |
| 507 Bind(&fulfill); | 508 Bind(&fulfill); |
| 508 { | 509 { |
| 509 CallRuntime(Runtime::kPromiseFulfill, context, promise, | 510 CallRuntime(Runtime::kPromiseFulfill, context, promise, |
| 510 SmiConstant(kPromiseFulfilled), result); | 511 SmiConstant(v8::Promise::kFulfilled), result); |
| 511 Goto(out); | 512 Goto(out); |
| 512 } | 513 } |
| 513 | 514 |
| 514 Bind(&if_cycle); | 515 Bind(&if_cycle); |
| 515 { | 516 { |
| 516 // 6.a Let selfResolutionError be a newly created TypeError object. | 517 // 6.a Let selfResolutionError be a newly created TypeError object. |
| 517 Node* const message_id = SmiConstant(MessageTemplate::kPromiseCyclic); | 518 Node* const message_id = SmiConstant(MessageTemplate::kPromiseCyclic); |
| 518 Node* const error = | 519 Node* const error = |
| 519 CallRuntime(Runtime::kNewTypeError, context, message_id, result); | 520 CallRuntime(Runtime::kNewTypeError, context, message_id, result); |
| 520 var_reason.Bind(error); | 521 var_reason.Bind(error); |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 CallRuntime(Runtime::kDebugPopPromise, context); | 986 CallRuntime(Runtime::kDebugPopPromise, context); |
| 986 Goto(&out); | 987 Goto(&out); |
| 987 | 988 |
| 988 Bind(&out); | 989 Bind(&out); |
| 989 Return(UndefinedConstant()); | 990 Return(UndefinedConstant()); |
| 990 } | 991 } |
| 991 } | 992 } |
| 992 | 993 |
| 993 } // namespace internal | 994 } // namespace internal |
| 994 } // namespace v8 | 995 } // namespace v8 |
| OLD | NEW |