LCOV - code coverage report
Current view: top level - src - prototype-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 59 63 93.7 %
Date: 2019-01-20 Functions: 8 8 100.0 %

          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             : #ifndef V8_PROTOTYPE_INL_H_
       6             : #define V8_PROTOTYPE_INL_H_
       7             : 
       8             : #include "src/prototype.h"
       9             : 
      10             : #include "src/handles-inl.h"
      11             : #include "src/objects/map-inl.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16    10486692 : PrototypeIterator::PrototypeIterator(Isolate* isolate,
      17             :                                      Handle<JSReceiver> receiver,
      18             :                                      WhereToStart where_to_start,
      19             :                                      WhereToEnd where_to_end)
      20             :     : isolate_(isolate),
      21             :       handle_(receiver),
      22             :       where_to_end_(where_to_end),
      23             :       is_at_end_(false),
      24    20973384 :       seen_proxies_(0) {
      25    10486692 :   CHECK(!handle_.is_null());
      26    10486692 :   if (where_to_start == kStartAtPrototype) Advance();
      27    10486694 : }
      28             : 
      29             : PrototypeIterator::PrototypeIterator(Isolate* isolate, JSReceiver receiver,
      30             :                                      WhereToStart where_to_start,
      31             :                                      WhereToEnd where_to_end)
      32             :     : isolate_(isolate),
      33             :       object_(receiver),
      34             :       where_to_end_(where_to_end),
      35             :       is_at_end_(false),
      36     2339972 :       seen_proxies_(0) {
      37      985691 :   if (where_to_start == kStartAtPrototype) Advance();
      38             : }
      39             : 
      40       59604 : PrototypeIterator::PrototypeIterator(Isolate* isolate, Map receiver_map,
      41             :                                      WhereToEnd where_to_end)
      42             :     : isolate_(isolate),
      43      119208 :       object_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype()),
      44             :       where_to_end_(where_to_end),
      45       59604 :       is_at_end_(object_->IsNull(isolate_)),
      46      238416 :       seen_proxies_(0) {
      47       59604 :   if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
      48             :     DCHECK(object_->IsJSReceiver());
      49           0 :     Map map = JSReceiver::cast(object_)->map();
      50           0 :     is_at_end_ = !map->has_hidden_prototype();
      51             :   }
      52       59604 : }
      53             : 
      54     1734989 : PrototypeIterator::PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
      55             :                                      WhereToEnd where_to_end)
      56             :     : isolate_(isolate),
      57     3469990 :       handle_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype(),
      58             :               isolate_),
      59             :       where_to_end_(where_to_end),
      60     5204994 :       is_at_end_(handle_->IsNull(isolate_)),
      61    10409972 :       seen_proxies_(0) {
      62     1734998 :   if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
      63             :     DCHECK(handle_->IsJSReceiver());
      64           0 :     Map map = JSReceiver::cast(*handle_)->map();
      65           0 :     is_at_end_ = !map->has_hidden_prototype();
      66             :   }
      67     1734998 : }
      68             : 
      69     6962015 : bool PrototypeIterator::HasAccess() const {
      70             :   // We can only perform access check in the handlified version of the
      71             :   // PrototypeIterator.
      72             :   DCHECK(!handle_.is_null());
      73    13924030 :   if (handle_->IsAccessCheckNeeded()) {
      74             :     return isolate_->MayAccess(handle(isolate_->context(), isolate_),
      75         406 :                                Handle<JSObject>::cast(handle_));
      76             :   }
      77             :   return true;
      78             : }
      79             : 
      80     8308559 : void PrototypeIterator::Advance() {
      81     9927560 :   if (handle_.is_null() && object_->IsJSProxy()) {
      82        1433 :     is_at_end_ = true;
      83        2866 :     object_ = ReadOnlyRoots(isolate_).null_value();
      84        1433 :     return;
      85    21686352 :   } else if (!handle_.is_null() && handle_->IsJSProxy()) {
      86         728 :     is_at_end_ = true;
      87        1456 :     handle_ = isolate_->factory()->null_value();
      88         728 :     return;
      89             :   }
      90     8306439 :   AdvanceIgnoringProxies();
      91             : }
      92             : 
      93    13811853 : void PrototypeIterator::AdvanceIgnoringProxies() {
      94    13811853 :   Object object = handle_.is_null() ? object_ : *handle_;
      95    13811849 :   Map map = HeapObject::cast(object)->map();
      96             : 
      97    13811849 :   Object prototype = map->prototype();
      98    18473208 :   is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN ? !map->has_hidden_prototype()
      99    32285070 :                                                   : prototype->IsNull(isolate_);
     100             : 
     101    13811861 :   if (handle_.is_null()) {
     102     1630492 :     object_ = prototype;
     103             :   } else {
     104    24362740 :     handle_ = handle(prototype, isolate_);
     105             :   }
     106    13811863 : }
     107             : 
     108     6962015 : V8_WARN_UNUSED_RESULT bool PrototypeIterator::AdvanceFollowingProxies() {
     109             :   DCHECK(!(handle_.is_null() && object_->IsJSProxy()));
     110     6962015 :   if (!HasAccess()) {
     111             :     // Abort the lookup if we do not have access to the current object.
     112         366 :     handle_ = isolate_->factory()->null_value();
     113         183 :     is_at_end_ = true;
     114         183 :     return true;
     115             :   }
     116     6961832 :   return AdvanceFollowingProxiesIgnoringAccessChecks();
     117             : }
     118             : 
     119             : V8_WARN_UNUSED_RESULT bool
     120     9107732 : PrototypeIterator::AdvanceFollowingProxiesIgnoringAccessChecks() {
     121    27323196 :   if (handle_.is_null() || !handle_->IsJSProxy()) {
     122     5391215 :     AdvanceIgnoringProxies();
     123     5391215 :     return true;
     124             :   }
     125             : 
     126             :   // Due to possible __proto__ recursion limit the number of Proxies
     127             :   // we visit to an arbitrarily chosen large number.
     128     3716517 :   seen_proxies_++;
     129     3716517 :   if (seen_proxies_ > JSProxy::kMaxIterationLimit) {
     130          36 :     isolate_->StackOverflow();
     131          36 :     return false;
     132             :   }
     133             :   MaybeHandle<Object> proto =
     134     3716481 :       JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_));
     135     7432962 :   if (!proto.ToHandle(&handle_)) return false;
     136    11063130 :   is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN || handle_->IsNull(isolate_);
     137             :   return true;
     138             : }
     139             : 
     140             : }  // namespace internal
     141             : }  // namespace v8
     142             : 
     143             : #endif  // V8_PROTOTYPE_INL_H_

Generated by: LCOV version 1.10