📄 debug-delay.js.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Default number of frames to include in the response to backtrace request.const kDefaultBacktraceLength = 10;const Debug = {};// Regular expression to skip "crud" at the beginning of a source line which is// not really code. Currently the regular expression matches whitespace and// comments.const sourceLineBeginningSkip = /^(?:[ \v\h]*(?:\/\*.*?\*\/)*)*/;// Debug events which can occour in the V8 JavaScript engine. These originate// from the API include file debug.h.Debug.DebugEvent = { Break: 1, Exception: 2, NewFunction: 3, BeforeCompile: 4, AfterCompile: 5 };// Types of exceptions that can be broken upon.Debug.ExceptionBreak = { All : 0, Uncaught: 1 };// The different types of steps.Debug.StepAction = { StepOut: 0, StepNext: 1, StepIn: 2, StepMin: 3, StepInMin: 4 };// The different types of scripts matching enum ScriptType in objects.h.Debug.ScriptType = { Native: 0, Extension: 1, Normal: 2 };function ScriptTypeFlag(type) { return (1 << type);}// Globals.var next_response_seq = 0;var next_break_point_number = 1;var break_points = [];var script_break_points = [];// Create a new break point object and add it to the list of break points.function MakeBreakPoint(source_position, opt_line, opt_column, opt_script_break_point) { var break_point = new BreakPoint(source_position, opt_line, opt_column, opt_script_break_point); break_points.push(break_point); return break_point;};// Object representing a break point.// NOTE: This object does not have a reference to the function having break// point as this would cause function not to be garbage collected when it is// not used any more. We do not want break points to keep functions alive.function BreakPoint(source_position, opt_line, opt_column, opt_script_break_point) { this.source_position_ = source_position; this.source_line_ = opt_line; this.source_column_ = opt_column; if (opt_script_break_point) { this.script_break_point_ = opt_script_break_point; } else { this.number_ = next_break_point_number++; } this.hit_count_ = 0; this.active_ = true; this.condition_ = null; this.ignoreCount_ = 0;};BreakPoint.prototype.number = function() { return this.number_;};BreakPoint.prototype.func = function() { return this.func_;};BreakPoint.prototype.source_position = function() { return this.source_position_;};BreakPoint.prototype.hit_count = function() { return this.hit_count_;};BreakPoint.prototype.active = function() { if (this.script_break_point()) { return this.script_break_point().active(); } return this.active_;};BreakPoint.prototype.condition = function() { if (this.script_break_point() && this.script_break_point().condition()) { return this.script_break_point().condition(); } return this.condition_;};BreakPoint.prototype.ignoreCount = function() { return this.ignoreCount_;};BreakPoint.prototype.script_break_point = function() { return this.script_break_point_;};BreakPoint.prototype.enable = function() { this.active_ = true;};BreakPoint.prototype.disable = function() { this.active_ = false;};BreakPoint.prototype.setCondition = function(condition) { this.condition_ = condition;};BreakPoint.prototype.setIgnoreCount = function(ignoreCount) { this.ignoreCount_ = ignoreCount;};BreakPoint.prototype.isTriggered = function(exec_state) { // Break point not active - not triggered. if (!this.active()) return false; // Check for conditional break point. if (this.condition()) { // If break point has condition try to evaluate it in the top frame. try { var mirror = exec_state.frame(0).evaluate(this.condition()); // If no sensible mirror or non true value break point not triggered. if (!(mirror instanceof ValueMirror) || !%ToBoolean(mirror.value_)) { return false; } } catch (e) { // Exception evaluating condition counts as not triggered. return false; } } // Update the hit count. this.hit_count_++; if (this.script_break_point_) { this.script_break_point_.hit_count_++; } // If the break point has an ignore count it is not triggered. if (this.ignoreCount_ > 0) { this.ignoreCount_--; return false; } // Break point triggered. return true;};// Function called from the runtime when a break point is hit. Returns true if// the break point is triggered and supposed to break execution.function IsBreakPointTriggered(break_id, break_point) { return break_point.isTriggered(MakeExecutionState(break_id));};// Object representing a script break point. The script is referenced by its// script name and the break point is represented as line and column.function ScriptBreakPoint(script_name, opt_line, opt_column) { this.script_name_ = script_name; this.line_ = opt_line || 0; this.column_ = opt_column; this.hit_count_ = 0; this.active_ = true; this.condition_ = null; this.ignoreCount_ = 0;};ScriptBreakPoint.prototype.number = function() { return this.number_;};ScriptBreakPoint.prototype.script_name = function() { return this.script_name_;};ScriptBreakPoint.prototype.line = function() { return this.line_;};ScriptBreakPoint.prototype.column = function() { return this.column_;};ScriptBreakPoint.prototype.hit_count = function() { return this.hit_count_;};ScriptBreakPoint.prototype.active = function() { return this.active_;};ScriptBreakPoint.prototype.condition = function() { return this.condition_;};ScriptBreakPoint.prototype.ignoreCount = function() { return this.ignoreCount_;};ScriptBreakPoint.prototype.enable = function() { this.active_ = true;};ScriptBreakPoint.prototype.disable = function() { this.active_ = false;};ScriptBreakPoint.prototype.setCondition = function(condition) { this.condition_ = condition;};ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) { this.ignoreCount_ = ignoreCount; // Set ignore count on all break points created from this script break point. for (var i = 0; i < break_points.length; i++) { if (break_points[i].script_break_point() === this) { break_points[i].setIgnoreCount(ignoreCount); } }};// Check whether a script matches this script break point. Currently this is// only based on script name.ScriptBreakPoint.prototype.matchesScript = function(script) { return this.script_name_ == script.name && script.line_offset <= this.line_ && this.line_ < script.line_offset + script.lineCount();};// Set the script break point in a script.ScriptBreakPoint.prototype.set = function (script) { var column = this.column(); var line = this.line(); // If the column is undefined the break is on the line. To help locate the // first piece of breakable code on the line try to find the column on the // line which contains some source. if (IS_UNDEFINED(column)) { var source_line = script.sourceLine(this.line()); // Allocate array for caching the columns where the actual source starts. if (!script.sourceColumnStart_) { script.sourceColumnStart_ = new Array(script.lineCount()); } // Fill cache if needed and get column where the actual source starts. if (IS_UNDEFINED(script.sourceColumnStart_[line])) { script.sourceColumnStart_[line] = source_line.match(sourceLineBeginningSkip)[0].length; } column = script.sourceColumnStart_[line]; } // Convert the line and column into an absolute position within the script. var pos = Debug.findScriptSourcePosition(script, this.line(), column); // Create a break point object and set the break point. break_point = MakeBreakPoint(pos, this.line(), this.column(), this); break_point.setIgnoreCount(this.ignoreCount()); %SetScriptBreakPoint(script, pos, break_point); return break_point;};// Clear all the break points created from this script break pointScriptBreakPoint.prototype.clear = function () { var remaining_break_points = []; for (var i = 0; i < break_points.length; i++) { if (break_points[i].script_break_point() && break_points[i].script_break_point() === this) { %ClearBreakPoint(break_points[i]); } else { remaining_break_points.push(break_points[i]); } } break_points = remaining_break_points;};// Function called from runtime when a new script is compiled to set any script// break points set in this script.function UpdateScriptBreakPoints(script) { for (var i = 0; i < script_break_points.length; i++) { if (script_break_points[i].script_name() == script.name) { script_break_points[i].set(script); } }};// Function called from the runtime to handle a debug request receiced from the// debugger. When this function is called the debugger is in the broken state// reflected by the exec_state parameter. When pending requests are handled the// parameter stopping indicate the expected running state.function ProcessDebugRequest(exec_state, request, stopping) { return exec_state.debugCommandProcessor().processDebugJSONRequest(request, stopping);}Debug.addListener = function(listener, opt_data) { if (!IS_FUNCTION(listener)) throw new Error('Parameters have wrong types.'); %AddDebugEventListener(listener, opt_data);};Debug.removeListener = function(listener) { if (!IS_FUNCTION(listener)) throw new Error('Parameters have wrong types.'); %RemoveDebugEventListener(listener);};Debug.breakExecution = function(f) { %Break();};Debug.breakLocations = function(f) { if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.'); return %GetBreakLocations(f);};// Returns a Script object. If the parameter is a function the return value// is the script in which the function is defined. If the parameter is a string// the return value is the script for which the script name has that string// value. If it is a regexp and there is a unique script whose name matches// we return that, otherwise undefined.Debug.findScript = function(func_or_script_name) { if (IS_FUNCTION(func_or_script_name)) { return %FunctionGetScript(func_or_script_name); } else if (IS_REGEXP(func_or_script_name)) { var scripts = Debug.scripts(); var last_result = null; var result_count = 0; for (var i in scripts) { var script = scripts[i]; if (func_or_script_name.test(script.name)) { last_result = script; result_count++; } } // Return the unique script matching the regexp. If there are more // than one we don't return a value since there is no good way to // decide which one to return. Returning a "random" one, say the // first, would introduce nondeterminism (or something close to it) // because the order is the heap iteration order. if (result_count == 1) { return last_result; } else { return undefined; } } else { return %GetScript(func_or_script_name); }};// Returns the script source. If the parameter is a function the return value// is the script source for the script in which the function is defined. If the// parameter is a string the return value is the script for which the script// name has that string value.Debug.scriptSource = function(func_or_script_name) { return this.findScript(func_or_script_name).source;};Debug.source = function(f) { if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.'); return %FunctionGetSourceCode(f);};Debug.assembler = function(f) { if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.'); return %FunctionGetAssemblerCode(f);};Debug.sourcePosition = function(f) { if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.'); return %FunctionGetScriptSourcePosition(f);};Debug.findFunctionSourcePosition = function(func, opt_line, opt_column) { var script = %FunctionGetScript(func); var script_offset = %FunctionGetScriptSourcePosition(func); return script.locationFromLine(opt_line, opt_column, script_offset).position;}// Returns the character position in a script based on a line number and an// optional position within that line.Debug.findScriptSourcePosition = function(script, opt_line, opt_column) { return script.locationFromLine(opt_line, opt_column).position;}Debug.findBreakPoint = function(break_point_number, remove) { var break_point; for (var i = 0; i < break_points.length; i++) { if (break_points[i].number() == break_point_number) { break_point = break_points[i]; // Remove the break point from the list if requested. if (remove) { break_points.splice(i, 1); } break; } } if (break_point) { return break_point; } else { return this.findScriptBreakPoint(break_point_number, remove); }};Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) { if (!IS_FUNCTION(func)) throw new Error('Parameters have wrong types.'); var source_position = this.findFunctionSourcePosition(func, opt_line, opt_column) - this.sourcePosition(func); // Find the script for the function. var script = %FunctionGetScript(func); // If the script for the function has a name convert this to a script break // point. if (script && script.name) { // Adjust the source position to be script relative. source_position += %FunctionGetScriptSourcePosition(func); // Find line and column for the position in the script and set a script // break point from that. var location = script.locationFromPosition(source_position); return this.setScriptBreakPoint(script.name, location.line, location.column, opt_condition); } else { // Set a break point directly on the function. var break_point = MakeBreakPoint(source_position, opt_line, opt_column); %SetFunctionBreakPoint(func, source_position, break_point); break_point.setCondition(opt_condition); return break_point.number(); }};Debug.enableBreakPoint = function(break_point_number) { var break_point = this.findBreakPoint(break_point_number, false); break_point.enable();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -