| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/isolate.h" | 5 #include "src/isolate.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include <fstream> // NOLINT(readability/streams) | 9 #include <fstream> // NOLINT(readability/streams) |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 1795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1806 delete tltop->promise_on_stack_; | 1806 delete tltop->promise_on_stack_; |
| 1807 tltop->promise_on_stack_ = prev; | 1807 tltop->promise_on_stack_ = prev; |
| 1808 global_handles()->Destroy(global_promise.location()); | 1808 global_handles()->Destroy(global_promise.location()); |
| 1809 } | 1809 } |
| 1810 | 1810 |
| 1811 namespace { | 1811 namespace { |
| 1812 bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate, | 1812 bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate, |
| 1813 Handle<JSPromise> promise); | 1813 Handle<JSPromise> promise); |
| 1814 | 1814 |
| 1815 bool PromiseHandlerCheck(Isolate* isolate, Handle<JSReceiver> handler, | 1815 bool PromiseHandlerCheck(Isolate* isolate, Handle<JSReceiver> handler, |
| 1816 Handle<JSObject> deferred) { | 1816 Handle<JSReceiver> deferred_promise) { |
| 1817 // Recurse to the forwarding Promise, if any. This may be due to | 1817 // Recurse to the forwarding Promise, if any. This may be due to |
| 1818 // - await reaction forwarding to the throwaway Promise, which has | 1818 // - await reaction forwarding to the throwaway Promise, which has |
| 1819 // a dependency edge to the outer Promise. | 1819 // a dependency edge to the outer Promise. |
| 1820 // - PromiseIdResolveHandler forwarding to the output of .then | 1820 // - PromiseIdResolveHandler forwarding to the output of .then |
| 1821 // - Promise.all/Promise.race forwarding to a throwaway Promise, which | 1821 // - Promise.all/Promise.race forwarding to a throwaway Promise, which |
| 1822 // has a dependency edge to the generated outer Promise. | 1822 // has a dependency edge to the generated outer Promise. |
| 1823 // Otherwise, this is a real reject handler for the Promise. | 1823 // Otherwise, this is a real reject handler for the Promise. |
| 1824 Handle<Symbol> key = isolate->factory()->promise_forwarding_handler_symbol(); | 1824 Handle<Symbol> key = isolate->factory()->promise_forwarding_handler_symbol(); |
| 1825 Handle<Object> forwarding_handler = JSReceiver::GetDataProperty(handler, key); | 1825 Handle<Object> forwarding_handler = JSReceiver::GetDataProperty(handler, key); |
| 1826 if (forwarding_handler->IsUndefined(isolate)) { | 1826 if (forwarding_handler->IsUndefined(isolate)) { |
| 1827 return true; | 1827 return true; |
| 1828 } | 1828 } |
| 1829 | 1829 |
| 1830 // TODO(gsathya): Remove this once we get rid of deferred objects. | 1830 if (!deferred_promise->IsJSPromise()) { |
| 1831 Handle<String> promise_str = isolate->factory()->promise_string(); | |
| 1832 Handle<Object> deferred_promise_obj = | |
| 1833 JSObject::GetDataProperty(deferred, promise_str); | |
| 1834 if (!deferred_promise_obj->IsJSPromise()) { | |
| 1835 return true; | 1831 return true; |
| 1836 } | 1832 } |
| 1837 | 1833 |
| 1838 return InternalPromiseHasUserDefinedRejectHandler( | 1834 return InternalPromiseHasUserDefinedRejectHandler( |
| 1839 isolate, Handle<JSPromise>::cast(deferred_promise_obj)); | 1835 isolate, Handle<JSPromise>::cast(deferred_promise)); |
| 1840 } | 1836 } |
| 1841 | 1837 |
| 1842 bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate, | 1838 bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate, |
| 1843 Handle<JSPromise> promise) { | 1839 Handle<JSPromise> promise) { |
| 1844 // If this promise was marked as being handled by a catch block | 1840 // If this promise was marked as being handled by a catch block |
| 1845 // in an async function, then it has a user-defined reject handler. | 1841 // in an async function, then it has a user-defined reject handler. |
| 1846 if (promise->handled_hint()) return true; | 1842 if (promise->handled_hint()) return true; |
| 1847 | 1843 |
| 1848 // If this Promise is subsumed by another Promise (a Promise resolved | 1844 // If this Promise is subsumed by another Promise (a Promise resolved |
| 1849 // with another Promise, or an intermediate, hidden, throwaway Promise | 1845 // with another Promise, or an intermediate, hidden, throwaway Promise |
| 1850 // within async/await), then recurse on the outer Promise. | 1846 // within async/await), then recurse on the outer Promise. |
| 1851 // In this case, the dependency is one possible way that the Promise | 1847 // In this case, the dependency is one possible way that the Promise |
| 1852 // could be resolved, so it does not subsume the other following cases. | 1848 // could be resolved, so it does not subsume the other following cases. |
| 1853 Handle<Symbol> key = isolate->factory()->promise_handled_by_symbol(); | 1849 Handle<Symbol> key = isolate->factory()->promise_handled_by_symbol(); |
| 1854 Handle<Object> outer_promise_obj = JSObject::GetDataProperty(promise, key); | 1850 Handle<Object> outer_promise_obj = JSObject::GetDataProperty(promise, key); |
| 1855 if (outer_promise_obj->IsJSPromise() && | 1851 if (outer_promise_obj->IsJSPromise() && |
| 1856 InternalPromiseHasUserDefinedRejectHandler( | 1852 InternalPromiseHasUserDefinedRejectHandler( |
| 1857 isolate, Handle<JSPromise>::cast(outer_promise_obj))) { | 1853 isolate, Handle<JSPromise>::cast(outer_promise_obj))) { |
| 1858 return true; | 1854 return true; |
| 1859 } | 1855 } |
| 1860 | 1856 |
| 1861 Handle<Object> queue(promise->reject_reactions(), isolate); | 1857 Handle<Object> queue(promise->reject_reactions(), isolate); |
| 1862 Handle<Object> deferred(promise->deferred(), isolate); | 1858 Handle<Object> deferred_promise(promise->deferred_promise(), isolate); |
| 1863 | 1859 |
| 1864 if (queue->IsUndefined(isolate)) { | 1860 if (queue->IsUndefined(isolate)) { |
| 1865 return false; | 1861 return false; |
| 1866 } | 1862 } |
| 1867 | 1863 |
| 1868 if (queue->IsCallable()) { | 1864 if (queue->IsCallable()) { |
| 1869 return PromiseHandlerCheck(isolate, Handle<JSReceiver>::cast(queue), | 1865 return PromiseHandlerCheck(isolate, Handle<JSReceiver>::cast(queue), |
| 1870 Handle<JSObject>::cast(deferred)); | 1866 Handle<JSReceiver>::cast(deferred_promise)); |
| 1871 } | 1867 } |
| 1872 | 1868 |
| 1873 Handle<FixedArray> queue_arr = Handle<FixedArray>::cast(queue); | 1869 Handle<FixedArray> queue_arr = Handle<FixedArray>::cast(queue); |
| 1874 Handle<FixedArray> deferred_arr = Handle<FixedArray>::cast(deferred); | 1870 Handle<FixedArray> deferred_promise_arr = |
| 1875 for (int i = 0; i < deferred_arr->length(); i++) { | 1871 Handle<FixedArray>::cast(deferred_promise); |
| 1872 for (int i = 0; i < deferred_promise_arr->length(); i++) { |
| 1876 Handle<JSReceiver> queue_item(JSReceiver::cast(queue_arr->get(i))); | 1873 Handle<JSReceiver> queue_item(JSReceiver::cast(queue_arr->get(i))); |
| 1877 Handle<JSObject> deferred_item(JSObject::cast(deferred_arr->get(i))); | 1874 Handle<JSReceiver> deferred_promise_item( |
| 1878 if (PromiseHandlerCheck(isolate, queue_item, deferred_item)) { | 1875 JSReceiver::cast(deferred_promise_arr->get(i))); |
| 1876 if (PromiseHandlerCheck(isolate, queue_item, deferred_promise_item)) { |
| 1879 return true; | 1877 return true; |
| 1880 } | 1878 } |
| 1881 } | 1879 } |
| 1882 | 1880 |
| 1883 return false; | 1881 return false; |
| 1884 } | 1882 } |
| 1885 | 1883 |
| 1886 } // namespace | 1884 } // namespace |
| 1887 | 1885 |
| 1888 bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<Object> promise) { | 1886 bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<Object> promise) { |
| (...skipping 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3292 void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info, | 3290 void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info, |
| 3293 MaybeHandle<Object>* result, | 3291 MaybeHandle<Object>* result, |
| 3294 MaybeHandle<Object>* maybe_exception) { | 3292 MaybeHandle<Object>* maybe_exception) { |
| 3295 PromiseDebugEventScope helper(this, info->debug_id(), info->debug_name()); | 3293 PromiseDebugEventScope helper(this, info->debug_id(), info->debug_name()); |
| 3296 | 3294 |
| 3297 Handle<JSPromise> promise(info->promise(), this); | 3295 Handle<JSPromise> promise(info->promise(), this); |
| 3298 Handle<Object> value(info->value(), this); | 3296 Handle<Object> value(info->value(), this); |
| 3299 Handle<Object> tasks(info->tasks(), this); | 3297 Handle<Object> tasks(info->tasks(), this); |
| 3300 Handle<JSFunction> promise_handle_fn = promise_handle(); | 3298 Handle<JSFunction> promise_handle_fn = promise_handle(); |
| 3301 Handle<Object> undefined = factory()->undefined_value(); | 3299 Handle<Object> undefined = factory()->undefined_value(); |
| 3302 Handle<Object> deferred(info->deferred(), this); | 3300 Handle<Object> deferred_promise(info->deferred_promise(), this); |
| 3303 | 3301 |
| 3304 if (deferred->IsFixedArray()) { | 3302 if (deferred_promise->IsFixedArray()) { |
| 3305 DCHECK(tasks->IsFixedArray()); | 3303 DCHECK(tasks->IsFixedArray()); |
| 3306 Handle<FixedArray> deferred_arr = Handle<FixedArray>::cast(deferred); | 3304 Handle<FixedArray> deferred_promise_arr = |
| 3305 Handle<FixedArray>::cast(deferred_promise); |
| 3306 Handle<FixedArray> deferred_on_resolve_arr( |
| 3307 FixedArray::cast(info->deferred_on_resolve()), this); |
| 3308 Handle<FixedArray> deferred_on_reject_arr( |
| 3309 FixedArray::cast(info->deferred_on_reject()), this); |
| 3307 Handle<FixedArray> tasks_arr = Handle<FixedArray>::cast(tasks); | 3310 Handle<FixedArray> tasks_arr = Handle<FixedArray>::cast(tasks); |
| 3308 for (int i = 0; i < deferred_arr->length(); i++) { | 3311 for (int i = 0; i < deferred_promise_arr->length(); i++) { |
| 3309 Handle<Object> argv[] = {promise, value, handle(tasks_arr->get(i), this), | 3312 Handle<Object> argv[] = {promise, |
| 3310 handle(deferred_arr->get(i), this)}; | 3313 value, |
| 3314 handle(tasks_arr->get(i), this), |
| 3315 handle(deferred_promise_arr->get(i), this), |
| 3316 handle(deferred_on_resolve_arr->get(i), this), |
| 3317 handle(deferred_on_reject_arr->get(i), this)}; |
| 3311 *result = Execution::TryCall(this, promise_handle_fn, undefined, | 3318 *result = Execution::TryCall(this, promise_handle_fn, undefined, |
| 3312 arraysize(argv), argv, maybe_exception); | 3319 arraysize(argv), argv, maybe_exception); |
| 3313 // If execution is terminating, just bail out. | 3320 // If execution is terminating, just bail out. |
| 3314 if (result->is_null() && maybe_exception->is_null()) { | 3321 if (result->is_null() && maybe_exception->is_null()) { |
| 3315 return; | 3322 return; |
| 3316 } | 3323 } |
| 3317 } | 3324 } |
| 3318 } else { | 3325 } else { |
| 3319 Handle<Object> argv[] = {promise, value, tasks, deferred}; | 3326 Handle<Object> argv[] = {promise, |
| 3327 value, |
| 3328 tasks, |
| 3329 deferred_promise, |
| 3330 handle(info->deferred_on_resolve(), this), |
| 3331 handle(info->deferred_on_reject(), this)}; |
| 3320 *result = Execution::TryCall(this, promise_handle_fn, undefined, | 3332 *result = Execution::TryCall(this, promise_handle_fn, undefined, |
| 3321 arraysize(argv), argv, maybe_exception); | 3333 arraysize(argv), argv, maybe_exception); |
| 3322 } | 3334 } |
| 3323 } | 3335 } |
| 3324 | 3336 |
| 3325 void Isolate::PromiseResolveThenableJob( | 3337 void Isolate::PromiseResolveThenableJob( |
| 3326 Handle<PromiseResolveThenableJobInfo> info, MaybeHandle<Object>* result, | 3338 Handle<PromiseResolveThenableJobInfo> info, MaybeHandle<Object>* result, |
| 3327 MaybeHandle<Object>* maybe_exception) { | 3339 MaybeHandle<Object>* maybe_exception) { |
| 3328 PromiseDebugEventScope helper(this, info->debug_id(), info->debug_name()); | 3340 PromiseDebugEventScope helper(this, info->debug_id(), info->debug_name()); |
| 3329 | 3341 |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3648 // Then check whether this scope intercepts. | 3660 // Then check whether this scope intercepts. |
| 3649 if ((flag & intercept_mask_)) { | 3661 if ((flag & intercept_mask_)) { |
| 3650 intercepted_flags_ |= flag; | 3662 intercepted_flags_ |= flag; |
| 3651 return true; | 3663 return true; |
| 3652 } | 3664 } |
| 3653 return false; | 3665 return false; |
| 3654 } | 3666 } |
| 3655 | 3667 |
| 3656 } // namespace internal | 3668 } // namespace internal |
| 3657 } // namespace v8 | 3669 } // namespace v8 |
| OLD | NEW |