Skip to content

Commit ebd070e

Browse files
alexkozyCommit Bot
authored andcommitted
reland: inspector: move injected script source to native
- introduced ValueMirror interface, this interface contains methods to generate different protocol entities, - introduced DebugPropertyIterator, this iterator iterates through object properties in the following order: exotic indices, enumerable strings, all other properties, - removed all injected script infra, e.g. closure compiler, R=dgozman@chromium.org TBR=yangguo@chromium.org Bug: chromium:595206 Change-Id: I030fdb3a80074ca6edd4749f86b39b590776ae6f Reviewed-on: https://chromium-review.googlesource.com/c/1310056 Reviewed-by: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org> Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org> Cr-Commit-Position: refs/heads/master@{#57181}
1 parent 6dcbd4f commit ebd070e

57 files changed

Lines changed: 2644 additions & 3655 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎BUILD.gn‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,6 +1937,8 @@ v8_source_set("v8_base") {
19371937
"src/debug/debug-frames.cc",
19381938
"src/debug/debug-frames.h",
19391939
"src/debug/debug-interface.h",
1940+
"src/debug/debug-property-iterator.cc",
1941+
"src/debug/debug-property-iterator.h",
19401942
"src/debug/debug-scope-iterator.cc",
19411943
"src/debug/debug-scope-iterator.h",
19421944
"src/debug/debug-scopes.cc",

‎DEPS‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,17 +245,6 @@ hooks = [
245245
'-s', 'v8/test/wasm-spec-tests/tests.tar.gz.sha1',
246246
],
247247
},
248-
{
249-
'name': 'closure_compiler',
250-
'pattern': '.',
251-
'action': [ 'download_from_google_storage',
252-
'--no_resume',
253-
'--no_auth',
254-
'-u',
255-
'--bucket', 'chromium-v8-closure-compiler',
256-
'-s', 'v8/src/inspector/build/closure-compiler.tar.gz.sha1',
257-
],
258-
},
259248
{
260249
'name': 'sysroot_arm',
261250
'pattern': '.',

‎src/api.cc‎

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9548,31 +9548,20 @@ Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
95489548
i::HandleScope handle_scope(isolate);
95499549
i::Builtins::Name builtin_id;
95509550
switch (builtin) {
9551-
case kObjectKeys:
9552-
builtin_id = i::Builtins::kObjectKeys;
9553-
break;
9554-
case kObjectGetPrototypeOf:
9555-
builtin_id = i::Builtins::kObjectGetPrototypeOf;
9556-
break;
9557-
case kObjectGetOwnPropertyDescriptor:
9558-
builtin_id = i::Builtins::kObjectGetOwnPropertyDescriptor;
9559-
break;
9560-
case kObjectGetOwnPropertyNames:
9561-
builtin_id = i::Builtins::kObjectGetOwnPropertyNames;
9562-
break;
9563-
case kObjectGetOwnPropertySymbols:
9564-
builtin_id = i::Builtins::kObjectGetOwnPropertySymbols;
9551+
case kStringToLowerCase:
9552+
builtin_id = i::Builtins::kStringPrototypeToLocaleLowerCase;
95659553
break;
95669554
default:
95679555
UNREACHABLE();
95689556
}
95699557

95709558
i::Handle<i::String> name = isolate->factory()->empty_string();
95719559
i::NewFunctionArgs args = i::NewFunctionArgs::ForBuiltinWithoutPrototype(
9572-
name, builtin_id, i::LanguageMode::kSloppy);
9560+
name, builtin_id, i::LanguageMode::kStrict);
95739561
i::Handle<i::JSFunction> fun = isolate->factory()->NewFunction(args);
95749562

9575-
fun->shared()->DontAdaptArguments();
9563+
fun->shared()->set_internal_formal_parameter_count(0);
9564+
fun->shared()->set_length(0);
95769565
return Utils::ToLocal(handle_scope.CloseAndEscape(fun));
95779566
}
95789567

@@ -9697,41 +9686,6 @@ void debug::SetReturnValue(v8::Isolate* v8_isolate,
96979686
isolate->debug()->set_return_value(*Utils::OpenHandle(*value));
96989687
}
96999688

