Commit 130d0486 authored by dgozman's avatar dgozman Committed by Commit bot

[inspector] Initial import of v8_inspector.

Attempt #2, formatted and disabled lint for src/inspector.

BUG=chromium:635948
NOPRESUBMIT=true (for grammar check in license code)

Review-Url: https://codereview.chromium.org/2292573002
Cr-Commit-Position: refs/heads/master@{#39107}
parent 3b8ad45e
......@@ -63,6 +63,7 @@ Felix Geisendörfer <haimuiba@gmail.com>
Filipe David Manana <fdmanana@gmail.com>
Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Geoffrey Garside <ggarside@gmail.com>
Gwang Yoon Hwang <ryumiel@company100.net>
Han Choongwoo <cwhan.tunz@gmail.com>
Hirofumi Mako <mkhrfm@gmail.com>
Honggyu Kim <honggyu.kp@gmail.com>
......@@ -95,9 +96,11 @@ Mike Pennisi <mike@mikepennisi.com>
Milton Chiang <milton.chiang@mediatek.com>
Myeong-bo Shim <m0609.shim@samsung.com>
Nicolas Antonius Ernst Leopold Maria Kaiser <nikai@nikai.net>
Noj Vek <nojvek@gmail.com>
Oleksandr Chekhovskyi <oleksandr.chekhovskyi@gmail.com>
Paolo Giarrusso <p.giarrusso@gmail.com>
Patrick Gansterer <paroga@paroga.com>
Peter Rybin <peter.rybin@gmail.com>
Peter Varga <pvarga@inf.u-szeged.hu>
Paul Lind <plind44@gmail.com>
Rafal Krypa <rafal@krypa.net>
......
// 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_ALLOCATOR_H_
#define V8_INSPECTOR_ALLOCATOR_H_
#include <cstddef>
#include <cstdint>
enum NotNullTagEnum { NotNullLiteral };
#define V8_INSPECTOR_DISALLOW_NEW() \
private: \
void* operator new(size_t) = delete; \
void* operator new(size_t, NotNullTagEnum, void*) = delete; \
void* operator new(size_t, void*) = delete; \
\
public:
#define V8_INSPECTOR_DISALLOW_COPY(ClassName) \
private: \
ClassName(const ClassName&) = delete; \
ClassName& operator=(const ClassName&) = delete
// Macro that returns a compile time constant with the length of an array, but
// gives an error if passed a non-array.
template <typename T, std::size_t Size>
char (&ArrayLengthHelperFunction(T (&)[Size]))[Size];
// GCC needs some help to deduce a 0 length array.
#if defined(__GNUC__)
template <typename T>
char (&ArrayLengthHelperFunction(T (&)[0]))[0];
#endif
#define V8_INSPECTOR_ARRAY_LENGTH(array) \
sizeof(::ArrayLengthHelperFunction(array))
#endif // V8_INSPECTOR_ALLOCATOR_H_
// 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_ATOMICS_H_
#define V8_INSPECTOR_ATOMICS_H_
#include <stdint.h>
#if defined(_MSC_VER)
#include <windows.h>
#endif
namespace v8_inspector {
#if defined(_MSC_VER)
inline int atomicIncrement(int volatile* addend) {
return InterlockedIncrement(reinterpret_cast<long volatile*>(addend));
}
#else
inline int atomicAdd(int volatile* addend, int increment) {
return __sync_add_and_fetch(addend, increment);
}
inline int atomicIncrement(int volatile* addend) {
return atomicAdd(addend, 1);
}
#endif
} // namespace v8_inspector
#endif // V8_INSPECTOR_ATOMICS_H_
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2012 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_INJECTEDSCRIPT_H_
#define V8_INSPECTOR_INJECTEDSCRIPT_H_
#include "src/inspector/Allocator.h"
#include "src/inspector/InjectedScriptNative.h"
#include "src/inspector/InspectedContext.h"
#include "src/inspector/V8Console.h"
#include "src/inspector/V8Debugger.h"
#include "src/inspector/protocol/Forward.h"
#include "src/inspector/protocol/Runtime.h"
#include <v8.h>
namespace v8_inspector {
class RemoteObjectId;
class V8FunctionCall;
class V8InspectorImpl;
class V8InspectorSessionImpl;
using protocol::ErrorString;
using protocol::Maybe;
class InjectedScript final {
V8_INSPECTOR_DISALLOW_COPY(InjectedScript);
public:
static std::unique_ptr<InjectedScript> create(InspectedContext*);
~InjectedScript();
InspectedContext* context() const { return m_context; }
void getProperties(
ErrorString*, v8::Local<v8::Object>, const String16& groupName,
bool ownProperties, bool accessorPropertiesOnly, bool generatePreview,
std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>*
result,
Maybe<protocol::Runtime::ExceptionDetails>*);
void releaseObject(const String16& objectId);
std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject(
ErrorString*, v8::Local<v8::Value>, const String16& groupName,
bool forceValueType = false, bool generatePreview = false) const;
bool wrapObjectProperty(ErrorString*, v8::Local<v8::Object>,
v8::Local<v8::Name> key, const String16& groupName,
bool forceValueType = false,
bool generatePreview = false) const;
bool wrapPropertyInArray(ErrorString*, v8::Local<v8::Array>,
v8::Local<v8::String> property,
const String16& groupName,
bool forceValueType = false,
bool generatePreview = false) const;
bool wrapObjectsInArray(ErrorString*, v8::Local<v8::Array>,
const String16& groupName,
bool forceValueType = false,
bool generatePreview = false) const;
std::unique_ptr<protocol::Runtime::RemoteObject> wrapTable(
v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const;
bool findObject(ErrorString*, const RemoteObjectId&,
v8::Local<v8::Value>*) const;
String16 objectGroupName(const RemoteObjectId&) const;
void releaseObjectGroup(const String16&);
void setCustomObjectFormatterEnabled(bool);
v8::MaybeLocal<v8::Value> resolveCallArgument(
ErrorString*, protocol::Runtime::CallArgument*);
std::unique_ptr<protocol::Runtime::ExceptionDetails> createExceptionDetails(
ErrorString*, const v8::TryCatch&, const String16& groupName,
bool generatePreview);
void wrapEvaluateResult(
ErrorString*, v8::MaybeLocal<v8::Value> maybeResultValue,
const v8::TryCatch&, const String16& objectGroup, bool returnByValue,
bool generatePreview,
std::unique_ptr<protocol::Runtime::RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>*);
v8::Local<v8::Value> lastEvaluationResult() const;
class Scope {
public:
bool initialize();
bool installCommandLineAPI();
void ignoreExceptionsAndMuteConsole();
void pretendUserGesture();
v8::Local<v8::Context> context() const { return m_context; }
InjectedScript* injectedScript() const { return m_injectedScript; }
const v8::TryCatch& tryCatch() const { return m_tryCatch; }
protected:
Scope(ErrorString*, V8InspectorImpl*, int contextGroupId);
~Scope();
virtual void findInjectedScript(V8InspectorSessionImpl*) = 0;
ErrorString* m_errorString;
V8InspectorImpl* m_inspector;
int m_contextGroupId;
InjectedScript* m_injectedScript;
private:
void cleanup();
V8Debugger::PauseOnExceptionsState setPauseOnExceptionsState(
V8Debugger::PauseOnExceptionsState);
v8::HandleScope m_handleScope;
v8::TryCatch m_tryCatch;
v8::Local<v8::Context> m_context;
std::unique_ptr<V8Console::CommandLineAPIScope> m_commandLineAPIScope;
bool m_ignoreExceptionsAndMuteConsole;
V8Debugger::PauseOnExceptionsState m_previousPauseOnExceptionsState;
bool m_userGesture;
};
class ContextScope : public Scope {
V8_INSPECTOR_DISALLOW_COPY(ContextScope);
public:
ContextScope(ErrorString*, V8InspectorImpl*, int contextGroupId,
int executionContextId);
~ContextScope();
private:
void findInjectedScript(V8InspectorSessionImpl*) override;
int m_executionContextId;
};
class ObjectScope : public Scope {
V8_INSPECTOR_DISALLOW_COPY(ObjectScope);
public:
ObjectScope(ErrorString*, V8InspectorImpl*, int contextGroupId,
const String16& remoteObjectId);
~ObjectScope();
const String16& objectGroupName() const { return m_objectGroupName; }
v8::Local<v8::Value> object() const { return m_object; }
private:
void findInjectedScript(V8InspectorSessionImpl*) override;
String16 m_remoteObjectId;
String16 m_objectGroupName;
v8::Local<v8::Value> m_object;
};
class CallFrameScope : public Scope {
V8_INSPECTOR_DISALLOW_COPY(CallFrameScope);
public:
CallFrameScope(ErrorString*, V8InspectorImpl*, int contextGroupId,
const String16& remoteCallFrameId);
~CallFrameScope();
size_t frameOrdinal() const { return m_frameOrdinal; }
private:
void findInjectedScript(V8InspectorSessionImpl*) override;
String16 m_remoteCallFrameId;
size_t m_frameOrdinal;
};
private:
InjectedScript(InspectedContext*, v8::Local<v8::Object>,
std::unique_ptr<InjectedScriptNative>);
v8::Local<v8::Value> v8Value() const;
v8::MaybeLocal<v8::Value> wrapValue(ErrorString*, v8::Local<v8::Value>,
const String16& groupName,
bool forceValueType,
bool generatePreview) const;
v8::Local<v8::Object> commandLineAPI();
InspectedContext* m_context;
v8::Global<v8::Value> m_value;
v8::Global<v8::Value> m_lastEvaluationResult;
std::unique_ptr<InjectedScriptNative> m_native;
v8::Global<v8::Object> m_commandLineAPI;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_INJECTEDSCRIPT_H_
// 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.
#include "src/inspector/InjectedScriptNative.h"
namespace v8_inspector {
InjectedScriptNative::InjectedScriptNative(v8::Isolate* isolate)
: m_lastBoundObjectId(1), m_isolate(isolate) {}
static const char privateKeyName[] = "v8-inspector#injectedScript";
InjectedScriptNative::~InjectedScriptNative() {}
void InjectedScriptNative::setOnInjectedScriptHost(
v8::Local<v8::Object> injectedScriptHost) {
v8::HandleScope handleScope(m_isolate);
v8::Local<v8::External> external = v8::External::New(m_isolate, this);
v8::Local<v8::Private> privateKey = v8::Private::ForApi(
m_isolate, v8::String::NewFromUtf8(m_isolate, privateKeyName,
v8::NewStringType::kInternalized)
.ToLocalChecked());
injectedScriptHost->SetPrivate(m_isolate->GetCurrentContext(), privateKey,
external);
}
InjectedScriptNative* InjectedScriptNative::fromInjectedScriptHost(
v8::Local<v8::Object> injectedScriptObject) {
v8::Isolate* isolate = injectedScriptObject->GetIsolate();
v8::HandleScope handleScope(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::Private> privateKey = v8::Private::ForApi(
isolate, v8::String::NewFromUtf8(isolate, privateKeyName,
v8::NewStringType::kInternalized)
.ToLocalChecked());
v8::Local<v8::Value> value =
injectedScriptObject->GetPrivate(context, privateKey).ToLocalChecked();
DCHECK(value->IsExternal());
v8::Local<v8::External> external = value.As<v8::External>();
return static_cast<InjectedScriptNative*>(external->Value());
}
int InjectedScriptNative::bind(v8::Local<v8::Value> value,
const String16& groupName) {
if (m_lastBoundObjectId <= 0) m_lastBoundObjectId = 1;
int id = m_lastBoundObjectId++;
m_idToWrappedObject[id] =
wrapUnique(new v8::Global<v8::Value>(m_isolate, value));
addObjectToGroup(id, groupName);
return id;
}
void InjectedScriptNative::unbind(int id) {
m_idToWrappedObject.erase(id);
m_idToObjectGroupName.erase(id);
}
v8::Local<v8::Value> InjectedScriptNative::objectForId(int id) {
auto iter = m_idToWrappedObject.find(id);
return iter != m_idToWrappedObject.end() ? iter->second->Get(m_isolate)
: v8::Local<v8::Value>();
}
void InjectedScriptNative::addObjectToGroup(int objectId,
const String16& groupName) {
if (groupName.isEmpty()) return;
if (objectId <= 0) return;
m_idToObjectGroupName[objectId] = groupName;
m_nameToObjectGroup[groupName].push_back(
objectId); // Creates an empty vector if key is not there
}
void InjectedScriptNative::releaseObjectGroup(const String16& groupName) {
if (groupName.isEmpty()) return;
NameToObjectGroup::iterator groupIt = m_nameToObjectGroup.find(groupName);
if (groupIt == m_nameToObjectGroup.end()) return;
for (int id : groupIt->second) unbind(id);
m_nameToObjectGroup.erase(groupIt);
}
String16 InjectedScriptNative::groupName(int objectId) const {
if (objectId <= 0) return String16();
IdToObjectGroupName::const_iterator iterator =
m_idToObjectGroupName.find(objectId);
return iterator != m_idToObjectGroupName.end() ? iterator->second
: String16();
}
} // namespace v8_inspector
// 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_INJECTEDSCRIPTNATIVE_H_
#define V8_INSPECTOR_INJECTEDSCRIPTNATIVE_H_
#include "src/inspector/protocol/Protocol.h"
#include <v8.h>
#include <vector>
namespace v8_inspector {
class InjectedScriptNative final {
public:
explicit InjectedScriptNative(v8::Isolate*);
~InjectedScriptNative();
void setOnInjectedScriptHost(v8::Local<v8::Object>);
static InjectedScriptNative* fromInjectedScriptHost(v8::Local<v8::Object>);
int bind(v8::Local<v8::Value>, const String16& groupName);
void unbind(int id);
v8::Local<v8::Value> objectForId(int id);
void releaseObjectGroup(const String16& groupName);
String16 groupName(int objectId) const;
private:
void addObjectToGroup(int objectId, const String16& groupName);
int m_lastBoundObjectId;
v8::Isolate* m_isolate;
protocol::HashMap<int, std::unique_ptr<v8::Global<v8::Value>>>
m_idToWrappedObject;
typedef protocol::HashMap<int, String16> IdToObjectGroupName;
IdToObjectGroupName m_idToObjectGroupName;
typedef protocol::HashMap<String16, std::vector<int>> NameToObjectGroup;
NameToObjectGroup m_nameToObjectGroup;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_INJECTEDSCRIPTNATIVE_H_
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.
#include "src/inspector/InspectedContext.h"
#include "src/inspector/InjectedScript.h"
#include "src/inspector/StringUtil.h"
#include "src/inspector/V8Console.h"
#include "src/inspector/V8InspectorImpl.h"
#include "src/inspector/V8ValueCopier.h"
#include "src/inspector/public/V8ContextInfo.h"
#include "src/inspector/public/V8InspectorClient.h"
namespace v8_inspector {
void InspectedContext::weakCallback(
const v8::WeakCallbackInfo<InspectedContext>& data) {
InspectedContext* context = data.GetParameter();
if (!context->m_context.IsEmpty()) {
context->m_context.Reset();
data.SetSecondPassCallback(&InspectedContext::weakCallback);
} else {
context->m_inspector->discardInspectedContext(context->m_contextGroupId,
context->m_contextId);
}
}
void InspectedContext::consoleWeakCallback(
const v8::WeakCallbackInfo<InspectedContext>& data) {
data.GetParameter()->m_console.Reset();
}
InspectedContext::InspectedContext(V8InspectorImpl* inspector,
const V8ContextInfo& info, int contextId)
: m_inspector(inspector),
m_context(info.context->GetIsolate(), info.context),
m_contextId(contextId),
m_contextGroupId(info.contextGroupId),
m_origin(toString16(info.origin)),
m_humanReadableName(toString16(info.humanReadableName)),
m_auxData(toString16(info.auxData)),
m_reported(false) {
m_context.SetWeak(this, &InspectedContext::weakCallback,
v8::WeakCallbackType::kParameter);
v8::Isolate* isolate = m_inspector->isolate();
v8::Local<v8::Object> global = info.context->Global();
v8::Local<v8::Object> console =
V8Console::createConsole(this, info.hasMemoryOnConsole);
if (!global
->Set(info.context, toV8StringInternalized(isolate, "console"),
console)
.FromMaybe(false))
return;
m_console.Reset(isolate, console);
m_console.SetWeak(this, &InspectedContext::consoleWeakCallback,
v8::WeakCallbackType::kParameter);
}
InspectedContext::~InspectedContext() {
if (!m_context.IsEmpty() && !m_console.IsEmpty()) {
v8::HandleScope scope(isolate());
V8Console::clearInspectedContextIfNeeded(context(),
m_console.Get(isolate()));
}
}
v8::Local<v8::Context> InspectedContext::context() const {
return m_context.Get(isolate());
}
v8::Isolate* InspectedContext::isolate() const {
return m_inspector->isolate();
}
void InspectedContext::createInjectedScript() {
DCHECK(!m_injectedScript);
m_injectedScript = InjectedScript::create(this);
}
void InspectedContext::discardInjectedScript() { m_injectedScript.reset(); }
} // 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_INSPECTEDCONTEXT_H_
#define V8_INSPECTOR_INSPECTEDCONTEXT_H_
#include "src/inspector/Allocator.h"
#include "src/inspector/String16.h"
#include <v8.h>
namespace v8_inspector {
class InjectedScript;
class InjectedScriptHost;
class V8ContextInfo;
class V8InspectorImpl;
class InspectedContext {
V8_INSPECTOR_DISALLOW_COPY(InspectedContext);
public:
~InspectedContext();
v8::Local<v8::Context> context() const;
int contextId() const { return m_contextId; }
int contextGroupId() const { return m_contextGroupId; }
String16 origin() const { return m_origin; }
String16 humanReadableName() const { return m_humanReadableName; }
String16 auxData() const { return m_auxData; }
bool isReported() const { return m_reported; }
void setReported(bool reported) { m_reported = reported; }
v8::Isolate* isolate() const;
V8InspectorImpl* inspector() const { return m_inspector; }
InjectedScript* getInjectedScript() { return m_injectedScript.get(); }
void createInjectedScript();
void discardInjectedScript();
private:
friend class V8InspectorImpl;
InspectedContext(V8InspectorImpl*, const V8ContextInfo&, int contextId);
static void weakCallback(const v8::WeakCallbackInfo<InspectedContext>&);
static void consoleWeakCallback(
const v8::WeakCallbackInfo<InspectedContext>&);
V8InspectorImpl* m_inspector;
v8::Global<v8::Context> m_context;
int m_contextId;
int m_contextGroupId;
const String16 m_origin;
const String16 m_humanReadableName;
const String16 m_auxData;
bool m_reported;
std::unique_ptr<InjectedScript> m_injectedScript;
v8::Global<v8::Object> m_console;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_INSPECTEDCONTEXT_H_
/*
* Copyright (c) 2010, 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/JavaScriptCallFrame.h"
#include "src/inspector/StringUtil.h"
#include "src/inspector/V8Compat.h"
#include <v8-debug.h>
namespace v8_inspector {
JavaScriptCallFrame::JavaScriptCallFrame(v8::Local<v8::Context> debuggerContext,
v8::Local<v8::Object> callFrame)
: m_isolate(debuggerContext->GetIsolate()),
m_debuggerContext(m_isolate, debuggerContext),
m_callFrame(m_isolate, callFrame) {}
JavaScriptCallFrame::~JavaScriptCallFrame() {}
int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const {
v8::HandleScope handleScope(m_isolate);
v8::MicrotasksScope microtasks(m_isolate,
v8::MicrotasksScope::kDoNotRunMicrotasks);
v8::Local<v8::Context> context =
v8::Local<v8::Context>::New(m_isolate, m_debuggerContext);
v8::Local<v8::Object> callFrame =
v8::Local<v8::Object>::New(m_isolate, m_callFrame);
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(
callFrame->Get(toV8StringInternalized(m_isolate, name)));
v8::Local<v8::Value> result;
if (!func->Call(context, callFrame, 0, nullptr).ToLocal(&result) ||
!result->IsInt32())
return 0;
return result.As<v8::Int32>()->Value();
}
int JavaScriptCallFrame::sourceID() const {
return callV8FunctionReturnInt("sourceID");
}
int JavaScriptCallFrame::line() const {
return callV8FunctionReturnInt("line");
}
int JavaScriptCallFrame::column() const {
return callV8FunctionReturnInt("column");
}
int JavaScriptCallFrame::contextId() const {
return callV8FunctionReturnInt("contextId");
}
bool JavaScriptCallFrame::isAtReturn() const {
v8::HandleScope handleScope(m_isolate);
v8::Local<v8::Value> result =
v8::Local<v8::Object>::New(m_isolate, m_callFrame)
->Get(toV8StringInternalized(m_isolate, "isAtReturn"));
if (result.IsEmpty() || !result->IsBoolean()) return false;
return result->BooleanValue();
}
v8::Local<v8::Object> JavaScriptCallFrame::details() const {
v8::MicrotasksScope microtasks(m_isolate,
v8::MicrotasksScope::kDoNotRunMicrotasks);
v8::Local<v8::Object> callFrame =
v8::Local<v8::Object>::New(m_isolate, m_callFrame);
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(
callFrame->Get(toV8StringInternalized(m_isolate, "details")));
return v8::Local<v8::Object>::Cast(
func->Call(m_debuggerContext.Get(m_isolate), callFrame, 0, nullptr)
.ToLocalChecked());
}
v8::MaybeLocal<v8::Value> JavaScriptCallFrame::evaluate(
v8::Local<v8::Value> expression) {
v8::MicrotasksScope microtasks(m_isolate,
v8::MicrotasksScope::kRunMicrotasks);
v8::Local<v8::Object> callFrame =
v8::Local<v8::Object>::New(m_isolate, m_callFrame);
v8::Local<v8::Function> evalFunction = v8::Local<v8::Function>::Cast(
callFrame->Get(toV8StringInternalized(m_isolate, "evaluate")));
return evalFunction->Call(m_debuggerContext.Get(m_isolate), callFrame, 1,
&expression);
}
v8::MaybeLocal<v8::Value> JavaScriptCallFrame::restart() {
v8::MicrotasksScope microtasks(m_isolate,
v8::MicrotasksScope::kDoNotRunMicrotasks);
v8::Local<v8::Object> callFrame =
v8::Local<v8::Object>::New(m_isolate, m_callFrame);
v8::Local<v8::Function> restartFunction = v8::Local<v8::Function>::Cast(
callFrame->Get(toV8StringInternalized(m_isolate, "restart")));
v8::Debug::SetLiveEditEnabled(m_isolate, true);
v8::MaybeLocal<v8::Value> result = restartFunction->Call(
m_debuggerContext.Get(m_isolate), callFrame, 0, nullptr);
v8::Debug::SetLiveEditEnabled(m_isolate, false);
return result;
}
v8::MaybeLocal<v8::Value> JavaScriptCallFrame::setVariableValue(
int scopeNumber, v8::Local<v8::Value> variableName,
v8::Local<v8::Value> newValue) {
v8::MicrotasksScope microtasks(m_isolate,
v8::MicrotasksScope::kDoNotRunMicrotasks);
v8::Local<v8::Object> callFrame =
v8::Local<v8::Object>::New(m_isolate, m_callFrame);
v8::Local<v8::Function> setVariableValueFunction =
v8::Local<v8::Function>::Cast(callFrame->Get(
toV8StringInternalized(m_isolate, "setVariableValue")));
v8::Local<v8::Value> argv[] = {
v8::Local<v8::Value>(v8::Integer::New(m_isolate, scopeNumber)),
variableName, newValue};
return setVariableValueFunction->Call(m_debuggerContext.Get(m_isolate),
callFrame,
V8_INSPECTOR_ARRAY_LENGTH(argv), argv);
}
} // namespace v8_inspector
/*
* Copyright (c) 2010, 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_JAVASCRIPTCALLFRAME_H_
#define V8_INSPECTOR_JAVASCRIPTCALLFRAME_H_
#include "src/inspector/Allocator.h"
#include "src/inspector/ProtocolPlatform.h"
#include <v8.h>
#include <vector>
namespace v8_inspector {
class JavaScriptCallFrame {
V8_INSPECTOR_DISALLOW_COPY(JavaScriptCallFrame);
public:
static std::unique_ptr<JavaScriptCallFrame> create(
v8::Local<v8::Context> debuggerContext, v8::Local<v8::Object> callFrame) {
return wrapUnique(new JavaScriptCallFrame(debuggerContext, callFrame));
}
~JavaScriptCallFrame();
int sourceID() const;
int line() const;
int column() const;
int contextId() const;
bool isAtReturn() const;
v8::Local<v8::Object> details() const;
v8::MaybeLocal<v8::Value> evaluate(v8::Local<v8::Value> expression);
v8::MaybeLocal<v8::Value> restart();
v8::MaybeLocal<v8::Value> setVariableValue(int scopeNumber,
v8::Local<v8::Value> variableName,
v8::Local<v8::Value> newValue);
private:
JavaScriptCallFrame(v8::Local<v8::Context> debuggerContext,
v8::Local<v8::Object> callFrame);
int callV8FunctionReturnInt(const char* name) const;
v8::Isolate* m_isolate;
v8::Global<v8::Context> m_debuggerContext;
v8::Global<v8::Object> m_callFrame;
};
using JavaScriptCallFrames = std::vector<std::unique_ptr<JavaScriptCallFrame>>;
} // namespace v8_inspector
#endif // V8_INSPECTOR_JAVASCRIPTCALLFRAME_H_
// 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_PROTOCOLPLATFORM_H_
#define V8_INSPECTOR_PROTOCOLPLATFORM_H_
// TODO(dgozman): this file should be removed from v8_inspector.
//#include "wtf/Assertions.h"
//#include "wtf/PtrUtil.h"
#include <memory>
#endif // V8_INSPECTOR_PROTOCOLPLATFORM_H_
// 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.
#include "src/inspector/RemoteObjectId.h"
#include "src/inspector/StringUtil.h"
#include "src/inspector/protocol/Protocol.h"
namespace v8_inspector {
RemoteObjectIdBase::RemoteObjectIdBase() : m_injectedScriptId(0) {}
std::unique_ptr<protocol::DictionaryValue>
RemoteObjectIdBase::parseInjectedScriptId(const String16& objectId) {
std::unique_ptr<protocol::Value> parsedValue = protocol::parseJSON(objectId);
if (!parsedValue || parsedValue->type() != protocol::Value::TypeObject)
return nullptr;
std::unique_ptr<protocol::DictionaryValue> parsedObjectId(
protocol::DictionaryValue::cast(parsedValue.release()));
bool success =
parsedObjectId->getInteger("injectedScriptId", &m_injectedScriptId);
if (success) return parsedObjectId;
return nullptr;
}
RemoteObjectId::RemoteObjectId() : RemoteObjectIdBase(), m_id(0) {}
std::unique_ptr<RemoteObjectId> RemoteObjectId::parse(
ErrorString* errorString, const String16& objectId) {
std::unique_ptr<RemoteObjectId> result(new RemoteObjectId());
std::unique_ptr<protocol::DictionaryValue> parsedObjectId =
result->parseInjectedScriptId(objectId);
if (!parsedObjectId) {
*errorString = "Invalid remote object id";
return nullptr;
}
bool success = parsedObjectId->getInteger("id", &result->m_id);
if (!success) {
*errorString = "Invalid remote object id";
return nullptr;
}
return result;
}
RemoteCallFrameId::RemoteCallFrameId()
: RemoteObjectIdBase(), m_frameOrdinal(0) {}
std::unique_ptr<RemoteCallFrameId> RemoteCallFrameId::parse(
ErrorString* errorString, const String16& objectId) {
std::unique_ptr<RemoteCallFrameId> result(new RemoteCallFrameId());
std::unique_ptr<protocol::DictionaryValue> parsedObjectId =
result->parseInjectedScriptId(objectId);
if (!parsedObjectId) {
*errorString = "Invalid call frame id";
return nullptr;
}
bool success = parsedObjectId->getInteger("ordinal", &result->m_frameOrdinal);
if (!success) {
*errorString = "Invalid call frame id";
return nullptr;
}
return result;
}
String16 RemoteCallFrameId::serialize(int injectedScriptId, int frameOrdinal) {
return "{\"ordinal\":" + String16::fromInteger(frameOrdinal) +
",\"injectedScriptId\":" + String16::fromInteger(injectedScriptId) +
"}";
}
} // namespace v8_inspector
// 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_REMOTEOBJECTID_H_
#define V8_INSPECTOR_REMOTEOBJECTID_H_
#include "src/inspector/protocol/Forward.h"
namespace v8_inspector {
using protocol::ErrorString;
class RemoteObjectIdBase {
public:
int contextId() const { return m_injectedScriptId; }
protected:
RemoteObjectIdBase();
~RemoteObjectIdBase() {}
std::unique_ptr<protocol::DictionaryValue> parseInjectedScriptId(
const String16&);
int m_injectedScriptId;
};
class RemoteObjectId final : public RemoteObjectIdBase {
public:
static std::unique_ptr<RemoteObjectId> parse(ErrorString*, const String16&);
~RemoteObjectId() {}
int id() const { return m_id; }
private:
RemoteObjectId();
int m_id;
};
class RemoteCallFrameId final : public RemoteObjectIdBase {
public:
static std::unique_ptr<RemoteCallFrameId> parse(ErrorString*,
const String16&);
~RemoteCallFrameId() {}
int frameOrdinal() const { return m_frameOrdinal; }
static String16 serialize(int injectedScriptId, int frameOrdinal);
private:
RemoteCallFrameId();
int m_frameOrdinal;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_REMOTEOBJECTID_H_
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* 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:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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_SCRIPTBREAKPOINT_H_
#define V8_INSPECTOR_SCRIPTBREAKPOINT_H_
#include "src/inspector/String16.h"
namespace v8_inspector {
struct ScriptBreakpoint {
ScriptBreakpoint() : ScriptBreakpoint(0, 0, String16()) {}
ScriptBreakpoint(int lineNumber, int columnNumber, const String16& condition)
: lineNumber(lineNumber),
columnNumber(columnNumber),
condition(condition) {}
int lineNumber;
int columnNumber;
String16 condition;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_SCRIPTBREAKPOINT_H_
// 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/SearchUtil.h"
#include "src/inspector/V8InspectorImpl.h"
#include "src/inspector/V8InspectorSessionImpl.h"
#include "src/inspector/V8Regex.h"
#include "src/inspector/protocol/Protocol.h"
namespace v8_inspector {
namespace {
String16 findMagicComment(const String16& content, const String16& name,
bool multiline) {
DCHECK(name.find("=") == String16::kNotFound);
unsigned length = content.length();
unsigned nameLength = name.length();
size_t pos = length;
size_t equalSignPos = 0;
size_t closingCommentPos = 0;
while (true) {
pos = content.reverseFind(name, pos);
if (pos == String16::kNotFound) return String16();
// Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name.
if (pos < 4) return String16();
pos -= 4;
if (content[pos] != '/') continue;
if ((content[pos + 1] != '/' || multiline) &&
(content[pos + 1] != '*' || !multiline))
continue;
if (content[pos + 2] != '#' && content[pos + 2] != '@') continue;
if (content[pos + 3] != ' ' && content[pos + 3] != '\t') continue;
equalSignPos = pos + 4 + nameLength;
if (equalSignPos < length && content[equalSignPos] != '=') continue;
if (multiline) {
closingCommentPos = content.find("*/", equalSignPos + 1);
if (closingCommentPos == String16::kNotFound) return String16();
}
break;
}
DCHECK(equalSignPos);
DCHECK(!multiline || closingCommentPos);
size_t urlPos = equalSignPos + 1;
String16 match = multiline
? content.substring(urlPos, closingCommentPos - urlPos)
: content.substring(urlPos);
size_t newLine = match.find("\n");
if (newLine != String16::kNotFound) match = match.substring(0, newLine);
match = match.stripWhiteSpace();
for (unsigned i = 0; i < match.length(); ++i) {
UChar c = match[i];
if (c == '"' || c == '\'' || c == ' ' || c == '\t') return "";
}
return match;
}
String16 createSearchRegexSource(const String16& text) {
String16Builder result;
for (unsigned i = 0; i < text.length(); i++) {
UChar c = text[i];
if (c == '[' || c == ']' || c == '(' || c == ')' || c == '{' || c == '}' ||
c == '+' || c == '-' || c == '*' || c == '.' || c == ',' || c == '?' ||
c == '\\' || c == '^' || c == '$' || c == '|') {
result.append('\\');
}
result.append(c);
}
return result.toString();
}
std::unique_ptr<std::vector<unsigned>> lineEndings(const String16& text) {
std::unique_ptr<std::vector<unsigned>> result(new std::vector<unsigned>());
const String16 lineEndString = "\n";
unsigned start = 0;
while (start < text.length()) {
size_t lineEnd = text.find(lineEndString, start);
if (lineEnd == String16::kNotFound) break;
result->push_back(static_cast<unsigned>(lineEnd));
start = lineEnd + 1;
}
result->push_back(static_cast<unsigned>(text.length()));
return result;
}
std::vector<std::pair<int, String16>> scriptRegexpMatchesByLines(
const V8Regex& regex, const String16& text) {
std::vector<std::pair<int, String16>> result;
if (text.isEmpty()) return result;
std::unique_ptr<std::vector<unsigned>> endings(lineEndings(text));
unsigned size = endings->size();
unsigned start = 0;
for (unsigned lineNumber = 0; lineNumber < size; ++lineNumber) {
unsigned lineEnd = endings->at(lineNumber);
String16 line = text.substring(start, lineEnd - start);
if (line.length() && line[line.length() - 1] == '\r')
line = line.substring(0, line.length() - 1);
int matchLength;
if (regex.match(line, 0, &matchLength) != -1)
result.push_back(std::pair<int, String16>(lineNumber, line));
start = lineEnd + 1;
}
return result;
}
std::unique_ptr<protocol::Debugger::SearchMatch> buildObjectForSearchMatch(
int lineNumber, const String16& lineContent) {
return protocol::Debugger::SearchMatch::create()
.setLineNumber(lineNumber)
.setLineContent(lineContent)
.build();
}
std::unique_ptr<V8Regex> createSearchRegex(V8InspectorImpl* inspector,
const String16& query,
bool caseSensitive, bool isRegex) {
String16 regexSource = isRegex ? query : createSearchRegexSource(query);
return wrapUnique(new V8Regex(inspector, regexSource, caseSensitive));
}
} // namespace
std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>>
searchInTextByLinesImpl(V8InspectorSession* session, const String16& text,
const String16& query, const bool caseSensitive,
const bool isRegex) {
std::unique_ptr<V8Regex> regex = createSearchRegex(
static_cast<V8InspectorSessionImpl*>(session)->inspector(), query,
caseSensitive, isRegex);
std::vector<std::pair<int, String16>> matches =
scriptRegexpMatchesByLines(*regex.get(), text);
std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> result;
for (const auto& match : matches)
result.push_back(buildObjectForSearchMatch(match.first, match.second));
return result;
}
String16 findSourceURL(const String16& content, bool multiline) {
return findMagicComment(content, "sourceURL", multiline);
}
String16 findSourceMapURL(const String16& content, bool multiline) {
return findMagicComment(content, "sourceMappingURL", multiline);
}
} // 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_SEARCHUTIL_H_
#define V8_INSPECTOR_SEARCHUTIL_H_
#include "src/inspector/StringUtil.h"
#include "src/inspector/protocol/Debugger.h"
namespace v8_inspector {
class V8InspectorSession;
String16 findSourceURL(const String16& content, bool multiline);
String16 findSourceMapURL(const String16& content, bool multiline);
std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>>
searchInTextByLinesImpl(V8InspectorSession*, const String16& text,
const String16& query, bool caseSensitive,
bool isRegex);
} // namespace v8_inspector
#endif // V8_INSPECTOR_SEARCHUTIL_H_
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.
#ifndef V8_INSPECTOR_STRING16_H_
#define V8_INSPECTOR_STRING16_H_
#include <stdint.h>
#include <cctype>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
namespace v8_inspector {
using UChar = uint16_t;
class String16 {
public:
static const size_t kNotFound = static_cast<size_t>(-1);
String16() {}
String16(const String16& other) : m_impl(other.m_impl) {}
String16(const UChar* characters, size_t size) : m_impl(characters, size) {}
String16(const UChar* characters) : m_impl(characters) {}
String16(const char* characters)
: String16(characters, std::strlen(characters)) {}
String16(const char* characters, size_t size) {
m_impl.resize(size);
for (size_t i = 0; i < size; ++i) m_impl[i] = characters[i];
}
static String16 fromInteger(int);
static String16 fromDouble(double);
static String16 fromDoublePrecision3(double);
static String16 fromDoublePrecision6(double);
int toInteger(bool* ok = nullptr) const;
String16 stripWhiteSpace() const;
const UChar* characters16() const { return m_impl.c_str(); }
size_t length() const { return m_impl.length(); }
bool isEmpty() const { return !m_impl.length(); }
UChar operator[](unsigned index) const { return m_impl[index]; }
String16 substring(unsigned pos, unsigned len = UINT_MAX) const {
return String16(m_impl.substr(pos, len));
}
size_t find(const String16& str, unsigned start = 0) const {
return m_impl.find(str.m_impl, start);
}
size_t reverseFind(const String16& str, unsigned start = UINT_MAX) const {
return m_impl.rfind(str.m_impl, start);
}
void swap(String16& other) { m_impl.swap(other.m_impl); }
// Convenience methods.
std::string utf8() const;
static String16 fromUTF8(const char* stringStart, size_t length);
const std::basic_string<UChar>& impl() const { return m_impl; }
explicit String16(const std::basic_string<UChar>& impl) : m_impl(impl) {}
std::size_t hash() const {
if (!has_hash) {
size_t hash = 0;
for (size_t i = 0; i < length(); ++i) hash = 31 * hash + m_impl[i];
hash_code = hash;
has_hash = true;
}
return hash_code;
}
private:
std::basic_string<UChar> m_impl;
mutable bool has_hash = false;
mutable std::size_t hash_code = 0;
};
inline bool operator==(const String16& a, const String16& b) {
return a.impl() == b.impl();
}
inline bool operator<(const String16& a, const String16& b) {
return a.impl() < b.impl();
}
inline bool operator!=(const String16& a, const String16& b) {
return a.impl() != b.impl();
}
inline bool operator==(const String16& a, const char* b) {
return a.impl() == String16(b).impl();
}
inline String16 operator+(const String16& a, const char* b) {
return String16(a.impl() + String16(b).impl());
}
inline String16 operator+(const char* a, const String16& b) {
return String16(String16(a).impl() + b.impl());
}
inline String16 operator+(const String16& a, const String16& b) {
return String16(a.impl() + b.impl());
}
class String16Builder {
public:
String16Builder();
void append(const String16&);
void append(UChar);
void append(char);
void append(const UChar*, size_t);
void append(const char*, size_t);
String16 toString();
void reserveCapacity(size_t);
private:
std::vector<UChar> m_buffer;
};
} // namespace v8_inspector
#if !defined(__APPLE__) || defined(_LIBCPP_VERSION)
namespace std {
template <>
struct hash<v8_inspector::String16> {
std::size_t operator()(const v8_inspector::String16& string) const {
return string.hash();
}
};
} // namespace std
#endif // !defined(__APPLE__) || defined(_LIBCPP_VERSION)
#endif // V8_INSPECTOR_STRING16_H_
// 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/StringUtil.h"
#include "src/inspector/protocol/Protocol.h"
namespace v8_inspector {
v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String16& string) {
if (string.isEmpty()) return v8::String::Empty(isolate);
return v8::String::NewFromTwoByte(
isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
v8::NewStringType::kNormal, string.length())
.ToLocalChecked();
}
v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate,
const String16& string) {
if (string.isEmpty()) return v8::String::Empty(isolate);
return v8::String::NewFromTwoByte(
isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
v8::NewStringType::kInternalized, string.length())
.ToLocalChecked();
}
v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate,
const char* str) {
return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kInternalized)
.ToLocalChecked();
}
v8::Local<v8::String> toV8String(v8::Isolate* isolate,
const StringView& string) {
if (!string.length()) return v8::String::Empty(isolate);
if (string.is8Bit())
return v8::String::NewFromOneByte(
isolate, reinterpret_cast<const uint8_t*>(string.characters8()),
v8::NewStringType::kNormal, string.length())
.ToLocalChecked();
return v8::String::NewFromTwoByte(
isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
v8::NewStringType::kNormal, string.length())
.ToLocalChecked();
}
String16 toProtocolString(v8::Local<v8::String> value) {
if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
return String16();
std::unique_ptr<UChar[]> buffer(new UChar[value->Length()]);
value->Write(reinterpret_cast<uint16_t*>(buffer.get()), 0, value->Length());
return String16(buffer.get(), value->Length());
}
String16 toProtocolStringWithTypeCheck(v8::Local<v8::Value> value) {
if (value.IsEmpty() || !value->IsString()) return String16();
return toProtocolString(value.As<v8::String>());
}
String16 toString16(const StringView& string) {
if (!string.length()) return String16();
if (string.is8Bit())
return String16(reinterpret_cast<const char*>(string.characters8()),
string.length());
return String16(reinterpret_cast<const UChar*>(string.characters16()),
string.length());
}
StringView toStringView(const String16& string) {
if (string.isEmpty()) return StringView();
return StringView(reinterpret_cast<const uint16_t*>(string.characters16()),
string.length());
}
bool stringViewStartsWith(const StringView& string, const char* prefix) {
if (!string.length()) return !(*prefix);
if (string.is8Bit()) {
for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
if (string.characters8()[i] != prefix[j]) return false;
}
} else {
for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
if (string.characters16()[i] != prefix[j]) return false;
}
}
return true;
}
namespace protocol {
std::unique_ptr<protocol::Value> parseJSON(const StringView& string) {
if (!string.length()) return nullptr;
if (string.is8Bit())
return protocol::parseJSON(string.characters8(), string.length());
return protocol::parseJSON(string.characters16(), string.length());
}
std::unique_ptr<protocol::Value> parseJSON(const String16& string) {
if (!string.length()) return nullptr;
return protocol::parseJSON(string.characters16(), string.length());
}
} // namespace protocol
std::unique_ptr<protocol::Value> toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value,
int maxDepth) {
if (value.IsEmpty()) {
NOTREACHED();
return nullptr;
}
if (!maxDepth) return nullptr;
maxDepth--;
if (value->IsNull() || value->IsUndefined()) return protocol::Value::null();
if (value->IsBoolean())
return protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value();
int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue)
return protocol::FundamentalValue::create(intValue);
return protocol::FundamentalValue::create(doubleValue);
}
if (value->IsString())
return protocol::StringValue::create(
toProtocolString(value.As<v8::String>()));
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 nullptr;
std::unique_ptr<protocol::Value> element =
toProtocolValue(context, value, maxDepth);
if (!element) return nullptr;
inspectorArray->pushValue(std::move(element));
}
return std::move(inspectorArray);
}
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 nullptr;
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 nullptr;
// 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.IsJust() || !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 nullptr;
std::unique_ptr<protocol::Value> propertyValue =
toProtocolValue(context, property, maxDepth);
if (!propertyValue) return nullptr;
jsonObject->setValue(toProtocolString(propertyName),
std::move(propertyValue));
}
return std::move(jsonObject);
}
NOTREACHED();
return nullptr;
}
// static
std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) {
String16 owner = toString16(string);
return StringBufferImpl::adopt(owner);
}
// static
std::unique_ptr<StringBufferImpl> StringBufferImpl::adopt(String16& string) {
return wrapUnique(new StringBufferImpl(string));
}
StringBufferImpl::StringBufferImpl(String16& string) {
m_owner.swap(string);
m_string = toStringView(m_owner);
}
} // 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_STRINGUTIL_H_
#define V8_INSPECTOR_STRINGUTIL_H_
#include "src/inspector/Allocator.h"
#include "src/inspector/String16.h"
#include "src/inspector/public/StringBuffer.h"
#include "src/inspector/public/StringView.h"
#include <v8.h>
namespace v8_inspector {
namespace protocol {
class Value;
using String = v8_inspector::String16;
using StringBuilder = v8_inspector::String16Builder;
class StringUtil {
public:
static String substring(const String& s, unsigned pos, unsigned len) {
return s.substring(pos, len);
}
static String fromInteger(int number) { return String::fromInteger(number); }
static String fromDouble(double number) { return String::fromDouble(number); }
static const size_t kNotFound = String::kNotFound;
static void builderReserve(StringBuilder& builder, unsigned capacity) {
builder.reserveCapacity(capacity);
}
};
std::unique_ptr<protocol::Value> parseJSON(const StringView& json);
std::unique_ptr<protocol::Value> parseJSON(const String16& json);
} // namespace protocol
std::unique_ptr<protocol::Value> toProtocolValue(v8::Local<v8::Context>,
v8::Local<v8::Value>,
int maxDepth = 1000);
v8::Local<v8::String> toV8String(v8::Isolate*, const String16&);
v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const String16&);
v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const char*);
v8::Local<v8::String> toV8String(v8::Isolate*, const StringView&);
// TODO(dgozman): rename to toString16.
String16 toProtocolString(v8::Local<v8::String>);
String16 toProtocolStringWithTypeCheck(v8::Local<v8::Value>);
String16 toString16(const StringView&);
StringView toStringView(const String16&);
bool stringViewStartsWith(const StringView&, const char*);
class StringBufferImpl : public StringBuffer {
V8_INSPECTOR_DISALLOW_COPY(StringBufferImpl);
public:
// Destroys string's content.
static std::unique_ptr<StringBufferImpl> adopt(String16&);
const StringView& string() override { return m_string; }
private:
explicit StringBufferImpl(String16&);
String16 m_owner;
StringView m_string;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_STRINGUTIL_H_
// 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_V8COMPAT_H_
#define V8_INSPECTOR_V8COMPAT_H_
#include <v8.h>
#if V8_MAJOR_VERSION < 5 || (V8_MAJOR_VERSION == 5 && V8_MINOR_VERSION < 1)
namespace v8 {
// In standalone V8 inspector this is expected to be noop anyways...
class V8_EXPORT MicrotasksScope {
public:
enum Type { kRunMicrotasks, kDoNotRunMicrotasks };
MicrotasksScope(Isolate* isolate, Type type) {
// No-op
}
};
} // namespace v8
#define V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, callback, data, length) \
v8::Function::New((context), (callback), (data), (length))
#else
#define V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, callback, data, length) \
v8::Function::New((context), (callback), (data), (length), \
v8::ConstructorBehavior::kThrow)
#endif // V8_MAJOR_VERSION < 5 || (V8_MAJOR_VERSION == 5 && V8_MINOR_VERSION <
// 1)
#endif // V8_INSPECTOR_V8COMPAT_H_
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.
#ifndef V8_INSPECTOR_V8CONSOLE_H_
#define V8_INSPECTOR_V8CONSOLE_H_
#include "src/inspector/Allocator.h"
#include <v8.h>
namespace v8_inspector {
class InspectedContext;
// Console API
// https://console.spec.whatwg.org/#console-interface
class V8Console {
public:
static v8::Local<v8::Object> createConsole(InspectedContext*,
bool hasMemoryAttribute);
static void clearInspectedContextIfNeeded(v8::Local<v8::Context>,
v8::Local<v8::Object> console);
static v8::Local<v8::Object> createCommandLineAPI(InspectedContext*);
class CommandLineAPIScope {
V8_INSPECTOR_DISALLOW_COPY(CommandLineAPIScope);
public:
CommandLineAPIScope(v8::Local<v8::Context>,
v8::Local<v8::Object> commandLineAPI,
v8::Local<v8::Object> global);
~CommandLineAPIScope();
private:
static void accessorGetterCallback(
v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&);
static void accessorSetterCallback(v8::Local<v8::Name>,
v8::Local<v8::Value>,
const v8::PropertyCallbackInfo<void>&);
v8::Local<v8::Context> m_context;
v8::Local<v8::Object> m_commandLineAPI;
v8::Local<v8::Object> m_global;
v8::Local<v8::Set> m_installedMethods;
bool m_cleanup;
};
private:
static void debugCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void errorCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void infoCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void logCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void warnCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void dirCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void dirxmlCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void tableCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void traceCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void groupCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void groupCollapsedCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void groupEndCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void clearCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void countCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void assertCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void markTimelineCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void profileCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void profileEndCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void timelineCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void timelineEndCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void timeCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void timeEndCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void timeStampCallback(const v8::FunctionCallbackInfo<v8::Value>&);
// TODO(foolip): There is no spec for the Memory Info API, see blink-dev:
// https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ
static void memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void memorySetterCallback(const v8::FunctionCallbackInfo<v8::Value>&);
// CommandLineAPI
static void keysCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void valuesCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void debugFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void undebugFunctionCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void monitorFunctionCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void unmonitorFunctionCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void lastEvaluationResultCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void inspectCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void copyCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void inspectedObject(const v8::FunctionCallbackInfo<v8::Value>&,
unsigned num);
static void inspectedObject0(
const v8::FunctionCallbackInfo<v8::Value>& info) {
inspectedObject(info, 0);
}
static void inspectedObject1(
const v8::FunctionCallbackInfo<v8::Value>& info) {
inspectedObject(info, 1);
}
static void inspectedObject2(
const v8::FunctionCallbackInfo<v8::Value>& info) {
inspectedObject(info, 2);
}
static void inspectedObject3(
const v8::FunctionCallbackInfo<v8::Value>& info) {
inspectedObject(info, 3);
}
static void inspectedObject4(
const v8::FunctionCallbackInfo<v8::Value>& info) {
inspectedObject(info, 4);
}
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8CONSOLE_H_
// 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/V8ConsoleAgentImpl.h"
#include "src/inspector/V8ConsoleMessage.h"
#include "src/inspector/V8InspectorImpl.h"
#include "src/inspector/V8InspectorSessionImpl.h"
#include "src/inspector/V8StackTraceImpl.h"
#include "src/inspector/protocol/Protocol.h"
namespace v8_inspector {
namespace ConsoleAgentState {
static const char consoleEnabled[] = "consoleEnabled";
}
V8ConsoleAgentImpl::V8ConsoleAgentImpl(
V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel,
protocol::DictionaryValue* state)
: m_session(session),
m_state(state),
m_frontend(frontendChannel),
m_enabled(false) {}
V8ConsoleAgentImpl::~V8ConsoleAgentImpl() {}
void V8ConsoleAgentImpl::enable(ErrorString* errorString) {
if (m_enabled) return;
m_state->setBoolean(ConsoleAgentState::consoleEnabled, true);
m_enabled = true;
m_session->inspector()->enableStackCapturingIfNeeded();
reportAllMessages();
}
void V8ConsoleAgentImpl::disable(ErrorString* errorString) {
if (!m_enabled) return;
m_session->inspector()->disableStackCapturingIfNeeded();
m_state->setBoolean(ConsoleAgentState::consoleEnabled, false);
m_enabled = false;
}
void V8ConsoleAgentImpl::clearMessages(ErrorString* errorString) {}
void V8ConsoleAgentImpl::restore() {
if (!m_state->booleanProperty(ConsoleAgentState::consoleEnabled, false))
return;
ErrorString ignored;
enable(&ignored);
}
void V8ConsoleAgentImpl::messageAdded(V8ConsoleMessage* message) {
if (m_enabled) reportMessage(message, true);
}
bool V8ConsoleAgentImpl::enabled() { return m_enabled; }
void V8ConsoleAgentImpl::reportAllMessages() {
V8ConsoleMessageStorage* storage =
m_session->inspector()->ensureConsoleMessageStorage(
m_session->contextGroupId());
for (const auto& message : storage->messages()) {
if (message->origin() == V8MessageOrigin::kConsole)
reportMessage(message.get(), false);
}
}
void V8ConsoleAgentImpl::reportMessage(V8ConsoleMessage* message,
bool generatePreview) {
DCHECK(message->origin() == V8MessageOrigin::kConsole);
message->reportToFrontend(&m_frontend);
m_frontend.flush();
}
} // 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_V8CONSOLEAGENTIMPL_H_
#define V8_INSPECTOR_V8CONSOLEAGENTIMPL_H_
#include "src/inspector/Allocator.h"
#include "src/inspector/protocol/Console.h"
#include "src/inspector/protocol/Forward.h"
namespace v8_inspector {
class V8ConsoleMessage;
class V8InspectorSessionImpl;
using protocol::ErrorString;
class V8ConsoleAgentImpl : public protocol::Console::Backend {
V8_INSPECTOR_DISALLOW_COPY(V8ConsoleAgentImpl);
public:
V8ConsoleAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*,
protocol::DictionaryValue* state);
~V8ConsoleAgentImpl() override;
void enable(ErrorString*) override;
void disable(ErrorString*) override;
void clearMessages(ErrorString*) override;
void restore();
void messageAdded(V8ConsoleMessage*);
void reset();
bool enabled();
private:
void reportAllMessages();
void reportMessage(V8ConsoleMessage*, bool generatePreview);
V8InspectorSessionImpl* m_session;
protocol::DictionaryValue* m_state;
protocol::Console::Frontend m_frontend;
bool m_enabled;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8CONSOLEAGENTIMPL_H_
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.
#ifndef V8_INSPECTOR_V8CONSOLEMESSAGE_H_
#define V8_INSPECTOR_V8CONSOLEMESSAGE_H_
#include <v8.h>
#include <deque>
#include "src/inspector/protocol/Console.h"
#include "src/inspector/protocol/Forward.h"
#include "src/inspector/protocol/Runtime.h"
namespace v8_inspector {
class InspectedContext;
class V8InspectorImpl;
class V8InspectorSessionImpl;
class V8StackTraceImpl;
enum class V8MessageOrigin { kConsole, kException, kRevokedException };
enum class ConsoleAPIType {
kLog,
kDebug,
kInfo,
kError,
kWarning,
kDir,
kDirXML,
kTable,
kTrace,
kStartGroup,
kStartGroupCollapsed,
kEndGroup,
kClear,
kAssert,
kTimeEnd,
kCount
};
class V8ConsoleMessage {
public:
~V8ConsoleMessage();
static std::unique_ptr<V8ConsoleMessage> createForConsoleAPI(
double timestamp, ConsoleAPIType,
const std::vector<v8::Local<v8::Value>>& arguments,
std::unique_ptr<V8StackTraceImpl>, InspectedContext*);
static std::unique_ptr<V8ConsoleMessage> createForException(
double timestamp, const String16& detailedMessage, const String16& url,
unsigned lineNumber, unsigned columnNumber,
std::unique_ptr<V8StackTraceImpl>, int scriptId, v8::Isolate*,
const String16& message, int contextId, v8::Local<v8::Value> exception,
unsigned exceptionId);
static std::unique_ptr<V8ConsoleMessage> createForRevokedException(
double timestamp, const String16& message, unsigned revokedExceptionId);
V8MessageOrigin origin() const;
void reportToFrontend(protocol::Console::Frontend*) const;
void reportToFrontend(protocol::Runtime::Frontend*, V8InspectorSessionImpl*,
bool generatePreview) const;
ConsoleAPIType type() const;
void contextDestroyed(int contextId);
private:
V8ConsoleMessage(V8MessageOrigin, double timestamp, const String16& message);
using Arguments = std::vector<std::unique_ptr<v8::Global<v8::Value>>>;
std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>>
wrapArguments(V8InspectorSessionImpl*, bool generatePreview) const;
std::unique_ptr<protocol::Runtime::RemoteObject> wrapException(
V8InspectorSessionImpl*, bool generatePreview) const;
void setLocation(const String16& url, unsigned lineNumber,
unsigned columnNumber, std::unique_ptr<V8StackTraceImpl>,
int scriptId);
V8MessageOrigin m_origin;
double m_timestamp;
String16 m_message;
String16 m_url;
unsigned m_lineNumber;
unsigned m_columnNumber;
std::unique_ptr<V8StackTraceImpl> m_stackTrace;
int m_scriptId;
int m_contextId;
ConsoleAPIType m_type;
unsigned m_exceptionId;
unsigned m_revokedExceptionId;
Arguments m_arguments;
String16 m_detailedMessage;
};
class V8ConsoleMessageStorage {
public:
V8ConsoleMessageStorage(V8InspectorImpl*, int contextGroupId);
~V8ConsoleMessageStorage();
int contextGroupId() { return m_contextGroupId; }
int expiredCount() { return m_expiredCount; }
const std::deque<std::unique_ptr<V8ConsoleMessage>>& messages() const {
return m_messages;
}
void addMessage(std::unique_ptr<V8ConsoleMessage>);
void contextDestroyed(int contextId);
void clear();
private:
V8InspectorImpl* m_inspector;
int m_contextGroupId;
int m_expiredCount;
std::deque<std::unique_ptr<V8ConsoleMessage>> m_messages;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8CONSOLEMESSAGE_H_
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright 2014 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/V8DebuggerScript.h"
#include "src/inspector/ProtocolPlatform.h"
#include "src/inspector/StringUtil.h"
namespace v8_inspector {
static const char hexDigits[17] = "0123456789ABCDEF";
static void appendUnsignedAsHex(unsigned number, String16Builder* destination) {
for (size_t i = 0; i < 8; ++i) {
UChar c = hexDigits[number & 0xF];
destination->append(c);
number >>= 4;
}
}
// Hash algorithm for substrings is described in "Über die Komplexität der
// Multiplikation in
// eingeschränkten Branchingprogrammmodellen" by Woelfe.
// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
static String16 calculateHash(const String16& str) {
static uint64_t prime[] = {0x3FB75161, 0xAB1F4E4F, 0x82675BC5, 0xCD924D35,
0x81ABE279};
static uint64_t random[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
0xC3D2E1F0};
static uint32_t randomOdd[] = {0xB4663807, 0xCC322BF5, 0xD4F91BBD, 0xA7BEA11D,
0x8F462907};
uint64_t hashes[] = {0, 0, 0, 0, 0};
uint64_t zi[] = {1, 1, 1, 1, 1};
const size_t hashesSize = V8_INSPECTOR_ARRAY_LENGTH(hashes);
size_t current = 0;
const uint32_t* data = nullptr;
size_t sizeInBytes = sizeof(UChar) * str.length();
data = reinterpret_cast<const uint32_t*>(str.characters16());
for (size_t i = 0; i < sizeInBytes / 4; i += 4) {
uint32_t v = data[i];
uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
zi[current] = (zi[current] * random[current]) % prime[current];
current = current == hashesSize - 1 ? 0 : current + 1;
}
if (sizeInBytes % 4) {
uint32_t v = 0;
for (size_t i = sizeInBytes - sizeInBytes % 4; i < sizeInBytes; ++i) {
v <<= 8;
v |= reinterpret_cast<const uint8_t*>(data)[i];
}
uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
zi[current] = (zi[current] * random[current]) % prime[current];
current = current == hashesSize - 1 ? 0 : current + 1;
}
for (size_t i = 0; i < hashesSize; ++i)
hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i];
String16Builder hash;
for (size_t i = 0; i < hashesSize; ++i) appendUnsignedAsHex(hashes[i], &hash);
return hash.toString();
}
V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate,
v8::Local<v8::Object> object,
bool isLiveEdit) {
v8::Local<v8::Value> idValue =
object->Get(toV8StringInternalized(isolate, "id"));
DCHECK(!idValue.IsEmpty() && idValue->IsInt32());
m_id = String16::fromInteger(idValue->Int32Value());
m_url = toProtocolStringWithTypeCheck(
object->Get(toV8StringInternalized(isolate, "name")));
m_sourceURL = toProtocolStringWithTypeCheck(
object->Get(toV8StringInternalized(isolate, "sourceURL")));
m_sourceMappingURL = toProtocolStringWithTypeCheck(
object->Get(toV8StringInternalized(isolate, "sourceMappingURL")));
m_startLine = object->Get(toV8StringInternalized(isolate, "startLine"))
->ToInteger(isolate)
->Value();
m_startColumn = object->Get(toV8StringInternalized(isolate, "startColumn"))
->ToInteger(isolate)
->Value();
m_endLine = object->Get(toV8StringInternalized(isolate, "endLine"))
->ToInteger(isolate)
->Value();
m_endColumn = object->Get(toV8StringInternalized(isolate, "endColumn"))
->ToInteger(isolate)
->Value();
m_executionContextAuxData = toProtocolStringWithTypeCheck(
object->Get(toV8StringInternalized(isolate, "executionContextAuxData")));
m_executionContextId =
object->Get(toV8StringInternalized(isolate, "executionContextId"))
->ToInteger(isolate)
->Value();
m_isLiveEdit = isLiveEdit;
v8::Local<v8::Value> sourceValue =
object->Get(toV8StringInternalized(isolate, "source"));
if (!sourceValue.IsEmpty() && sourceValue->IsString())
setSource(isolate, sourceValue.As<v8::String>());
}
V8DebuggerScript::~V8DebuggerScript() {}
const String16& V8DebuggerScript::sourceURL() const {
return m_sourceURL.isEmpty() ? m_url : m_sourceURL;
}
v8::Local<v8::String> V8DebuggerScript::source(v8::Isolate* isolate) const {
return m_source.Get(isolate);
}
void V8DebuggerScript::setSourceURL(const String16& sourceURL) {
m_sourceURL = sourceURL;
}
void V8DebuggerScript::setSourceMappingURL(const String16& sourceMappingURL) {
m_sourceMappingURL = sourceMappingURL;
}
void V8DebuggerScript::setSource(v8::Isolate* isolate,
v8::Local<v8::String> source) {
m_source.Reset(isolate, source);
m_hash = calculateHash(toProtocolString(source));
}
} // namespace v8_inspector
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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