LCOV - code coverage report
Current view: top level - src/builtins - builtins-weak-refs.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 52 52 100.0 %
Date: 2019-03-21 Functions: 15 22 68.2 %

          Line data    Source code
       1             : // Copyright 2018 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/builtins/builtins-utils-inl.h"
       6             : #include "src/counters.h"
       7             : #include "src/objects/js-weak-refs-inl.h"
       8             : 
       9             : namespace v8 {
      10             : namespace internal {
      11             : 
      12        1770 : BUILTIN(FinalizationGroupConstructor) {
      13             :   HandleScope scope(isolate);
      14             :   Handle<JSFunction> target = args.target();
      15         354 :   if (args.new_target()->IsUndefined(isolate)) {  // [[Call]]
      16          27 :     THROW_NEW_ERROR_RETURN_FAILURE(
      17             :         isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
      18             :                               handle(target->shared()->Name(), isolate)));
      19             :   }
      20             :   // [[Construct]]
      21         345 :   Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
      22             :   Handle<Object> cleanup = args.atOrUndefined(isolate, 1);
      23             : 
      24         345 :   if (!cleanup->IsCallable()) {
      25          92 :     THROW_NEW_ERROR_RETURN_FAILURE(
      26             :         isolate, NewTypeError(MessageTemplate::kWeakRefsCleanupMustBeCallable));
      27             :   }
      28             : 
      29             :   Handle<JSObject> result;
      30         598 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      31             :       isolate, result,
      32             :       JSObject::New(target, new_target, Handle<AllocationSite>::null()));
      33             : 
      34             :   Handle<JSFinalizationGroup> finalization_group =
      35             :       Handle<JSFinalizationGroup>::cast(result);
      36         598 :   finalization_group->set_native_context(*isolate->native_context());
      37         299 :   finalization_group->set_cleanup(*cleanup);
      38             :   finalization_group->set_flags(
      39             :       JSFinalizationGroup::ScheduledForCleanupField::encode(false));
      40             : 
      41             :   DCHECK(finalization_group->active_cells()->IsUndefined(isolate));
      42             :   DCHECK(finalization_group->cleared_cells()->IsUndefined(isolate));
      43             :   DCHECK(finalization_group->key_map()->IsUndefined(isolate));
      44         299 :   return *finalization_group;
      45             : }
      46             : 
      47        2035 : BUILTIN(FinalizationGroupRegister) {
      48             :   HandleScope scope(isolate);
      49             :   const char* method_name = "FinalizationGroup.prototype.register";
      50             : 
      51         434 :   CHECK_RECEIVER(JSFinalizationGroup, finalization_group, method_name);
      52             : 
      53             :   Handle<Object> target = args.atOrUndefined(isolate, 1);
      54         398 :   if (!target->IsJSReceiver()) {
      55         118 :     THROW_NEW_ERROR_RETURN_FAILURE(
      56             :         isolate,
      57             :         NewTypeError(MessageTemplate::kWeakRefsRegisterTargetMustBeObject));
      58             :   }
      59             :   Handle<Object> holdings = args.atOrUndefined(isolate, 2);
      60         339 :   if (target->SameValue(*holdings)) {
      61          28 :     THROW_NEW_ERROR_RETURN_FAILURE(
      62             :         isolate,
      63             :         NewTypeError(
      64             :             MessageTemplate::kWeakRefsRegisterTargetAndHoldingsMustNotBeSame));
      65             :   }
      66             : 
      67         325 :   Handle<Object> key = args.atOrUndefined(isolate, 3);
      68             :   // TODO(marja, gsathya): Restrictions on "key" (e.g., does it need to be an
      69             :   // object).
      70             : 
      71             :   // TODO(marja): Realms.
      72             : 
      73             :   JSFinalizationGroup::Register(finalization_group,
      74             :                                 Handle<JSReceiver>::cast(target), holdings, key,
      75         325 :                                 isolate);
      76         325 :   return ReadOnlyRoots(isolate).undefined_value();
      77             : }
      78             : 
      79         540 : BUILTIN(FinalizationGroupUnregister) {
      80             :   HandleScope scope(isolate);
      81             :   const char* method_name = "FinalizationGroup.prototype.unregister";
      82             : 
      83         108 :   CHECK_RECEIVER(JSFinalizationGroup, finalization_group, method_name);
      84             : 
      85         108 :   Handle<Object> key = args.atOrUndefined(isolate, 1);
      86         108 :   JSFinalizationGroup::Unregister(finalization_group, key, isolate);
      87         108 :   return ReadOnlyRoots(isolate).undefined_value();
      88             : }
      89             : 
      90         270 : BUILTIN(FinalizationGroupCleanupSome) {
      91             :   HandleScope scope(isolate);
      92             :   const char* method_name = "FinalizationGroup.prototype.cleanupSome";
      93             : 
      94          81 :   CHECK_RECEIVER(JSFinalizationGroup, finalization_group, method_name);
      95             : 
      96             :   // TODO(marja, gsathya): Add missing "cleanup" callback.
      97             : 
      98             :   // Don't do set_scheduled_for_cleanup(false); we still have the microtask
      99             :   // scheduled and don't want to schedule another one in case the user never
     100             :   // executes microtasks.
     101          45 :   JSFinalizationGroup::Cleanup(finalization_group, isolate);
     102          45 :   return ReadOnlyRoots(isolate).undefined_value();
     103             : }
     104             : 
     105        1845 : BUILTIN(FinalizationGroupCleanupIteratorNext) {
     106             :   HandleScope scope(isolate);
     107         369 :   CHECK_RECEIVER(JSFinalizationGroupCleanupIterator, iterator, "next");
     108             : 
     109             :   Handle<JSFinalizationGroup> finalization_group(iterator->finalization_group(),
     110             :                                                  isolate);
     111         369 :   if (!finalization_group->NeedsCleanup()) {
     112         324 :     return *isolate->factory()->NewJSIteratorResult(
     113         324 :         handle(ReadOnlyRoots(isolate).undefined_value(), isolate), true);
     114             :   }
     115             :   Handle<Object> holdings = handle(
     116             :       JSFinalizationGroup::PopClearedCellHoldings(finalization_group, isolate),
     117         414 :       isolate);
     118             : 
     119         414 :   return *isolate->factory()->NewJSIteratorResult(holdings, false);
     120             : }
     121             : 
     122         720 : BUILTIN(WeakRefConstructor) {
     123             :   HandleScope scope(isolate);
     124             :   Handle<JSFunction> target = args.target();
     125         144 :   if (args.new_target()->IsUndefined(isolate)) {  // [[Call]]
     126          27 :     THROW_NEW_ERROR_RETURN_FAILURE(
     127             :         isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
     128             :                               handle(target->shared()->Name(), isolate)));
     129             :   }
     130             :   // [[Construct]]
     131         135 :   Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
     132             :   Handle<Object> target_object = args.atOrUndefined(isolate, 1);
     133         135 :   if (!target_object->IsJSReceiver()) {
     134         126 :     THROW_NEW_ERROR_RETURN_FAILURE(
     135             :         isolate,
     136             :         NewTypeError(
     137             :             MessageTemplate::kWeakRefsWeakRefConstructorTargetMustBeObject));
     138             :   }
     139             :   Handle<JSReceiver> target_receiver =
     140             :       handle(JSReceiver::cast(*target_object), isolate);
     141          72 :   isolate->heap()->AddKeepDuringJobTarget(target_receiver);
     142             : 
     143             :   // TODO(marja): Realms.
     144             : 
     145             :   Handle<JSObject> result;
     146         144 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     147             :       isolate, result,
     148             :       JSObject::New(target, new_target, Handle<AllocationSite>::null()));
     149             : 
     150             :   Handle<JSWeakRef> weak_ref = Handle<JSWeakRef>::cast(result);
     151         144 :   weak_ref->set_target(*target_receiver);
     152          72 :   return *weak_ref;
     153             : }
     154             : 
     155         720 : BUILTIN(WeakRefDeref) {
     156             :   HandleScope scope(isolate);
     157         144 :   CHECK_RECEIVER(JSWeakRef, weak_ref, "WeakRef.prototype.deref");
     158         144 :   if (weak_ref->target()->IsJSReceiver()) {
     159             :     Handle<JSReceiver> target =
     160          90 :         handle(JSReceiver::cast(weak_ref->target()), isolate);
     161             :     // AddKeepDuringJobTarget might allocate and cause a GC, but it won't clear
     162             :     // weak_ref since we hold a Handle to its target.
     163          90 :     isolate->heap()->AddKeepDuringJobTarget(target);
     164             :   } else {
     165             :     DCHECK(weak_ref->target()->IsUndefined(isolate));
     166             :   }
     167         144 :   return weak_ref->target();
     168             : }
     169             : 
     170             : }  // namespace internal
     171      120216 : }  // namespace v8

Generated by: LCOV version 1.10