Commit 7e079c66 authored by Alexey Kozyatinskiy's avatar Alexey Kozyatinskiy Committed by Commit Bot

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: Idcfc04489ee52e015ad1d1d191c3474cc65e63f2
Reviewed-on: https://chromium-review.googlesource.com/c/1308353Reviewed-by: 's avatarAleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57150}
parent 2995df7d
......@@ -1937,6 +1937,8 @@ v8_source_set("v8_base") {
"src/debug/debug-frames.cc",
"src/debug/debug-frames.h",
"src/debug/debug-interface.h",
"src/debug/debug-property-iterator.cc",
"src/debug/debug-property-iterator.h",
"src/debug/debug-scope-iterator.cc",
"src/debug/debug-scope-iterator.h",
"src/debug/debug-scopes.cc",
......
......@@ -245,17 +245,6 @@ hooks = [
'-s', 'v8/test/wasm-spec-tests/tests.tar.gz.sha1',
],
},
{
'name': 'closure_compiler',
'pattern': '.',
'action': [ 'download_from_google_storage',
'--no_resume',
'--no_auth',
'-u',
'--bucket', 'chromium-v8-closure-compiler',
'-s', 'v8/src/inspector/build/closure-compiler.tar.gz.sha1',
],
},
{
'name': 'sysroot_arm',
'pattern': '.',
......
......@@ -9556,20 +9556,8 @@ Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
i::HandleScope handle_scope(isolate);
i::Builtins::Name builtin_id;
switch (builtin) {
case kObjectKeys:
builtin_id = i::Builtins::kObjectKeys;
break;
case kObjectGetPrototypeOf:
builtin_id = i::Builtins::kObjectGetPrototypeOf;
break;
case kObjectGetOwnPropertyDescriptor:
builtin_id = i::Builtins::kObjectGetOwnPropertyDescriptor;
break;
case kObjectGetOwnPropertyNames:
builtin_id = i::Builtins::kObjectGetOwnPropertyNames;
break;
case kObjectGetOwnPropertySymbols:
builtin_id = i::Builtins::kObjectGetOwnPropertySymbols;
case kStringToLowerCase:
builtin_id = i::Builtins::kStringPrototypeToLocaleLowerCase;
break;
default:
UNREACHABLE();
......@@ -9577,10 +9565,11 @@ Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
i::Handle<i::String> name = isolate->factory()->empty_string();
i::NewFunctionArgs args = i::NewFunctionArgs::ForBuiltinWithoutPrototype(
name, builtin_id, i::LanguageMode::kSloppy);
name, builtin_id, i::LanguageMode::kStrict);
i::Handle<i::JSFunction> fun = isolate->factory()->NewFunction(args);
fun->shared()->DontAdaptArguments();
fun->shared()->set_internal_formal_parameter_count(0);
fun->shared()->set_length(0);
return Utils::ToLocal(handle_scope.CloseAndEscape(fun));
}
......@@ -9705,41 +9694,6 @@ void debug::SetReturnValue(v8::Isolate* v8_isolate,
isolate->debug()->set_return_value(*Utils::OpenHandle(*value));
}
int debug::GetNativeAccessorDescriptor(v8::Local<v8::Context> context,
v8::Local<v8::Object> v8_object,
v8::Local<v8::Name> v8_name) {
i::Handle<i::JSReceiver> object = Utils::OpenHandle(*v8_object);
i::Handle<i::Name> name = Utils::OpenHandle(*v8_name);
uint32_t index;
if (name->AsArrayIndex(&index)) {
return static_cast<int>(debug::NativeAccessorType::None);
}
i::LookupIterator it = i::LookupIterator(object->GetIsolate(), object, name,
i::LookupIterator::OWN);
if (!it.IsFound()) return static_cast<int>(debug::NativeAccessorType::None);
if (it.state() != i::LookupIterator::ACCESSOR) {
return static_cast<int>(debug::NativeAccessorType::None);
}
i::Handle<i::Object> structure = it.GetAccessors();
if (!structure->IsAccessorInfo()) {
return static_cast<int>(debug::NativeAccessorType::None);
}
auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
int result = 0;
#define IS_BUILTIN_ACESSOR(_, name, ...) \
if (*structure == *isolate->factory()->name##_accessor()) \
result |= static_cast<int>(debug::NativeAccessorType::IsBuiltin);
ACCESSOR_INFO_LIST_GENERATOR(IS_BUILTIN_ACESSOR, /* not used */)
#undef IS_BUILTIN_ACESSOR
i::Handle<i::AccessorInfo> accessor_info =
i::Handle<i::AccessorInfo>::cast(structure);
if (accessor_info->getter())
result |= static_cast<int>(debug::NativeAccessorType::HasGetter);
if (accessor_info->setter())
result |= static_cast<int>(debug::NativeAccessorType::HasSetter);
return result;
}
int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) {
return reinterpret_cast<i::Isolate*>(v8_isolate)
->random_number_generator()
......
......@@ -193,13 +193,7 @@ void ResetBlackboxedStateCache(Isolate* isolate,
int EstimatedValueSize(Isolate* isolate, v8::Local<v8::Value> value);
enum Builtin {
kObjectKeys,
kObjectGetPrototypeOf,
kObjectGetOwnPropertyDescriptor,
kObjectGetOwnPropertyNames,
kObjectGetOwnPropertySymbols,
};
enum Builtin { kStringToLowerCase };
Local<Function> GetBuiltin(Isolate* isolate, Builtin builtin);
......@@ -474,14 +468,9 @@ void SetReturnValue(v8::Isolate* isolate, v8::Local<v8::Value> value);
enum class NativeAccessorType {
None = 0,
HasGetter = 1 << 0,
HasSetter = 1 << 1,
IsBuiltin = 1 << 2
HasSetter = 1 << 1
};
int GetNativeAccessorDescriptor(v8::Local<v8::Context> context,
v8::Local<v8::Object> object,
v8::Local<v8::Name> name);
int64_t GetNextRandomInt64(v8::Isolate* isolate);
v8::MaybeLocal<v8::Value> EvaluateGlobal(v8::Isolate* isolate,
......@@ -518,6 +507,39 @@ class WeakMap : public v8::Object {
private:
WeakMap();
};
struct PropertyDescriptor {
bool enumerable : 1;
bool has_enumerable : 1;
bool configurable : 1;
bool has_configurable : 1;
bool writable : 1;
bool has_writable : 1;
v8::Local<v8::Value> value;
v8::Local<v8::Value> get;
v8::Local<v8::Value> set;
};
class PropertyIterator {
public:
static std::unique_ptr<PropertyIterator> Create(v8::Local<v8::Object> object);
virtual ~PropertyIterator() = default;
virtual bool Done() const = 0;
virtual void Advance() = 0;
virtual v8::Local<v8::Name> name() const = 0;
virtual bool is_native_accessor() = 0;
virtual bool has_native_getter() = 0;
virtual bool has_native_setter() = 0;
virtual Maybe<PropertyAttribute> attributes() = 0;
virtual Maybe<PropertyDescriptor> descriptor() = 0;
virtual bool is_own() = 0;
virtual bool is_array_index() = 0;
};
} // namespace debug
} // namespace v8
......
// Copyright 2018 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-property-iterator.h"
#include "src/api-inl.h"
#include "src/base/flags.h"
#include "src/keys.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/property-descriptor.h"
#include "src/property-details.h"
namespace v8 {
std::unique_ptr<debug::PropertyIterator> debug::PropertyIterator::Create(
v8::Local<v8::Object> v8_object) {
internal::Isolate* isolate =
reinterpret_cast<internal::Isolate*>(v8_object->GetIsolate());
return std::unique_ptr<debug::PropertyIterator>(
new internal::DebugPropertyIterator(isolate,
Utils::OpenHandle(*v8_object)));
}
namespace internal {
DebugPropertyIterator::DebugPropertyIterator(Isolate* isolate,
Handle<JSReceiver> receiver)
: isolate_(isolate),
prototype_iterator_(isolate, receiver, kStartAtReceiver,
PrototypeIterator::END_AT_NULL) {
if (receiver->IsJSProxy()) {
is_own_ = false;
prototype_iterator_.AdvanceIgnoringProxies();
}
if (prototype_iterator_.IsAtEnd()) return;
FillKeysForCurrentPrototypeAndStage();
if (should_move_to_next_stage()) Advance();
}
bool DebugPropertyIterator::Done() const {
return prototype_iterator_.IsAtEnd();
}
void DebugPropertyIterator::Advance() {
++current_key_index_;
calculated_native_accessor_flags_ = false;
while (should_move_to_next_stage()) {
switch (stage_) {
case Stage::kExoticIndices:
stage_ = Stage::kEnumerableStrings;
break;
case Stage::kEnumerableStrings:
stage_ = Stage::kAllProperties;
break;
case Stage::kAllProperties:
stage_ = kExoticIndices;
is_own_ = false;
prototype_iterator_.AdvanceIgnoringProxies();
break;
}
FillKeysForCurrentPrototypeAndStage();
}
}
bool DebugPropertyIterator::is_native_accessor() {
if (stage_ == kExoticIndices) return false;
CalculateNativeAccessorFlags();
return native_accessor_flags_;
}
bool DebugPropertyIterator::has_native_getter() {
if (stage_ == kExoticIndices) return false;
CalculateNativeAccessorFlags();
return native_accessor_flags_ &
static_cast<int>(debug::NativeAccessorType::HasGetter);
}
bool DebugPropertyIterator::has_native_setter() {
if (stage_ == kExoticIndices) return false;
CalculateNativeAccessorFlags();
return native_accessor_flags_ &
static_cast<int>(debug::NativeAccessorType::HasSetter);
}
Handle<Name> DebugPropertyIterator::raw_name() const {
DCHECK(!Done());
if (stage_ == kExoticIndices) {
return isolate_->factory()->Uint32ToString(current_key_index_);
} else {
return Handle<Name>::cast(
FixedArray::get(*keys_, current_key_index_, isolate_));
}
}
v8::Local<v8::Name> DebugPropertyIterator::name() const {
return Utils::ToLocal(raw_name());
}
v8::Maybe<v8::PropertyAttribute> DebugPropertyIterator::attributes() {
Handle<JSReceiver> receiver =
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
auto result = JSReceiver::GetPropertyAttributes(receiver, raw_name());
if (result.IsNothing()) return Nothing<v8::PropertyAttribute>();
DCHECK(result.FromJust() != ABSENT);
return Just(static_cast<v8::PropertyAttribute>(result.FromJust()));
}
v8::Maybe<v8::debug::PropertyDescriptor> DebugPropertyIterator::descriptor() {
Handle<JSReceiver> receiver =
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
PropertyDescriptor descriptor;
Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
isolate_, receiver, raw_name(), &descriptor);
if (did_get_descriptor.IsNothing()) {
return Nothing<v8::debug::PropertyDescriptor>();
}
DCHECK(did_get_descriptor.FromJust());
return Just(v8::debug::PropertyDescriptor{
descriptor.enumerable(), descriptor.has_enumerable(),
descriptor.configurable(), descriptor.has_configurable(),
descriptor.writable(), descriptor.has_writable(),
descriptor.has_value() ? Utils::ToLocal(descriptor.value())
: v8::Local<v8::Value>(),
descriptor.has_get() ? Utils::ToLocal(descriptor.get())
: v8::Local<v8::Value>(),
descriptor.has_set() ? Utils::ToLocal(descriptor.set())
: v8::Local<v8::Value>(),
});
}
bool DebugPropertyIterator::is_own() { return is_own_; }
bool DebugPropertyIterator::is_array_index() {
if (stage_ == kExoticIndices) return true;
uint32_t index = 0;
return raw_name()->AsArrayIndex(&index);
}
void DebugPropertyIterator::FillKeysForCurrentPrototypeAndStage() {
current_key_index_ = 0;
exotic_length_ = 0;
keys_ = Handle<FixedArray>::null();
if (prototype_iterator_.IsAtEnd()) return;
Handle<JSReceiver> receiver =
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
bool has_exotic_indices = receiver->IsJSTypedArray();
if (stage_ == kExoticIndices) {
if (!has_exotic_indices) return;
exotic_length_ = static_cast<uint32_t>(
Handle<JSTypedArray>::cast(receiver)->length_value());
return;
}
bool skip_indices = has_exotic_indices;
PropertyFilter filter =
stage_ == kEnumerableStrings ? ENUMERABLE_STRINGS : ALL_PROPERTIES;
if (!KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter,
GetKeysConversion::kConvertToString, false,
skip_indices)
.ToHandle(&keys_)) {
keys_ = Handle<FixedArray>::null();
}
}
bool DebugPropertyIterator::should_move_to_next_stage() const {
if (prototype_iterator_.IsAtEnd()) return false;
if (stage_ == kExoticIndices) return current_key_index_ >= exotic_length_;
return keys_.is_null() ||
current_key_index_ >= static_cast<uint32_t>(keys_->length());
}
namespace {
base::Flags<debug::NativeAccessorType, int> GetNativeAccessorDescriptorInternal(
Handle<JSReceiver> object, Handle<Name> name) {
uint32_t index;
if (name->AsArrayIndex(&index)) return debug::NativeAccessorType::None;
LookupIterator it =
LookupIterator(object->GetIsolate(), object, name, LookupIterator::OWN);
if (!it.IsFound()) return debug::NativeAccessorType::None;
if (it.state() != LookupIterator::ACCESSOR) {
return debug::NativeAccessorType::None;
}
Handle<Object> structure = it.GetAccessors();
if (!structure->IsAccessorInfo()) return debug::NativeAccessorType::None;
auto isolate = object->GetIsolate();
base::Flags<debug::NativeAccessorType, int> result;
#define IS_BUILTIN_ACESSOR(_, name, ...) \
if (*structure == *isolate->factory()->name##_accessor()) \
return debug::NativeAccessorType::None;
ACCESSOR_INFO_LIST_GENERATOR(IS_BUILTIN_ACESSOR, /* not used */)
#undef IS_BUILTIN_ACESSOR
Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
if (accessor_info->getter()) {
result |= debug::NativeAccessorType::HasGetter;
}
if (accessor_info->setter()) {
result |= debug::NativeAccessorType::HasSetter;
}
return result;
}
} // anonymous namespace
void DebugPropertyIterator::CalculateNativeAccessorFlags() {
if (calculated_native_accessor_flags_) return;
Handle<JSReceiver> receiver =
PrototypeIterator::GetCurrent<JSReceiver>(prototype_iterator_);
native_accessor_flags_ =
GetNativeAccessorDescriptorInternal(receiver, raw_name());
calculated_native_accessor_flags_ = true;
}
} // namespace internal
} // namespace v8
// Copyright 2018 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.
#ifndef V8_DEBUG_DEBUG_PROPERTY_ITERATOR_H_
#define V8_DEBUG_DEBUG_PROPERTY_ITERATOR_H_
#include "src/debug/debug-interface.h"
#include "src/handles.h"
#include "src/isolate.h"
#include "src/prototype.h"
#include "include/v8.h"
namespace v8 {
namespace internal {
class JSReceiver;
class DebugPropertyIterator final : public debug::PropertyIterator {
public:
DebugPropertyIterator(Isolate* isolate, Handle<JSReceiver> receiver);
~DebugPropertyIterator() override = default;
bool Done() const override;
void Advance() override;
v8::Local<v8::Name> name() const override;
bool is_native_accessor() override;
bool has_native_getter() override;
bool has_native_setter() override;
v8::Maybe<v8::PropertyAttribute> attributes() override;
v8::Maybe<v8::debug::PropertyDescriptor> descriptor() override;
bool is_own() override;
bool is_array_index() override;
private:
void FillKeysForCurrentPrototypeAndStage();
bool should_move_to_next_stage() const;
void CalculateNativeAccessorFlags();
Handle<Name> raw_name() const;
Isolate* isolate_;
PrototypeIterator prototype_iterator_;
enum Stage { kExoticIndices = 0, kEnumerableStrings = 1, kAllProperties = 2 };
Stage stage_ = kExoticIndices;
uint32_t current_key_index_ = 0;
Handle<FixedArray> keys_;
uint32_t exotic_length_ = 0;
bool calculated_native_accessor_flags_ = false;
int native_accessor_flags_ = 0;
bool is_own_ = true;
DISALLOW_COPY_AND_ASSIGN(DebugPropertyIterator);
};
} // namespace internal
} // namespace v8
#endif // V8_DEBUG_DEBUG_PROPERTY_ITERATOR_H_
......@@ -61,22 +61,6 @@ inspector_protocol_generate("protocol_generated_sources") {
outputs = _protocol_generated
}
action("inspector_injected_script") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
script = "build/xxd.py"
inputs = [
"injected-script-source.js",
]
outputs = [
"$target_gen_dir/injected-script-source.h",
]
args = [
"InjectedScriptSource_js",
rebase_path("injected-script-source.js", root_build_dir),
rebase_path("$target_gen_dir/injected-script-source.h", root_build_dir),
]
}
config("inspector_config") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
if (is_component_build) {
......@@ -86,7 +70,6 @@ config("inspector_config") {
v8_source_set("inspector") {
deps = [
":inspector_injected_script",
":protocol_generated_sources",
]
configs = [ ":inspector_config" ]
......@@ -101,7 +84,6 @@ v8_source_set("inspector") {
"../../include/v8-inspector-protocol.h",
"../../include/v8-inspector.h",
]
sources += get_target_outputs(":inspector_injected_script")
sources += [
"custom-preview.cc",
"custom-preview.h",
......@@ -131,18 +113,12 @@ v8_source_set("inspector") {
"v8-debugger-script.h",
"v8-debugger.cc",
"v8-debugger.h",
"v8-function-call.cc",
"v8-function-call.h",
"v8-heap-profiler-agent-impl.cc",
"v8-heap-profiler-agent-impl.h",
"v8-injected-script-host.cc",
"v8-injected-script-host.h",
"v8-inspector-impl.cc",
"v8-inspector-impl.h",
"v8-inspector-session-impl.cc",
"v8-inspector-session-impl.h",
"v8-internal-value-type.cc",
"v8-internal-value-type.h",
"v8-profiler-agent-impl.cc",
"v8-profiler-agent-impl.h",
"v8-regex.cc",
......@@ -155,6 +131,8 @@ v8_source_set("inspector") {
"v8-stack-trace-impl.h",
"v8-value-utils.cc",
"v8-value-utils.h",
"value-mirror.cc",
"value-mirror.h",
"wasm-translation.cc",
"wasm-translation.h",
]
......
#!/usr/bin/env python
#
# Copyright 2016 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.
"""v8_inspect presubmit script
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
compile_note = "Be sure to run your patch by the compile-scripts.py script prior to committing!"
def _CompileScripts(input_api, output_api):
local_paths = [f.LocalPath() for f in input_api.AffectedFiles()]
compilation_related_files = [
"js_protocol.json"
"compile-scripts.js",
"injected-script-source.js",
"injected_script_externs.js",
"check_injected_script_source.js"
]
for file in compilation_related_files:
if (any(file in path for path in local_paths)):
script_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
"build", "compile-scripts.py")
proc = input_api.subprocess.Popen(
[input_api.python_executable, script_path],
stdout=input_api.subprocess.PIPE,
stderr=input_api.subprocess.STDOUT)
out, _ = proc.communicate()
if "ERROR" in out or "WARNING" in out or proc.returncode:
return [output_api.PresubmitError(out)]
if "NOTE" in out:
return [output_api.PresubmitPromptWarning(out + compile_note)]
return []
return []
def CheckChangeOnUpload(input_api, output_api):
results = []
results.extend(_CompileScripts(input_api, output_api))
return results
def CheckChangeOnCommit(input_api, output_api):
results = []
results.extend(_CompileScripts(input_api, output_api))
return results
#!/usr/bin/env python
# Copyright (c) 2014 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Copied from blink:
# WebKit/Source/devtools/scripts/check_injected_script_source.py
#
import re
import sys
import os
def validate_injected_script(fileName):
f = open(fileName, "r")
lines = f.readlines()
f.close()
proto_functions = "|".join([
# Array.prototype.*
"concat", "every", "filter", "forEach", "indexOf", "join", "lastIndexOf", "map", "pop",
"push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toString", "unshift",
# Function.prototype.*
"apply", "bind", "call", "isGenerator", "toSource",
# Object.prototype.*
"toString",
])
global_functions = "|".join([
"eval", "uneval", "isFinite", "isNaN", "parseFloat", "parseInt", "decodeURI", "decodeURIComponent",
"encodeURI", "encodeURIComponent", "escape", "unescape", "Map", "Set"
])
# Black list:
# - instanceof, since e.g. "obj instanceof Error" may throw if Error is overridden and is not a function
# - Object.prototype.toString()
# - Array.prototype.*
# - Function.prototype.*
# - Math.*
# - Global functions
black_list_call_regex = re.compile(r"\sinstanceof\s+\w*|\bMath\.\w+\(|(?<!InjectedScriptHost)\.(" + proto_functions + r")\(|[^\.]\b(" + global_functions + r")\(")
errors_found = False
for i, line in enumerate(lines):
if line.find("suppressBlacklist") != -1:
continue
for match in re.finditer(black_list_call_regex, line):
errors_found = True
print "ERROR: Black listed expression in %s at line %02d column %02d: %s" % (os.path.basename(fileName), i + 1, match.start(), match.group(0))
if not errors_found:
print "OK"
def main(argv):
if len(argv) < 2:
print('ERROR: Usage: %s path/to/injected-script-source.js' % argv[0])
return 1
validate_injected_script(argv[1])
if __name__ == '__main__':
sys.exit(main(sys.argv))
69937d3c239ca63e4c9045718886ddd096ffc054
\ No newline at end of file
#!/usr/bin/env python
#
# Copyright 2016 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.
import os
import os.path as path
import generate_protocol_externs
import re
import subprocess
import sys
if len(sys.argv) == 2 and sys.argv[1] == '--help':
print("Usage: %s" % path.basename(sys.argv[0]))
sys.exit(0)
java_required_major = 1
java_required_minor = 7
v8_inspector_path = path.dirname(path.dirname(path.abspath(__file__)))
protocol_externs_file = path.join(v8_inspector_path, 'protocol_externs.js')
injected_script_source_name = path.join(v8_inspector_path,
'injected-script-source.js')
injected_script_externs_file = path.join(v8_inspector_path,
'injected_script_externs.js')
generate_protocol_externs.generate_protocol_externs(protocol_externs_file,
path.join(v8_inspector_path, 'js_protocol.json'))
error_warning_regex = re.compile(r'WARNING|ERROR')
closure_compiler_jar = path.join(v8_inspector_path, 'build',
'closure-compiler', 'closure-compiler.jar')
common_closure_args = [
'--checks_only',
'--warning_level', 'VERBOSE'
]
# Error reporting and checking.
errors_found = False
def popen(arguments):
return subprocess.Popen(arguments, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
def error_excepthook(exctype, value, traceback):
print 'ERROR:'
sys.__excepthook__(exctype, value, traceback)
sys.excepthook = error_excepthook
def has_errors(output):
return re.search(error_warning_regex, output) != None
# Find java. Based on
# http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python.
def which(program):
def is_exe(fpath):
return path.isfile(fpath) and os.access(fpath, os.X_OK)
fpath, fname = path.split(program)
if fpath:
if is_exe(program):
return program
else:
for part in os.environ['PATH'].split(os.pathsep):
part = part.strip('"')
exe_file = path.join(part, program)
if is_exe(exe_file):
return exe_file
return None
def find_java():
exec_command = None
has_server_jvm = True
java_path = which('java')
if not java_path:
java_path = which('java.exe')
if not java_path:
print 'NOTE: No Java executable found in $PATH.'
sys.exit(0)
is_ok = False
java_version_out, _ = popen([java_path, '-version']).communicate()
java_build_regex = re.compile(r'^\w+ version "(\d+)\.(\d+)')
# pylint: disable=E1103
match = re.search(java_build_regex, java_version_out)
if match:
major = int(match.group(1))
minor = int(match.group(2))
is_ok = major >= java_required_major and minor >= java_required_minor
if is_ok:
exec_command = [java_path, '-Xms1024m', '-server',
'-XX:+TieredCompilation']
check_server_proc = popen(exec_command + ['-version'])
check_server_proc.communicate()
if check_server_proc.returncode != 0:
# Not all Java installs have server JVMs.
exec_command = exec_command.remove('-server')
has_server_jvm = False
if not is_ok:
print 'NOTE: Java executable version %d.%d or above not found in $PATH.' % (java_required_major, java_required_minor)
sys.exit(0)
print 'Java executable: %s%s' % (java_path, '' if has_server_jvm else ' (no server JVM)')
return exec_command
java_exec = find_java()
spawned_compiler_command = java_exec + [
'-jar',
closure_compiler_jar
] + common_closure_args
print 'Compiling injected-script-source.js...'
command = spawned_compiler_command + [
'--externs', injected_script_externs_file,
'--externs', protocol_externs_file,
'--js', injected_script_source_name
]
injected_script_compile_proc = popen(command)
print 'Validating injected-script-source.js...'
injectedscript_check_script_path = path.join(v8_inspector_path, 'build',
'check_injected_script_source.py')
validate_injected_script_proc = popen([sys.executable,
injectedscript_check_script_path, injected_script_source_name])
print
(injected_script_compile_out, _) = injected_script_compile_proc.communicate()
print 'injected-script-source.js compilation output:%s' % os.linesep
print injected_script_compile_out
errors_found |= has_errors(injected_script_compile_out)
(validate_injected_script_out, _) = validate_injected_script_proc.communicate()
print 'Validate injected-script-source.js output:%s' % os.linesep
print validate_injected_script_out if validate_injected_script_out else '<empty>'
errors_found |= has_errors(validate_injected_script_out)
os.remove(protocol_externs_file)
if errors_found:
print 'ERRORS DETECTED'
sys.exit(1)
This diff is collapsed.
This diff is collapsed.
# Copyright 2016 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.
"""Represent a file as a C++ constant string.
Usage:
python xxd.py VAR SOURCE DEST
"""
import sys
import rjsmin
def main():
variable_name, input_filename, output_filename = sys.argv[1:]
with open(input_filename) as input_file:
input_text = input_file.read()
input_text = rjsmin.jsmin(input_text)
hex_values = ['0x{0:02x}'.format(ord(char)) for char in input_text]
const_declaration = 'const char %s[] = {\n%s\n};\n' % (
variable_name, ', '.join(hex_values))
with open(output_filename, 'w') as output_file:
output_file.write(const_declaration)
if __name__ == '__main__':
sys.exit(main())
......@@ -113,7 +113,7 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
}
std::unique_ptr<protocol::Runtime::RemoteObject> wrapper;
protocol::Response response =
injectedScript->wrapObject(originValue, groupName, false, false,
injectedScript->wrapObject(originValue, groupName, WrapMode::kNoPreview,
configValue, maxDepth - 1, &wrapper);
if (!response.isSuccess() || !wrapper) {
reportError(context, tryCatch, "cannot wrap value");
......@@ -379,13 +379,8 @@ void generateCustomPreview(int sessionId, const String16& groupName,
reportError(context, tryCatch, "cannot find context with specified id");
return;
}
(*preview)->setBodyGetterId(String16::concat(
"{\"injectedScriptId\":",
String16::fromInteger(InspectedContext::contextId(context)),
",\"id\":",
String16::fromInteger(
injectedScript->bindObject(bodyFunction, groupName)),
"}"));
(*preview)->setBodyGetterId(
injectedScript->bindObject(bodyFunction, groupName));
}
return;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -46,9 +46,9 @@
namespace v8_inspector {
class RemoteObjectId;
class V8FunctionCall;
class V8InspectorImpl;
class V8InspectorSessionImpl;
enum class WrapMode;
using protocol::Maybe;
using protocol::Response;
......@@ -65,38 +65,40 @@ class EvaluateCallback {
class InjectedScript final {
public:
static std::unique_ptr<InjectedScript> create(InspectedContext*,
int sessionId);
InjectedScript(InspectedContext*, int sessionId);
~InjectedScript();
static InjectedScript* fromInjectedScriptHost(v8::Isolate* isolate,
v8::Local<v8::Object>);
InspectedContext* context() const { return m_context; }
Response getProperties(
v8::Local<v8::Object>, const String16& groupName, bool ownProperties,
bool accessorPropertiesOnly, bool generatePreview,
bool accessorPropertiesOnly, WrapMode wrapMode,
std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>*
result,
Maybe<protocol::Runtime::ExceptionDetails>*);
Response getInternalProperties(
v8::Local<v8::Value>, const String16& groupName,
std::unique_ptr<
protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>*
result);
void releaseObject(const String16& objectId);
Response wrapObject(
v8::Local<v8::Value>, const String16& groupName, bool forceValueType,
bool generatePreview,
std::unique_ptr<protocol::Runtime::RemoteObject>* result) const;
Response wrapObject(
v8::Local<v8::Value>, const String16& groupName, bool forceValueType,
bool generatePreview, v8::MaybeLocal<v8::Value> customPreviewConfig,
int maxCustomPreviewDepth,
std::unique_ptr<protocol::Runtime::RemoteObject>* result) const;
Response wrapObject(v8::Local<v8::Value>, const String16& groupName,
WrapMode wrapMode,
std::unique_ptr<protocol::Runtime::RemoteObject>* result);
Response wrapObject(v8::Local<v8::Value>, const String16& groupName,
WrapMode wrapMode,
v8::MaybeLocal<v8::Value> customPreviewConfig,
int maxCustomPreviewDepth,
std::unique_ptr<protocol::Runtime::RemoteObject>* result);
std::unique_ptr<protocol::Runtime::RemoteObject> wrapTable(
v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const;
v8::Local<v8::Object> table, v8::MaybeLocal<v8::Array> columns);
void addPromiseCallback(V8InspectorSessionImpl* session,
v8::MaybeLocal<v8::Value> value,
const String16& objectGroup, bool returnByValue,
bool generatePreview,
const String16& objectGroup, WrapMode wrapMode,
std::unique_ptr<EvaluateCallback> callback);
Response findObject(const RemoteObjectId&, v8::Local<v8::Value>*) const;
......@@ -107,18 +109,16 @@ class InjectedScript final {
v8::Local<v8::Value>* result);
Response createExceptionDetails(
const v8::TryCatch&, const String16& groupName, bool generatePreview,
const v8::TryCatch&, const String16& groupName, WrapMode wrapMode,
Maybe<protocol::Runtime::ExceptionDetails>* result);
Response wrapEvaluateResult(
v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch&,
const String16& objectGroup, bool returnByValue, bool generatePreview,
const String16& objectGroup, WrapMode wrapMode,
std::unique_ptr<protocol::Runtime::RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>*);
v8::Local<v8::Value> lastEvaluationResult() const;
void setLastEvaluationResult(v8::Local<v8::Value> result);
int bindObject(v8::Local<v8::Value>, const String16& groupName);
class Scope {
public:
Response initialize();
......@@ -196,23 +196,21 @@ class InjectedScript final {
DISALLOW_COPY_AND_ASSIGN(CallFrameScope);
};
String16 bindObject(v8::Local<v8::Value>, const String16& groupName);
private:
InjectedScript(InspectedContext*, v8::Local<v8::Object>, int sessionId);
v8::Local<v8::Value> v8Value() const;
Response wrapValue(v8::Local<v8::Value>, const String16& groupName,
bool forceValueType, bool generatePreview,
v8::Local<v8::Value>* result) const;
v8::Local<v8::Object> commandLineAPI();
void unbindObject(int id);
void bindRemoteObjectIfNeeded(v8::Local<v8::Value>, const String16& groupName,
protocol::Runtime::RemoteObject* remoteObject);
class ProtocolPromiseHandler;
void discardEvaluateCallbacks();
std::unique_ptr<EvaluateCallback> takeEvaluateCallback(
EvaluateCallback* callback);
InspectedContext* m_context;
v8::Global<v8::Value> m_value;
int m_sessionId;
v8::Global<v8::Value> m_lastEvaluationResult;
v8::Global<v8::Object> m_commandLineAPI;
......
// Copyright 2015 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.
/** @interface */
function InjectedScriptHostClass()
{
}
/**
* @param {*} obj
*/
InjectedScriptHostClass.prototype.nullifyPrototype = function(obj) {}
/**
* @param {*} obj
* @param {string} name
* @return {*}
*/
InjectedScriptHostClass.prototype.getProperty = function(obj, name) {}
/**
* @param {*} obj
* @return {string}
*/
InjectedScriptHostClass.prototype.internalConstructorName = function(obj) {}
/**
* @param {*} obj
* @param {function()|undefined} func
* @return {boolean}
*/
InjectedScriptHostClass.prototype.formatAccessorsAsProperties = function(obj, func) {}
/**
* @param {*} obj
* @return {string}
*/
InjectedScriptHostClass.prototype.subtype = function(obj) {}
/**
* @param {*} obj
* @return {boolean}
*/
InjectedScriptHostClass.prototype.isTypedArray = function(obj) {}
/**
* @param {*} obj
* @return {!Array.<*>}
*/
InjectedScriptHostClass.prototype.getInternalProperties = function(obj) {}
/**
* @param {!Object} object
* @param {string} propertyName
* @return {boolean}
*/
InjectedScriptHostClass.prototype.objectHasOwnProperty = function(object, propertyName) {}
/**
* @param {*} value
* @param {string} groupName
* @return {number}
*/
InjectedScriptHostClass.prototype.bind = function(value, groupName) {}
/**
* @param {!Object} object
* @return {!Object}
*/
InjectedScriptHostClass.prototype.proxyTargetValue = function(object) {}
/**
* @param {!Object} obj
* @return {!Array<string>}
*/
InjectedScriptHostClass.prototype.keys = function(obj) {}
/**
* @param {!Object} obj
* @return {Object}
*/
InjectedScriptHostClass.prototype.getPrototypeOf = function(obj) {}
/**
* @param {!Object} obj
* @param {string} prop
* @return {Object}
*/
InjectedScriptHostClass.prototype.getOwnPropertyDescriptor = function(obj, prop) {}
/**
* @param {!Object} obj
* @return {!Array<string>}
*/
InjectedScriptHostClass.prototype.getOwnPropertyNames = function(obj) {}
/**
* @param {!Object} obj
* @return {!Array<symbol>}
*/
InjectedScriptHostClass.prototype.getOwnPropertySymbols = function(obj) {}
/**
* @param {!Object} obj
* @param {string|symbol} name
* @return {{isBuiltin:boolean, hasGetter:boolean, hasSetter:boolean}|undefined}
*/
InjectedScriptHostClass.prototype.nativeAccessorDescriptor = function(obj, name) {}
/**
* @param {!Object} arrayBuffer
* @return {Array<Object>|undefined}
*/
InjectedScriptHostClass.prototype.typedArrayProperties = function(arrayBuffer) {}
/** @type {!InjectedScriptHostClass} */
var InjectedScriptHost;
/** @type {!Window} */
var inspectedGlobalObject;
/** @type {number} */
var injectedScriptId;
......@@ -109,14 +109,12 @@ InjectedScript* InspectedContext::getInjectedScript(int sessionId) {
return it == m_injectedScripts.end() ? nullptr : it->second.get();
}
bool InspectedContext::createInjectedScript(int sessionId) {
InjectedScript* InspectedContext::createInjectedScript(int sessionId) {
std::unique_ptr<InjectedScript> injectedScript =
InjectedScript::create(this, sessionId);
// InjectedScript::create can destroy |this|.
if (!injectedScript) return false;
v8::base::make_unique<InjectedScript>(this, sessionId);
CHECK(m_injectedScripts.find(sessionId) == m_injectedScripts.end());
m_injectedScripts[sessionId] = std::move(injectedScript);
return true;
return getInjectedScript(sessionId);
}
void InspectedContext::discardInjectedScript(int sessionId) {
......
......@@ -40,7 +40,7 @@ class InspectedContext {
V8InspectorImpl* inspector() const { return m_inspector; }
InjectedScript* getInjectedScript(int sessionId);
bool createInjectedScript(int sessionId);
InjectedScript* createInjectedScript(int sessionId);
void discardInjectedScript(int sessionId);
private:
......
......@@ -1890,7 +1890,9 @@
"error",
"proxy",
"promise",
"typedarray"
"typedarray",
"arraybuffer",
"dataview"
]
},
{
......
......@@ -887,6 +887,8 @@ domain Runtime
proxy
promise
typedarray
arraybuffer
dataview
# Object class (constructor) name. Specified for `object` type values only.
optional string className
# Remote object value in case of primitive values or JSON values (if it was requested).
......
......@@ -259,19 +259,33 @@ V8ConsoleMessage::wrapArguments(V8InspectorSessionImpl* session,
std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>> args =
protocol::Array<protocol::Runtime::RemoteObject>::create();
if (m_type == ConsoleAPIType::kTable && generatePreview) {
v8::Local<v8::Value> table = m_arguments[0]->Get(isolate);
v8::Local<v8::Value> columns = m_arguments.size() > 1
? m_arguments[1]->Get(isolate)
: v8::Local<v8::Value>();
v8::Local<v8::Value> value = m_arguments[0]->Get(isolate);
if (value->IsObject() && m_type == ConsoleAPIType::kTable &&
generatePreview) {
v8::MaybeLocal<v8::Array> columns;
if (m_arguments.size() > 1) {
v8::Local<v8::Value> secondArgument = m_arguments[1]->Get(isolate);
if (secondArgument->IsArray()) {
columns = v8::Local<v8::Array>::Cast(secondArgument);
} else if (secondArgument->IsString()) {
v8::TryCatch tryCatch(isolate);
v8::Local<v8::Array> array = v8::Array::New(isolate);
if (array->Set(context, 0, secondArgument).IsJust()) {
columns = array;
}
}
}
std::unique_ptr<protocol::Runtime::RemoteObject> wrapped =
session->wrapTable(context, table, columns);
session->wrapTable(context, v8::Local<v8::Object>::Cast(value),
columns);
inspectedContext = inspector->getContext(contextGroupId, contextId);
if (!inspectedContext) return nullptr;
if (wrapped)
if (wrapped) {
args->addItem(std::move(wrapped));
else
} else {
args = nullptr;
}
} else {
for (size_t i = 0; i < m_arguments.size(); ++i) {
std::unique_ptr<protocol::Runtime::RemoteObject> wrapped =
......
......@@ -600,9 +600,8 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
InjectedScript* injectedScript = helper.injectedScript(sessionId);
if (!injectedScript) return;
std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject;
protocol::Response response =
injectedScript->wrapObject(value, "", false /** forceValueType */,
false /** generatePreview */, &wrappedObject);
protocol::Response response = injectedScript->wrapObject(
value, "", WrapMode::kNoPreview, &wrappedObject);
if (!response.isSuccess()) return;
std::unique_ptr<protocol::DictionaryValue> hints =
......
......@@ -260,8 +260,9 @@ Response buildScopes(v8::Isolate* isolate, v8::debug::ScopeIterator* iterator,
for (; !iterator->Done(); iterator->Advance()) {
std::unique_ptr<RemoteObject> object;
Response result = injectedScript->wrapObject(
iterator->GetObject(), kBacktraceObjectGroup, false, false, &object);
Response result =
injectedScript->wrapObject(iterator->GetObject(), kBacktraceObjectGroup,
WrapMode::kNoPreview, &object);
if (!result.isSuccess()) return result;
auto scope = Scope::create()
......@@ -1085,10 +1086,12 @@ Response V8DebuggerAgentImpl::evaluateOnCallFrame(
// context or session.
response = scope.initialize();
if (!response.isSuccess()) return response;
WrapMode mode = generatePreview.fromMaybe(false) ? WrapMode::kWithPreview
: WrapMode::kNoPreview;
if (returnByValue.fromMaybe(false)) mode = WrapMode::kForceValue;
return scope.injectedScript()->wrapEvaluateResult(
maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""),
returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result,
exceptionDetails);
maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), mode,
result, exceptionDetails);
}
Response V8DebuggerAgentImpl::setVariableValue(
......@@ -1268,8 +1271,9 @@ Response V8DebuggerAgentImpl::currentCallFrames(
if (injectedScript) {
v8::Local<v8::Value> receiver;
if (iterator->GetReceiver().ToLocal(&receiver)) {
res = injectedScript->wrapObject(receiver, kBacktraceObjectGroup, false,
false, &protocolReceiver);
res =
injectedScript->wrapObject(receiver, kBacktraceObjectGroup,
WrapMode::kNoPreview, &protocolReceiver);
if (!res.isSuccess()) return res;
}
}
......@@ -1320,7 +1324,7 @@ Response V8DebuggerAgentImpl::currentCallFrames(
if (!returnValue.IsEmpty() && injectedScript) {
std::unique_ptr<RemoteObject> value;
res = injectedScript->wrapObject(returnValue, kBacktraceObjectGroup,
false, false, &value);
WrapMode::kNoPreview, &value);
if (!res.isSuccess()) return res;
frame->setReturnValue(std::move(value));
}
......@@ -1528,8 +1532,8 @@ void V8DebuggerAgentImpl::didPause(
? protocol::Debugger::Paused::ReasonEnum::PromiseRejection
: protocol::Debugger::Paused::ReasonEnum::Exception;
std::unique_ptr<protocol::Runtime::RemoteObject> obj;
injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false,
&obj);
injectedScript->wrapObject(exception, kBacktraceObjectGroup,
WrapMode::kNoPreview, &obj);
std::unique_ptr<protocol::DictionaryValue> breakAuxData;
if (obj) {
breakAuxData = obj->toValue();
......
This diff is collapsed.
......@@ -30,6 +30,9 @@ class V8InspectorImpl;
class V8StackTraceImpl;
struct V8StackTraceId;
enum class WrapMode { kForceValue, kNoPreview, kWithPreview };
enum class V8InternalValueType { kNone, kEntry, kScope, kScopeList };
using protocol::Response;
using ScheduleStepIntoAsyncCallback =
protocol::Debugger::Backend::ScheduleStepIntoAsyncCallback;
......@@ -134,6 +137,12 @@ class V8Debugger : public v8::debug::DebugDelegate,
std::shared_ptr<AsyncStackTrace> stackTraceFor(int contextGroupId,
const V8StackTraceId& id);
bool addInternalObject(v8::Local<v8::Context> context,
v8::Local<v8::Object> object,
V8InternalValueType type);
V8InternalValueType getInternalType(v8::Local<v8::Context> context,
v8::Local<v8::Object> object);
private:
void clearContinueToLocation();
bool shouldContinueToCurrentLocation();
......@@ -160,6 +169,8 @@ class V8Debugger : public v8::debug::DebugDelegate,
v8::Local<v8::Function>);
v8::MaybeLocal<v8::Value> generatorScopes(v8::Local<v8::Context>,
v8::Local<v8::Value>);
v8::MaybeLocal<v8::Array> collectionsEntries(v8::Local<v8::Context> context,
v8::Local<v8::Value> value);
void asyncTaskScheduledForStack(const String16& taskName, void* task,
bool recurring);
......@@ -253,6 +264,8 @@ class V8Debugger : public v8::debug::DebugDelegate,
uint32_t m_lastStableObjectId = 0;
v8::Global<v8::debug::WeakMap> m_stableObjectId;
v8::Global<v8::debug::WeakMap> m_internalObjects;
WasmTranslation m_wasmTranslation;
DISALLOW_COPY_AND_ASSIGN(V8Debugger);
......
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "src/inspector/v8-function-call.h"
#include "src/inspector/inspected-context.h"
#include "src/inspector/string-util.h"
#include "src/inspector/v8-debugger.h"
#include "src/inspector/v8-inspector-impl.h"
#include "include/v8-inspector.h"
namespace v8_inspector {
V8FunctionCall::V8FunctionCall(V8InspectorImpl* inspector,
v8::Local<v8::Context> context,
v8::Local<v8::Value> value, const String16& name)
: m_inspector(inspector),
m_context(context),
m_name(toV8String(context->GetIsolate(), name)),
m_value(value) {}
void V8FunctionCall::appendArgument(v8::Local<v8::Value> value) {
m_arguments.push_back(value);
}
void V8FunctionCall::appendArgument(const String16& argument) {
m_arguments.push_back(toV8String(m_context->GetIsolate(), argument));
}
void V8FunctionCall::appendArgument(int argument) {
m_arguments.push_back(v8::Number::New(m_context->GetIsolate(), argument));
}
void V8FunctionCall::appendArgument(bool argument) {
m_arguments.push_back(argument ? v8::True(m_context->GetIsolate())
: v8::False(m_context->GetIsolate()));
}
v8::Local<v8::Value> V8FunctionCall::call(bool& hadException,
bool reportExceptions) {
v8::TryCatch tryCatch(m_context->GetIsolate());
tryCatch.SetVerbose(reportExceptions);
v8::Local<v8::Value> result = callWithoutExceptionHandling();
hadException = tryCatch.HasCaught();
return result;
}
v8::Local<v8::Value> V8FunctionCall::callWithoutExceptionHandling() {
v8::Context::Scope contextScope(m_context);
v8::Local<v8::Object> thisObject = v8::Local<v8::Object>::Cast(m_value);
v8::Local<v8::Value> value;
if (!thisObject->Get(m_context, m_name).ToLocal(&value))
return v8::Local<v8::Value>();
DCHECK(value->IsFunction());
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value);
std::unique_ptr<v8::Local<v8::Value>[]> info(
new v8::Local<v8::Value>[m_arguments.size()]);
for (size_t i = 0; i < m_arguments.size(); ++i) {
info[i] = m_arguments[i];
DCHECK(!info[i].IsEmpty());
}
int contextGroupId = m_inspector->contextGroupId(m_context);
if (contextGroupId) {
m_inspector->client()->muteMetrics(contextGroupId);
m_inspector->muteExceptions(contextGroupId);
}
v8::MicrotasksScope microtasksScope(m_context->GetIsolate(),
v8::MicrotasksScope::kDoNotRunMicrotasks);
v8::Isolate::AllowJavascriptExecutionScope(m_context->GetIsolate());
v8::MaybeLocal<v8::Value> maybeResult = function->Call(
m_context, thisObject, static_cast<int>(m_arguments.size()), info.get());
if (contextGroupId) {
m_inspector->client()->unmuteMetrics(contextGroupId);
m_inspector->unmuteExceptions(contextGroupId);
}
v8::Local<v8::Value> result;
if (!maybeResult.ToLocal(&result)) return v8::Local<v8::Value>();
return result;
}
} // namespace v8_inspector
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef V8_INSPECTOR_V8_FUNCTION_CALL_H_
#define V8_INSPECTOR_V8_FUNCTION_CALL_H_
#include "src/inspector/string-16.h"
#include "include/v8.h"
namespace v8_inspector {
class V8InspectorImpl;
class V8FunctionCall {
public:
V8FunctionCall(V8InspectorImpl*, v8::Local<v8::Context>, v8::Local<v8::Value>,
const String16& name);
void appendArgument(v8::Local<v8::Value>);
void appendArgument(const String16&);
void appendArgument(int);
void appendArgument(bool);
v8::Local<v8::Value> call(bool& hadException, bool reportExceptions = true);
v8::Local<v8::Value> callWithoutExceptionHandling();
protected:
V8InspectorImpl* m_inspector;
v8::Local<v8::Context> m_context;
std::vector<v8::Local<v8::Value>> m_arguments;
v8::Local<v8::String> m_name;
v8::Local<v8::Value> m_value;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8_FUNCTION_CALL_H_
This diff is collapsed.
// Copyright 2015 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.
#ifndef V8_INSPECTOR_V8_INJECTED_SCRIPT_HOST_H_
#define V8_INSPECTOR_V8_INJECTED_SCRIPT_HOST_H_
#include "include/v8.h"
namespace v8_inspector {
class V8InspectorImpl;
// SECURITY NOTE: Although the InjectedScriptHost is intended for use solely by
// the inspector,
// a reference to the InjectedScriptHost may be leaked to the page being
// inspected. Thus, the
// InjectedScriptHost must never implemment methods that have more power over
// the page than the
// page already has itself (e.g. origin restriction bypasses).
class V8InjectedScriptHost {
public:
// We expect that debugger outlives any JS context and thus
// V8InjectedScriptHost (owned by JS)
// is destroyed before inspector.
static v8::Local<v8::Object> create(v8::Local<v8::Context>, V8InspectorImpl*);
private:
static void nullifyPrototypeCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void getPropertyCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void internalConstructorNameCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void formatAccessorsAsProperties(
const v8::FunctionCallbackInfo<v8::Value>&);
static void subtypeCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void getInternalPropertiesCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void objectHasOwnPropertyCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void bindCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void proxyTargetValueCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void nativeAccessorDescriptorCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void typedArrayPropertiesCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8_INJECTED_SCRIPT_HOST_H_
......@@ -203,12 +203,7 @@ Response V8InspectorSessionImpl::findInjectedScript(
if (!context) return Response::Error("Cannot find context with specified id");
injectedScript = context->getInjectedScript(m_sessionId);
if (!injectedScript) {
if (!context->createInjectedScript(m_sessionId)) {
if (m_inspector->isolate()->IsExecutionTerminating())
return Response::Error("Execution was terminated");
return Response::Error("Cannot access specified execution context");
}
injectedScript = context->getInjectedScript(m_sessionId);
injectedScript = context->createInjectedScript(m_sessionId);
if (m_customObjectFormatterEnabled)
injectedScript->setCustomObjectFormatterEnabled(true);
}
......@@ -285,14 +280,16 @@ V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context,
findInjectedScript(InspectedContext::contextId(context), injectedScript);
if (!injectedScript) return nullptr;
std::unique_ptr<protocol::Runtime::RemoteObject> result;
injectedScript->wrapObject(value, groupName, false, generatePreview, &result);
injectedScript->wrapObject(
value, groupName,
generatePreview ? WrapMode::kWithPreview : WrapMode::kNoPreview, &result);
return result;
}
std::unique_ptr<protocol::Runtime::RemoteObject>
V8InspectorSessionImpl::wrapTable(v8::Local<v8::Context> context,
v8::Local<v8::Value> table,
v8::Local<v8::Value> columns) {
v8::Local<v8::Object> table,
v8::MaybeLocal<v8::Array> columns) {
InjectedScript* injectedScript = nullptr;
findInjectedScript(InspectedContext::contextId(context), injectedScript);
if (!injectedScript) return nullptr;
......
......@@ -55,8 +55,8 @@ class V8InspectorSessionImpl : public V8InspectorSession,
v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName,
bool generatePreview);
std::unique_ptr<protocol::Runtime::RemoteObject> wrapTable(
v8::Local<v8::Context>, v8::Local<v8::Value> table,
v8::Local<v8::Value> columns);
v8::Local<v8::Context>, v8::Local<v8::Object> table,
v8::MaybeLocal<v8::Array> columns);
std::vector<std::unique_ptr<protocol::Schema::Domain>> supportedDomainsImpl();
Response unwrapObject(const String16& objectId, v8::Local<v8::Value>*,
v8::Local<v8::Context>*, String16* objectGroup);
......
// Copyright 2016 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/inspector/v8-internal-value-type.h"
#include "src/inspector/string-util.h"
namespace v8_inspector {
namespace {
v8::Local<v8::Private> internalSubtypePrivate(v8::Isolate* isolate) {
return v8::Private::ForApi(
isolate,
toV8StringInternalized(isolate, "V8InternalType#internalSubtype"));
}
v8::Local<v8::String> subtypeForInternalType(v8::Isolate* isolate,
V8InternalValueType type) {
switch (type) {
case V8InternalValueType::kEntry:
return toV8StringInternalized(isolate, "internal#entry");
case V8InternalValueType::kLocation:
return toV8StringInternalized(isolate, "internal#location");
case V8InternalValueType::kScope:
return toV8StringInternalized(isolate, "internal#scope");
case V8InternalValueType::kScopeList:
return toV8StringInternalized(isolate, "internal#scopeList");
}
UNREACHABLE();
}
} // namespace
bool markAsInternal(v8::Local<v8::Context> context,
v8::Local<v8::Object> object, V8InternalValueType type) {
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Private> privateValue = internalSubtypePrivate(isolate);
v8::Local<v8::String> subtype = subtypeForInternalType(isolate, type);
return object->SetPrivate(context, privateValue, subtype).FromMaybe(false);
}
bool markArrayEntriesAsInternal(v8::Local<v8::Context> context,
v8::Local<v8::Array> array,
V8InternalValueType type) {
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Private> privateValue = internalSubtypePrivate(isolate);
v8::Local<v8::String> subtype = subtypeForInternalType(isolate, type);
for (uint32_t i = 0; i < array->Length(); ++i) {
v8::Local<v8::Value> entry;
if (!array->Get(context, i).ToLocal(&entry) || !entry->IsObject())
return false;
if (!entry.As<v8::Object>()
->SetPrivate(context, privateValue, subtype)
.FromMaybe(false))
return false;
}
return true;
}
v8::Local<v8::Value> v8InternalValueTypeFrom(v8::Local<v8::Context> context,
v8::Local<v8::Object> object) {
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Private> privateValue = internalSubtypePrivate(isolate);
if (!object->HasPrivate(context, privateValue).FromMaybe(false))
return v8::Null(isolate);
v8::Local<v8::Value> subtypeValue;
if (!object->GetPrivate(context, privateValue).ToLocal(&subtypeValue) ||
!subtypeValue->IsString())
return v8::Null(isolate);
return subtypeValue;
}
} // namespace v8_inspector
// Copyright 2016 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.
#ifndef V8_INSPECTOR_V8_INTERNAL_VALUE_TYPE_H_
#define V8_INSPECTOR_V8_INTERNAL_VALUE_TYPE_H_
#include "include/v8.h"
namespace v8_inspector {
enum class V8InternalValueType { kEntry, kLocation, kScope, kScopeList };
bool markAsInternal(v8::Local<v8::Context>, v8::Local<v8::Object>,
V8InternalValueType);
bool markArrayEntriesAsInternal(v8::Local<v8::Context>, v8::Local<v8::Array>,
V8InternalValueType);
v8::Local<v8::Value> v8InternalValueTypeFrom(v8::Local<v8::Context>,
v8::Local<v8::Object>);
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8_INTERNAL_VALUE_TYPE_H_
This diff is collapsed.
......@@ -6,102 +6,6 @@
namespace v8_inspector {
namespace {
protocol::Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, int maxDepth,
std::unique_ptr<protocol::Value>* result) {
using protocol::Response;
if (value.IsEmpty()) {
UNREACHABLE();
}
if (!maxDepth) return Response::Error("Object reference chain is too long");
maxDepth--;
if (value->IsNull() || value->IsUndefined()) {
*result = protocol::Value::null();
return Response::OK();
}
if (value->IsBoolean()) {
*result =
protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
return Response::OK();
}
if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value();
int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue) {
*result = protocol::FundamentalValue::create(intValue);
return Response::OK();
}
*result = protocol::FundamentalValue::create(doubleValue);
return Response::OK();
}
if (value->IsString()) {
*result = protocol::StringValue::create(
toProtocolString(context->GetIsolate(), value.As<v8::String>()));
return Response::OK();
}
if (value->IsArray()) {
v8::Local<v8::Array> array = value.As<v8::Array>();
std::unique_ptr<protocol::ListValue> inspectorArray =
protocol::ListValue::create();
uint32_t length = array->Length();
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> value;
if (!array->Get(context, i).ToLocal(&value))
return Response::InternalError();
std::unique_ptr<protocol::Value> element;
Response response = toProtocolValue(context, value, maxDepth, &element);
if (!response.isSuccess()) return response;
inspectorArray->pushValue(std::move(element));
}
*result = std::move(inspectorArray);
return Response::OK();
}
if (value->IsObject()) {
std::unique_ptr<protocol::DictionaryValue> jsonObject =
protocol::DictionaryValue::create();
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
v8::Local<v8::Array> propertyNames;
if (!object->GetPropertyNames(context).ToLocal(&propertyNames))
return Response::InternalError();
uint32_t length = propertyNames->Length();
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> name;
if (!propertyNames->Get(context, i).ToLocal(&name))
return Response::InternalError();
// FIXME(yurys): v8::Object should support GetOwnPropertyNames
if (name->IsString()) {
v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty(
context, v8::Local<v8::String>::Cast(name));
if (hasRealNamedProperty.IsNothing() ||
!hasRealNamedProperty.FromJust())
continue;
}
v8::Local<v8::String> propertyName;
if (!name->ToString(context).ToLocal(&propertyName)) continue;
v8::Local<v8::Value> property;
if (!object->Get(context, name).ToLocal(&property))
return Response::InternalError();
if (property->IsUndefined()) continue;
std::unique_ptr<protocol::Value> propertyValue;
Response response =
toProtocolValue(context, property, maxDepth, &propertyValue);
if (!response.isSuccess()) return response;
jsonObject->setValue(
toProtocolString(context->GetIsolate(), propertyName),
std::move(propertyValue));
}
*result = std::move(jsonObject);
return Response::OK();
}
return Response::Error("Object couldn't be returned by value");
}
} // namespace
v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context,
v8::Local<v8::Object> object,
v8::Local<v8::Name> key,
......@@ -122,11 +26,4 @@ v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context,
v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
return array->CreateDataProperty(context, index, value);
}
protocol::Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value,
std::unique_ptr<protocol::Value>* result) {
return toProtocolValue(context, value, 1000, result);
}
} // namespace v8_inspector
......@@ -18,9 +18,6 @@ v8::Maybe<bool> createDataProperty(v8::Local<v8::Context>,
v8::Maybe<bool> createDataProperty(v8::Local<v8::Context>, v8::Local<v8::Array>,
int index, v8::Local<v8::Value>);
protocol::Response toProtocolValue(v8::Local<v8::Context>, v8::Local<v8::Value>,
std::unique_ptr<protocol::Value>* result);
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8_VALUE_UTILS_H_
This diff is collapsed.
// Copyright 2018 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.
#ifndef V8_INSPECTOR_VALUE_MIRROR_H_
#define V8_INSPECTOR_VALUE_MIRROR_H_
#include <memory>
#include "src/base/macros.h"
#include "src/inspector/protocol/Protocol.h"
#include "src/inspector/protocol/Runtime.h"
#include "src/inspector/string-16.h"
#include "include/v8-inspector.h"
#include "include/v8.h"
namespace v8_inspector {
class ValueMirror;
enum class WrapMode;
struct InternalPropertyMirror {
String16 name;
std::unique_ptr<ValueMirror> value;
};
struct PropertyMirror {
String16 name;
bool writable;
bool configurable;
bool enumerable;
bool isOwn;
bool isIndex;
std::unique_ptr<ValueMirror> value;
std::unique_ptr<ValueMirror> getter;
std::unique_ptr<ValueMirror> setter;
std::unique_ptr<ValueMirror> symbol;
std::unique_ptr<ValueMirror> exception;
};
class ValueMirror {
public:
virtual ~ValueMirror();
static std::unique_ptr<ValueMirror> create(v8::Local<v8::Context> context,
v8::Local<v8::Value> value);
virtual protocol::Response buildRemoteObject(
v8::Local<v8::Context> context, WrapMode mode,
std::unique_ptr<protocol::Runtime::RemoteObject>* result) = 0;
virtual void buildPropertyPreview(
v8::Local<v8::Context> context, const String16& name,
std::unique_ptr<protocol::Runtime::PropertyPreview>*) {}
virtual void buildObjectPreview(
v8::Local<v8::Context> context, bool generatePreviewForProperties,
int* nameLimit, int* indexLimit,
std::unique_ptr<protocol::Runtime::ObjectPreview>*) {}
virtual void buildEntryPreview(
v8::Local<v8::Context> context, bool generatePreviewForProperties,
int* nameLimit, int* indexLimit,
std::unique_ptr<protocol::Runtime::ObjectPreview>*) {}
virtual v8::Local<v8::Value> v8Value() = 0;
class PropertyAccumulator {
public:
virtual ~PropertyAccumulator() = default;
virtual bool Add(PropertyMirror mirror) = 0;
};
static bool getProperties(v8::Local<v8::Context> context,
v8::Local<v8::Object> object, bool ownProperties,
bool accessorPropertiesOnly,
PropertyAccumulator* accumulator);
static void getInternalProperties(
v8::Local<v8::Context> context, v8::Local<v8::Object> object,
std::vector<InternalPropertyMirror>* mirrors);
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_VALUE_MIRROR_H_
......@@ -44,7 +44,6 @@ v8_executable("inspector-test") {
"sessions/",
"testcfg.py",
"type-profiler/",
"../../src/inspector/injected-script-source.js",
]
cflags = []
......
......@@ -26,18 +26,7 @@ expression: Object(Symbol(42))
{
name : [[PrimitiveValue]]
type : symbol
valuePreview : {
description : Symbol
overflow : false
properties : [
[0] : {
name : description
type : string
value : 42
}
]
type : object
}
value : Symbol(42)
}
expression: Object(BigInt(2))
......
Tests that stepping ignores injected script
InjectedSciptSource was not reached
// 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests that stepping ignores injected script');
Protocol.Debugger.onPaused(message => {
let url = session._scriptMap.get(message.params.callFrames[0].location.scriptId).url;
if (url !== 'test.js') {
InspectorTest.log('InjectedSciptSource on stack.');
InspectorTest.completeTest();
}
Protocol.Debugger.stepInto();
});
session.setupScriptMap();
Protocol.Debugger.enable();
Protocol.Debugger.pause();
Protocol.Runtime.evaluate({expression: 'console.log(42)//# sourceURL=test.js'})
.then(() => InspectorTest.log('InjectedSciptSource was not reached'))
.then(InspectorTest.completeTest);
Tests that stepping does not ignore injected script when passed a flag
InjectedSciptSource on stack.
// 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.
// Flags: --expose-inspector-scripts
let {session, contextGroup, Protocol} = InspectorTest.start('Tests that stepping does not ignore injected script when passed a flag');
Protocol.Debugger.onPaused(message => {
let url = session._scriptMap.get(message.params.callFrames[0].location.scriptId).url;
if (url !== 'test.js') {
InspectorTest.log('InjectedSciptSource on stack.');
InspectorTest.completeTest();
}
Protocol.Debugger.stepInto();
});
session.setupScriptMap();
Protocol.Debugger.enable();
Protocol.Debugger.pause();
Protocol.Runtime.evaluate({expression: 'console.log(42)//# sourceURL=test.js'})
.then(() => InspectorTest.log('InjectedSciptSource was not reached'))
.then(InspectorTest.completeTest);
......@@ -17,8 +17,6 @@
##############################################################################
['system == android', {
# https://crbug.com/v8/8160
'debugger/stepping-with-exposed-injected-script': [FAIL],
# https://crbug.com/v8/8197
'debugger/get-possible-breakpoints-class-fields': [SKIP],
}], # 'system == android'
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment