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