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