9700-
int debug::GetNativeAccessorDescriptor(v8::Local<v8::Context> context,
9701-
v8::Local<v8::Object> v8_object,
9702-
v8::Local<v8::Name> v8_name) {
9703-
i::Handle<i::JSReceiver> object = Utils::OpenHandle(*v8_object);
9704-
i::Handle<i::Name> name = Utils::OpenHandle(*v8_name);
9705-
uint32_t index;
9706-
if (name->AsArrayIndex(&index)) {
9707-
return static_cast<int>(debug::NativeAccessorType::None);
9708-
}
9709-
i::LookupIterator it = i::LookupIterator(object->GetIsolate(), object, name,
9710-
i::LookupIterator::OWN);
9711-
if (!it.IsFound()) return static_cast<int>(debug::NativeAccessorType::None);
9712-
if (it.state() != i::LookupIterator::ACCESSOR) {
9713-
return static_cast<int>(debug::NativeAccessorType::None);
9714-
}
9715-
i::Handle<i::Object> structure = it.GetAccessors();
9716-
if (!structure->IsAccessorInfo()) {
9717-
return static_cast<int>(debug::NativeAccessorType::None);
9718-
}
9719-
auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
9720-
int result = 0;
9721-
#define IS_BUILTIN_ACESSOR(_, name, ...) \
9722-
if (*structure == *isolate->factory()->name##_accessor()) \
9723-
result |= static_cast<int>(debug::NativeAccessorType::IsBuiltin);
9724-
ACCESSOR_INFO_LIST_GENERATOR(IS_BUILTIN_ACESSOR, /* not used */)
9725-
#undef IS_BUILTIN_ACESSOR
9726-
i::Handle<i::AccessorInfo> accessor_info =
9727-
i::Handle<i::AccessorInfo>::cast(structure);
9728-
if (accessor_info->getter())
9729-
result |= static_cast<int>(debug::NativeAccessorType::HasGetter);
9730-
if (accessor_info->setter())
9731-
result |= static_cast<int>(debug::NativeAccessorType::HasSetter);
9732-
return result;
9733-
}
9734-
97359689
int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) {
97369690
return reinterpret_cast<i::Isolate*>(v8_isolate)
97379691
->random_number_generator()

‎src/debug/debug-interface.h‎

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,7 @@ void ResetBlackboxedStateCache(Isolate* isolate,
193193

194194
int EstimatedValueSize(Isolate* isolate, v8::Local<v8::Value> value);
195195

196-
enum Builtin {
197-
kObjectKeys,
198-
kObjectGetPrototypeOf,
199-
kObjectGetOwnPropertyDescriptor,
200-
kObjectGetOwnPropertyNames,
201-
kObjectGetOwnPropertySymbols,
202-
};
196+
enum Builtin { kStringToLowerCase };
203197

204198
Local<Function> GetBuiltin(Isolate* isolate, Builtin builtin);
205199

@@ -474,14 +468,9 @@ void SetReturnValue(v8::Isolate* isolate, v8::Local<v8::Value> value);
474468
enum class NativeAccessorType {
475469
None = 0,
476470
HasGetter = 1 << 0,
477-
HasSetter = 1 << 1,
478-
IsBuiltin = 1 << 2
471+
HasSetter = 1 << 1
479472
};
480473

481-
int GetNativeAccessorDescriptor(v8::Local<v8::Context> context,
482-
v8::Local<v8::Object> object,
483-
v8::Local<v8::Name> name);
484-
485474
int64_t GetNextRandomInt64(v8::Isolate* isolate);
486475

487476
v8::MaybeLocal<v8::Value> EvaluateGlobal(v8::Isolate* isolate,
@@ -518,6 +507,39 @@ class WeakMap : public v8::Object {
518507
private:
519508
WeakMap();
520509
};
510+
511+
struct PropertyDescriptor {
512+
bool enumerable : 1;
513+
bool has_enumerable : 1;
514+
bool configurable : 1;
515+
bool has_configurable : 1;
516+
bool writable : 1;
517+
bool has_writable : 1;
518+
v8::Local<v8::Value> value;
519+
v8::Local<v8::Value> get;
520+
v8::Local<v8::Value> set;
521+
};
522+
523+
class PropertyIterator {
524+
public:
525+
static std::unique_ptr<PropertyIterator> Create(v8::Local<v8::Object> object);
526+
527+
virtual ~PropertyIterator() = default;
528+
529+
virtual bool Done() const = 0;
530+
virtual void Advance() = 0;
531+
532+
virtual v8::Local<v8::Name> name() const = 0;
533+
534+
virtual bool is_native_accessor() = 0;
535+
virtual bool has_native_getter() = 0;
536+
virtual bool has_native_setter() = 0;
537+
virtual Maybe<PropertyAttribute> attributes() = 0;
538+
virtual Maybe<PropertyDescriptor> descriptor() = 0;
539+
540+
virtual bool is_own() = 0;
541+
virtual bool is_array_index() = 0;
542+
};
521543
} // namespace debug
522544
} // namespace v8
523545

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
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+
#include "src/debug/debug-property-iterator.h"
6+
7+
#include "src/api-inl.h"
8+
#include "src/base/flags.h"
9+
#include "src/keys.h"
10+
#include "src/objects/js-array-buffer-inl.h"
11+
#include "src/property-descriptor.h"
12+
#include "src/property-details.h"
13+
14+
namespace v8 {
15+
16+
std::unique_ptr<debug::PropertyIterator> debug::PropertyIterator::Create(
17+
v8::Local<v8::Object> v8_object) {
18+
internal::Isolate* isolate =
19+
reinterpret_cast<internal::Isolate*>(v8_object->GetIsolate());
20+
return std::unique_ptr<debug::PropertyIterator>(
21+
new internal::DebugPropertyIterator(isolate,
22+
Utils::OpenHandle(*v8_object)));
23+
}
24+
25+
namespace internal {
26+
27+
DebugPropertyIterator::DebugPropertyIterator(Isolate* isolate,
28+
Handle<JSReceiver> receiver)
29+
: isolate_(isolate),
30+
prototype_iterator_(isolate, receiver, kStartAtReceiver,
31+
PrototypeIterator::END_AT_NULL) {
32+
if (receiver->IsJSProxy()) {
33+
is_own_ = false;
34+
prototype_iterator_.AdvanceIgnoringProxies();
35+
}
36+
if (prototype_iterator_.IsAtEnd()) return;
37+
FillKeysForCurrentPrototypeAndStage();
38+
if (should_move_to_next_stage()) Advance();
39+
}
40+
41+
bool DebugPropertyIterator::Done() const {
42+
return prototype_iterator_.IsAtEnd();
43+
}
44+
45+
void DebugPropertyIterator::Advance() {
46+
++current_key_index_;
47+
calculated_native_accessor_flags_ = false;
48+
while (should_move_to_next_stage()) {
49+
switch (stage_) {
50+
case Stage::kExoticIndices:
51+
stage_ = Stage::kEnumerableStrings;
52+
break;
53+
case Stage::kEnumerableStrings:
54+
stage_ = Stage::kAllProperties;
55+
break;
56+
case Stage::kAllProperties:
57+
stage_ = kExoticIndices;
58+
is_own_ = false;
59+
prototype_iterator_.AdvanceIgnoringProxies();
60+
break;
61+
}
62+
FillKeysForCurrentPrototypeAndStage();
63+
}
64+
}
65+
66+
bool DebugPropertyIterator::is_native_accessor() {
67+
if (stage_ == kExoticIndices) return false;
68+
CalculateNativeAccessorFlags();
69+
return native_accessor_flags_;
70+
}
71+
72+
bool DebugPropertyIterator::has_native_getter() {
73+
if (stage_ == kExoticIndices) return false;
74+
CalculateNativeAccessorFlags();
75+
return native_accessor_flags_ &
76+
static_cast<int>(debug::NativeAccessorType::HasGetter);
77+
}
78+
79+
bool DebugPropertyIterator::has_native_setter() {
80+
if (stage_ == kExoticIndices) return false;
81+
CalculateNativeAccessorFlags();
82+
return native_accessor_flags_ &
83+
static_cast<int>(debug::NativeAccessorType::HasSetter);
84+
}
85+
86+
Handle<Name> DebugPropertyIterator::raw_name() const {
87+
DCHECK(!Done());
88+
if (stage_ == kExoticIndices) {
89+
return isolate_->factory()->Uint32ToString(current_key_index_);
90+
} else {
91+
return Handle<Name>::cast(
92+
FixedArray::get(*keys_, current_key_index_, isolate_));
93+
}
94+
}
95+
96+
v8::Local<v8::Name> DebugPropertyIterator::name() const {
97+
return Utils::ToLocal(raw_name());
98+
}
99+
100+
v8::Maybe<v8::PropertyAttribute> DebugPropertyIterator::attributes() {
101+
Handle<JSReceiver> receiver =
102+
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
103+
auto result = JSReceiver::GetPropertyAttributes(receiver, raw_name());
104+
if (result.IsNothing()) return Nothing<v8::PropertyAttribute>();
105+
DCHECK(result.FromJust() != ABSENT);
106+
return Just(static_cast<v8::PropertyAttribute>(result.FromJust()));
107+
}
108+
109+
v8::Maybe<v8::debug::PropertyDescriptor> DebugPropertyIterator::descriptor() {
110+
Handle<JSReceiver> receiver =
111+
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
112+
113+
PropertyDescriptor descriptor;
114+
Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
115+
isolate_, receiver, raw_name(), &descriptor);
116+
if (did_get_descriptor.IsNothing()) {
117+
return Nothing<v8::debug::PropertyDescriptor>();
118+
}
119+
DCHECK(did_get_descriptor.FromJust());
120+
return Just(v8::debug::PropertyDescriptor{
121+
descriptor.enumerable(), descriptor.has_enumerable(),
122+
descriptor.configurable(), descriptor.has_configurable(),
123+
descriptor.writable(), descriptor.has_writable(),
124+
descriptor.has_value() ? Utils::ToLocal(descriptor.value())
125+
: v8::Local<v8::Value>(),
126+
descriptor.has_get() ? Utils::ToLocal(descriptor.get())
127+
: v8::Local<v8::Value>(),
128+
descriptor.has_set() ? Utils::ToLocal(descriptor.set())
129+
: v8::Local<v8::Value>(),
130+
});
131+
}
132+
133+
bool DebugPropertyIterator::is_own() { return is_own_; }
134+
135+
bool DebugPropertyIterator::is_array_index() {
136+
if (stage_ == kExoticIndices) return true;
137+
uint32_t index = 0;
138+
return raw_name()->AsArrayIndex(&index);
139+
}
140+
141+
void DebugPropertyIterator::FillKeysForCurrentPrototypeAndStage() {
142+
current_key_index_ = 0;
143+
exotic_length_ = 0;
144+
keys_ = Handle<FixedArray>::null();
145+
if (prototype_iterator_.IsAtEnd()) return;
146+
Handle<JSReceiver> receiver =
147+
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
148+
bool has_exotic_indices = receiver->IsJSTypedArray();
149+
if (stage_ == kExoticIndices) {
150+
if (!has_exotic_indices) return;
151+
exotic_length_ = static_cast<uint32_t>(
152+
Handle<JSTypedArray>::cast(receiver)->length_value());
153+
return;
154+
}
155+
bool skip_indices = has_exotic_indices;
156+
PropertyFilter filter =
157+
stage_ == kEnumerableStrings ? ENUMERABLE_STRINGS : ALL_PROPERTIES;
158+
if (!KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter,
159+
GetKeysConversion::kConvertToString, false,
160+
skip_indices)
161+
.ToHandle(&keys_)) {
162+
keys_ = Handle<FixedArray>::null();
163+
}
164+
}
165+
166+
bool DebugPropertyIterator::should_move_to_next_stage() const {
167+
if (prototype_iterator_.IsAtEnd()) return false;
168+
if (stage_ == kExoticIndices) return current_key_index_ >= exotic_length_;
169+
return keys_.is_null() ||
170+
current_key_index_ >= static_cast<uint32_t>(keys_->length());
171+
}
172+
173+
namespace {
174+
base::Flags<debug::NativeAccessorType, int> GetNativeAccessorDescriptorInternal(
175+
Handle<JSReceiver> object, Handle<Name> name) {
176+
uint32_t index;
177+
if (name->AsArrayIndex(&index)) return debug::NativeAccessorType::None;
178+
LookupIterator it =
179+
LookupIterator(object->GetIsolate(), object, name, LookupIterator::OWN);
180+
if (!it.IsFound()) return debug::NativeAccessorType::None;
181+
if (it.state() != LookupIterator::ACCESSOR) {
182+
return debug::NativeAccessorType::None;
183+
}
184+
Handle<Object> structure = it.GetAccessors();
185+
if (!structure->IsAccessorInfo()) return debug::NativeAccessorType::None;
186+
auto isolate = object->GetIsolate();
187+
base::Flags<debug::NativeAccessorType, int> result;
188+
#define IS_BUILTIN_ACESSOR(_, name, ...) \
189+
if (*structure == *isolate->factory()->name##_accessor()) \
190+
return debug::NativeAccessorType::None;
191+
ACCESSOR_INFO_LIST_GENERATOR(IS_BUILTIN_ACESSOR, /* not used */)
192+
#undef IS_BUILTIN_ACESSOR
193+
Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
194+
if (accessor_info->getter()) {
195+
result |= debug::NativeAccessorType::HasGetter;
196+
}
197+
if (accessor_info->setter()) {
198+
result |= debug::NativeAccessorType::HasSetter;
199+
}
200+
return result;
201+
}
202+
} // anonymous namespace
203+
204+
void DebugPropertyIterator::CalculateNativeAccessorFlags() {
205+
if (calculated_native_accessor_flags_) return;
206+
Handle<JSReceiver> receiver =
207+
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
208+
native_accessor_flags_ =
209+
GetNativeAccessorDescriptorInternal(receiver, raw_name());
210+
calculated_native_accessor_flags_ = true;
211+
}
212+
} // namespace internal
213+
} // namespace v8

0 commit comments

Comments
 (0)