Tools/Debugger.Object

Debugger.Object

Debugger.Object インスタンスはデバッグ対象のオブジェクトを表し、その参照オブジェクトを検査および変更するためのリフレクション指向のメソッドを提供します。参照先のプロパティは、Debugger.Object インスタンスのプロパティとして直接表示されません。デバッガはDebugger.Object.prototype.getOwnPropertyDescriptorDebugger.Object.prototype.defineProperty のようなメソッドを介してのみデバッガにアクセスし、デバッガが誤ってリファレンスの getter と setter を呼び出さないようにします。

SpiderMonkey は、特定の Debugger インスタンスに提示する各デバッグオブジェクトに対して、Debugger.Object インスタンスを1つだけ作成します。つまり、デバッガが2つの異なるルートを介して同じオブジェクトに遭遇した場合 (おそらく2つの関数が同じオブジェクトで呼び出される)、SpiderMonkey は毎回同じ Debugger.Object インスタンスをデバッガに提示します。これは、デバッガが == 演算子を使用して、2つの Debugger.Object インスタンスが同じデバッグオブジェクトを参照していることを認識し、Debugger.Object インスタンスに独自のプロパティを配置して特定のデバッグオブジェクトに関するメタデータを格納できることを意味します。

異なるコンパートメントの JavaScript コードは、同じオブジェクトの異なるビューを持つことができます。たとえば Firefox では、特権区画内のコードは、コンテンツコードによってそのオブジェクトのプロパティに対して行われた再定義または拡張を伴わずにコンテンツ DOM 要素オブジェクトを認識します。デバッガのコードがデバッグ対象と同じように各オブジェクトを確実に見るために、各 Debugger.Object インスタンスは特定のコンパートメントから見えるようにその参照を表示します。この「表示コンパートメント」は、デバッガが指示対象をどのようにして来るかに合わせて選択されます。結果として、単一の Debugger インスタンスは実際には複数の Debugger.Object インスタンスを持つことができます。つまり、参照先が表示される各コンパートメントに1つです。

複数の Debugger インスタンスが同じコードをデバッグしている場合、各 Debugger は指定されたオブジェクトに対して個別の Debugger.Object インスタンスを取得します。これにより、各 Debugger インスタンスを使用するコードは、他のデバッガとの干渉を心配することなく、独自の Debugger.Object インスタンスに任意のプロパティを配置できます。

ほとんどの Debugger.Object インスタンスは、デバッガの動作と状態をデバッガに公開するプロセスで SpiderMonkey によって作成されますが、デバッガはDebugger.Object.prototype.makeDebuggeeValue を使用して、指定されたデバッグ対象オブジェクトの Debugger.Object インスタンスを作成するか、Debugger.Object.prototype.copy および Debugger.Object.prototype.create を使用して、デバッグ区画に新しいオブジェクトを作成します。

Debugger.Object インスタンスはガベージコレクタから参照先を保護します。Debugger.Object インスタンスが生存している限り、指示対象はそのまま残ります。これは、ガベージコレクションが Debugger.Object インスタンスに目に見える影響を与えないことを意味します。

Debugger.Object プロトタイプのAccessorプロパティ

Debugger.Object インスタンスは、プロトタイプから次のアクセサプロパティを継承します。

proto

参照先のプロトタイプ (新しい Debugger.Object インスタンス)、またはプロトタイプがない場合は null

class

指示対象の ECMAScript [[Class]] を表す文字列。

callable

参照先が呼び出し可能なオブジェクト (関数や関数プロキシなど) であれば true。そうでなければ false。

name

参照先の名前 (名前付き関数の場合)。指示対象が無名関数か全く関数でない場合、これは undefined です。

このアクセサは、
関数が (関数を囲みスコープ内の名前にバインドする) 関数宣言をインスタンス化した結果であるか、(関数を本体の内部でのみ名前にバインドする) 関数式を評価しているかにかかわらず、ソースコード内で function キーワードの後に現れた名前を返します。

displayName

