LCOV - code coverage report
Current view: top level - src/runtime - runtime-promise.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 93 93 100.0 %
Date: 2019-03-21 Functions: 18 34 52.9 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/api-inl.h"
       6             : #include "src/arguments-inl.h"
       7             : #include "src/counters.h"
       8             : #include "src/debug/debug.h"
       9             : #include "src/elements.h"
      10             : #include "src/microtask-queue.h"
      11             : #include "src/objects-inl.h"
      12             : #include "src/objects/heap-object-inl.h"
      13             : #include "src/objects/js-promise-inl.h"
      14             : #include "src/objects/oddball-inl.h"
      15             : #include "src/runtime/runtime-utils.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : 
      20        1618 : RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) {
      21             :   DCHECK_EQ(2, args.length());
      22             :   HandleScope scope(isolate);
      23         809 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
      24             :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
      25             : 
      26             :   Handle<Object> rejected_promise = promise;
      27         809 :   if (isolate->debug()->is_active()) {
      28             :     // If the Promise.reject() call is caught, then this will return
      29             :     // undefined, which we interpret as being a caught exception event.
      30         315 :     rejected_promise = isolate->GetPromiseOnStackOnThrow();
      31             :   }
      32         809 :   isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
      33         809 :                           isolate->factory()->undefined_value());
      34         809 :   isolate->debug()->OnPromiseReject(rejected_promise, value);
      35             : 
      36             :   // Report only if we don't actually have a handler.
      37         809 :   if (!promise->has_handler()) {
      38             :     isolate->ReportPromiseReject(promise, value,
      39         809 :                                  v8::kPromiseRejectWithNoHandler);
      40             :   }
      41             :   return ReadOnlyRoots(isolate).undefined_value();
      42             : }
      43             : 
      44         272 : RUNTIME_FUNCTION(Runtime_PromiseRejectAfterResolved) {
      45             :   DCHECK_EQ(2, args.length());
      46             :   HandleScope scope(isolate);
      47         136 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
      48             :   CONVERT_ARG_HANDLE_CHECKED(Object, reason, 1);
      49             :   isolate->ReportPromiseReject(promise, reason,
      50         136 :                                v8::kPromiseRejectAfterResolved);
      51             :   return ReadOnlyRoots(isolate).undefined_value();
      52             : }
      53             : 
      54        2074 : RUNTIME_FUNCTION(Runtime_PromiseResolveAfterResolved) {
      55             :   DCHECK_EQ(2, args.length());
      56             :   HandleScope scope(isolate);
      57        1037 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
      58             :   CONVERT_ARG_HANDLE_CHECKED(Object, resolution, 1);
      59             :   isolate->ReportPromiseReject(promise, resolution,
      60        1037 :                                v8::kPromiseResolveAfterResolved);
      61             :   return ReadOnlyRoots(isolate).undefined_value();
      62             : }
      63             : 
      64        8758 : RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
      65             :   DCHECK_EQ(1, args.length());
      66             :   HandleScope scope(isolate);
      67        4379 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
      68             :   // At this point, no revocation has been issued before
      69        4379 :   CHECK(!promise->has_handler());
      70        4379 :   isolate->ReportPromiseReject(promise, Handle<Object>(),
      71        4379 :                                v8::kPromiseHandlerAddedAfterReject);
      72             :   return ReadOnlyRoots(isolate).undefined_value();
      73             : }
      74             : 
      75         558 : RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
      76             :   HandleScope scope(isolate);
      77             :   DCHECK_EQ(1, args.length());
      78         279 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
      79             : 
      80             :   Handle<CallableTask> microtask = isolate->factory()->NewCallableTask(
      81         558 :       function, handle(function->native_context(), isolate));
      82         837 :   function->native_context()->microtask_queue()->EnqueueMicrotask(*microtask);
      83             :   return ReadOnlyRoots(isolate).undefined_value();
      84             : }
      85             : 
      86       15856 : RUNTIME_FUNCTION(Runtime_PerformMicrotaskCheckpoint) {
      87             :   HandleScope scope(isolate);
      88             :   DCHECK_EQ(0, args.length());
      89        7928 :   MicrotasksScope::PerformCheckpoint(reinterpret_cast<v8::Isolate*>(isolate));
      90             :   return ReadOnlyRoots(isolate).undefined_value();
      91             : }
      92             : 
      93         914 : RUNTIME_FUNCTION(Runtime_RunMicrotaskCallback) {
      94             :   HandleScope scope(isolate);
      95             :   DCHECK_EQ(2, args.length());
      96             :   CONVERT_ARG_CHECKED(Object, microtask_callback, 0);
      97             :   CONVERT_ARG_CHECKED(Object, microtask_data, 1);
      98         457 :   MicrotaskCallback callback = ToCData<MicrotaskCallback>(microtask_callback);
      99         457 :   void* data = ToCData<void*>(microtask_data);
     100         457 :   callback(data);
     101         457 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
     102             :   return ReadOnlyRoots(isolate).undefined_value();
     103             : }
     104             : 
     105          30 : RUNTIME_FUNCTION(Runtime_PromiseStatus) {
     106             :   HandleScope scope(isolate);
     107             :   DCHECK_EQ(1, args.length());
     108          15 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     109             : 
     110          30 :   return Smi::FromInt(promise->status());
     111             : }
     112             : 
     113          10 : RUNTIME_FUNCTION(Runtime_PromiseMarkAsHandled) {
     114             :   SealHandleScope shs(isolate);
     115             :   DCHECK_EQ(1, args.length());
     116          10 :   CONVERT_ARG_CHECKED(JSPromise, promise, 0);
     117             : 
     118           5 :   promise->set_has_handler(true);
     119             :   return ReadOnlyRoots(isolate).undefined_value();
     120             : }
     121             : 
     122       28040 : RUNTIME_FUNCTION(Runtime_PromiseHookInit) {
     123             :   HandleScope scope(isolate);
     124             :   DCHECK_EQ(2, args.length());
     125       14020 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     126             :   CONVERT_ARG_HANDLE_CHECKED(Object, parent, 1);
     127       14020 :   isolate->RunPromiseHook(PromiseHookType::kInit, promise, parent);
     128             :   return ReadOnlyRoots(isolate).undefined_value();
     129             : }
     130             : 
     131             : namespace {
     132             : 
     133        4328 : Handle<JSPromise> AwaitPromisesInitCommon(Isolate* isolate,
     134             :                                           Handle<Object> value,
     135             :                                           Handle<JSPromise> promise,
     136             :                                           Handle<JSPromise> outer_promise,
     137             :                                           Handle<JSFunction> reject_handler,
     138             :                                           bool is_predicted_as_caught) {
     139             :   // Allocate the throwaway promise and fire the appropriate init
     140             :   // hook for the throwaway promise (passing the {promise} as its
     141             :   // parent).
     142        4328 :   Handle<JSPromise> throwaway = isolate->factory()->NewJSPromiseWithoutHook();
     143        4328 :   isolate->RunPromiseHook(PromiseHookType::kInit, throwaway, promise);
     144             : 
     145             :   // On inspector side we capture async stack trace and store it by
     146             :   // outer_promise->async_task_id when async function is suspended first time.
     147             :   // To use captured stack trace later throwaway promise should have the same
     148             :   // async_task_id as outer_promise since we generate WillHandle and DidHandle
     149             :   // events using throwaway promise.
     150        8656 :   throwaway->set_async_task_id(outer_promise->async_task_id());
     151             : 
     152             :   // The Promise will be thrown away and not handled, but it
     153             :   // shouldn't trigger unhandled reject events as its work is done
     154        4328 :   throwaway->set_has_handler(true);
     155             : 
     156             :   // Enable proper debug support for promises.
     157        4328 :   if (isolate->debug()->is_active()) {
     158        4292 :     if (value->IsJSPromise()) {
     159        6194 :       Object::SetProperty(
     160             :           isolate, reject_handler,
     161             :           isolate->factory()->promise_forwarding_handler_symbol(),
     162             :           isolate->factory()->true_value(), StoreOrigin::kMaybeKeyed,
     163        3097 :           Just(ShouldThrow::kThrowOnError))
     164             :           .Check();
     165        6194 :       Handle<JSPromise>::cast(value)->set_handled_hint(is_predicted_as_caught);
     166             :     }
     167             : 
     168             :     // Mark the dependency to {outer_promise} in case the {throwaway}
     169             :     // Promise is found on the Promise stack
     170        8584 :     Object::SetProperty(isolate, throwaway,
     171             :                         isolate->factory()->promise_handled_by_symbol(),
     172             :                         outer_promise, StoreOrigin::kMaybeKeyed,
     173        4292 :                         Just(ShouldThrow::kThrowOnError))
     174             :         .Check();
     175             :   }
     176             : 
     177        4328 :   return throwaway;
     178             : }
     179             : 
     180             : }  // namespace
     181             : 
     182        6230 : RUNTIME_FUNCTION(Runtime_AwaitPromisesInit) {
     183             :   DCHECK_EQ(5, args.length());
     184             :   HandleScope scope(isolate);
     185             :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
     186        3115 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 1);
     187        3115 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, outer_promise, 2);
     188        3115 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject_handler, 3);
     189        3115 :   CONVERT_BOOLEAN_ARG_CHECKED(is_predicted_as_caught, 4);
     190        6230 :   return *AwaitPromisesInitCommon(isolate, value, promise, outer_promise,
     191        3115 :                                   reject_handler, is_predicted_as_caught);
     192             : }
     193             : 
     194        2426 : RUNTIME_FUNCTION(Runtime_AwaitPromisesInitOld) {
     195             :   DCHECK_EQ(5, args.length());
     196             :   HandleScope scope(isolate);
     197             :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
     198        1213 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 1);
     199        1213 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, outer_promise, 2);
     200        1213 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject_handler, 3);
     201        1213 :   CONVERT_BOOLEAN_ARG_CHECKED(is_predicted_as_caught, 4);
     202             : 
     203             :   // Fire the init hook for the wrapper promise (that we created for the
     204             :   // {value} previously).
     205        1213 :   isolate->RunPromiseHook(PromiseHookType::kInit, promise, outer_promise);
     206        2426 :   return *AwaitPromisesInitCommon(isolate, value, promise, outer_promise,
     207        1213 :                                   reject_handler, is_predicted_as_caught);
     208             : }
     209             : 
     210       22314 : RUNTIME_FUNCTION(Runtime_PromiseHookBefore) {
     211             :   HandleScope scope(isolate);
     212             :   DCHECK_EQ(1, args.length());
     213       11157 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, maybe_promise, 0);
     214       22314 :   if (!maybe_promise->IsJSPromise())
     215             :     return ReadOnlyRoots(isolate).undefined_value();
     216       11134 :   Handle<JSPromise> promise = Handle<JSPromise>::cast(maybe_promise);
     217       22092 :   if (isolate->debug()->is_active()) isolate->PushPromise(promise);
     218       22268 :   if (promise->IsJSPromise()) {
     219       11134 :     isolate->RunPromiseHook(PromiseHookType::kBefore, promise,
     220       11134 :                             isolate->factory()->undefined_value());
     221             :   }
     222             :   return ReadOnlyRoots(isolate).undefined_value();
     223             : }
     224             : 
     225       22274 : RUNTIME_FUNCTION(Runtime_PromiseHookAfter) {
     226             :   HandleScope scope(isolate);
     227             :   DCHECK_EQ(1, args.length());
     228       11137 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, maybe_promise, 0);
     229       22274 :   if (!maybe_promise->IsJSPromise())
     230             :     return ReadOnlyRoots(isolate).undefined_value();
     231       11114 :   Handle<JSPromise> promise = Handle<JSPromise>::cast(maybe_promise);
     232       11114 :   if (isolate->debug()->is_active()) isolate->PopPromise();
     233       22228 :   if (promise->IsJSPromise()) {
     234       11114 :     isolate->RunPromiseHook(PromiseHookType::kAfter, promise,
     235       11114 :                             isolate->factory()->undefined_value());
     236             :   }
     237             :   return ReadOnlyRoots(isolate).undefined_value();
     238             : }
     239             : 
     240        9674 : RUNTIME_FUNCTION(Runtime_RejectPromise) {
     241             :   HandleScope scope(isolate);
     242             :   DCHECK_EQ(3, args.length());
     243        4837 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     244             :   CONVERT_ARG_HANDLE_CHECKED(Object, reason, 1);
     245        4837 :   CONVERT_ARG_HANDLE_CHECKED(Oddball, debug_event, 2);
     246        9674 :   return *JSPromise::Reject(promise, reason,
     247        9674 :                             debug_event->BooleanValue(isolate));
     248             : }
     249             : 
     250       56064 : RUNTIME_FUNCTION(Runtime_ResolvePromise) {
     251             :   HandleScope scope(isolate);
     252             :   DCHECK_EQ(2, args.length());
     253       28032 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     254             :   CONVERT_ARG_HANDLE_CHECKED(Object, resolution, 1);
     255             :   Handle<Object> result;
     256       56064 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
     257             :                                      JSPromise::Resolve(promise, resolution));
     258             :   return *result;
     259             : }
     260             : 
     261             : }  // namespace internal
     262      120216 : }  // namespace v8

Generated by: LCOV version 1.10