LCOV - code coverage report
Current view: top level - src - prototype-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 59 61 96.7 %
Date: 2019-04-19 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/js-proxy.h"
      12             : #include "src/objects/map-inl.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17     6305581 : PrototypeIterator::PrototypeIterator(Isolate* isolate,
      18             :                                      Handle<JSReceiver> receiver,
      19             :                                      WhereToStart where_to_start,
      20             :                                      WhereToEnd where_to_end)
      21             :     : isolate_(isolate),
      22             :       handle_(receiver),
      23             :       where_to_end_(where_to_end),
      24             :       is_at_end_(false),
      25    22469944 :       seen_proxies_(0) {
      26    11234972 :   CHECK(!handle_.is_null());
      27     6305581 :   if (where_to_start == kStartAtPrototype) Advance();
      28     6305584 : }
      29             : 
      30             : PrototypeIterator::PrototypeIterator(Isolate* isolate, JSReceiver receiver,
      31             :                                      WhereToStart where_to_start,
      32             :                                      WhereToEnd where_to_end)
      33             :     : isolate_(isolate),
      34             :       object_(receiver),
      35             :       where_to_end_(where_to_end),
      36             :       is_at_end_(false),
      37     2339338 :       seen_proxies_(0) {
      38      985261 :   if (where_to_start == kStartAtPrototype) Advance();
      39             : }
      40             : 
      41       62130 : PrototypeIterator::PrototypeIterator(Isolate* isolate, Map receiver_map,
      42             :                                      WhereToEnd where_to_end)
      43             :     : isolate_(isolate),
      44      124260 :       object_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype()),
      45             :       where_to_end_(where_to_end),
      46       62130 :       is_at_end_(object_->IsNull(isolate_)),
      47      248520 :       seen_proxies_(0) {
      48       62130 :   if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
      49             :     DCHECK(object_->IsJSReceiver());
      50             :     Map map = JSReceiver::cast(object_)->map();
      51           0 :     is_at_end_ = !map->has_hidden_prototype();
      52             :   }
      53       62130 : }
      54             : 
      55     1798678 : PrototypeIterator::PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
      56             :                                      WhereToEnd where_to_end)
      57             :     : isolate_(isolate),
      58     3597348 :       handle_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype(),
      59             :               isolate_),
      60             :       where_to_end_(where_to_end),
      61     1798670 :       is_at_end_(handle_->IsNull(isolate_)),
      62     5396018 :       seen_proxies_(0) {
      63     1798670 :   if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
      64             :     DCHECK(handle_->IsJSReceiver());
      65             :     Map map = JSReceiver::cast(*handle_)->map();
      66           0 :     is_at_end_ = !map->has_hidden_prototype();
      67             :   }
      68     1798670 : }
      69             : 
      70     6975810 : bool PrototypeIterator::HasAccess() const {
      71             :   // We can only perform access check in the handlified version of the
      72             :   // PrototypeIterator.
      73             :   DCHECK(!handle_.is_null());
      74     6975810 :   if (handle_->IsAccessCheckNeeded()) {
      75         382 :     return isolate_->MayAccess(handle(isolate_->context(), isolate_),
      76         191 :                                Handle<JSObject>::cast(handle_));
      77             :   }
      78             :   return true;
      79             : }
      80             : 
      81     9295469 : void PrototypeIterator::Advance() {
      82    10921058 :   if (handle_.is_null() && object_->IsJSProxy()) {
      83        1429 :     is_at_end_ = true;
      84        2858 :     object_ = ReadOnlyRoots(isolate_).null_value();
      85        1429 :     return;
      86    16963911 :   } else if (!handle_.is_null() && handle_->IsJSProxy()) {
      87         760 :     is_at_end_ = true;
      88        1520 :     handle_ = isolate_->factory()->null_value();
      89         760 :     return;
      90             :   }
      91     9293280 :   AdvanceIgnoringProxies();
      92             : }
      93             : 
      94    14894972 : void PrototypeIterator::AdvanceIgnoringProxies() {
      95    14894972 :   Object object = handle_.is_null() ? object_ : *handle_;
      96             :   Map map = HeapObject::cast(object)->map();
      97             : 
      98             :   HeapObject prototype = map->prototype();
      99    14894972 :   is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN ? !map->has_hidden_prototype()
     100    34539019 :                                                   : prototype->IsNull(isolate_);
     101             : 
     102    14894972 :   if (handle_.is_null()) {
     103     1637549 :     object_ = prototype;
     104             :   } else {
     105    26514854 :     handle_ = handle(prototype, isolate_);
     106             :   }
     107    14894980 : }
     108             : 
     109     6975810 : V8_WARN_UNUSED_RESULT bool PrototypeIterator::AdvanceFollowingProxies() {
     110             :   DCHECK(!(handle_.is_null() && object_->IsJSProxy()));
     111     6975810 :   if (!HasAccess()) {
     112             :     // Abort the lookup if we do not have access to the current object.
     113         342 :     handle_ = isolate_->factory()->null_value();
     114         171 :     is_at_end_ = true;
     115         171 :     return true;
     116             :   }
     117     6975639 :   return AdvanceFollowingProxiesIgnoringAccessChecks();
     118             : }
     119             : 
     120             : V8_WARN_UNUSED_RESULT bool
     121     9218744 : PrototypeIterator::AdvanceFollowingProxiesIgnoringAccessChecks() {
     122    18437488 :   if (handle_.is_null() || !handle_->IsJSProxy()) {
     123     5486902 :     AdvanceIgnoringProxies();
     124     5486902 :     return true;
     125             :   }
     126             : 
     127             :   // Due to possible __proto__ recursion limit the number of Proxies
     128             :   // we visit to an arbitrarily chosen large number.
     129     3731842 :   seen_proxies_++;
     130     3731842 :   if (seen_proxies_ > JSProxy::kMaxIterationLimit) {
     131          36 :     isolate_->StackOverflow();
     132          36 :     return false;
     133             :   }
     134             :   MaybeHandle<HeapObject> proto =
     135     3731806 :       JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_));
     136     7463612 :   if (!proto.ToHandle(&handle_)) return false;
     137     7375664 :   is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN || handle_->IsNull(isolate_);
     138     3688066 :   return true;
     139             : }
     140             : 
     141             : }  // namespace internal
     142             : }  // namespace v8
     143             : 
     144             : #endif  // V8_PROTOTYPE_INL_H_

Generated by: LCOV version 1.10