指示対象が表示名を持つ関数であれば、指示対象の表示名。参照先が関数でない場合、または表示名がない場合は、これは undefined です。

関数に指定された名前がある場合、その表示名は指定された名前と同じです。この場合、displayNamename プロパティは等しくなります。

関数に名前がない場合、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<
parameterNames

指示対象がデバッグ関数の場合、そのパラメータの名前を文字列の配列として指定します。指示対象がデバッグ機能でないか、まったく機能していない場合、これは undefined です。

指示対象がパラメータ名を使用できないホスト関数である場合は、パラメータごとに1つの要素を持つ配列を返します。それぞれの配列は undefined です。

参照先が関数プロキシの場合は、空の配列を返します。

指示対象が非構造化パラメータを使用する場合、配列の要素はパラメータの構造を反映します。たとえば、参照先が次のように宣言された関数である場合、

function f(a, [b, c], {d, e:f}) { ... }

この Debugger.Object インスタンスの parameterNames プロパティの値は次のようになります。

["a", ["b", "c"], {d:"d", e:"f"}]
script

参照先がデバッグコードである関数の場合、Debugger.Script インスタンスとしての、その関数のスクリプトです。参照先が関数プロキシであるかデバッグコードでない場合、これは undefined です。

environment

参照先がデバッグコードである関数である場合、作成時にその関数を囲む字句環境を表す Debugger.Environment インスタンス。参照先が関数プロキシであるかデバッグコードでない場合、これは undefined です。

proxyHandler

参照先がデバッグコードによって割り当てられたハンドラオブジェクトのプロキシである場合、これはハンドラオブジェクトです。プロキシのプロパティのアクセスを実装するためにメソッドが呼び出されるオブジェクトです。指示対象が、デバッグコードによってハンドラオブジェクトが割り当てられたプロキシでない場合、これは null です。

proxyCallTrap

参照先がデバッグコードによってハンドラオブジェクトが割り当てられた関数プロキシの場合、これはコールトラップ関数です。これは関数プロキシが呼び出されたときに呼び出される関数です。指示対象が、デバッグコードによってハンドラオブジェクトが割り当てられた関数プロキシでない場合、これは null です。

proxyConstructTrap

対象オブジェクトがデバッグコードによって割り当てられた関数プロキシである場合、その構築トラップ関数、つまり関数プロキシが new の式を介して呼び出されるときに呼び出される関数。指示対象が、デバッグコードによってハンドラオブジェクトが割り当てられた関数プロキシでない場合、これは null です。

global

参照先が割り当てられたスコープのグローバルオブジェクトを参照する Debugger.Object インスタンス。これは、クロスコンパートメントラッパーをアンラップしません。参照先がラッパーである場合、結果はラッパーのグローバルであり、ラップされたオブジェクトのグローバルではありません。結果はラッパーを介さずにグローバルに直接参照されます。

hostAnnotations

参照先に関する追加のメタデータを提供する JavaScript オブジェクト。存在しない場合は null。メタデータオブジェクトは、この Debugger.Object インスタンスと同じコンパートメントにあります。同じメタデータオブジェクトが、指定された Debugger.Object インスタンスに対して毎回返されます。

典型的な JavaScript 組み込みは、アプリケーション固有の機能をスクリプトに公開するための「ホストオブジェクト」を提供します。hostAnnotations アクセサは、デバッガが関心を持っている可能性がある参照先に関する追加情報の埋め込みを調べます。返されるオブジェクトのプロパティの意味は、埋め込みまでです。 たとえば、Web ブラウザは、グローバルオブジェクトのホスト注釈を提供して、トップレベルのウィンドウ、iframe、および内部 JavaScript スコープを区別することがあります。

規約では、ホストアノテーションオブジェクトに文字列値の "type" プロパティがあり、これはオブジェクトのクラスと一緒に、参照先がどのようなものであるかを示します。ホストアノテーションオブジェクトの他のプロパティは、型に応じて詳細を提供します。たとえば、Firefox では、JavaScript モジュールのグローバルオブジェクトのメタデータオブジェクトは次のようになります。

