michael@0: # General Conventions
michael@0:
michael@0: This page describes general conventions used in the [`Debugger`][debugger] API,
michael@0: and defines some terminology used throughout the specification.
michael@0:
michael@0:
michael@0: ## Properties
michael@0:
michael@0: Properties of objects that comprise the `Debugger` interface, and those
michael@0: that the interface creates, follow some general conventions:
michael@0:
michael@0: - Instances and prototypes are extensible; you can add your own properties
michael@0: and methods to them.
michael@0:
michael@0: - Properties are configurable. This applies to both "own" and prototype
michael@0: properties, and to both methods and data properties. (Leaving these
michael@0: properties open to redefinition will hopefully make it easier for
michael@0: JavaScript debugger code to cope with bugs, bug fixes, and changes in the
michael@0: interface over time.)
michael@0:
michael@0: - Method properties are writable.
michael@0:
michael@0: - We prefer inherited accessor properties to own data properties. Both are
michael@0: read using the same syntax, but inherited accessors seem like a more
michael@0: accurate reflection of what's going on. Unless otherwise noted, these
michael@0: properties have getters but no setters, as they cannot meaningfully be
michael@0: assigned to.
michael@0:
michael@0:
michael@0: ## Debuggee Values
michael@0:
michael@0: The `Debugger` interface follows some conventions to help debuggers safely
michael@0: inspect and modify the debuggee's objects and values. Primitive values are
michael@0: passed freely between debugger and debuggee; copying or wrapping is handled
michael@0: transparently. Objects received from the debuggee (including host objects
michael@0: like DOM elements) are fronted in the debugger by `Debugger.Object`
michael@0: instances, which provide reflection-oriented methods for inspecting their
michael@0: referents; see `Debugger.Object`, below.
michael@0:
michael@0: Of the debugger's objects, only `Debugger.Object` instances may be passed
michael@0: to the debuggee: when this occurs, the debuggee receives the
michael@0: `Debugger.Object`'s referent, not the `Debugger.Object` instance itself.
michael@0:
michael@0: In the descriptions below, the term "debuggee value" means either a
michael@0: primitive value or a `Debugger.Object` instance; it is a value that might
michael@0: be received from the debuggee, or that could be passed to the debuggee.
michael@0:
michael@0:
michael@0: ## Debuggee Code
michael@0:
michael@0: Each `Debugger` instance maintains a set of global objects that, taken
michael@0: together, comprise the debuggee. Code evaluated in the scope of a debuggee
michael@0: global object, directly or indirectly, is considered *debuggee code*.
michael@0: Similarly:
michael@0:
michael@0: - a *debuggee frame* is a frame running debuggee code;
michael@0:
michael@0: - a *debuggee function* is a function that closes over a debuggee
michael@0: global object (and thus the function's code is debuggee code);
michael@0:
michael@0: - a *debuggee environment* is an environment whose outermost
michael@0: enclosing environment is a debuggee global object; and
michael@0:
michael@0: - a *debuggee script* is a script containing debuggee code.
michael@0:
michael@0:
michael@0: ## Completion Values
michael@0:
michael@0: When a debuggee stack frame completes its execution, or when some sort
michael@0: of debuggee call initiated by the debugger finishes, the `Debugger`
michael@0: interface provides a value describing how the code completed; these are
michael@0: called *completion values*. A completion value has one of the
michael@0: following forms:
michael@0:
michael@0: { return: value }
michael@0: : The code completed normally, returning value. Value is a
michael@0: debuggee value.
michael@0:
michael@0: { yield: value }
michael@0: : (Not yet implemented.) The running code is a generator frame
michael@0: which has yielded value. Value is a debuggee value.
michael@0:
michael@0: { throw: value }
michael@0: : The code threw value as an exception. Value is a debuggee
michael@0: value.
michael@0:
michael@0: `null`
michael@0: : The code was terminated, as if by the "slow script" dialog box.
michael@0:
michael@0: If control reaches the end of a generator frame, the completion value is
michael@0: { throw: stop }
where stop is a
michael@0: `Debugger.Object` object representing the `StopIteration` object being
michael@0: thrown.
michael@0:
michael@0:
michael@0: ## Resumption Values
michael@0:
michael@0: As the debuggee runs, the `Debugger` interface calls various
michael@0: debugger-provided handler functions to report the debuggee's behavior.
michael@0: Some of these calls can return a value indicating how the debuggee's
michael@0: execution should continue; these are called *resumption values*. A
michael@0: resumption value has one of the following forms:
michael@0:
michael@0: `undefined`
michael@0: : The debuggee should continue execution normally.
michael@0:
michael@0: { return: value }
michael@0: : Return value immediately as the current value of the function.
michael@0: Value must be a debuggee value. (Most handler functions support
michael@0: this, except those whose descriptions say otherwise.) If the function
michael@0: was called as a constructor (that is, via a `new` expression), then
michael@0: value serves as the value returned by the function's body, not
michael@0: that produced by the `new` expression: if the value is not an object,
michael@0: the `new` expression returns the frame's `this` value.
michael@0:
michael@0: { yield: value }
michael@0: : (Not yet implemented.) Yield value immediately as the
michael@0: next value of the current frame, which must be a generator frame.
michael@0: Value is a debuggee value. The current frame must be a generator
michael@0: frame that has not yet completed in some other way. You may use `yield`
michael@0: resumption values to substitute a new value or one already yielded by a
michael@0: generator, or to make a generator yield additional values.
michael@0:
michael@0: { throw: value }
michael@0: : Throw value as an exception from the current bytecode
michael@0: instruction. Value must be a debuggee value.
michael@0:
michael@0: `null`
michael@0: : Terminate the debuggee, as if it had been cancelled by the "slow script"
michael@0: dialog box.
michael@0:
michael@0: If a function that would normally return a resumption value to indicate
michael@0: how the debuggee should continue instead throws an exception, we never
michael@0: propagate such an exception to the debuggee; instead, we call the
michael@0: associated `Debugger` instance's `uncaughtExceptionHook` property, as
michael@0: described below.
michael@0:
michael@0:
michael@0: ## The `Debugger.DebuggeeWouldRun` Exception
michael@0:
michael@0: Some debugger operations that appear to simply inspect the debuggee's state
michael@0: may actually cause debuggee code to run. For example, reading a variable
michael@0: might run a getter function on the global or on a `with` expression's
michael@0: operand; and getting an object's property descriptor will run a handler
michael@0: trap if the object is a proxy. To protect the debugger's integrity, only
michael@0: methods whose stated purpose is to run debuggee code can do so. These
michael@0: methods are called [invocation functions][inv fr], and they follow certain
michael@0: common conventions to report the debuggee's behavior safely. For other
michael@0: methods, if their normal operation would cause debuggee code to run, they
michael@0: throw an instance of the `Debugger.DebuggeeWouldRun` exception.
michael@0:
michael@0: A `Debugger.DebuggeeWouldRun` exception may have a `cause` property,
michael@0: providing more detailed information on why the debuggee would have run. The
michael@0: `cause` property's value is one of the following strings:
michael@0:
michael@0: cause value meaning
michael@0: -------------------- --------------------------------------------------------------------------------
michael@0: "proxy" Carrying out the operation would have caused a proxy handler to run.
michael@0: "getter" Carrying out the operation would have caused an object property getter to run.
michael@0: "setter" Carrying out the operation would have caused an object property setter to run.
michael@0:
michael@0: If the system can't determine why control attempted to enter the debuggee,
michael@0: it will leave the exception's `cause` property undefined.