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

Side by Side Diff: sky/engine/bindings/core/v8/DebuggerScript.js

Issue 776743002: Make v8 inspector not crash (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years 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
« no previous file with comments | « no previous file | sky/engine/core/fetch/ImageResource.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2010 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 (function () {
32
33 var DebuggerScript = {};
34
35 DebuggerScript.PauseOnExceptionsState = {
36 DontPauseOnExceptions: 0,
37 PauseOnAllExceptions: 1,
38 PauseOnUncaughtExceptions: 2
39 };
40
41 DebuggerScript.ScopeInfoDetails = {
42 AllScopes: 0,
43 FastAsyncScopes: 1,
44 NoScopes: 2
45 };
46
47 DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.D ontPauseOnExceptions;
48 Debug.clearBreakOnException();
49 Debug.clearBreakOnUncaughtException();
50
51 DebuggerScript.getAfterCompileScript = function(eventData)
52 {
53 return DebuggerScript._formatScript(eventData.script_.script_);
54 }
55
56 DebuggerScript.getWorkerScripts = function()
57 {
58 var result = [];
59 var scripts = Debug.scripts();
60 for (var i = 0; i < scripts.length; ++i) {
61 var script = scripts[i];
62 // Workers don't share same V8 heap now so there is no need to complicat e stuff with
63 // the context id like we do to discriminate between scripts from differ ent pages.
64 // However we need to filter out v8 native scripts.
65 if (script.context_data && script.context_data === "worker")
66 result.push(DebuggerScript._formatScript(script));
67 }
68 return result;
69 }
70
71 DebuggerScript.getFunctionScopes = function(fun)
72 {
73 var mirror = MakeMirror(fun);
74 var count = mirror.scopeCount();
75 if (count == 0)
76 return null;
77 var result = [];
78 for (var i = 0; i < count; i++) {
79 var scopeDetails = mirror.scope(i).details();
80 var scopeObject = DebuggerScript._buildScopeObject(scopeDetails.type(), scopeDetails.object());
81 if (!scopeObject)
82 continue;
83 result.push({
84 type: scopeDetails.type(),
85 object: scopeObject
86 });
87 }
88 return result;
89 }
90
91 DebuggerScript.getCollectionEntries = function(object)
92 {
93 var mirror = MakeMirror(object, true /* transient */);
94 if (mirror.isMap())
95 return mirror.entries();
96 if (mirror.isSet()) {
97 var result = [];
98 var values = mirror.values();
99 for (var i = 0; i < values.length; ++i)
100 result.push({ value: values[i] });
101 return result;
102 }
103 }
104
105 DebuggerScript.getInternalProperties = function(value)
106 {
107 var properties = ObjectMirror.GetInternalProperties(value);
108 var result = [];
109 for (var i = 0; i < properties.length; i++) {
110 var mirror = properties[i];
111 result.push({
112 name: mirror.name(),
113 value: mirror.value().value()
114 });
115 }
116 return result;
117 }
118
119 DebuggerScript.setFunctionVariableValue = function(functionValue, scopeIndex, va riableName, newValue)
120 {
121 var mirror = MakeMirror(functionValue);
122 if (!mirror.isFunction())
123 throw new Error("Function value has incorrect type");
124 return DebuggerScript._setScopeVariableValue(mirror, scopeIndex, variableNam e, newValue);
125 }
126
127 DebuggerScript._setScopeVariableValue = function(scopeHolder, scopeIndex, variab leName, newValue)
128 {
129 var scopeMirror = scopeHolder.scope(scopeIndex);
130 if (!scopeMirror)
131 throw new Error("Incorrect scope index");
132 scopeMirror.setVariableValue(variableName, newValue);
133 return undefined;
134 }
135
136 DebuggerScript.getScripts = function(contextData)
137 {
138 var result = [];
139
140 if (!contextData)
141 return result;
142 var comma = contextData.indexOf(",");
143 if (comma === -1)
144 return result;
145 // Context data is a string in the following format:
146 // ("page"|"injected")","<page id>
147 var idSuffix = contextData.substring(comma); // including the comma
148
149 var scripts = Debug.scripts();
150 for (var i = 0; i < scripts.length; ++i) {
151 var script = scripts[i];
152 if (script.context_data && script.context_data.lastIndexOf(idSuffix) != -1)
153 result.push(DebuggerScript._formatScript(script));
154 }
155 return result;
156 }
157
158 DebuggerScript._formatScript = function(script)
159 {
160 var lineEnds = script.line_ends;
161 var lineCount = lineEnds.length;
162 var endLine = script.line_offset + lineCount - 1;
163 var endColumn;
164 // V8 will not count last line if script source ends with \n.
165 if (script.source[script.source.length - 1] === '\n') {
166 endLine += 1;
167 endColumn = 0;
168 } else {
169 if (lineCount === 1)
170 endColumn = script.source.length + script.column_offset;
171 else
172 endColumn = script.source.length - (lineEnds[lineCount - 2] + 1);
173 }
174
175 return {
176 id: script.id,
177 name: script.nameOrSourceURL(),
178 sourceURL: script.source_url,
179 sourceMappingURL: script.source_mapping_url,
180 source: script.source,
181 startLine: script.line_offset,
182 startColumn: script.column_offset,
183 endLine: endLine,
184 endColumn: endColumn,
185 isContentScript: !!script.context_data && script.context_data.indexOf("i njected") == 0
186 };
187 }
188
189 DebuggerScript.setBreakpoint = function(execState, info)
190 {
191 var positionAlignment = info.interstatementLocation ? Debug.BreakPositionAli gnment.BreakPosition : Debug.BreakPositionAlignment.Statement;
192 var breakId = Debug.setScriptBreakPointById(info.sourceID, info.lineNumber, info.columnNumber, info.condition, undefined, positionAlignment);
193
194 var locations = Debug.findBreakPointActualLocations(breakId);
195 if (!locations.length)
196 return undefined;
197 info.lineNumber = locations[0].line;
198 info.columnNumber = locations[0].column;
199 return breakId.toString();
200 }
201
202 DebuggerScript.removeBreakpoint = function(execState, info)
203 {
204 Debug.findBreakPoint(info.breakpointId, true);
205 }
206
207 DebuggerScript.pauseOnExceptionsState = function()
208 {
209 return DebuggerScript._pauseOnExceptionsState;
210 }
211
212 DebuggerScript.setPauseOnExceptionsState = function(newState)
213 {
214 DebuggerScript._pauseOnExceptionsState = newState;
215
216 if (DebuggerScript.PauseOnExceptionsState.PauseOnAllExceptions === newState)
217 Debug.setBreakOnException();
218 else
219 Debug.clearBreakOnException();
220
221 if (DebuggerScript.PauseOnExceptionsState.PauseOnUncaughtExceptions === newS tate)
222 Debug.setBreakOnUncaughtException();
223 else
224 Debug.clearBreakOnUncaughtException();
225 }
226
227 DebuggerScript.frameCount = function(execState)
228 {
229 return execState.frameCount();
230 }
231
232 DebuggerScript.currentCallFrame = function(execState, data)
233 {
234 var maximumLimit = data >> 2;
235 var scopeDetailsLevel = data & 3;
236
237 var frameCount = execState.frameCount();
238 if (maximumLimit && maximumLimit < frameCount)
239 frameCount = maximumLimit;
240 var topFrame = undefined;
241 for (var i = frameCount - 1; i >= 0; i--) {
242 var frameMirror = execState.frame(i);
243 topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFram e, scopeDetailsLevel);
244 }
245 return topFrame;
246 }
247
248 DebuggerScript.currentCallFrameByIndex = function(execState, index)
249 {
250 if (index < 0)
251 return undefined;
252 var frameCount = execState.frameCount();
253 if (index >= frameCount)
254 return undefined;
255 return DebuggerScript._frameMirrorToJSCallFrame(execState.frame(index), unde fined, DebuggerScript.ScopeInfoDetails.NoScopes);
256 }
257
258 DebuggerScript.stepIntoStatement = function(execState)
259 {
260 execState.prepareStep(Debug.StepAction.StepIn, 1);
261 }
262
263 DebuggerScript.stepOverStatement = function(execState, callFrame)
264 {
265 execState.prepareStep(Debug.StepAction.StepNext, 1);
266 }
267
268 DebuggerScript.stepOutOfFunction = function(execState, callFrame)
269 {
270 execState.prepareStep(Debug.StepAction.StepOut, 1);
271 }
272
273 // Returns array in form:
274 // [ 0, <v8_result_report> ] in case of success
275 // or [ 1, <general_error_message>, <compiler_message>, <line_number>, <column _number> ] in case of compile error, numbers are 1-based.
276 // or throws exception with message.
277 DebuggerScript.liveEditScriptSource = function(scriptId, newSource, preview)
278 {
279 var scripts = Debug.scripts();
280 var scriptToEdit = null;
281 for (var i = 0; i < scripts.length; i++) {
282 if (scripts[i].id == scriptId) {
283 scriptToEdit = scripts[i];
284 break;
285 }
286 }
287 if (!scriptToEdit)
288 throw("Script not found");
289
290 var changeLog = [];
291 try {
292 var result = Debug.LiveEdit.SetScriptSource(scriptToEdit, newSource, pre view, changeLog);
293 return [0, result];
294 } catch (e) {
295 if (e instanceof Debug.LiveEdit.Failure && "details" in e) {
296 var details = e.details;
297 if (details.type === "liveedit_compile_error") {
298 var startPosition = details.position.start;
299 return [1, String(e), String(details.syntaxErrorMessage), Number (startPosition.line), Number(startPosition.column)];
300 }
301 }
302 throw e;
303 }
304 }
305
306 DebuggerScript.clearBreakpoints = function(execState, info)
307 {
308 Debug.clearAllBreakPoints();
309 }
310
311 DebuggerScript.setBreakpointsActivated = function(execState, info)
312 {
313 Debug.debuggerFlags().breakPointsActive.setValue(info.enabled);
314 }
315
316 DebuggerScript.getScriptSource = function(eventData)
317 {
318 return eventData.script().source();
319 }
320
321 DebuggerScript.setScriptSource = function(eventData, source)
322 {
323 if (eventData.script().data() === "injected-script")
324 return;
325 eventData.script().setSource(source);
326 }
327
328 DebuggerScript.getScriptName = function(eventData)
329 {
330 return eventData.script().script_.nameOrSourceURL();
331 }
332
333 DebuggerScript.getBreakpointNumbers = function(eventData)
334 {
335 var breakpoints = eventData.breakPointsHit();
336 var numbers = [];
337 if (!breakpoints)
338 return numbers;
339
340 for (var i = 0; i < breakpoints.length; i++) {
341 var breakpoint = breakpoints[i];
342 var scriptBreakPoint = breakpoint.script_break_point();
343 numbers.push(scriptBreakPoint ? scriptBreakPoint.number() : breakpoint.n umber());
344 }
345 return numbers;
346 }
347
348 DebuggerScript.isEvalCompilation = function(eventData)
349 {
350 var script = eventData.script();
351 return (script.compilationType() === Debug.ScriptCompilationType.Eval);
352 }
353
354 // NOTE: This function is performance critical, as it can be run on every
355 // statement that generates an async event (like addEventListener) to support
356 // asynchronous call stacks. Thus, when possible, initialize the data lazily.
357 DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame, sc opeDetailsLevel)
358 {
359 // Stuff that can not be initialized lazily (i.e. valid while paused with a valid break_id).
360 // The frameMirror and scopeMirror can be accessed only while paused on the debugger.
361 var frameDetails = frameMirror.details();
362
363 var funcObject = frameDetails.func();
364 var sourcePosition = frameDetails.sourcePosition();
365 var thisObject = frameDetails.receiver();
366
367 var isAtReturn = !!frameDetails.isAtReturn();
368 var returnValue = isAtReturn ? frameDetails.returnValue() : undefined;
369
370 var scopeMirrors = (scopeDetailsLevel === DebuggerScript.ScopeInfoDetails.No Scopes ? [] : frameMirror.allScopes(scopeDetailsLevel === DebuggerScript.ScopeIn foDetails.FastAsyncScopes));
371 var scopeTypes = new Array(scopeMirrors.length);
372 var scopeObjects = new Array(scopeMirrors.length);
373 for (var i = 0; i < scopeMirrors.length; ++i) {
374 var scopeDetails = scopeMirrors[i].details();
375 scopeTypes[i] = scopeDetails.type();
376 scopeObjects[i] = scopeDetails.object();
377 }
378
379 // Calculated lazily.
380 var scopeChain;
381 var funcMirror;
382 var location;
383
384 function lazyScopeChain()
385 {
386 if (!scopeChain) {
387 scopeChain = [];
388 for (var i = 0, j = 0; i < scopeObjects.length; ++i) {
389 var scopeObject = DebuggerScript._buildScopeObject(scopeTypes[i] , scopeObjects[i]);
390 if (scopeObject) {
391 scopeTypes[j] = scopeTypes[i];
392 scopeChain[j] = scopeObject;
393 ++j;
394 }
395 }
396 scopeTypes.length = scopeChain.length;
397 scopeObjects = null; // Free for GC.
398 }
399 return scopeChain;
400 }
401
402 function lazyScopeTypes()
403 {
404 if (!scopeChain)
405 lazyScopeChain();
406 return scopeTypes;
407 }
408
409 function ensureFuncMirror()
410 {
411 if (!funcMirror) {
412 funcMirror = MakeMirror(funcObject);
413 if (!funcMirror.isFunction())
414 funcMirror = new UnresolvedFunctionMirror(funcObject);
415 }
416 return funcMirror;
417 }
418
419 function ensureLocation()
420 {
421 if (!location) {
422 var script = ensureFuncMirror().script();
423 if (script)
424 location = script.locationFromPosition(sourcePosition, true);
425 if (!location)
426 location = { line: 0, column: 0 };
427 }
428 return location;
429 }
430
431 function line()
432 {
433 return ensureLocation().line;
434 }
435
436 function column()
437 {
438 return ensureLocation().column;
439 }
440
441 function sourceID()
442 {
443 var script = ensureFuncMirror().script();
444 return script && script.id();
445 }
446
447 function scriptName()
448 {
449 var script = ensureFuncMirror().script();
450 return script && script.name();
451 }
452
453 function functionName()
454 {
455 var func = ensureFuncMirror();
456 if (!func.resolved())
457 return undefined;
458 var displayName;
459 var valueMirror = func.property("displayName").value();
460 if (valueMirror && valueMirror.isString())
461 displayName = valueMirror.value();
462 return displayName || func.name() || func.inferredName();
463 }
464
465 function evaluate(expression)
466 {
467 return frameMirror.evaluate(expression, false).value();
468 }
469
470 function restart()
471 {
472 return Debug.LiveEdit.RestartFrame(frameMirror);
473 }
474
475 function setVariableValue(scopeNumber, variableName, newValue)
476 {
477 return DebuggerScript._setScopeVariableValue(frameMirror, scopeNumber, v ariableName, newValue);
478 }
479
480 function stepInPositions()
481 {
482 var stepInPositionsV8 = frameMirror.stepInPositions();
483 var stepInPositionsProtocol;
484 if (stepInPositionsV8) {
485 stepInPositionsProtocol = [];
486 var script = ensureFuncMirror().script();
487 if (script) {
488 var scriptId = String(script.id());
489 for (var i = 0; i < stepInPositionsV8.length; i++) {
490 var item = {
491 scriptId: scriptId,
492 lineNumber: stepInPositionsV8[i].position.line,
493 columnNumber: stepInPositionsV8[i].position.column
494 };
495 stepInPositionsProtocol.push(item);
496 }
497 }
498 }
499 return JSON.stringify(stepInPositionsProtocol);
500 }
501
502 return {
503 "sourceID": sourceID,
504 "line": line,
505 "column": column,
506 "scriptName": scriptName,
507 "functionName": functionName,
508 "thisObject": thisObject,
509 "scopeChain": lazyScopeChain,
510 "scopeType": lazyScopeTypes,
511 "evaluate": evaluate,
512 "caller": callerFrame,
513 "restart": restart,
514 "setVariableValue": setVariableValue,
515 "stepInPositions": stepInPositions,
516 "isAtReturn": isAtReturn,
517 "returnValue": returnValue
518 };
519 }
520
521 DebuggerScript._buildScopeObject = function(scopeType, scopeObject)
522 {
523 var result;
524 switch (scopeType) {
525 case ScopeType.Local:
526 case ScopeType.Closure:
527 case ScopeType.Catch:
528 // For transient objects we create a "persistent" copy that contains
529 // the same properties.
530 // Reset scope object prototype to null so that the proto properties
531 // don't appear in the local scope section.
532 result = { __proto__: null };
533 var properties = MakeMirror(scopeObject, true /* transient */).propertie s();
534 for (var j = 0; j < properties.length; j++) {
535 var name = properties[j].name();
536 if (name.charAt(0) === ".")
537 continue; // Skip internal variables like ".arguments"
538 result[name] = properties[j].value_;
539 }
540 break;
541 case ScopeType.Global:
542 case ScopeType.With:
543 result = scopeObject;
544 break;
545 case ScopeType.Block:
546 // Unsupported yet. Mustn't be reachable.
547 break;
548 }
549 return result;
550 }
551
552 DebuggerScript.getPromiseDetails = function(eventData)
553 {
554 return {
555 "promise": eventData.promise().value(),
556 "parentPromise": eventData.parentPromise().value(),
557 "status": eventData.status()
558 };
559 }
560
561 // We never resolve Mirror by its handle so to avoid memory leaks caused by Mirr ors in the cache we disable it.
562 ToggleMirrorCache(false);
563
564 return DebuggerScript;
565 })();
OLDNEW
« no previous file with comments | « no previous file | sky/engine/core/fetch/ImageResource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698