OLD | NEW |
(Empty) | |
| 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 #include "src/inspector/InjectedScript.h" |
| 32 |
| 33 #include "src/inspector/InjectedScriptNative.h" |
| 34 #include "src/inspector/InjectedScriptSource.h" |
| 35 #include "src/inspector/InspectedContext.h" |
| 36 #include "src/inspector/RemoteObjectId.h" |
| 37 #include "src/inspector/StringUtil.h" |
| 38 #include "src/inspector/V8Compat.h" |
| 39 #include "src/inspector/V8Console.h" |
| 40 #include "src/inspector/V8FunctionCall.h" |
| 41 #include "src/inspector/V8InjectedScriptHost.h" |
| 42 #include "src/inspector/V8InspectorImpl.h" |
| 43 #include "src/inspector/V8InspectorSessionImpl.h" |
| 44 #include "src/inspector/V8StackTraceImpl.h" |
| 45 #include "src/inspector/V8ValueCopier.h" |
| 46 #include "src/inspector/protocol/Protocol.h" |
| 47 #include "src/inspector/public/V8InspectorClient.h" |
| 48 |
| 49 namespace v8_inspector { |
| 50 |
| 51 using protocol::Array; |
| 52 using protocol::Runtime::PropertyDescriptor; |
| 53 using protocol::Runtime::InternalPropertyDescriptor; |
| 54 using protocol::Runtime::RemoteObject; |
| 55 using protocol::Maybe; |
| 56 |
| 57 static bool hasInternalError(ErrorString* errorString, bool hasError) { |
| 58 if (hasError) *errorString = "Internal error"; |
| 59 return hasError; |
| 60 } |
| 61 |
| 62 std::unique_ptr<InjectedScript> InjectedScript::create( |
| 63 InspectedContext* inspectedContext) { |
| 64 v8::Isolate* isolate = inspectedContext->isolate(); |
| 65 v8::HandleScope handles(isolate); |
| 66 v8::Local<v8::Context> context = inspectedContext->context(); |
| 67 v8::Context::Scope scope(context); |
| 68 |
| 69 std::unique_ptr<InjectedScriptNative> injectedScriptNative( |
| 70 new InjectedScriptNative(isolate)); |
| 71 v8::Local<v8::Object> scriptHostWrapper = |
| 72 V8InjectedScriptHost::create(context, inspectedContext->inspector()); |
| 73 injectedScriptNative->setOnInjectedScriptHost(scriptHostWrapper); |
| 74 |
| 75 // Inject javascript into the context. The compiled script is supposed to |
| 76 // evaluate into |
| 77 // a single anonymous function(it's anonymous to avoid cluttering the global |
| 78 // object with |
| 79 // inspector's stuff) the function is called a few lines below with |
| 80 // InjectedScriptHost wrapper, |
| 81 // injected script id and explicit reference to the inspected global object. |
| 82 // The function is expected |
| 83 // to create and configure InjectedScript instance that is going to be used by |
| 84 // the inspector. |
| 85 String16 injectedScriptSource( |
| 86 reinterpret_cast<const char*>(InjectedScriptSource_js), |
| 87 sizeof(InjectedScriptSource_js)); |
| 88 v8::Local<v8::Value> value; |
| 89 if (!inspectedContext->inspector() |
| 90 ->compileAndRunInternalScript( |
| 91 context, toV8String(isolate, injectedScriptSource)) |
| 92 .ToLocal(&value)) |
| 93 return nullptr; |
| 94 DCHECK(value->IsFunction()); |
| 95 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value); |
| 96 v8::Local<v8::Object> windowGlobal = context->Global(); |
| 97 v8::Local<v8::Value> info[] = { |
| 98 scriptHostWrapper, windowGlobal, |
| 99 v8::Number::New(isolate, inspectedContext->contextId())}; |
| 100 v8::MicrotasksScope microtasksScope(isolate, |
| 101 v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 102 v8::Local<v8::Value> injectedScriptValue; |
| 103 if (!function |
| 104 ->Call(context, windowGlobal, V8_INSPECTOR_ARRAY_LENGTH(info), info) |
| 105 .ToLocal(&injectedScriptValue)) |
| 106 return nullptr; |
| 107 if (!injectedScriptValue->IsObject()) return nullptr; |
| 108 return wrapUnique(new InjectedScript(inspectedContext, |
| 109 injectedScriptValue.As<v8::Object>(), |
| 110 std::move(injectedScriptNative))); |
| 111 } |
| 112 |
| 113 InjectedScript::InjectedScript( |
| 114 InspectedContext* context, v8::Local<v8::Object> object, |
| 115 std::unique_ptr<InjectedScriptNative> injectedScriptNative) |
| 116 : m_context(context), |
| 117 m_value(context->isolate(), object), |
| 118 m_native(std::move(injectedScriptNative)) {} |
| 119 |
| 120 InjectedScript::~InjectedScript() {} |
| 121 |
| 122 void InjectedScript::getProperties( |
| 123 ErrorString* errorString, v8::Local<v8::Object> object, |
| 124 const String16& groupName, bool ownProperties, bool accessorPropertiesOnly, |
| 125 bool generatePreview, |
| 126 std::unique_ptr<Array<PropertyDescriptor>>* properties, |
| 127 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { |
| 128 v8::HandleScope handles(m_context->isolate()); |
| 129 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 130 v8Value(), "getProperties"); |
| 131 function.appendArgument(object); |
| 132 function.appendArgument(groupName); |
| 133 function.appendArgument(ownProperties); |
| 134 function.appendArgument(accessorPropertiesOnly); |
| 135 function.appendArgument(generatePreview); |
| 136 |
| 137 v8::TryCatch tryCatch(m_context->isolate()); |
| 138 v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling(); |
| 139 if (tryCatch.HasCaught()) { |
| 140 *exceptionDetails = createExceptionDetails(errorString, tryCatch, groupName, |
| 141 generatePreview); |
| 142 // FIXME: make properties optional |
| 143 *properties = Array<PropertyDescriptor>::create(); |
| 144 return; |
| 145 } |
| 146 |
| 147 std::unique_ptr<protocol::Value> protocolValue = |
| 148 toProtocolValue(m_context->context(), resultValue); |
| 149 if (hasInternalError(errorString, !protocolValue)) return; |
| 150 protocol::ErrorSupport errors(errorString); |
| 151 std::unique_ptr<Array<PropertyDescriptor>> result = |
| 152 Array<PropertyDescriptor>::parse(protocolValue.get(), &errors); |
| 153 if (!hasInternalError(errorString, errors.hasErrors())) |
| 154 *properties = std::move(result); |
| 155 } |
| 156 |
| 157 void InjectedScript::releaseObject(const String16& objectId) { |
| 158 std::unique_ptr<protocol::Value> parsedObjectId = |
| 159 protocol::parseJSON(objectId); |
| 160 if (!parsedObjectId) return; |
| 161 protocol::DictionaryValue* object = |
| 162 protocol::DictionaryValue::cast(parsedObjectId.get()); |
| 163 if (!object) return; |
| 164 int boundId = 0; |
| 165 if (!object->getInteger("id", &boundId)) return; |
| 166 m_native->unbind(boundId); |
| 167 } |
| 168 |
| 169 std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapObject( |
| 170 ErrorString* errorString, v8::Local<v8::Value> value, |
| 171 const String16& groupName, bool forceValueType, |
| 172 bool generatePreview) const { |
| 173 v8::HandleScope handles(m_context->isolate()); |
| 174 v8::Local<v8::Value> wrappedObject; |
| 175 if (!wrapValue(errorString, value, groupName, forceValueType, generatePreview) |
| 176 .ToLocal(&wrappedObject)) |
| 177 return nullptr; |
| 178 protocol::ErrorSupport errors; |
| 179 std::unique_ptr<protocol::Runtime::RemoteObject> remoteObject = |
| 180 protocol::Runtime::RemoteObject::parse( |
| 181 toProtocolValue(m_context->context(), wrappedObject).get(), &errors); |
| 182 if (!remoteObject) *errorString = "Object has too long reference chain"; |
| 183 return remoteObject; |
| 184 } |
| 185 |
| 186 bool InjectedScript::wrapObjectProperty(ErrorString* errorString, |
| 187 v8::Local<v8::Object> object, |
| 188 v8::Local<v8::Name> key, |
| 189 const String16& groupName, |
| 190 bool forceValueType, |
| 191 bool generatePreview) const { |
| 192 v8::Local<v8::Value> property; |
| 193 if (hasInternalError( |
| 194 errorString, |
| 195 !object->Get(m_context->context(), key).ToLocal(&property))) |
| 196 return false; |
| 197 v8::Local<v8::Value> wrappedProperty; |
| 198 if (!wrapValue(errorString, property, groupName, forceValueType, |
| 199 generatePreview) |
| 200 .ToLocal(&wrappedProperty)) |
| 201 return false; |
| 202 v8::Maybe<bool> success = |
| 203 createDataProperty(m_context->context(), object, key, wrappedProperty); |
| 204 if (hasInternalError(errorString, success.IsNothing() || !success.FromJust())) |
| 205 return false; |
| 206 return true; |
| 207 } |
| 208 |
| 209 bool InjectedScript::wrapPropertyInArray(ErrorString* errorString, |
| 210 v8::Local<v8::Array> array, |
| 211 v8::Local<v8::String> property, |
| 212 const String16& groupName, |
| 213 bool forceValueType, |
| 214 bool generatePreview) const { |
| 215 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 216 v8Value(), "wrapPropertyInArray"); |
| 217 function.appendArgument(array); |
| 218 function.appendArgument(property); |
| 219 function.appendArgument(groupName); |
| 220 function.appendArgument(forceValueType); |
| 221 function.appendArgument(generatePreview); |
| 222 bool hadException = false; |
| 223 function.call(hadException); |
| 224 return !hasInternalError(errorString, hadException); |
| 225 } |
| 226 |
| 227 bool InjectedScript::wrapObjectsInArray(ErrorString* errorString, |
| 228 v8::Local<v8::Array> array, |
| 229 const String16& groupName, |
| 230 bool forceValueType, |
| 231 bool generatePreview) const { |
| 232 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 233 v8Value(), "wrapObjectsInArray"); |
| 234 function.appendArgument(array); |
| 235 function.appendArgument(groupName); |
| 236 function.appendArgument(forceValueType); |
| 237 function.appendArgument(generatePreview); |
| 238 bool hadException = false; |
| 239 function.call(hadException); |
| 240 return !hasInternalError(errorString, hadException); |
| 241 } |
| 242 |
| 243 v8::MaybeLocal<v8::Value> InjectedScript::wrapValue( |
| 244 ErrorString* errorString, v8::Local<v8::Value> value, |
| 245 const String16& groupName, bool forceValueType, |
| 246 bool generatePreview) const { |
| 247 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 248 v8Value(), "wrapObject"); |
| 249 function.appendArgument(value); |
| 250 function.appendArgument(groupName); |
| 251 function.appendArgument(forceValueType); |
| 252 function.appendArgument(generatePreview); |
| 253 bool hadException = false; |
| 254 v8::Local<v8::Value> r = function.call(hadException); |
| 255 if (hasInternalError(errorString, hadException || r.IsEmpty())) |
| 256 return v8::MaybeLocal<v8::Value>(); |
| 257 return r; |
| 258 } |
| 259 |
| 260 std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( |
| 261 v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const { |
| 262 v8::HandleScope handles(m_context->isolate()); |
| 263 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 264 v8Value(), "wrapTable"); |
| 265 function.appendArgument(table); |
| 266 if (columns.IsEmpty()) |
| 267 function.appendArgument(false); |
| 268 else |
| 269 function.appendArgument(columns); |
| 270 bool hadException = false; |
| 271 v8::Local<v8::Value> r = function.call(hadException); |
| 272 if (hadException) return nullptr; |
| 273 protocol::ErrorSupport errors; |
| 274 return protocol::Runtime::RemoteObject::parse( |
| 275 toProtocolValue(m_context->context(), r).get(), &errors); |
| 276 } |
| 277 |
| 278 bool InjectedScript::findObject(ErrorString* errorString, |
| 279 const RemoteObjectId& objectId, |
| 280 v8::Local<v8::Value>* outObject) const { |
| 281 *outObject = m_native->objectForId(objectId.id()); |
| 282 if (outObject->IsEmpty()) |
| 283 *errorString = "Could not find object with given id"; |
| 284 return !outObject->IsEmpty(); |
| 285 } |
| 286 |
| 287 String16 InjectedScript::objectGroupName(const RemoteObjectId& objectId) const { |
| 288 return m_native->groupName(objectId.id()); |
| 289 } |
| 290 |
| 291 void InjectedScript::releaseObjectGroup(const String16& objectGroup) { |
| 292 m_native->releaseObjectGroup(objectGroup); |
| 293 if (objectGroup == "console") m_lastEvaluationResult.Reset(); |
| 294 } |
| 295 |
| 296 void InjectedScript::setCustomObjectFormatterEnabled(bool enabled) { |
| 297 v8::HandleScope handles(m_context->isolate()); |
| 298 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 299 v8Value(), "setCustomObjectFormatterEnabled"); |
| 300 function.appendArgument(enabled); |
| 301 bool hadException = false; |
| 302 function.call(hadException); |
| 303 DCHECK(!hadException); |
| 304 } |
| 305 |
| 306 v8::Local<v8::Value> InjectedScript::v8Value() const { |
| 307 return m_value.Get(m_context->isolate()); |
| 308 } |
| 309 |
| 310 v8::Local<v8::Value> InjectedScript::lastEvaluationResult() const { |
| 311 if (m_lastEvaluationResult.IsEmpty()) |
| 312 return v8::Undefined(m_context->isolate()); |
| 313 return m_lastEvaluationResult.Get(m_context->isolate()); |
| 314 } |
| 315 |
| 316 v8::MaybeLocal<v8::Value> InjectedScript::resolveCallArgument( |
| 317 ErrorString* errorString, protocol::Runtime::CallArgument* callArgument) { |
| 318 if (callArgument->hasObjectId()) { |
| 319 std::unique_ptr<RemoteObjectId> remoteObjectId = |
| 320 RemoteObjectId::parse(errorString, callArgument->getObjectId("")); |
| 321 if (!remoteObjectId) return v8::MaybeLocal<v8::Value>(); |
| 322 if (remoteObjectId->contextId() != m_context->contextId()) { |
| 323 *errorString = |
| 324 "Argument should belong to the same JavaScript world as target " |
| 325 "object"; |
| 326 return v8::MaybeLocal<v8::Value>(); |
| 327 } |
| 328 v8::Local<v8::Value> object; |
| 329 if (!findObject(errorString, *remoteObjectId, &object)) |
| 330 return v8::MaybeLocal<v8::Value>(); |
| 331 return object; |
| 332 } |
| 333 if (callArgument->hasValue() || callArgument->hasUnserializableValue()) { |
| 334 String16 value = |
| 335 callArgument->hasValue() |
| 336 ? callArgument->getValue(nullptr)->toJSONString() |
| 337 : "Number(\"" + callArgument->getUnserializableValue("") + "\")"; |
| 338 v8::Local<v8::Value> object; |
| 339 if (!m_context->inspector() |
| 340 ->compileAndRunInternalScript( |
| 341 m_context->context(), toV8String(m_context->isolate(), value)) |
| 342 .ToLocal(&object)) { |
| 343 *errorString = "Couldn't parse value object in call argument"; |
| 344 return v8::MaybeLocal<v8::Value>(); |
| 345 } |
| 346 return object; |
| 347 } |
| 348 return v8::Undefined(m_context->isolate()); |
| 349 } |
| 350 |
| 351 std::unique_ptr<protocol::Runtime::ExceptionDetails> |
| 352 InjectedScript::createExceptionDetails(ErrorString* errorString, |
| 353 const v8::TryCatch& tryCatch, |
| 354 const String16& objectGroup, |
| 355 bool generatePreview) { |
| 356 if (!tryCatch.HasCaught()) return nullptr; |
| 357 v8::Local<v8::Message> message = tryCatch.Message(); |
| 358 v8::Local<v8::Value> exception = tryCatch.Exception(); |
| 359 String16 messageText = |
| 360 message.IsEmpty() ? String16() : toProtocolString(message->Get()); |
| 361 std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails = |
| 362 protocol::Runtime::ExceptionDetails::create() |
| 363 .setExceptionId(m_context->inspector()->nextExceptionId()) |
| 364 .setText(exception.IsEmpty() ? messageText : String16("Uncaught")) |
| 365 .setLineNumber( |
| 366 message.IsEmpty() |
| 367 ? 0 |
| 368 : message->GetLineNumber(m_context->context()).FromMaybe(1) - |
| 369 1) |
| 370 .setColumnNumber( |
| 371 message.IsEmpty() |
| 372 ? 0 |
| 373 : message->GetStartColumn(m_context->context()).FromMaybe(0)) |
| 374 .build(); |
| 375 if (!message.IsEmpty()) { |
| 376 exceptionDetails->setScriptId( |
| 377 String16::fromInteger(message->GetScriptOrigin().ScriptID()->Value())); |
| 378 v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace(); |
| 379 if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) |
| 380 exceptionDetails->setStackTrace(m_context->inspector() |
| 381 ->debugger() |
| 382 ->createStackTrace(stackTrace) |
| 383 ->buildInspectorObjectImpl()); |
| 384 } |
| 385 if (!exception.IsEmpty()) { |
| 386 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = wrapObject( |
| 387 errorString, exception, objectGroup, false /* forceValueType */, |
| 388 generatePreview && !exception->IsNativeError()); |
| 389 if (!wrapped) return nullptr; |
| 390 exceptionDetails->setException(std::move(wrapped)); |
| 391 } |
| 392 return exceptionDetails; |
| 393 } |
| 394 |
| 395 void InjectedScript::wrapEvaluateResult( |
| 396 ErrorString* errorString, v8::MaybeLocal<v8::Value> maybeResultValue, |
| 397 const v8::TryCatch& tryCatch, const String16& objectGroup, |
| 398 bool returnByValue, bool generatePreview, |
| 399 std::unique_ptr<protocol::Runtime::RemoteObject>* result, |
| 400 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { |
| 401 v8::Local<v8::Value> resultValue; |
| 402 if (!tryCatch.HasCaught()) { |
| 403 if (hasInternalError(errorString, !maybeResultValue.ToLocal(&resultValue))) |
| 404 return; |
| 405 std::unique_ptr<RemoteObject> remoteObject = wrapObject( |
| 406 errorString, resultValue, objectGroup, returnByValue, generatePreview); |
| 407 if (!remoteObject) return; |
| 408 if (objectGroup == "console") |
| 409 m_lastEvaluationResult.Reset(m_context->isolate(), resultValue); |
| 410 *result = std::move(remoteObject); |
| 411 } else { |
| 412 v8::Local<v8::Value> exception = tryCatch.Exception(); |
| 413 std::unique_ptr<RemoteObject> remoteObject = |
| 414 wrapObject(errorString, exception, objectGroup, false, |
| 415 generatePreview && !exception->IsNativeError()); |
| 416 if (!remoteObject) return; |
| 417 // We send exception in result for compatibility reasons, even though it's |
| 418 // accessible through exceptionDetails.exception. |
| 419 *result = std::move(remoteObject); |
| 420 *exceptionDetails = createExceptionDetails(errorString, tryCatch, |
| 421 objectGroup, generatePreview); |
| 422 } |
| 423 } |
| 424 |
| 425 v8::Local<v8::Object> InjectedScript::commandLineAPI() { |
| 426 if (m_commandLineAPI.IsEmpty()) |
| 427 m_commandLineAPI.Reset(m_context->isolate(), |
| 428 V8Console::createCommandLineAPI(m_context)); |
| 429 return m_commandLineAPI.Get(m_context->isolate()); |
| 430 } |
| 431 |
| 432 InjectedScript::Scope::Scope(ErrorString* errorString, |
| 433 V8InspectorImpl* inspector, int contextGroupId) |
| 434 : m_errorString(errorString), |
| 435 m_inspector(inspector), |
| 436 m_contextGroupId(contextGroupId), |
| 437 m_injectedScript(nullptr), |
| 438 m_handleScope(inspector->isolate()), |
| 439 m_tryCatch(inspector->isolate()), |
| 440 m_ignoreExceptionsAndMuteConsole(false), |
| 441 m_previousPauseOnExceptionsState(V8Debugger::DontPauseOnExceptions), |
| 442 m_userGesture(false) {} |
| 443 |
| 444 bool InjectedScript::Scope::initialize() { |
| 445 cleanup(); |
| 446 // TODO(dgozman): what if we reattach to the same context group during |
| 447 // evaluate? Introduce a session id? |
| 448 V8InspectorSessionImpl* session = |
| 449 m_inspector->sessionForContextGroup(m_contextGroupId); |
| 450 if (!session) { |
| 451 *m_errorString = "Internal error"; |
| 452 return false; |
| 453 } |
| 454 findInjectedScript(session); |
| 455 if (!m_injectedScript) return false; |
| 456 m_context = m_injectedScript->context()->context(); |
| 457 m_context->Enter(); |
| 458 return true; |
| 459 } |
| 460 |
| 461 bool InjectedScript::Scope::installCommandLineAPI() { |
| 462 DCHECK(m_injectedScript && !m_context.IsEmpty() && |
| 463 !m_commandLineAPIScope.get()); |
| 464 m_commandLineAPIScope.reset(new V8Console::CommandLineAPIScope( |
| 465 m_context, m_injectedScript->commandLineAPI(), m_context->Global())); |
| 466 return true; |
| 467 } |
| 468 |
| 469 void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() { |
| 470 DCHECK(!m_ignoreExceptionsAndMuteConsole); |
| 471 m_ignoreExceptionsAndMuteConsole = true; |
| 472 m_inspector->client()->muteMetrics(m_contextGroupId); |
| 473 m_inspector->muteExceptions(m_contextGroupId); |
| 474 m_previousPauseOnExceptionsState = |
| 475 setPauseOnExceptionsState(V8Debugger::DontPauseOnExceptions); |
| 476 } |
| 477 |
| 478 V8Debugger::PauseOnExceptionsState |
| 479 InjectedScript::Scope::setPauseOnExceptionsState( |
| 480 V8Debugger::PauseOnExceptionsState newState) { |
| 481 if (!m_inspector->debugger()->enabled()) return newState; |
| 482 V8Debugger::PauseOnExceptionsState presentState = |
| 483 m_inspector->debugger()->getPauseOnExceptionsState(); |
| 484 if (presentState != newState) |
| 485 m_inspector->debugger()->setPauseOnExceptionsState(newState); |
| 486 return presentState; |
| 487 } |
| 488 |
| 489 void InjectedScript::Scope::pretendUserGesture() { |
| 490 DCHECK(!m_userGesture); |
| 491 m_userGesture = true; |
| 492 m_inspector->client()->beginUserGesture(); |
| 493 } |
| 494 |
| 495 void InjectedScript::Scope::cleanup() { |
| 496 m_commandLineAPIScope.reset(); |
| 497 if (!m_context.IsEmpty()) { |
| 498 m_context->Exit(); |
| 499 m_context.Clear(); |
| 500 } |
| 501 } |
| 502 |
| 503 InjectedScript::Scope::~Scope() { |
| 504 if (m_ignoreExceptionsAndMuteConsole) { |
| 505 setPauseOnExceptionsState(m_previousPauseOnExceptionsState); |
| 506 m_inspector->client()->unmuteMetrics(m_contextGroupId); |
| 507 m_inspector->unmuteExceptions(m_contextGroupId); |
| 508 } |
| 509 if (m_userGesture) m_inspector->client()->endUserGesture(); |
| 510 cleanup(); |
| 511 } |
| 512 |
| 513 InjectedScript::ContextScope::ContextScope(ErrorString* errorString, |
| 514 V8InspectorImpl* inspector, |
| 515 int contextGroupId, |
| 516 int executionContextId) |
| 517 : InjectedScript::Scope(errorString, inspector, contextGroupId), |
| 518 m_executionContextId(executionContextId) {} |
| 519 |
| 520 InjectedScript::ContextScope::~ContextScope() {} |
| 521 |
| 522 void InjectedScript::ContextScope::findInjectedScript( |
| 523 V8InspectorSessionImpl* session) { |
| 524 m_injectedScript = |
| 525 session->findInjectedScript(m_errorString, m_executionContextId); |
| 526 } |
| 527 |
| 528 InjectedScript::ObjectScope::ObjectScope(ErrorString* errorString, |
| 529 V8InspectorImpl* inspector, |
| 530 int contextGroupId, |
| 531 const String16& remoteObjectId) |
| 532 : InjectedScript::Scope(errorString, inspector, contextGroupId), |
| 533 m_remoteObjectId(remoteObjectId) {} |
| 534 |
| 535 InjectedScript::ObjectScope::~ObjectScope() {} |
| 536 |
| 537 void InjectedScript::ObjectScope::findInjectedScript( |
| 538 V8InspectorSessionImpl* session) { |
| 539 std::unique_ptr<RemoteObjectId> remoteId = |
| 540 RemoteObjectId::parse(m_errorString, m_remoteObjectId); |
| 541 if (!remoteId) return; |
| 542 InjectedScript* injectedScript = |
| 543 session->findInjectedScript(m_errorString, remoteId.get()); |
| 544 if (!injectedScript) return; |
| 545 m_objectGroupName = injectedScript->objectGroupName(*remoteId); |
| 546 if (!injectedScript->findObject(m_errorString, *remoteId, &m_object)) return; |
| 547 m_injectedScript = injectedScript; |
| 548 } |
| 549 |
| 550 InjectedScript::CallFrameScope::CallFrameScope(ErrorString* errorString, |
| 551 V8InspectorImpl* inspector, |
| 552 int contextGroupId, |
| 553 const String16& remoteObjectId) |
| 554 : InjectedScript::Scope(errorString, inspector, contextGroupId), |
| 555 m_remoteCallFrameId(remoteObjectId) {} |
| 556 |
| 557 InjectedScript::CallFrameScope::~CallFrameScope() {} |
| 558 |
| 559 void InjectedScript::CallFrameScope::findInjectedScript( |
| 560 V8InspectorSessionImpl* session) { |
| 561 std::unique_ptr<RemoteCallFrameId> remoteId = |
| 562 RemoteCallFrameId::parse(m_errorString, m_remoteCallFrameId); |
| 563 if (!remoteId) return; |
| 564 m_frameOrdinal = static_cast<size_t>(remoteId->frameOrdinal()); |
| 565 m_injectedScript = session->findInjectedScript(m_errorString, remoteId.get()); |
| 566 } |
| 567 |
| 568 } // namespace v8_inspector |
OLD | NEW |