Debugger.Script¶
一个 Debugger.Script
实例可能引用调试目标中的字节码序列或 WebAssembly 代码块。对于前者,它是 Debugger API 对 JSAPI JSScript
对象的表示。这两种情况可以通过它们的 format
属性区分,属性值为 "js"
或 "wasm"
。
用于 JSScripts 的 Debugger.Script¶
对于引用 JSScript
的 Debugger.Script
实例,它们的 format
属性值为 "js"
。
以下每个内容都由一个 JSScript
对象表示
函数体——也就是说,函数中所有不包含在嵌套函数中的代码。
传递给
eval
的单个调用的代码,不包括该代码定义的任何函数的函数体。<script>
元素的内容。DOM 事件处理程序,无论是在 HTML 中嵌入还是由其他 JavaScript 代码附加到元素上。
出现在
javascript:
URL 中的代码。
当调试器发现调试目标代码的脚本时,Debugger 接口会构造 Debugger.Script
对象:通过 onNewScript
处理程序方法;通过 Debugger.Frame 的 script
属性;通过 Debugger.Object 实例的 functionScript
方法;等等。对于给定的 Debugger 实例,SpiderMonkey 为每个底层脚本对象正好构造一个 Debugger.Script
实例;调试器代码可以向脚本对象添加自己的属性并期望稍后找到它们,使用 ==
来确定两个表达式是否引用同一个脚本,等等。
(如果多个 Debugger 实例正在调试相同的代码,则每个 Debugger 为给定的脚本获取一个单独的 Debugger.Script
实例。这允许使用每个 Debugger 实例的代码在其 Debugger.Script
实例上放置任何它喜欢的属性,而无需担心干扰其他调试器。)
Debugger.Script
实例是对 JSScript 对象的强引用;它防止它引用的脚本被垃圾回收。
请注意,SpiderMonkey 可能会对等效的函数或已评估的代码使用相同的 Debugger.Script
实例——也就是说,表示相同源代码、在相同源文件中的相同位置、在相同词法环境中评估的脚本。
用于 WebAssembly 的 Debugger.Script¶
对于引用 WebAssembly 代码块的 Debugger.Script
实例,它们的 format
属性值为 "wasm"
。
目前仅表示通过 new WebAssembly.Module
评估的整个模块。
Debugger.Script
用于 WebAssembly 的对象在实例化新的 WebAssembly 模块时通过 onNewScript
发现,并通过 Debugger 实例上的 findScripts
方法发现。SpiderMonkey 为每个底层 WebAssembly 模块(每个 Debugger 实例)构造正好一个 Debugger.Script
。
Debugger.Script
实例是对底层 WebAssembly 模块的强引用;它防止它引用的模块被垃圾回收。
请注意,在撰写本文时,对 WebAssembly 的支持还处于非常初步的阶段。下面许多属性和方法都会抛出异常。
约定¶
对于下面属性和方法的描述,如果属性或方法的行为在引用 JSScript
的实例或引用 WebAssembly 代码块的实例之间存在差异,则文本将分为两个部分,分别以“如果实例引用 JSScript”和“如果实例引用 WebAssembly 代码”为标题。如果行为没有差异,则不会出现此类强调标题。
Debugger.Script 原型对象的访问器属性¶
Debugger.Script
实例从其原型继承以下访问器属性
isGeneratorFunction
如果此实例引用使用
function*
表达式或语句定义的函数的JSScript
,则为 true。否则为 false。isAsyncFunction
如果此实例引用使用
async function
表达式或语句定义的异步函数的JSScript
,则为 true。否则为 false。displayName
如果实例引用 JSScript,则为脚本的显示名称(如果存在)。如果脚本没有显示名称——例如,如果它是顶级
eval
脚本——则为undefined
。如果脚本的函数具有给定的名称,则其显示名称与其函数的给定名称相同。
如果脚本的函数没有名称,则 SpiderMonkey 会尝试根据其上下文推断一个合适的名称。例如
function f() {} // display name: f (the given name) var g = function () {}; // display name: g o.p = function () {}; // display name: o.p var q = { r: function () {} // display name: q.r };
请注意,显示名称可能不是正确的 JavaScript 标识符,甚至不是正确的表达式:即使函数没有立即赋值为某个变量或属性的值,我们也尝试找到有用的名称。因此,我们使用
a/b
来引用在 a 中定义的 b,并使用a<
来引用出现在分配给 a 的表达式的某个位置的函数。例如function h() { var i = function() {}; // display name: h/i f(function () {}); // display name: h/< } var s = f(function () {}); // display name: s<``</pre>
如果实例引用 WebAssembly 代码,则抛出
TypeError
。
url
如果实例引用 JSScript,则为加载此脚本代码的文件名或 URL。对于由
eval
或Function
构造函数创建的脚本,这可能是一个合成的文件名,以有效的 URL 开头,后跟跟踪代码如何引入系统的信息;整个字符串不是有效的 URL。对于Function.prototype
的脚本,这是null
。如果此Debugger.Script
的source
属性非null
,则它等于source.url
。如果实例引用 WebAssembly 代码,则抛出
TypeError
。
startLine
如果实例引用 JSScript,则为此脚本代码在
url
指定的文件或文档中开始的行号。lineCount
如果实例引用 JSScript,则为此脚本代码在
url
指定的文件或文档中占用的行数。source
如果实例引用 JSScript,则为表示生成此脚本的源代码的 Debugger.Source 实例。如果源代码未保留,则为
null
。如果实例引用 WebAssembly 代码,则为表示 WebAssembly 代码序列化文本格式的 Debugger.Source 实例。
sourceStart
如果实例引用 JSScript,则为
source
给出的 Debugger.Source 实例中此脚本代码开始处的字符;从零开始。如果这是一个函数的脚本,则这是源代码中function
令牌开始的索引。如果实例引用 WebAssembly 代码,则抛出
TypeError
。sourceLength
如果实例引用 JSScript,则为
source
给出的 Debugger.Source 实例中此脚本代码的长度(以字符为单位)。如果实例引用 WebAssembly 代码,则抛出
TypeError
。
global
如果实例引用 JSScript,则为引用此脚本运行的全局对象的 Debugger.Object 实例。结果直接引用全局对象,而不是通过包装器或
WindowProxy
(在 Firefox 中为“外部窗口”)。如果实例引用 WebAssembly 代码,则抛出
TypeError
。
format
如果实例引用 JSScript,则为
"js"
。如果实例引用 WebAssembly 代码,则为
"wasm"
。
Debugger.Script 原型对象的函数属性¶
下面描述的函数只能使用引用 Debugger.Script
实例的 this
值来调用;它们不能用作其他类型对象的的方法。
getAllOffsets()
如果实例引用的是 JSScript,则返回一个数组 L,描述此脚本中字节码指令偏移量和源代码位置之间的关系。L 是稀疏的,并以源代码行号为索引。如果源代码行号 line 没有代码,则 L 没有 line 属性。如果 line 有代码,则
L[line]
是该行字节码指令入口点的偏移量数组。例如,假设我们有一个脚本,其源代码如下所示
a=[] for (i=1; i < 10; i++) // It's hip to be square. a[i] = i*i;
对该代码调用
getAllOffsets()
可能会产生如下所示的数组[[0], [5, 20], , [10]]
此数组表示
第一行代码从脚本中的偏移量 0 开始;
for
语句头有两个入口点,偏移量分别为 5 和 20(用于仅执行一次的初始化和每次迭代开始时执行的循环测试);第三行没有代码;
第四行从偏移量 10 开始。
如果实例引用 WebAssembly 代码,则抛出
TypeError
。getAllColumnOffsets()
:如果实例引用的是 JSScript,则返回一个数组,描述此脚本中字节码指令偏移量和源代码位置之间的关系。与返回每行所有入口点的偏移量的 getAllOffsets() 不同,getAllColumnOffsets() 返回每个 (行,列) 对的所有入口点的偏移量。
数组的元素是对象,每个对象描述一个入口点,并包含以下属性
lineNumber:偏移量是其入口点的行号
columnNumber:偏移量是其入口点的基于 1 的列号
offset:入口点的字节码指令偏移量
例如,假设我们有一个脚本,其源代码如下所示
a=[] for (i=1; i < 10; i++) // It's hip to be square. a[i] = i*i;
对该代码调用
getAllColumnOffsets()
可能会产生如下所示的数组[{ lineNumber: 0, columnNumber: 1, offset: 0 }, { lineNumber: 1, columnNumber: 6, offset: 5 }, { lineNumber: 1, columnNumber: 11, offset: 20 }, { lineNumber: 3, columnNumber: 5, offset: 10 }]
如果实例引用 WebAssembly 代码,则抛出
TypeError
。getLineOffsets(line)
如果实例引用的是 JSScript,则返回一个字节码指令偏移量数组,表示源代码行 line 的入口点。如果脚本在该行没有可执行代码,则返回的数组为空。
getOffsetLocation(offset)
如果实例引用的是 JSScript,则返回一个对象,描述此脚本中 offset 处的字节码对应的源代码位置。该对象具有以下属性
lineNumber:偏移量是其入口点的行号
columnNumber:偏移量是其入口点的基于 1 的列号
isEntryPoint:如果偏移量是列入口点(如 getAllColumnOffsets() 所报告的那样),则为 true;否则为 false。
getOffsetsCoverage()
:如果实例引用的是 JSScript,则返回
null
或一个数组,其中包含所有操作码覆盖范围的信息。数组的元素是对象,每个对象描述一个操作码,并包含以下属性lineNumber:当前操作码的行号。
columnNumber:当前操作码的基于 1 的列号。
offset:当前操作码的字节码指令偏移量。
count:当前操作码执行的次数。
如果此脚本没有覆盖范围,或者没有进行检测,则此函数将返回
null
。要确保被调试者已进行检测,应将标志Debugger.collectCoverageInfo
设置为true
。如果实例引用 WebAssembly 代码,则抛出
TypeError
。getChildScripts()
如果实例引用的是 JSScript,则返回一个新数组,其元素是此脚本中每个函数的 Debugger.Script 对象。仅包含直接子项;嵌套子项可以通过遍历树来访问。
如果实例引用 WebAssembly 代码,则抛出
TypeError
。setBreakpoint(offset, handler)
如果实例引用的是 JSScript,则在此脚本的 offset 处的字节码指令处设置断点,并将命中情况报告给 handler 的
hit
方法。如果 offset 不是此脚本中的有效偏移量,则抛出错误。当执行到达给定指令时,SpiderMonkey 会调用 handler 的
hit
方法,并传递一个 Debugger.Frame 实例,表示当前正在执行的堆栈帧。hit
方法的返回值应为恢复值,确定执行应如何继续。可以在一个位置设置任意数量的断点;当控制权到达该点时,SpiderMonkey 会以未指定的顺序调用它们的处理程序。
任意数量的断点可以使用相同的 handler 对象。
断点处理程序方法调用是跨隔室、线程内调用:调用发生在命中断点的同一线程中,以及包含处理程序函数的隔室中(通常是调试器的隔室)。
新断点属于此脚本所属的 Debugger 实例。禁用 Debugger 实例会禁用此断点;从 Debugger 实例的被调试者集中删除全局变量会清除该 Debugger 实例在该全局变量的脚本中的所有断点。
getBreakpoints([offset])
如果实例引用的是 JSScript,则返回一个数组,其中包含在此脚本的 offset 处设置的所有断点的处理程序对象。如果省略 offset,则返回在此脚本中任何位置设置的所有断点的处理程序。如果 offset 存在,但不是此脚本中的有效偏移量,则抛出错误。
如果实例引用 WebAssembly 代码,则抛出
TypeError
。clearBreakpoint(handler, [offset])
如果实例引用的是 JSScript,则删除在此 Debugger 实例中使用 handler 作为其处理程序的所有断点。如果给定 offset,则仅删除在 offset 处设置并使用 handler 的断点;如果 offset 不是此脚本中的有效偏移量,则抛出错误。
请注意,如果使用其他处理程序对象的断点设置在与 handler 相同的位置,则这些断点将保留。
clearAllBreakpoints([offset])
如果实例引用的是 JSScript,则删除在此脚本中设置的所有断点。如果 offset 存在,则删除在此脚本的该偏移量处设置的所有断点;如果 offset 不是此脚本中的有效字节码偏移量,则抛出错误。
isInCatchScope([offset])
如果实例引用的是 JSScript,则如果此偏移量落在 try 块的范围内,则为
true
,否则为false
。如果实例引用 WebAssembly 代码,则抛出
TypeError
。
源元数据¶
- 生成自文件
js/src/doc/Debugger/Debugger.Script.md
- 水印
sha256:8816a4e8617be32c4ce7f3ae54970fe9c8a7d248175d215a8990ccff23e6efa9
- 变更集