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 |