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-inl.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/objects/js-generator-inl.h"
13 : #include "src/wasm/wasm-objects-inl.h"
14 :
15 : namespace v8 {
16 :
17 70 : std::unique_ptr<debug::ScopeIterator> debug::ScopeIterator::CreateForFunction(
18 : v8::Isolate* v8_isolate, v8::Local<v8::Function> v8_func) {
19 : internal::Handle<internal::JSReceiver> receiver =
20 : internal::Handle<internal::JSReceiver>::cast(Utils::OpenHandle(*v8_func));
21 :
22 : // Besides JSFunction and JSBoundFunction, {v8_func} could be an
23 : // ObjectTemplate with a CallAsFunctionHandler. We only handle plain
24 : // JSFunctions.
25 70 : if (!receiver->IsJSFunction()) return nullptr;
26 :
27 : internal::Handle<internal::JSFunction> function =
28 : internal::Handle<internal::JSFunction>::cast(receiver);
29 :
30 : // Blink has function objects with callable map, JS_SPECIAL_API_OBJECT_TYPE
31 : // but without context on heap.
32 60 : if (!function->has_context()) return nullptr;
33 : return std::unique_ptr<debug::ScopeIterator>(new internal::DebugScopeIterator(
34 120 : reinterpret_cast<internal::Isolate*>(v8_isolate), function));
35 : }
36 :
37 : std::unique_ptr<debug::ScopeIterator>
38 40 : debug::ScopeIterator::CreateForGeneratorObject(
39 : v8::Isolate* v8_isolate, v8::Local<v8::Object> v8_generator) {
40 : internal::Handle<internal::Object> generator =
41 : Utils::OpenHandle(*v8_generator);
42 : DCHECK(generator->IsJSGeneratorObject());
43 : return std::unique_ptr<debug::ScopeIterator>(new internal::DebugScopeIterator(
44 : reinterpret_cast<internal::Isolate*>(v8_isolate),
45 80 : internal::Handle<internal::JSGeneratorObject>::cast(generator)));
46 : }
47 :
48 : namespace internal {
49 :
50 146947 : DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
51 : FrameInspector* frame_inspector)
52 146947 : : iterator_(isolate, frame_inspector) {
53 146947 : if (!Done() && ShouldIgnore()) Advance();
54 146947 : }
55 :
56 60 : DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
57 : Handle<JSFunction> function)
58 60 : : iterator_(isolate, function) {
59 60 : if (!Done() && ShouldIgnore()) Advance();
60 60 : }
61 :
62 40 : DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
63 : Handle<JSGeneratorObject> generator)
64 40 : : iterator_(isolate, generator) {
65 40 : if (!Done() && ShouldIgnore()) Advance();
66 40 : }
67 :
68 1323884 : bool DebugScopeIterator::Done() { return iterator_.Done(); }
69 :
70 382776 : void DebugScopeIterator::Advance() {
71 : DCHECK(!Done());
72 382776 : iterator_.Next();
73 403830 : while (!Done() && ShouldIgnore()) {
74 10527 : iterator_.Next();
75 : }
76 382776 : }
77 :
78 393554 : bool DebugScopeIterator::ShouldIgnore() {
79 393554 : if (GetType() == debug::ScopeIterator::ScopeTypeLocal) return false;
80 309650 : return !iterator_.DeclaresLocals(i::ScopeIterator::Mode::ALL);
81 : }
82 :
83 372515 : v8::debug::ScopeIterator::ScopeType DebugScopeIterator::GetType() {
84 : DCHECK(!Done());
85 766069 : return static_cast<v8::debug::ScopeIterator::ScopeType>(iterator_.Type());
86 : }
87 :
88 372515 : v8::Local<v8::Object> DebugScopeIterator::GetObject() {
89 : DCHECK(!Done());
90 372515 : Handle<JSObject> value = iterator_.ScopeObject(i::ScopeIterator::Mode::ALL);
91 372515 : return Utils::ToLocal(value);
92 : }
93 :
94 142340 : int DebugScopeIterator::GetScriptId() {
95 : DCHECK(!Done());
96 142340 : return iterator_.GetScript()->id();
97 : }
98 :
99 372515 : v8::Local<v8::Value> DebugScopeIterator::GetFunctionDebugName() {
100 : DCHECK(!Done());
101 372515 : Handle<Object> name = iterator_.GetFunctionDebugName();
102 372515 : return Utils::ToLocal(name);
103 : }
104 :
105 372365 : bool DebugScopeIterator::HasLocationInfo() {
106 372365 : return iterator_.HasPositionInfo();
107 : }
108 :
109 155318 : debug::Location DebugScopeIterator::GetStartLocation() {
110 : DCHECK(!Done());
111 : return ToApiHandle<v8::debug::Script>(iterator_.GetScript())
112 155318 : ->GetSourceLocation(iterator_.start_position());
113 : }
114 :
115 155318 : debug::Location DebugScopeIterator::GetEndLocation() {
116 : DCHECK(!Done());
117 : return ToApiHandle<v8::debug::Script>(iterator_.GetScript())
118 155318 : ->GetSourceLocation(iterator_.end_position());
119 : }
120 :
121 251 : bool DebugScopeIterator::SetVariableValue(v8::Local<v8::String> name,
122 : v8::Local<v8::Value> value) {
123 : DCHECK(!Done());
124 251 : return iterator_.SetVariableValue(Utils::OpenHandle(*name),
125 251 : Utils::OpenHandle(*value));
126 : }
127 :
128 464 : DebugWasmScopeIterator::DebugWasmScopeIterator(Isolate* isolate,
129 : StandardFrame* frame,
130 : int inlined_frame_index)
131 : : isolate_(isolate),
132 : frame_(frame),
133 : inlined_frame_index_(inlined_frame_index),
134 464 : type_(debug::ScopeIterator::ScopeTypeGlobal) {}
135 :
136 1856 : bool DebugWasmScopeIterator::Done() {
137 1856 : return type_ != debug::ScopeIterator::ScopeTypeGlobal &&
138 1856 : type_ != debug::ScopeIterator::ScopeTypeLocal;
139 : }
140 :
141 928 : void DebugWasmScopeIterator::Advance() {
142 : DCHECK(!Done());
143 928 : if (type_ == debug::ScopeIterator::ScopeTypeGlobal) {
144 464 : type_ = debug::ScopeIterator::ScopeTypeLocal;
145 : } else {
146 : // We use ScopeTypeWith type as marker for done.
147 464 : type_ = debug::ScopeIterator::ScopeTypeWith;
148 : }
149 928 : }
150 :
151 928 : v8::debug::ScopeIterator::ScopeType DebugWasmScopeIterator::GetType() {
152 : DCHECK(!Done());
153 928 : return type_;
154 : }
155 :
156 928 : v8::Local<v8::Object> DebugWasmScopeIterator::GetObject() {
157 : DCHECK(!Done());
158 : Handle<WasmDebugInfo> debug_info(
159 928 : WasmInterpreterEntryFrame::cast(frame_)->debug_info(), isolate_);
160 928 : switch (type_) {
161 : case debug::ScopeIterator::ScopeTypeGlobal:
162 : return Utils::ToLocal(WasmDebugInfo::GetGlobalScopeObject(
163 464 : debug_info, frame_->fp(), inlined_frame_index_));
164 : case debug::ScopeIterator::ScopeTypeLocal:
165 : return Utils::ToLocal(WasmDebugInfo::GetLocalScopeObject(
166 464 : debug_info, frame_->fp(), inlined_frame_index_));
167 : default:
168 0 : return v8::Local<v8::Object>();
169 : }
170 : return v8::Local<v8::Object>();
171 : }
172 :
173 464 : int DebugWasmScopeIterator::GetScriptId() {
174 : DCHECK(!Done());
175 464 : return -1;
176 : }
177 :
178 928 : v8::Local<v8::Value> DebugWasmScopeIterator::GetFunctionDebugName() {
179 : DCHECK(!Done());
180 1856 : return Utils::ToLocal(isolate_->factory()->empty_string());
181 : }
182 :
183 928 : bool DebugWasmScopeIterator::HasLocationInfo() { return false; }
184 :
185 0 : debug::Location DebugWasmScopeIterator::GetStartLocation() {
186 : DCHECK(!Done());
187 0 : return debug::Location();
188 : }
189 :
190 0 : debug::Location DebugWasmScopeIterator::GetEndLocation() {
191 : DCHECK(!Done());
192 0 : return debug::Location();
193 : }
194 :
195 0 : bool DebugWasmScopeIterator::SetVariableValue(v8::Local<v8::String> name,
196 : v8::Local<v8::Value> value) {
197 : DCHECK(!Done());
198 0 : return false;
199 : }
200 : } // namespace internal
201 122036 : } // namespace v8
|