{ "type":"jsm", "uri":"resource:://gre/modules/XPCOMUtils.jsm" }

Firefox はそのホストオブジェクトに対して [DebuggerHostAnnotationsForFirefox annotations] を提供します。

Debugger.Object プロトタイプの関数プロパティ

以下で説明する関数は、この値を使用して Debugger.Object インスタンスを参照する場合にのみ呼び出すことができます。他の種類のオブジェクトのメソッドとして使用することはできません。 この説明では、「この Debugger.Object インスタンスの参照先」を意味するために「参照先」が使用されています。

他に指定されていない限り、これらのメソッドは呼び出し関数ではありません。呼び出しによってデバッグコードが実行されると (ハンドラがデバッグコードであるアクセサプロパティを取得または設定するため、またはデバッグコードであるトラップを持つプロキシであるため)、コールは Debugger.DebuggeeWouldRun 例外をスローします。

getProperty(name)

参照先の名前付きプロパティの値を返します。名前がない場合は undefined を返します。名前は文字列でなければなりません。 結果はデバッグ値です。

setProperty(name,value)

値が存在しない場合はプロパティを作成します。名前は文字列でなければならず、値はデバッグ値でなければなりません。

getOwnPropertyDescriptor(name)

参照先のnameという名前のプロパティのプロパティ記述子を返します。指示対象にそのようなプロパティがない場合は undefined を返します。(この関数は標準の Object.getOwnPropertyDescriptor 関数のように動作しますが、検査対象オブジェクトは暗黙的です。返されたプロパティ記述子は、デバッガのグローバルオブジェクトにスコープされたコードによって割り当てられます
 (したがって、デバッガのコンパートメントにあります)。そしてその valuegetset プロパティ(存在する場合) は debuggee の値です)。

getOwnPropertyNames()

デバッガで Object.getOwnPropertyNames(referent) が呼び出され、その結果がデバッガのグローバルオブジェクトのスコープにコピーされたかのように、すべての参照先のプロパティを指定する文字列の配列を返します。

defineProperty(name,attributes)

プロパティディスクリプタ記述子で説明されているように、name という名前の参照先にプロパティを定義します。属性の valueget、および set プロパティはすべてデバッグ対象の値でなければなりません。(この関数は対象オブジェクトが暗黙的で、関数と記述子とは異なるコンパートメントにあることを除いて、Object.defineProperty のように動作します)。

defineProperties(properties)

properties によって与えられたプロパティを参照に追加します。(この関数はターゲットオブジェクトが暗黙的であることを除いて、Object.defineProperties のように動作し、properties 引数とは異なるコンパートメントにあります)。

deleteProperty(name)

参照の name という名前のプロパティを削除します。プロパティが正常に削除された場合、または参照先にそのようなプロパティがない場合は true を返します。プロパティが設定可能でない場合は false を返します。

seal()

レポジトリへのプロパティの追加や削除を防止します。そしてこの Debugger.Object インスタンスを返します。(この関数は標準の Object.seal 関数のように動作しますが、封印されるオブジェクトは暗黙的で、呼び出し元とは異なるコンパートメントにあります)。

freeze()

プロパティが参照に追加されたり参照から削除されたりするのを防ぎ、各プロパティを書き込み不能としてマークします。そしてこの Debugger.Object インスタンスを返します。(この関数は標準の Object.freeze 関数のように動作しますが、封印されるオブジェクトは暗黙的で、呼び出し元とは異なるコンパートメントにあります)。

preventExtensions()

レポジトリにプロパティが追加されないようにします。(この関数は標準の Object.preventExtensions 関数と同じように動作しますが、操作対象は暗黙的で、呼び出し元とは異なるコンパートメントになります)。

isSealed()

指示対象が封印されている場合、つまり拡張可能ではなく、すべてのプロパティが設定不可能とマークされている場合に true を返します。(この関数は標準の Object.isSealed 関数と同じように動作しますが、検査されるオブジェクトは暗黙的で、呼び出し元とは異なるコンパートメントにあります)。

