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-02-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     9614081 : 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    19228162 :       seen_proxies_(0) {
      26     9614081 :   CHECK(!handle_.is_null());
      27     9614081 :   if (where_to_start == kStartAtPrototype) Advance();
      28     9614084 : }
      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     2321466 :       seen_proxies_(0) {
      38      976777 :   if (where_to_start == kStartAtPrototype) Advance();
      39             : }
      40             : 
      41       58170 : PrototypeIterator::PrototypeIterator(Isolate* isolate, Map receiver_map,
      42             :                                      WhereToEnd where_to_end)
      43             :     : isolate_(isolate),
      44      116340 :       object_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype()),
      45             :       where_to_end_(where_to_end),
      46       58170 :       is_at_end_(object_->IsNull(isolate_)),
      47      232680 :       seen_proxies_(0) {
      48       58170 :   if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
      49             :     DCHECK(object_->IsJSReceiver());
      50           0 :     Map map = JSReceiver::cast(object_)->map();
      51           0 :     is_at_end_ = !map->has_hidden_prototype();
      52             :   }
      53       58170 : }
      54             : 
      55     1723334 : PrototypeIterator::PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
      56             :                                      WhereToEnd where_to_end)
      57             :     : isolate_(isolate),
      58     3446665 :       handle_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype(),
      59             :               isolate_),
      60             :       where_to_end_(where_to_end),
      61     5169995 :       is_at_end_(handle_->IsNull(isolate_)),
      62    10339999 :       seen_proxies_(0) {
      63     1723335 :   if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
      64             :     DCHECK(handle_->IsJSReceiver());
      65           0 :     Map map = JSReceiver::cast(*handle_)->map();
      66           0 :     is_at_end_ = !map->has_hidden_prototype();
      67             :   }
      68     1723335 : }
      69             : 
      70     6955439 : 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    13910878 :   if (handle_->IsAccessCheckNeeded()) {
      75             :     return isolate_->MayAccess(handle(isolate_->context(), isolate_),
      76         382 :                                Handle<JSObject>::cast(handle_));
      77             :   }
      78             :   return true;
      79             : }
      80             : 
      81     7741258 : void PrototypeIterator::Advance() {
      82     9347540 :   if (handle_.is_null() && object_->IsJSProxy()) {
      83        1429 :     is_at_end_ = true;
      84        2858 :     object_ = ReadOnlyRoots(isolate_).null_value();
      85        1429 :     return;
      86    20009818 :   } else if (!handle_.is_null() && handle_->IsJSProxy()) {
      87         749 :     is_at_end_ = true;
      88        1498 :     handle_ = isolate_->factory()->null_value();
      89         749 :     return;
      90             :   }
      91     7739097 :   AdvanceIgnoringProxies();
      92             : }
      93             : 
      94    13241842 : void PrototypeIterator::AdvanceIgnoringProxies() {
      95    13241842 :   Object object = handle_.is_null() ? object_ : *handle_;
      96    13241837 :   Map map = HeapObject::cast(object)->map();
      97             : 
      98    13241837 :   Object prototype = map->prototype();
      99    17894057 :   is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN ? !map->has_hidden_prototype()
     100    31135897 :                                                   : prototype->IsNull(isolate_);
     101             : 
     102    13241838 :   if (handle_.is_null()) {
     103     1617777 :     object_ = prototype;
     104             :   } else {
     105    23248123 :     handle_ = handle(prototype, isolate_);
     106             :   }
     107    13241839 : }
     108             : 
     109     6955439 : V8_WARN_UNUSED_RESULT bool PrototypeIterator::AdvanceFollowingProxies() {
     110             :   DCHECK(!(handle_.is_null() && object_->IsJSProxy()));
     111     6955439 :   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     6955268 :   return AdvanceFollowingProxiesIgnoringAccessChecks();
     118             : }
     119             : 
     120             : V8_WARN_UNUSED_RESULT bool
     121     9100350 : PrototypeIterator::AdvanceFollowingProxiesIgnoringAccessChecks() {
     122    27301050 :   if (handle_.is_null() || !handle_->IsJSProxy()) {
     123     5388560 :     AdvanceIgnoringProxies();
     124     5388560 :     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     3711790 :   seen_proxies_++;
     130     3711790 :   if (seen_proxies_ > JSProxy::kMaxIterationLimit) {
     131          36 :     isolate_->StackOverflow();
     132          36 :     return false;
     133             :   }
     134             :   MaybeHandle<Object> proto =
     135     3711754 :       JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_));
     136     7423508 :   if (!proto.ToHandle(&handle_)) return false;
     137    11063100 :   is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN || handle_->IsNull(isolate_);
     138             :   return true;
     139             : }
     140             : 
     141             : }  // namespace internal
     142             : }  // namespace v8
     143             : 
     144             : #endif  // V8_PROTOTYPE_INL_H_

Generated by: LCOV version 1.10