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