isFrozen()

参照先が固定されている場合、つまり拡張可能ではなく、すべてのプロパティが設定不可能で読み取り専用であるとマークされている場合に true を返します。(この関数は標準の Object.isSealed 関数のように動作しますが、検査されるオブジェクトは暗黙的で、呼び出し元とは異なるコンパートメントにあります)。

isExtensible()

参照先が拡張可能である場合、つまり新しい参照先が定義可能な場合は true を返します。(この関数は標準の Object.isExtensible 関数のように動作しますが、検査されるオブジェクトは暗黙的で、呼び出し元とは異なるコンパートメントにあります)。

copy(value)

HTML5 の "構造化クローニング" アルゴリズムを適用して、参照オブジェクトのグローバルオブジェクト (したがって参照オブジェクトのコンパートメント) に値のコピーを作成し、そのコピーを参照する Debugger.Object インスタンスを返します。

これはプリミティブ値をそのまま返します。つまり、Debugger.Object.prototype.copy を「構造化クローニング」アルゴリズムの制限内で、汎用「デバッグ値からデバッグ対象値へ」変換関数として使用できます。

create(prototype, [properties])

参照オブジェクトのグローバル (したがって参照オブジェクトのコンパートメント) に新しいオブジェクトを作成し、そのオブジェクトを参照する Debugger.Object を返します。
新しいオブジェクトのプロトタイプは prototype であり、これは Debugger.Object インスタンスでなければなりません。
新しいオブジェクトのプロパティは、プロパティが Debugger.Object.prototype.defineProperties に渡されたかのように、properties によって指定されたもので、新しい Debugger.Object インスタンスが this の値として渡されます。

makeDebuggeeValue(value)

デバッグ対象の値を表す debuggee 値を返します。value がプリミティブの場合、そのまま返します。value がオブジェクトの場合、この Debugger.Object の参照先のコンパートメントで適切にラップされたオブジェクトを表す Debugger.Object インスタンスを返します。

value がオブジェクトの場合は、debuggee グローバルに割り当てられている必要はなく、デバッグ区画にも割り当てられている必要はありません。デバッガが debuggee 値として使用したい任意のオブジェクトにすることができます。

上で説明したように、各 Debugger.Object インスタンスは、特定のコンパートメントから見たときにその参照を提示します。
Debugger.Object がインスタンス化され、オブジェクト o が与えられた場合、d.makeDebuggeeValue(o) 呼び出しは、dの区画内のコードが示すようにoを表す Debugger.Object インスタンスを返します。

decompile([pretty])

指示対象がデバッグコードである関数である場合、その結果とその結果の参照関数に相当する関数定義の JavaScript ソースコードを文字列として返します。pretty が存在し、真であれば、インデントされたコードを改行で生成します。 参照先がデバッグコードである関数でない場合は、undefined を返します。

call(this,argument, ...)
指示対象が呼び出し可能である場合は、この値と引数の値を使用して呼び出すことができ、呼び出しがどのように完了したかを示す完了値を返します。これはデバッグ対象の値、あるいはコンストラクタとして参照先を呼び出すには { asConstructor: true } でなければなりません。SpiderMonkey は this の値自体を適切に提供します。各引数はデバッグ対象の値でなければなりません。現存するすべてのハンドラメソッド、ブレークポイント、ウォッチポイントなどは、呼び出し中も有効なままです。参照が呼び出し可能でない場合は、TypeError をスローします。この関数は、呼び出し関数の規則に従います。
apply(this,arguments)

指示対象が呼び出し可能である場合は、与えられたこの値と引数の引数値で呼び出され、呼び出しがどのように完了したかを示す完了値を返します。これはデバッグ対象の値、あるいは関数をコンストラクタとして呼び出すには { asConstructor: true } でなければなりません。SpiderMonkey は this の値自体を適切に提供します。引数は、デバッガの値の配列 (デバッガ内の配列) または空の配列として扱われる null または undefined のいずれかでなければなりません。現存するすべてのハンドラメソッド、ブレークポイント、ウォッチポイントなどは、呼び出し中も有効なままです。参照が呼び出し可能でない場合は、TypeError をスローします。この関数は、呼び出し関数の規則に従います。

