| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 #include "include/v8-inspector.h" | 47 #include "include/v8-inspector.h" |
| 48 | 48 |
| 49 namespace v8_inspector { | 49 namespace v8_inspector { |
| 50 | 50 |
| 51 using protocol::Array; | 51 using protocol::Array; |
| 52 using protocol::Runtime::PropertyDescriptor; | 52 using protocol::Runtime::PropertyDescriptor; |
| 53 using protocol::Runtime::InternalPropertyDescriptor; | 53 using protocol::Runtime::InternalPropertyDescriptor; |
| 54 using protocol::Runtime::RemoteObject; | 54 using protocol::Runtime::RemoteObject; |
| 55 using protocol::Maybe; | 55 using protocol::Maybe; |
| 56 | 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( | 57 std::unique_ptr<InjectedScript> InjectedScript::create( |
| 63 InspectedContext* inspectedContext) { | 58 InspectedContext* inspectedContext) { |
| 64 v8::Isolate* isolate = inspectedContext->isolate(); | 59 v8::Isolate* isolate = inspectedContext->isolate(); |
| 65 v8::HandleScope handles(isolate); | 60 v8::HandleScope handles(isolate); |
| 66 v8::Local<v8::Context> context = inspectedContext->context(); | 61 v8::Local<v8::Context> context = inspectedContext->context(); |
| 67 v8::Context::Scope scope(context); | 62 v8::Context::Scope scope(context); |
| 68 | 63 |
| 69 std::unique_ptr<InjectedScriptNative> injectedScriptNative( | 64 std::unique_ptr<InjectedScriptNative> injectedScriptNative( |
| 70 new InjectedScriptNative(isolate)); | 65 new InjectedScriptNative(isolate)); |
| 71 v8::Local<v8::Object> scriptHostWrapper = | 66 v8::Local<v8::Object> scriptHostWrapper = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 112 |
| 118 InjectedScript::InjectedScript( | 113 InjectedScript::InjectedScript( |
| 119 InspectedContext* context, v8::Local<v8::Object> object, | 114 InspectedContext* context, v8::Local<v8::Object> object, |
| 120 std::unique_ptr<InjectedScriptNative> injectedScriptNative) | 115 std::unique_ptr<InjectedScriptNative> injectedScriptNative) |
| 121 : m_context(context), | 116 : m_context(context), |
| 122 m_value(context->isolate(), object), | 117 m_value(context->isolate(), object), |
| 123 m_native(std::move(injectedScriptNative)) {} | 118 m_native(std::move(injectedScriptNative)) {} |
| 124 | 119 |
| 125 InjectedScript::~InjectedScript() {} | 120 InjectedScript::~InjectedScript() {} |
| 126 | 121 |
| 127 void InjectedScript::getProperties( | 122 Response InjectedScript::getProperties( |
| 128 ErrorString* errorString, v8::Local<v8::Object> object, | 123 v8::Local<v8::Object> object, const String16& groupName, bool ownProperties, |
| 129 const String16& groupName, bool ownProperties, bool accessorPropertiesOnly, | 124 bool accessorPropertiesOnly, bool generatePreview, |
| 130 bool generatePreview, | |
| 131 std::unique_ptr<Array<PropertyDescriptor>>* properties, | 125 std::unique_ptr<Array<PropertyDescriptor>>* properties, |
| 132 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { | 126 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { |
| 133 v8::HandleScope handles(m_context->isolate()); | 127 v8::HandleScope handles(m_context->isolate()); |
| 134 v8::Local<v8::Context> context = m_context->context(); | 128 v8::Local<v8::Context> context = m_context->context(); |
| 135 V8FunctionCall function(m_context->inspector(), m_context->context(), | 129 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 136 v8Value(), "getProperties"); | 130 v8Value(), "getProperties"); |
| 137 function.appendArgument(object); | 131 function.appendArgument(object); |
| 138 function.appendArgument(groupName); | 132 function.appendArgument(groupName); |
| 139 function.appendArgument(ownProperties); | 133 function.appendArgument(ownProperties); |
| 140 function.appendArgument(accessorPropertiesOnly); | 134 function.appendArgument(accessorPropertiesOnly); |
| 141 function.appendArgument(generatePreview); | 135 function.appendArgument(generatePreview); |
| 142 | 136 |
| 143 v8::TryCatch tryCatch(m_context->isolate()); | 137 v8::TryCatch tryCatch(m_context->isolate()); |
| 144 v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling(); | 138 v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling(); |
| 145 if (tryCatch.HasCaught()) { | 139 if (tryCatch.HasCaught()) { |
| 146 *exceptionDetails = createExceptionDetails(errorString, tryCatch, groupName, | 140 Response response = createExceptionDetails( |
| 147 generatePreview); | 141 tryCatch, groupName, generatePreview, exceptionDetails); |
| 142 if (!response.isSuccess()) return response; |
| 148 // FIXME: make properties optional | 143 // FIXME: make properties optional |
| 149 *properties = Array<PropertyDescriptor>::create(); | 144 *properties = Array<PropertyDescriptor>::create(); |
| 150 return; | 145 return Response::OK(); |
| 151 } | 146 } |
| 152 if (hasInternalError(errorString, resultValue.IsEmpty())) return; | 147 if (resultValue.IsEmpty()) return Response::InternalError(); |
| 153 std::unique_ptr<protocol::Value> protocolValue = | 148 std::unique_ptr<protocol::Value> protocolValue; |
| 154 toProtocolValue(errorString, context, resultValue); | 149 Response response = toProtocolValue(context, resultValue, &protocolValue); |
| 155 if (!protocolValue) return; | 150 if (!response.isSuccess()) return response; |
| 156 protocol::ErrorSupport errors(errorString); | 151 protocol::ErrorSupport errors; |
| 157 std::unique_ptr<Array<PropertyDescriptor>> result = | 152 std::unique_ptr<Array<PropertyDescriptor>> result = |
| 158 Array<PropertyDescriptor>::parse(protocolValue.get(), &errors); | 153 Array<PropertyDescriptor>::parse(protocolValue.get(), &errors); |
| 159 if (!hasInternalError(errorString, errors.hasErrors())) | 154 if (errors.hasErrors()) return Response::Error(errors.errors()); |
| 160 *properties = std::move(result); | 155 *properties = std::move(result); |
| 156 return Response::OK(); |
| 161 } | 157 } |
| 162 | 158 |
| 163 void InjectedScript::releaseObject(const String16& objectId) { | 159 void InjectedScript::releaseObject(const String16& objectId) { |
| 164 std::unique_ptr<protocol::Value> parsedObjectId = | 160 std::unique_ptr<protocol::Value> parsedObjectId = |
| 165 protocol::parseJSON(objectId); | 161 protocol::parseJSON(objectId); |
| 166 if (!parsedObjectId) return; | 162 if (!parsedObjectId) return; |
| 167 protocol::DictionaryValue* object = | 163 protocol::DictionaryValue* object = |
| 168 protocol::DictionaryValue::cast(parsedObjectId.get()); | 164 protocol::DictionaryValue::cast(parsedObjectId.get()); |
| 169 if (!object) return; | 165 if (!object) return; |
| 170 int boundId = 0; | 166 int boundId = 0; |
| 171 if (!object->getInteger("id", &boundId)) return; | 167 if (!object->getInteger("id", &boundId)) return; |
| 172 m_native->unbind(boundId); | 168 m_native->unbind(boundId); |
| 173 } | 169 } |
| 174 | 170 |
| 175 std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapObject( | 171 Response InjectedScript::wrapObject( |
| 176 ErrorString* errorString, v8::Local<v8::Value> value, | 172 v8::Local<v8::Value> value, const String16& groupName, bool forceValueType, |
| 177 const String16& groupName, bool forceValueType, | 173 bool generatePreview, |
| 178 bool generatePreview) const { | 174 std::unique_ptr<protocol::Runtime::RemoteObject>* result) const { |
| 179 v8::HandleScope handles(m_context->isolate()); | 175 v8::HandleScope handles(m_context->isolate()); |
| 180 v8::Local<v8::Value> wrappedObject; | 176 v8::Local<v8::Value> wrappedObject; |
| 181 v8::Local<v8::Context> context = m_context->context(); | 177 v8::Local<v8::Context> context = m_context->context(); |
| 182 if (!wrapValue(errorString, value, groupName, forceValueType, generatePreview) | 178 Response response = wrapValue(value, groupName, forceValueType, |
| 183 .ToLocal(&wrappedObject)) | 179 generatePreview, &wrappedObject); |
| 184 return nullptr; | 180 if (!response.isSuccess()) return response; |
| 185 protocol::ErrorSupport errors; | 181 protocol::ErrorSupport errors; |
| 186 std::unique_ptr<protocol::Value> protocolValue = | 182 std::unique_ptr<protocol::Value> protocolValue; |
| 187 toProtocolValue(errorString, context, wrappedObject); | 183 response = toProtocolValue(context, wrappedObject, &protocolValue); |
| 188 if (!protocolValue) return nullptr; | 184 if (!response.isSuccess()) return response; |
| 189 std::unique_ptr<protocol::Runtime::RemoteObject> remoteObject = | 185 |
| 186 *result = |
| 190 protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors); | 187 protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors); |
| 191 if (!remoteObject) *errorString = errors.errors(); | 188 if (!result->get()) return Response::Error(errors.errors()); |
| 192 return remoteObject; | 189 return Response::OK(); |
| 193 } | 190 } |
| 194 | 191 |
| 195 bool InjectedScript::wrapObjectProperty(ErrorString* errorString, | 192 Response InjectedScript::wrapObjectProperty(v8::Local<v8::Object> object, |
| 196 v8::Local<v8::Object> object, | 193 v8::Local<v8::Name> key, |
| 197 v8::Local<v8::Name> key, | 194 const String16& groupName, |
| 198 const String16& groupName, | 195 bool forceValueType, |
| 199 bool forceValueType, | 196 bool generatePreview) const { |
| 200 bool generatePreview) const { | |
| 201 v8::Local<v8::Value> property; | 197 v8::Local<v8::Value> property; |
| 202 v8::Local<v8::Context> context = m_context->context(); | 198 v8::Local<v8::Context> context = m_context->context(); |
| 203 if (hasInternalError(errorString, | 199 if (!object->Get(context, key).ToLocal(&property)) |
| 204 !object->Get(context, key).ToLocal(&property))) | 200 return Response::InternalError(); |
| 205 return false; | |
| 206 v8::Local<v8::Value> wrappedProperty; | 201 v8::Local<v8::Value> wrappedProperty; |
| 207 if (!wrapValue(errorString, property, groupName, forceValueType, | 202 Response response = wrapValue(property, groupName, forceValueType, |
| 208 generatePreview) | 203 generatePreview, &wrappedProperty); |
| 209 .ToLocal(&wrappedProperty)) | 204 if (!response.isSuccess()) return response; |
| 210 return false; | |
| 211 v8::Maybe<bool> success = | 205 v8::Maybe<bool> success = |
| 212 createDataProperty(context, object, key, wrappedProperty); | 206 createDataProperty(context, object, key, wrappedProperty); |
| 213 if (hasInternalError(errorString, success.IsNothing() || !success.FromJust())) | 207 if (success.IsNothing() || !success.FromJust()) |
| 214 return false; | 208 return Response::InternalError(); |
| 215 return true; | 209 return Response::OK(); |
| 216 } | 210 } |
| 217 | 211 |
| 218 bool InjectedScript::wrapPropertyInArray(ErrorString* errorString, | 212 Response InjectedScript::wrapPropertyInArray(v8::Local<v8::Array> array, |
| 219 v8::Local<v8::Array> array, | 213 v8::Local<v8::String> property, |
| 220 v8::Local<v8::String> property, | 214 const String16& groupName, |
| 221 const String16& groupName, | 215 bool forceValueType, |
| 222 bool forceValueType, | 216 bool generatePreview) const { |
| 223 bool generatePreview) const { | |
| 224 V8FunctionCall function(m_context->inspector(), m_context->context(), | 217 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 225 v8Value(), "wrapPropertyInArray"); | 218 v8Value(), "wrapPropertyInArray"); |
| 226 function.appendArgument(array); | 219 function.appendArgument(array); |
| 227 function.appendArgument(property); | 220 function.appendArgument(property); |
| 228 function.appendArgument(groupName); | 221 function.appendArgument(groupName); |
| 229 function.appendArgument(forceValueType); | 222 function.appendArgument(forceValueType); |
| 230 function.appendArgument(generatePreview); | 223 function.appendArgument(generatePreview); |
| 231 bool hadException = false; | 224 bool hadException = false; |
| 232 function.call(hadException); | 225 function.call(hadException); |
| 233 return !hasInternalError(errorString, hadException); | 226 return hadException ? Response::InternalError() : Response::OK(); |
| 234 } | 227 } |
| 235 | 228 |
| 236 bool InjectedScript::wrapObjectsInArray(ErrorString* errorString, | 229 Response InjectedScript::wrapValue(v8::Local<v8::Value> value, |
| 237 v8::Local<v8::Array> array, | 230 const String16& groupName, |
| 238 const String16& groupName, | 231 bool forceValueType, bool generatePreview, |
| 239 bool forceValueType, | 232 v8::Local<v8::Value>* result) const { |
| 240 bool generatePreview) const { | |
| 241 V8FunctionCall function(m_context->inspector(), m_context->context(), | |
| 242 v8Value(), "wrapObjectsInArray"); | |
| 243 function.appendArgument(array); | |
| 244 function.appendArgument(groupName); | |
| 245 function.appendArgument(forceValueType); | |
| 246 function.appendArgument(generatePreview); | |
| 247 bool hadException = false; | |
| 248 function.call(hadException); | |
| 249 return !hasInternalError(errorString, hadException); | |
| 250 } | |
| 251 | |
| 252 v8::MaybeLocal<v8::Value> InjectedScript::wrapValue( | |
| 253 ErrorString* errorString, v8::Local<v8::Value> value, | |
| 254 const String16& groupName, bool forceValueType, | |
| 255 bool generatePreview) const { | |
| 256 V8FunctionCall function(m_context->inspector(), m_context->context(), | 233 V8FunctionCall function(m_context->inspector(), m_context->context(), |
| 257 v8Value(), "wrapObject"); | 234 v8Value(), "wrapObject"); |
| 258 function.appendArgument(value); | 235 function.appendArgument(value); |
| 259 function.appendArgument(groupName); | 236 function.appendArgument(groupName); |
| 260 function.appendArgument(forceValueType); | 237 function.appendArgument(forceValueType); |
| 261 function.appendArgument(generatePreview); | 238 function.appendArgument(generatePreview); |
| 262 bool hadException = false; | 239 bool hadException = false; |
| 263 v8::Local<v8::Value> r = function.call(hadException); | 240 *result = function.call(hadException); |
| 264 if (hasInternalError(errorString, hadException || r.IsEmpty())) | 241 if (hadException || result->IsEmpty()) return Response::InternalError(); |
| 265 return v8::MaybeLocal<v8::Value>(); | 242 return Response::OK(); |
| 266 return r; | |
| 267 } | 243 } |
| 268 | 244 |
| 269 std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( | 245 std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( |
| 270 v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const { | 246 v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const { |
| 271 v8::HandleScope handles(m_context->isolate()); | 247 v8::HandleScope handles(m_context->isolate()); |
| 272 v8::Local<v8::Context> context = m_context->context(); | 248 v8::Local<v8::Context> context = m_context->context(); |
| 273 V8FunctionCall function(m_context->inspector(), context, v8Value(), | 249 V8FunctionCall function(m_context->inspector(), context, v8Value(), |
| 274 "wrapTable"); | 250 "wrapTable"); |
| 275 function.appendArgument(table); | 251 function.appendArgument(table); |
| 276 if (columns.IsEmpty()) | 252 if (columns.IsEmpty()) |
| 277 function.appendArgument(false); | 253 function.appendArgument(false); |
| 278 else | 254 else |
| 279 function.appendArgument(columns); | 255 function.appendArgument(columns); |
| 280 bool hadException = false; | 256 bool hadException = false; |
| 281 v8::Local<v8::Value> r = function.call(hadException); | 257 v8::Local<v8::Value> r = function.call(hadException); |
| 282 if (hadException || r.IsEmpty()) return nullptr; | 258 if (hadException || r.IsEmpty()) return nullptr; |
| 283 protocol::ErrorString errorString; | 259 std::unique_ptr<protocol::Value> protocolValue; |
| 284 std::unique_ptr<protocol::Value> protocolValue = | 260 Response response = toProtocolValue(context, r, &protocolValue); |
| 285 toProtocolValue(&errorString, context, r); | 261 if (!response.isSuccess()) return nullptr; |
| 286 if (!protocolValue) return nullptr; | |
| 287 protocol::ErrorSupport errors; | 262 protocol::ErrorSupport errors; |
| 288 return protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors); | 263 return protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors); |
| 289 } | 264 } |
| 290 | 265 |
| 291 bool InjectedScript::findObject(ErrorString* errorString, | 266 Response InjectedScript::findObject(const RemoteObjectId& objectId, |
| 292 const RemoteObjectId& objectId, | 267 v8::Local<v8::Value>* outObject) const { |
| 293 v8::Local<v8::Value>* outObject) const { | |
| 294 *outObject = m_native->objectForId(objectId.id()); | 268 *outObject = m_native->objectForId(objectId.id()); |
| 295 if (outObject->IsEmpty()) | 269 if (outObject->IsEmpty()) |
| 296 *errorString = "Could not find object with given id"; | 270 return Response::Error("Could not find object with given id"); |
| 297 return !outObject->IsEmpty(); | 271 return Response::OK(); |
| 298 } | 272 } |
| 299 | 273 |
| 300 String16 InjectedScript::objectGroupName(const RemoteObjectId& objectId) const { | 274 String16 InjectedScript::objectGroupName(const RemoteObjectId& objectId) const { |
| 301 return m_native->groupName(objectId.id()); | 275 return m_native->groupName(objectId.id()); |
| 302 } | 276 } |
| 303 | 277 |
| 304 void InjectedScript::releaseObjectGroup(const String16& objectGroup) { | 278 void InjectedScript::releaseObjectGroup(const String16& objectGroup) { |
| 305 m_native->releaseObjectGroup(objectGroup); | 279 m_native->releaseObjectGroup(objectGroup); |
| 306 if (objectGroup == "console") m_lastEvaluationResult.Reset(); | 280 if (objectGroup == "console") m_lastEvaluationResult.Reset(); |
| 307 } | 281 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 319 v8::Local<v8::Value> InjectedScript::v8Value() const { | 293 v8::Local<v8::Value> InjectedScript::v8Value() const { |
| 320 return m_value.Get(m_context->isolate()); | 294 return m_value.Get(m_context->isolate()); |
| 321 } | 295 } |
| 322 | 296 |
| 323 v8::Local<v8::Value> InjectedScript::lastEvaluationResult() const { | 297 v8::Local<v8::Value> InjectedScript::lastEvaluationResult() const { |
| 324 if (m_lastEvaluationResult.IsEmpty()) | 298 if (m_lastEvaluationResult.IsEmpty()) |
| 325 return v8::Undefined(m_context->isolate()); | 299 return v8::Undefined(m_context->isolate()); |
| 326 return m_lastEvaluationResult.Get(m_context->isolate()); | 300 return m_lastEvaluationResult.Get(m_context->isolate()); |
| 327 } | 301 } |
| 328 | 302 |
| 329 v8::MaybeLocal<v8::Value> InjectedScript::resolveCallArgument( | 303 Response InjectedScript::resolveCallArgument( |
| 330 ErrorString* errorString, protocol::Runtime::CallArgument* callArgument) { | 304 protocol::Runtime::CallArgument* callArgument, |
| 305 v8::Local<v8::Value>* result) { |
| 331 if (callArgument->hasObjectId()) { | 306 if (callArgument->hasObjectId()) { |
| 332 std::unique_ptr<RemoteObjectId> remoteObjectId = | 307 std::unique_ptr<RemoteObjectId> remoteObjectId; |
| 333 RemoteObjectId::parse(errorString, callArgument->getObjectId("")); | 308 Response response = |
| 334 if (!remoteObjectId) return v8::MaybeLocal<v8::Value>(); | 309 RemoteObjectId::parse(callArgument->getObjectId(""), &remoteObjectId); |
| 335 if (remoteObjectId->contextId() != m_context->contextId()) { | 310 if (!response.isSuccess()) return response; |
| 336 *errorString = | 311 if (remoteObjectId->contextId() != m_context->contextId()) |
| 312 return Response::Error( |
| 337 "Argument should belong to the same JavaScript world as target " | 313 "Argument should belong to the same JavaScript world as target " |
| 338 "object"; | 314 "object"); |
| 339 return v8::MaybeLocal<v8::Value>(); | 315 return findObject(*remoteObjectId, result); |
| 340 } | |
| 341 v8::Local<v8::Value> object; | |
| 342 if (!findObject(errorString, *remoteObjectId, &object)) | |
| 343 return v8::MaybeLocal<v8::Value>(); | |
| 344 return object; | |
| 345 } | 316 } |
| 346 if (callArgument->hasValue() || callArgument->hasUnserializableValue()) { | 317 if (callArgument->hasValue() || callArgument->hasUnserializableValue()) { |
| 347 String16 value = | 318 String16 value = |
| 348 callArgument->hasValue() | 319 callArgument->hasValue() |
| 349 ? callArgument->getValue(nullptr)->toJSONString() | 320 ? callArgument->getValue(nullptr)->toJSONString() |
| 350 : "Number(\"" + callArgument->getUnserializableValue("") + "\")"; | 321 : "Number(\"" + callArgument->getUnserializableValue("") + "\")"; |
| 351 v8::Local<v8::Value> object; | |
| 352 if (!m_context->inspector() | 322 if (!m_context->inspector() |
| 353 ->compileAndRunInternalScript( | 323 ->compileAndRunInternalScript( |
| 354 m_context->context(), toV8String(m_context->isolate(), value)) | 324 m_context->context(), toV8String(m_context->isolate(), value)) |
| 355 .ToLocal(&object)) { | 325 .ToLocal(result)) { |
| 356 *errorString = "Couldn't parse value object in call argument"; | 326 return Response::Error("Couldn't parse value object in call argument"); |
| 357 return v8::MaybeLocal<v8::Value>(); | |
| 358 } | 327 } |
| 359 return object; | 328 return Response::OK(); |
| 360 } | 329 } |
| 361 return v8::Undefined(m_context->isolate()); | 330 *result = v8::Undefined(m_context->isolate()); |
| 331 return Response::OK(); |
| 362 } | 332 } |
| 363 | 333 |
| 364 std::unique_ptr<protocol::Runtime::ExceptionDetails> | 334 Response InjectedScript::createExceptionDetails( |
| 365 InjectedScript::createExceptionDetails(ErrorString* errorString, | 335 const v8::TryCatch& tryCatch, const String16& objectGroup, |
| 366 const v8::TryCatch& tryCatch, | 336 bool generatePreview, Maybe<protocol::Runtime::ExceptionDetails>* result) { |
| 367 const String16& objectGroup, | 337 if (!tryCatch.HasCaught()) return Response::InternalError(); |
| 368 bool generatePreview) { | |
| 369 if (!tryCatch.HasCaught()) return nullptr; | |
| 370 v8::Local<v8::Message> message = tryCatch.Message(); | 338 v8::Local<v8::Message> message = tryCatch.Message(); |
| 371 v8::Local<v8::Value> exception = tryCatch.Exception(); | 339 v8::Local<v8::Value> exception = tryCatch.Exception(); |
| 372 String16 messageText = | 340 String16 messageText = |
| 373 message.IsEmpty() ? String16() : toProtocolString(message->Get()); | 341 message.IsEmpty() ? String16() : toProtocolString(message->Get()); |
| 374 std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails = | 342 std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails = |
| 375 protocol::Runtime::ExceptionDetails::create() | 343 protocol::Runtime::ExceptionDetails::create() |
| 376 .setExceptionId(m_context->inspector()->nextExceptionId()) | 344 .setExceptionId(m_context->inspector()->nextExceptionId()) |
| 377 .setText(exception.IsEmpty() ? messageText : String16("Uncaught")) | 345 .setText(exception.IsEmpty() ? messageText : String16("Uncaught")) |
| 378 .setLineNumber( | 346 .setLineNumber( |
| 379 message.IsEmpty() | 347 message.IsEmpty() |
| 380 ? 0 | 348 ? 0 |
| 381 : message->GetLineNumber(m_context->context()).FromMaybe(1) - | 349 : message->GetLineNumber(m_context->context()).FromMaybe(1) - |
| 382 1) | 350 1) |
| 383 .setColumnNumber( | 351 .setColumnNumber( |
| 384 message.IsEmpty() | 352 message.IsEmpty() |
| 385 ? 0 | 353 ? 0 |
| 386 : message->GetStartColumn(m_context->context()).FromMaybe(0)) | 354 : message->GetStartColumn(m_context->context()).FromMaybe(0)) |
| 387 .build(); | 355 .build(); |
| 388 if (!message.IsEmpty()) { | 356 if (!message.IsEmpty()) { |
| 389 exceptionDetails->setScriptId(String16::fromInteger( | 357 exceptionDetails->setScriptId(String16::fromInteger( |
| 390 static_cast<int>(message->GetScriptOrigin().ScriptID()->Value()))); | 358 static_cast<int>(message->GetScriptOrigin().ScriptID()->Value()))); |
| 391 v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace(); | 359 v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace(); |
| 392 if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) | 360 if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) |
| 393 exceptionDetails->setStackTrace(m_context->inspector() | 361 exceptionDetails->setStackTrace(m_context->inspector() |
| 394 ->debugger() | 362 ->debugger() |
| 395 ->createStackTrace(stackTrace) | 363 ->createStackTrace(stackTrace) |
| 396 ->buildInspectorObjectImpl()); | 364 ->buildInspectorObjectImpl()); |
| 397 } | 365 } |
| 398 if (!exception.IsEmpty()) { | 366 if (!exception.IsEmpty()) { |
| 399 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = wrapObject( | 367 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped; |
| 400 errorString, exception, objectGroup, false /* forceValueType */, | 368 Response response = |
| 401 generatePreview && !exception->IsNativeError()); | 369 wrapObject(exception, objectGroup, false /* forceValueType */, |
| 402 if (!wrapped) return nullptr; | 370 generatePreview && !exception->IsNativeError(), &wrapped); |
| 371 if (!response.isSuccess()) return response; |
| 403 exceptionDetails->setException(std::move(wrapped)); | 372 exceptionDetails->setException(std::move(wrapped)); |
| 404 } | 373 } |
| 405 return exceptionDetails; | 374 *result = std::move(exceptionDetails); |
| 375 return Response::OK(); |
| 406 } | 376 } |
| 407 | 377 |
| 408 void InjectedScript::wrapEvaluateResult( | 378 Response InjectedScript::wrapEvaluateResult( |
| 409 ErrorString* errorString, v8::MaybeLocal<v8::Value> maybeResultValue, | 379 v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch& tryCatch, |
| 410 const v8::TryCatch& tryCatch, const String16& objectGroup, | 380 const String16& objectGroup, bool returnByValue, bool generatePreview, |
| 411 bool returnByValue, bool generatePreview, | |
| 412 std::unique_ptr<protocol::Runtime::RemoteObject>* result, | 381 std::unique_ptr<protocol::Runtime::RemoteObject>* result, |
| 413 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { | 382 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { |
| 414 v8::Local<v8::Value> resultValue; | 383 v8::Local<v8::Value> resultValue; |
| 415 if (!tryCatch.HasCaught()) { | 384 if (!tryCatch.HasCaught()) { |
| 416 if (hasInternalError(errorString, !maybeResultValue.ToLocal(&resultValue))) | 385 if (!maybeResultValue.ToLocal(&resultValue)) |
| 417 return; | 386 return Response::InternalError(); |
| 418 std::unique_ptr<RemoteObject> remoteObject = wrapObject( | 387 Response response = wrapObject(resultValue, objectGroup, returnByValue, |
| 419 errorString, resultValue, objectGroup, returnByValue, generatePreview); | 388 generatePreview, result); |
| 420 if (!remoteObject) return; | 389 if (!response.isSuccess()) return response; |
| 421 if (objectGroup == "console") | 390 if (objectGroup == "console") |
| 422 m_lastEvaluationResult.Reset(m_context->isolate(), resultValue); | 391 m_lastEvaluationResult.Reset(m_context->isolate(), resultValue); |
| 423 *result = std::move(remoteObject); | |
| 424 } else { | 392 } else { |
| 425 v8::Local<v8::Value> exception = tryCatch.Exception(); | 393 v8::Local<v8::Value> exception = tryCatch.Exception(); |
| 426 std::unique_ptr<RemoteObject> remoteObject = | 394 Response response = |
| 427 wrapObject(errorString, exception, objectGroup, false, | 395 wrapObject(exception, objectGroup, false, |
| 428 generatePreview && !exception->IsNativeError()); | 396 generatePreview && !exception->IsNativeError(), result); |
| 429 if (!remoteObject) return; | 397 if (!response.isSuccess()) return response; |
| 430 // We send exception in result for compatibility reasons, even though it's | 398 // We send exception in result for compatibility reasons, even though it's |
| 431 // accessible through exceptionDetails.exception. | 399 // accessible through exceptionDetails.exception. |
| 432 *result = std::move(remoteObject); | 400 response = createExceptionDetails(tryCatch, objectGroup, generatePreview, |
| 433 *exceptionDetails = createExceptionDetails(errorString, tryCatch, | 401 exceptionDetails); |
| 434 objectGroup, generatePreview); | 402 if (!response.isSuccess()) return response; |
| 435 } | 403 } |
| 404 return Response::OK(); |
| 436 } | 405 } |
| 437 | 406 |
| 438 v8::Local<v8::Object> InjectedScript::commandLineAPI() { | 407 v8::Local<v8::Object> InjectedScript::commandLineAPI() { |
| 439 if (m_commandLineAPI.IsEmpty()) | 408 if (m_commandLineAPI.IsEmpty()) |
| 440 m_commandLineAPI.Reset(m_context->isolate(), | 409 m_commandLineAPI.Reset(m_context->isolate(), |
| 441 V8Console::createCommandLineAPI(m_context)); | 410 V8Console::createCommandLineAPI(m_context)); |
| 442 return m_commandLineAPI.Get(m_context->isolate()); | 411 return m_commandLineAPI.Get(m_context->isolate()); |
| 443 } | 412 } |
| 444 | 413 |
| 445 InjectedScript::Scope::Scope(ErrorString* errorString, | 414 InjectedScript::Scope::Scope(V8InspectorImpl* inspector, int contextGroupId) |
| 446 V8InspectorImpl* inspector, int contextGroupId) | 415 : m_inspector(inspector), |
| 447 : m_errorString(errorString), | |
| 448 m_inspector(inspector), | |
| 449 m_contextGroupId(contextGroupId), | 416 m_contextGroupId(contextGroupId), |
| 450 m_injectedScript(nullptr), | 417 m_injectedScript(nullptr), |
| 451 m_handleScope(inspector->isolate()), | 418 m_handleScope(inspector->isolate()), |
| 452 m_tryCatch(inspector->isolate()), | 419 m_tryCatch(inspector->isolate()), |
| 453 m_ignoreExceptionsAndMuteConsole(false), | 420 m_ignoreExceptionsAndMuteConsole(false), |
| 454 m_previousPauseOnExceptionsState(v8::DebugInterface::NoBreakOnException), | 421 m_previousPauseOnExceptionsState(v8::DebugInterface::NoBreakOnException), |
| 455 m_userGesture(false) {} | 422 m_userGesture(false) {} |
| 456 | 423 |
| 457 bool InjectedScript::Scope::initialize() { | 424 Response InjectedScript::Scope::initialize() { |
| 458 cleanup(); | 425 cleanup(); |
| 459 // TODO(dgozman): what if we reattach to the same context group during | 426 // TODO(dgozman): what if we reattach to the same context group during |
| 460 // evaluate? Introduce a session id? | 427 // evaluate? Introduce a session id? |
| 461 V8InspectorSessionImpl* session = | 428 V8InspectorSessionImpl* session = |
| 462 m_inspector->sessionForContextGroup(m_contextGroupId); | 429 m_inspector->sessionForContextGroup(m_contextGroupId); |
| 463 if (!session) { | 430 if (!session) return Response::InternalError(); |
| 464 *m_errorString = "Internal error"; | 431 Response response = findInjectedScript(session); |
| 465 return false; | 432 if (!response.isSuccess()) return response; |
| 466 } | |
| 467 findInjectedScript(session); | |
| 468 if (!m_injectedScript) return false; | |
| 469 m_context = m_injectedScript->context()->context(); | 433 m_context = m_injectedScript->context()->context(); |
| 470 m_context->Enter(); | 434 m_context->Enter(); |
| 471 return true; | 435 return Response::OK(); |
| 472 } | 436 } |
| 473 | 437 |
| 474 bool InjectedScript::Scope::installCommandLineAPI() { | 438 void InjectedScript::Scope::installCommandLineAPI() { |
| 475 DCHECK(m_injectedScript && !m_context.IsEmpty() && | 439 DCHECK(m_injectedScript && !m_context.IsEmpty() && |
| 476 !m_commandLineAPIScope.get()); | 440 !m_commandLineAPIScope.get()); |
| 477 m_commandLineAPIScope.reset(new V8Console::CommandLineAPIScope( | 441 m_commandLineAPIScope.reset(new V8Console::CommandLineAPIScope( |
| 478 m_context, m_injectedScript->commandLineAPI(), m_context->Global())); | 442 m_context, m_injectedScript->commandLineAPI(), m_context->Global())); |
| 479 return true; | |
| 480 } | 443 } |
| 481 | 444 |
| 482 void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() { | 445 void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() { |
| 483 DCHECK(!m_ignoreExceptionsAndMuteConsole); | 446 DCHECK(!m_ignoreExceptionsAndMuteConsole); |
| 484 m_ignoreExceptionsAndMuteConsole = true; | 447 m_ignoreExceptionsAndMuteConsole = true; |
| 485 m_inspector->client()->muteMetrics(m_contextGroupId); | 448 m_inspector->client()->muteMetrics(m_contextGroupId); |
| 486 m_inspector->muteExceptions(m_contextGroupId); | 449 m_inspector->muteExceptions(m_contextGroupId); |
| 487 m_previousPauseOnExceptionsState = | 450 m_previousPauseOnExceptionsState = |
| 488 setPauseOnExceptionsState(v8::DebugInterface::NoBreakOnException); | 451 setPauseOnExceptionsState(v8::DebugInterface::NoBreakOnException); |
| 489 } | 452 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 516 InjectedScript::Scope::~Scope() { | 479 InjectedScript::Scope::~Scope() { |
| 517 if (m_ignoreExceptionsAndMuteConsole) { | 480 if (m_ignoreExceptionsAndMuteConsole) { |
| 518 setPauseOnExceptionsState(m_previousPauseOnExceptionsState); | 481 setPauseOnExceptionsState(m_previousPauseOnExceptionsState); |
| 519 m_inspector->client()->unmuteMetrics(m_contextGroupId); | 482 m_inspector->client()->unmuteMetrics(m_contextGroupId); |
| 520 m_inspector->unmuteExceptions(m_contextGroupId); | 483 m_inspector->unmuteExceptions(m_contextGroupId); |
| 521 } | 484 } |
| 522 if (m_userGesture) m_inspector->client()->endUserGesture(); | 485 if (m_userGesture) m_inspector->client()->endUserGesture(); |
| 523 cleanup(); | 486 cleanup(); |
| 524 } | 487 } |
| 525 | 488 |
| 526 InjectedScript::ContextScope::ContextScope(ErrorString* errorString, | 489 InjectedScript::ContextScope::ContextScope(V8InspectorImpl* inspector, |
| 527 V8InspectorImpl* inspector, | |
| 528 int contextGroupId, | 490 int contextGroupId, |
| 529 int executionContextId) | 491 int executionContextId) |
| 530 : InjectedScript::Scope(errorString, inspector, contextGroupId), | 492 : InjectedScript::Scope(inspector, contextGroupId), |
| 531 m_executionContextId(executionContextId) {} | 493 m_executionContextId(executionContextId) {} |
| 532 | 494 |
| 533 InjectedScript::ContextScope::~ContextScope() {} | 495 InjectedScript::ContextScope::~ContextScope() {} |
| 534 | 496 |
| 535 void InjectedScript::ContextScope::findInjectedScript( | 497 Response InjectedScript::ContextScope::findInjectedScript( |
| 536 V8InspectorSessionImpl* session) { | 498 V8InspectorSessionImpl* session) { |
| 537 m_injectedScript = | 499 return session->findInjectedScript(m_executionContextId, m_injectedScript); |
| 538 session->findInjectedScript(m_errorString, m_executionContextId); | |
| 539 } | 500 } |
| 540 | 501 |
| 541 InjectedScript::ObjectScope::ObjectScope(ErrorString* errorString, | 502 InjectedScript::ObjectScope::ObjectScope(V8InspectorImpl* inspector, |
| 542 V8InspectorImpl* inspector, | |
| 543 int contextGroupId, | 503 int contextGroupId, |
| 544 const String16& remoteObjectId) | 504 const String16& remoteObjectId) |
| 545 : InjectedScript::Scope(errorString, inspector, contextGroupId), | 505 : InjectedScript::Scope(inspector, contextGroupId), |
| 546 m_remoteObjectId(remoteObjectId) {} | 506 m_remoteObjectId(remoteObjectId) {} |
| 547 | 507 |
| 548 InjectedScript::ObjectScope::~ObjectScope() {} | 508 InjectedScript::ObjectScope::~ObjectScope() {} |
| 549 | 509 |
| 550 void InjectedScript::ObjectScope::findInjectedScript( | 510 Response InjectedScript::ObjectScope::findInjectedScript( |
| 551 V8InspectorSessionImpl* session) { | 511 V8InspectorSessionImpl* session) { |
| 552 std::unique_ptr<RemoteObjectId> remoteId = | 512 std::unique_ptr<RemoteObjectId> remoteId; |
| 553 RemoteObjectId::parse(m_errorString, m_remoteObjectId); | 513 Response response = RemoteObjectId::parse(m_remoteObjectId, &remoteId); |
| 554 if (!remoteId) return; | 514 if (!response.isSuccess()) return response; |
| 555 InjectedScript* injectedScript = | 515 InjectedScript* injectedScript = nullptr; |
| 556 session->findInjectedScript(m_errorString, remoteId.get()); | 516 response = session->findInjectedScript(remoteId.get(), injectedScript); |
| 557 if (!injectedScript) return; | 517 if (!response.isSuccess()) return response; |
| 558 m_objectGroupName = injectedScript->objectGroupName(*remoteId); | 518 m_objectGroupName = injectedScript->objectGroupName(*remoteId); |
| 559 if (!injectedScript->findObject(m_errorString, *remoteId, &m_object)) return; | 519 response = injectedScript->findObject(*remoteId, &m_object); |
| 520 if (!response.isSuccess()) return response; |
| 560 m_injectedScript = injectedScript; | 521 m_injectedScript = injectedScript; |
| 522 return Response::OK(); |
| 561 } | 523 } |
| 562 | 524 |
| 563 InjectedScript::CallFrameScope::CallFrameScope(ErrorString* errorString, | 525 InjectedScript::CallFrameScope::CallFrameScope(V8InspectorImpl* inspector, |
| 564 V8InspectorImpl* inspector, | |
| 565 int contextGroupId, | 526 int contextGroupId, |
| 566 const String16& remoteObjectId) | 527 const String16& remoteObjectId) |
| 567 : InjectedScript::Scope(errorString, inspector, contextGroupId), | 528 : InjectedScript::Scope(inspector, contextGroupId), |
| 568 m_remoteCallFrameId(remoteObjectId) {} | 529 m_remoteCallFrameId(remoteObjectId) {} |
| 569 | 530 |
| 570 InjectedScript::CallFrameScope::~CallFrameScope() {} | 531 InjectedScript::CallFrameScope::~CallFrameScope() {} |
| 571 | 532 |
| 572 void InjectedScript::CallFrameScope::findInjectedScript( | 533 Response InjectedScript::CallFrameScope::findInjectedScript( |
| 573 V8InspectorSessionImpl* session) { | 534 V8InspectorSessionImpl* session) { |
| 574 std::unique_ptr<RemoteCallFrameId> remoteId = | 535 std::unique_ptr<RemoteCallFrameId> remoteId; |
| 575 RemoteCallFrameId::parse(m_errorString, m_remoteCallFrameId); | 536 Response response = RemoteCallFrameId::parse(m_remoteCallFrameId, &remoteId); |
| 576 if (!remoteId) return; | 537 if (!response.isSuccess()) return response; |
| 577 m_frameOrdinal = static_cast<size_t>(remoteId->frameOrdinal()); | 538 m_frameOrdinal = static_cast<size_t>(remoteId->frameOrdinal()); |
| 578 m_injectedScript = session->findInjectedScript(m_errorString, remoteId.get()); | 539 return session->findInjectedScript(remoteId.get(), m_injectedScript); |
| 579 } | 540 } |
| 580 | 541 |
| 581 } // namespace v8_inspector | 542 } // namespace v8_inspector |
| OLD | NEW |