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-04-19 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        1688 : RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) {
      21             :   DCHECK_EQ(2, args.length());
      22             :   HandleScope scope(isolate);
      23         844 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
      24             :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
      25             : 
      26             :   Handle<Object> rejected_promise = promise;
      27         844 :   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         844 :   isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
      33         844 :                           isolate->factory()->undefined_value());
      34         844 :   isolate->debug()->OnPromiseReject(rejected_promise, value);
      35             : 
      36             :   // Report only if we don't actually have a handler.
      37         844 :   if (!promise->has_handler()) {
      38             :     isolate->ReportPromiseReject(promise, value,
      39         844 :                                  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        8882 : RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
      65             :   DCHECK_EQ(1, args.length());
      66             :   HandleScope scope(isolate);
      67        4441 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
      68             :   // At this point, no revocation has been issued before
      69        4441 :   CHECK(!promise->has_handler());
      70        4441 :   isolate->ReportPromiseReject(promise, Handle<Object>(),
      71        4441 :                                v8::kPromiseHandlerAddedAfterReject);
      72             :   return ReadOnlyRoots(isolate).undefined_value();
      73             : }
      74             : 
      75         560 : RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
      76             :   HandleScope scope(isolate);
      77             :   DCHECK_EQ(1, args.length());
      78         280 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
      79             : 
      80             :   Handle<CallableTask> microtask = isolate->factory()->NewCallableTask(
      81         280 :       function, handle(function->native_context(), isolate));
      82             :   MicrotaskQueue* microtask_queue =
      83             :       function->native_context()->microtask_queue();
      84         559 :   if (microtask_queue) microtask_queue->EnqueueMicrotask(*microtask);
      85             :   return ReadOnlyRoots(isolate).undefined_value();
      86             : }
      87             : 
      88       16072 : RUNTIME_FUNCTION(Runtime_PerformMicrotaskCheckpoint) {
      89             :   HandleScope scope(isolate);
      90             :   DCHECK_EQ(0, args.length());
      91        8036 :   MicrotasksScope::PerformCheckpoint(reinterpret_cast<v8::Isolate*>(isolate));
      92             :   return ReadOnlyRoots(isolate).undefined_value();
      93             : }
      94             : 
      95         916 : RUNTIME_FUNCTION(Runtime_RunMicrotaskCallback) {
      96             :   HandleScope scope(isolate);
      97             :   DCHECK_EQ(2, args.length());
      98             :   CONVERT_ARG_CHECKED(Object, microtask_callback, 0);
      99             :   CONVERT_ARG_CHECKED(Object, microtask_data, 1);
     100         458 :   MicrotaskCallback callback = ToCData<MicrotaskCallback>(microtask_callback);
     101         458 :   void* data = ToCData<void*>(microtask_data);
     102         458 :   callback(data);
     103         458 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
     104             :   return ReadOnlyRoots(isolate).undefined_value();
     105             : }
     106             : 
     107          30 : RUNTIME_FUNCTION(Runtime_PromiseStatus) {
     108             :   HandleScope scope(isolate);
     109             :   DCHECK_EQ(1, args.length());
     110          15 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     111             : 
     112          30 :   return Smi::FromInt(promise->status());
     113             : }
     114             : 
     115          10 : RUNTIME_FUNCTION(Runtime_PromiseMarkAsHandled) {
     116             :   SealHandleScope shs(isolate);
     117             :   DCHECK_EQ(1, args.length());
     118          10 :   CONVERT_ARG_CHECKED(JSPromise, promise, 0);
     119             : 
     120           5 :   promise->set_has_handler(true);
     121             :   return ReadOnlyRoots(isolate).undefined_value();
     122             : }
     123             : 
     124       28092 : RUNTIME_FUNCTION(Runtime_PromiseHookInit) {
     125             :   HandleScope scope(isolate);
     126             :   DCHECK_EQ(2, args.length());
     127       14046 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     128             :   CONVERT_ARG_HANDLE_CHECKED(Object, parent, 1);
     129       14046 :   isolate->RunPromiseHook(PromiseHookType::kInit, promise, parent);
     130             :   return ReadOnlyRoots(isolate).undefined_value();
     131             : }
     132             : 
     133             : namespace {
     134             : 
     135        4328 : Handle<JSPromise> AwaitPromisesInitCommon(Isolate* isolate,
     136             :                                           Handle<Object> value,
     137             :                                           Handle<JSPromise> promise,
     138             :                                           Handle<JSPromise> outer_promise,
     139             :                                           Handle<JSFunction> reject_handler,
     140             :                                           bool is_predicted_as_caught) {
     141             :   // Allocate the throwaway promise and fire the appropriate init
     142             :   // hook for the throwaway promise (passing the {promise} as its
     143             :   // parent).
     144        4328 :   Handle<JSPromise> throwaway = isolate->factory()->NewJSPromiseWithoutHook();
     145        4328 :   isolate->RunPromiseHook(PromiseHookType::kInit, throwaway, promise);
     146             : 
     147             :   // On inspector side we capture async stack trace and store it by
     148             :   // outer_promise->async_task_id when async function is suspended first time.
     149             :   // To use captured stack trace later throwaway promise should have the same
     150             :   // async_task_id as outer_promise since we generate WillHandle and DidHandle
     151             :   // events using throwaway promise.
     152        8656 :   throwaway->set_async_task_id(outer_promise->async_task_id());
     153             : 
     154             :   // The Promise will be thrown away and not handled, but it
     155             :   // shouldn't trigger unhandled reject events as its work is done
     156        4328 :   throwaway->set_has_handler(true);
     157             : 
     158             :   // Enable proper debug support for promises.
     159        4328 :   if (isolate->debug()->is_active()) {
     160        4292 :     if (value->IsJSPromise()) {
     161        6194 :       Object::SetProperty(
     162             :           isolate, reject_handler,
     163             :           isolate->factory()->promise_forwarding_handler_symbol(),
     164             :           isolate->factory()->true_value(), StoreOrigin::kMaybeKeyed,
     165        3097 :           Just(ShouldThrow::kThrowOnError))
     166             :           .Check();
     167        6194 :       Handle<JSPromise>::cast(value)->set_handled_hint(is_predicted_as_caught);
     168             :     }
     169             : 
     170             :     // Mark the dependency to {outer_promise} in case the {throwaway}
     171             :     // Promise is found on the Promise stack
     172        8584 :     Object::SetProperty(isolate, throwaway,
     173             :                         isolate->factory()->promise_handled_by_symbol(),
     174             :                         outer_promise, StoreOrigin::kMaybeKeyed,
     175        4292 :                         Just(ShouldThrow::kThrowOnError))
     176             :         .Check();
     177             :   }
     178             : 
     179        4328 :   return throwaway;
     180             : }
     181             : 
     182             : }  // namespace
     183             : 
     184        6230 : RUNTIME_FUNCTION(Runtime_AwaitPromisesInit) {
     185             :   DCHECK_EQ(5, args.length());
     186             :   HandleScope scope(isolate);
     187             :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
     188        3115 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 1);
     189        3115 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, outer_promise, 2);
     190        3115 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject_handler, 3);
     191        3115 :   CONVERT_BOOLEAN_ARG_CHECKED(is_predicted_as_caught, 4);
     192        6230 :   return *AwaitPromisesInitCommon(isolate, value, promise, outer_promise,
     193        3115 :                                   reject_handler, is_predicted_as_caught);
     194             : }
     195             : 
     196        2426 : RUNTIME_FUNCTION(Runtime_AwaitPromisesInitOld) {
     197             :   DCHECK_EQ(5, args.length());
     198             :   HandleScope scope(isolate);
     199             :   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
     200        1213 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 1);
     201        1213 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, outer_promise, 2);
     202        1213 :   CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject_handler, 3);
     203        1213 :   CONVERT_BOOLEAN_ARG_CHECKED(is_predicted_as_caught, 4);
     204             : 
     205             :   // Fire the init hook for the wrapper promise (that we created for the
     206             :   // {value} previously).
     207        1213 :   isolate->RunPromiseHook(PromiseHookType::kInit, promise, outer_promise);
     208        2426 :   return *AwaitPromisesInitCommon(isolate, value, promise, outer_promise,
     209        1213 :                                   reject_handler, is_predicted_as_caught);
     210             : }
     211             : 
     212       22314 : RUNTIME_FUNCTION(Runtime_PromiseHookBefore) {
     213             :   HandleScope scope(isolate);
     214             :   DCHECK_EQ(1, args.length());
     215       11157 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, maybe_promise, 0);
     216       22314 :   if (!maybe_promise->IsJSPromise())
     217             :     return ReadOnlyRoots(isolate).undefined_value();
     218       11134 :   Handle<JSPromise> promise = Handle<JSPromise>::cast(maybe_promise);
     219       22092 :   if (isolate->debug()->is_active()) isolate->PushPromise(promise);
     220       22268 :   if (promise->IsJSPromise()) {
     221       11134 :     isolate->RunPromiseHook(PromiseHookType::kBefore, promise,
     222       11134 :                             isolate->factory()->undefined_value());
     223             :   }
     224             :   return ReadOnlyRoots(isolate).undefined_value();
     225             : }
     226             : 
     227       22274 : RUNTIME_FUNCTION(Runtime_PromiseHookAfter) {
     228             :   HandleScope scope(isolate);
     229             :   DCHECK_EQ(1, args.length());
     230       11137 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, maybe_promise, 0);
     231       22274 :   if (!maybe_promise->IsJSPromise())
     232             :     return ReadOnlyRoots(isolate).undefined_value();
     233       11114 :   Handle<JSPromise> promise = Handle<JSPromise>::cast(maybe_promise);
     234       11114 :   if (isolate->debug()->is_active()) isolate->PopPromise();
     235       22228 :   if (promise->IsJSPromise()) {
     236       11114 :     isolate->RunPromiseHook(PromiseHookType::kAfter, promise,
     237       11114 :                             isolate->factory()->undefined_value());
     238             :   }
     239             :   return ReadOnlyRoots(isolate).undefined_value();
     240             : }
     241             : 
     242        9764 : RUNTIME_FUNCTION(Runtime_RejectPromise) {
     243             :   HandleScope scope(isolate);
     244             :   DCHECK_EQ(3, args.length());
     245        4882 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     246             :   CONVERT_ARG_HANDLE_CHECKED(Object, reason, 1);
     247        4882 :   CONVERT_ARG_HANDLE_CHECKED(Oddball, debug_event, 2);
     248        9764 :   return *JSPromise::Reject(promise, reason,
     249        9764 :                             debug_event->BooleanValue(isolate));
     250             : }
     251             : 
     252       56116 : RUNTIME_FUNCTION(Runtime_ResolvePromise) {
     253             :   HandleScope scope(isolate);
     254             :   DCHECK_EQ(2, args.length());
     255       28058 :   CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
     256             :   CONVERT_ARG_HANDLE_CHECKED(Object, resolution, 1);
     257             :   Handle<Object> result;
     258       56116 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
     259             :                                      JSPromise::Resolve(promise, resolution));
     260             :   return *result;
     261             : }
     262             : 
     263             : }  // namespace internal
     264      122036 : }  // namespace v8

Generated by: LCOV version 1.10