Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1568)

Side by Side Diff: third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp

Issue 2295913003: [DevTools] Switch from platform/v8_inspector to v8/v8-inspector.h. (Closed)
Patch Set: rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2011 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/V8RuntimeAgentImpl.h"
32
33 #include "platform/v8_inspector/InjectedScript.h"
34 #include "platform/v8_inspector/InspectedContext.h"
35 #include "platform/v8_inspector/RemoteObjectId.h"
36 #include "platform/v8_inspector/StringUtil.h"
37 #include "platform/v8_inspector/V8Compat.h"
38 #include "platform/v8_inspector/V8ConsoleMessage.h"
39 #include "platform/v8_inspector/V8Debugger.h"
40 #include "platform/v8_inspector/V8DebuggerAgentImpl.h"
41 #include "platform/v8_inspector/V8InspectorImpl.h"
42 #include "platform/v8_inspector/V8InspectorSessionImpl.h"
43 #include "platform/v8_inspector/V8StackTraceImpl.h"
44 #include "platform/v8_inspector/protocol/Protocol.h"
45 #include "platform/v8_inspector/public/V8InspectorClient.h"
46
47 namespace v8_inspector {
48
49 namespace V8RuntimeAgentImplState {
50 static const char customObjectFormatterEnabled[] = "customObjectFormatterEnabled ";
51 static const char runtimeEnabled[] = "runtimeEnabled";
52 };
53
54 using protocol::Runtime::RemoteObject;
55
56 static bool hasInternalError(ErrorString* errorString, bool hasError)
57 {
58 if (hasError)
59 *errorString = "Internal error";
60 return hasError;
61 }
62
63 namespace {
64
65 template<typename Callback>
66 class ProtocolPromiseHandler {
67 public:
68 static void add(V8InspectorImpl* inspector, v8::Local<v8::Context> context, v8::MaybeLocal<v8::Value> value, const String16& notPromiseError, int contextGro upId, int executionContextId, const String16& objectGroup, bool returnByValue, b ool generatePreview, std::unique_ptr<Callback> callback)
69 {
70 if (value.IsEmpty()) {
71 callback->sendFailure("Internal error");
72 return;
73 }
74 if (!value.ToLocalChecked()->IsPromise()) {
75 callback->sendFailure(notPromiseError);
76 return;
77 }
78 v8::Local<v8::Promise> promise = v8::Local<v8::Promise>::Cast(value.ToLo calChecked());
79 Callback* rawCallback = callback.get();
80 ProtocolPromiseHandler<Callback>* handler = new ProtocolPromiseHandler(i nspector, contextGroupId, executionContextId, objectGroup, returnByValue, genera tePreview, std::move(callback));
81 v8::Local<v8::Value> wrapper = handler->m_wrapper.Get(inspector->isolate ());
82
83 v8::Local<v8::Function> thenCallbackFunction = V8_FUNCTION_NEW_REMOVE_PR OTOTYPE(context, thenCallback, wrapper, 0).ToLocalChecked();
84 if (promise->Then(context, thenCallbackFunction).IsEmpty()) {
85 rawCallback->sendFailure("Internal error");
86 return;
87 }
88 v8::Local<v8::Function> catchCallbackFunction = V8_FUNCTION_NEW_REMOVE_P ROTOTYPE(context, catchCallback, wrapper, 0).ToLocalChecked();
89 if (promise->Catch(context, catchCallbackFunction).IsEmpty()) {
90 rawCallback->sendFailure("Internal error");
91 return;
92 }
93 }
94 private:
95 static void thenCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
96 {
97 ProtocolPromiseHandler<Callback>* handler = static_cast<ProtocolPromiseH andler<Callback>*>(info.Data().As<v8::External>()->Value());
98 DCHECK(handler);
99 v8::Local<v8::Value> value = info.Length() > 0 ? info[0] : v8::Local<v8: :Value>::Cast(v8::Undefined(info.GetIsolate()));
100 handler->m_callback->sendSuccess(handler->wrapObject(value), Maybe<proto col::Runtime::ExceptionDetails>());
101 }
102
103 static void catchCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
104 {
105 ProtocolPromiseHandler<Callback>* handler = static_cast<ProtocolPromiseH andler<Callback>*>(info.Data().As<v8::External>()->Value());
106 DCHECK(handler);
107 v8::Local<v8::Value> value = info.Length() > 0 ? info[0] : v8::Local<v8: :Value>::Cast(v8::Undefined(info.GetIsolate()));
108
109 std::unique_ptr<V8StackTraceImpl> stack = handler->m_inspector->debugger ()->captureStackTrace(true);
110 std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails = protocol::Runtime::ExceptionDetails::create()
111 .setExceptionId(handler->m_inspector->nextExceptionId())
112 .setText("Uncaught (in promise)")
113 .setLineNumber(stack && !stack->isEmpty() ? stack->topLineNumber() : 0)
114 .setColumnNumber(stack && !stack->isEmpty() ? stack->topColumnNumber () : 0)
115 .setException(handler->wrapObject(value))
116 .build();
117 if (stack)
118 exceptionDetails->setStackTrace(stack->buildInspectorObjectImpl());
119 if (stack && !stack->isEmpty())
120 exceptionDetails->setScriptId(toString16(stack->topScriptId()));
121 handler->m_callback->sendSuccess(handler->wrapObject(value), std::move(e xceptionDetails));
122 }
123
124 ProtocolPromiseHandler(V8InspectorImpl* inspector, int contextGroupId, int e xecutionContextId, const String16& objectGroup, bool returnByValue, bool generat ePreview, std::unique_ptr<Callback> callback)
125 : m_inspector(inspector)
126 , m_contextGroupId(contextGroupId)
127 , m_executionContextId(executionContextId)
128 , m_objectGroup(objectGroup)
129 , m_returnByValue(returnByValue)
130 , m_generatePreview(generatePreview)
131 , m_callback(std::move(callback))
132 , m_wrapper(inspector->isolate(), v8::External::New(inspector->isolate() , this))
133 {
134 m_wrapper.SetWeak(this, cleanup, v8::WeakCallbackType::kParameter);
135 }
136
137 static void cleanup(const v8::WeakCallbackInfo<ProtocolPromiseHandler<Callba ck>>& data)
138 {
139 if (!data.GetParameter()->m_wrapper.IsEmpty()) {
140 data.GetParameter()->m_wrapper.Reset();
141 data.SetSecondPassCallback(cleanup);
142 } else {
143 data.GetParameter()->m_callback->sendFailure("Promise was collected" );
144 delete data.GetParameter();
145 }
146 }
147
148 std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject(v8::Local<v8::Va lue> value)
149 {
150 ErrorString errorString;
151 InjectedScript::ContextScope scope(&errorString, m_inspector, m_contextG roupId, m_executionContextId);
152 if (!scope.initialize()) {
153 m_callback->sendFailure(errorString);
154 return nullptr;
155 }
156 std::unique_ptr<protocol::Runtime::RemoteObject> wrappedValue = scope.in jectedScript()->wrapObject(&errorString, value, m_objectGroup, m_returnByValue, m_generatePreview);
157 if (!wrappedValue) {
158 m_callback->sendFailure(errorString);
159 return nullptr;
160 }
161 return wrappedValue;
162 }
163
164 V8InspectorImpl* m_inspector;
165 int m_contextGroupId;
166 int m_executionContextId;
167 String16 m_objectGroup;
168 bool m_returnByValue;
169 bool m_generatePreview;
170 std::unique_ptr<Callback> m_callback;
171 v8::Global<v8::External> m_wrapper;
172 };
173
174 template<typename Callback>
175 bool wrapEvaluateResultAsync(InjectedScript* injectedScript, v8::MaybeLocal<v8:: Value> maybeResultValue, const v8::TryCatch& tryCatch, const String16& objectGro up, bool returnByValue, bool generatePreview, Callback* callback)
176 {
177 std::unique_ptr<RemoteObject> result;
178 Maybe<protocol::Runtime::ExceptionDetails> exceptionDetails;
179
180 ErrorString errorString;
181 injectedScript->wrapEvaluateResult(&errorString,
182 maybeResultValue,
183 tryCatch,
184 objectGroup,
185 returnByValue,
186 generatePreview,
187 &result,
188 &exceptionDetails);
189 if (errorString.isEmpty()) {
190 callback->sendSuccess(std::move(result), exceptionDetails);
191 return true;
192 }
193 callback->sendFailure(errorString);
194 return false;
195 }
196
197 int ensureContext(ErrorString* errorString, V8InspectorImpl* inspector, int cont extGroupId, const Maybe<int>& executionContextId)
198 {
199 int contextId;
200 if (executionContextId.isJust()) {
201 contextId = executionContextId.fromJust();
202 } else {
203 v8::HandleScope handles(inspector->isolate());
204 v8::Local<v8::Context> defaultContext = inspector->client()->ensureDefau ltContextInGroup(contextGroupId);
205 if (defaultContext.IsEmpty()) {
206 *errorString = "Cannot find default execution context";
207 return 0;
208 }
209 contextId = V8Debugger::contextId(defaultContext);
210 }
211 return contextId;
212 }
213
214 } // namespace
215
216 V8RuntimeAgentImpl::V8RuntimeAgentImpl(V8InspectorSessionImpl* session, protocol ::FrontendChannel* FrontendChannel, protocol::DictionaryValue* state)
217 : m_session(session)
218 , m_state(state)
219 , m_frontend(FrontendChannel)
220 , m_inspector(session->inspector())
221 , m_enabled(false)
222 {
223 }
224
225 V8RuntimeAgentImpl::~V8RuntimeAgentImpl()
226 {
227 }
228
229 void V8RuntimeAgentImpl::evaluate(
230 const String16& expression,
231 const Maybe<String16>& objectGroup,
232 const Maybe<bool>& includeCommandLineAPI,
233 const Maybe<bool>& silent,
234 const Maybe<int>& executionContextId,
235 const Maybe<bool>& returnByValue,
236 const Maybe<bool>& generatePreview,
237 const Maybe<bool>& userGesture,
238 const Maybe<bool>& awaitPromise,
239 std::unique_ptr<EvaluateCallback> callback)
240 {
241 ErrorString errorString;
242 int contextId = ensureContext(&errorString, m_inspector, m_session->contextG roupId(), executionContextId);
243 if (!errorString.isEmpty()) {
244 callback->sendFailure(errorString);
245 return;
246 }
247
248 InjectedScript::ContextScope scope(&errorString, m_inspector, m_session->con textGroupId(), contextId);
249 if (!scope.initialize()) {
250 callback->sendFailure(errorString);
251 return;
252 }
253
254 if (silent.fromMaybe(false))
255 scope.ignoreExceptionsAndMuteConsole();
256 if (userGesture.fromMaybe(false))
257 scope.pretendUserGesture();
258
259 if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI() ) {
260 callback->sendFailure(errorString);
261 return;
262 }
263
264 bool evalIsDisabled = !scope.context()->IsCodeGenerationFromStringsAllowed() ;
265 // Temporarily enable allow evals for inspector.
266 if (evalIsDisabled)
267 scope.context()->AllowCodeGenerationFromStrings(true);
268
269 v8::MaybeLocal<v8::Value> maybeResultValue;
270 v8::Local<v8::Script> script = m_inspector->compileScript(scope.context(), t oV8String(m_inspector->isolate(), expression), String16(), false);
271 if (!script.IsEmpty())
272 maybeResultValue = m_inspector->runCompiledScript(scope.context(), scrip t);
273
274 if (evalIsDisabled)
275 scope.context()->AllowCodeGenerationFromStrings(false);
276
277 // Re-initialize after running client's code, as it could have destroyed con text or session.
278 if (!scope.initialize()) {
279 callback->sendFailure(errorString);
280 return;
281 }
282
283 if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) {
284 wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue, scope. tryCatch(), objectGroup.fromMaybe(""), returnByValue.fromMaybe(false), generateP review.fromMaybe(false), callback.get());
285 return;
286 }
287 ProtocolPromiseHandler<EvaluateCallback>::add(
288 m_inspector,
289 scope.context(),
290 maybeResultValue,
291 "Result of the evaluation is not a promise",
292 m_session->contextGroupId(),
293 scope.injectedScript()->context()->contextId(),
294 objectGroup.fromMaybe(""),
295 returnByValue.fromMaybe(false),
296 generatePreview.fromMaybe(false),
297 std::move(callback));
298 }
299
300 void V8RuntimeAgentImpl::awaitPromise(
301 const String16& promiseObjectId,
302 const Maybe<bool>& returnByValue,
303 const Maybe<bool>& generatePreview,
304 std::unique_ptr<AwaitPromiseCallback> callback)
305 {
306 ErrorString errorString;
307 InjectedScript::ObjectScope scope(&errorString, m_inspector, m_session->cont extGroupId(), promiseObjectId);
308 if (!scope.initialize()) {
309 callback->sendFailure(errorString);
310 return;
311 }
312 ProtocolPromiseHandler<AwaitPromiseCallback>::add(
313 m_inspector,
314 scope.context(),
315 scope.object(),
316 "Could not find promise with given id",
317 m_session->contextGroupId(),
318 scope.injectedScript()->context()->contextId(),
319 scope.objectGroupName(),
320 returnByValue.fromMaybe(false),
321 generatePreview.fromMaybe(false),
322 std::move(callback));
323 }
324
325 void V8RuntimeAgentImpl::callFunctionOn(
326 const String16& objectId,
327 const String16& expression,
328 const Maybe<protocol::Array<protocol::Runtime::CallArgument>>& optionalArgum ents,
329 const Maybe<bool>& silent,
330 const Maybe<bool>& returnByValue,
331 const Maybe<bool>& generatePreview,
332 const Maybe<bool>& userGesture,
333 const Maybe<bool>& awaitPromise,
334 std::unique_ptr<CallFunctionOnCallback> callback)
335 {
336 ErrorString errorString;
337 InjectedScript::ObjectScope scope(&errorString, m_inspector, m_session->cont extGroupId(), objectId);
338 if (!scope.initialize()) {
339 callback->sendFailure(errorString);
340 return;
341 }
342
343 std::unique_ptr<v8::Local<v8::Value>[]> argv = nullptr;
344 int argc = 0;
345 if (optionalArguments.isJust()) {
346 protocol::Array<protocol::Runtime::CallArgument>* arguments = optionalAr guments.fromJust();
347 argc = arguments->length();
348 argv.reset(new v8::Local<v8::Value>[argc]);
349 for (int i = 0; i < argc; ++i) {
350 v8::Local<v8::Value> argumentValue;
351 if (!scope.injectedScript()->resolveCallArgument(&errorString, argum ents->get(i)).ToLocal(&argumentValue)) {
352 callback->sendFailure(errorString);
353 return;
354 }
355 argv[i] = argumentValue;
356 }
357 }
358
359 if (silent.fromMaybe(false))
360 scope.ignoreExceptionsAndMuteConsole();
361 if (userGesture.fromMaybe(false))
362 scope.pretendUserGesture();
363
364 v8::MaybeLocal<v8::Value> maybeFunctionValue = m_inspector->compileAndRunInt ernalScript(scope.context(), toV8String(m_inspector->isolate(), "(" + expression + ")"));
365 // Re-initialize after running client's code, as it could have destroyed con text or session.
366 if (!scope.initialize()) {
367 callback->sendFailure(errorString);
368 return;
369 }
370
371 if (scope.tryCatch().HasCaught()) {
372 wrapEvaluateResultAsync(scope.injectedScript(), maybeFunctionValue, scop e.tryCatch(), scope.objectGroupName(), false, false, callback.get());
373 return;
374 }
375
376 v8::Local<v8::Value> functionValue;
377 if (!maybeFunctionValue.ToLocal(&functionValue) || !functionValue->IsFunctio n()) {
378 callback->sendFailure("Given expression does not evaluate to a function" );
379 return;
380 }
381
382 v8::MaybeLocal<v8::Value> maybeResultValue = m_inspector->callFunction(funct ionValue.As<v8::Function>(), scope.context(), scope.object(), argc, argv.get());
383 // Re-initialize after running client's code, as it could have destroyed con text or session.
384 if (!scope.initialize()) {
385 callback->sendFailure(errorString);
386 return;
387 }
388
389 if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) {
390 wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue, scope. tryCatch(), scope.objectGroupName(), returnByValue.fromMaybe(false), generatePre view.fromMaybe(false), callback.get());
391 return;
392 }
393
394 ProtocolPromiseHandler<CallFunctionOnCallback>::add(
395 m_inspector,
396 scope.context(),
397 maybeResultValue,
398 "Result of the function call is not a promise",
399 m_session->contextGroupId(),
400 scope.injectedScript()->context()->contextId(),
401 scope.objectGroupName(),
402 returnByValue.fromMaybe(false),
403 generatePreview.fromMaybe(false),
404 std::move(callback));
405 }
406
407 void V8RuntimeAgentImpl::getProperties(
408 ErrorString* errorString,
409 const String16& objectId,
410 const Maybe<bool>& ownProperties,
411 const Maybe<bool>& accessorPropertiesOnly,
412 const Maybe<bool>& generatePreview,
413 std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>* res ult,
414 Maybe<protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>* inter nalProperties,
415 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails)
416 {
417 using protocol::Runtime::InternalPropertyDescriptor;
418
419 InjectedScript::ObjectScope scope(errorString, m_inspector, m_session->conte xtGroupId(), objectId);
420 if (!scope.initialize())
421 return;
422
423 scope.ignoreExceptionsAndMuteConsole();
424 if (!scope.object()->IsObject()) {
425 *errorString = "Value with given id is not an object";
426 return;
427 }
428
429 v8::Local<v8::Object> object = scope.object().As<v8::Object>();
430 scope.injectedScript()->getProperties(errorString, object, scope.objectGroup Name(), ownProperties.fromMaybe(false), accessorPropertiesOnly.fromMaybe(false), generatePreview.fromMaybe(false), result, exceptionDetails);
431 if (!errorString->isEmpty() || exceptionDetails->isJust() || accessorPropert iesOnly.fromMaybe(false))
432 return;
433 v8::Local<v8::Array> propertiesArray;
434 if (hasInternalError(errorString, !m_inspector->debugger()->internalProperti es(scope.context(), scope.object()).ToLocal(&propertiesArray)))
435 return;
436 std::unique_ptr<protocol::Array<InternalPropertyDescriptor>> propertiesProto colArray = protocol::Array<InternalPropertyDescriptor>::create();
437 for (uint32_t i = 0; i < propertiesArray->Length(); i += 2) {
438 v8::Local<v8::Value> name;
439 if (hasInternalError(errorString, !propertiesArray->Get(scope.context(), i).ToLocal(&name)) || !name->IsString())
440 return;
441 v8::Local<v8::Value> value;
442 if (hasInternalError(errorString, !propertiesArray->Get(scope.context(), i + 1).ToLocal(&value)))
443 return;
444 std::unique_ptr<RemoteObject> wrappedValue = scope.injectedScript()->wra pObject(errorString, value, scope.objectGroupName());
445 if (!wrappedValue)
446 return;
447 propertiesProtocolArray->addItem(InternalPropertyDescriptor::create()
448 .setName(toProtocolString(name.As<v8::String>()))
449 .setValue(std::move(wrappedValue)).build());
450 }
451 if (!propertiesProtocolArray->length())
452 return;
453 *internalProperties = std::move(propertiesProtocolArray);
454 }
455
456 void V8RuntimeAgentImpl::releaseObject(ErrorString* errorString, const String16& objectId)
457 {
458 InjectedScript::ObjectScope scope(errorString, m_inspector, m_session->conte xtGroupId(), objectId);
459 if (!scope.initialize())
460 return;
461 scope.injectedScript()->releaseObject(objectId);
462 }
463
464 void V8RuntimeAgentImpl::releaseObjectGroup(ErrorString*, const String16& object Group)
465 {
466 m_session->releaseObjectGroup(objectGroup);
467 }
468
469 void V8RuntimeAgentImpl::runIfWaitingForDebugger(ErrorString* errorString)
470 {
471 m_inspector->client()->runIfWaitingForDebugger(m_session->contextGroupId());
472 }
473
474 void V8RuntimeAgentImpl::setCustomObjectFormatterEnabled(ErrorString*, bool enab led)
475 {
476 m_state->setBoolean(V8RuntimeAgentImplState::customObjectFormatterEnabled, e nabled);
477 m_session->setCustomObjectFormatterEnabled(enabled);
478 }
479
480 void V8RuntimeAgentImpl::discardConsoleEntries(ErrorString*)
481 {
482 V8ConsoleMessageStorage* storage = m_inspector->ensureConsoleMessageStorage( m_session->contextGroupId());
483 storage->clear();
484 }
485
486 void V8RuntimeAgentImpl::compileScript(ErrorString* errorString,
487 const String16& expression,
488 const String16& sourceURL,
489 bool persistScript,
490 const Maybe<int>& executionContextId,
491 Maybe<String16>* scriptId,
492 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails)
493 {
494 if (!m_enabled) {
495 *errorString = "Runtime agent is not enabled";
496 return;
497 }
498 int contextId = ensureContext(errorString, m_inspector, m_session->contextGr oupId(), executionContextId);
499 if (!errorString->isEmpty())
500 return;
501 InjectedScript::ContextScope scope(errorString, m_inspector, m_session->cont extGroupId(), contextId);
502 if (!scope.initialize())
503 return;
504
505 if (!persistScript)
506 m_inspector->debugger()->muteScriptParsedEvents();
507 v8::Local<v8::Script> script = m_inspector->compileScript(scope.context(), t oV8String(m_inspector->isolate(), expression), sourceURL, false);
508 if (!persistScript)
509 m_inspector->debugger()->unmuteScriptParsedEvents();
510 if (script.IsEmpty()) {
511 if (scope.tryCatch().HasCaught())
512 *exceptionDetails = scope.injectedScript()->createExceptionDetails(e rrorString, scope.tryCatch(), String16(), false);
513 else
514 *errorString = "Script compilation failed";
515 return;
516 }
517
518 if (!persistScript)
519 return;
520
521 String16 scriptValueId = String16::fromInteger(script->GetUnboundScript()->G etId());
522 std::unique_ptr<v8::Global<v8::Script>> global(new v8::Global<v8::Script>(m_ inspector->isolate(), script));
523 m_compiledScripts[scriptValueId] = std::move(global);
524 *scriptId = scriptValueId;
525 }
526
527 void V8RuntimeAgentImpl::runScript(
528 const String16& scriptId,
529 const Maybe<int>& executionContextId,
530 const Maybe<String16>& objectGroup,
531 const Maybe<bool>& silent,
532 const Maybe<bool>& includeCommandLineAPI,
533 const Maybe<bool>& returnByValue,
534 const Maybe<bool>& generatePreview,
535 const Maybe<bool>& awaitPromise,
536 std::unique_ptr<RunScriptCallback> callback)
537 {
538 if (!m_enabled) {
539 callback->sendFailure("Runtime agent is not enabled");
540 return;
541 }
542
543 auto it = m_compiledScripts.find(scriptId);
544 if (it == m_compiledScripts.end()) {
545 callback->sendFailure("No script with given id");
546 return;
547 }
548
549 ErrorString errorString;
550 int contextId = ensureContext(&errorString, m_inspector, m_session->contextG roupId(), executionContextId);
551 if (!errorString.isEmpty()) {
552 callback->sendFailure(errorString);
553 return;
554 }
555
556 InjectedScript::ContextScope scope(&errorString, m_inspector, m_session->con textGroupId(), contextId);
557 if (!scope.initialize()) {
558 callback->sendFailure(errorString);
559 return;
560 }
561
562 if (silent.fromMaybe(false))
563 scope.ignoreExceptionsAndMuteConsole();
564
565 std::unique_ptr<v8::Global<v8::Script>> scriptWrapper = std::move(it->second );
566 m_compiledScripts.erase(it);
567 v8::Local<v8::Script> script = scriptWrapper->Get(m_inspector->isolate());
568 if (script.IsEmpty()) {
569 callback->sendFailure("Script execution failed");
570 return;
571 }
572
573 if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI() )
574 return;
575
576 v8::MaybeLocal<v8::Value> maybeResultValue = m_inspector->runCompiledScript( scope.context(), script);
577
578 // Re-initialize after running client's code, as it could have destroyed con text or session.
579 if (!scope.initialize())
580 return;
581
582 if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) {
583 wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue, scope. tryCatch(), objectGroup.fromMaybe(""), returnByValue.fromMaybe(false), generateP review.fromMaybe(false), callback.get());
584 return;
585 }
586 ProtocolPromiseHandler<RunScriptCallback>::add(
587 m_inspector,
588 scope.context(),
589 maybeResultValue.ToLocalChecked(),
590 "Result of the script execution is not a promise",
591 m_session->contextGroupId(),
592 scope.injectedScript()->context()->contextId(),
593 objectGroup.fromMaybe(""),
594 returnByValue.fromMaybe(false),
595 generatePreview.fromMaybe(false),
596 std::move(callback));
597 }
598
599 void V8RuntimeAgentImpl::restore()
600 {
601 if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled, false ))
602 return;
603 m_frontend.executionContextsCleared();
604 ErrorString error;
605 enable(&error);
606 if (m_state->booleanProperty(V8RuntimeAgentImplState::customObjectFormatterE nabled, false))
607 m_session->setCustomObjectFormatterEnabled(true);
608 }
609
610 void V8RuntimeAgentImpl::enable(ErrorString* errorString)
611 {
612 if (m_enabled)
613 return;
614 m_inspector->client()->beginEnsureAllContextsInGroup(m_session->contextGroup Id());
615 m_enabled = true;
616 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, true);
617 m_inspector->enableStackCapturingIfNeeded();
618 m_session->reportAllContexts(this);
619 V8ConsoleMessageStorage* storage = m_inspector->ensureConsoleMessageStorage( m_session->contextGroupId());
620 for (const auto& message : storage->messages())
621 reportMessage(message.get(), false);
622 }
623
624 void V8RuntimeAgentImpl::disable(ErrorString* errorString)
625 {
626 if (!m_enabled)
627 return;
628 m_enabled = false;
629 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false);
630 m_inspector->disableStackCapturingIfNeeded();
631 m_session->discardInjectedScripts();
632 reset();
633 m_inspector->client()->endEnsureAllContextsInGroup(m_session->contextGroupId ());
634 }
635
636 void V8RuntimeAgentImpl::reset()
637 {
638 m_compiledScripts.clear();
639 if (m_enabled) {
640 if (const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->conte xtGroup(m_session->contextGroupId())) {
641 for (auto& idContext : *contexts)
642 idContext.second->setReported(false);
643 }
644 m_frontend.executionContextsCleared();
645 }
646 }
647
648 void V8RuntimeAgentImpl::reportExecutionContextCreated(InspectedContext* context )
649 {
650 if (!m_enabled)
651 return;
652 context->setReported(true);
653 std::unique_ptr<protocol::Runtime::ExecutionContextDescription> description = protocol::Runtime::ExecutionContextDescription::create()
654 .setId(context->contextId())
655 .setName(context->humanReadableName())
656 .setOrigin(context->origin()).build();
657 if (!context->auxData().isEmpty())
658 description->setAuxData(protocol::DictionaryValue::cast(protocol::parseJ SON(context->auxData())));
659 m_frontend.executionContextCreated(std::move(description));
660 }
661
662 void V8RuntimeAgentImpl::reportExecutionContextDestroyed(InspectedContext* conte xt)
663 {
664 if (m_enabled && context->isReported()) {
665 context->setReported(false);
666 m_frontend.executionContextDestroyed(context->contextId());
667 }
668 }
669
670 void V8RuntimeAgentImpl::inspect(std::unique_ptr<protocol::Runtime::RemoteObject > objectToInspect, std::unique_ptr<protocol::DictionaryValue> hints)
671 {
672 if (m_enabled)
673 m_frontend.inspectRequested(std::move(objectToInspect), std::move(hints) );
674 }
675
676 void V8RuntimeAgentImpl::messageAdded(V8ConsoleMessage* message)
677 {
678 if (m_enabled)
679 reportMessage(message, true);
680 }
681
682 void V8RuntimeAgentImpl::reportMessage(V8ConsoleMessage* message, bool generateP review)
683 {
684 message->reportToFrontend(&m_frontend, m_session, generatePreview);
685 m_frontend.flush();
686 }
687
688 } // namespace v8_inspector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698