evalInGlobal(code, [options])

指示対象がグローバルオブジェクトである場合、そのグローバル環境内のコードを評価し、どのように完了したかを記述する補完値を返します。 コードは文字列です。 現存するすべてのハンドラメソッド、ブレークポイント、ウォッチポイントなどは、呼び出し中も有効なままです。 この関数は、呼び出し関数の規則に従います。 参照先がグローバルオブジェクトでない場合は、TypeError 例外をスローします。

Use Strict ディレクティブが含まれている場合、コードは厳密なモードコードとして解釈されます。

コードが厳密なモードコードでない場合、変数宣言は参照グローバルオブジェクトに影響を与えます。(ECMAScript 仕様で使用されている用語では、評価コードの実行コンテキストの VariableEnvironment が参照先です)

options 引数は、Debugger.Frame.prototype.eval の場合と同じです。

evalInGlobalWithBindings(code,bindings, [options])

evalInGlobal に似ていますが、変数オブジェクトとして参照先を使用してコードを評価しますが、lexical 環境はオブジェクトバインディングからのバインディングで拡張されています。値が isvalue である namedname というバインディングの各自の enumerable プロパティについては、lexical 環境で、code が namedname で評価され、その値は isvalue である変数をインクルードします。各値はデバッグ値でなければなりません。(これは with 文と似ていません。コードはバインディングオブジェクトに何の影響も与えることなく、導入されたバインディングにアクセス、割り当て、削除することができます)。

このメソッドを使用すると、デバッガコードは、指定されたデバッグコードで参照可能な一時的なバインディングを導入することができます。また、既存のデバッグ環境を変更することなく、デバッガが保持するデバッグの値を参照できます。

evalInGlobal と同様に、evalInGlobalWithBindings に渡されたコードが厳密なモードコードでない場合、コードがバインディングに従って拡張された環境で評価されても、それに含まれる宣言はすべて参照対象グローバルオブジェクトに影響を与えます。(ECMAScript 仕様で使用されている条件では、非厳密な評価コードの実行コンテキストの VariableEnvironment が参照先であり、バインディングは評価コードの LexicalEnvironment である新しい宣言環境に表示されます)。

options 引数は、Debugger.Frame.prototype.eval の場合と同じです。

asEnvironment()

参照先がグローバルオブジェクトである場合は、参照先を表す Debugger.Environment インスタンスをコードを評価するための可変環境として返します。参照先がグローバルオブジェクトでない場合は、TypeError をスローします。

setObjectWatchpoint(handler)(future plan)

すべての参照先のプロパティにウォッチポイントを設定し、呼び出しハンドラのメソッドでイベントを報告します。この Debugger.Object インスタンスの以前のウォッチポイントハンドラはすべて置き換えられます。handler が null の場合、参照先は監視されなくなります。ハンドラには、以下のメソッドがあります。

add(frame,name,descriptor)

name という名前のプロパティが referent.Descriptor に追加されました。これは、Debugger.Object.prototype.defineProperty で受け入れられたソートのプロパティ記述子で、新たに追加されたプロパティの属性を与えます。

delete(frame,name)

name という名前のプロパティは、参照対象から削除されようとしています。

change(frame,name,oldDescriptor,newDescriptor)

参照先の既存の namedname という名前のプロパティは、oldDescriptor によって与えられたものから newDescriptor によって与えられたものに変更されています。このハンドラメソッドはその値以外のプロパティの属性が変更されている場合にのみ呼び出されます。値だけが変更されている場合、SpiderMonkey はハンドラの set メソッドを呼び出します。

set(frame,oldValue,newValue)

参照先の name という名前のデータプロパティは、値が oldValue から newValue へ変更されようとしています。

SpiderMonkey は、成功するデータプロパティへの代入に対してのみこのメソッドを呼び出します。書き込み不可能なデータプロパティへの割り当ては、デバッガに通知することなく失敗します。

