Remote Debugging Protocol: Difference between revisions

m
Typos.
(Expand lexical environments example; mention iterators.)
m (Typos.)
Line 31: Line 31:
Every packet sent from the client has the form:
Every packet sent from the client has the form:


   { "to":<i>actor</i>, "type": <i>type</i>, ... }
   { "to":<i>actor</i>, "type":<i>type</i>, ... }


where <i>actor</i> is the actor to whom the packet is directed&mdash;actor names are always natural numbers&mdash;and <i>type</i> is a string specifying what sort of packet it is. Additional properties may be present, depending on <i>type</i>.
where <i>actor</i> is the actor to whom the packet is directed&mdash;actor names are always natural numbers&mdash;and <i>type</i> is a string specifying what sort of packet it is. Additional properties may be present, depending on <i>type</i>.
Line 43: Line 43:
If a packet is directed to an actor that no longer exists, the server sends a packet to the client of the following form:
If a packet is directed to an actor that no longer exists, the server sends a packet to the client of the following form:


   { "from":null, "type":"no-such-actor" }
   { "from":null, "error":"no-such-actor" }


Clients should silently ignore properties they do not recognize. We expect that, as the protocol evolves, we will specify new properties that can appear in existing packets, and experimental implementations will do the same.
Clients should silently ignore packet properties they do not recognize. We expect that, as the protocol evolves, we will specify new properties that can appear in existing packets, and experimental implementations will do the same.


= Requests and Replies =
= Requests and Replies =


In this protocol description, a <b>request</b> is a packet sent from the client which always elicits a single packet from the recipient, the <b>reply</b>. These terms indicate a simple pattern of communication: at any given time, either the client or actor is permitted to send a packet, but never both.
In this protocol description, a <b>request</b> is a packet sent from the client which always elicits a single packet from the recipient, the <b>reply</b>. These terms indicate a simple pattern of communication: at any given time, either the client or actor is permitted to send a packet to the other, but never both.


The client's communication with each actor is treated separately: the client may send a request to one actor, and then send a request to a different actor before receiving a reply from the first.
The client's communication with each actor is treated separately: the client may send a request to one actor, and then send a request to a different actor before receiving a reply from the first.


Any actor can send reply to a request it is unable to carry out with an <b>error reply</b> of the form:
Packets not described as requests or replies are part of some more complicated interaction, which should be spelled out in more detail.
 
Any actor can reply to a request it is unable to carry out with an <b>error reply</b> of the form:


   { "from":<i>actor</i>, "error":<i>name</i>, "message":<i>message</i> }
   { "from":<i>actor</i>, "error":<i>name</i>, "message":<i>message</i> }


where <i>name</i> is a JSON string naming what went wrong, and <i>message</i> is an English error message. Error <i>name</i>s are specified by the protocol; the client can use the name to identify which error condition arose. The <i>message</i> may vary from implementation to implementation, and should only be displayed to the user as a last resort, as the server lacks enough information about the user interface context to provide appropriate messages.
where <i>name</i> is a JSON string naming what went wrong, and <i>message</i> is an English error message. Error <i>name</i>s are specified by the protocol; the client can use the name to identify which error condition arose. The <i>message</i> may vary from implementation to implementation, and should only be displayed to the user as a last resort, as the server lacks enough information about the user interface context to provide appropriate messages.
Packets not described as requests or replies are part of some more complicated interaction, which should be spelled out in more detail.


= Grips =
= Grips =
Line 139: Line 139:
     "get":<i>getter</i>, "set":<i>setter</i> }
     "get":<i>getter</i>, "set":<i>setter</i> }


where <i>getter</i> and <i>setter</i> are grips on the property's getter and setter functions. These may be <tt>{ "type":"undefined" }</tt> if the property lacks the given accessor function.
where <i>getter</i> and <i>setter</i> are grips on the property's getter and setter functions. These may be <tt>{&nbsp;"type":"undefined"&nbsp;}</tt> if the property lacks the given accessor function.


