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 |