extensionsPrevented(frame)

オブジェクトは、Object.preventExtensionsの呼び出しにより、拡張不可能になりました

すべてのウォッチポイントハンドラメソッドについて:

  • ハンドラ呼び出しは、this の値としてハンドラオブジェクト自体を受け取ります

  • Theframe 引数は現在のスタックフレームで、そのコードは報告されるオブジェクトに対して操作を実行しようとしています

  • メソッドが undefined を返した場合、SpiderMonkey はオブジェクトに対して通知された変更を行い、正常に実行を続行します。メソッドがオブジェクトを返す場合:

  • オブジェクトに値が true である superseded プロパティがある場合、SpiderMonkey は通知された変更を行いません

  • オブジェクトに resume プロパティがある場合、その値は再開値として取得され、実行の進行方法を示します (ただし、return 再開値はサポートされていません)

  • 与えられたメソッドがハンドラにない場合、そのソートのイベントは無視されます。ウォッチポイントを設定した後にハンドラにメソッドを追加する、またはハンドラからメソッドを削除することは、対応するイベントのレポートを有効または無効にするために、イベントが発生するたびにwatchpoint consultshandler のプロパティです

  • ハンドラのメソッドに渡される値はデバッグ値です。 Handlerのメソッドに渡される記述子は、デバッガのコンパートメント内の通常のオブジェクトですが、デバッガの値である記述子の valueget、および set プロパティは例外で、Debugger.Object.prototype.defineProperty によって期待される値の一種です

  • ウォッチポイントハンドラコールは、クロスコンパートメントなスレッド内コールです。コールはプロパティを変更したスレッドとインハンドラのメソッドのコンパートメント (通常はデバッガのコンパートメントと同じ) で行われます

新しいウォッチポイントは、この Debugger.Object インスタンスが属する Debugger インスタンスに属します。Debugger インスタンスを無効にすると、このウォッチポイントは無効になります。

clearObjectWatchpoint()(future plan)

指示対象に設定されているオブジェクトウォッチポイントをすべて削除します。

setPropertyWatchpoint(name,handler)(future plan)

コール先ハンドラのメソッドでイベントを報告する、参照先のプロパティー (name) にウォッチポイントを設定します。この Debugger.Object インスタンスのこのプロパティの以前のウォッチポイントハンドラが置き換えられます。handler が null の場合、プロパティは監視されなくなります。Handlerは、extensionsPrevented イベントを受け取らない点を除き、 Debugger.Object.prototype.setObjectWatchpoint について説明したとおりです。

clearPropertyWatchpoint(name)(future plan)

name という名前の参照先のプロパティに設定されているウォッチポイントをすべて削除します。

unwrap()

指示対象がこの Debugger.Object のコンパートメントのラップ解除が許可されているラッパーの場合は、ラップされたオブジェクトを参照する Debugger.Object インスタンスを返します。指示対象のラップを解除できない場合は null を返します。指示対象がラッパーでない場合は、この Debugger.Object インスタンスをそのまま返します。

unsafeDereference()

この Debugger.Object インスタンスの参照先を返します。

対象が内部オブジェクト (HTML5 Window オブジェクトなど) である場合は、対応する外部オブジェクト (HTML5 WindowProxy オブジェクトなど) を返します。これにより、unsafeDereference は、呼び出し関数を使用せずにデバッグコードで直接使用するのに適した値を生成するのに役立ちます。

このメソッドは、デバッガコードをデバッグコードから保護するための Debugger.Object インスタンスのメンブレンを貫通し、デバッガコードが Debugger.Object のリフレクション指向のインターフェイスではなく、標準のクロスコンパートメントラッパーを介してデバッグオブジェクトにアクセスできるようにします。このメソッドを使用すると、大きなコードベースをこの Debugger API に徐々に適合させることが容易になります。コードの適切な部分で Debugger.Object インスタンスを使用できますが、このメソッドを使用して直接更新されていないコードに直接オブジェクト参照を渡します。