LCOV - code coverage report
Current view: top level - src/debug - debug-scope-iterator.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 68 76 89.5 %
Date: 2017-10-20 Functions: 20 23 87.0 %

          Line data    Source code
       1             : // Copyright 2017 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/debug/debug-scope-iterator.h"
       6             : 
       7             : #include "src/api.h"
       8             : #include "src/debug/debug.h"
       9             : #include "src/debug/liveedit.h"
      10             : #include "src/frames-inl.h"
      11             : #include "src/isolate.h"
      12             : #include "src/wasm/wasm-objects-inl.h"
      13             : 
      14             : namespace v8 {
      15             : 
      16          25 : std::unique_ptr<debug::ScopeIterator> debug::ScopeIterator::CreateForFunction(
      17             :     v8::Isolate* v8_isolate, v8::Local<v8::Function> v8_func) {
      18             :   internal::Handle<internal::JSFunction> func =
      19             :       internal::Handle<internal::JSFunction>::cast(Utils::OpenHandle(*v8_func));
      20             :   // Blink has function objects with callable map, JS_SPECIAL_API_OBJECT_TYPE
      21             :   // but without context on heap.
      22          25 :   if (!func->has_context()) return nullptr;
      23             :   return std::unique_ptr<debug::ScopeIterator>(new internal::DebugScopeIterator(
      24          50 :       reinterpret_cast<internal::Isolate*>(v8_isolate), func));
      25             : }
      26             : 
      27             : std::unique_ptr<debug::ScopeIterator>
      28          35 : debug::ScopeIterator::CreateForGeneratorObject(
      29             :     v8::Isolate* v8_isolate, v8::Local<v8::Object> v8_generator) {
      30             :   internal::Handle<internal::Object> generator =
      31             :       Utils::OpenHandle(*v8_generator);
      32             :   DCHECK(generator->IsJSGeneratorObject());
      33             :   return std::unique_ptr<debug::ScopeIterator>(new internal::DebugScopeIterator(
      34             :       reinterpret_cast<internal::Isolate*>(v8_isolate),
      35          70 :       internal::Handle<internal::JSGeneratorObject>::cast(generator)));
      36             : }
      37             : 
      38             : namespace internal {
      39             : 
      40      125102 : DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
      41             :                                        FrameInspector* frame_inspector)
      42      125102 :     : iterator_(isolate, frame_inspector) {
      43      125102 :   if (!Done() && ShouldIgnore()) Advance();
      44      125102 : }
      45             : 
      46          25 : DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
      47             :                                        Handle<JSFunction> function)
      48          25 :     : iterator_(isolate, function) {
      49          25 :   if (!Done() && ShouldIgnore()) Advance();
      50          25 : }
      51             : 
      52          35 : DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
      53             :                                        Handle<JSGeneratorObject> generator)
      54          35 :     : iterator_(isolate, generator) {
      55          35 :   if (!Done() && ShouldIgnore()) Advance();
      56          35 : }
      57             : 
      58      902318 : bool DebugScopeIterator::Done() { return iterator_.Done(); }
      59             : 
      60      333412 : void DebugScopeIterator::Advance() {
      61             :   DCHECK(!Done());
      62      333412 :   iterator_.Next();
      63      674021 :   while (!Done() && ShouldIgnore()) {
      64        7197 :     iterator_.Next();
      65             :   }
      66      333412 : }
      67             : 
      68      340894 : bool DebugScopeIterator::ShouldIgnore() {
      69             :   // Almost always Script scope will be empty, so just filter out that noise.
      70             :   // Also drop empty Block, Eval and Script scopes, should we get any.
      71             :   DCHECK(!Done());
      72             :   debug::ScopeIterator::ScopeType type = GetType();
      73      340894 :   if (type != debug::ScopeIterator::ScopeTypeBlock &&
      74             :       type != debug::ScopeIterator::ScopeTypeScript &&
      75      340894 :       type != debug::ScopeIterator::ScopeTypeEval &&
      76             :       type != debug::ScopeIterator::ScopeTypeModule) {
      77             :     return false;
      78             :   }
      79             : 
      80             :   // TODO(kozyatinskiy): make this function faster.
      81             :   Handle<JSObject> value;
      82      263462 :   if (!iterator_.ScopeObject().ToHandle(&value)) return false;
      83             :   Handle<FixedArray> keys =
      84             :       KeyAccumulator::GetKeys(value, KeyCollectionMode::kOwnOnly,
      85             :                               ENUMERABLE_STRINGS,
      86      131731 :                               GetKeysConversion::kConvertToString)
      87      263462 :           .ToHandleChecked();
      88      131731 :   return keys->length() == 0;
      89             : }
      90             : 
      91      325976 : v8::debug::ScopeIterator::ScopeType DebugScopeIterator::GetType() {
      92             :   DCHECK(!Done());
      93      666870 :   return static_cast<v8::debug::ScopeIterator::ScopeType>(iterator_.Type());
      94             : }
      95             : 
      96      326045 : v8::Local<v8::Object> DebugScopeIterator::GetObject() {
      97             :   DCHECK(!Done());
      98             :   Handle<JSObject> value;
      99      652090 :   if (iterator_.ScopeObject().ToHandle(&value)) {
     100             :     return Utils::ToLocal(value);
     101             :   }
     102           0 :   return v8::Local<v8::Object>();
     103             : }
     104             : 
     105      325976 : v8::Local<v8::Function> DebugScopeIterator::GetFunction() {
     106             :   DCHECK(!Done());
     107      325976 :   Handle<JSFunction> closure = iterator_.GetClosure();
     108      325976 :   if (closure.is_null()) return v8::Local<v8::Function>();
     109             :   return Utils::ToLocal(closure);
     110             : }
     111             : 
     112       88213 : debug::Location DebugScopeIterator::GetStartLocation() {
     113             :   DCHECK(!Done());
     114       88213 :   Handle<JSFunction> closure = iterator_.GetClosure();
     115       88213 :   if (closure.is_null()) return debug::Location();
     116             :   Object* obj = closure->shared()->script();
     117       88213 :   if (!obj->IsScript()) return debug::Location();
     118             :   return ToApiHandle<v8::debug::Script>(handle(Script::cast(obj)))
     119      176426 :       ->GetSourceLocation(iterator_.start_position());
     120             : }
     121             : 
     122       88213 : debug::Location DebugScopeIterator::GetEndLocation() {
     123             :   DCHECK(!Done());
     124       88213 :   Handle<JSFunction> closure = iterator_.GetClosure();
     125       88213 :   if (closure.is_null()) return debug::Location();
     126             :   Object* obj = closure->shared()->script();
     127       88213 :   if (!obj->IsScript()) return debug::Location();
     128             :   return ToApiHandle<v8::debug::Script>(handle(Script::cast(obj)))
     129      176426 :       ->GetSourceLocation(iterator_.end_position());
     130             : }
     131             : 
     132         216 : bool DebugScopeIterator::SetVariableValue(v8::Local<v8::String> name,
     133             :                                           v8::Local<v8::Value> value) {
     134             :   DCHECK(!Done());
     135             :   return iterator_.SetVariableValue(Utils::OpenHandle(*name),
     136         216 :                                     Utils::OpenHandle(*value));
     137             : }
     138             : 
     139         285 : DebugWasmScopeIterator::DebugWasmScopeIterator(Isolate* isolate,
     140             :                                                StandardFrame* frame,
     141             :                                                int inlined_frame_index)
     142             :     : isolate_(isolate),
     143             :       frame_(frame),
     144             :       inlined_frame_index_(inlined_frame_index),
     145         285 :       type_(debug::ScopeIterator::ScopeTypeGlobal) {}
     146             : 
     147         855 : bool DebugWasmScopeIterator::Done() {
     148         855 :   return type_ != debug::ScopeIterator::ScopeTypeGlobal &&
     149         855 :          type_ != debug::ScopeIterator::ScopeTypeLocal;
     150             : }
     151             : 
     152         570 : void DebugWasmScopeIterator::Advance() {
     153             :   DCHECK(!Done());
     154         570 :   if (type_ == debug::ScopeIterator::ScopeTypeGlobal) {
     155         285 :     type_ = debug::ScopeIterator::ScopeTypeLocal;
     156             :   } else {
     157             :     // We use ScopeTypeWith type as marker for done.
     158         285 :     type_ = debug::ScopeIterator::ScopeTypeWith;
     159             :   }
     160         570 : }
     161             : 
     162         570 : v8::debug::ScopeIterator::ScopeType DebugWasmScopeIterator::GetType() {
     163             :   DCHECK(!Done());
     164         570 :   return type_;
     165             : }
     166             : 
     167         570 : v8::Local<v8::Object> DebugWasmScopeIterator::GetObject() {
     168             :   DCHECK(!Done());
     169             :   Handle<WasmDebugInfo> debug_info(
     170             :       WasmInterpreterEntryFrame::cast(frame_)->wasm_instance()->debug_info(),
     171         570 :       isolate_);
     172         570 :   switch (type_) {
     173             :     case debug::ScopeIterator::ScopeTypeGlobal:
     174             :       return Utils::ToLocal(WasmDebugInfo::GetGlobalScopeObject(
     175         570 :           debug_info, frame_->fp(), inlined_frame_index_));
     176             :     case debug::ScopeIterator::ScopeTypeLocal:
     177             :       return Utils::ToLocal(WasmDebugInfo::GetLocalScopeObject(
     178         570 :           debug_info, frame_->fp(), inlined_frame_index_));
     179             :     default:
     180           0 :       return v8::Local<v8::Object>();
     181             :   }
     182             :   return v8::Local<v8::Object>();
     183             : }
     184             : 
     185         570 : v8::Local<v8::Function> DebugWasmScopeIterator::GetFunction() {
     186             :   DCHECK(!Done());
     187         570 :   return v8::Local<v8::Function>();
     188             : }
     189             : 
     190           0 : debug::Location DebugWasmScopeIterator::GetStartLocation() {
     191             :   DCHECK(!Done());
     192           0 :   return debug::Location();
     193             : }
     194             : 
     195           0 : debug::Location DebugWasmScopeIterator::GetEndLocation() {
     196             :   DCHECK(!Done());
     197           0 :   return debug::Location();
     198             : }
     199             : 
     200           0 : bool DebugWasmScopeIterator::SetVariableValue(v8::Local<v8::String> name,
     201             :                                               v8::Local<v8::Value> value) {
     202             :   DCHECK(!Done());
     203           0 :   return false;
     204             : }
     205             : }  // namespace internal
     206             : }  // namespace v8

Generated by: LCOV version 1.10