• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/api-inl.h"
8 #include "src/debug/debug.h"
9 #include "src/debug/liveedit.h"
10 #include "src/execution/frames-inl.h"
11 #include "src/execution/isolate.h"
12 #include "src/objects/js-generator-inl.h"
13 
14 namespace v8 {
15 
CreateForFunction(v8::Isolate * v8_isolate,v8::Local<v8::Function> v8_func)16 std::unique_ptr<debug::ScopeIterator> debug::ScopeIterator::CreateForFunction(
17     v8::Isolate* v8_isolate, v8::Local<v8::Function> v8_func) {
18   internal::Handle<internal::JSReceiver> receiver =
19       internal::Handle<internal::JSReceiver>::cast(Utils::OpenHandle(*v8_func));
20 
21   // Besides JSFunction and JSBoundFunction, {v8_func} could be an
22   // ObjectTemplate with a CallAsFunctionHandler. We only handle plain
23   // JSFunctions.
24   if (!receiver->IsJSFunction()) return nullptr;
25 
26   internal::Handle<internal::JSFunction> function =
27       internal::Handle<internal::JSFunction>::cast(receiver);
28 
29   // Blink has function objects with callable map, JS_SPECIAL_API_OBJECT_TYPE
30   // but without context on heap.
31   if (!function->has_context()) return nullptr;
32   return std::unique_ptr<debug::ScopeIterator>(new internal::DebugScopeIterator(
33       reinterpret_cast<internal::Isolate*>(v8_isolate), function));
34 }
35 
36 std::unique_ptr<debug::ScopeIterator>
CreateForGeneratorObject(v8::Isolate * v8_isolate,v8::Local<v8::Object> v8_generator)37 debug::ScopeIterator::CreateForGeneratorObject(
38     v8::Isolate* v8_isolate, v8::Local<v8::Object> v8_generator) {
39   internal::Handle<internal::Object> generator =
40       Utils::OpenHandle(*v8_generator);
41   DCHECK(generator->IsJSGeneratorObject());
42   return std::unique_ptr<debug::ScopeIterator>(new internal::DebugScopeIterator(
43       reinterpret_cast<internal::Isolate*>(v8_isolate),
44       internal::Handle<internal::JSGeneratorObject>::cast(generator)));
45 }
46 
47 namespace internal {
48 
DebugScopeIterator(Isolate * isolate,FrameInspector * frame_inspector)49 DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
50                                        FrameInspector* frame_inspector)
51     : iterator_(
52           isolate, frame_inspector,
53           ::v8::internal::ScopeIterator::ReparseStrategy::kFunctionLiteral) {
54   if (!Done() && ShouldIgnore()) Advance();
55 }
56 
DebugScopeIterator(Isolate * isolate,Handle<JSFunction> function)57 DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
58                                        Handle<JSFunction> function)
59     : iterator_(isolate, function) {
60   if (!Done() && ShouldIgnore()) Advance();
61 }
62 
DebugScopeIterator(Isolate * isolate,Handle<JSGeneratorObject> generator)63 DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
64                                        Handle<JSGeneratorObject> generator)
65     : iterator_(isolate, generator) {
66   if (!Done() && ShouldIgnore()) Advance();
67 }
68 
Done()69 bool DebugScopeIterator::Done() { return iterator_.Done(); }
70 
Advance()71 void DebugScopeIterator::Advance() {
72   DCHECK(!Done());
73   iterator_.Next();
74   while (!Done() && ShouldIgnore()) {
75     iterator_.Next();
76   }
77 }
78 
ShouldIgnore()79 bool DebugScopeIterator::ShouldIgnore() {
80   if (GetType() == debug::ScopeIterator::ScopeTypeLocal) return false;
81   return !iterator_.DeclaresLocals(i::ScopeIterator::Mode::ALL);
82 }
83 
GetType()84 v8::debug::ScopeIterator::ScopeType DebugScopeIterator::GetType() {
85   DCHECK(!Done());
86   return static_cast<v8::debug::ScopeIterator::ScopeType>(iterator_.Type());
87 }
88 
GetObject()89 v8::Local<v8::Object> DebugScopeIterator::GetObject() {
90   DCHECK(!Done());
91   Handle<JSObject> value = iterator_.ScopeObject(i::ScopeIterator::Mode::ALL);
92   return Utils::ToLocal(value);
93 }
94 
GetScriptId()95 int DebugScopeIterator::GetScriptId() {
96   DCHECK(!Done());
97   return iterator_.GetScript()->id();
98 }
99 
GetFunctionDebugName()100 v8::Local<v8::Value> DebugScopeIterator::GetFunctionDebugName() {
101   DCHECK(!Done());
102   Handle<Object> name = iterator_.GetFunctionDebugName();
103   return Utils::ToLocal(name);
104 }
105 
HasLocationInfo()106 bool DebugScopeIterator::HasLocationInfo() {
107   return iterator_.HasPositionInfo();
108 }
109 
GetStartLocation()110 debug::Location DebugScopeIterator::GetStartLocation() {
111   DCHECK(!Done());
112   return ToApiHandle<v8::debug::Script>(iterator_.GetScript())
113       ->GetSourceLocation(iterator_.start_position());
114 }
115 
GetEndLocation()116 debug::Location DebugScopeIterator::GetEndLocation() {
117   DCHECK(!Done());
118   return ToApiHandle<v8::debug::Script>(iterator_.GetScript())
119       ->GetSourceLocation(iterator_.end_position());
120 }
121 
SetVariableValue(v8::Local<v8::String> name,v8::Local<v8::Value> value)122 bool DebugScopeIterator::SetVariableValue(v8::Local<v8::String> name,
123                                           v8::Local<v8::Value> value) {
124   DCHECK(!Done());
125   return iterator_.SetVariableValue(Utils::OpenHandle(*name),
126                                     Utils::OpenHandle(*value));
127 }
128 
129 }  // namespace internal
130 }  // namespace v8
131