4 **XPIDL** is an Interface Description Language used to specify XPCOM interface
7 Interface Description Languages (IDL) are used to describe interfaces in a
8 language- and machine-independent way. IDLs make it possible to define
9 interfaces which can then be processed by tools to autogenerate
10 language-dependent interface specifications.
12 An xpidl file is essentially just a series of declarations. At the top level,
13 we can define typedefs, native types, or interfaces. Interfaces may
14 furthermore contain typedefs, natives, methods, constants, or attributes.
15 Most declarations can have properties applied to them.
20 There are three ways to make types: a typedef, a native, or an interface. In
21 addition, there are a few built-in native types. The built-in native types
22 are those listed under the type_spec production above. The following is the
25 =========================== =============== =========================== ============================ ======================= =======================
26 IDL Type Javascript Type C++ in parameter C++ out parameter Rust in parameter Rust out parameter
27 =========================== =============== =========================== ============================ ======================= =======================
28 ``boolean`` boolean ``bool`` ``bool*`` ``bool`` ``*mut bool``
29 ``char`` string ``char`` ``char*`` ``c_char`` ``*mut c_char``
30 ``double`` number ``double`` ``double*`` ``f64`` ``*mut f64``
31 ``float`` number ``float`` ``float*`` ``f32`` ``*mut f32``
32 ``long`` number ``int32_t`` ``int32_t*`` ``i32`` ``*mut i32``
33 ``long long`` number ``int64_t`` ``int64_t*`` ``i64`` ``*mut i64``
34 ``octet`` number ``uint8_t`` ``uint8_t*`` ``u8`` ``*mut u8``
35 ``short`` number ``uint16_t`` ``uint16_t*`` ``u16`` ``*mut u16``
36 ``string`` [#strptr]_ string ``const char*`` ``char**`` ``*const c_char`` ``*mut *mut c_char``
37 ``unsigned long`` number ``uint32_t`` ``uint32_t*`` ``u32`` ``*mut u32``
38 ``unsigned long long`` number ``uint64_t`` ``uint64_t*`` ``u64`` ``*mut u64``
39 ``unsigned short`` number ``uint16_t`` ``uint16_t*`` ``u16`` ``*mut u16``
40 ``wchar`` string ``char16_t`` ``char16_t*`` ``i16`` ``*mut i16``
41 ``wstring`` [#strptr]_ string ``const char16_t*`` ``char16_t**`` ``*const i16`` ``*mut *mut i16``
42 ``MozExternalRefCountType`` number ``MozExternalRefCountType`` ``MozExternalRefCountType*`` ``u32`` ``*mut u32``
43 ``Array<T>`` [#array]_ array ``const nsTArray<T>&`` ``nsTArray<T>&`` ``*const ThinVec<T>`` ``*mut ThinVec<T>``
44 =========================== =============== =========================== ============================ ======================= =======================
48 Prefer using the string class types such as ``AString``, ``AUTF8String``
49 or ``ACString`` to this type. The behaviour of these types is documented
50 more in the :ref:`String Guide <stringguide.xpidl>`
54 The C++ or Rust exposed type ``T`` will be an owned variant. (e.g.
55 ``ns[C]String``, ``RefPtr<T>``, or ``uint32_t``)
57 ``string``, ``wstring``, ``[ptr] native`` and ``[ref] native`` are
58 unsupported as element types.
61 In addition to this list, nearly every IDL file includes ``nsrootidl.idl`` in
62 some fashion, which also defines the following types:
64 ======================= ======================= ======================= ======================= ======================= =======================
65 IDL Type Javascript Type C++ in parameter C++ out parameter Rust in parameter Rust out parameter
66 ======================= ======================= ======================= ======================= ======================= =======================
67 ``PRTime`` number ``uint64_t`` ``uint64_t*`` ``u64`` ``*mut u64``
68 ``nsresult`` number ``nsresult`` ``nsresult*`` ``u32`` [#rsresult]_ ``*mut u32``
69 ``size_t`` number ``uint32_t`` ``uint32_t*`` ``u32`` ``*mut u32``
70 ``voidPtr`` N/A ``void*`` ``void**`` ``*mut c_void`` ``*mut *mut c_void``
71 ``charPtr`` N/A ``char*`` ``char**`` ``*mut c_char`` ``*mut *mut c_char``
72 ``unicharPtr`` N/A ``char16_t*`` ``char16_t**`` ``*mut i16`` ``*mut *mut i16``
73 ``nsIDRef`` ID object ``const nsID&`` ``nsID*`` ``*const nsID`` ``*mut nsID``
74 ``nsIIDRef`` ID object ``const nsIID&`` ``nsIID*`` ``*const nsIID`` ``*mut nsIID``
75 ``nsCIDRef`` ID object ``const nsCID&`` ``nsCID*`` ``*const nsCID`` ``*mut nsCID``
76 ``nsIDPtr`` ID object ``const nsID*`` ``nsID**`` ``*const nsID`` ``*mut *mut nsID``
77 ``nsIIDPtr`` ID object ``const nsIID*`` ``nsIID**`` ``*const nsIID`` ``*mut *mut nsIID``
78 ``nsCIDPtr`` ID object ``const nsCID*`` ``nsCID**`` ``*const nsCID`` ``*mut *mut nsCID``
79 ``nsID`` N/A ``nsID`` ``nsID*`` N/A N/A
80 ``nsIID`` N/A ``nsIID`` ``nsIID*`` N/A N/A
81 ``nsCID`` N/A ``nsCID`` ``nsCID*`` N/A N/A
82 ``nsQIResult`` object ``void*`` ``void**`` ``*mut c_void`` ``*mut *mut c_void``
83 ``AUTF8String`` [#str]_ string ``const nsACString&`` ``nsACString&`` ``*const nsACString`` ``*mut nsACString``
84 ``ACString`` [#str]_ string ``const nsACString&`` ``nsACString&`` ``*const nsACString`` ``*mut nsACString``
85 ``AString`` [#str]_ string ``const nsAString&`` ``nsAString&`` ``*const nsAString`` ``*mut nsAString``
86 ``jsval`` any ``HandleValue`` ``MutableHandleValue`` N/A N/A
87 ``jsid`` N/A ``jsid`` ``jsid*`` N/A N/A
88 ``Promise`` Promise object ``dom::Promise*`` ``dom::Promise**`` N/A N/A
89 ======================= ======================= ======================= ======================= ======================= =======================
93 A bare ``u32`` is only for bare ``nsresult`` in/outparams in XPIDL. The
94 result should be wrapped as the ``nserror::nsresult`` type.
98 The behaviour of these types is documented more in the :ref:`String Guide
101 Typedefs in IDL are basically as they are in C or C++: you define first the
102 type that you want to refer to and then the name of the type. Types can of
103 course be one of the fundamental types, or any other type declared via a
104 typedef, interface, or a native type.
106 Native types are types which correspond to a given C++ type. Most native
107 types are not scriptable: if it is not present in the list above, then it is
108 certainly not scriptable (some of the above, particularly jsid, are not
111 The contents of the parentheses of a native type declaration (although native
112 declarations without parentheses are parsable, I do not trust that they are
113 properly handled by the xpidl handlers) is a string equivalent to the C++
114 type. XPIDL itself does not interpret this string, it just literally pastes
115 it anywhere the native type is used. The interpretation of the type can be
116 modified by using the ``[ptr]`` or ``[ref]`` attributes on the native
117 declaration. Other attributes are only intended for use in ``nsrootidl.idl``.
122 WebIDL interfaces are also valid XPIDL types. To declare a WebIDL interface in
125 .. code-block:: JavaScript
127 webidl InterfaceName;
129 WebIDL types will be passed as ``mozilla::dom::InterfaceName*`` when used as
130 in-parameters, as ``mozilla::dom::InterfaceName**`` when used as out or
131 inout-parameters, and as ``RefPtr<mozilla::dom::InterfaceName>`` when used as
136 Other WebIDL types (e.g. dictionaries, enums, and unions) are not currently
142 Constants must be attached to an interface. The only constants supported are
143 those which become integer types when compiled to source code; string constants
144 and floating point constants are currently not supported.
146 Often constants are used to describe a set of enum values. In cases like this
147 the ``cenum`` construct can be used to group constants together. Constants
148 grouped in a ``cenum`` will be reflected as-if they were declared directly on
149 the interface, in Rust and Javascript code.
151 .. code-block:: JavaScript
154 eSomeValue, // starts at 0
158 The number after the enum name, like ``: 8`` in the example above, defines the
159 width of enum values with the given type. The cenum's type may be referenced in
160 xpidl as ``nsIInterfaceName_MyCEnum``.
165 Interfaces are basically a collection of constants, methods, and attributes.
166 Interfaces can inherit from one-another, and every interface must eventually
167 inherit from ``nsISupports``.
172 Interfaces may have the following attributes:
177 The internal unique identifier for the interface. it must be unique, and the
178 uuid must be generated when creating the interface. After that, it doesn't need
179 to be changed any more.
181 Online tools such as http://mozilla.pettay.fi/cgi-bin/mozuuid.pl can help
182 generate UUIDs for new interfaces.
187 JavaScript classes are forbidden from implementing this interface. All child
188 interfaces must also be marked with this property.
193 The JavaScript implementation of this interface may be a function that is
194 invoked on property calls instead of an object with the given property
199 This interface is usable by JavaScript classes. Must inherit from a
200 ``scriptable`` interface.
205 This interface is safe to use from multiple threads concurrently. All child
206 interfaces must also be marked with this property. Interfaces marked this way
207 must be either non-scriptable or ``builtinclass``, and must use threadsafe
210 Interfaces marked as ``rust_sync`` will implement the ``Sync`` trait in Rust.
211 For more details on what that means, read the trait's documentation:
212 https://doc.rust-lang.org/nightly/std/marker/trait.Sync.html.
214 Methods and Attributes
215 ~~~~~~~~~~~~~~~~~~~~~~
217 Interfaces declare a series of attributes and methods. Attributes in IDL are
218 akin to JavaScript properties, in that they are a getter and (optionally) a
219 setter pair. In JavaScript contexts, attributes are exposed as a regular
220 property access, while native code sees attributes as a Get and possibly a Set
223 Attributes can be declared readonly, in which case setting causes an error to
224 be thrown in script contexts and native contexts lack the Set method, by using
225 the ``readonly`` keyword.
227 To native code, on attribute declared ``attribute type foo;`` is syntactic
228 sugar for the declaration of two methods ``type getFoo();`` and ``void
229 setFoo(in type foo);``. If ``foo`` were declared readonly, the latter method
230 would not be present. Attributes support all of the properties of methods with
231 the exception of ``optional_argc``, as this does not make sense for attributes.
233 There are some special rules for attribute naming. As a result of vtable
234 munging by the MSVC++ compiler, an attribute with the name ``IID`` is
235 forbidden. Also like methods, if the first character of an attribute is
236 lowercase in IDL, it is made uppercase in native code only.
238 Methods define a return type and a series of in and out parameters. When called
239 from a JavaScript context, they invocation looks as it is declared for the most
240 part; some parameter properties can adjust what the code looks like. The calls
241 are more mangled in native contexts.
243 An important attribute for methods and attributes is scriptability. A method or
244 attribute is scriptable if it is declared in a ``scriptable`` interface and it
245 lacks a ``noscript`` or ``notxpcom`` property. Any method that is not
246 scriptable can only be accessed by native code. However, ``scriptable`` methods
247 must contain parameters and a return type that can be translated to script: any
248 native type, save a few declared in ``nsrootidl.idl`` (see above), may not be
249 used in a scriptable method or attribute. An exception to the above rule is if
250 a ``nsQIResult`` parameter has the ``iid_is`` property (a special case for some
251 QueryInterface-like operations).
253 Methods and attributes are mangled on conversion to native code. If a method is
254 declared ``notxpcom``, the mangling of the return type is prevented, so it is
255 called mostly as it looks. Otherwise, the return type of the native method is
256 ``nsresult``, and the return type acts as a final outparameter if it is not
257 ``void``. The name is translated so that the first character is
258 unconditionally uppercase; subsequent characters are unaffected. However, the
259 presence of the ``binaryname`` property allows the user to select another name
260 to use in native code (to avoid conflicts with other functions). For example,
261 the method ``[binaryname(foo)] void bar();`` becomes ``nsresult Foo()`` in
262 native code (note that capitalization is still applied). However, the
263 capitalization is not applied when using ``binaryname`` with attributes; i.e.,
264 ``[binaryname(foo)] readonly attribute Quux bar;`` becomes ``Getfoo(Quux**)``
267 The ``implicit_jscontext`` and ``optional_argc`` parameters are properties
268 which help native code implementations determine how the call was made from
269 script. If ``implicit_jscontext`` is present on a method, then an additional
270 ``JSContext* cx`` parameter is added just after the regular list which receives
271 the context of the caller. If ``optional_argc`` is present, then an additional
272 ``uint8_t _argc`` parameter is added at the end which receives the number of
273 optional arguments that were actually used (obviously, you need to have an
274 optional argument in the first place). Note that if both properties are set,
275 the ``JSContext* cx`` is added first, followed by the ``uint8_t _argc``, and
276 then ending with return value parameter. Finally, as an exception to everything
277 already mentioned, for attribute getters and setters the ``JSContext *cx``
278 comes before any other arguments.
280 Another native-only property is ``nostdcall``. Normally, declarations are made
281 in the stdcall ABI on Windows to be ABI-compatible with COM interfaces. Any
282 non-scriptable method or attribute with ``nostdcall`` instead uses the
283 ``thiscall`` ABI convention. Methods without this property generally use
284 ``NS_IMETHOD`` in their declarations and ``NS_IMETHODIMP`` in their definitions
285 to automatically add in the stdcall declaration specifier on requisite
286 compilers; those that use this method may use a plain ``nsresult`` instead.
288 Another property, ``infallible``, is attribute-only. When present, it causes an
289 infallible C++ getter function definition to be generated for the attribute
290 alongside the normal fallible C++ getter declaration. It should only be used if
291 the fallible getter will be infallible in practice (i.e. always return
292 ``NS_OK``) for all possible implementations. This infallible getter contains
293 code that calls the fallible getter, asserts success, and returns the gotten
294 value directly. The point of using this property is to make C++ code nicer -- a
295 call to the infallible getter is more concise and readable than a call to the
296 fallible getter. This property can only be used for attributes having built-in
297 or interface types, and within classes that are marked with ``builtinclass``.
298 The latter restriction is because C++ implementations of fallible getters can
299 be audited for infallibility, but JS implementations can always throw (e.g. due
302 The ``must_use`` property is useful if the result of a method call or an
303 attribute get/set should always (or usually) be checked, which is frequently
304 the case. (e.g. a method that opens a file should almost certainly have its
305 result checked.) This property will cause ``[[nodiscard]]`` to be added to the
306 generated function declarations, which means certain compilers (e.g. clang and
307 GCC) will reports errors if these results are not used.
312 Each method parameter can be specified in one of three modes: ``in``, ``out``,
313 or ``inout``. An ``out`` parameter is essentially an auxiliary return value,
314 although these are moderately cumbersome to use from script contexts and should
315 therefore be avoided if reasonable. An ``inout`` parameter is an in parameter
316 whose value may be changed as a result of the method; these parameters are
317 rather annoying to use and should generally be avoided if at all possible.
319 ``out`` and ``inout`` parameters are reflected as objects having the ``.value``
320 property which contains the real value of the parameter; the ``value``
321 attribute is missing in the case of ``out`` parameters and is initialized to
322 the passed-in-value for ``inout`` parameters. The script code needs to set this
323 property to assign a value to the parameter. Regular ``in`` parameters are
324 reflected more or less normally, with numeric types all representing numbers,
325 booleans as ``true`` or ``false``, the various strings (including ``AString``
326 etc.) as a JavaScript string, and ``nsID`` types as a ``Components.ID``
327 instance. In addition, the ``jsval`` type is translated as the appropriate
328 JavaScript value (since a ``jsval`` is the internal representation of all
329 JavaScript values), and parameters with the ``nsIVeriant`` interface have their
330 types automatically boxed and unboxed as appropriate.
332 The equivalent representations of all IDL types in native code is given in the
333 earlier tables; parameters of type ``inout`` follow their ``out`` form. Native
334 code should pay particular attention to not passing in null values for out
335 parameters (although some parts of the codebase are known to violate this, it
336 is strictly enforced at the JS<->native barrier).
338 Representations of types additionally depend on some of the many types of
339 properties they may have. The ``array`` property turns the parameter into an array;
340 the parameter must also have a corresponding ``size_is`` property whose argument is
341 the parameter that has the size of the array. In native code, the type gains
342 another pointer indirection, and JavaScript arrays are used in script code.
343 Script code callers can ignore the value of array parameter, but implementers
344 must still set the values appropriately.
348 Prefer using the ``Array<T>`` builtin over the ``[array]`` attribute for
349 new code. It is more ergonomic to use from both JS and C++. In the future,
350 ``[array]`` may be deprecated and removed.
352 The ``const`` and ``shared`` properties are special to native code. As its name
353 implies, the ``const`` property makes its corresponding argument ``const``. The
354 ``shared`` property is only meaningful for ``out`` or ``inout`` parameters and
355 it means that the pointer value should not be freed by the caller. Only simple
356 native pointer types like ``string``, ``wstring``, and ``octetPtr`` may be
357 declared shared. The shared property also makes its corresponding argument
360 The ``retval`` property indicates that the parameter is actually acting as the
361 return value, and it is only the need to assign properties to the parameter
362 that is causing it to be specified as a parameter. It has no effect on native
363 code, but script code uses it like a regular return value. Naturally, a method
364 which contains a ``retval`` parameter must be declared ``void``, and the
365 parameter itself must be an ``out`` parameter and the last parameter.
367 Other properties are the ``optional`` and ``iid_is`` property. The ``optional``
368 property indicates that script code may omit the property without problems; all
369 subsequent parameters must either by optional themselves or the retval
370 parameter. Note that optional out parameters still pass in a variable for the
371 parameter, but its value will be ignored. The ``iid_is`` parameter indicates
372 that the real IID of an ``nsQIResult`` parameter may be found in the
373 corresponding parameter, to allow script code to automatically unbox the type.
375 Not all type combinations are possible. Native types with the various string
376 properties are all forbidden from being used as an ``inout`` parameter or as an
377 ``array`` parameter. In addition, native types with the ``nsid`` property but
378 lacking either a ``ptr`` or ``ref`` property are forbidden unless the method is
379 ``notxpcom`` and it is used as an ``in`` parameter.
384 For types that reference heap-allocated data (strings, arrays, interface
385 pointers, etc), you must follow the XPIDL data ownership conventions in order
386 to avoid memory corruption and security vulnerabilities:
388 * For ``in`` parameters, the caller allocates and deallocates all data. If the
389 callee needs to use the data after the call completes, it must make a private
390 copy of the data, or, in the case of interface pointers, ``AddRef`` it.
391 * For ``out`` parameters, the callee creates the data, and transfers ownership
392 to the caller. For buffers, the callee allocates the buffer with ``malloc``,
393 and the caller frees the buffer with ``free``. For interface pointers, the
394 callee does the ``AddRef`` on behalf of the caller, and the caller must call
395 ``Release``. This manual reference/memory management should be performed
396 using the ``getter_AddRefs`` and ``getter_Transfers`` helpers in new code.
397 * For ``inout`` parameters, the callee must clean up the old data if it chooses
398 to replace it. Buffers must be deallocated with ``free``, and interface
399 pointers must be ``Release``'d. Afterwards, the above rules for ``out``
401 * ``shared`` out-parameters should not be freed, as they are intended to refer
402 to constant string literals.