OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "core/inspector/InjectedScript.h" | |
32 | |
33 #include "bindings/core/v8/ScriptFunctionCall.h" | |
34 #include "bindings/core/v8/V8Binding.h" | |
35 #include "core/inspector/InjectedScriptHost.h" | |
36 #include "core/inspector/InjectedScriptManager.h" | |
37 #include "core/inspector/InspectorTraceEvents.h" | |
38 #include "core/inspector/JSONParser.h" | |
39 #include "core/inspector/RemoteObjectId.h" | |
40 #include "core/inspector/v8/V8Debugger.h" | |
41 #include "core/inspector/v8/V8DebuggerClient.h" | |
42 #include "platform/JSONValues.h" | |
43 #include "platform/JSONValuesForV8.h" | |
44 #include "wtf/text/WTFString.h" | |
45 | |
46 using blink::TypeBuilder::Array; | |
47 using blink::TypeBuilder::Debugger::CallFrame; | |
48 using blink::TypeBuilder::Debugger::CollectionEntry; | |
49 using blink::TypeBuilder::Debugger::FunctionDetails; | |
50 using blink::TypeBuilder::Debugger::GeneratorObjectDetails; | |
51 using blink::TypeBuilder::Runtime::PropertyDescriptor; | |
52 using blink::TypeBuilder::Runtime::InternalPropertyDescriptor; | |
53 using blink::TypeBuilder::Runtime::RemoteObject; | |
54 | |
55 namespace blink { | |
56 | |
57 static PassRefPtr<TypeBuilder::Debugger::ExceptionDetails> toExceptionDetails(Pa
ssRefPtr<JSONObject> object) | |
58 { | |
59 String text; | |
60 if (!object->getString("text", &text)) | |
61 return nullptr; | |
62 | |
63 RefPtr<TypeBuilder::Debugger::ExceptionDetails> exceptionDetails = TypeBuild
er::Debugger::ExceptionDetails::create().setText(text); | |
64 String url; | |
65 if (object->getString("url", &url)) | |
66 exceptionDetails->setUrl(url); | |
67 int line = 0; | |
68 if (object->getNumber("line", &line)) | |
69 exceptionDetails->setLine(line); | |
70 int column = 0; | |
71 if (object->getNumber("column", &column)) | |
72 exceptionDetails->setColumn(column); | |
73 int originScriptId = 0; | |
74 object->getNumber("scriptId", &originScriptId); | |
75 | |
76 RefPtr<JSONArray> stackTrace = object->getArray("stackTrace"); | |
77 if (stackTrace && stackTrace->length() > 0) { | |
78 RefPtr<TypeBuilder::Array<TypeBuilder::Console::CallFrame>> frames = Typ
eBuilder::Array<TypeBuilder::Console::CallFrame>::create(); | |
79 for (unsigned i = 0; i < stackTrace->length(); ++i) { | |
80 RefPtr<JSONObject> stackFrame = stackTrace->get(i)->asObject(); | |
81 int lineNumber = 0; | |
82 stackFrame->getNumber("lineNumber", &lineNumber); | |
83 int column = 0; | |
84 stackFrame->getNumber("column", &column); | |
85 int scriptId = 0; | |
86 stackFrame->getNumber("scriptId", &scriptId); | |
87 if (i == 0 && scriptId == originScriptId) | |
88 originScriptId = 0; | |
89 | |
90 String sourceURL; | |
91 stackFrame->getString("scriptNameOrSourceURL", &sourceURL); | |
92 String functionName; | |
93 stackFrame->getString("functionName", &functionName); | |
94 | |
95 RefPtr<TypeBuilder::Console::CallFrame> callFrame = TypeBuilder::Con
sole::CallFrame::create() | |
96 .setFunctionName(functionName) | |
97 .setScriptId(String::number(scriptId)) | |
98 .setUrl(sourceURL) | |
99 .setLineNumber(lineNumber) | |
100 .setColumnNumber(column); | |
101 | |
102 frames->addItem(callFrame.release()); | |
103 } | |
104 exceptionDetails->setStackTrace(frames.release()); | |
105 } | |
106 if (originScriptId) | |
107 exceptionDetails->setScriptId(String::number(originScriptId)); | |
108 return exceptionDetails.release(); | |
109 } | |
110 | |
111 static void weakCallback(const v8::WeakCallbackInfo<InjectedScript>& data) | |
112 { | |
113 data.GetParameter()->dispose(); | |
114 } | |
115 | |
116 InjectedScript::InjectedScript(InjectedScriptManager* manager, v8::Local<v8::Con
text> context, v8::Local<v8::Object> object, V8DebuggerClient* client, PassRefPt
r<InjectedScriptNative> injectedScriptNative, int contextId) | |
117 : m_manager(manager) | |
118 , m_isolate(context->GetIsolate()) | |
119 , m_context(m_isolate, context) | |
120 , m_value(m_isolate, object) | |
121 , m_client(client) | |
122 , m_native(injectedScriptNative) | |
123 , m_contextId(contextId) | |
124 { | |
125 m_context.SetWeak(this, &weakCallback, v8::WeakCallbackType::kParameter); | |
126 } | |
127 | |
128 InjectedScript::~InjectedScript() | |
129 { | |
130 } | |
131 | |
132 void InjectedScript::evaluate(ErrorString* errorString, const String& expression
, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, boo
l generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuild
er::OptOutput<bool>* wasThrown, RefPtr<TypeBuilder::Debugger::ExceptionDetails>*
exceptionDetails) | |
133 { | |
134 v8::HandleScope handles(m_isolate); | |
135 ScriptFunctionCall function(m_client, context(), v8Value(), "evaluate"); | |
136 function.appendArgument(expression); | |
137 function.appendArgument(objectGroup); | |
138 function.appendArgument(includeCommandLineAPI); | |
139 function.appendArgument(returnByValue); | |
140 function.appendArgument(generatePreview); | |
141 makeEvalCall(errorString, function, result, wasThrown, exceptionDetails); | |
142 } | |
143 | |
144 void InjectedScript::callFunctionOn(ErrorString* errorString, const String& obje
ctId, const String& expression, const String& arguments, bool returnByValue, boo
l generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuild
er::OptOutput<bool>* wasThrown) | |
145 { | |
146 v8::HandleScope handles(m_isolate); | |
147 ScriptFunctionCall function(m_client, context(), v8Value(), "callFunctionOn"
); | |
148 function.appendArgument(objectId); | |
149 function.appendArgument(expression); | |
150 function.appendArgument(arguments); | |
151 function.appendArgument(returnByValue); | |
152 function.appendArgument(generatePreview); | |
153 makeEvalCall(errorString, function, result, wasThrown); | |
154 } | |
155 | |
156 void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, v8::Local<v8:
:Object> callFrames, bool isAsyncCallStack, const String& callFrameId, const Str
ing& expression, const String& objectGroup, bool includeCommandLineAPI, bool ret
urnByValue, bool generatePreview, RefPtr<RemoteObject>* result, TypeBuilder::Opt
Output<bool>* wasThrown, RefPtr<TypeBuilder::Debugger::ExceptionDetails>* except
ionDetails) | |
157 { | |
158 v8::HandleScope handles(m_isolate); | |
159 ScriptFunctionCall function(m_client, context(), v8Value(), "evaluateOnCallF
rame"); | |
160 function.appendArgument(callFrames); | |
161 function.appendArgument(isAsyncCallStack); | |
162 function.appendArgument(callFrameId); | |
163 function.appendArgument(expression); | |
164 function.appendArgument(objectGroup); | |
165 function.appendArgument(includeCommandLineAPI); | |
166 function.appendArgument(returnByValue); | |
167 function.appendArgument(generatePreview); | |
168 makeEvalCall(errorString, function, result, wasThrown, exceptionDetails); | |
169 } | |
170 | |
171 void InjectedScript::restartFrame(ErrorString* errorString, v8::Local<v8::Object
> callFrames, const String& callFrameId) | |
172 { | |
173 v8::HandleScope handles(m_isolate); | |
174 ScriptFunctionCall function(m_client, context(), v8Value(), "restartFrame"); | |
175 function.appendArgument(callFrames); | |
176 function.appendArgument(callFrameId); | |
177 RefPtr<JSONValue> resultValue; | |
178 makeCall(function, &resultValue); | |
179 if (resultValue) { | |
180 if (resultValue->type() == JSONValue::TypeString) { | |
181 resultValue->asString(errorString); | |
182 } else { | |
183 bool value; | |
184 ASSERT_UNUSED(value, resultValue->asBoolean(&value) && value); | |
185 } | |
186 return; | |
187 } | |
188 *errorString = "Internal error"; | |
189 } | |
190 | |
191 void InjectedScript::getStepInPositions(ErrorString* errorString, v8::Local<v8::
Object> callFrames, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugge
r::Location>>& positions) | |
192 { | |
193 v8::HandleScope handles(m_isolate); | |
194 ScriptFunctionCall function(m_client, context(), v8Value(), "getStepInPositi
ons"); | |
195 function.appendArgument(callFrames); | |
196 function.appendArgument(callFrameId); | |
197 RefPtr<JSONValue> resultValue; | |
198 makeCall(function, &resultValue); | |
199 if (resultValue) { | |
200 if (resultValue->type() == JSONValue::TypeString) { | |
201 resultValue->asString(errorString); | |
202 return; | |
203 } | |
204 if (resultValue->type() == JSONValue::TypeArray) { | |
205 positions = Array<TypeBuilder::Debugger::Location>::runtimeCast(resu
ltValue); | |
206 return; | |
207 } | |
208 } | |
209 *errorString = "Internal error"; | |
210 } | |
211 | |
212 void InjectedScript::setVariableValue(ErrorString* errorString, v8::Local<v8::Ob
ject> callFrames, const String* callFrameIdOpt, const String* functionObjectIdOp
t, int scopeNumber, const String& variableName, const String& newValueStr) | |
213 { | |
214 v8::HandleScope handles(m_isolate); | |
215 ScriptFunctionCall function(m_client, context(), v8Value(), "setVariableValu
e"); | |
216 if (callFrameIdOpt) { | |
217 function.appendArgument(callFrames); | |
218 function.appendArgument(*callFrameIdOpt); | |
219 } else { | |
220 function.appendArgument(false); | |
221 function.appendArgument(false); | |
222 } | |
223 if (functionObjectIdOpt) | |
224 function.appendArgument(*functionObjectIdOpt); | |
225 else | |
226 function.appendArgument(false); | |
227 function.appendArgument(scopeNumber); | |
228 function.appendArgument(variableName); | |
229 function.appendArgument(newValueStr); | |
230 RefPtr<JSONValue> resultValue; | |
231 makeCall(function, &resultValue); | |
232 if (!resultValue) { | |
233 *errorString = "Internal error"; | |
234 return; | |
235 } | |
236 if (resultValue->type() == JSONValue::TypeString) { | |
237 resultValue->asString(errorString); | |
238 return; | |
239 } | |
240 // Normal return. | |
241 } | |
242 | |
243 void InjectedScript::getFunctionDetails(ErrorString* errorString, const String&
functionId, RefPtr<FunctionDetails>* result) | |
244 { | |
245 v8::HandleScope handles(m_isolate); | |
246 ScriptFunctionCall function(m_client, context(), v8Value(), "getFunctionDeta
ils"); | |
247 function.appendArgument(functionId); | |
248 RefPtr<JSONValue> resultValue; | |
249 makeCall(function, &resultValue); | |
250 if (!resultValue || resultValue->type() != JSONValue::TypeObject) { | |
251 if (!resultValue->asString(errorString)) | |
252 *errorString = "Internal error"; | |
253 return; | |
254 } | |
255 *result = FunctionDetails::runtimeCast(resultValue); | |
256 } | |
257 | |
258 void InjectedScript::getGeneratorObjectDetails(ErrorString* errorString, const S
tring& objectId, RefPtr<GeneratorObjectDetails>* result) | |
259 { | |
260 v8::HandleScope handles(m_isolate); | |
261 ScriptFunctionCall function(m_client, context(), v8Value(), "getGeneratorObj
ectDetails"); | |
262 function.appendArgument(objectId); | |
263 RefPtr<JSONValue> resultValue; | |
264 makeCall(function, &resultValue); | |
265 if (!resultValue || resultValue->type() != JSONValue::TypeObject) { | |
266 if (!resultValue->asString(errorString)) | |
267 *errorString = "Internal error"; | |
268 return; | |
269 } | |
270 *result = GeneratorObjectDetails::runtimeCast(resultValue); | |
271 } | |
272 | |
273 void InjectedScript::getCollectionEntries(ErrorString* errorString, const String
& objectId, RefPtr<Array<CollectionEntry> >* result) | |
274 { | |
275 v8::HandleScope handles(m_isolate); | |
276 ScriptFunctionCall function(m_client, context(), v8Value(), "getCollectionEn
tries"); | |
277 function.appendArgument(objectId); | |
278 RefPtr<JSONValue> resultValue; | |
279 makeCall(function, &resultValue); | |
280 if (!resultValue || resultValue->type() != JSONValue::TypeArray) { | |
281 if (!resultValue->asString(errorString)) | |
282 *errorString = "Internal error"; | |
283 return; | |
284 } | |
285 *result = Array<CollectionEntry>::runtimeCast(resultValue); | |
286 } | |
287 | |
288 void InjectedScript::getProperties(ErrorString* errorString, const String& objec
tId, bool ownProperties, bool accessorPropertiesOnly, bool generatePreview, RefP
tr<Array<PropertyDescriptor>>* properties, RefPtr<TypeBuilder::Debugger::Excepti
onDetails>* exceptionDetails) | |
289 { | |
290 v8::HandleScope handles(m_isolate); | |
291 ScriptFunctionCall function(m_client, context(), v8Value(), "getProperties")
; | |
292 function.appendArgument(objectId); | |
293 function.appendArgument(ownProperties); | |
294 function.appendArgument(accessorPropertiesOnly); | |
295 function.appendArgument(generatePreview); | |
296 | |
297 RefPtr<JSONValue> result; | |
298 makeCallWithExceptionDetails(function, &result, exceptionDetails); | |
299 if (*exceptionDetails) { | |
300 // FIXME: make properties optional | |
301 *properties = Array<PropertyDescriptor>::create(); | |
302 return; | |
303 } | |
304 if (!result || result->type() != JSONValue::TypeArray) { | |
305 *errorString = "Internal error"; | |
306 return; | |
307 } | |
308 *properties = Array<PropertyDescriptor>::runtimeCast(result); | |
309 } | |
310 | |
311 void InjectedScript::getInternalProperties(ErrorString* errorString, const Strin
g& objectId, RefPtr<Array<InternalPropertyDescriptor>>* properties, RefPtr<TypeB
uilder::Debugger::ExceptionDetails>* exceptionDetails) | |
312 { | |
313 v8::HandleScope handles(m_isolate); | |
314 ScriptFunctionCall function(m_client, context(), v8Value(), "getInternalProp
erties"); | |
315 function.appendArgument(objectId); | |
316 | |
317 RefPtr<JSONValue> result; | |
318 makeCallWithExceptionDetails(function, &result, exceptionDetails); | |
319 if (*exceptionDetails) | |
320 return; | |
321 if (!result || result->type() != JSONValue::TypeArray) { | |
322 *errorString = "Internal error"; | |
323 return; | |
324 } | |
325 RefPtr<Array<InternalPropertyDescriptor> > array = Array<InternalPropertyDes
criptor>::runtimeCast(result); | |
326 if (array->length() > 0) | |
327 *properties = array; | |
328 } | |
329 | |
330 void InjectedScript::releaseObject(const String& objectId) | |
331 { | |
332 RefPtr<JSONValue> parsedObjectId = parseJSON(objectId); | |
333 if (!parsedObjectId) | |
334 return; | |
335 RefPtr<JSONObject> object; | |
336 if (!parsedObjectId->asObject(&object)) | |
337 return; | |
338 int boundId = 0; | |
339 if (!object->getNumber("id", &boundId)) | |
340 return; | |
341 m_native->unbind(boundId); | |
342 } | |
343 | |
344 PassRefPtr<Array<CallFrame>> InjectedScript::wrapCallFrames(v8::Local<v8::Object
> callFrames, int asyncOrdinal) | |
345 { | |
346 v8::HandleScope handles(m_isolate); | |
347 ScriptFunctionCall function(m_client, context(), v8Value(), "wrapCallFrames"
); | |
348 function.appendArgument(callFrames); | |
349 function.appendArgument(asyncOrdinal); | |
350 bool hadException = false; | |
351 v8::Local<v8::Value> callFramesValue = callFunctionWithEvalEnabled(function,
hadException); | |
352 ASSERT(!hadException); | |
353 RefPtr<JSONValue> result = toJSONValue(context(), callFramesValue); | |
354 if (result && result->type() == JSONValue::TypeArray) | |
355 return Array<CallFrame>::runtimeCast(result); | |
356 return Array<CallFrame>::create(); | |
357 } | |
358 | |
359 PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapObject(v8::Lo
cal<v8::Value> value, const String& groupName, bool generatePreview) const | |
360 { | |
361 v8::HandleScope handles(m_isolate); | |
362 ScriptFunctionCall function(m_client, context(), v8Value(), "wrapObject"); | |
363 function.appendArgument(value); | |
364 function.appendArgument(groupName); | |
365 function.appendArgument(canAccessInspectedWindow()); | |
366 function.appendArgument(generatePreview); | |
367 bool hadException = false; | |
368 v8::Local<v8::Value> r = callFunctionWithEvalEnabled(function, hadException)
; | |
369 if (hadException) | |
370 return nullptr; | |
371 RefPtr<JSONObject> rawResult = toJSONValue(context(), r)->asObject(); | |
372 return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult); | |
373 } | |
374 | |
375 PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapTable(v8::Loc
al<v8::Value> table, v8::Local<v8::Value> columns) const | |
376 { | |
377 v8::HandleScope handles(m_isolate); | |
378 ScriptFunctionCall function(m_client, context(), v8Value(), "wrapTable"); | |
379 function.appendArgument(canAccessInspectedWindow()); | |
380 function.appendArgument(table); | |
381 if (columns.IsEmpty()) | |
382 function.appendArgument(false); | |
383 else | |
384 function.appendArgument(columns); | |
385 bool hadException = false; | |
386 v8::Local<v8::Value> r = callFunctionWithEvalEnabled(function, hadException
); | |
387 if (hadException) | |
388 return nullptr; | |
389 RefPtr<JSONObject> rawResult = toJSONValue(context(), r)->asObject(); | |
390 return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult); | |
391 } | |
392 | |
393 v8::Local<v8::Value> InjectedScript::findObject(const RemoteObjectId& objectId)
const | |
394 { | |
395 return m_native->objectForId(objectId.id()); | |
396 } | |
397 | |
398 String InjectedScript::objectIdToObjectGroupName(const String& objectId) const | |
399 { | |
400 RefPtr<JSONValue> parsedObjectId = parseJSON(objectId); | |
401 if (!parsedObjectId) | |
402 return String(); | |
403 RefPtr<JSONObject> object; | |
404 if (!parsedObjectId->asObject(&object)) | |
405 return String(); | |
406 int boundId = 0; | |
407 if (!object->getNumber("id", &boundId)) | |
408 return String(); | |
409 return m_native->groupName(boundId); | |
410 } | |
411 | |
412 void InjectedScript::releaseObjectGroup(const String& objectGroup) | |
413 { | |
414 v8::HandleScope handles(m_isolate); | |
415 m_native->releaseObjectGroup(objectGroup); | |
416 if (objectGroup == "console") { | |
417 ScriptFunctionCall function(m_client, context(), v8Value(), "clearLastEv
aluationResult"); | |
418 bool hadException = false; | |
419 callFunctionWithEvalEnabled(function, hadException); | |
420 ASSERT(!hadException); | |
421 } | |
422 } | |
423 | |
424 void InjectedScript::setCustomObjectFormatterEnabled(bool enabled) | |
425 { | |
426 v8::HandleScope handles(m_isolate); | |
427 ScriptFunctionCall function(m_client, context(), v8Value(), "setCustomObject
FormatterEnabled"); | |
428 function.appendArgument(enabled); | |
429 RefPtr<JSONValue> result; | |
430 makeCall(function, &result); | |
431 } | |
432 | |
433 bool InjectedScript::canAccessInspectedWindow() const | |
434 { | |
435 v8::Local<v8::Context> callingContext = m_isolate->GetCallingContext(); | |
436 if (callingContext.IsEmpty()) | |
437 return true; | |
438 return m_client->callingContextCanAccessContext(callingContext, context()); | |
439 } | |
440 | |
441 v8::Local<v8::Context> InjectedScript::context() const | |
442 { | |
443 return m_context.Get(m_isolate); | |
444 } | |
445 | |
446 v8::Local<v8::Value> InjectedScript::v8Value() const | |
447 { | |
448 return m_value.Get(m_isolate); | |
449 } | |
450 | |
451 v8::Local<v8::Value> InjectedScript::callFunctionWithEvalEnabled(ScriptFunctionC
all& function, bool& hadException) const | |
452 { | |
453 v8::Local<v8::Context> localContext = context(); | |
454 v8::Context::Scope scope(localContext); | |
455 bool evalIsDisabled = !localContext->IsCodeGenerationFromStringsAllowed(); | |
456 // Temporarily enable allow evals for inspector. | |
457 if (evalIsDisabled) | |
458 localContext->AllowCodeGenerationFromStrings(true); | |
459 v8::Local<v8::Value> resultValue = function.call(hadException); | |
460 if (evalIsDisabled) | |
461 localContext->AllowCodeGenerationFromStrings(false); | |
462 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Update
Counters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data(
)); | |
463 return resultValue; | |
464 } | |
465 | |
466 void InjectedScript::makeCall(ScriptFunctionCall& function, RefPtr<JSONValue>* r
esult) | |
467 { | |
468 if (!canAccessInspectedWindow()) { | |
469 *result = JSONString::create("Can not access given context."); | |
470 return; | |
471 } | |
472 | |
473 bool hadException = false; | |
474 v8::Local<v8::Value> resultValue = callFunctionWithEvalEnabled(function, had
Exception); | |
475 | |
476 ASSERT(!hadException); | |
477 if (!hadException) { | |
478 *result = toJSONValue(function.context(), resultValue); | |
479 if (!*result) | |
480 *result = JSONString::create(String::format("Object has too long ref
erence chain(must not be longer than %d)", JSONValue::maxDepth)); | |
481 } else { | |
482 *result = JSONString::create("Exception while making a call."); | |
483 } | |
484 } | |
485 | |
486 void InjectedScript::makeEvalCall(ErrorString* errorString, ScriptFunctionCall&
function, RefPtr<TypeBuilder::Runtime::RemoteObject>* objectResult, TypeBuilder:
:OptOutput<bool>* wasThrown, RefPtr<TypeBuilder::Debugger::ExceptionDetails>* ex
ceptionDetails) | |
487 { | |
488 RefPtr<JSONValue> result; | |
489 makeCall(function, &result); | |
490 if (!result) { | |
491 *errorString = "Internal error: result value is empty"; | |
492 return; | |
493 } | |
494 if (result->type() == JSONValue::TypeString) { | |
495 result->asString(errorString); | |
496 ASSERT(errorString->length()); | |
497 return; | |
498 } | |
499 RefPtr<JSONObject> resultPair = result->asObject(); | |
500 if (!resultPair) { | |
501 *errorString = "Internal error: result is not an Object"; | |
502 return; | |
503 } | |
504 RefPtr<JSONObject> resultObj = resultPair->getObject("result"); | |
505 bool wasThrownVal = false; | |
506 if (!resultObj || !resultPair->getBoolean("wasThrown", &wasThrownVal)) { | |
507 *errorString = "Internal error: result is not a pair of value and wasThr
own flag"; | |
508 return; | |
509 } | |
510 if (wasThrownVal) { | |
511 RefPtr<JSONObject> objectExceptionDetails = resultPair->getObject("excep
tionDetails"); | |
512 if (objectExceptionDetails) | |
513 *exceptionDetails = toExceptionDetails(objectExceptionDetails.releas
e()); | |
514 } | |
515 *objectResult = TypeBuilder::Runtime::RemoteObject::runtimeCast(resultObj); | |
516 *wasThrown = wasThrownVal; | |
517 } | |
518 | |
519 void InjectedScript::makeCallWithExceptionDetails(ScriptFunctionCall& function,
RefPtr<JSONValue>* result, RefPtr<TypeBuilder::Debugger::ExceptionDetails>* exce
ptionDetails) | |
520 { | |
521 v8::TryCatch tryCatch(m_isolate); | |
522 v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling(); | |
523 if (tryCatch.HasCaught()) { | |
524 v8::Local<v8::Message> message = tryCatch.Message(); | |
525 String text = !message.IsEmpty() ? toCoreStringWithUndefinedOrNullCheck(
message->Get()) : "Internal error"; | |
526 *exceptionDetails = TypeBuilder::Debugger::ExceptionDetails::create().se
tText(text); | |
527 } else { | |
528 *result = toJSONValue(function.context(), resultValue); | |
529 if (!*result) | |
530 *result = JSONString::create(String::format("Object has too long ref
erence chain(must not be longer than %d)", JSONValue::maxDepth)); | |
531 } | |
532 } | |
533 | |
534 void InjectedScript::dispose() | |
535 { | |
536 m_manager->discardInjectedScript(m_contextId); | |
537 } | |
538 | |
539 } // namespace blink | |
OLD | NEW |