For example, if the JavaScript program being debugged evaluates the expression:
For example, if the JavaScript program being debugged evaluates the expression:
Line 151: Line 151:
and sending a [[#Finding_An_Object's_Prototype_And_Properties|"prototype-and-properties"]] request to <i>actor</i> would produce the following reply:
and sending a [[#Finding_An_Object's_Prototype_And_Properties|"prototype-and-properties"]] request to <i>actor</i> would produce the following reply:


   { "from":<i>actor</i>, "prototype": { "type":"object", "class":"Object", "actor":<i>objproto-actor</i> },
   { "from":<i>actor</i>, "prototype":{ "type":"object", "class":"Object", "actor":<i>objproto-actor</i> },
     "own-properties": { "x":{ "enumerable":true, "configurable":true, "writeable":true, "value":10 },
     "own-properties":{ "x":{ "enumerable":true, "configurable":true, "writeable":true, "value":10 },
                        "y":{ "enumerable":true, "configurable":true, "writeable":true, "value":"kaiju" },
                      "y":{ "enumerable":true, "configurable":true, "writeable":true, "value":"kaiju" },
                        "a":{ "enumerable":true, "configurable":true,
                      "a":{ "enumerable":true, "configurable":true,
                              "get":{ "type":"object", "class":"Function", "actor":<i>getter-actor</i> }
                            "get":{ "type":"object", "class":"Function", "actor":<i>getter-actor</i> },
                            }
                            "set":{ "type":"undefined" }
                      }
                          }
                    }
   }
   }


Line 199: Line 200:
to which the grip actor replies:
to which the grip actor replies:


   { "from":<i>grip-actor</i>, "own-property-names": [ <i>name<i>, ... ] }
   { "from":<i>grip-actor</i>, "own-property-names":[ <i>name<i>, ... ] }


where each <i>name</i> is a string naming an own property of the object.
where each <i>name</i> is a string naming an own property of the object.
Line 332: Line 333:


   { "from":0, "application-type":"browser",
   { "from":0, "application-type":"browser",
     "contexts": [ { "actor":1, "title":"Fruits",
     "contexts":[ { "actor":1, "title":"Fruits",
                    "url":"http://www.example.com/fruits/" },
                  "url":"http://www.example.com/fruits/" },
                  { "actor":2, "title":"Bats",
                { "actor":2, "title":"Bats",
                    "url":"http://www.example.com/bats/" }]}
                  "url":"http://www.example.com/bats/" }]}


<i>(This may not be the right information to provide in these packets; suggestions very welcome. The point here is to give the debugger enough information to select which context it would like to debug without having to do too many round trips. Round trips are bad for UI responsiveness, but large packets are probably not a problem, so whatever would help to add, we should add.)</i>
<i>(This may not be the right information to provide in these packets; suggestions very welcome. The point here is to give the debugger enough information to select which context it would like to debug without having to do too many round trips. Round trips are bad for UI responsiveness, but large packets are probably not a problem, so whatever would help to add, we should add.)</i>
Line 484: Line 485:


   { "to":<i>thread</i>, "type":"resume",
   { "to":<i>thread</i>, "type":"resume",
     "pause-for": { "pre-return":true, "pre-throw":true } }
     "pause-for":{ "pre-return":true, "pre-throw":true } }


Certain pause types cause other pause types to be included automatically, if those pause types are not mentioned explicitly in <i>pause-types</i>:
Certain pause types cause other pause types to be included automatically, if those pause types are not mentioned explicitly in <i>pause-types</i>:
Line 745: Line 746:
then we would hit that breakpoint, eliciting a packet like the following:
then we would hit that breakpoint, eliciting a packet like the following:


   { "from":<i>thread</i>, "type":"paused": "actor":<i>pause-actor</i>,
   { "from":<i>thread</i>, "type":"paused", "actor":<i>pause-actor</i>,
     "why":{ "type":"breakpoint", "actors":[<i>breakpoint-actor</i>] },
     "why":{ "type":"breakpoint", "actors":[<i>breakpoint-actor</i>] },
     "frame":{ "actor":<i>frame-actor</i>, "depth":1, "id":1,
     "frame":{ "actor":<i>frame-actor</i>, "depth":1, "id":1,
               "type":"call", "where": { "url":"sample.js", "line":3 },
               "type":"call", "where":{ "url":"sample.js", "line":3 },
               "environment": { "type":"function", "actor":<i>g-frame-actor</i>,
               "environment":{ "type":"function", "actor":<i>g-frame-actor</i>,
                              "function":{ "type":"object", "class":"Function", "actor":<i>g-actor</i> },
                              "function":{ "type":"object", "class":"Function", "actor":<i>g-actor</i> },
                              "function-name":"g",
                              "function-name":"g",
                              "bindings":{ "mutable": { "y":"argument to g" } },
                              "bindings":{ "mutable":{ "y":"argument to g" } },
                              "parent": { "type":"function", "actor":<i>f-frame-actor</i>,
                              "parent":{ "type":"function", "actor":<i>f-frame-actor</i>,
                                          "function":{ "type":"object", "class":"Function", "actor":<i>f-actor</i> },
                                        "function":{ "type":"object", "class":"Function", "actor":<i>f-actor</i> },
                                          "function-name":"f",
                                        "function-name":"f",
                                          "bindings":{ "mutable": { "x":"argument to f" } },
                                        "bindings":{ "mutable":{ "x":"argument to f" } },
                                          "parent": { "type":"object", "actor":<i>global-code-actor</i>,
                                        "parent":{ "type":"object", "actor":<i>global-code-actor</i>,
                                                      "object":{ "type":"object", "class":"Global",
                                                    "object":{ "type":"object", "class":"Global",
                                                                  "actor":<i>global-object-actor</i> }
                                                              "actor":<i>global-object-actor</i> }
                                                    }
                                                  }
                                        }
                                      }
                            },
                            },
                         "callee":<i>g-actor</i>, "callee-name":"g",
                         "callee":<i>g-actor</i>, "callee-name":"g",
               "this":{ "type":"object", "class":"Function", "actor":<i>g-actor</i> },
               "this":{ "type":"object", "class":"Function", "actor":<i>g-actor</i> },
Confirmed users
496

edits