1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef V8_INSPECTOR_INJECTED_SCRIPT_H_ 32 #define V8_INSPECTOR_INJECTED_SCRIPT_H_ 33 34 #include <memory> 35 #include <unordered_map> 36 #include <unordered_set> 37 38 #include "include/v8-exception.h" 39 #include "include/v8-local-handle.h" 40 #include "include/v8-persistent-handle.h" 41 #include "src/base/macros.h" 42 #include "src/inspector/inspected-context.h" 43 #include "src/inspector/protocol/Forward.h" 44 #include "src/inspector/protocol/Runtime.h" 45 #include "src/inspector/v8-console.h" 46 #include "src/inspector/v8-debugger.h" 47 48 namespace v8_inspector { 49 50 class RemoteObjectId; 51 class V8InspectorImpl; 52 class V8InspectorSessionImpl; 53 class ValueMirror; 54 enum class WrapMode; 55 56 using protocol::Maybe; 57 using protocol::Response; 58 59 class EvaluateCallback { 60 public: 61 virtual void sendSuccess( 62 std::unique_ptr<protocol::Runtime::RemoteObject> result, 63 protocol::Maybe<protocol::Runtime::ExceptionDetails> 64 exceptionDetails) = 0; 65 virtual void sendFailure(const protocol::DispatchResponse& response) = 0; 66 virtual ~EvaluateCallback() = default; 67 }; 68 69 class InjectedScript final { 70 public: 71 InjectedScript(InspectedContext*, int sessionId); 72 ~InjectedScript(); 73 InjectedScript(const InjectedScript&) = delete; 74 InjectedScript& operator=(const InjectedScript&) = delete; 75 context()76 InspectedContext* context() const { return m_context; } 77 78 Response getProperties( 79 v8::Local<v8::Object>, const String16& groupName, bool ownProperties, 80 bool accessorPropertiesOnly, bool nonIndexedPropertiesOnly, 81 WrapMode wrapMode, 82 std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>* 83 result, 84 Maybe<protocol::Runtime::ExceptionDetails>*); 85 86 Response getInternalAndPrivateProperties( 87 v8::Local<v8::Value>, const String16& groupName, 88 bool accessorPropertiesOnly, 89 std::unique_ptr< 90 protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>* 91 internalProperties, 92 std::unique_ptr< 93 protocol::Array<protocol::Runtime::PrivatePropertyDescriptor>>* 94 privateProperties); 95 96 void releaseObject(const String16& objectId); 97 98 Response wrapObject(v8::Local<v8::Value>, const String16& groupName, 99 WrapMode wrapMode, 100 std::unique_ptr<protocol::Runtime::RemoteObject>* result); 101 Response wrapObject(v8::Local<v8::Value>, const String16& groupName, 102 WrapMode wrapMode, 103 v8::MaybeLocal<v8::Value> customPreviewConfig, 104 int maxCustomPreviewDepth, 105 std::unique_ptr<protocol::Runtime::RemoteObject>* result); 106 Response wrapObjectMirror( 107 const ValueMirror& mirror, const String16& groupName, WrapMode wrapMode, 108 v8::MaybeLocal<v8::Value> customPreviewConfig, int maxCustomPreviewDepth, 109 std::unique_ptr<protocol::Runtime::RemoteObject>* result); 110 std::unique_ptr<protocol::Runtime::RemoteObject> wrapTable( 111 v8::Local<v8::Object> table, v8::MaybeLocal<v8::Array> columns); 112 113 void addPromiseCallback(V8InspectorSessionImpl* session, 114 v8::MaybeLocal<v8::Value> value, 115 const String16& objectGroup, WrapMode wrapMode, 116 bool replMode, 117 std::unique_ptr<EvaluateCallback> callback); 118 119 Response findObject(const RemoteObjectId&, v8::Local<v8::Value>*) const; 120 String16 objectGroupName(const RemoteObjectId&) const; 121 void releaseObjectGroup(const String16&); 122 void setCustomObjectFormatterEnabled(bool); 123 Response resolveCallArgument(protocol::Runtime::CallArgument*, 124 v8::Local<v8::Value>* result); 125 126 Response createExceptionDetails( 127 const v8::TryCatch&, const String16& groupName, 128 Maybe<protocol::Runtime::ExceptionDetails>* result); 129 Response createExceptionDetails( 130 v8::Local<v8::Message> message, v8::Local<v8::Value> exception, 131 const String16& groupName, 132 Maybe<protocol::Runtime::ExceptionDetails>* result); 133 134 Response wrapEvaluateResult( 135 v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch&, 136 const String16& objectGroup, WrapMode wrapMode, 137 std::unique_ptr<protocol::Runtime::RemoteObject>* result, 138 Maybe<protocol::Runtime::ExceptionDetails>*); 139 v8::Local<v8::Value> lastEvaluationResult() const; 140 void setLastEvaluationResult(v8::Local<v8::Value> result); 141 142 class Scope { 143 public: 144 Response initialize(); 145 void installCommandLineAPI(); 146 void ignoreExceptionsAndMuteConsole(); 147 void pretendUserGesture(); 148 void allowCodeGenerationFromStrings(); context()149 v8::Local<v8::Context> context() const { return m_context; } injectedScript()150 InjectedScript* injectedScript() const { return m_injectedScript; } tryCatch()151 const v8::TryCatch& tryCatch() const { return m_tryCatch; } inspector()152 V8InspectorImpl* inspector() const { return m_inspector; } 153 154 protected: 155 explicit Scope(V8InspectorSessionImpl*); 156 virtual ~Scope(); 157 virtual Response findInjectedScript(V8InspectorSessionImpl*) = 0; 158 159 V8InspectorImpl* m_inspector; 160 InjectedScript* m_injectedScript; 161 162 private: 163 void cleanup(); 164 v8::debug::ExceptionBreakState setPauseOnExceptionsState( 165 v8::debug::ExceptionBreakState); 166 167 v8::HandleScope m_handleScope; 168 v8::TryCatch m_tryCatch; 169 v8::Local<v8::Context> m_context; 170 std::unique_ptr<V8Console::CommandLineAPIScope> m_commandLineAPIScope; 171 bool m_ignoreExceptionsAndMuteConsole; 172 v8::debug::ExceptionBreakState m_previousPauseOnExceptionsState; 173 bool m_userGesture; 174 bool m_allowEval; 175 int m_contextGroupId; 176 int m_sessionId; 177 }; 178 179 class ContextScope : public Scope, 180 public V8InspectorSession::CommandLineAPIScope { 181 public: 182 ContextScope(V8InspectorSessionImpl*, int executionContextId); 183 ~ContextScope() override; 184 ContextScope(const ContextScope&) = delete; 185 ContextScope& operator=(const ContextScope&) = delete; 186 187 private: 188 Response findInjectedScript(V8InspectorSessionImpl*) override; 189 int m_executionContextId; 190 }; 191 192 class ObjectScope : public Scope { 193 public: 194 ObjectScope(V8InspectorSessionImpl*, const String16& remoteObjectId); 195 ~ObjectScope() override; 196 ObjectScope(const ObjectScope&) = delete; 197 ObjectScope& operator=(const ObjectScope&) = delete; objectGroupName()198 const String16& objectGroupName() const { return m_objectGroupName; } object()199 v8::Local<v8::Value> object() const { return m_object; } 200 201 private: 202 Response findInjectedScript(V8InspectorSessionImpl*) override; 203 String16 m_remoteObjectId; 204 String16 m_objectGroupName; 205 v8::Local<v8::Value> m_object; 206 }; 207 208 class CallFrameScope : public Scope { 209 public: 210 CallFrameScope(V8InspectorSessionImpl*, const String16& remoteCallFrameId); 211 ~CallFrameScope() override; 212 CallFrameScope(const CallFrameScope&) = delete; 213 CallFrameScope& operator=(const CallFrameScope&) = delete; frameOrdinal()214 size_t frameOrdinal() const { return m_frameOrdinal; } 215 216 private: 217 Response findInjectedScript(V8InspectorSessionImpl*) override; 218 String16 m_remoteCallFrameId; 219 size_t m_frameOrdinal; 220 }; 221 String16 bindObject(v8::Local<v8::Value>, const String16& groupName); 222 223 private: 224 v8::Local<v8::Object> commandLineAPI(); 225 void unbindObject(int id); 226 227 static Response bindRemoteObjectIfNeeded( 228 int sessionId, v8::Local<v8::Context> context, v8::Local<v8::Value>, 229 const String16& groupName, protocol::Runtime::RemoteObject* remoteObject); 230 231 class ProtocolPromiseHandler; 232 void discardEvaluateCallbacks(); 233 std::unique_ptr<EvaluateCallback> takeEvaluateCallback( 234 EvaluateCallback* callback); 235 Response addExceptionToDetails( 236 v8::Local<v8::Value> exception, 237 protocol::Runtime::ExceptionDetails* exceptionDetails, 238 const String16& objectGroup); 239 240 InspectedContext* m_context; 241 int m_sessionId; 242 v8::Global<v8::Value> m_lastEvaluationResult; 243 v8::Global<v8::Object> m_commandLineAPI; 244 int m_lastBoundObjectId = 1; 245 std::unordered_map<int, v8::Global<v8::Value>> m_idToWrappedObject; 246 std::unordered_map<int, String16> m_idToObjectGroupName; 247 std::unordered_map<String16, std::vector<int>> m_nameToObjectGroup; 248 std::unordered_set<EvaluateCallback*> m_evaluateCallbacks; 249 bool m_customPreviewEnabled = false; 250 }; 251 252 } // namespace v8_inspector 253 254 #endif // V8_INSPECTOR_INJECTED_SCRIPT_H_ 255